2013-12-15 18:30:16 -05:00
|
|
|
/*----------------------------------------------------------------------------*/
|
2016-01-02 03:02:34 -08:00
|
|
|
/* Copyright (c) FIRST 2008-2016. All Rights Reserved. */
|
|
|
|
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
2013-12-15 18:30:16 -05:00
|
|
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
2016-01-02 03:02:34 -08:00
|
|
|
/* the project. */
|
2013-12-15 18:30:16 -05:00
|
|
|
/*----------------------------------------------------------------------------*/
|
2016-01-02 03:02:34 -08:00
|
|
|
|
2013-12-15 18:30:16 -05:00
|
|
|
package edu.wpi.first.wpilibj;
|
|
|
|
|
|
2014-01-06 10:12:21 -05:00
|
|
|
import java.nio.ByteBuffer;
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2014-01-06 10:12:21 -05:00
|
|
|
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
|
2014-08-06 11:29:15 -04:00
|
|
|
import edu.wpi.first.wpilibj.communication.HALAllianceStationID;
|
2016-05-20 12:07:40 -04:00
|
|
|
import edu.wpi.first.wpilibj.communication.HALControlWord;
|
2014-01-06 10:12:21 -05:00
|
|
|
import edu.wpi.first.wpilibj.hal.HALUtil;
|
2014-08-08 14:56:22 -04:00
|
|
|
import edu.wpi.first.wpilibj.hal.PowerJNI;
|
2013-12-15 18:30:16 -05:00
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Provide access to the network communication data to / from the Driver Station.
|
2013-12-15 18:30:16 -05:00
|
|
|
*/
|
2014-07-29 17:34:39 -04:00
|
|
|
public class DriverStation implements RobotState.Interface {
|
2013-12-15 18:30:16 -05:00
|
|
|
|
2015-06-25 15:07:55 -04:00
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Number of Joystick Ports.
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
|
|
|
|
public static final int kJoystickPorts = 6;
|
|
|
|
|
|
|
|
|
|
private class HALJoystickButtons {
|
2016-05-20 12:07:40 -04:00
|
|
|
public int m_buttons;
|
|
|
|
|
public byte m_count;
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* The robot alliance that the robot is a part of.
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
|
|
|
|
public enum Alliance {
|
|
|
|
|
Red, Blue, Invalid
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static final double JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL = 1.0;
|
|
|
|
|
private double m_nextMessageTime = 0.0;
|
|
|
|
|
|
|
|
|
|
private static class DriverStationTask implements Runnable {
|
|
|
|
|
|
|
|
|
|
private DriverStation m_ds;
|
|
|
|
|
|
|
|
|
|
DriverStationTask(DriverStation ds) {
|
|
|
|
|
m_ds = ds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void run() {
|
|
|
|
|
m_ds.task();
|
|
|
|
|
}
|
|
|
|
|
} /* DriverStationTask */
|
|
|
|
|
|
|
|
|
|
private static DriverStation instance = new DriverStation();
|
|
|
|
|
|
|
|
|
|
private short[][] m_joystickAxes =
|
|
|
|
|
new short[kJoystickPorts][FRCNetworkCommunicationsLibrary.kMaxJoystickAxes];
|
|
|
|
|
private short[][] m_joystickPOVs =
|
|
|
|
|
new short[kJoystickPorts][FRCNetworkCommunicationsLibrary.kMaxJoystickPOVs];
|
|
|
|
|
private HALJoystickButtons[] m_joystickButtons = new HALJoystickButtons[kJoystickPorts];
|
|
|
|
|
private int[] m_joystickIsXbox = new int[kJoystickPorts];
|
|
|
|
|
private int[] m_joystickType = new int[kJoystickPorts];
|
|
|
|
|
private String[] m_joystickName = new String[kJoystickPorts];
|
|
|
|
|
private int[][] m_joystickAxisType =
|
|
|
|
|
new int[kJoystickPorts][FRCNetworkCommunicationsLibrary.kMaxJoystickAxes];
|
|
|
|
|
|
|
|
|
|
private Thread m_thread;
|
|
|
|
|
private final Object m_dataSem;
|
2016-05-20 12:07:40 -04:00
|
|
|
private volatile boolean m_threadKeepAlive = true;
|
2015-06-25 15:07:55 -04:00
|
|
|
private boolean m_userInDisabled = false;
|
|
|
|
|
private boolean m_userInAutonomous = false;
|
|
|
|
|
private boolean m_userInTeleop = false;
|
|
|
|
|
private boolean m_userInTest = false;
|
|
|
|
|
private boolean m_newControlData;
|
2015-11-01 09:11:52 -08:00
|
|
|
private final long m_packetDataAvailableMutex;
|
|
|
|
|
private final long m_packetDataAvailableSem;
|
2015-06-25 15:07:55 -04:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets an instance of the DriverStation
|
|
|
|
|
*
|
|
|
|
|
* @return The DriverStation.
|
|
|
|
|
*/
|
|
|
|
|
public static DriverStation getInstance() {
|
|
|
|
|
return DriverStation.instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* DriverStation constructor.
|
|
|
|
|
*
|
2016-05-20 12:07:40 -04:00
|
|
|
* <p>The single DriverStation instance is created statically with the instance static member
|
|
|
|
|
* variable.
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
|
|
|
|
protected DriverStation() {
|
|
|
|
|
m_dataSem = new Object();
|
|
|
|
|
for (int i = 0; i < kJoystickPorts; i++) {
|
|
|
|
|
m_joystickButtons[i] = new HALJoystickButtons();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_packetDataAvailableMutex = HALUtil.initializeMutexNormal();
|
|
|
|
|
m_packetDataAvailableSem = HALUtil.initializeMultiWait();
|
|
|
|
|
FRCNetworkCommunicationsLibrary.setNewDataSem(m_packetDataAvailableSem);
|
|
|
|
|
|
|
|
|
|
m_thread = new Thread(new DriverStationTask(this), "FRCDriverStation");
|
|
|
|
|
m_thread.setPriority((Thread.NORM_PRIORITY + Thread.MAX_PRIORITY) / 2);
|
|
|
|
|
|
|
|
|
|
m_thread.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Kill the thread.
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
|
|
|
|
public void release() {
|
2016-05-20 12:07:40 -04:00
|
|
|
m_threadKeepAlive = false;
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Provides the service routine for the DS polling m_thread.
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
|
|
|
|
private void task() {
|
|
|
|
|
int safetyCounter = 0;
|
2016-05-20 12:07:40 -04:00
|
|
|
while (m_threadKeepAlive) {
|
2015-08-19 11:12:54 -04:00
|
|
|
HALUtil.takeMultiWait(m_packetDataAvailableSem, m_packetDataAvailableMutex);
|
2015-06-25 15:07:55 -04:00
|
|
|
synchronized (this) {
|
|
|
|
|
getData();
|
|
|
|
|
}
|
|
|
|
|
synchronized (m_dataSem) {
|
|
|
|
|
m_dataSem.notifyAll();
|
|
|
|
|
}
|
|
|
|
|
if (++safetyCounter >= 4) {
|
|
|
|
|
MotorSafetyHelper.checkMotors();
|
|
|
|
|
safetyCounter = 0;
|
|
|
|
|
}
|
|
|
|
|
if (m_userInDisabled) {
|
|
|
|
|
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramDisabled();
|
|
|
|
|
}
|
|
|
|
|
if (m_userInAutonomous) {
|
|
|
|
|
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramAutonomous();
|
|
|
|
|
}
|
|
|
|
|
if (m_userInTeleop) {
|
|
|
|
|
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramTeleop();
|
|
|
|
|
}
|
|
|
|
|
if (m_userInTest) {
|
|
|
|
|
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramTest();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Wait for new data from the driver station.
|
|
|
|
|
*/
|
|
|
|
|
public void waitForData() {
|
|
|
|
|
waitForData(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Wait for new data or for timeout, which ever comes first. If timeout is 0, wait for new data
|
|
|
|
|
* only.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @param timeout The maximum time in milliseconds to wait.
|
|
|
|
|
*/
|
|
|
|
|
public void waitForData(long timeout) {
|
|
|
|
|
synchronized (m_dataSem) {
|
|
|
|
|
try {
|
|
|
|
|
m_dataSem.wait(timeout);
|
|
|
|
|
} catch (InterruptedException ex) {
|
2016-05-20 12:07:40 -04:00
|
|
|
Thread.currentThread().interrupt();
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Copy data from the DS task for the user. If no new data exists, it will just be returned,
|
|
|
|
|
* otherwise the data will be copied from the DS polling loop.
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
|
|
|
|
protected synchronized void getData() {
|
|
|
|
|
|
|
|
|
|
// Get the status of all of the joysticks
|
|
|
|
|
for (byte stick = 0; stick < kJoystickPorts; stick++) {
|
|
|
|
|
m_joystickAxes[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickAxes(stick);
|
|
|
|
|
m_joystickPOVs[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickPOVs(stick);
|
|
|
|
|
ByteBuffer countBuffer = ByteBuffer.allocateDirect(1);
|
2016-05-20 12:07:40 -04:00
|
|
|
m_joystickButtons[stick].m_buttons =
|
|
|
|
|
FRCNetworkCommunicationsLibrary.HALGetJoystickButtons(stick, countBuffer);
|
|
|
|
|
m_joystickButtons[stick].m_count = countBuffer.get();
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_newControlData = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Read the battery voltage.
|
|
|
|
|
*
|
|
|
|
|
* @return The battery voltage in Volts.
|
|
|
|
|
*/
|
|
|
|
|
public double getBatteryVoltage() {
|
2015-11-01 09:11:52 -08:00
|
|
|
return PowerJNI.getVinVoltage();
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Reports errors related to unplugged joysticks Throttles the errors so that they don't overwhelm
|
|
|
|
|
* the DS.
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
|
|
|
|
private void reportJoystickUnpluggedError(String message) {
|
|
|
|
|
double currentTime = Timer.getFPGATimestamp();
|
|
|
|
|
if (currentTime > m_nextMessageTime) {
|
|
|
|
|
reportError(message, false);
|
|
|
|
|
m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-04 22:29:11 -08:00
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Reports errors related to unplugged joysticks Throttles the errors so that they don't overwhelm
|
|
|
|
|
* the DS.
|
2016-02-04 22:29:11 -08:00
|
|
|
*/
|
|
|
|
|
private void reportJoystickUnpluggedWarning(String message) {
|
|
|
|
|
double currentTime = Timer.getFPGATimestamp();
|
|
|
|
|
if (currentTime > m_nextMessageTime) {
|
|
|
|
|
reportWarning(message, false);
|
|
|
|
|
m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-25 15:07:55 -04:00
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Get the value of the axis on a joystick. This depends on the mapping of the joystick connected
|
|
|
|
|
* to the specified port.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @param stick The joystick to read.
|
2016-05-20 12:07:40 -04:00
|
|
|
* @param axis The analog axis value to read from the joystick.
|
2015-06-25 15:07:55 -04:00
|
|
|
* @return The value of the axis on the joystick.
|
|
|
|
|
*/
|
|
|
|
|
public synchronized double getStickAxis(int stick, int axis) {
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (axis < 0 || axis >= FRCNetworkCommunicationsLibrary.kMaxJoystickAxes) {
|
|
|
|
|
throw new RuntimeException("Joystick axis is out of range");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (axis >= m_joystickAxes[stick].length) {
|
2016-02-04 22:29:11 -08:00
|
|
|
reportJoystickUnpluggedWarning("Joystick axis " + axis + " on port " + stick
|
|
|
|
|
+ " not available, check if controller is plugged in");
|
2015-06-25 15:07:55 -04:00
|
|
|
return 0.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
byte value = (byte) m_joystickAxes[stick][axis];
|
|
|
|
|
|
|
|
|
|
if (value < 0) {
|
|
|
|
|
return value / 128.0;
|
|
|
|
|
} else {
|
|
|
|
|
return value / 127.0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Returns the number of axes on a given joystick port.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @param stick The joystick port number
|
|
|
|
|
* @return The number of axes on the indicated joystick
|
|
|
|
|
*/
|
|
|
|
|
public synchronized int getStickAxisCount(int stick) {
|
|
|
|
|
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m_joystickAxes[stick].length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the state of a POV on the joystick.
|
|
|
|
|
*
|
|
|
|
|
* @return the angle of the POV in degrees, or -1 if the POV is not pressed.
|
|
|
|
|
*/
|
|
|
|
|
public synchronized int getStickPOV(int stick, int pov) {
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pov < 0 || pov >= FRCNetworkCommunicationsLibrary.kMaxJoystickPOVs) {
|
|
|
|
|
throw new RuntimeException("Joystick POV is out of range");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pov >= m_joystickPOVs[stick].length) {
|
2016-02-04 22:29:11 -08:00
|
|
|
reportJoystickUnpluggedWarning("Joystick POV " + pov + " on port " + stick
|
|
|
|
|
+ " not available, check if controller is plugged in");
|
2015-06-25 15:07:55 -04:00
|
|
|
return -1;
|
2014-10-17 14:46:25 -04:00
|
|
|
}
|
|
|
|
|
|
2015-06-25 15:07:55 -04:00
|
|
|
return m_joystickPOVs[stick][pov];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Returns the number of POVs on a given joystick port.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @param stick The joystick port number
|
|
|
|
|
* @return The number of POVs on the indicated joystick
|
|
|
|
|
*/
|
|
|
|
|
public synchronized int getStickPOVCount(int stick) {
|
|
|
|
|
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m_joystickPOVs[stick].length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The state of the buttons on the joystick.
|
|
|
|
|
*
|
|
|
|
|
* @param stick The joystick to read.
|
|
|
|
|
* @return The state of the buttons on the joystick.
|
|
|
|
|
*/
|
|
|
|
|
public synchronized int getStickButtons(final int stick) {
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-3");
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-20 12:07:40 -04:00
|
|
|
return m_joystickButtons[stick].m_buttons;
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The state of one joystick button. Button indexes begin at 1.
|
|
|
|
|
*
|
2016-05-20 12:07:40 -04:00
|
|
|
* @param stick The joystick to read.
|
2015-06-25 15:07:55 -04:00
|
|
|
* @param button The button index, beginning at 1.
|
|
|
|
|
* @return The state of the joystick button.
|
|
|
|
|
*/
|
|
|
|
|
public synchronized boolean getStickButton(final int stick, byte button) {
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-3");
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|
2015-06-25 15:07:55 -04:00
|
|
|
|
|
|
|
|
|
2016-05-20 12:07:40 -04:00
|
|
|
if (button > m_joystickButtons[stick].m_count) {
|
2016-02-04 22:29:11 -08:00
|
|
|
reportJoystickUnpluggedWarning("Joystick Button " + button + " on port " + stick
|
|
|
|
|
+ " not available, check if controller is plugged in");
|
2015-06-25 15:07:55 -04:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (button <= 0) {
|
2016-02-04 22:29:11 -08:00
|
|
|
reportJoystickUnpluggedError("Button indexes begin at 1 in WPILib for C++ and Java");
|
2015-06-25 15:07:55 -04:00
|
|
|
return false;
|
|
|
|
|
}
|
2016-05-20 12:07:40 -04:00
|
|
|
return ((0x1 << (button - 1)) & m_joystickButtons[stick].m_buttons) != 0;
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets the number of buttons on a joystick.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @param stick The joystick port number
|
|
|
|
|
* @return The number of buttons on the indicated joystick
|
|
|
|
|
*/
|
|
|
|
|
public synchronized int getStickButtonCount(int stick) {
|
|
|
|
|
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2016-05-20 12:07:40 -04:00
|
|
|
return m_joystickButtons[stick].m_count;
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets the value of isXbox on a joystick.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @param stick The joystick port number
|
|
|
|
|
* @return A boolean that returns the value of isXbox
|
|
|
|
|
*/
|
|
|
|
|
public synchronized boolean getJoystickIsXbox(int stick) {
|
|
|
|
|
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
|
|
|
|
}
|
|
|
|
|
// TODO: Remove this when calling for descriptor on empty stick no longer
|
|
|
|
|
// crashes
|
2016-05-20 12:07:40 -04:00
|
|
|
if (1 > m_joystickButtons[stick].m_count && 1 > m_joystickAxes[stick].length) {
|
2016-02-04 22:29:11 -08:00
|
|
|
reportJoystickUnpluggedWarning("Joystick on port " + stick
|
|
|
|
|
+ " not available, check if controller is plugged in");
|
2015-06-25 15:07:55 -04:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
boolean retVal = false;
|
|
|
|
|
if (FRCNetworkCommunicationsLibrary.HALGetJoystickIsXbox((byte) stick) == 1) {
|
|
|
|
|
retVal = true;
|
|
|
|
|
}
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets the value of type on a joystick.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @param stick The joystick port number
|
|
|
|
|
* @return The value of type
|
|
|
|
|
*/
|
|
|
|
|
public synchronized int getJoystickType(int stick) {
|
|
|
|
|
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
|
|
|
|
}
|
|
|
|
|
// TODO: Remove this when calling for descriptor on empty stick no longer
|
|
|
|
|
// crashes
|
2016-05-20 12:07:40 -04:00
|
|
|
if (1 > m_joystickButtons[stick].m_count && 1 > m_joystickAxes[stick].length) {
|
2016-02-04 22:29:11 -08:00
|
|
|
reportJoystickUnpluggedWarning("Joystick on port " + stick
|
|
|
|
|
+ " not available, check if controller is plugged in");
|
2015-06-25 15:07:55 -04:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return FRCNetworkCommunicationsLibrary.HALGetJoystickType((byte) stick);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets the name of the joystick at a port.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @param stick The joystick port number
|
|
|
|
|
* @return The value of name
|
|
|
|
|
*/
|
|
|
|
|
public synchronized String getJoystickName(int stick) {
|
|
|
|
|
|
|
|
|
|
if (stick < 0 || stick >= kJoystickPorts) {
|
|
|
|
|
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
|
|
|
|
}
|
|
|
|
|
// TODO: Remove this when calling for descriptor on empty stick no longer
|
|
|
|
|
// crashes
|
2016-05-20 12:07:40 -04:00
|
|
|
if (1 > m_joystickButtons[stick].m_count && 1 > m_joystickAxes[stick].length) {
|
2016-02-04 22:29:11 -08:00
|
|
|
reportJoystickUnpluggedWarning("Joystick on port " + stick
|
|
|
|
|
+ " not available, check if controller is plugged in");
|
2015-06-25 15:07:55 -04:00
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
return FRCNetworkCommunicationsLibrary.HALGetJoystickName((byte) stick);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets a value indicating whether the Driver Station requires the robot to be enabled.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @return True if the robot is enabled, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isEnabled() {
|
|
|
|
|
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
|
|
|
|
return controlWord.getEnabled() && controlWord.getDSAttached();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets a value indicating whether the Driver Station requires the robot to be disabled.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @return True if the robot should be disabled, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isDisabled() {
|
|
|
|
|
return !isEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets a value indicating whether the Driver Station requires the robot to be running in
|
|
|
|
|
* autonomous mode.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @return True if autonomous mode should be enabled, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isAutonomous() {
|
|
|
|
|
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
|
|
|
|
return controlWord.getAutonomous();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets a value indicating whether the Driver Station requires the robot to be running in test
|
|
|
|
|
* mode.
|
|
|
|
|
*
|
2015-06-25 15:07:55 -04:00
|
|
|
* @return True if test mode should be enabled, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isTest() {
|
|
|
|
|
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
|
|
|
|
return controlWord.getTest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets a value indicating whether the Driver Station requires the robot to be running in
|
|
|
|
|
* operator-controlled mode.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
2016-05-20 12:07:40 -04:00
|
|
|
* @return True if operator-controlled mode should be enabled, false otherwise.
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
|
|
|
|
public boolean isOperatorControl() {
|
|
|
|
|
return !(isAutonomous() || isTest());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Gets a value indicating whether the FPGA outputs are enabled. The outputs may be disabled if
|
|
|
|
|
* the robot is disabled or e-stopped, the watdhog has expired, or if the roboRIO browns out.
|
2015-06-25 15:07:55 -04:00
|
|
|
*
|
|
|
|
|
* @return True if the FPGA outputs are enabled.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isSysActive() {
|
2015-11-01 09:11:52 -08:00
|
|
|
return FRCNetworkCommunicationsLibrary.HALGetSystemActive();
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if the system is browned out.
|
2016-05-20 12:07:40 -04:00
|
|
|
*
|
2015-06-25 15:07:55 -04:00
|
|
|
* @return True if the system is browned out
|
|
|
|
|
*/
|
|
|
|
|
public boolean isBrownedOut() {
|
2015-11-01 09:11:52 -08:00
|
|
|
return FRCNetworkCommunicationsLibrary.HALGetBrownedOut();
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Has a new control packet from the driver station arrived since the last time this function was
|
|
|
|
|
* called?
|
|
|
|
|
*
|
2015-06-25 15:07:55 -04:00
|
|
|
* @return True if the control data has been updated since the last call.
|
|
|
|
|
*/
|
|
|
|
|
public synchronized boolean isNewControlData() {
|
|
|
|
|
boolean result = m_newControlData;
|
|
|
|
|
m_newControlData = false;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Get the current alliance from the FMS.
|
|
|
|
|
*
|
2015-06-25 15:07:55 -04:00
|
|
|
* @return the current alliance
|
|
|
|
|
*/
|
|
|
|
|
public Alliance getAlliance() {
|
|
|
|
|
HALAllianceStationID allianceStationID =
|
|
|
|
|
FRCNetworkCommunicationsLibrary.HALGetAllianceStation();
|
|
|
|
|
if (allianceStationID == null) {
|
|
|
|
|
return Alliance.Invalid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (allianceStationID) {
|
|
|
|
|
case Red1:
|
|
|
|
|
case Red2:
|
|
|
|
|
case Red3:
|
|
|
|
|
return Alliance.Red;
|
|
|
|
|
|
|
|
|
|
case Blue1:
|
|
|
|
|
case Blue2:
|
|
|
|
|
case Blue3:
|
|
|
|
|
return Alliance.Blue;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return Alliance.Invalid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the location of the team's driver station controls.
|
|
|
|
|
*
|
|
|
|
|
* @return the location of the team's driver station controls: 1, 2, or 3
|
|
|
|
|
*/
|
|
|
|
|
public int getLocation() {
|
|
|
|
|
HALAllianceStationID allianceStationID =
|
|
|
|
|
FRCNetworkCommunicationsLibrary.HALGetAllianceStation();
|
|
|
|
|
if (allianceStationID == null) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
switch (allianceStationID) {
|
|
|
|
|
case Red1:
|
|
|
|
|
case Blue1:
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
case Red2:
|
|
|
|
|
case Blue2:
|
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
|
|
case Blue3:
|
|
|
|
|
case Red3:
|
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Is the driver station attached to a Field Management System? Note: This does not work with the
|
|
|
|
|
* Blue DS.
|
|
|
|
|
*
|
|
|
|
|
* @return True if the robot is competing on a field being controlled by a Field Management System
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
|
|
|
|
public boolean isFMSAttached() {
|
|
|
|
|
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
|
|
|
|
return controlWord.getFMSAttached();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isDSAttached() {
|
|
|
|
|
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
|
|
|
|
return controlWord.getDSAttached();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Return the approximate match time The FMS does not send an official match time to the robots,
|
|
|
|
|
* but does send an approximate match time. The value will count down the time remaining in the
|
|
|
|
|
* current period (auto or teleop). Warning: This is not an official time (so it cannot be used to
|
|
|
|
|
* dispute ref calls or guarantee that a function will trigger before the match ends) The
|
|
|
|
|
* Practice Match function of the DS approximates the behaviour seen on the field.
|
|
|
|
|
*
|
2015-06-25 15:07:55 -04:00
|
|
|
* @return Time remaining in current match period (auto or teleop) in seconds
|
|
|
|
|
*/
|
|
|
|
|
public double getMatchTime() {
|
|
|
|
|
return FRCNetworkCommunicationsLibrary.HALGetMatchTime();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Report error to Driver Station. Also prints error to System.err Optionally appends Stack trace
|
|
|
|
|
* to error message.
|
|
|
|
|
*
|
2015-06-25 15:07:55 -04:00
|
|
|
* @param printTrace If true, append stack trace to error string
|
|
|
|
|
*/
|
|
|
|
|
public static void reportError(String error, boolean printTrace) {
|
2016-02-04 22:29:11 -08:00
|
|
|
reportErrorImpl(true, 1, error, printTrace);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Report warning to Driver Station. Also prints error to System.err Optionally appends Stack
|
|
|
|
|
* trace to warning message.
|
|
|
|
|
*
|
2016-02-04 22:29:11 -08:00
|
|
|
* @param printTrace If true, append stack trace to warning string
|
|
|
|
|
*/
|
|
|
|
|
public static void reportWarning(String error, boolean printTrace) {
|
|
|
|
|
reportErrorImpl(false, 1, error, printTrace);
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-20 12:07:40 -04:00
|
|
|
private static void reportErrorImpl(boolean isError, int code, String error, boolean
|
|
|
|
|
printTrace) {
|
2016-02-04 22:29:11 -08:00
|
|
|
StackTraceElement[] traces = Thread.currentThread().getStackTrace();
|
|
|
|
|
String locString;
|
2016-05-20 12:07:40 -04:00
|
|
|
if (traces.length > 3) {
|
2016-02-04 22:29:11 -08:00
|
|
|
locString = traces[3].toString();
|
2016-05-20 12:07:40 -04:00
|
|
|
} else {
|
2016-02-04 22:29:11 -08:00
|
|
|
locString = new String();
|
2016-05-20 12:07:40 -04:00
|
|
|
}
|
2016-02-04 22:29:11 -08:00
|
|
|
boolean haveLoc = false;
|
2016-05-20 12:07:40 -04:00
|
|
|
String traceString = " at ";
|
2016-02-04 22:29:11 -08:00
|
|
|
for (int i = 3; i < traces.length; i++) {
|
|
|
|
|
String loc = traces[i].toString();
|
|
|
|
|
traceString += loc + "\n";
|
|
|
|
|
// get first user function
|
|
|
|
|
if (!haveLoc && !loc.startsWith("edu.wpi.first.wpilibj")) {
|
|
|
|
|
locString = loc;
|
|
|
|
|
haveLoc = true;
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
}
|
2016-05-20 12:07:40 -04:00
|
|
|
FRCNetworkCommunicationsLibrary.HALSendError(isError, code, false, error, locString,
|
|
|
|
|
printTrace ? traceString : "", true);
|
2015-06-25 15:07:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
|
|
|
|
|
* purposes only.
|
|
|
|
|
*
|
|
|
|
|
* @param entering If true, starting disabled code; if false, leaving disabled code
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
2016-05-20 12:07:40 -04:00
|
|
|
@SuppressWarnings("MethodName")
|
2015-06-25 15:07:55 -04:00
|
|
|
public void InDisabled(boolean entering) {
|
|
|
|
|
m_userInDisabled = entering;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
|
|
|
|
|
* purposes only.
|
|
|
|
|
*
|
|
|
|
|
* @param entering If true, starting autonomous code; if false, leaving autonomous code
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
2016-05-20 12:07:40 -04:00
|
|
|
@SuppressWarnings("MethodName")
|
2015-06-25 15:07:55 -04:00
|
|
|
public void InAutonomous(boolean entering) {
|
|
|
|
|
m_userInAutonomous = entering;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
|
|
|
|
|
* purposes only.
|
|
|
|
|
*
|
|
|
|
|
* @param entering If true, starting teleop code; if false, leaving teleop code
|
2015-06-25 15:07:55 -04:00
|
|
|
*/
|
2016-05-20 12:07:40 -04:00
|
|
|
@SuppressWarnings("MethodName")
|
2015-06-25 15:07:55 -04:00
|
|
|
public void InOperatorControl(boolean entering) {
|
|
|
|
|
m_userInTeleop = entering;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-05-20 12:07:40 -04:00
|
|
|
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
|
|
|
|
|
* purposes only.
|
|
|
|
|
*
|
2015-06-25 15:07:55 -04:00
|
|
|
* @param entering If true, starting test code; if false, leaving test code
|
|
|
|
|
*/
|
2016-05-20 12:07:40 -04:00
|
|
|
@SuppressWarnings("MethodName")
|
2015-06-25 15:07:55 -04:00
|
|
|
public void InTest(boolean entering) {
|
|
|
|
|
m_userInTest = entering;
|
|
|
|
|
}
|
2013-12-15 18:30:16 -05:00
|
|
|
}
|