mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
User code: - OpModeRobot used as the robot base class - LinearOpMode and PeriodicOpMode are provided opmode base classes - In Java, annotations can be used to automatically register opmode classes Additional user code functionality: - OpMode (string) is available in addition to the overall auto/teleop/test robot mode - OpMode does not indicate enable (enable/disable is still separate) - The HAL API uses integer UIDs; these are exposed at the user API level as well for faster checks - User code creates opmodes on startup (these have name, category, description, etc). DS: - DS will present opmode selection lists for auto and teleop for match/practice. During a match, the DS will automatically activate the selected opmode in the corresponding match period. - For testing, an overall mode is selected (e.g. teleop/auto/test) and a single opmode is selected Future work: - Command framework support/integration - Python annotation support - Unit tests (needs race-free DS sim updates) - Porting of examples Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
560 lines
18 KiB
Java
560 lines
18 KiB
Java
// Copyright (c) FIRST and other WPILib contributors.
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
// the WPILib BSD license file in the root directory of this project.
|
|
|
|
package org.wpilib.simulation;
|
|
|
|
import java.util.function.BiConsumer;
|
|
import org.wpilib.driverstation.DriverStation;
|
|
import org.wpilib.hardware.hal.AllianceStationID;
|
|
import org.wpilib.hardware.hal.DriverStationJNI;
|
|
import org.wpilib.hardware.hal.OpModeOption;
|
|
import org.wpilib.hardware.hal.RobotMode;
|
|
import org.wpilib.hardware.hal.simulation.DriverStationDataJNI;
|
|
import org.wpilib.hardware.hal.simulation.NotifyCallback;
|
|
import org.wpilib.util.WPIUtilJNI;
|
|
|
|
/** Class to control a simulated driver station. */
|
|
public final class DriverStationSim {
|
|
private DriverStationSim() {
|
|
throw new UnsupportedOperationException("This is a utility class!");
|
|
}
|
|
|
|
/**
|
|
* Register a callback on whether the DS is enabled.
|
|
*
|
|
* @param callback the callback that will be called whenever the enabled state is changed
|
|
* @param initialNotify if true, the callback will be run on the initial value
|
|
* @return the {@link CallbackStore} object associated with this callback.
|
|
*/
|
|
public static CallbackStore registerEnabledCallback(
|
|
NotifyCallback callback, boolean initialNotify) {
|
|
int uid = DriverStationDataJNI.registerEnabledCallback(callback, initialNotify);
|
|
return new CallbackStore(uid, DriverStationDataJNI::cancelEnabledCallback);
|
|
}
|
|
|
|
/**
|
|
* Check if the DS is enabled.
|
|
*
|
|
* @return true if enabled
|
|
*/
|
|
public static boolean getEnabled() {
|
|
return DriverStationDataJNI.getEnabled();
|
|
}
|
|
|
|
/**
|
|
* Change whether the DS is enabled.
|
|
*
|
|
* @param enabled the new value
|
|
*/
|
|
public static void setEnabled(boolean enabled) {
|
|
DriverStationDataJNI.setEnabled(enabled);
|
|
}
|
|
|
|
/**
|
|
* Register a callback on DS robot mode changes.
|
|
*
|
|
* @param callback the callback that will be called when the robot mode changes
|
|
* @param initialNotify if true, the callback will be run on the initial value
|
|
* @return the {@link CallbackStore} object associated with this callback.
|
|
*/
|
|
public static CallbackStore registerRobotModeCallback(
|
|
NotifyCallback callback, boolean initialNotify) {
|
|
int uid = DriverStationDataJNI.registerRobotModeCallback(callback, initialNotify);
|
|
return new CallbackStore(uid, DriverStationDataJNI::cancelRobotModeCallback);
|
|
}
|
|
|
|
/**
|
|
* Gets the robot mode set by the DS.
|
|
*
|
|
* @return robot mode
|
|
*/
|
|
public static RobotMode getRobotMode() {
|
|
return DriverStationDataJNI.getRobotMode();
|
|
}
|
|
|
|
/**
|
|
* Change the robot mode set by the DS.
|
|
*
|
|
* @param mode the new value
|
|
*/
|
|
public static void setRobotMode(RobotMode mode) {
|
|
DriverStationDataJNI.setRobotMode(mode);
|
|
}
|
|
|
|
/**
|
|
* Register a callback on the eStop state.
|
|
*
|
|
* @param callback the callback that will be called whenever the eStop state changes
|
|
* @param initialNotify if true, the callback will be run on the initial value
|
|
* @return the {@link CallbackStore} object associated with this callback.
|
|
*/
|
|
public static CallbackStore registerEStopCallback(
|
|
NotifyCallback callback, boolean initialNotify) {
|
|
int uid = DriverStationDataJNI.registerEStopCallback(callback, initialNotify);
|
|
return new CallbackStore(uid, DriverStationDataJNI::cancelEStopCallback);
|
|
}
|
|
|
|
/**
|
|
* Check if eStop has been activated.
|
|
*
|
|
* @return true if eStopped
|
|
*/
|
|
public static boolean getEStop() {
|
|
return DriverStationDataJNI.getEStop();
|
|
}
|
|
|
|
/**
|
|
* Set whether eStop is active.
|
|
*
|
|
* @param eStop true to activate
|
|
*/
|
|
public static void setEStop(boolean eStop) {
|
|
DriverStationDataJNI.setEStop(eStop);
|
|
}
|
|
|
|
/**
|
|
* Register a callback on whether the FMS is connected.
|
|
*
|
|
* @param callback the callback that will be called whenever the FMS connection changes
|
|
* @param initialNotify if true, the callback will be run on the initial value
|
|
* @return the {@link CallbackStore} object associated with this callback.
|
|
*/
|
|
public static CallbackStore registerFmsAttachedCallback(
|
|
NotifyCallback callback, boolean initialNotify) {
|
|
int uid = DriverStationDataJNI.registerFmsAttachedCallback(callback, initialNotify);
|
|
return new CallbackStore(uid, DriverStationDataJNI::cancelFmsAttachedCallback);
|
|
}
|
|
|
|
/**
|
|
* Check if the FMS is connected.
|
|
*
|
|
* @return true if FMS is connected
|
|
*/
|
|
public static boolean getFmsAttached() {
|
|
return DriverStationDataJNI.getFmsAttached();
|
|
}
|
|
|
|
/**
|
|
* Change whether the FMS is connected.
|
|
*
|
|
* @param fmsAttached the new value
|
|
*/
|
|
public static void setFmsAttached(boolean fmsAttached) {
|
|
DriverStationDataJNI.setFmsAttached(fmsAttached);
|
|
}
|
|
|
|
/**
|
|
* Register a callback on whether the DS is connected.
|
|
*
|
|
* @param callback the callback that will be called whenever the DS connection changes
|
|
* @param initialNotify if true, the callback will be run on the initial value
|
|
* @return the {@link CallbackStore} object associated with this callback.
|
|
*/
|
|
public static CallbackStore registerDsAttachedCallback(
|
|
NotifyCallback callback, boolean initialNotify) {
|
|
int uid = DriverStationDataJNI.registerDsAttachedCallback(callback, initialNotify);
|
|
return new CallbackStore(uid, DriverStationDataJNI::cancelDsAttachedCallback);
|
|
}
|
|
|
|
/**
|
|
* Check if the DS is attached.
|
|
*
|
|
* @return true if attached
|
|
*/
|
|
public static boolean getDsAttached() {
|
|
return DriverStationDataJNI.getDsAttached();
|
|
}
|
|
|
|
/**
|
|
* Change whether the DS is attached.
|
|
*
|
|
* @param dsAttached the new value
|
|
*/
|
|
public static void setDsAttached(boolean dsAttached) {
|
|
DriverStationDataJNI.setDsAttached(dsAttached);
|
|
}
|
|
|
|
/**
|
|
* Register a callback on the alliance station ID.
|
|
*
|
|
* @param callback the callback that will be called whenever the alliance station changes
|
|
* @param initialNotify if true, the callback will be run on the initial value
|
|
* @return the {@link CallbackStore} object associated with this callback.
|
|
*/
|
|
public static CallbackStore registerAllianceStationIdCallback(
|
|
NotifyCallback callback, boolean initialNotify) {
|
|
int uid = DriverStationDataJNI.registerAllianceStationIdCallback(callback, initialNotify);
|
|
return new CallbackStore(uid, DriverStationDataJNI::cancelAllianceStationIdCallback);
|
|
}
|
|
|
|
/**
|
|
* Get the alliance station ID (color + number).
|
|
*
|
|
* @return the alliance station color and number
|
|
*/
|
|
public static AllianceStationID getAllianceStationId() {
|
|
return switch (DriverStationDataJNI.getAllianceStationId()) {
|
|
case DriverStationJNI.kUnknownAllianceStation -> AllianceStationID.Unknown;
|
|
case DriverStationJNI.kRed1AllianceStation -> AllianceStationID.Red1;
|
|
case DriverStationJNI.kRed2AllianceStation -> AllianceStationID.Red2;
|
|
case DriverStationJNI.kRed3AllianceStation -> AllianceStationID.Red3;
|
|
case DriverStationJNI.kBlue1AllianceStation -> AllianceStationID.Blue1;
|
|
case DriverStationJNI.kBlue2AllianceStation -> AllianceStationID.Blue2;
|
|
case DriverStationJNI.kBlue3AllianceStation -> AllianceStationID.Blue3;
|
|
default -> AllianceStationID.Unknown;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Change the alliance station.
|
|
*
|
|
* @param allianceStationId the new alliance station
|
|
*/
|
|
public static void setAllianceStationId(AllianceStationID allianceStationId) {
|
|
int allianceStation =
|
|
switch (allianceStationId) {
|
|
case Unknown -> DriverStationJNI.kUnknownAllianceStation;
|
|
case Red1 -> DriverStationJNI.kRed1AllianceStation;
|
|
case Red2 -> DriverStationJNI.kRed2AllianceStation;
|
|
case Red3 -> DriverStationJNI.kRed3AllianceStation;
|
|
case Blue1 -> DriverStationJNI.kBlue1AllianceStation;
|
|
case Blue2 -> DriverStationJNI.kBlue2AllianceStation;
|
|
case Blue3 -> DriverStationJNI.kBlue3AllianceStation;
|
|
};
|
|
DriverStationDataJNI.setAllianceStationId(allianceStation);
|
|
}
|
|
|
|
/**
|
|
* Register a callback on match time.
|
|
*
|
|
* @param callback the callback that will be called whenever match time changes
|
|
* @param initialNotify if true, the callback will be run on the initial value
|
|
* @return the {@link CallbackStore} object associated with this callback.
|
|
*/
|
|
public static CallbackStore registerMatchTimeCallback(
|
|
NotifyCallback callback, boolean initialNotify) {
|
|
int uid = DriverStationDataJNI.registerMatchTimeCallback(callback, initialNotify);
|
|
return new CallbackStore(uid, DriverStationDataJNI::cancelMatchTimeCallback);
|
|
}
|
|
|
|
/**
|
|
* Get the current value of the match timer.
|
|
*
|
|
* @return the current match time
|
|
*/
|
|
public static double getMatchTime() {
|
|
return DriverStationDataJNI.getMatchTime();
|
|
}
|
|
|
|
/**
|
|
* Sets the match timer.
|
|
*
|
|
* @param matchTime the new match time
|
|
*/
|
|
public static void setMatchTime(double matchTime) {
|
|
DriverStationDataJNI.setMatchTime(matchTime);
|
|
}
|
|
|
|
/**
|
|
* Register a callback on opmode changes.
|
|
*
|
|
* @param callback the callback that will be called when the opmode changes
|
|
* @param initialNotify if true, the callback will be run on the initial value
|
|
* @return the {@link CallbackStore} object associated with this callback.
|
|
*/
|
|
public static CallbackStore registerOpModeCallback(
|
|
NotifyCallback callback, boolean initialNotify) {
|
|
int uid = DriverStationDataJNI.registerOpModeCallback(callback, initialNotify);
|
|
return new CallbackStore(uid, DriverStationDataJNI::cancelOpModeCallback);
|
|
}
|
|
|
|
/**
|
|
* Gets the opmode.
|
|
*
|
|
* @return opmode
|
|
*/
|
|
public static long getOpMode() {
|
|
return DriverStationDataJNI.getOpMode();
|
|
}
|
|
|
|
/**
|
|
* Change the opmode.
|
|
*
|
|
* @param opmode the new value
|
|
*/
|
|
public static void setOpMode(long opmode) {
|
|
DriverStationDataJNI.setOpMode(opmode);
|
|
}
|
|
|
|
/**
|
|
* Register a callback on opmode options changes.
|
|
*
|
|
* @param callback the callback that will be called when the list of opmodes changes
|
|
* @param initialNotify if true, the callback will be run on the initial value
|
|
* @return the {@link CallbackStore} object associated with this callback.
|
|
*/
|
|
public static CallbackStore registerOpModeOptionsCallback(
|
|
BiConsumer<String, OpModeOption[]> callback, boolean initialNotify) {
|
|
int uid = DriverStationDataJNI.registerOpModeOptionsCallback(callback, initialNotify);
|
|
return new CallbackStore(uid, DriverStationDataJNI::cancelOpModeOptionsCallback);
|
|
}
|
|
|
|
/**
|
|
* Gets the list of opmode options.
|
|
*
|
|
* @return opmodes list
|
|
*/
|
|
public static OpModeOption[] getOpModeOptions() {
|
|
return DriverStationDataJNI.getOpModeOptions();
|
|
}
|
|
|
|
/** Updates DriverStation data so that new values are visible to the user program. */
|
|
public static void notifyNewData() {
|
|
int handle = WPIUtilJNI.createEvent(false, false);
|
|
DriverStationJNI.provideNewDataEventHandle(handle);
|
|
DriverStationDataJNI.notifyNewData();
|
|
try {
|
|
WPIUtilJNI.waitForObject(handle);
|
|
} catch (InterruptedException e) {
|
|
e.printStackTrace();
|
|
}
|
|
DriverStationJNI.removeNewDataEventHandle(handle);
|
|
WPIUtilJNI.destroyEvent(handle);
|
|
DriverStation.refreshData();
|
|
}
|
|
|
|
/**
|
|
* Sets suppression of DriverStation.reportError and reportWarning messages.
|
|
*
|
|
* @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 int getJoystickLeds(int stick) {
|
|
return DriverStationDataJNI.getJoystickLeds(stick);
|
|
}
|
|
|
|
/**
|
|
* Gets the joystick rumble.
|
|
*
|
|
* @param stick The joystick number
|
|
* @param rumbleNum Rumble to get (0=left, 1=right, 2=left trigger, 3=right trigger)
|
|
* @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 0.
|
|
*
|
|
* @param stick The joystick number
|
|
* @param button The button index, beginning at 0
|
|
* @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
|
|
*/
|
|
public static void setJoystickPOV(int stick, int pov, DriverStation.POVDirection value) {
|
|
DriverStationDataJNI.setJoystickPOV(stick, pov, value.value);
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum index that an axis is available at.
|
|
*
|
|
* @param stick The joystick number
|
|
* @param maximumIndex The maximum index an axis is available at.
|
|
*/
|
|
public static void setJoystickAxesMaximumIndex(int stick, int maximumIndex) {
|
|
setJoystickAxesAvailable(stick, (1 << maximumIndex) - 1);
|
|
}
|
|
|
|
/**
|
|
* 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 setJoystickAxesAvailable(int stick, int count) {
|
|
DriverStationDataJNI.setJoystickAxesAvailable(stick, count);
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum index that a pov is available at.
|
|
*
|
|
* @param stick The joystick number
|
|
* @param maximumIndex The maximum index a pov is available at.
|
|
*/
|
|
public static void setJoystickPOVsMaximumIndex(int stick, int maximumIndex) {
|
|
setJoystickPOVsAvailable(stick, (1 << maximumIndex) - 1);
|
|
}
|
|
|
|
/**
|
|
* 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 setJoystickPOVsAvailable(int stick, int count) {
|
|
DriverStationDataJNI.setJoystickPOVsAvailable(stick, count);
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum index that a button is available at.
|
|
*
|
|
* @param stick The joystick number
|
|
* @param maximumIndex The maximum index a button is available at.
|
|
*/
|
|
public static void setJoystickButtonsMaximumIndex(int stick, int maximumIndex) {
|
|
if (maximumIndex >= 64) {
|
|
setJoystickButtonsAvailable(stick, 0xFFFFFFFFFFFFFFFFL);
|
|
} else {
|
|
setJoystickButtonsAvailable(stick, (1L << maximumIndex) - 1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 setJoystickButtonsAvailable(int stick, long count) {
|
|
DriverStationDataJNI.setJoystickButtonsAvailable(stick, count);
|
|
}
|
|
|
|
/**
|
|
* Sets the value of isGamepad for a joystick.
|
|
*
|
|
* @param stick The joystick number
|
|
* @param isGamepad The value of isGamepad
|
|
*/
|
|
public static void setJoystickIsGamepad(int stick, boolean isGamepad) {
|
|
DriverStationDataJNI.setJoystickIsGamepad(stick, isGamepad);
|
|
}
|
|
|
|
/**
|
|
* Sets the value of type for a joystick.
|
|
*
|
|
* @param stick The joystick number
|
|
* @param type The value of type
|
|
*/
|
|
public static void setJoystickGamepadType(int stick, int type) {
|
|
DriverStationDataJNI.setJoystickGamepadType(stick, type);
|
|
}
|
|
|
|
/**
|
|
* Sets the value of supported outputs for a joystick.
|
|
*
|
|
* @param stick The joystick number
|
|
* @param supportedOutputs The value of supported outputs
|
|
*/
|
|
public static void setJoystickSupportedOutputs(int stick, int supportedOutputs) {
|
|
DriverStationDataJNI.setJoystickSupportedOutputs(stick, supportedOutputs);
|
|
}
|
|
|
|
/**
|
|
* 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 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 -> 1;
|
|
case Qualification -> 2;
|
|
case Elimination -> 3;
|
|
case None -> 0;
|
|
};
|
|
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);
|
|
}
|
|
|
|
/** Reset all simulation data for the Driver Station. */
|
|
public static void resetData() {
|
|
DriverStationDataJNI.resetData();
|
|
}
|
|
}
|