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
007// import edu.wpi.first.hal.FRCNetComm.tResourceType;
008// import edu.wpi.first.hal.HAL;
009import edu.wpi.first.wpilibj.event.BooleanEvent;
010import edu.wpi.first.wpilibj.event.EventLoop;
011
012/**
013 * Handle input from Stadia controllers connected to the Driver Station.
014 *
015 * <p>This class handles Stadia input that comes from the Driver Station. Each time a value is
016 * requested the most recent value is returned. There is a single class instance for each controller
017 * and the mapping of ports to hardware buttons depends on the code in the Driver Station.
018 */
019public class StadiaController extends GenericHID {
020  /** Represents a digital button on a StadiaController. */
021  public enum Button {
022    /** A button. */
023    kA(1),
024    /** B button. */
025    kB(2),
026    /** X Button. */
027    kX(3),
028    /** Y Button. */
029    kY(4),
030    /** Left bumper button. */
031    kLeftBumper(5),
032    /** Right bumper button. */
033    kRightBumper(6),
034    /** Left stick button. */
035    kLeftStick(7),
036    /** Right stick button. */
037    kRightStick(8),
038    /** Ellipses button. */
039    kEllipses(9),
040    /** Hamburger button. */
041    kHamburger(10),
042    /** Stadia button. */
043    kStadia(11),
044    /** Right trigger button. */
045    kRightTrigger(12),
046    /** Left trigger button. */
047    kLeftTrigger(13),
048    /** Google button. */
049    kGoogle(14),
050    /** Frame button. */
051    kFrame(15);
052
053    /** Button value. */
054    public final int value;
055
056    Button(int value) {
057      this.value = value;
058    }
059
060    /**
061     * Get the human-friendly name of the button, matching the relevant methods. This is done by
062     * stripping the leading `k`, and if not a Bumper button append `Button`.
063     *
064     * <p>Primarily used for automated unit tests.
065     *
066     * @return the human-friendly name of the button.
067     */
068    @Override
069    public String toString() {
070      var name = this.name().substring(1); // Remove leading `k`
071      if (name.endsWith("Bumper")) {
072        return name;
073      }
074      return name + "Button";
075    }
076  }
077
078  /** Represents an axis on a StadiaController. */
079  public enum Axis {
080    /** Left X axis. */
081    kLeftX(0),
082    /** Right X axis. */
083    kRightX(3),
084    /** Left Y axis. */
085    kLeftY(1),
086    /** Right Y axis. */
087    kRightY(4);
088
089    /** Axis value. */
090    public final int value;
091
092    Axis(int value) {
093      this.value = value;
094    }
095
096    /**
097     * Get the human-friendly name of the axis, matching the relevant methods. This is done by
098     * stripping the leading `k`, and if a trigger axis append `Axis`.
099     *
100     * <p>Primarily used for automated unit tests.
101     *
102     * @return the human-friendly name of the axis.
103     */
104    @Override
105    public String toString() {
106      var name = this.name().substring(1); // Remove leading `k`
107      if (name.endsWith("Trigger")) {
108        return name + "Axis";
109      }
110      return name;
111    }
112  }
113
114  /**
115   * Construct an instance of a controller.
116   *
117   * @param port The port index on the Driver Station that the controller is plugged into.
118   */
119  public StadiaController(final int port) {
120    super(port);
121    // re-enable when StadiaController is added to Usage Reporting
122    // HAL.report(tResourceType.kResourceType_Joystick, port + 1);
123  }
124
125  /**
126   * Get the X axis value of left side of the controller.
127   *
128   * @return The axis value.
129   */
130  public double getLeftX() {
131    return getRawAxis(Axis.kLeftX.value);
132  }
133
134  /**
135   * Get the X axis value of right side of the controller.
136   *
137   * @return The axis value.
138   */
139  public double getRightX() {
140    return getRawAxis(Axis.kRightX.value);
141  }
142
143  /**
144   * Get the Y axis value of left side of the controller.
145   *
146   * @return The axis value.
147   */
148  public double getLeftY() {
149    return getRawAxis(Axis.kLeftY.value);
150  }
151
152  /**
153   * Get the Y axis value of right side of the controller.
154   *
155   * @return The axis value.
156   */
157  public double getRightY() {
158    return getRawAxis(Axis.kRightY.value);
159  }
160
161  /**
162   * Read the value of the left bumper (LB) button on the controller.
163   *
164   * @return The state of the button.
165   */
166  public boolean getLeftBumper() {
167    return getRawButton(Button.kLeftBumper.value);
168  }
169
170  /**
171   * Read the value of the right bumper (RB) button on the controller.
172   *
173   * @return The state of the button.
174   */
175  public boolean getRightBumper() {
176    return getRawButton(Button.kRightBumper.value);
177  }
178
179  /**
180   * Whether the left bumper (LB) was pressed since the last check.
181   *
182   * @return Whether the button was pressed since the last check.
183   */
184  public boolean getLeftBumperPressed() {
185    return getRawButtonPressed(Button.kLeftBumper.value);
186  }
187
188  /**
189   * Whether the right bumper (RB) was pressed since the last check.
190   *
191   * @return Whether the button was pressed since the last check.
192   */
193  public boolean getRightBumperPressed() {
194    return getRawButtonPressed(Button.kRightBumper.value);
195  }
196
197  /**
198   * Whether the left bumper (LB) was released since the last check.
199   *
200   * @return Whether the button was released since the last check.
201   */
202  public boolean getLeftBumperReleased() {
203    return getRawButtonReleased(Button.kLeftBumper.value);
204  }
205
206  /**
207   * Whether the right bumper (RB) was released since the last check.
208   *
209   * @return Whether the button was released since the last check.
210   */
211  public boolean getRightBumperReleased() {
212    return getRawButtonReleased(Button.kRightBumper.value);
213  }
214
215  /**
216   * Constructs an event instance around the right bumper's digital signal.
217   *
218   * @param loop the event loop instance to attach the event to.
219   * @return an event instance representing the right bumper's digital signal attached to the given
220   *     loop.
221   */
222  public BooleanEvent leftBumper(EventLoop loop) {
223    return new BooleanEvent(loop, this::getLeftBumper);
224  }
225
226  /**
227   * Constructs an event instance around the left bumper's digital signal.
228   *
229   * @param loop the event loop instance to attach the event to.
230   * @return an event instance representing the left bumper's digital signal attached to the given
231   *     loop.
232   */
233  public BooleanEvent rightBumper(EventLoop loop) {
234    return new BooleanEvent(loop, this::getRightBumper);
235  }
236
237  /**
238   * Read the value of the left stick button (LSB) on the controller.
239   *
240   * @return The state of the button.
241   */
242  public boolean getLeftStickButton() {
243    return getRawButton(Button.kLeftStick.value);
244  }
245
246  /**
247   * Read the value of the right stick button (RSB) on the controller.
248   *
249   * @return The state of the button.
250   */
251  public boolean getRightStickButton() {
252    return getRawButton(Button.kRightStick.value);
253  }
254
255  /**
256   * Whether the left stick button (LSB) was pressed since the last check.
257   *
258   * @return Whether the button was pressed since the last check.
259   */
260  public boolean getLeftStickButtonPressed() {
261    return getRawButtonPressed(Button.kLeftStick.value);
262  }
263
264  /**
265   * Whether the right stick button (RSB) was pressed since the last check.
266   *
267   * @return Whether the button was pressed since the last check.
268   */
269  public boolean getRightStickButtonPressed() {
270    return getRawButtonPressed(Button.kRightStick.value);
271  }
272
273  /**
274   * Whether the left stick button (LSB) was released since the last check.
275   *
276   * @return Whether the button was released since the last check.
277   */
278  public boolean getLeftStickButtonReleased() {
279    return getRawButtonReleased(Button.kLeftStick.value);
280  }
281
282  /**
283   * Whether the right stick (RSB) button was released since the last check.
284   *
285   * @return Whether the button was released since the last check.
286   */
287  public boolean getRightStickButtonReleased() {
288    return getRawButtonReleased(Button.kRightStick.value);
289  }
290
291  /**
292   * Constructs an event instance around the left stick button's digital signal.
293   *
294   * @param loop the event loop instance to attach the event to.
295   * @return an event instance representing the left stick button's digital signal attached to the
296   *     given loop.
297   */
298  public BooleanEvent leftStick(EventLoop loop) {
299    return new BooleanEvent(loop, this::getLeftStickButton);
300  }
301
302  /**
303   * Constructs an event instance around the right stick button's digital signal.
304   *
305   * @param loop the event loop instance to attach the event to.
306   * @return an event instance representing the right stick button's digital signal attached to the
307   *     given loop.
308   */
309  public BooleanEvent rightStick(EventLoop loop) {
310    return new BooleanEvent(loop, this::getRightStickButton);
311  }
312
313  /**
314   * Read the value of the left trigger button (LTB) on the controller.
315   *
316   * @return The state of the button.
317   */
318  public boolean getLeftTriggerButton() {
319    return getRawButton(Button.kLeftTrigger.value);
320  }
321
322  /**
323   * Read the value of the right trigger button (RTB) on the controller.
324   *
325   * @return The state of the button.
326   */
327  public boolean getRightTriggerButton() {
328    return getRawButton(Button.kRightTrigger.value);
329  }
330
331  /**
332   * Whether the left trigger button (LTB) was pressed since the last check.
333   *
334   * @return Whether the button was pressed since the last check.
335   */
336  public boolean getLeftTriggerButtonPressed() {
337    return getRawButtonPressed(Button.kLeftTrigger.value);
338  }
339
340  /**
341   * Whether the right trigger button (RTB) was pressed since the last check.
342   *
343   * @return Whether the button was pressed since the last check.
344   */
345  public boolean getRightTriggerButtonPressed() {
346    return getRawButtonPressed(Button.kRightTrigger.value);
347  }
348
349  /**
350   * Whether the left trigger button (LTB) was released since the last check.
351   *
352   * @return Whether the button was released since the last check.
353   */
354  public boolean getLeftTriggerButtonReleased() {
355    return getRawButtonReleased(Button.kLeftTrigger.value);
356  }
357
358  /**
359   * Whether the right trigger (RTB) button was released since the last check.
360   *
361   * @return Whether the button was released since the last check.
362   */
363  public boolean getRightTriggerButtonReleased() {
364    return getRawButtonReleased(Button.kRightTrigger.value);
365  }
366
367  /**
368   * Constructs an event instance around the left trigger button's digital signal.
369   *
370   * @param loop the event loop instance to attach the event to.
371   * @return an event instance representing the left trigger button's digital signal attached to the
372   *     given loop.
373   */
374  public BooleanEvent leftTrigger(EventLoop loop) {
375    return new BooleanEvent(loop, this::getLeftTriggerButton);
376  }
377
378  /**
379   * Constructs an event instance around the right trigger button's digital signal.
380   *
381   * @param loop the event loop instance to attach the event to.
382   * @return an event instance representing the right trigger button's digital signal attached to
383   *     the given loop.
384   */
385  public BooleanEvent rightTrigger(EventLoop loop) {
386    return new BooleanEvent(loop, this::getRightTriggerButton);
387  }
388
389  /**
390   * Read the value of the A button on the controller.
391   *
392   * @return The state of the button.
393   */
394  public boolean getAButton() {
395    return getRawButton(Button.kA.value);
396  }
397
398  /**
399   * Whether the A button was pressed since the last check.
400   *
401   * @return Whether the button was pressed since the last check.
402   */
403  public boolean getAButtonPressed() {
404    return getRawButtonPressed(Button.kA.value);
405  }
406
407  /**
408   * Whether the A button was released since the last check.
409   *
410   * @return Whether the button was released since the last check.
411   */
412  public boolean getAButtonReleased() {
413    return getRawButtonReleased(Button.kA.value);
414  }
415
416  /**
417   * Constructs an event instance around the A button's digital signal.
418   *
419   * @param loop the event loop instance to attach the event to.
420   * @return an event instance representing the A button's digital signal attached to the given
421   *     loop.
422   */
423  @SuppressWarnings("MethodName")
424  public BooleanEvent a(EventLoop loop) {
425    return new BooleanEvent(loop, this::getAButton);
426  }
427
428  /**
429   * Read the value of the B button on the controller.
430   *
431   * @return The state of the button.
432   */
433  public boolean getBButton() {
434    return getRawButton(Button.kB.value);
435  }
436
437  /**
438   * Whether the B button was pressed since the last check.
439   *
440   * @return Whether the button was pressed since the last check.
441   */
442  public boolean getBButtonPressed() {
443    return getRawButtonPressed(Button.kB.value);
444  }
445
446  /**
447   * Whether the B button was released since the last check.
448   *
449   * @return Whether the button was released since the last check.
450   */
451  public boolean getBButtonReleased() {
452    return getRawButtonReleased(Button.kB.value);
453  }
454
455  /**
456   * Constructs an event instance around the B button's digital signal.
457   *
458   * @param loop the event loop instance to attach the event to.
459   * @return an event instance representing the B button's digital signal attached to the given
460   *     loop.
461   */
462  @SuppressWarnings("MethodName")
463  public BooleanEvent b(EventLoop loop) {
464    return new BooleanEvent(loop, this::getBButton);
465  }
466
467  /**
468   * Read the value of the X button on the controller.
469   *
470   * @return The state of the button.
471   */
472  public boolean getXButton() {
473    return getRawButton(Button.kX.value);
474  }
475
476  /**
477   * Whether the X button was pressed since the last check.
478   *
479   * @return Whether the button was pressed since the last check.
480   */
481  public boolean getXButtonPressed() {
482    return getRawButtonPressed(Button.kX.value);
483  }
484
485  /**
486   * Whether the X button was released since the last check.
487   *
488   * @return Whether the button was released since the last check.
489   */
490  public boolean getXButtonReleased() {
491    return getRawButtonReleased(Button.kX.value);
492  }
493
494  /**
495   * Constructs an event instance around the X button's digital signal.
496   *
497   * @param loop the event loop instance to attach the event to.
498   * @return an event instance representing the X button's digital signal attached to the given
499   *     loop.
500   */
501  @SuppressWarnings("MethodName")
502  public BooleanEvent x(EventLoop loop) {
503    return new BooleanEvent(loop, this::getXButton);
504  }
505
506  /**
507   * Read the value of the Y button on the controller.
508   *
509   * @return The state of the button.
510   */
511  public boolean getYButton() {
512    return getRawButton(Button.kY.value);
513  }
514
515  /**
516   * Whether the Y button was pressed since the last check.
517   *
518   * @return Whether the button was pressed since the last check.
519   */
520  public boolean getYButtonPressed() {
521    return getRawButtonPressed(Button.kY.value);
522  }
523
524  /**
525   * Whether the Y button was released since the last check.
526   *
527   * @return Whether the button was released since the last check.
528   */
529  public boolean getYButtonReleased() {
530    return getRawButtonReleased(Button.kY.value);
531  }
532
533  /**
534   * Constructs an event instance around the Y button's digital signal.
535   *
536   * @param loop the event loop instance to attach the event to.
537   * @return an event instance representing the Y button's digital signal attached to the given
538   *     loop.
539   */
540  @SuppressWarnings("MethodName")
541  public BooleanEvent y(EventLoop loop) {
542    return new BooleanEvent(loop, this::getYButton);
543  }
544
545  /**
546   * Read the value of the ellipses button on the controller.
547   *
548   * @return The state of the button.
549   */
550  public boolean getEllipsesButton() {
551    return getRawButton(Button.kEllipses.value);
552  }
553
554  /**
555   * Whether the ellipses button was pressed since the last check.
556   *
557   * @return Whether the button was pressed since the last check.
558   */
559  public boolean getEllipsesButtonPressed() {
560    return getRawButtonPressed(Button.kEllipses.value);
561  }
562
563  /**
564   * Whether the ellipses button was released since the last check.
565   *
566   * @return Whether the button was released since the last check.
567   */
568  public boolean getEllipsesButtonReleased() {
569    return getRawButtonReleased(Button.kEllipses.value);
570  }
571
572  /**
573   * Constructs an event instance around the ellipses button's digital signal.
574   *
575   * @param loop the event loop instance to attach the event to.
576   * @return an event instance representing the ellipses button's digital signal attached to the
577   *     given loop.
578   */
579  public BooleanEvent ellipses(EventLoop loop) {
580    return new BooleanEvent(loop, this::getEllipsesButton);
581  }
582
583  /**
584   * Read the value of the hamburger button on the controller.
585   *
586   * @return The state of the button.
587   */
588  public boolean getHamburgerButton() {
589    return getRawButton(Button.kHamburger.value);
590  }
591
592  /**
593   * Whether the hamburger button was pressed since the last check.
594   *
595   * @return Whether the button was pressed since the last check.
596   */
597  public boolean getHamburgerButtonPressed() {
598    return getRawButtonPressed(Button.kHamburger.value);
599  }
600
601  /**
602   * Whether the hamburger button was released since the last check.
603   *
604   * @return Whether the button was released since the last check.
605   */
606  public boolean getHamburgerButtonReleased() {
607    return getRawButtonReleased(Button.kHamburger.value);
608  }
609
610  /**
611   * Constructs an event instance around the hamburger button's digital signal.
612   *
613   * @param loop the event loop instance to attach the event to.
614   * @return an event instance representing the hamburger button's digital signal attached to the
615   *     given loop.
616   */
617  public BooleanEvent hamburger(EventLoop loop) {
618    return new BooleanEvent(loop, this::getHamburgerButton);
619  }
620
621  /**
622   * Read the value of the stadia button on the controller.
623   *
624   * @return The state of the button.
625   */
626  public boolean getStadiaButton() {
627    return getRawButton(Button.kStadia.value);
628  }
629
630  /**
631   * Whether the stadia button was pressed since the last check.
632   *
633   * @return Whether the button was pressed since the last check.
634   */
635  public boolean getStadiaButtonPressed() {
636    return getRawButtonPressed(Button.kStadia.value);
637  }
638
639  /**
640   * Whether the stadia button was released since the last check.
641   *
642   * @return Whether the button was released since the last check.
643   */
644  public boolean getStadiaButtonReleased() {
645    return getRawButtonReleased(Button.kStadia.value);
646  }
647
648  /**
649   * Constructs an event instance around the stadia button's digital signal.
650   *
651   * @param loop the event loop instance to attach the event to.
652   * @return an event instance representing the stadia button's digital signal attached to the given
653   *     loop.
654   */
655  @SuppressWarnings("MethodName")
656  public BooleanEvent stadia(EventLoop loop) {
657    return new BooleanEvent(loop, this::getStadiaButton);
658  }
659
660  /**
661   * Read the value of the google button on the controller.
662   *
663   * @return The state of the button.
664   */
665  public boolean getGoogleButton() {
666    return getRawButton(Button.kGoogle.value);
667  }
668
669  /**
670   * Whether the google button was pressed since the last check.
671   *
672   * @return Whether the button was pressed since the last check.
673   */
674  public boolean getGoogleButtonPressed() {
675    return getRawButtonPressed(Button.kGoogle.value);
676  }
677
678  /**
679   * Whether the google button was released since the last check.
680   *
681   * @return Whether the button was released since the last check.
682   */
683  public boolean getGoogleButtonReleased() {
684    return getRawButtonReleased(Button.kGoogle.value);
685  }
686
687  /**
688   * Constructs an event instance around the google button's digital signal.
689   *
690   * @param loop the event loop instance to attach the event to.
691   * @return an event instance representing the google button's digital signal attached to the given
692   *     loop.
693   */
694  @SuppressWarnings("MethodName")
695  public BooleanEvent google(EventLoop loop) {
696    return new BooleanEvent(loop, this::getGoogleButton);
697  }
698
699  /**
700   * Read the value of the frame button on the controller.
701   *
702   * @return The state of the button.
703   */
704  public boolean getFrameButton() {
705    return getRawButton(Button.kFrame.value);
706  }
707
708  /**
709   * Whether the frame button was pressed since the last check.
710   *
711   * @return Whether the button was pressed since the last check.
712   */
713  public boolean getFrameButtonPressed() {
714    return getRawButtonPressed(Button.kFrame.value);
715  }
716
717  /**
718   * Whether the frame button was released since the last check.
719   *
720   * @return Whether the button was released since the last check.
721   */
722  public boolean getFrameButtonReleased() {
723    return getRawButtonReleased(Button.kFrame.value);
724  }
725
726  /**
727   * Constructs an event instance around the frame button's digital signal.
728   *
729   * @param loop the event loop instance to attach the event to.
730   * @return an event instance representing the frame button's digital signal attached to the given
731   *     loop.
732   */
733  @SuppressWarnings("MethodName")
734  public BooleanEvent frame(EventLoop loop) {
735    return new BooleanEvent(loop, this::getFrameButton);
736  }
737}