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.simulation;
006
007import edu.wpi.first.hal.AllianceStationID;
008import edu.wpi.first.hal.DriverStationJNI;
009import edu.wpi.first.hal.simulation.DriverStationDataJNI;
010import edu.wpi.first.hal.simulation.NotifyCallback;
011import edu.wpi.first.util.WPIUtilJNI;
012import edu.wpi.first.wpilibj.DriverStation;
013
014/** Class to control a simulated driver station. */
015public final class DriverStationSim {
016  private DriverStationSim() {
017    throw new UnsupportedOperationException("This is a utility class!");
018  }
019
020  /**
021   * Register a callback on whether the DS is enabled.
022   *
023   * @param callback the callback that will be called whenever the enabled state is changed
024   * @param initialNotify if true, the callback will be run on the initial value
025   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
026   *     this object so GC doesn't cancel the callback.
027   */
028  public static CallbackStore registerEnabledCallback(
029      NotifyCallback callback, boolean initialNotify) {
030    int uid = DriverStationDataJNI.registerEnabledCallback(callback, initialNotify);
031    return new CallbackStore(uid, DriverStationDataJNI::cancelEnabledCallback);
032  }
033
034  /**
035   * Check if the DS is enabled.
036   *
037   * @return true if enabled
038   */
039  public static boolean getEnabled() {
040    return DriverStationDataJNI.getEnabled();
041  }
042
043  /**
044   * Change whether the DS is enabled.
045   *
046   * @param enabled the new value
047   */
048  public static void setEnabled(boolean enabled) {
049    DriverStationDataJNI.setEnabled(enabled);
050  }
051
052  /**
053   * Register a callback on whether the DS is in autonomous mode.
054   *
055   * @param callback the callback that will be called on autonomous mode entrance/exit
056   * @param initialNotify if true, the callback will be run on the initial value
057   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
058   *     this object so GC doesn't cancel the callback.
059   */
060  public static CallbackStore registerAutonomousCallback(
061      NotifyCallback callback, boolean initialNotify) {
062    int uid = DriverStationDataJNI.registerAutonomousCallback(callback, initialNotify);
063    return new CallbackStore(uid, DriverStationDataJNI::cancelAutonomousCallback);
064  }
065
066  /**
067   * Check if the DS is in autonomous.
068   *
069   * @return true if autonomous
070   */
071  public static boolean getAutonomous() {
072    return DriverStationDataJNI.getAutonomous();
073  }
074
075  /**
076   * Change whether the DS is in autonomous.
077   *
078   * @param autonomous the new value
079   */
080  public static void setAutonomous(boolean autonomous) {
081    DriverStationDataJNI.setAutonomous(autonomous);
082  }
083
084  /**
085   * Register a callback on whether the DS is in test mode.
086   *
087   * @param callback the callback that will be called whenever the test mode is entered or left
088   * @param initialNotify if true, the callback will be run on the initial value
089   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
090   *     this object so GC doesn't cancel the callback.
091   */
092  public static CallbackStore registerTestCallback(NotifyCallback callback, boolean initialNotify) {
093    int uid = DriverStationDataJNI.registerTestCallback(callback, initialNotify);
094    return new CallbackStore(uid, DriverStationDataJNI::cancelTestCallback);
095  }
096
097  /**
098   * Check if the DS is in test.
099   *
100   * @return true if test
101   */
102  public static boolean getTest() {
103    return DriverStationDataJNI.getTest();
104  }
105
106  /**
107   * Change whether the DS is in test.
108   *
109   * @param test the new value
110   */
111  public static void setTest(boolean test) {
112    DriverStationDataJNI.setTest(test);
113  }
114
115  /**
116   * Register a callback on the eStop state.
117   *
118   * @param callback the callback that will be called whenever the eStop state changes
119   * @param initialNotify if true, the callback will be run on the initial value
120   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
121   *     this object so GC doesn't cancel the callback.
122   */
123  public static CallbackStore registerEStopCallback(
124      NotifyCallback callback, boolean initialNotify) {
125    int uid = DriverStationDataJNI.registerEStopCallback(callback, initialNotify);
126    return new CallbackStore(uid, DriverStationDataJNI::cancelEStopCallback);
127  }
128
129  /**
130   * Check if eStop has been activated.
131   *
132   * @return true if eStopped
133   */
134  public static boolean getEStop() {
135    return DriverStationDataJNI.getEStop();
136  }
137
138  /**
139   * Set whether eStop is active.
140   *
141   * @param eStop true to activate
142   */
143  public static void setEStop(boolean eStop) {
144    DriverStationDataJNI.setEStop(eStop);
145  }
146
147  /**
148   * Register a callback on whether the FMS is connected.
149   *
150   * @param callback the callback that will be called whenever the FMS connection changes
151   * @param initialNotify if true, the callback will be run on the initial value
152   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
153   *     this object so GC doesn't cancel the callback.
154   */
155  public static CallbackStore registerFmsAttachedCallback(
156      NotifyCallback callback, boolean initialNotify) {
157    int uid = DriverStationDataJNI.registerFmsAttachedCallback(callback, initialNotify);
158    return new CallbackStore(uid, DriverStationDataJNI::cancelFmsAttachedCallback);
159  }
160
161  /**
162   * Check if the FMS is connected.
163   *
164   * @return true if FMS is connected
165   */
166  public static boolean getFmsAttached() {
167    return DriverStationDataJNI.getFmsAttached();
168  }
169
170  /**
171   * Change whether the FMS is connected.
172   *
173   * @param fmsAttached the new value
174   */
175  public static void setFmsAttached(boolean fmsAttached) {
176    DriverStationDataJNI.setFmsAttached(fmsAttached);
177  }
178
179  /**
180   * Register a callback on whether the DS is connected.
181   *
182   * @param callback the callback that will be called whenever the DS connection changes
183   * @param initialNotify if true, the callback will be run on the initial value
184   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
185   *     this object so GC doesn't cancel the callback.
186   */
187  public static CallbackStore registerDsAttachedCallback(
188      NotifyCallback callback, boolean initialNotify) {
189    int uid = DriverStationDataJNI.registerDsAttachedCallback(callback, initialNotify);
190    return new CallbackStore(uid, DriverStationDataJNI::cancelDsAttachedCallback);
191  }
192
193  /**
194   * Check if the DS is attached.
195   *
196   * @return true if attached
197   */
198  public static boolean getDsAttached() {
199    return DriverStationDataJNI.getDsAttached();
200  }
201
202  /**
203   * Change whether the DS is attached.
204   *
205   * @param dsAttached the new value
206   */
207  public static void setDsAttached(boolean dsAttached) {
208    DriverStationDataJNI.setDsAttached(dsAttached);
209  }
210
211  /**
212   * Register a callback on the alliance station ID.
213   *
214   * @param callback the callback that will be called whenever the alliance station changes
215   * @param initialNotify if true, the callback will be run on the initial value
216   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
217   *     this object so GC doesn't cancel the callback.
218   */
219  public static CallbackStore registerAllianceStationIdCallback(
220      NotifyCallback callback, boolean initialNotify) {
221    int uid = DriverStationDataJNI.registerAllianceStationIdCallback(callback, initialNotify);
222    return new CallbackStore(uid, DriverStationDataJNI::cancelAllianceStationIdCallback);
223  }
224
225  /**
226   * Get the alliance station ID (color + number).
227   *
228   * @return the alliance station color and number
229   */
230  public static AllianceStationID getAllianceStationId() {
231    switch (DriverStationDataJNI.getAllianceStationId()) {
232      case 0:
233        return AllianceStationID.Red1;
234      case 1:
235        return AllianceStationID.Red2;
236      case 2:
237        return AllianceStationID.Red3;
238      case 3:
239        return AllianceStationID.Blue1;
240      case 4:
241        return AllianceStationID.Blue2;
242      case 5:
243        return AllianceStationID.Blue3;
244      default:
245        return null;
246    }
247  }
248
249  /**
250   * Change the alliance station.
251   *
252   * @param allianceStationId the new alliance station
253   */
254  public static void setAllianceStationId(AllianceStationID allianceStationId) {
255    int allianceStation;
256    switch (allianceStationId) {
257      case Red1:
258        allianceStation = 0;
259        break;
260      case Red2:
261        allianceStation = 1;
262        break;
263      case Red3:
264        allianceStation = 2;
265        break;
266      case Blue1:
267        allianceStation = 3;
268        break;
269      case Blue2:
270        allianceStation = 4;
271        break;
272      case Blue3:
273        allianceStation = 5;
274        break;
275      default:
276        return;
277    }
278    DriverStationDataJNI.setAllianceStationId(allianceStation);
279  }
280
281  /**
282   * Register a callback on match time.
283   *
284   * @param callback the callback that will be called whenever match time changes
285   * @param initialNotify if true, the callback will be run on the initial value
286   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
287   *     this object so GC doesn't cancel the callback.
288   */
289  public static CallbackStore registerMatchTimeCallback(
290      NotifyCallback callback, boolean initialNotify) {
291    int uid = DriverStationDataJNI.registerMatchTimeCallback(callback, initialNotify);
292    return new CallbackStore(uid, DriverStationDataJNI::cancelMatchTimeCallback);
293  }
294
295  /**
296   * Get the current value of the match timer.
297   *
298   * @return the current match time
299   */
300  public static double getMatchTime() {
301    return DriverStationDataJNI.getMatchTime();
302  }
303
304  /**
305   * Sets the match timer.
306   *
307   * @param matchTime the new match time
308   */
309  public static void setMatchTime(double matchTime) {
310    DriverStationDataJNI.setMatchTime(matchTime);
311  }
312
313  /** Updates DriverStation data so that new values are visible to the user program. */
314  public static void notifyNewData() {
315    int handle = WPIUtilJNI.createEvent(false, false);
316    DriverStationJNI.provideNewDataEventHandle(handle);
317    DriverStationDataJNI.notifyNewData();
318    try {
319      WPIUtilJNI.waitForObject(handle);
320    } catch (InterruptedException e) {
321      e.printStackTrace();
322    }
323    DriverStationJNI.removeNewDataEventHandle(handle);
324    WPIUtilJNI.destroyEvent(handle);
325    DriverStation.refreshData();
326  }
327
328  /**
329   * Sets suppression of DriverStation.reportError and reportWarning messages.
330   *
331   * @param shouldSend If false then messages will be suppressed.
332   */
333  public static void setSendError(boolean shouldSend) {
334    DriverStationDataJNI.setSendError(shouldSend);
335  }
336
337  /**
338   * Sets suppression of DriverStation.sendConsoleLine messages.
339   *
340   * @param shouldSend If false then messages will be suppressed.
341   */
342  public static void setSendConsoleLine(boolean shouldSend) {
343    DriverStationDataJNI.setSendConsoleLine(shouldSend);
344  }
345
346  /**
347   * Gets the joystick outputs.
348   *
349   * @param stick The joystick number
350   * @return The joystick outputs
351   */
352  public static long getJoystickOutputs(int stick) {
353    return DriverStationDataJNI.getJoystickOutputs(stick);
354  }
355
356  /**
357   * Gets the joystick rumble.
358   *
359   * @param stick The joystick number
360   * @param rumbleNum Rumble to get (0=left, 1=right)
361   * @return The joystick rumble value
362   */
363  public static int getJoystickRumble(int stick, int rumbleNum) {
364    return DriverStationDataJNI.getJoystickRumble(stick, rumbleNum);
365  }
366
367  /**
368   * Sets the state of one joystick button. Button indexes begin at 1.
369   *
370   * @param stick The joystick number
371   * @param button The button index, beginning at 1
372   * @param state The state of the joystick button
373   */
374  public static void setJoystickButton(int stick, int button, boolean state) {
375    DriverStationDataJNI.setJoystickButton(stick, button, state);
376  }
377
378  /**
379   * Gets the value of the axis on a joystick.
380   *
381   * @param stick The joystick number
382   * @param axis The analog axis number
383   * @param value The value of the axis on the joystick
384   */
385  public static void setJoystickAxis(int stick, int axis, double value) {
386    DriverStationDataJNI.setJoystickAxis(stick, axis, value);
387  }
388
389  /**
390   * Gets the state of a POV on a joystick.
391   *
392   * @param stick The joystick number
393   * @param pov The POV number
394   * @param value the angle of the POV in degrees, or -1 for not pressed
395   */
396  public static void setJoystickPOV(int stick, int pov, int value) {
397    DriverStationDataJNI.setJoystickPOV(stick, pov, value);
398  }
399
400  /**
401   * Sets the state of all the buttons on a joystick.
402   *
403   * @param stick The joystick number
404   * @param buttons The bitmap state of the buttons on the joystick
405   */
406  public static void setJoystickButtons(int stick, int buttons) {
407    DriverStationDataJNI.setJoystickButtonsValue(stick, buttons);
408  }
409
410  /**
411   * Sets the number of axes for a joystick.
412   *
413   * @param stick The joystick number
414   * @param count The number of axes on the indicated joystick
415   */
416  public static void setJoystickAxisCount(int stick, int count) {
417    DriverStationDataJNI.setJoystickAxisCount(stick, count);
418  }
419
420  /**
421   * Sets the number of POVs for a joystick.
422   *
423   * @param stick The joystick number
424   * @param count The number of POVs on the indicated joystick
425   */
426  public static void setJoystickPOVCount(int stick, int count) {
427    DriverStationDataJNI.setJoystickPOVCount(stick, count);
428  }
429
430  /**
431   * Sets the number of buttons for a joystick.
432   *
433   * @param stick The joystick number
434   * @param count The number of buttons on the indicated joystick
435   */
436  public static void setJoystickButtonCount(int stick, int count) {
437    DriverStationDataJNI.setJoystickButtonCount(stick, count);
438  }
439
440  /**
441   * Sets the value of isXbox for a joystick.
442   *
443   * @param stick The joystick number
444   * @param isXbox The value of isXbox
445   */
446  public static void setJoystickIsXbox(int stick, boolean isXbox) {
447    DriverStationDataJNI.setJoystickIsXbox(stick, isXbox);
448  }
449
450  /**
451   * Sets the value of type for a joystick.
452   *
453   * @param stick The joystick number
454   * @param type The value of type
455   */
456  public static void setJoystickType(int stick, int type) {
457    DriverStationDataJNI.setJoystickType(stick, type);
458  }
459
460  /**
461   * Sets the name of a joystick.
462   *
463   * @param stick The joystick number
464   * @param name The value of name
465   */
466  public static void setJoystickName(int stick, String name) {
467    DriverStationDataJNI.setJoystickName(stick, name);
468  }
469
470  /**
471   * Sets the types of Axes for a joystick.
472   *
473   * @param stick The joystick number
474   * @param axis The target axis
475   * @param type The type of axis
476   */
477  public static void setJoystickAxisType(int stick, int axis, int type) {
478    DriverStationDataJNI.setJoystickAxisType(stick, axis, type);
479  }
480
481  /**
482   * Sets the game specific message.
483   *
484   * @param message the game specific message
485   */
486  public static void setGameSpecificMessage(String message) {
487    DriverStationDataJNI.setGameSpecificMessage(message);
488  }
489
490  /**
491   * Sets the event name.
492   *
493   * @param name the event name
494   */
495  public static void setEventName(String name) {
496    DriverStationDataJNI.setEventName(name);
497  }
498
499  /**
500   * Sets the match type.
501   *
502   * @param type the match type
503   */
504  public static void setMatchType(DriverStation.MatchType type) {
505    int matchType;
506    switch (type) {
507      case Practice:
508        matchType = 1;
509        break;
510      case Qualification:
511        matchType = 2;
512        break;
513      case Elimination:
514        matchType = 3;
515        break;
516      case None:
517        matchType = 0;
518        break;
519      default:
520        return;
521    }
522    DriverStationDataJNI.setMatchType(matchType);
523  }
524
525  /**
526   * Sets the match number.
527   *
528   * @param matchNumber the match number
529   */
530  public static void setMatchNumber(int matchNumber) {
531    DriverStationDataJNI.setMatchNumber(matchNumber);
532  }
533
534  /**
535   * Sets the replay number.
536   *
537   * @param replayNumber the replay number
538   */
539  public static void setReplayNumber(int replayNumber) {
540    DriverStationDataJNI.setReplayNumber(replayNumber);
541  }
542
543  /** Reset all simulation data for the Driver Station. */
544  public static void resetData() {
545    DriverStationDataJNI.resetData();
546  }
547}