[sim] Add joystick simulation support (#2595)

This adds joystick functions to DriverStationSim, and new GenericHIDSim,
JoystickSim, and XboxControllerSim classes.
This commit is contained in:
Peter Johnson
2020-07-15 00:33:57 -07:00
committed by GitHub
parent b06ddcdd86
commit b9feb81226
19 changed files with 1979 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2019 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2020 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
@@ -18,11 +18,11 @@ import edu.wpi.first.hal.HAL;
* and the mapping of ports to hardware buttons depends on the code in the Driver Station.
*/
public class Joystick extends GenericHID {
static final byte kDefaultXChannel = 0;
static final byte kDefaultYChannel = 1;
static final byte kDefaultZChannel = 2;
static final byte kDefaultTwistChannel = 2;
static final byte kDefaultThrottleChannel = 3;
public static final byte kDefaultXChannel = 0;
public static final byte kDefaultYChannel = 1;
public static final byte kDefaultZChannel = 2;
public static final byte kDefaultTwistChannel = 2;
public static final byte kDefaultThrottleChannel = 3;
/**
* Represents an analog axis on a joystick.

View File

@@ -7,13 +7,15 @@
package edu.wpi.first.wpilibj.simulation;
import edu.wpi.first.hal.AllianceStationID;
import edu.wpi.first.hal.simulation.DriverStationDataJNI;
import edu.wpi.first.hal.simulation.NotifyCallback;
import edu.wpi.first.wpilibj.DriverStation;
/**
* Class to control a simulated driver station.
*/
@SuppressWarnings("PMD.UseUtilityClass")
@SuppressWarnings({"PMD.UseUtilityClass", "PMD.GodClass", "PMD.ExcessivePublicCount"})
public class DriverStationSim {
public static CallbackStore registerEnabledCallback(NotifyCallback callback, boolean initialNotify) {
int uid = DriverStationDataJNI.registerEnabledCallback(callback, initialNotify);
@@ -80,19 +82,291 @@ public class DriverStationSim {
public static void setDsAttached(boolean dsAttached) {
DriverStationDataJNI.setDsAttached(dsAttached);
}
public static void notifyNewData() {
DriverStationDataJNI.notifyNewData();
public static CallbackStore registerAllianceStationIdCallback(NotifyCallback callback, boolean initialNotify) {
int uid = DriverStationDataJNI.registerAllianceStationIdCallback(callback, initialNotify);
return new CallbackStore(uid, DriverStationDataJNI::cancelAllianceStationIdCallback);
}
public static AllianceStationID getAllianceStationId() {
switch (DriverStationDataJNI.getAllianceStationId()) {
case 0:
return AllianceStationID.Red1;
case 1:
return AllianceStationID.Red2;
case 2:
return AllianceStationID.Red3;
case 3:
return AllianceStationID.Blue1;
case 4:
return AllianceStationID.Blue2;
case 5:
return AllianceStationID.Blue3;
default:
return null;
}
}
public static void setAllianceStationId(AllianceStationID allianceStationId) {
int allianceStation;
switch (allianceStationId) {
case Red1:
allianceStation = 0;
break;
case Red2:
allianceStation = 1;
break;
case Red3:
allianceStation = 2;
break;
case Blue1:
allianceStation = 3;
break;
case Blue2:
allianceStation = 4;
break;
case Blue3:
allianceStation = 5;
break;
default:
return;
}
DriverStationDataJNI.setAllianceStationId(allianceStation);
}
public static CallbackStore registerMatchTimeCallback(NotifyCallback callback, boolean initialNotify) {
int uid = DriverStationDataJNI.registerMatchTimeCallback(callback, initialNotify);
return new CallbackStore(uid, DriverStationDataJNI::cancelMatchTimeCallback);
}
public static double getMatchTime() {
return DriverStationDataJNI.getMatchTime();
}
public static void setMatchTime(double matchTime) {
DriverStationDataJNI.setMatchTime(matchTime);
}
/**
* Toggles suppression of DriverStation.reportError and reportWarning messages.
* Updates DriverStation data so that new values are visible to the user
* program.
*/
public static void notifyNewData() {
DriverStationDataJNI.notifyNewData();
DriverStation.getInstance().waitForData();
}
/**
* Sets suppression of DriverStation.reportError and reportWarning messages.
*
* @param shouldSend If false then messages will will be suppressed.
* @param shouldSend If false then messages will be suppressed.
*/
public static void setSendError(boolean shouldSend) {
DriverStationDataJNI.setSendError(shouldSend);
}
/**
* Sets suppression of DriverStation.sendConsoleLine messages.
*
* @param shouldSend If false then messages will be suppressed.
*/
public static void setSendConsoleLine(boolean shouldSend) {
DriverStationDataJNI.setSendConsoleLine(shouldSend);
}
/**
* Gets the joystick outputs.
*
* @param stick The joystick number
* @return The joystick outputs
*/
public static long getJoystickOutputs(int stick) {
return DriverStationDataJNI.getJoystickOutputs(stick);
}
/**
* Gets the joystick rumble.
*
* @param stick The joystick number
* @param rumbleNum Rumble to get (0=left, 1=right)
* @return The joystick rumble value
*/
public static int getJoystickRumble(int stick, int rumbleNum) {
return DriverStationDataJNI.getJoystickRumble(stick, rumbleNum);
}
/**
* Sets the state of one joystick button. Button indexes begin at 1.
*
* @param stick The joystick number
* @param button The button index, beginning at 1
* @param state The state of the joystick button
*/
public static void setJoystickButton(int stick, int button, boolean state) {
DriverStationDataJNI.setJoystickButton(stick, button, state);
}
/**
* Gets the value of the axis on a joystick.
*
* @param stick The joystick number
* @param axis The analog axis number
* @param value The value of the axis on the joystick
*/
public static void setJoystickAxis(int stick, int axis, double value) {
DriverStationDataJNI.setJoystickAxis(stick, axis, value);
}
/**
* Gets the state of a POV on a joystick.
*
* @param stick The joystick number
* @param pov The POV number
* @param value the angle of the POV in degrees, or -1 for not pressed
*/
public static void setJoystickPOV(int stick, int pov, int value) {
DriverStationDataJNI.setJoystickPOV(stick, pov, value);
}
/**
* Sets the state of all the buttons on a joystick.
*
* @param stick The joystick number
* @param buttons The bitmap state of the buttons on the joystick
*/
public static void setJoystickButtons(int stick, int buttons) {
DriverStationDataJNI.setJoystickButtonsValue(stick, buttons);
}
/**
* Sets the number of axes for a joystick.
*
* @param stick The joystick number
* @param count The number of axes on the indicated joystick
*/
public static void setJoystickAxisCount(int stick, int count) {
DriverStationDataJNI.setJoystickAxisCount(stick, count);
}
/**
* Sets the number of POVs for a joystick.
*
* @param stick The joystick number
* @param count The number of POVs on the indicated joystick
*/
public static void setJoystickPOVCount(int stick, int count) {
DriverStationDataJNI.setJoystickPOVCount(stick, count);
}
/**
* Sets the number of buttons for a joystick.
*
* @param stick The joystick number
* @param count The number of buttons on the indicated joystick
*/
public static void setJoystickButtonCount(int stick, int count) {
DriverStationDataJNI.setJoystickButtonCount(stick, count);
}
/**
* Sets the value of isXbox for a joystick.
*
* @param stick The joystick number
* @param isXbox The value of isXbox
*/
public static void setJoystickIsXbox(int stick, boolean isXbox) {
DriverStationDataJNI.setJoystickIsXbox(stick, isXbox);
}
/**
* Sets the value of type for a joystick.
*
* @param stick The joystick number
* @param type The value of type
*/
public static void setJoystickType(int stick, int type) {
DriverStationDataJNI.setJoystickType(stick, type);
}
/**
* Sets the name of a joystick.
*
* @param stick The joystick number
* @param name The value of name
*/
public static void setJoystickName(int stick, String name) {
DriverStationDataJNI.setJoystickName(stick, name);
}
/**
* Sets the types of Axes for a joystick.
*
* @param stick The joystick number
* @param axis The target axis
* @param type The type of axis
*/
public static void setJoystickAxisType(int stick, int axis, int type) {
DriverStationDataJNI.setJoystickAxisType(stick, axis, type);
}
/**
* Sets the game specific message.
*
* @param message the game specific message
*/
public static void setGameSpecificMessage(String message) {
DriverStationDataJNI.setGameSpecificMessage(message);
}
/**
* Sets the event name.
*
* @param name the event name
*/
public static void setEventName(String name) {
DriverStationDataJNI.setEventName(name);
}
/**
* Sets the match type.
*
* @param type the match type
*/
public static void setMatchType(DriverStation.MatchType type) {
int matchType;
switch (type) {
case Practice:
matchType = 1;
break;
case Qualification:
matchType = 2;
break;
case Elimination:
matchType = 3;
break;
case None:
matchType = 0;
break;
default:
return;
}
DriverStationDataJNI.setMatchType(matchType);
}
/**
* Sets the match number.
*
* @param matchNumber the match number
*/
public static void setMatchNumber(int matchNumber) {
DriverStationDataJNI.setMatchNumber(matchNumber);
}
/**
* Sets the replay number.
*
* @param replayNumber the replay number
*/
public static void setReplayNumber(int replayNumber) {
DriverStationDataJNI.setReplayNumber(replayNumber);
}
public static void resetData() {
DriverStationDataJNI.resetData();
}

View File

@@ -0,0 +1,97 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2020 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.simulation;
import edu.wpi.first.wpilibj.GenericHID;
/**
* Class to control a simulated generic joystick.
*/
public class GenericHIDSim {
protected final int m_port;
/**
* Constructs from a GenericHID object.
*
* @param joystick joystick to simulate
*/
public GenericHIDSim(GenericHID joystick) {
m_port = joystick.getPort();
}
/**
* Constructs from a joystick port number.
*
* @param port port number
*/
public GenericHIDSim(int port) {
m_port = port;
}
/**
* Updates joystick data so that new values are visible to the user program.
*/
public void notifyNewData() {
DriverStationSim.notifyNewData();
}
public void setRawButton(int button, boolean value) {
DriverStationSim.setJoystickButton(m_port, button, value);
}
public void setRawAxis(int axis, double value) {
DriverStationSim.setJoystickAxis(m_port, axis, value);
}
public void setPOV(int pov, int value) {
DriverStationSim.setJoystickPOV(m_port, pov, value);
}
public void setPOV(int value) {
setPOV(0, value);
}
public void setAxisCount(int count) {
DriverStationSim.setJoystickAxisCount(m_port, count);
}
public void setPOVCount(int count) {
DriverStationSim.setJoystickPOVCount(m_port, count);
}
public void setButtonCount(int count) {
DriverStationSim.setJoystickButtonCount(m_port, count);
}
public void setType(GenericHID.HIDType type) {
DriverStationSim.setJoystickType(m_port, type.value);
}
public void setName(String name) {
DriverStationSim.setJoystickName(m_port, name);
}
public void setAxisType(int axis, int type) {
DriverStationSim.setJoystickAxisType(m_port, axis, type);
}
public boolean getOutput(int outputNumber) {
long outputs = getOutputs();
return (outputs & (1 << (outputNumber - 1))) != 0;
}
public long getOutputs() {
return DriverStationSim.getJoystickOutputs(m_port);
}
public double getRumble(GenericHID.RumbleType type) {
int value = DriverStationSim.getJoystickRumble(
m_port, type == GenericHID.RumbleType.kLeftRumble ? 0 : 1);
return value / 65535.0;
}
}

View File

@@ -0,0 +1,76 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2020 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.simulation;
import edu.wpi.first.wpilibj.Joystick;
/**
* Class to control a simulated joystick.
*/
public class JoystickSim extends GenericHIDSim {
private Joystick m_joystick;
/**
* Constructs from a Joystick object.
*
* @param joystick joystick to simulate
*/
public JoystickSim(Joystick joystick) {
super(joystick);
m_joystick = joystick;
// default to a reasonable joystick configuration
setAxisCount(5);
setButtonCount(12);
setPOVCount(1);
}
/**
* Constructs from a joystick port number.
*
* @param port port number
*/
public JoystickSim(int port) {
super(port);
// default to a reasonable joystick configuration
setAxisCount(5);
setButtonCount(12);
setPOVCount(1);
}
public void setX(double value) {
setRawAxis(m_joystick != null ? m_joystick.getXChannel() : Joystick.kDefaultXChannel, value);
}
public void setY(double value) {
setRawAxis(m_joystick != null ? m_joystick.getYChannel() : Joystick.kDefaultYChannel, value);
}
public void setZ(double value) {
setRawAxis(m_joystick != null ? m_joystick.getZChannel() : Joystick.kDefaultZChannel, value);
}
public void setTwist(double value) {
setRawAxis(
m_joystick != null ? m_joystick.getTwistChannel() : Joystick.kDefaultTwistChannel,
value);
}
public void setThrottle(double value) {
setRawAxis(
m_joystick != null ? m_joystick.getThrottleChannel() : Joystick.kDefaultThrottleChannel,
value);
}
public void setTrigger(boolean state) {
setRawButton(1, state);
}
public void setTop(boolean state) {
setRawButton(2, state);
}
}

View File

@@ -0,0 +1,102 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2020 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.simulation;
import edu.wpi.first.wpilibj.GenericHID;
import edu.wpi.first.wpilibj.XboxController;
/**
* Class to control a simulated Xbox 360 or Xbox One controller.
*/
public class XboxControllerSim extends GenericHIDSim {
/**
* Constructs from a XboxController object.
*
* @param joystick controller to simulate
*/
public XboxControllerSim(XboxController joystick) {
super(joystick);
setAxisCount(6);
setButtonCount(10);
}
/**
* Constructs from a joystick port number.
*
* @param port port number
*/
public XboxControllerSim(int port) {
super(port);
setAxisCount(6);
setButtonCount(10);
}
public void setX(GenericHID.Hand hand, double value) {
if (hand.equals(GenericHID.Hand.kLeft)) {
setRawAxis(XboxController.Axis.kLeftX.value, value);
} else {
setRawAxis(XboxController.Axis.kRightX.value, value);
}
}
public void setY(GenericHID.Hand hand, double value) {
if (hand.equals(GenericHID.Hand.kLeft)) {
setRawAxis(XboxController.Axis.kLeftY.value, value);
} else {
setRawAxis(XboxController.Axis.kRightY.value, value);
}
}
public void setTriggerAxis(GenericHID.Hand hand, double value) {
if (hand.equals(GenericHID.Hand.kLeft)) {
setRawAxis(XboxController.Axis.kLeftTrigger.value, value);
} else {
setRawAxis(XboxController.Axis.kRightTrigger.value, value);
}
}
public void setBumper(GenericHID.Hand hand, boolean state) {
if (hand.equals(GenericHID.Hand.kLeft)) {
setRawButton(XboxController.Button.kBumperLeft.value, state);
} else {
setRawButton(XboxController.Button.kBumperRight.value, state);
}
}
public void setStickButton(GenericHID.Hand hand, boolean state) {
if (hand.equals(GenericHID.Hand.kLeft)) {
setRawButton(XboxController.Button.kStickLeft.value, state);
} else {
setRawButton(XboxController.Button.kStickRight.value, state);
}
}
public void setAButton(boolean state) {
setRawButton(XboxController.Button.kA.value, state);
}
public void setBButton(boolean state) {
setRawButton(XboxController.Button.kB.value, state);
}
public void setXButton(boolean state) {
setRawButton(XboxController.Button.kX.value, state);
}
public void setYButton(boolean state) {
setRawButton(XboxController.Button.kY.value, state);
}
public void setBackButton(boolean state) {
setRawButton(XboxController.Button.kBack.value, state);
}
public void setStartButton(boolean state) {
setRawButton(XboxController.Button.kStart.value, state);
}
}