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