001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.wpilibj; 006 007import edu.wpi.first.wpilibj.event.BooleanEvent; 008import edu.wpi.first.wpilibj.event.EventLoop; 009 010/** 011 * Handle input from PS5 controllers connected to the Driver Station. 012 * 013 * <p>This class handles PS5 input that comes from the Driver Station. Each time a value is 014 * requested the most recent value is returned. There is a single class instance for each controller 015 * and the mapping of ports to hardware buttons depends on the code in the Driver Station. 016 * 017 * <p>Only first party controllers from Sony are guaranteed to have the correct mapping, and only 018 * through the official NI DS. Sim is not guaranteed to have the same mapping, as well as any 3rd 019 * party controllers. 020 */ 021public class PS5Controller extends GenericHID { 022 /** 023 * Construct an instance of a device. 024 * 025 * @param port The port index on the Driver Station that the device is plugged into. 026 */ 027 public PS5Controller(int port) { 028 super(port); 029 // HAL.report(tResourceType.kResourceType_PS5Controller, port + 1); 030 } 031 032 /** Represents a digital button on a PS5Controller. */ 033 public enum Button { 034 /** Square button. */ 035 kSquare(1), 036 /** X button. */ 037 kCross(2), 038 /** Circle button. */ 039 kCircle(3), 040 /** Triangle button. */ 041 kTriangle(4), 042 /** Left trigger 1 button. */ 043 kL1(5), 044 /** Right trigger 1 button. */ 045 kR1(6), 046 /** Left trigger 2 button. */ 047 kL2(7), 048 /** Right trigger 2 button. */ 049 kR2(8), 050 /** Create button. */ 051 kCreate(9), 052 /** Options button. */ 053 kOptions(10), 054 /** Left stick button. */ 055 kL3(11), 056 /** Right stick button. */ 057 kR3(12), 058 /** PlayStation button. */ 059 kPS(13), 060 /** Touchpad click button. */ 061 kTouchpad(14); 062 063 /** Button value. */ 064 public final int value; 065 066 Button(int index) { 067 this.value = index; 068 } 069 070 /** 071 * Get the human-friendly name of the button, matching the relevant methods. This is done by 072 * stripping the leading `k`, and if not the touchpad append `Button`. 073 * 074 * <p>Primarily used for automated unit tests. 075 * 076 * @return the human-friendly name of the button. 077 */ 078 @Override 079 public String toString() { 080 var name = this.name().substring(1); // Remove leading `k` 081 if (this == kTouchpad) { 082 return name; 083 } 084 return name + "Button"; 085 } 086 } 087 088 /** Represents an axis on a PS5Controller. */ 089 public enum Axis { 090 /** Left X axis. */ 091 kLeftX(0), 092 /** Left Y axis. */ 093 kLeftY(1), 094 /** Right X axis. */ 095 kRightX(2), 096 /** Right Y axis. */ 097 kRightY(5), 098 /** Left Trigger 2. */ 099 kL2(3), 100 /** Right Trigger 2. */ 101 kR2(4); 102 103 /** Axis value. */ 104 public final int value; 105 106 Axis(int index) { 107 value = index; 108 } 109 110 /** 111 * Get the human-friendly name of the axis, matching the relevant methods. This is done by 112 * stripping the leading `k`, and if one of L2/R2 append `Axis`. 113 * 114 * <p>Primarily used for automated unit tests. 115 * 116 * @return the human-friendly name of the axis. 117 */ 118 @Override 119 public String toString() { 120 var name = this.name().substring(1); // Remove leading `k` 121 if (name.endsWith("2")) { 122 return name + "Axis"; 123 } 124 return name; 125 } 126 } 127 128 /** 129 * Get the X axis value of left side of the controller. 130 * 131 * @return the axis value. 132 */ 133 public double getLeftX() { 134 return getRawAxis(Axis.kLeftX.value); 135 } 136 137 /** 138 * Get the X axis value of right side of the controller. 139 * 140 * @return the axis value. 141 */ 142 public double getRightX() { 143 return getRawAxis(Axis.kRightX.value); 144 } 145 146 /** 147 * Get the Y axis value of left side of the controller. 148 * 149 * @return the axis value. 150 */ 151 public double getLeftY() { 152 return getRawAxis(Axis.kLeftY.value); 153 } 154 155 /** 156 * Get the Y axis value of right side of the controller. 157 * 158 * @return the axis value. 159 */ 160 public double getRightY() { 161 return getRawAxis(Axis.kRightY.value); 162 } 163 164 /** 165 * Get the L2 axis value of the controller. Note that this axis is bound to the range of [0, 1] as 166 * opposed to the usual [-1, 1]. 167 * 168 * @return the axis value. 169 */ 170 public double getL2Axis() { 171 return getRawAxis(Axis.kL2.value); 172 } 173 174 /** 175 * Get the R2 axis value of the controller. Note that this axis is bound to the range of [0, 1] as 176 * opposed to the usual [-1, 1]. 177 * 178 * @return the axis value. 179 */ 180 public double getR2Axis() { 181 return getRawAxis(Axis.kR2.value); 182 } 183 184 /** 185 * Read the value of the left trigger button on the controller. 186 * 187 * @return The state of the button. 188 */ 189 public boolean getL2Button() { 190 return getRawButton(Button.kL2.value); 191 } 192 193 /** 194 * Read the value of the right trigger button on the controller. 195 * 196 * @return The state of the button. 197 */ 198 public boolean getR2Button() { 199 return getRawButton(Button.kR2.value); 200 } 201 202 /** 203 * Whether the L2 button was pressed since the last check. 204 * 205 * @return Whether the button was pressed since the last check. 206 */ 207 public boolean getL2ButtonPressed() { 208 return getRawButtonPressed(Button.kL2.value); 209 } 210 211 /** 212 * Whether the R2 button was pressed since the last check. 213 * 214 * @return Whether the button was pressed since the last check. 215 */ 216 public boolean getR2ButtonPressed() { 217 return getRawButtonPressed(Button.kR2.value); 218 } 219 220 /** 221 * Whether the L2 button was released since the last check. 222 * 223 * @return Whether the button was released since the last check. 224 */ 225 public boolean getL2ButtonReleased() { 226 return getRawButtonReleased(Button.kL2.value); 227 } 228 229 /** 230 * Whether the R2 button was released since the last check. 231 * 232 * @return Whether the button was released since the last check. 233 */ 234 public boolean getR2ButtonReleased() { 235 return getRawButtonReleased(Button.kR2.value); 236 } 237 238 /** 239 * Constructs an event instance around the L2 button's digital signal. 240 * 241 * @param loop the event loop instance to attach the event to. 242 * @return an event instance representing the L2 button's digital signal attached to the given 243 * loop. 244 */ 245 @SuppressWarnings("MethodName") 246 public BooleanEvent L2(EventLoop loop) { 247 return new BooleanEvent(loop, this::getL2Button); 248 } 249 250 /** 251 * Constructs an event instance around the R2 button's digital signal. 252 * 253 * @param loop the event loop instance to attach the event to. 254 * @return an event instance representing the R2 button's digital signal attached to the given 255 * loop. 256 */ 257 @SuppressWarnings("MethodName") 258 public BooleanEvent R2(EventLoop loop) { 259 return new BooleanEvent(loop, this::getR2Button); 260 } 261 262 /** 263 * Read the value of the L1 button on the controller. 264 * 265 * @return The state of the button. 266 */ 267 public boolean getL1Button() { 268 return getRawButton(Button.kL1.value); 269 } 270 271 /** 272 * Read the value of the R1 button on the controller. 273 * 274 * @return The state of the button. 275 */ 276 public boolean getR1Button() { 277 return getRawButton(Button.kR1.value); 278 } 279 280 /** 281 * Whether the L1 button was pressed since the last check. 282 * 283 * @return Whether the button was pressed since the last check. 284 */ 285 public boolean getL1ButtonPressed() { 286 return getRawButtonPressed(Button.kL1.value); 287 } 288 289 /** 290 * Whether the R1 button was pressed since the last check. 291 * 292 * @return Whether the button was pressed since the last check. 293 */ 294 public boolean getR1ButtonPressed() { 295 return getRawButtonPressed(Button.kR1.value); 296 } 297 298 /** 299 * Whether the L1 button was released since the last check. 300 * 301 * @return Whether the button was released since the last check. 302 */ 303 public boolean getL1ButtonReleased() { 304 return getRawButtonReleased(Button.kL1.value); 305 } 306 307 /** 308 * Whether the R1 button was released since the last check. 309 * 310 * @return Whether the button was released since the last check. 311 */ 312 public boolean getR1ButtonReleased() { 313 return getRawButtonReleased(Button.kR1.value); 314 } 315 316 /** 317 * Constructs an event instance around the L1 button's digital signal. 318 * 319 * @param loop the event loop instance to attach the event to. 320 * @return an event instance representing the L1 button's digital signal attached to the given 321 * loop. 322 */ 323 @SuppressWarnings("MethodName") 324 public BooleanEvent L1(EventLoop loop) { 325 return new BooleanEvent(loop, this::getL1Button); 326 } 327 328 /** 329 * Constructs an event instance around the R1 button's digital signal. 330 * 331 * @param loop the event loop instance to attach the event to. 332 * @return an event instance representing the R1 button's digital signal attached to the given 333 * loop. 334 */ 335 @SuppressWarnings("MethodName") 336 public BooleanEvent R1(EventLoop loop) { 337 return new BooleanEvent(loop, this::getR1Button); 338 } 339 340 /** 341 * Read the value of the L3 button (pressing the left analog stick) on the controller. 342 * 343 * @return The state of the button. 344 */ 345 public boolean getL3Button() { 346 return getRawButton(Button.kL3.value); 347 } 348 349 /** 350 * Read the value of the R3 button (pressing the right analog stick) on the controller. 351 * 352 * @return The state of the button. 353 */ 354 public boolean getR3Button() { 355 return getRawButton(Button.kR3.value); 356 } 357 358 /** 359 * Whether the L3 (left stick) button was pressed since the last check. 360 * 361 * @return Whether the button was pressed since the last check. 362 */ 363 public boolean getL3ButtonPressed() { 364 return getRawButtonPressed(Button.kL3.value); 365 } 366 367 /** 368 * Whether the R3 (right stick) button was pressed since the last check. 369 * 370 * @return Whether the button was pressed since the last check. 371 */ 372 public boolean getR3ButtonPressed() { 373 return getRawButtonPressed(Button.kR3.value); 374 } 375 376 /** 377 * Whether the L3 (left stick) button was released since the last check. 378 * 379 * @return Whether the button was released since the last check. 380 */ 381 public boolean getL3ButtonReleased() { 382 return getRawButtonReleased(Button.kL3.value); 383 } 384 385 /** 386 * Whether the R3 (right stick) button was released since the last check. 387 * 388 * @return Whether the button was released since the last check. 389 */ 390 public boolean getR3ButtonReleased() { 391 return getRawButtonReleased(Button.kR3.value); 392 } 393 394 /** 395 * Constructs an event instance around the L3 button's digital signal. 396 * 397 * @param loop the event loop instance to attach the event to. 398 * @return an event instance representing the L3 button's digital signal attached to the given 399 * loop. 400 */ 401 @SuppressWarnings("MethodName") 402 public BooleanEvent L3(EventLoop loop) { 403 return new BooleanEvent(loop, this::getL3Button); 404 } 405 406 /** 407 * Constructs an event instance around the R3 button's digital signal. 408 * 409 * @param loop the event loop instance to attach the event to. 410 * @return an event instance representing the R3 button's digital signal attached to the given 411 * loop. 412 */ 413 @SuppressWarnings("MethodName") 414 public BooleanEvent R3(EventLoop loop) { 415 return new BooleanEvent(loop, this::getR3Button); 416 } 417 418 /** 419 * Read the value of the Square button on the controller. 420 * 421 * @return The state of the button. 422 */ 423 public boolean getSquareButton() { 424 return getRawButton(Button.kSquare.value); 425 } 426 427 /** 428 * Whether the Square button was pressed since the last check. 429 * 430 * @return Whether the button was pressed since the last check. 431 */ 432 public boolean getSquareButtonPressed() { 433 return getRawButtonPressed(Button.kSquare.value); 434 } 435 436 /** 437 * Whether the Square button was released since the last check. 438 * 439 * @return Whether the button was released since the last check. 440 */ 441 public boolean getSquareButtonReleased() { 442 return getRawButtonReleased(Button.kSquare.value); 443 } 444 445 /** 446 * Constructs an event instance around the square button's digital signal. 447 * 448 * @param loop the event loop instance to attach the event to. 449 * @return an event instance representing the square button's digital signal attached to the given 450 * loop. 451 */ 452 public BooleanEvent square(EventLoop loop) { 453 return new BooleanEvent(loop, this::getSquareButton); 454 } 455 456 /** 457 * Read the value of the Cross button on the controller. 458 * 459 * @return The state of the button. 460 */ 461 public boolean getCrossButton() { 462 return getRawButton(Button.kCross.value); 463 } 464 465 /** 466 * Whether the Cross button was pressed since the last check. 467 * 468 * @return Whether the button was pressed since the last check. 469 */ 470 public boolean getCrossButtonPressed() { 471 return getRawButtonPressed(Button.kCross.value); 472 } 473 474 /** 475 * Whether the Cross button was released since the last check. 476 * 477 * @return Whether the button was released since the last check. 478 */ 479 public boolean getCrossButtonReleased() { 480 return getRawButtonReleased(Button.kCross.value); 481 } 482 483 /** 484 * Constructs an event instance around the cross button's digital signal. 485 * 486 * @param loop the event loop instance to attach the event to. 487 * @return an event instance representing the cross button's digital signal attached to the given 488 * loop. 489 */ 490 public BooleanEvent cross(EventLoop loop) { 491 return new BooleanEvent(loop, this::getCrossButton); 492 } 493 494 /** 495 * Read the value of the Triangle button on the controller. 496 * 497 * @return The state of the button. 498 */ 499 public boolean getTriangleButton() { 500 return getRawButton(Button.kTriangle.value); 501 } 502 503 /** 504 * Whether the Triangle button was pressed since the last check. 505 * 506 * @return Whether the button was pressed since the last check. 507 */ 508 public boolean getTriangleButtonPressed() { 509 return getRawButtonPressed(Button.kTriangle.value); 510 } 511 512 /** 513 * Whether the Triangle button was released since the last check. 514 * 515 * @return Whether the button was released since the last check. 516 */ 517 public boolean getTriangleButtonReleased() { 518 return getRawButtonReleased(Button.kTriangle.value); 519 } 520 521 /** 522 * Constructs an event instance around the triangle button's digital signal. 523 * 524 * @param loop the event loop instance to attach the event to. 525 * @return an event instance representing the triangle button's digital signal attached to the 526 * given loop. 527 */ 528 public BooleanEvent triangle(EventLoop loop) { 529 return new BooleanEvent(loop, this::getTriangleButton); 530 } 531 532 /** 533 * Read the value of the Circle button on the controller. 534 * 535 * @return The state of the button. 536 */ 537 public boolean getCircleButton() { 538 return getRawButton(Button.kCircle.value); 539 } 540 541 /** 542 * Whether the Circle button was pressed since the last check. 543 * 544 * @return Whether the button was pressed since the last check. 545 */ 546 public boolean getCircleButtonPressed() { 547 return getRawButtonPressed(Button.kCircle.value); 548 } 549 550 /** 551 * Whether the Circle button was released since the last check. 552 * 553 * @return Whether the button was released since the last check. 554 */ 555 public boolean getCircleButtonReleased() { 556 return getRawButtonReleased(Button.kCircle.value); 557 } 558 559 /** 560 * Constructs an event instance around the circle button's digital signal. 561 * 562 * @param loop the event loop instance to attach the event to. 563 * @return an event instance representing the circle button's digital signal attached to the given 564 * loop. 565 */ 566 public BooleanEvent circle(EventLoop loop) { 567 return new BooleanEvent(loop, this::getCircleButton); 568 } 569 570 /** 571 * Read the value of the share button on the controller. 572 * 573 * @return The state of the button. 574 */ 575 public boolean getCreateButton() { 576 return getRawButton(Button.kCreate.value); 577 } 578 579 /** 580 * Whether the share button was pressed since the last check. 581 * 582 * @return Whether the button was pressed since the last check. 583 */ 584 public boolean getCreateButtonPressed() { 585 return getRawButtonPressed(Button.kCreate.value); 586 } 587 588 /** 589 * Whether the share button was released since the last check. 590 * 591 * @return Whether the button was released since the last check. 592 */ 593 public boolean getCreateButtonReleased() { 594 return getRawButtonReleased(Button.kCreate.value); 595 } 596 597 /** 598 * Constructs an event instance around the share button's digital signal. 599 * 600 * @param loop the event loop instance to attach the event to. 601 * @return an event instance representing the share button's digital signal attached to the given 602 * loop. 603 */ 604 @SuppressWarnings("MethodName") 605 public BooleanEvent create(EventLoop loop) { 606 return new BooleanEvent(loop, this::getCreateButton); 607 } 608 609 /** 610 * Read the value of the PS button on the controller. 611 * 612 * @return The state of the button. 613 */ 614 public boolean getPSButton() { 615 return getRawButton(Button.kPS.value); 616 } 617 618 /** 619 * Whether the PS button was pressed since the last check. 620 * 621 * @return Whether the button was pressed since the last check. 622 */ 623 public boolean getPSButtonPressed() { 624 return getRawButtonPressed(Button.kPS.value); 625 } 626 627 /** 628 * Whether the PS button was released since the last check. 629 * 630 * @return Whether the button was released since the last check. 631 */ 632 public boolean getPSButtonReleased() { 633 return getRawButtonReleased(Button.kPS.value); 634 } 635 636 /** 637 * Constructs an event instance around the PS button's digital signal. 638 * 639 * @param loop the event loop instance to attach the event to. 640 * @return an event instance representing the PS button's digital signal attached to the given 641 * loop. 642 */ 643 @SuppressWarnings("MethodName") 644 public BooleanEvent PS(EventLoop loop) { 645 return new BooleanEvent(loop, this::getPSButton); 646 } 647 648 /** 649 * Read the value of the options button on the controller. 650 * 651 * @return The state of the button. 652 */ 653 public boolean getOptionsButton() { 654 return getRawButton(Button.kOptions.value); 655 } 656 657 /** 658 * Whether the options button was pressed since the last check. 659 * 660 * @return Whether the button was pressed since the last check. 661 */ 662 public boolean getOptionsButtonPressed() { 663 return getRawButtonPressed(Button.kOptions.value); 664 } 665 666 /** 667 * Whether the options button was released since the last check. 668 * 669 * @return Whether the button was released since the last check. 670 */ 671 public boolean getOptionsButtonReleased() { 672 return getRawButtonReleased(Button.kOptions.value); 673 } 674 675 /** 676 * Constructs an event instance around the options button's digital signal. 677 * 678 * @param loop the event loop instance to attach the event to. 679 * @return an event instance representing the options button's digital signal attached to the 680 * given loop. 681 */ 682 public BooleanEvent options(EventLoop loop) { 683 return new BooleanEvent(loop, this::getOptionsButton); 684 } 685 686 /** 687 * Read the value of the touchpad on the controller. 688 * 689 * @return The state of the touchpad. 690 */ 691 public boolean getTouchpad() { 692 return getRawButton(Button.kTouchpad.value); 693 } 694 695 /** 696 * Whether the touchpad was pressed since the last check. 697 * 698 * @return Whether the touchpad was pressed since the last check. 699 */ 700 public boolean getTouchpadPressed() { 701 return getRawButtonPressed(Button.kTouchpad.value); 702 } 703 704 /** 705 * Whether the touchpad was released since the last check. 706 * 707 * @return Whether the touchpad was released since the last check. 708 */ 709 public boolean getTouchpadReleased() { 710 return getRawButtonReleased(Button.kTouchpad.value); 711 } 712 713 /** 714 * Constructs an event instance around the touchpad's digital signal. 715 * 716 * @param loop the event loop instance to attach the event to. 717 * @return an event instance representing the touchpad's digital signal attached to the given 718 * loop. 719 */ 720 public BooleanEvent touchpad(EventLoop loop) { 721 return new BooleanEvent(loop, this::getTouchpad); 722 } 723}