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 DriverStationJNI.kUnknownAllianceStation:
233        return AllianceStationID.Unknown;
234      case DriverStationJNI.kRed1AllianceStation:
235        return AllianceStationID.Red1;
236      case DriverStationJNI.kRed2AllianceStation:
237        return AllianceStationID.Red2;
238      case DriverStationJNI.kRed3AllianceStation:
239        return AllianceStationID.Red3;
240      case DriverStationJNI.kBlue1AllianceStation:
241        return AllianceStationID.Blue1;
242      case DriverStationJNI.kBlue2AllianceStation:
243        return AllianceStationID.Blue2;
244      case DriverStationJNI.kBlue3AllianceStation:
245        return AllianceStationID.Blue3;
246      default:
247        return AllianceStationID.Unknown;
248    }
249  }
250
251  /**
252   * Change the alliance station.
253   *
254   * @param allianceStationId the new alliance station
255   */
256  public static void setAllianceStationId(AllianceStationID allianceStationId) {
257    int allianceStation;
258    switch (allianceStationId) {
259      case Unknown:
260        allianceStation = DriverStationJNI.kUnknownAllianceStation;
261        break;
262      case Red1:
263        allianceStation = DriverStationJNI.kRed1AllianceStation;
264        break;
265      case Red2:
266        allianceStation = DriverStationJNI.kRed2AllianceStation;
267        break;
268      case Red3:
269        allianceStation = DriverStationJNI.kRed3AllianceStation;
270        break;
271      case Blue1:
272        allianceStation = DriverStationJNI.kBlue1AllianceStation;
273        break;
274      case Blue2:
275        allianceStation = DriverStationJNI.kBlue2AllianceStation;
276        break;
277      case Blue3:
278        allianceStation = DriverStationJNI.kBlue3AllianceStation;
279        break;
280      default:
281        return;
282    }
283    DriverStationDataJNI.setAllianceStationId(allianceStation);
284  }
285
286  /**
287   * Register a callback on match time.
288   *
289   * @param callback the callback that will be called whenever match time changes
290   * @param initialNotify if true, the callback will be run on the initial value
291   * @return the {@link CallbackStore} object associated with this callback. Save a reference to
292   *     this object so GC doesn't cancel the callback.
293   */
294  public static CallbackStore registerMatchTimeCallback(
295      NotifyCallback callback, boolean initialNotify) {
296    int uid = DriverStationDataJNI.registerMatchTimeCallback(callback, initialNotify);
297    return new CallbackStore(uid, DriverStationDataJNI::cancelMatchTimeCallback);
298  }
299
300  /**
301   * Get the current value of the match timer.
302   *
303   * @return the current match time
304   */
305  public static double getMatchTime() {
306    return DriverStationDataJNI.getMatchTime();
307  }
308
309  /**
310   * Sets the match timer.
311   *
312   * @param matchTime the new match time
313   */
314  public static void setMatchTime(double matchTime) {
315    DriverStationDataJNI.setMatchTime(matchTime);
316  }
317
318  /** Updates DriverStation data so that new values are visible to the user program. */
319  public static void notifyNewData() {
320    int handle = WPIUtilJNI.createEvent(false, false);
321    DriverStationJNI.provideNewDataEventHandle(handle);
322    DriverStationDataJNI.notifyNewData();
323    try {
324      WPIUtilJNI.waitForObject(handle);
325    } catch (InterruptedException e) {
326      e.printStackTrace();
327    }
328    DriverStationJNI.removeNewDataEventHandle(handle);
329    WPIUtilJNI.destroyEvent(handle);
330    DriverStation.refreshData();
331  }
332
333  /**
334   * Sets suppression of DriverStation.reportError and reportWarning messages.
335   *
336   * @param shouldSend If false then messages will be suppressed.
337   */
338  public static void setSendError(boolean shouldSend) {
339    DriverStationDataJNI.setSendError(shouldSend);
340  }
341
342  /**
343   * Sets suppression of DriverStation.sendConsoleLine messages.
344   *
345   * @param shouldSend If false then messages will be suppressed.
346   */
347  public static void setSendConsoleLine(boolean shouldSend) {
348    DriverStationDataJNI.setSendConsoleLine(shouldSend);
349  }
350
351  /**
352   * Gets the joystick outputs.
353   *
354   * @param stick The joystick number
355   * @return The joystick outputs
356   */
357  public static long getJoystickOutputs(int stick) {
358    return DriverStationDataJNI.getJoystickOutputs(stick);
359  }
360
361  /**
362   * Gets the joystick rumble.
363   *
364   * @param stick The joystick number
365   * @param rumbleNum Rumble to get (0=left, 1=right)
366   * @return The joystick rumble value
367   */
368  public static int getJoystickRumble(int stick, int rumbleNum) {
369    return DriverStationDataJNI.getJoystickRumble(stick, rumbleNum);
370  }
371
372  /**
373   * Sets the state of one joystick button. Button indexes begin at 1.
374   *
375   * @param stick The joystick number
376   * @param button The button index, beginning at 1
377   * @param state The state of the joystick button
378   */
379  public static void setJoystickButton(int stick, int button, boolean state) {
380    DriverStationDataJNI.setJoystickButton(stick, button, state);
381  }
382
383  /**
384   * Gets the value of the axis on a joystick.
385   *
386   * @param stick The joystick number
387   * @param axis The analog axis number
388   * @param value The value of the axis on the joystick
389   */
390  public static void setJoystickAxis(int stick, int axis, double value) {
391    DriverStationDataJNI.setJoystickAxis(stick, axis, value);
392  }
393
394  /**
395   * Gets the state of a POV on a joystick.
396   *
397   * @param stick The joystick number
398   * @param pov The POV number
399   * @param value the angle of the POV in degrees, or -1 for not pressed
400   */
401  public static void setJoystickPOV(int stick, int pov, int value) {
402    DriverStationDataJNI.setJoystickPOV(stick, pov, value);
403  }
404
405  /**
406   * Sets the state of all the buttons on a joystick.
407   *
408   * @param stick The joystick number
409   * @param buttons The bitmap state of the buttons on the joystick
410   */
411  public static void setJoystickButtons(int stick, int buttons) {
412    DriverStationDataJNI.setJoystickButtonsValue(stick, buttons);
413  }
414
415  /**
416   * Sets the number of axes for a joystick.
417   *
418   * @param stick The joystick number
419   * @param count The number of axes on the indicated joystick
420   */
421  public static void setJoystickAxisCount(int stick, int count) {
422    DriverStationDataJNI.setJoystickAxisCount(stick, count);
423  }
424
425  /**
426   * Sets the number of POVs for a joystick.
427   *
428   * @param stick The joystick number
429   * @param count The number of POVs on the indicated joystick
430   */
431  public static void setJoystickPOVCount(int stick, int count) {
432    DriverStationDataJNI.setJoystickPOVCount(stick, count);
433  }
434
435  /**
436   * Sets the number of buttons for a joystick.
437   *
438   * @param stick The joystick number
439   * @param count The number of buttons on the indicated joystick
440   */
441  public static void setJoystickButtonCount(int stick, int count) {
442    DriverStationDataJNI.setJoystickButtonCount(stick, count);
443  }
444
445  /**
446   * Sets the value of isXbox for a joystick.
447   *
448   * @param stick The joystick number
449   * @param isXbox The value of isXbox
450   */
451  public static void setJoystickIsXbox(int stick, boolean isXbox) {
452    DriverStationDataJNI.setJoystickIsXbox(stick, isXbox);
453  }
454
455  /**
456   * Sets the value of type for a joystick.
457   *
458   * @param stick The joystick number
459   * @param type The value of type
460   */
461  public static void setJoystickType(int stick, int type) {
462    DriverStationDataJNI.setJoystickType(stick, type);
463  }
464
465  /**
466   * Sets the name of a joystick.
467   *
468   * @param stick The joystick number
469   * @param name The value of name
470   */
471  public static void setJoystickName(int stick, String name) {
472    DriverStationDataJNI.setJoystickName(stick, name);
473  }
474
475  /**
476   * Sets the types of Axes for a joystick.
477   *
478   * @param stick The joystick number
479   * @param axis The target axis
480   * @param type The type of axis
481   */
482  public static void setJoystickAxisType(int stick, int axis, int type) {
483    DriverStationDataJNI.setJoystickAxisType(stick, axis, type);
484  }
485
486  /**
487   * Sets the game specific message.
488   *
489   * @param message the game specific message
490   */
491  public static void setGameSpecificMessage(String message) {
492    DriverStationDataJNI.setGameSpecificMessage(message);
493  }
494
495  /**
496   * Sets the event name.
497   *
498   * @param name the event name
499   */
500  public static void setEventName(String name) {
501    DriverStationDataJNI.setEventName(name);
502  }
503
504  /**
505   * Sets the match type.
506   *
507   * @param type the match type
508   */
509  public static void setMatchType(DriverStation.MatchType type) {
510    int matchType;
511    switch (type) {
512      case Practice:
513        matchType = 1;
514        break;
515      case Qualification:
516        matchType = 2;
517        break;
518      case Elimination:
519        matchType = 3;
520        break;
521      case None:
522        matchType = 0;
523        break;
524      default:
525        return;
526    }
527    DriverStationDataJNI.setMatchType(matchType);
528  }
529
530  /**
531   * Sets the match number.
532   *
533   * @param matchNumber the match number
534   */
535  public static void setMatchNumber(int matchNumber) {
536    DriverStationDataJNI.setMatchNumber(matchNumber);
537  }
538
539  /**
540   * Sets the replay number.
541   *
542   * @param replayNumber the replay number
543   */
544  public static void setReplayNumber(int replayNumber) {
545    DriverStationDataJNI.setReplayNumber(replayNumber);
546  }
547
548  /** Reset all simulation data for the Driver Station. */
549  public static void resetData() {
550    DriverStationDataJNI.resetData();
551  }
552}