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.PowerJNI;
015import edu.wpi.first.hal.can.CANJNI;
016import edu.wpi.first.hal.can.CANStatus;
017import edu.wpi.first.units.measure.Current;
018import edu.wpi.first.units.measure.Temperature;
019import edu.wpi.first.units.measure.Time;
020import edu.wpi.first.units.measure.Voltage;
021import java.util.function.LongSupplier;
022
023/** Contains functions for roboRIO functionality. */
024public final class RobotController {
025  private static LongSupplier m_timeSource = RobotController::getFPGATime;
026
027  private RobotController() {
028    throw new UnsupportedOperationException("This is a utility class!");
029  }
030
031  /**
032   * Return the FPGA Version number. For now, expect this to be the current year.
033   *
034   * @return FPGA Version number.
035   */
036  public static int getFPGAVersion() {
037    return HALUtil.getFPGAVersion();
038  }
039
040  /**
041   * Return the FPGA Revision number. The format of the revision is 3 numbers. The 12 most
042   * significant bits are the Major Revision. the next 8 bits are the Minor Revision. The 12 least
043   * significant bits are the Build Number.
044   *
045   * @return FPGA Revision number.
046   */
047  public static long getFPGARevision() {
048    return HALUtil.getFPGARevision();
049  }
050
051  /**
052   * Return the serial number of the roboRIO.
053   *
054   * @return The serial number of the roboRIO.
055   */
056  public static String getSerialNumber() {
057    return HALUtil.getSerialNumber();
058  }
059
060  /**
061   * Return the comments from the roboRIO web interface.
062   *
063   * <p>The comments string is cached after the first call to this function on the RoboRIO - restart
064   * the robot code to reload the comments string after changing it in the web interface.
065   *
066   * @return the comments from the roboRIO web interface.
067   */
068  public static String getComments() {
069    return HALUtil.getComments();
070  }
071
072  /**
073   * Returns the team number configured for the robot controller.
074   *
075   * @return team number, or 0 if not found.
076   */
077  public static int getTeamNumber() {
078    return HALUtil.getTeamNumber();
079  }
080
081  /**
082   * Sets a new source to provide the clock time in microseconds. Changing this affects the return
083   * value of {@code getTime} in Java.
084   *
085   * @param supplier Function to return the time in microseconds.
086   */
087  public static void setTimeSource(LongSupplier supplier) {
088    m_timeSource = supplier;
089  }
090
091  /**
092   * Read the microsecond timestamp. By default, the time is based on the FPGA hardware clock in
093   * microseconds since the FPGA started. However, the return value of this method may be modified
094   * to use any time base, including non-monotonic and non-continuous time bases.
095   *
096   * @return The current time in microseconds.
097   */
098  public static long getTime() {
099    return m_timeSource.getAsLong();
100  }
101
102  /**
103   * Read the microsecond timestamp. By default, the time is based on the FPGA hardware clock in
104   * microseconds since the FPGA started. However, the return value of this method may be modified
105   * to use any time base, including non-monotonic and non-continuous time bases.
106   *
107   * @return The current time in a measure.
108   */
109  public static Time getMeasureTime() {
110    return Microseconds.of(m_timeSource.getAsLong());
111  }
112
113  /**
114   * Read the microsecond timer from the FPGA.
115   *
116   * @return The current time in microseconds according to the FPGA.
117   */
118  public static long getFPGATime() {
119    return HALUtil.getFPGATime();
120  }
121
122  /**
123   * Read the microsecond timer in a measure from the FPGA.
124   *
125   * @return The current time according to the FPGA in a measure.
126   */
127  public static Time getMeasureFPGATime() {
128    return Microseconds.of(HALUtil.getFPGATime());
129  }
130
131  /**
132   * Read the battery voltage.
133   *
134   * @return The battery voltage in Volts.
135   */
136  public static double getBatteryVoltage() {
137    return PowerJNI.getVinVoltage();
138  }
139
140  /**
141   * Read the battery voltage in a measure.
142   *
143   * @return The battery voltage in a measure.
144   */
145  public static Voltage getMeasureBatteryVoltage() {
146    return Volts.of(PowerJNI.getVinVoltage());
147  }
148
149  /**
150   * Gets a value indicating whether the FPGA outputs are enabled. The outputs may be disabled if
151   * the robot is disabled or e-stopped, the watchdog has expired, or if the roboRIO browns out.
152   *
153   * @return True if the FPGA outputs are enabled.
154   */
155  public static boolean isSysActive() {
156    return HAL.getSystemActive();
157  }
158
159  /**
160   * Check if the system is browned out.
161   *
162   * @return True if the system is browned out
163   */
164  public static boolean isBrownedOut() {
165    return HAL.getBrownedOut();
166  }
167
168  /**
169   * Gets the number of times the system has been disabled due to communication errors with the
170   * Driver Station.
171   *
172   * @return number of disables due to communication errors.
173   */
174  public static int getCommsDisableCount() {
175    return HAL.getCommsDisableCount();
176  }
177
178  /**
179   * Gets the current state of the Robot Signal Light (RSL).
180   *
181   * @return The current state of the RSL- true if on, false if off
182   */
183  public static boolean getRSLState() {
184    return HAL.getRSLState();
185  }
186
187  /**
188   * Gets if the system time is valid.
189   *
190   * @return True if the system time is valid, false otherwise
191   */
192  public static boolean isSystemTimeValid() {
193    return HAL.getSystemTimeValid();
194  }
195
196  /**
197   * Get the input voltage to the robot controller.
198   *
199   * @return The controller input voltage value in Volts
200   */
201  public static double getInputVoltage() {
202    return PowerJNI.getVinVoltage();
203  }
204
205  /**
206   * Get the input voltage to the robot controller in a measure.
207   *
208   * @return The controller input voltage value in a measure.
209   */
210  public static Voltage getMeasureInputVoltage() {
211    return Volts.of(PowerJNI.getVinVoltage());
212  }
213
214  /**
215   * Get the voltage of the 3.3V rail.
216   *
217   * @return The controller 3.3V rail voltage value in Volts
218   */
219  public static double getVoltage3V3() {
220    return PowerJNI.getUserVoltage3V3();
221  }
222
223  /**
224   * Get the voltage in a measure of the 3.3V rail.
225   *
226   * @return The controller 3.3V rail voltage value in a measure.
227   */
228  public static Voltage getMeasureVoltage3V3() {
229    return Volts.of(PowerJNI.getUserVoltage3V3());
230  }
231
232  /**
233   * Get the current output of the 3.3V rail.
234   *
235   * @return The controller 3.3V rail output current value in Amps
236   */
237  public static double getCurrent3V3() {
238    return PowerJNI.getUserCurrent3V3();
239  }
240
241  /**
242   * Get the current output in a measure of the 3.3V rail.
243   *
244   * @return The controller 3.3V rail output current value in a measure.
245   */
246  public static Current getMeasureCurrent3V3() {
247    return Amps.of(PowerJNI.getUserCurrent3V3());
248  }
249
250  /**
251   * Enables or disables the 3.3V rail.
252   *
253   * @param enabled whether to enable the 3.3V rail.
254   */
255  public static void setEnabled3V3(boolean enabled) {
256    PowerJNI.setUserEnabled3V3(enabled);
257  }
258
259  /**
260   * Get the enabled state of the 3.3V rail. The rail may be disabled due to a controller brownout,
261   * a short circuit on the rail, or controller over-voltage.
262   *
263   * @return The controller 3.3V rail enabled value
264   */
265  public static boolean getEnabled3V3() {
266    return PowerJNI.getUserActive3V3();
267  }
268
269  /**
270   * Get the count of the total current faults on the 3.3V rail since the code started.
271   *
272   * @return The number of faults
273   */
274  public static int getFaultCount3V3() {
275    return PowerJNI.getUserCurrentFaults3V3();
276  }
277
278  /** Reset the overcurrent fault counters for all user rails to 0. */
279  public static void resetRailFaultCounts() {
280    PowerJNI.resetUserCurrentFaults();
281  }
282
283  /**
284   * Get the current brownout voltage setting.
285   *
286   * @return The brownout voltage
287   */
288  public static double getBrownoutVoltage() {
289    return PowerJNI.getBrownoutVoltage();
290  }
291
292  /**
293   * Get the current brownout voltage setting in a measure.
294   *
295   * @return The brownout voltage in a measure.
296   */
297  public static Voltage getMeasureBrownoutVoltage() {
298    return Volts.of(PowerJNI.getBrownoutVoltage());
299  }
300
301  /**
302   * Set the voltage the roboRIO will brownout and disable all outputs.
303   *
304   * <p>Note that this only does anything on the roboRIO 2. On the roboRIO it is a no-op.
305   *
306   * @param brownoutVoltage The brownout voltage
307   */
308  public static void setBrownoutVoltage(double brownoutVoltage) {
309    PowerJNI.setBrownoutVoltage(brownoutVoltage);
310  }
311
312  /**
313   * Set the voltage in a measure the roboRIO will brownout and disable all outputs.
314   *
315   * <p>Note that this only does anything on the roboRIO 2. On the roboRIO it is a no-op.
316   *
317   * @param brownoutVoltage The brownout voltage in a measure
318   */
319  public static void setBrownoutVoltage(Voltage brownoutVoltage) {
320    PowerJNI.setBrownoutVoltage(brownoutVoltage.baseUnitMagnitude());
321  }
322
323  /**
324   * Get the current CPU temperature in degrees Celsius.
325   *
326   * @return current CPU temperature in degrees Celsius
327   */
328  public static double getCPUTemp() {
329    return PowerJNI.getCPUTemp();
330  }
331
332  /**
333   * Get the current CPU temperature in a measure.
334   *
335   * @return current CPU temperature in a measure.
336   */
337  public static Temperature getMeasureCPUTemp() {
338    return Celsius.of(PowerJNI.getCPUTemp());
339  }
340
341  /**
342   * Get the current status of the CAN bus.
343   *
344   * @param busId The bus ID
345   * @return The status of the CAN bus
346   */
347  public static CANStatus getCANStatus(int busId) {
348    CANStatus status = new CANStatus();
349    CANJNI.getCANStatus(busId, status);
350    return status;
351  }
352}