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 007import static edu.wpi.first.units.Units.Amps; 008import static edu.wpi.first.units.Units.Celsius; 009import static edu.wpi.first.units.Units.Microseconds; 010import static edu.wpi.first.units.Units.Volts; 011 012import edu.wpi.first.hal.HAL; 013import edu.wpi.first.hal.HALUtil; 014import edu.wpi.first.hal.LEDJNI; 015import edu.wpi.first.hal.PowerJNI; 016import edu.wpi.first.hal.can.CANJNI; 017import edu.wpi.first.hal.can.CANStatus; 018import edu.wpi.first.units.measure.Current; 019import edu.wpi.first.units.measure.Temperature; 020import edu.wpi.first.units.measure.Time; 021import edu.wpi.first.units.measure.Voltage; 022import java.util.function.LongSupplier; 023 024/** Contains functions for roboRIO functionality. */ 025public final class RobotController { 026 private static LongSupplier m_timeSource = RobotController::getFPGATime; 027 028 private RobotController() { 029 throw new UnsupportedOperationException("This is a utility class!"); 030 } 031 032 /** 033 * Return the FPGA Version number. For now, expect this to be the current year. 034 * 035 * @return FPGA Version number. 036 */ 037 public static int getFPGAVersion() { 038 return HALUtil.getFPGAVersion(); 039 } 040 041 /** 042 * Return the FPGA Revision number. The format of the revision is 3 numbers. The 12 most 043 * significant bits are the Major Revision. the next 8 bits are the Minor Revision. The 12 least 044 * significant bits are the Build Number. 045 * 046 * @return FPGA Revision number. 047 */ 048 public static long getFPGARevision() { 049 return HALUtil.getFPGARevision(); 050 } 051 052 /** 053 * Return the serial number of the roboRIO. 054 * 055 * @return The serial number of the roboRIO. 056 */ 057 public static String getSerialNumber() { 058 return HALUtil.getSerialNumber(); 059 } 060 061 /** 062 * Return the comments from the roboRIO web interface. 063 * 064 * <p>The comments string is cached after the first call to this function on the RoboRIO - restart 065 * the robot code to reload the comments string after changing it in the web interface. 066 * 067 * @return the comments from the roboRIO web interface. 068 */ 069 public static String getComments() { 070 return HALUtil.getComments(); 071 } 072 073 /** 074 * Returns the team number configured for the robot controller. 075 * 076 * @return team number, or 0 if not found. 077 */ 078 public static int getTeamNumber() { 079 return HALUtil.getTeamNumber(); 080 } 081 082 /** 083 * Sets a new source to provide the clock time in microseconds. Changing this affects the return 084 * value of {@code getTime} in Java. 085 * 086 * @param supplier Function to return the time in microseconds. 087 */ 088 public static void setTimeSource(LongSupplier supplier) { 089 m_timeSource = supplier; 090 } 091 092 /** 093 * Read the microsecond timestamp. By default, the time is based on the FPGA hardware clock in 094 * microseconds since the FPGA started. However, the return value of this method may be modified 095 * to use any time base, including non-monotonic and non-continuous time bases. 096 * 097 * @return The current time in microseconds. 098 */ 099 public static long getTime() { 100 return m_timeSource.getAsLong(); 101 } 102 103 /** 104 * Read the microsecond timestamp. By default, the time is based on the FPGA hardware clock in 105 * microseconds since the FPGA started. However, the return value of this method may be modified 106 * to use any time base, including non-monotonic and non-continuous time bases. 107 * 108 * @return The current time in a measure. 109 */ 110 public static Time getMeasureTime() { 111 return Microseconds.of(m_timeSource.getAsLong()); 112 } 113 114 /** 115 * Read the microsecond timer from the FPGA. 116 * 117 * @return The current time in microseconds according to the FPGA. 118 */ 119 public static long getFPGATime() { 120 return HALUtil.getFPGATime(); 121 } 122 123 /** 124 * Read the microsecond timer in a measure from the FPGA. 125 * 126 * @return The current time according to the FPGA in a measure. 127 */ 128 public static Time getMeasureFPGATime() { 129 return Microseconds.of(HALUtil.getFPGATime()); 130 } 131 132 /** 133 * Get the state of the "USER" button on the roboRIO. 134 * 135 * <p>Warning: the User Button is used to stop user programs from automatically loading if it is 136 * held for more then 5 seconds. Because of this, it's not recommended to be used by teams for any 137 * other purpose. 138 * 139 * @return true if the button is currently pressed down 140 */ 141 public static boolean getUserButton() { 142 return HALUtil.getFPGAButton(); 143 } 144 145 /** 146 * Read the battery voltage. 147 * 148 * @return The battery voltage in Volts. 149 */ 150 public static double getBatteryVoltage() { 151 return PowerJNI.getVinVoltage(); 152 } 153 154 /** 155 * Read the battery voltage in a measure. 156 * 157 * @return The battery voltage in a measure. 158 */ 159 public static Voltage getMeasureBatteryVoltage() { 160 return Volts.of(PowerJNI.getVinVoltage()); 161 } 162 163 /** 164 * Gets a value indicating whether the FPGA outputs are enabled. The outputs may be disabled if 165 * the robot is disabled or e-stopped, the watchdog has expired, or if the roboRIO browns out. 166 * 167 * @return True if the FPGA outputs are enabled. 168 */ 169 public static boolean isSysActive() { 170 return HAL.getSystemActive(); 171 } 172 173 /** 174 * Check if the system is browned out. 175 * 176 * @return True if the system is browned out 177 */ 178 public static boolean isBrownedOut() { 179 return HAL.getBrownedOut(); 180 } 181 182 /** 183 * Gets the number of times the system has been disabled due to communication errors with the 184 * Driver Station. 185 * 186 * @return number of disables due to communication errors. 187 */ 188 public static int getCommsDisableCount() { 189 return HAL.getCommsDisableCount(); 190 } 191 192 /** 193 * Gets the current state of the Robot Signal Light (RSL). 194 * 195 * @return The current state of the RSL- true if on, false if off 196 */ 197 public static boolean getRSLState() { 198 return HAL.getRSLState(); 199 } 200 201 /** 202 * Gets if the system time is valid. 203 * 204 * @return True if the system time is valid, false otherwise 205 */ 206 public static boolean isSystemTimeValid() { 207 return HAL.getSystemTimeValid(); 208 } 209 210 /** 211 * Get the input voltage to the robot controller. 212 * 213 * @return The controller input voltage value in Volts 214 */ 215 public static double getInputVoltage() { 216 return PowerJNI.getVinVoltage(); 217 } 218 219 /** 220 * Get the input voltage to the robot controller in a measure. 221 * 222 * @return The controller input voltage value in a measure. 223 */ 224 public static Voltage getMeasureInputVoltage() { 225 return Volts.of(PowerJNI.getVinVoltage()); 226 } 227 228 /** 229 * Get the input current to the robot controller. 230 * 231 * @return The controller input current value in Amps 232 */ 233 public static double getInputCurrent() { 234 return PowerJNI.getVinCurrent(); 235 } 236 237 /** 238 * Get the input current to the robot controller in a measure. 239 * 240 * @return The controller input current value in a measure. 241 */ 242 public static Current getMeasureInputCurrent() { 243 return Amps.of(PowerJNI.getVinCurrent()); 244 } 245 246 /** 247 * Get the voltage of the 3.3V rail. 248 * 249 * @return The controller 3.3V rail voltage value in Volts 250 */ 251 public static double getVoltage3V3() { 252 return PowerJNI.getUserVoltage3V3(); 253 } 254 255 /** 256 * Get the voltage in a measure of the 3.3V rail. 257 * 258 * @return The controller 3.3V rail voltage value in a measure. 259 */ 260 public static Voltage getMeasureVoltage3V3() { 261 return Volts.of(PowerJNI.getUserVoltage3V3()); 262 } 263 264 /** 265 * Get the current output of the 3.3V rail. 266 * 267 * @return The controller 3.3V rail output current value in Amps 268 */ 269 public static double getCurrent3V3() { 270 return PowerJNI.getUserCurrent3V3(); 271 } 272 273 /** 274 * Get the current output in a measure of the 3.3V rail. 275 * 276 * @return The controller 3.3V rail output current value in a measure. 277 */ 278 public static Current getMeasureCurrent3V3() { 279 return Amps.of(PowerJNI.getUserCurrent3V3()); 280 } 281 282 /** 283 * Enables or disables the 3.3V rail. 284 * 285 * @param enabled whether to enable the 3.3V rail. 286 */ 287 public static void setEnabled3V3(boolean enabled) { 288 PowerJNI.setUserEnabled3V3(enabled); 289 } 290 291 /** 292 * Get the enabled state of the 3.3V rail. The rail may be disabled due to a controller brownout, 293 * a short circuit on the rail, or controller over-voltage. 294 * 295 * @return The controller 3.3V rail enabled value 296 */ 297 public static boolean getEnabled3V3() { 298 return PowerJNI.getUserActive3V3(); 299 } 300 301 /** 302 * Get the count of the total current faults on the 3.3V rail since the code started. 303 * 304 * @return The number of faults 305 */ 306 public static int getFaultCount3V3() { 307 return PowerJNI.getUserCurrentFaults3V3(); 308 } 309 310 /** 311 * Get the voltage of the 5V rail. 312 * 313 * @return The controller 5V rail voltage value in Volts 314 */ 315 public static double getVoltage5V() { 316 return PowerJNI.getUserVoltage5V(); 317 } 318 319 /** 320 * Get the voltage in a measure of the 5V rail. 321 * 322 * @return The controller 5V rail voltage value in a measure. 323 */ 324 public static Voltage getMeasureVoltage5V() { 325 return Volts.of(PowerJNI.getUserVoltage5V()); 326 } 327 328 /** 329 * Get the current output of the 5V rail. 330 * 331 * @return The controller 5V rail output current value in Amps 332 */ 333 public static double getCurrent5V() { 334 return PowerJNI.getUserCurrent5V(); 335 } 336 337 /** 338 * Get the current output in a measure of the 5V rail. 339 * 340 * @return The controller 5V rail output current value in a measure. 341 */ 342 public static Current getMeasureCurrent5V() { 343 return Amps.of(PowerJNI.getUserCurrent5V()); 344 } 345 346 /** 347 * Enables or disables the 5V rail. 348 * 349 * @param enabled whether to enable the 5V rail. 350 */ 351 public static void setEnabled5V(boolean enabled) { 352 PowerJNI.setUserEnabled5V(enabled); 353 } 354 355 /** 356 * Get the enabled state of the 5V rail. The rail may be disabled due to a controller brownout, a 357 * short circuit on the rail, or controller over-voltage. 358 * 359 * @return The controller 5V rail enabled value 360 */ 361 public static boolean getEnabled5V() { 362 return PowerJNI.getUserActive5V(); 363 } 364 365 /** 366 * Get the count of the total current faults on the 5V rail since the code started. 367 * 368 * @return The number of faults 369 */ 370 public static int getFaultCount5V() { 371 return PowerJNI.getUserCurrentFaults5V(); 372 } 373 374 /** 375 * Get the voltage of the 6V rail. 376 * 377 * @return The controller 6V rail voltage value in Volts 378 */ 379 public static double getVoltage6V() { 380 return PowerJNI.getUserVoltage6V(); 381 } 382 383 /** 384 * Get the voltage in a measure of the 6V rail. 385 * 386 * @return The controller 6V rail voltage value in a measure. 387 */ 388 public static Voltage getMeasureVoltage6V() { 389 return Volts.of(PowerJNI.getUserVoltage6V()); 390 } 391 392 /** 393 * Get the current output of the 6V rail. 394 * 395 * @return The controller 6V rail output current value in Amps 396 */ 397 public static double getCurrent6V() { 398 return PowerJNI.getUserCurrent6V(); 399 } 400 401 /** 402 * Get the current output in a measure of the 6V rail. 403 * 404 * @return The controller 6V rail output current value in a measure. 405 */ 406 public static Current getMeasureCurrent6V() { 407 return Amps.of(PowerJNI.getUserCurrent6V()); 408 } 409 410 /** 411 * Enables or disables the 6V rail. 412 * 413 * @param enabled whether to enable the 6V rail. 414 */ 415 public static void setEnabled6V(boolean enabled) { 416 PowerJNI.setUserEnabled6V(enabled); 417 } 418 419 /** 420 * Get the enabled state of the 6V rail. The rail may be disabled due to a controller brownout, a 421 * short circuit on the rail, or controller over-voltage. 422 * 423 * @return The controller 6V rail enabled value 424 */ 425 public static boolean getEnabled6V() { 426 return PowerJNI.getUserActive6V(); 427 } 428 429 /** 430 * Get the count of the total current faults on the 6V rail since the code started. 431 * 432 * @return The number of faults 433 */ 434 public static int getFaultCount6V() { 435 return PowerJNI.getUserCurrentFaults6V(); 436 } 437 438 /** Reset the overcurrent fault counters for all user rails to 0. */ 439 public static void resetRailFaultCounts() { 440 PowerJNI.resetUserCurrentFaults(); 441 } 442 443 /** 444 * Get the current brownout voltage setting. 445 * 446 * @return The brownout voltage 447 */ 448 public static double getBrownoutVoltage() { 449 return PowerJNI.getBrownoutVoltage(); 450 } 451 452 /** 453 * Get the current brownout voltage setting in a measure. 454 * 455 * @return The brownout voltage in a measure. 456 */ 457 public static Voltage getMeasureBrownoutVoltage() { 458 return Volts.of(PowerJNI.getBrownoutVoltage()); 459 } 460 461 /** 462 * Set the voltage the roboRIO will brownout and disable all outputs. 463 * 464 * <p>Note that this only does anything on the roboRIO 2. On the roboRIO it is a no-op. 465 * 466 * @param brownoutVoltage The brownout voltage 467 */ 468 public static void setBrownoutVoltage(double brownoutVoltage) { 469 PowerJNI.setBrownoutVoltage(brownoutVoltage); 470 } 471 472 /** 473 * Set the voltage in a measure the roboRIO will brownout and disable all outputs. 474 * 475 * <p>Note that this only does anything on the roboRIO 2. On the roboRIO it is a no-op. 476 * 477 * @param brownoutVoltage The brownout voltage in a measure 478 */ 479 public static void setBrownoutVoltage(Voltage brownoutVoltage) { 480 PowerJNI.setBrownoutVoltage(brownoutVoltage.baseUnitMagnitude()); 481 } 482 483 /** 484 * Get the current CPU temperature in degrees Celsius. 485 * 486 * @return current CPU temperature in degrees Celsius 487 */ 488 public static double getCPUTemp() { 489 return PowerJNI.getCPUTemp(); 490 } 491 492 /** 493 * Get the current CPU temperature in a measure. 494 * 495 * @return current CPU temperature in a measure. 496 */ 497 public static Temperature getMeasureCPUTemp() { 498 return Celsius.of(PowerJNI.getCPUTemp()); 499 } 500 501 /** State for the radio led. */ 502 public enum RadioLEDState { 503 /** Off. */ 504 kOff(LEDJNI.RADIO_LED_STATE_OFF), 505 /** Green. */ 506 kGreen(LEDJNI.RADIO_LED_STATE_GREEN), 507 /** Red. */ 508 kRed(LEDJNI.RADIO_LED_STATE_RED), 509 /** Orange. */ 510 kOrange(LEDJNI.RADIO_LED_STATE_ORANGE); 511 512 /** The native value for this state. */ 513 public final int value; 514 515 RadioLEDState(int value) { 516 this.value = value; 517 } 518 519 /** 520 * Gets a state from an int value. 521 * 522 * @param value int value 523 * @return state 524 */ 525 public static RadioLEDState fromValue(int value) { 526 return switch (value) { 527 case LEDJNI.RADIO_LED_STATE_OFF -> RadioLEDState.kOff; 528 case LEDJNI.RADIO_LED_STATE_GREEN -> RadioLEDState.kGreen; 529 case LEDJNI.RADIO_LED_STATE_RED -> RadioLEDState.kRed; 530 case LEDJNI.RADIO_LED_STATE_ORANGE -> RadioLEDState.kOrange; 531 default -> RadioLEDState.kOff; 532 }; 533 } 534 } 535 536 /** 537 * Set the state of the "Radio" LED. On the RoboRIO, this writes to sysfs, so this function should 538 * not be called multiple times per loop cycle to avoid overruns. 539 * 540 * @param state The state to set the LED to. 541 */ 542 public static void setRadioLEDState(RadioLEDState state) { 543 LEDJNI.setRadioLEDState(state.value); 544 } 545 546 /** 547 * Get the state of the "Radio" LED. On the RoboRIO, this reads from sysfs, so this function 548 * should not be called multiple times per loop cycle to avoid overruns. 549 * 550 * @return The state of the LED. 551 */ 552 public static RadioLEDState getRadioLEDState() { 553 return RadioLEDState.fromValue(LEDJNI.getRadioLEDState()); 554 } 555 556 /** 557 * Get the current status of the CAN bus. 558 * 559 * @return The status of the CAN bus 560 */ 561 public static CANStatus getCANStatus() { 562 CANStatus status = new CANStatus(); 563 CANJNI.getCANStatus(status); 564 return status; 565 } 566}