mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-23 01:21:42 +00:00
[sim] Various WebSockets fixes and enhancements (#2952)
This is a breaking change to the WebSockets layer to align it with recent specification documentation work. To support this, HAL SimValue changed readonly to a direction enum. This allows specifying bidirectional in addition to input and output. The SimValue change is specifically designed to avoid API and ABI breakage. This is completely transparent in C++; in Java a new callback class was added, and the old readonly functions have been marked deprecated. A new SimValue creation function for enums allows specifying double values for each enum value, not just strings. This allows mapping enum values to doubles in the WebSockets layer. A ":" in the SimDevice name now maps it to different WebSocket types (e.g. "Accel:Name" becomes type "Accel", device "Name"). The type is hidden in the GUI. Other WebSockets changes: * Implemented match_time and game_data * Added joystick rumble data * Added builtin accelerometer support * SimValue enums are mapped to string and double value on WS interface * Added WebSockets protocol specification * Added READMEs
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2019 FIRST. All Rights Reserved. */
|
||||
/* Copyright (c) 2019-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. */
|
||||
@@ -11,6 +11,18 @@ package edu.wpi.first.hal;
|
||||
* A wrapper around a simulator device handle.
|
||||
*/
|
||||
public class SimDevice implements AutoCloseable {
|
||||
public enum Direction {
|
||||
kInput(SimDeviceJNI.kInput),
|
||||
kOutput(SimDeviceJNI.kOutput),
|
||||
kBidir(SimDeviceJNI.kBidir);
|
||||
|
||||
public final int m_value;
|
||||
|
||||
Direction(int value) {
|
||||
m_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a simulated device.
|
||||
*
|
||||
@@ -101,9 +113,26 @@ public class SimDevice implements AutoCloseable {
|
||||
* @param readonly if the value should not be written from simulation side
|
||||
* @param initialValue initial value
|
||||
* @return simulated value object
|
||||
*
|
||||
* @deprecated Use direction function instead
|
||||
*/
|
||||
@Deprecated
|
||||
public SimValue createValue(String name, boolean readonly, HALValue initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValue(m_handle, name, readonly, initialValue);
|
||||
return createValue(name, readonly ? Direction.kOutput : Direction.kInput, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a value on the simulated device.
|
||||
*
|
||||
* <p>Returns null if not in simulation.
|
||||
*
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated value object
|
||||
*/
|
||||
public SimValue createValue(String name, Direction direction, HALValue initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValue(m_handle, name, direction.m_value, initialValue);
|
||||
if (handle <= 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -119,9 +148,26 @@ public class SimDevice implements AutoCloseable {
|
||||
* @param readonly if the value should not be written from simulation side
|
||||
* @param initialValue initial value
|
||||
* @return simulated double value object
|
||||
*
|
||||
* @deprecated Use direction function instead
|
||||
*/
|
||||
@Deprecated
|
||||
public SimDouble createDouble(String name, boolean readonly, double initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValueDouble(m_handle, name, readonly, initialValue);
|
||||
return createDouble(name, readonly ? Direction.kOutput : Direction.kInput, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a double value on the simulated device.
|
||||
*
|
||||
* <p>Returns null if not in simulation.
|
||||
*
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated double value object
|
||||
*/
|
||||
public SimDouble createDouble(String name, Direction direction, double initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValueDouble(m_handle, name, direction.m_value, initialValue);
|
||||
if (handle <= 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -140,9 +186,54 @@ public class SimDevice implements AutoCloseable {
|
||||
* @param options array of option descriptions
|
||||
* @param initialValue initial value (selection)
|
||||
* @return simulated enum value object
|
||||
*
|
||||
* @deprecated Use direction function instead
|
||||
*/
|
||||
@Deprecated
|
||||
public SimEnum createEnum(String name, boolean readonly, String[] options, int initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValueEnum(m_handle, name, readonly, options, initialValue);
|
||||
return createEnum(name, readonly ? Direction.kOutput : Direction.kInput, options, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enumerated value on the simulated device.
|
||||
*
|
||||
* <p>Enumerated values are always in the range 0 to numOptions-1.
|
||||
*
|
||||
* <p>Returns null if not in simulation.
|
||||
*
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param options array of option descriptions
|
||||
* @param initialValue initial value (selection)
|
||||
* @return simulated enum value object
|
||||
*/
|
||||
public SimEnum createEnum(String name, Direction direction, String[] options, int initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValueEnum(m_handle, name, direction.m_value, options,
|
||||
initialValue);
|
||||
if (handle <= 0) {
|
||||
return null;
|
||||
}
|
||||
return new SimEnum(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enumerated value on the simulated device with double values.
|
||||
*
|
||||
* <p>Enumerated values are always in the range 0 to numOptions-1.
|
||||
*
|
||||
* <p>Returns null if not in simulation.
|
||||
*
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param options array of option descriptions
|
||||
* @param optionValues array of option values (must be the same size as options)
|
||||
* @param initialValue initial value (selection)
|
||||
* @return simulated enum value object
|
||||
*/
|
||||
public SimEnum createEnumDouble(String name, Direction direction, String[] options,
|
||||
double[] optionValues, int initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValueEnumDouble(m_handle, name, direction.m_value, options,
|
||||
optionValues, initialValue);
|
||||
if (handle <= 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -158,9 +249,27 @@ public class SimDevice implements AutoCloseable {
|
||||
* @param readonly if the value should not be written from simulation side
|
||||
* @param initialValue initial value
|
||||
* @return simulated boolean value object
|
||||
*
|
||||
* @deprecated Use direction function instead
|
||||
*/
|
||||
@Deprecated
|
||||
public SimBoolean createBoolean(String name, boolean readonly, boolean initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValueBoolean(m_handle, name, readonly, initialValue);
|
||||
return createBoolean(name, readonly ? Direction.kOutput : Direction.kInput, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boolean value on the simulated device.
|
||||
*
|
||||
* <p>Returns null if not in simulation.
|
||||
*
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated boolean value object
|
||||
*/
|
||||
public SimBoolean createBoolean(String name, Direction direction, boolean initialValue) {
|
||||
int handle = SimDeviceJNI.createSimValueBoolean(m_handle, name, direction.m_value,
|
||||
initialValue);
|
||||
if (handle <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2019 FIRST. All Rights Reserved. */
|
||||
/* Copyright (c) 2019-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. */
|
||||
@@ -8,6 +8,10 @@
|
||||
package edu.wpi.first.hal;
|
||||
|
||||
public class SimDeviceJNI extends JNIWrapper {
|
||||
public static final int kInput = 0;
|
||||
public static final int kOutput = 1;
|
||||
public static final int kBidir = 2;
|
||||
|
||||
/**
|
||||
* Creates a simulated device.
|
||||
*
|
||||
@@ -33,7 +37,7 @@ public class SimDeviceJNI extends JNIWrapper {
|
||||
*/
|
||||
public static native void freeSimDevice(int handle);
|
||||
|
||||
private static native int createSimValueNative(int device, String name, boolean readonly,
|
||||
private static native int createSimValueNative(int device, String name, int direction,
|
||||
int type, long value1, double value2);
|
||||
|
||||
/**
|
||||
@@ -47,10 +51,31 @@ public class SimDeviceJNI extends JNIWrapper {
|
||||
* @param readonly if the value should not be written from simulation side
|
||||
* @param initialValue initial value
|
||||
* @return simulated value handle
|
||||
*
|
||||
* @deprecated Use direction-taking function instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static int createSimValue(int device, String name, boolean readonly,
|
||||
HALValue initialValue) {
|
||||
return createSimValueNative(device, name, readonly, initialValue.getType(),
|
||||
return createSimValueNative(device, name, readonly ? kOutput : kInput, initialValue.getType(),
|
||||
initialValue.getNativeLong(), initialValue.getNativeDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a value on a simulated device.
|
||||
*
|
||||
* <p>Returns 0 if not in simulation; this can be used to avoid calls
|
||||
* to Set/Get functions.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated value handle
|
||||
*/
|
||||
public static int createSimValue(int device, String name, int direction,
|
||||
HALValue initialValue) {
|
||||
return createSimValueNative(device, name, direction, initialValue.getType(),
|
||||
initialValue.getNativeLong(), initialValue.getNativeDouble());
|
||||
}
|
||||
|
||||
@@ -65,10 +90,30 @@ public class SimDeviceJNI extends JNIWrapper {
|
||||
* @param readonly if the value should not be written from simulation side
|
||||
* @param initialValue initial value
|
||||
* @return simulated value handle
|
||||
*
|
||||
* @deprecated Use direction-taking function instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static int createSimValueDouble(int device, String name, boolean readonly,
|
||||
double initialValue) {
|
||||
return createSimValueNative(device, name, readonly, HALValue.kDouble, 0, initialValue);
|
||||
return createSimValueNative(device, name, readonly ? kOutput : kInput, HALValue.kDouble, 0, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a double value on a simulated device.
|
||||
*
|
||||
* <p>Returns 0 if not in simulation; this can be used to avoid calls
|
||||
* to Set/Get functions.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated value handle
|
||||
*/
|
||||
public static int createSimValueDouble(int device, String name, int direction,
|
||||
double initialValue) {
|
||||
return createSimValueNative(device, name, direction, HALValue.kDouble, 0, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,10 +130,52 @@ public class SimDeviceJNI extends JNIWrapper {
|
||||
* @param options array of option descriptions
|
||||
* @param initialValue initial value (selection)
|
||||
* @return simulated value handle
|
||||
*
|
||||
* @deprecated Use direction-taking function instead
|
||||
*/
|
||||
public static native int createSimValueEnum(int device, String name, boolean readonly,
|
||||
@Deprecated
|
||||
public static int createSimValueEnum(int device, String name, boolean readonly,
|
||||
String[] options, int initialValue) {
|
||||
return createSimValueEnum(device, name, readonly ? kOutput : kInput, options, initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enumerated value on a simulated device.
|
||||
*
|
||||
* <p>Enumerated values are always in the range 0 to numOptions-1.
|
||||
*
|
||||
* <p>Returns 0 if not in simulation; this can be used to avoid calls
|
||||
* to Set/Get functions.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param options array of option descriptions
|
||||
* @param initialValue initial value (selection)
|
||||
* @return simulated value handle
|
||||
*/
|
||||
public static native int createSimValueEnum(int device, String name, int direction,
|
||||
String[] options, int initialValue);
|
||||
|
||||
/**
|
||||
* Creates an enumerated value on a simulated device with double values.
|
||||
*
|
||||
* <p>Enumerated values are always in the range 0 to numOptions-1.
|
||||
*
|
||||
* <p>Returns 0 if not in simulation; this can be used to avoid calls
|
||||
* to Set/Get functions.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param options array of option descriptions
|
||||
* @param optionValues array of option values (must be the same size as options)
|
||||
* @param initialValue initial value (selection)
|
||||
* @return simulated value handle
|
||||
*/
|
||||
public static native int createSimValueEnumDouble(int device, String name, int direction,
|
||||
String[] options, double[] optionValues, int initialValue);
|
||||
|
||||
/**
|
||||
* Creates a boolean value on a simulated device.
|
||||
*
|
||||
@@ -100,10 +187,31 @@ public class SimDeviceJNI extends JNIWrapper {
|
||||
* @param readonly if the value should not be written from simulation side
|
||||
* @param initialValue initial value
|
||||
* @return simulated value handle
|
||||
*
|
||||
* @deprecated Use direction-taking function instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static int createSimValueBoolean(int device, String name, boolean readonly,
|
||||
boolean initialValue) {
|
||||
return createSimValueNative(device, name, readonly, HALValue.kBoolean,
|
||||
return createSimValueNative(device, name, readonly ? kOutput : kInput, HALValue.kBoolean,
|
||||
initialValue ? 1 : 0, 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boolean value on a simulated device.
|
||||
*
|
||||
* <p>Returns 0 if not in simulation; this can be used to avoid calls
|
||||
* to Set/Get functions.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
* @param name value name
|
||||
* @param direction input/output/bidir (from perspective of user code)
|
||||
* @param initialValue initial value
|
||||
* @return simulated value handle
|
||||
*/
|
||||
public static int createSimValueBoolean(int device, String name, int direction,
|
||||
boolean initialValue) {
|
||||
return createSimValueNative(device, name, direction, HALValue.kBoolean,
|
||||
initialValue ? 1 : 0, 0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,18 +41,21 @@ public class SimDeviceDataJNI extends JNIWrapper {
|
||||
public static native SimDeviceInfo[] enumerateSimDevices(String prefix);
|
||||
|
||||
public static native int registerSimValueCreatedCallback(int device, SimValueCallback callback, boolean initialNotify);
|
||||
public static native int registerSimValueCreatedCallback2(int device, SimValueCallback2 callback, boolean initialNotify);
|
||||
public static native void cancelSimValueCreatedCallback(int uid);
|
||||
|
||||
public static native int registerSimValueChangedCallback(int handle, SimValueCallback callback, boolean initialNotify);
|
||||
public static native int registerSimValueChangedCallback2(int handle, SimValueCallback2 callback, boolean initialNotify);
|
||||
public static native void cancelSimValueChangedCallback(int uid);
|
||||
|
||||
public static native int getSimValueHandle(int device, String name);
|
||||
|
||||
public static class SimValueInfo {
|
||||
public SimValueInfo(String name, int handle, boolean readonly, int type, long value1, double value2) {
|
||||
public SimValueInfo(String name, int handle, int direction, int type, long value1, double value2) {
|
||||
this.name = name;
|
||||
this.handle = handle;
|
||||
this.readonly = readonly;
|
||||
this.readonly = direction == 1;
|
||||
this.direction = direction;
|
||||
this.value = HALValue.fromNative(type, value1, value2);
|
||||
}
|
||||
|
||||
@@ -63,8 +66,12 @@ public class SimDeviceDataJNI extends JNIWrapper {
|
||||
public int handle;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
@Deprecated
|
||||
public boolean readonly;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public int direction;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public HALValue value;
|
||||
}
|
||||
@@ -72,5 +79,7 @@ public class SimDeviceDataJNI extends JNIWrapper {
|
||||
|
||||
public static native String[] getSimValueEnumOptions(int handle);
|
||||
|
||||
public static native double[] getSimValueEnumDoubleValues(int handle);
|
||||
|
||||
public static native void resetSimDeviceData();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2019-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.hal.simulation;
|
||||
|
||||
import edu.wpi.first.hal.HALValue;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SimValueCallback2 {
|
||||
void callback(String name, int handle, int direction, HALValue value);
|
||||
|
||||
default void callbackNative(String name, int handle, int direction, int type, long value1, double value2) {
|
||||
callback(name, handle, direction, HALValue.fromNative(type, value1, value2));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user