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