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