From 2c557d62e7e50a15cd39717496251e127364f309 Mon Sep 17 00:00:00 2001 From: PepperLola Date: Tue, 20 Aug 2024 17:58:36 -0700 Subject: [PATCH 01/13] gyro angle support, rate and robot-side outputs TODO --- .../simulation/wpilib_brain/SimInput.ts | 11 +- .../simulation/wpilib_brain/WPILibBrain.ts | 13 +- .../java/com/autodesk/synthesis/Gyro.java | 121 ++++++++++++++++++ .../src/main/java/frc/robot/Robot.java | 11 +- 4 files changed, 138 insertions(+), 18 deletions(-) create mode 100644 simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/Gyro.java diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index 6061d9a47e..a65a9e6c7b 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -40,12 +40,11 @@ export class SimGyroInput implements SimInput { this._robot = robot this._joltID = this._robot.nodeToBody.get(this._robot.rootBody) - if (this._joltID) - this._joltBody = World.PhysicsSystem.GetBody(this._joltID) + if (this._joltID) this._joltBody = World.PhysicsSystem.GetBody(this._joltID) } private GetAxis(axis: Jolt.Vec3): number { - return (this._joltBody?.GetRotation().GetRotationAngle(axis) ?? 0) * 180 / Math.PI + return ((this._joltBody?.GetRotation().GetRotationAngle(axis) ?? 0) * 180) / Math.PI } private GetX(): number { @@ -65,8 +64,8 @@ export class SimGyroInput implements SimInput { const y = this.GetY() const z = this.GetZ() // console.log(`${this._device}\n${x}\n${y}\n${z}`) - SimGyro.SetAngleX(this._device, x); - SimGyro.SetAngleY(this._device, y); - SimGyro.SetAngleZ(this._device, z); + SimGyro.SetAngleX(this._device, x) + SimGyro.SetAngleY(this._device, y) + SimGyro.SetAngleZ(this._device, z) } } diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index 1e83bc686e..57b7b4e453 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -161,15 +161,15 @@ export class SimGyro { private constructor() {} public static SetAngleX(device: string, angle: number): boolean { - return SimGeneric.Set("Gyro", device, ">angle_x", angle); + return SimGeneric.Set("Gyro", device, ">angle_x", angle) } public static SetAngleY(device: string, angle: number): boolean { - return SimGeneric.Set("Gyro", device, ">angle_y", angle); + return SimGeneric.Set("Gyro", device, ">angle_y", angle) } public static SetAngleZ(device: string, angle: number): boolean { - return SimGeneric.Set("Gyro", device, ">angle_z", angle); + return SimGeneric.Set("Gyro", device, ">angle_z", angle) } } @@ -209,6 +209,9 @@ worker.addEventListener("message", (eventData: MessageEvent) => { case "CANEncoder": UpdateSimMap("CANEncoder", device, updateData) break + case "Gyro": + UpdateSimMap("Gyro", device, updateData) + break default: break } @@ -247,7 +250,7 @@ class WPILibBrain extends Brain { return } - this.addSimInput(new SimGyroInput("Gyro:ADXRS450[0]", mechanism)); + this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) } public addSimOutputGroup(device: SimOutputGroup) { @@ -261,7 +264,7 @@ class WPILibBrain extends Brain { public Update(deltaT: number): void { this._simOutputs.forEach(d => d.Update(deltaT)) this._simInputs.forEach(i => i.Update(deltaT)) - console.log(simMap) + // console.log(simMap) } public Enable(): void { diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/Gyro.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/Gyro.java new file mode 100644 index 0000000000..c17f1af4ab --- /dev/null +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/Gyro.java @@ -0,0 +1,121 @@ +package com.autodesk.synthesis; + +import edu.wpi.first.hal.SimBoolean; +import edu.wpi.first.hal.SimDevice; +import edu.wpi.first.hal.SimDevice.Direction; +import edu.wpi.first.hal.SimDouble; + +/** + * Gyro class for easy implementation of documentation-compliant simulation data. + * + * See https://github.com/wpilibsuite/allwpilib/blob/6478ba6e3fa317ee041b8a41e562d925602b6ea4/simulation/halsim_ws_core/doc/hardware_ws_api.md + * for documentation on the WebSocket API Specification. + */ +public class Gyro { + + private SimDevice m_device; + + private SimDouble m_range; + private SimBoolean m_connected; + private SimDouble m_angleX; + private SimDouble m_angleY; + private SimDouble m_angleZ; + private SimDouble m_rateX; + private SimDouble m_rateY; + private SimDouble m_rateZ; + + /** + * Creates a CANMotor sim device in accordance with the WebSocket API Specification. + * + * @param name Name of the Gyro. This is generally the class name of the originating gyro (i.e. "ADXRS450"). + * @param deviceId ID of the Gyro. + */ + public Gyro(String name, int deviceId) { + m_device = SimDevice.create("Gyro:" + name, deviceId); + + m_range = m_device.createDouble("range", Direction.kOutput, 0.0); + m_connected = m_device.createBoolean("connected", Direction.kOutput, false); + m_angleX = m_device.createDouble("angle_x", Direction.kInput, 0.0); + m_angleY = m_device.createDouble("angle_y", Direction.kInput, 0.0); + m_angleZ = m_device.createDouble("angle_z", Direction.kInput, 0.0); + m_rateX = m_device.createDouble("rate_x", Direction.kInput, 0.0); + m_rateY = m_device.createDouble("rate_y", Direction.kInput, 0.0); + m_rateZ = m_device.createDouble("rate_z", Direction.kInput, 0.0); + } + + /** + * Set the range of the gyro. + * + * @param range Range of the gyro + */ + public void setRange(double range) { + if (Double.isNaN(range) || Double.isInfinite(range)) { + range = 0.0; + } + + m_range.set(range); + } + + /** + * Set whether the gyro is connected. + * + * @param connected Whether the gyro is connected + */ + public void setConnected(boolean connected) { + m_connected.set(connected); + } + + /** + * Get the angleX of the gyro. + * + * @return angleX + */ + public double getAngleX() { + return m_angleX.get(); + } + + /** + * Get the angleY of the gyro. + * + * @return angleY + */ + public double getAngleY() { + return m_angleY.get(); + } + + /** + * Get the angleZ of the gyro. + * + * @return angleZ + */ + public double getAngleZ() { + return m_angleZ.get(); + } + + /** + * Get the rateX of the gyro. + * + * @return rateX + */ + public double getRateX() { + return m_rateX.get(); + } + + /** + * Get the rateY of the gyro. + * + * @return rateY + */ + public double getRateY() { + return m_rateY.get(); + } + + /** + * Get the rateZ of the gyro. + * + * @return rateZ + */ + public double getRateZ() { + return m_rateZ.get(); + } +} diff --git a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java index 3dc569c051..70cfac85d9 100644 --- a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java +++ b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java @@ -19,7 +19,8 @@ import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import com.autodesk.synthesis.revrobotics.CANSparkMax; -import com.autodesk.synthesis.Joystick; +// import com.autodesk.synthesis.Joystick; +import com.autodesk.synthesis.Gyro; /** * The VM is configured to automatically run this class, and to call the functions corresponding to @@ -38,8 +39,7 @@ public class Robot extends TimedRobot { private CANSparkMax m_SparkMax = new CANSparkMax(1, MotorType.kBrushless); private TalonFX m_Talon = new TalonFX(2); private XboxController m_Controller = new XboxController(0); - private ADXRS450_Gyro m_Gyro; - private ADXRS450_GyroSim m_GyroSim; + private Gyro m_Gyro = new Gyro("Test Gyro", 1); /** * This function is run when the robot is first started up and should be used for any @@ -50,9 +50,6 @@ public void robotInit() { m_chooser.setDefaultOption("Default Auto", kDefaultAuto); m_chooser.addOption("My Auto", kCustomAuto); SmartDashboard.putData("Auto choices", m_chooser); - m_Gyro = new ADXRS450_Gyro(); - m_GyroSim = new ADXRS450_GyroSim(m_Gyro); - m_Gyro.calibrate(); } /** @@ -111,7 +108,7 @@ public void teleopInit() {} public void teleopPeriodic() { m_Spark1.set(m_Controller.getLeftY()); m_Spark2.set(-m_Controller.getRightY()); - System.out.println(m_Gyro.getAngle()); + System.out.println(m_Gyro.getAngleY()); // m_Spark1.set(0.25); // m_Spark2.set(0.25); m_SparkMax.set(0.75); From 8ce978d0f19320703299851c9d6befe31067d6f7 Mon Sep 17 00:00:00 2001 From: PepperLola Date: Wed, 21 Aug 2024 14:46:39 -0700 Subject: [PATCH 02/13] gyro rate works --- .../systems/simulation/wpilib_brain/SimInput.ts | 17 +++++++++++++++++ .../simulation/wpilib_brain/WPILibBrain.ts | 12 ++++++++++++ 2 files changed, 29 insertions(+) diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index a65a9e6c7b..97a285cfc0 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -59,6 +59,20 @@ export class SimGyroInput implements SimInput { return this.GetAxis(SimGyroInput.AXIS_Z) } + private GetAxisVelocity(axis: "x" | "y" | "z"): number { + const axes = this._joltBody?.GetAngularVelocity() + if (!axes) return 0 + + switch (axis) { + case "x": + return axes.GetX() + case "y": + return axes.GetY() + case "z": + return axes.GetZ() + } + } + public Update(_deltaT: number) { const x = this.GetX() const y = this.GetY() @@ -67,5 +81,8 @@ export class SimGyroInput implements SimInput { SimGyro.SetAngleX(this._device, x) SimGyro.SetAngleY(this._device, y) SimGyro.SetAngleZ(this._device, z) + SimGyro.SetRateX(this._device, this.GetAxisVelocity("x")) + SimGyro.SetRateY(this._device, this.GetAxisVelocity("y")) + SimGyro.SetRateZ(this._device, this.GetAxisVelocity("z")) } } diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index 57b7b4e453..e5edd9de2f 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -171,6 +171,18 @@ export class SimGyro { public static SetAngleZ(device: string, angle: number): boolean { return SimGeneric.Set("Gyro", device, ">angle_z", angle) } + + public static SetRateX(device: string, rate: number): boolean { + return SimGeneric.Set("Gyro", device, ">rate_x", rate) + } + + public static SetRateY(device: string, rate: number): boolean { + return SimGeneric.Set("Gyro", device, ">rate_y", rate) + } + + public static SetRateZ(device: string, rate: number): boolean { + return SimGeneric.Set("Gyro", device, ">rate_z", rate) + } } worker.addEventListener("message", (eventData: MessageEvent) => { From 72af99237a6d768cf14e9a1808486ede8360f4e0 Mon Sep 17 00:00:00 2001 From: PepperLola Date: Wed, 21 Aug 2024 15:38:30 -0700 Subject: [PATCH 03/13] accelerometer data is sent but don't know how to get acceleration from Jolt --- .../simulation/wpilib_brain/SimInput.ts | 39 +++++++- .../simulation/wpilib_brain/WPILibBrain.ts | 38 +++++-- fission/src/ui/panels/WSViewPanel.tsx | 99 +++---------------- .../src/main/java/frc/robot/Robot.java | 9 ++ 4 files changed, 88 insertions(+), 97 deletions(-) diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index 97a285cfc0..d74940619d 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -1,6 +1,6 @@ import World from "@/systems/World" import EncoderStimulus from "../stimulus/EncoderStimulus" -import { SimCANEncoder, SimGyro } from "./WPILibBrain" +import { SimCANEncoder, SimGyro, SimAccel } from "./WPILibBrain" import Mechanism from "@/systems/physics/Mechanism" import Jolt from "@barclah/jolt-physics" import JOLT from "@/util/loading/JoltSyncLoader" @@ -77,7 +77,7 @@ export class SimGyroInput implements SimInput { const x = this.GetX() const y = this.GetY() const z = this.GetZ() - // console.log(`${this._device}\n${x}\n${y}\n${z}`) + SimGyro.SetAngleX(this._device, x) SimGyro.SetAngleY(this._device, y) SimGyro.SetAngleZ(this._device, z) @@ -86,3 +86,38 @@ export class SimGyroInput implements SimInput { SimGyro.SetRateZ(this._device, this.GetAxisVelocity("z")) } } + +export class SimAccelInput implements SimInput { + private _device: string + private _robot: Mechanism + private _joltID?: Jolt.BodyID + private _joltBody?: Jolt.Body + + constructor(device: string, robot: Mechanism) { + this._device = device + this._robot = robot + this._joltID = this._robot.nodeToBody.get(this._robot.rootBody) + + if (this._joltID) this._joltBody = World.PhysicsSystem.GetBody(this._joltID) + } + + private GetAxis(axis: "x" | "y" | "z"): number { + const forces = this._joltBody?.GetAccumulatedForce() + if (!forces) return 0 + + switch (axis) { + case "x": + return forces.GetX() + case "y": + return forces.GetY() + case "z": + return forces.GetZ() + } + } + + public Update(_deltaT: number) { + SimAccel.SetX(this._device, this.GetAxis("x")) + SimAccel.SetY(this._device, this.GetAxis("y")) + SimAccel.SetZ(this._device, this.GetAxis("z")) + } +} diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index e5edd9de2f..30282dc2f5 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -7,7 +7,7 @@ import { SimulationLayer } from "../SimulationSystem" import World from "@/systems/World" import { SimOutputGroup } from "./SimOutput" -import { SimGyroInput, SimInput } from "./SimInput" +import { SimAccelInput, SimGyroInput, SimInput } from "./SimInput" const worker = new WPILibWSWorker() @@ -17,7 +17,7 @@ const CANMOTOR_DUTY_CYCLE = ">() export class SimGeneric { - private constructor() {} + private constructor() { } public static Get(simType: SimType, device: string, field: string, defaultValue?: T): T | undefined { const fieldType = GetFieldType(field) @@ -106,7 +106,7 @@ export class SimGeneric { } export class SimPWM { - private constructor() {} + private constructor() { } public static GetSpeed(device: string): number | undefined { return SimGeneric.Get("PWM", device, PWM_SPEED, 0.0) @@ -118,7 +118,7 @@ export class SimPWM { } export class SimCAN { - private constructor() {} + private constructor() { } public static GetDeviceWithID(id: number, type: SimType): any { const id_exp = /.*\[(\d+)\]/g @@ -138,7 +138,7 @@ export class SimCAN { } export class SimCANMotor { - private constructor() {} + private constructor() { } public static GetDutyCycle(device: string): number | undefined { return SimGeneric.Get("CANMotor", device, CANMOTOR_DUTY_CYCLE, 0.0) @@ -150,7 +150,7 @@ export class SimCANMotor { } export class SimCANEncoder { - private constructor() {} + private constructor() { } public static SetRawInputPosition(device: string, rawInputPosition: number): boolean { return SimGeneric.Set("CANEncoder", device, CANENCODER_RAW_INPUT_POSITION, rawInputPosition) @@ -158,7 +158,7 @@ export class SimCANEncoder { } export class SimGyro { - private constructor() {} + private constructor() { } public static SetAngleX(device: string, angle: number): boolean { return SimGeneric.Set("Gyro", device, ">angle_x", angle) @@ -185,6 +185,22 @@ export class SimGyro { } } +export class SimAccel { + private constructor() { } + + public static SetX(device: string, accel: number): boolean { + return SimGeneric.Set("Accel", device, ">x", accel) + } + + public static SetY(device: string, accel: number): boolean { + return SimGeneric.Set("Accel", device, ">y", accel) + } + + public static SetZ(device: string, accel: number): boolean { + return SimGeneric.Set("Accel", device, ">z", accel) + } +} + worker.addEventListener("message", (eventData: MessageEvent) => { let data: any | undefined try { @@ -224,6 +240,9 @@ worker.addEventListener("message", (eventData: MessageEvent) => { case "Gyro": UpdateSimMap("Gyro", device, updateData) break + case "Accel": + UpdateSimMap("Accel", device, updateData) + break default: break } @@ -262,7 +281,8 @@ class WPILibBrain extends Brain { return } - this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) + // this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) + this.addSimInput(new SimAccelInput("ADXL362[4]", mechanism)) } public addSimOutputGroup(device: SimOutputGroup) { diff --git a/fission/src/ui/panels/WSViewPanel.tsx b/fission/src/ui/panels/WSViewPanel.tsx index f7b47eff28..31699e2164 100644 --- a/fission/src/ui/panels/WSViewPanel.tsx +++ b/fission/src/ui/panels/WSViewPanel.tsx @@ -27,16 +27,19 @@ const TypoStyled = styled(Typography)({ }) function generateTableBody() { + const names: SimType[] = ["PWM", "SimDevice", "CANMotor", "CANEncoder", "Gyro", "Accel"] + return ( - {simMap.has("PWM") ? ( - [...simMap.get("PWM")!.entries()] - .filter(x => x[1][" { - return ( + {names.map(name => + simMap.has(name) ? ( + [...simMap.get(name)!.entries()] + // most devices don't have !Object.keys(x[1]).includes(" ( - PWM + {name} {x[0]} @@ -45,86 +48,10 @@ function generateTableBody() { {JSON.stringify(x[1])} - ) - }) - ) : ( - <> - )} - {simMap.has("SimDevice") ? ( - [...simMap.get("SimDevice")!.entries()].map(x => { - return ( - - - SimDevice - - - {x[0]} - - - {JSON.stringify(x[1])} - - - ) - }) - ) : ( - <> - )} - {simMap.has("CANMotor") ? ( - [...simMap.get("CANMotor")!.entries()].map(x => { - return ( - - - CAN Motor - - - {x[0]} - - - {JSON.stringify(x[1])} - - - ) - }) - ) : ( - <> - )} - {simMap.has("CANEncoder") ? ( - [...simMap.get("CANEncoder")!.entries()].map(x => { - return ( - - - CAN Encoder - - - {x[0]} - - - {JSON.stringify(x[1])} - - - ) - }) - ) : ( - <> - )} - {simMap.has("Gyro") ? ( - [...simMap.get("Gyro")!.entries()].map(x => { - return ( - - - Gyro - - - {x[0]} - - - {JSON.stringify(x[1])} - - - ) - }) - ) : ( - <> + )) + ) : ( + <> + ) )} ) diff --git a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java index 70cfac85d9..3a8a2b4901 100644 --- a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java +++ b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java @@ -4,13 +4,17 @@ package frc.robot; +import com.ctre.phoenix6.hardware.Pigeon2; import com.ctre.phoenix6.hardware.TalonFX; +import com.kauailabs.navx.frc.AHRS; import com.revrobotics.CANSparkBase.IdleMode; // import com.revrobotics.CANSparkMax; import com.revrobotics.CANSparkLowLevel.MotorType; +import edu.wpi.first.wpilibj.ADXL362; import edu.wpi.first.wpilibj.ADXRS450_Gyro; import edu.wpi.first.wpilibj.AnalogGyro; +import edu.wpi.first.wpilibj.SPI; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.XboxController; import edu.wpi.first.wpilibj.motorcontrol.Spark; @@ -40,6 +44,11 @@ public class Robot extends TimedRobot { private TalonFX m_Talon = new TalonFX(2); private XboxController m_Controller = new XboxController(0); private Gyro m_Gyro = new Gyro("Test Gyro", 1); + private AHRS m_NavX = new AHRS(); + // Creates an ADXL362 accelerometer object on the MXP SPI port + // with a measurement range from -8 to 8 G's + private ADXL362 m_Accelerometer = new ADXL362(SPI.Port.kMXP, ADXL362.Range.k8G); + private Pigeon2 m_Pigeon2 = new Pigeon2(0); /** * This function is run when the robot is first started up and should be used for any From 9f9948d275d78ebc08ccdf76f996b5e89e42133e Mon Sep 17 00:00:00 2001 From: PepperLola Date: Thu, 22 Aug 2024 17:53:53 -0700 Subject: [PATCH 04/13] hopefully fission-side DIO/AIO is done --- .../simulation/wpilib_brain/SimInput.ts | 44 ++++++- .../simulation/wpilib_brain/SimOutput.ts | 28 ++++- .../simulation/wpilib_brain/WPILibBrain.ts | 114 ++++++++++++++++-- .../rio-config/RCConfigCANGroupModal.tsx | 2 +- .../rio-config/RCConfigPWMGroupModal.tsx | 2 +- fission/src/ui/panels/WSViewPanel.tsx | 6 +- .../src/main/java/frc/robot/Robot.java | 18 ++- 7 files changed, 191 insertions(+), 23 deletions(-) diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index 87b0367969..974503b5b0 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -1,6 +1,6 @@ import World from "@/systems/World" import EncoderStimulus from "../stimulus/EncoderStimulus" -import { SimCANEncoder, SimGyro, SimAccel } from "./WPILibBrain" +import { SimCANEncoder, SimGyro, SimAccel, SimDIO as WSSimDIO, SimAI } from "./WPILibBrain" import Mechanism from "@/systems/physics/Mechanism" import Jolt from "@barclah/jolt-physics" import JOLT from "@/util/loading/JoltSyncLoader" @@ -120,3 +120,45 @@ export class SimAccelInput implements SimInput { SimAccel.SetZ(this._device, this.GetAxis("z")) } } + +export class SimDIO implements SimInput { + private _device: string + private _valueSupplier?: () => boolean + + /** + * Creates a Simulation Digital Input/Output object. + * + * @param device Device ID + * @param valueSupplier Called each frame and returns what the value should be set to. Don't specify if DIO should be treated as an output. + */ + constructor(device: string, valueSupplier?: () => boolean) { + this._device = device + this._valueSupplier = valueSupplier + } + + public SetValue(value: boolean) { + WSSimDIO.SetValue(this._device, value); + } + + public GetValue(): boolean { + return WSSimDIO.GetValue(this._device) + } + + public Update(_deltaT: number) { + if (this._valueSupplier) this.SetValue(this._valueSupplier()) + } +} + +export class SimAnalogInput implements SimInput { + private _device: string + private _valueSupplier: () => number + + constructor(device: string, valueSupplier: () => number) { + this._device = device + this._valueSupplier = valueSupplier + } + + public Update(_deltaT: number) { + SimAI.SetValue(this._device, this._valueSupplier()) + } +} diff --git a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts index 40fe5494e9..a4ce35d7ff 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts @@ -2,7 +2,7 @@ import Driver from "../driver/Driver" import HingeDriver from "../driver/HingeDriver" import SliderDriver from "../driver/SliderDriver" import WheelDriver from "../driver/WheelDriver" -import { SimCAN, SimPWM, SimType } from "./WPILibBrain" +import { SimAO, SimCAN, SimPWM, SimType } from "./WPILibBrain" // TODO: Averaging is probably not the right solution (if we want large output groups) // We can keep averaging, but we need a better ui for creating one to one (or just small) output groups @@ -10,14 +10,24 @@ import { SimCAN, SimPWM, SimType } from "./WPILibBrain" // We instead want a system where every driver gets (a) unique motor(s) that control it // That way a single driver might get the average of two motors or something, if it has two motors to control it // A system where motors a drivers are visually "linked" with "threads" in the UI would work well in my opinion -export abstract class SimOutputGroup { + +export abstract class SimOutput { public name: string + + constructor(name: string) { + this.name = name + } + + public abstract Update(deltaT: number): void +} + +export abstract class SimOutputGroup extends SimOutput { public ports: number[] public drivers: Driver[] public type: SimType public constructor(name: string, ports: number[], drivers: Driver[], type: SimType) { - this.name = name + super(name) this.ports = ports this.drivers = drivers this.type = type @@ -72,3 +82,15 @@ export class CANOutputGroup extends SimOutputGroup { }) } } + +export class SimAnalogOutput extends SimOutput { + public constructor(name: string) { + super(name) + } + + public GetVoltage(): number { + return SimAO.GetVoltage(this.name) + } + + public Update(_deltaT: number) { } +} diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index 1e046a68a7..a6495ac20a 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -5,8 +5,8 @@ import WPILibWSWorker from "./WPILibWSWorker?worker" import { SimulationLayer } from "../SimulationSystem" import World from "@/systems/World" -import { SimOutputGroup } from "./SimOutput" -import { SimAccelInput, SimGyroInput, SimInput } from "./SimInput" +import { SimAnalogOutput, SimOutput, SimOutputGroup } from "./SimOutput" +import { SimAccelInput, SimInput, SimDIO as SimDIOIn, SimAnalogInput } from "./SimInput" const worker = new WPILibWSWorker() const PWM_SPEED = ">() export class SimGeneric { private constructor() { } + public static Get(simType: SimType, device: string, field: string): T | undefined; + public static Get(simType: SimType, device: string, field: string, defaultValue: T): T; public static Get(simType: SimType, device: string, field: string, defaultValue?: T): T | undefined { const fieldType = GetFieldType(field) if (fieldType != FieldType.Read && fieldType != FieldType.Both) { @@ -195,27 +201,27 @@ export class SimGyro { private constructor() { } public static SetAngleX(device: string, angle: number): boolean { - return SimGeneric.Set("Gyro", device, ">angle_x", angle) + return SimGeneric.Set(SimType.Gyro, device, ">angle_x", angle) } public static SetAngleY(device: string, angle: number): boolean { - return SimGeneric.Set("Gyro", device, ">angle_y", angle) + return SimGeneric.Set(SimType.Gyro, device, ">angle_y", angle) } public static SetAngleZ(device: string, angle: number): boolean { - return SimGeneric.Set("Gyro", device, ">angle_z", angle) + return SimGeneric.Set(SimType.Gyro, device, ">angle_z", angle) } public static SetRateX(device: string, rate: number): boolean { - return SimGeneric.Set("Gyro", device, ">rate_x", rate) + return SimGeneric.Set(SimType.Gyro, device, ">rate_x", rate) } public static SetRateY(device: string, rate: number): boolean { - return SimGeneric.Set("Gyro", device, ">rate_y", rate) + return SimGeneric.Set(SimType.Gyro, device, ">rate_y", rate) } public static SetRateZ(device: string, rate: number): boolean { - return SimGeneric.Set("Gyro", device, ">rate_z", rate) + return SimGeneric.Set(SimType.Gyro, device, ">rate_z", rate) } } @@ -223,15 +229,92 @@ export class SimAccel { private constructor() { } public static SetX(device: string, accel: number): boolean { - return SimGeneric.Set("Accel", device, ">x", accel) + return SimGeneric.Set(SimType.Accel, device, ">x", accel) } public static SetY(device: string, accel: number): boolean { - return SimGeneric.Set("Accel", device, ">y", accel) + return SimGeneric.Set(SimType.Accel, device, ">y", accel) } public static SetZ(device: string, accel: number): boolean { - return SimGeneric.Set("Accel", device, ">z", accel) + return SimGeneric.Set(SimType.Accel, device, ">z", accel) + } +} + +export class SimDIO { + private constructor() { } + + public static SetValue(device: string, value: boolean): boolean { + return SimGeneric.Set(SimType.DIO, device, "<>value", +value); + } + + public static GetValue(device: string): boolean { + return SimGeneric.Get(SimType.DIO, device, "<>value", false) + } +} + +export class SimAI { + constructor() { } + + public static SetValue(device: string, value: number): boolean { + return SimGeneric.Set(SimType.AI, device, ">voltage", value) + } + + /** + * The number of averaging bits + */ + public static GetAvgBits(device: string) { + return SimGeneric.Get(SimType.AI, device, "voltage", voltage) + } + /** + * If the accumulator is initialized in the robot program + */ + public static GetAccumInit(device: string) { + return SimGeneric.Get(SimType.AI, device, "accum_value", accum_value) + } + /** + * The number of accumulated values + */ + public static SetAccumCount(device: string, accum_count: number) { + return SimGeneric.Set(SimType.AI, device, ">accum_count", accum_count) + } + /** + * The center value of the accumulator + */ + public static GetAccumCenter(device: string) { + return SimGeneric.Get(SimType.AI, device, "voltage", 0.0) } } @@ -282,7 +365,7 @@ function UpdateSimMap(type: SimType, device: string, updateData: DeviceData) { class WPILibBrain extends Brain { private _simLayer: SimulationLayer - private _simOutputs: SimOutputGroup[] = [] + private _simOutputs: SimOutput[] = [] private _simInputs: SimInput[] = [] constructor(mechanism: Mechanism) { @@ -297,9 +380,13 @@ class WPILibBrain extends Brain { // this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) // this.addSimInput(new SimAccelInput("ADXL362[4]", mechanism)) + // this.addSimInput(new SimDIOIn("In[0]", () => Math.random() > 0.5)) + // this.addSimInput(new SimDIOIn("Out[1]")) + // this.addSimInput(new SimAnalogInput("In[0]", () => Math.random() * 12)) + // this.addSimOutput(new SimAnalogOutput("Out[1]")) } - public addSimOutputGroup(device: SimOutputGroup) { + public addSimOutput(device: SimOutput) { this._simOutputs.push(device) } @@ -310,6 +397,7 @@ class WPILibBrain extends Brain { public Update(deltaT: number): void { this._simOutputs.forEach(d => d.Update(deltaT)) this._simInputs.forEach(i => i.Update(deltaT)) + console.log(simMap) } public Enable(): void { diff --git a/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx b/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx index 624e133708..1584ba3d50 100644 --- a/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx +++ b/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx @@ -47,7 +47,7 @@ const RCConfigCANGroupModal: React.FC = ({ modalId }) => { acceptName="Done" onAccept={() => { // no eslint complain - brain.addSimOutputGroup(new CANOutputGroup(name, checkedPorts, checkedDrivers)) + brain.addSimOutput(new CANOutputGroup(name, checkedPorts, checkedDrivers)) console.log(name, checkedPorts, checkedDrivers) const replacer = (_: unknown, value: unknown) => { if (value instanceof Map) { diff --git a/fission/src/ui/modals/configuring/rio-config/RCConfigPWMGroupModal.tsx b/fission/src/ui/modals/configuring/rio-config/RCConfigPWMGroupModal.tsx index 700094449c..3a227dc4a2 100644 --- a/fission/src/ui/modals/configuring/rio-config/RCConfigPWMGroupModal.tsx +++ b/fission/src/ui/modals/configuring/rio-config/RCConfigPWMGroupModal.tsx @@ -47,7 +47,7 @@ const RCConfigPWMGroupModal: React.FC = ({ modalId }) => { acceptName="Done" onAccept={() => { // no eslint complain - brain.addSimOutputGroup(new PWMOutputGroup(name, checkedPorts, checkedDrivers)) + brain.addSimOutput(new PWMOutputGroup(name, checkedPorts, checkedDrivers)) console.log(name, checkedPorts, checkedDrivers) }} onCancel={() => { diff --git a/fission/src/ui/panels/WSViewPanel.tsx b/fission/src/ui/panels/WSViewPanel.tsx index 6e90cfbaff..9dd2b6fbdd 100644 --- a/fission/src/ui/panels/WSViewPanel.tsx +++ b/fission/src/ui/panels/WSViewPanel.tsx @@ -35,7 +35,9 @@ function formatMap(map: Map): string { } function generateTableBody() { - const names: SimType[] = ["PWM", "SimDevice", "CANMotor", "CANEncoder", "Gyro", "Accel"] + const names: SimType[] = [SimType.PWM, SimType.SimDevice, SimType.CANMotor, SimType.CANEncoder, SimType.Gyro, SimType.Accel, SimType.DIO, SimType.AI, SimType.AO] + + console.log(simMap) return ( @@ -43,7 +45,7 @@ function generateTableBody() { simMap.has(name) ? ( [...simMap.get(name)!.entries()] // most devices don't have !Object.keys(x[1]).includes(" !Object.keys(x[1]).includes(" ( diff --git a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java index e3febe19b3..891e77651f 100644 --- a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java +++ b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java @@ -13,6 +13,10 @@ import edu.wpi.first.wpilibj.ADXL362; import edu.wpi.first.wpilibj.ADXRS450_Gyro; import edu.wpi.first.wpilibj.AnalogGyro; +import edu.wpi.first.wpilibj.AnalogInput; +import edu.wpi.first.wpilibj.AnalogOutput; +import edu.wpi.first.wpilibj.DigitalInput; +import edu.wpi.first.wpilibj.DigitalOutput; import edu.wpi.first.wpilibj.SPI; import edu.wpi.first.wpilibj.TimedRobot; @@ -50,6 +54,10 @@ public class Robot extends TimedRobot { // with a measurement range from -8 to 8 G's private ADXL362 m_Accelerometer = new ADXL362(SPI.Port.kMXP, ADXL362.Range.k8G); private Pigeon2 m_Pigeon2 = new Pigeon2(0); + private DigitalInput m_DI = new DigitalInput(0); + private DigitalOutput m_DO = new DigitalOutput(1); + private AnalogInput m_AI = new AnalogInput(0); + private AnalogOutput m_AO = new AnalogOutput(1); private CANSparkMax m_SparkMax1 = new CANSparkMax(1, MotorType.kBrushless); private CANSparkMax m_SparkMax2 = new CANSparkMax(2, MotorType.kBrushless); @@ -94,6 +102,8 @@ public void autonomousInit() { m_autoSelected = m_chooser.getSelected(); // m_autoSelected = SmartDashboard.getString("Auto Selector", kDefaultAuto); System.out.println("Auto selected: " + m_autoSelected); + m_DO.set(true); + m_AO.setVoltage(0.0); } /** This function is called periodically during autonomous. */ @@ -135,14 +145,17 @@ public void autonomousPeriodic() { /** This function is called once when teleop is enabled. */ @Override - public void teleopInit() { } + public void teleopInit() { + m_DO.set(false); + m_AO.setVoltage(6.0); + } /** This function is called periodically during operator control. */ @Override public void teleopPeriodic() { m_Spark1.set(m_Controller.getLeftY()); m_Spark2.set(-m_Controller.getRightY()); - System.out.println(m_Gyro.getAngleY()); + System.out.println(m_DI.get()); // m_Spark1.set(0.25); // m_Spark2.set(0.25); m_Talon.set(-0.5); @@ -164,6 +177,7 @@ public void disabledInit() { m_SparkMax4.set(0.0); m_SparkMax5.set(0.0); m_SparkMax6.set(0.0); + m_AO.setVoltage(12.0); } /** This function is called periodically when disabled. */ From 88c551b7b3bbcd0f95fe9632d52954799577ec42 Mon Sep 17 00:00:00 2001 From: PepperLola Date: Mon, 26 Aug 2024 16:36:37 -0700 Subject: [PATCH 05/13] digital and analog inputs work but can't be configured show joint name in CAN config panel update robot code to use all the sim things --- fission/src/Synthesis.tsx | 6 -- .../simulation/wpilib_brain/SimOutput.ts | 1 - .../simulation/wpilib_brain/WPILibBrain.ts | 23 ++--- .../rio-config/RCConfigCANGroupModal.tsx | 14 +-- .../autodesk/synthesis/io/AnalogInput.java | 90 +++++++++++++++++++ .../autodesk/synthesis/io/AnalogOutput.java | 32 +++++++ .../autodesk/synthesis/io/DigitalInput.java | 33 +++++++ .../autodesk/synthesis/io/DigitalOutput.java | 38 ++++++++ .../src/main/java/frc/robot/Robot.java | 27 ++---- 9 files changed, 212 insertions(+), 52 deletions(-) create mode 100644 simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/AnalogInput.java create mode 100644 simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/AnalogOutput.java create mode 100644 simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/DigitalInput.java create mode 100644 simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/DigitalOutput.java diff --git a/fission/src/Synthesis.tsx b/fission/src/Synthesis.tsx index badb33a281..7052b887d5 100644 --- a/fission/src/Synthesis.tsx +++ b/fission/src/Synthesis.tsx @@ -47,9 +47,7 @@ import ChooseInputSchemePanel from "./ui/panels/configuring/ChooseInputSchemePan import ProgressNotifications from "./ui/components/ProgressNotification.tsx" import SceneOverlay from "./ui/components/SceneOverlay.tsx" -import WPILibWSWorker from "@/systems/simulation/wpilib_brain/WPILibWSWorker.ts?worker" import WSViewPanel from "./ui/panels/WSViewPanel.tsx" -import Lazy from "./util/Lazy.ts" import RCConfigPWMGroupModal from "@/modals/configuring/rio-config/RCConfigPWMGroupModal.tsx" import RCConfigCANGroupModal from "@/modals/configuring/rio-config/RCConfigCANGroupModal.tsx" @@ -61,8 +59,6 @@ import PreferencesSystem from "./systems/preferences/PreferencesSystem.ts" import APSManagementModal from "./ui/modals/APSManagementModal.tsx" import ConfigurePanel from "./ui/panels/configuring/assembly-config/ConfigurePanel.tsx" -const worker = new Lazy(() => new WPILibWSWorker()) - function Synthesis() { const { openModal, closeModal, getActiveModalElement } = useModalManager(initialModals) const { openPanel, closePanel, closeAllPanels, getActivePanelElements } = usePanelManager(initialPanels) @@ -93,8 +89,6 @@ function Synthesis() { setConsentPopupDisable(false) } - worker.getValue() - let mainLoopHandle = 0 const mainLoop = () => { mainLoopHandle = requestAnimationFrame(mainLoop) diff --git a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts index a4ce35d7ff..4a64f221f2 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts @@ -45,7 +45,6 @@ export class PWMOutputGroup extends SimOutputGroup { const average = this.ports.reduce((sum, port) => { const speed = SimPWM.GetSpeed(`${port}`) ?? 0 - console.debug(port, speed) return sum + speed }, 0) / this.ports.length diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index a6495ac20a..7eaad915e8 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -1,6 +1,7 @@ import Mechanism from "@/systems/physics/Mechanism" import Brain from "../Brain" +import Lazy from "@/util/Lazy.ts" import WPILibWSWorker from "./WPILibWSWorker?worker" import { SimulationLayer } from "../SimulationSystem" import World from "@/systems/World" @@ -8,7 +9,8 @@ import World from "@/systems/World" import { SimAnalogOutput, SimOutput, SimOutputGroup } from "./SimOutput" import { SimAccelInput, SimInput, SimDIO as SimDIOIn, SimAnalogInput } from "./SimInput" -const worker = new WPILibWSWorker() +const worker: Lazy = new Lazy(() => new WPILibWSWorker()) + const PWM_SPEED = " } -worker.addEventListener("message", (eventData: MessageEvent) => { +worker.getValue().addEventListener("message", (eventData: MessageEvent) => { let data: WSMessage | undefined if (typeof eventData.data == "object") { @@ -338,7 +340,7 @@ worker.addEventListener("message", (eventData: MessageEvent) => { } } - if (!data?.type || !(Object.values(SimType) as string[]).includes(data.type) || data.device.split(" ")[0] != "SYN") + if (!data?.type || !(Object.values(SimType) as string[]).includes(data.type))// || data.device.split(" ")[0] != "SYN") return UpdateSimMap(data.type as SimType, data.device, data.data) @@ -380,10 +382,10 @@ class WPILibBrain extends Brain { // this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) // this.addSimInput(new SimAccelInput("ADXL362[4]", mechanism)) - // this.addSimInput(new SimDIOIn("In[0]", () => Math.random() > 0.5)) - // this.addSimInput(new SimDIOIn("Out[1]")) - // this.addSimInput(new SimAnalogInput("In[0]", () => Math.random() * 12)) - // this.addSimOutput(new SimAnalogOutput("Out[1]")) + // this.addSimInput(new SimDIOIn("SYN DI[0]", () => Math.random() > 0.5)) + // this.addSimInput(new SimDIOIn("SYN DO[1]")) + // this.addSimInput(new SimAnalogInput("SYN AI[0]", () => Math.random() * 12)) + // this.addSimOutput(new SimAnalogOutput("SYN AO[1]")) } public addSimOutput(device: SimOutput) { @@ -397,15 +399,14 @@ class WPILibBrain extends Brain { public Update(deltaT: number): void { this._simOutputs.forEach(d => d.Update(deltaT)) this._simInputs.forEach(i => i.Update(deltaT)) - console.log(simMap) } public Enable(): void { - worker.postMessage({ command: "connect" }) + worker.getValue().postMessage({ command: "connect" }) } public Disable(): void { - worker.postMessage({ command: "disconnect" }) + worker.getValue().postMessage({ command: "disconnect" }) } } diff --git a/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx b/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx index 1584ba3d50..075eda2d2f 100644 --- a/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx +++ b/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx @@ -25,13 +25,11 @@ const RCConfigCANGroupModal: React.FC = ({ modalId }) => { let brain: WPILibBrain const miraObjs = [...World.SceneRenderer.sceneObjects.entries()].filter(x => x[1] instanceof MirabufSceneObject) - console.log(`Number of mirabuf scene objects: ${miraObjs.length}`) if (miraObjs.length > 0) { const mechanism = (miraObjs[0][1] as MirabufSceneObject).mechanism simLayer = World.SimulationSystem.GetSimulationLayer(mechanism) drivers = simLayer?.drivers ?? [] - brain = new WPILibBrain(mechanism) - simLayer?.SetBrain(brain) + brain = simLayer?.brain as WPILibBrain } const cans = simMap.get(SimType.CANMotor) ?? new Map>() @@ -49,14 +47,6 @@ const RCConfigCANGroupModal: React.FC = ({ modalId }) => { // no eslint complain brain.addSimOutput(new CANOutputGroup(name, checkedPorts, checkedDrivers)) console.log(name, checkedPorts, checkedDrivers) - const replacer = (_: unknown, value: unknown) => { - if (value instanceof Map) { - return Object.fromEntries(value) - } else { - return value - } - } - console.log(JSON.stringify(simMap, replacer)) }} onCancel={() => { openModal("roborio") @@ -92,7 +82,7 @@ const RCConfigCANGroupModal: React.FC = ({ modalId }) => { {drivers.map((driver, idx) => ( { if (checked && !checkedDrivers.includes(driver)) { diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/AnalogInput.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/AnalogInput.java new file mode 100644 index 0000000000..d093a510c4 --- /dev/null +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/AnalogInput.java @@ -0,0 +1,90 @@ +package com.autodesk.synthesis.io; + +import edu.wpi.first.hal.SimBoolean; +import edu.wpi.first.hal.SimDevice; +import edu.wpi.first.hal.SimDouble; +import edu.wpi.first.hal.SimInt; +import edu.wpi.first.hal.SimDevice.Direction; + +public class AnalogInput extends edu.wpi.first.wpilibj.AnalogInput { + private SimDevice m_device; + + private SimBoolean m_init; + private SimInt m_avgBits; + private SimInt m_oversampleBits; + private SimDouble m_voltage; + private SimBoolean m_accumInit; + private SimInt m_accumValue; + private SimInt m_accumCount; + private SimInt m_accumCenter; + private SimInt m_accumDeadband; + + public AnalogInput(int channel) { + super(channel); + + m_device = SimDevice.create("AI:SYN AI", channel); + + m_init = m_device.createBoolean("init", Direction.kOutput, true); + m_avgBits = m_device.createInt("avg_bits", Direction.kOutput, 0); + m_oversampleBits = m_device.createInt("oversample_bits", Direction.kOutput, 0); + m_voltage = m_device.createDouble("voltage", Direction.kInput, 0.0); + m_accumInit = m_device.createBoolean("accum_init", Direction.kOutput, false); + m_accumValue = m_device.createInt("accum_value", Direction.kInput, 0); + m_accumCount = m_device.createInt("accum_count", Direction.kInput, 0); + m_accumCenter = m_device.createInt("accum_center", Direction.kOutput, 0); + m_accumDeadband = m_device.createInt("accum_deadband", Direction.kOutput, 0); + + this.setSimDevice(m_device); + } + + @Override + public double getVoltage() { + return m_voltage.get(); + } + + @Override + public int getAverageBits() { + return m_avgBits.get(); + } + + @Override + public void setAverageBits(int bits) { + m_avgBits.set(bits); + } + + @Override + public int getOversampleBits() { + return m_oversampleBits.get(); + } + + @Override + public void setOversampleBits(int bits) { + m_oversampleBits.set(bits); + } + + @Override + public void initAccumulator() { + super.initAccumulator(); + m_accumInit.set(true); + } + + @Override + public long getAccumulatorValue() { + return m_accumValue.get(); + } + + @Override + public long getAccumulatorCount() { + return m_accumCount.get(); + } + + @Override + public void setAccumulatorCenter(int center) { + m_accumCenter.set(center); + } + + @Override + public void setAccumulatorDeadband(int deadband) { + m_accumDeadband.set(deadband); + } +} diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/AnalogOutput.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/AnalogOutput.java new file mode 100644 index 0000000000..46b66b05b9 --- /dev/null +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/AnalogOutput.java @@ -0,0 +1,32 @@ +package com.autodesk.synthesis.io; + +import edu.wpi.first.hal.SimBoolean; +import edu.wpi.first.hal.SimDevice; +import edu.wpi.first.hal.SimDouble; +import edu.wpi.first.hal.SimDevice.Direction; + +public class AnalogOutput extends edu.wpi.first.wpilibj.AnalogOutput { + private SimDevice m_device; + + private SimBoolean m_init; + private SimDouble m_voltage; + + public AnalogOutput(int channel) { + super(channel); + + m_device = SimDevice.create("AI:SYN AO", channel); + + m_init = m_device.createBoolean("init", Direction.kOutput, true); + m_voltage = m_device.createDouble("voltage", Direction.kOutput, 0.0); + } + + @Override + public void setVoltage(double voltage) { + m_voltage.set(voltage); + } + + @Override + public double getVoltage() { + return m_voltage.get(); + } +} diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/DigitalInput.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/DigitalInput.java new file mode 100644 index 0000000000..e4df20931f --- /dev/null +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/DigitalInput.java @@ -0,0 +1,33 @@ +package com.autodesk.synthesis.io; + +import edu.wpi.first.hal.SimBoolean; +import edu.wpi.first.hal.SimDevice; +import edu.wpi.first.hal.SimDouble; +import edu.wpi.first.hal.SimDevice.Direction; + +public class DigitalInput extends edu.wpi.first.wpilibj.DigitalInput { + private SimDevice m_device; + + private SimBoolean m_init; + private SimBoolean m_input; + private SimBoolean m_value; + private SimDouble m_pulseLength; // unused but in HALSim spec + + public DigitalInput(int channel) { + super(channel); + + m_device = SimDevice.create("DIO:SYN DI", channel); + + m_init = m_device.createBoolean("init", Direction.kOutput, true); + m_input = m_device.createBoolean("input", Direction.kOutput, true); + m_value = m_device.createBoolean("value", Direction.kBidir, false); + m_pulseLength = m_device.createDouble("pulse_length", Direction.kOutput, 0.0); + + this.setSimDevice(m_device); + } + + @Override + public boolean get() { + return m_value.get(); + } +} diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/DigitalOutput.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/DigitalOutput.java new file mode 100644 index 0000000000..ea76679485 --- /dev/null +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/io/DigitalOutput.java @@ -0,0 +1,38 @@ +package com.autodesk.synthesis.io; + +import edu.wpi.first.hal.SimBoolean; +import edu.wpi.first.hal.SimDevice; +import edu.wpi.first.hal.SimDouble; +import edu.wpi.first.hal.SimDevice.Direction; + +public class DigitalOutput extends edu.wpi.first.wpilibj.DigitalOutput { + private SimDevice m_device; + + private SimBoolean m_init; + private SimBoolean m_input; + private SimBoolean m_value; + private SimDouble m_pulseLength; // unused but in HALSim spec + + public DigitalOutput(int channel) { + super(channel); + + m_device = SimDevice.create("DIO:SYN DO", channel); + + m_init = m_device.createBoolean("init", Direction.kOutput, true); + m_input = m_device.createBoolean("input", Direction.kOutput, true); + m_value = m_device.createBoolean("value", Direction.kBidir, false); + m_pulseLength = m_device.createDouble("pulse_length", Direction.kOutput, 0.0); + + this.setSimDevice(m_device); + } + + @Override + public boolean get() { + return m_value.get(); + } + + @Override + public void set(boolean value) { + m_value.set(value); + } +} diff --git a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java index 891e77651f..3f85f59bc4 100644 --- a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java +++ b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java @@ -4,20 +4,9 @@ package frc.robot; -import com.ctre.phoenix6.hardware.Pigeon2; -import com.kauailabs.navx.frc.AHRS; -import com.revrobotics.CANSparkBase.IdleMode; -// import com.revrobotics.CANSparkMax; import com.revrobotics.CANSparkLowLevel.MotorType; -import edu.wpi.first.wpilibj.ADXL362; -import edu.wpi.first.wpilibj.ADXRS450_Gyro; -import edu.wpi.first.wpilibj.AnalogGyro; -import edu.wpi.first.wpilibj.AnalogInput; -import edu.wpi.first.wpilibj.AnalogOutput; -import edu.wpi.first.wpilibj.DigitalInput; -import edu.wpi.first.wpilibj.DigitalOutput; -import edu.wpi.first.wpilibj.SPI; +import com.autodesk.synthesis.io.*; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.motorcontrol.Spark; @@ -26,7 +15,6 @@ import edu.wpi.first.wpilibj.XboxController; import com.autodesk.synthesis.revrobotics.CANSparkMax; -import com.autodesk.synthesis.Gyro; import com.autodesk.synthesis.ctre.TalonFX; /** @@ -48,12 +36,7 @@ public class Robot extends TimedRobot { private Spark m_Spark2 = new Spark(1); private TalonFX m_Talon = new TalonFX(2); private XboxController m_Controller = new XboxController(0); - private Gyro m_Gyro = new Gyro("Test Gyro", 1); - private AHRS m_NavX = new AHRS(); - // Creates an ADXL362 accelerometer object on the MXP SPI port - // with a measurement range from -8 to 8 G's - private ADXL362 m_Accelerometer = new ADXL362(SPI.Port.kMXP, ADXL362.Range.k8G); - private Pigeon2 m_Pigeon2 = new Pigeon2(0); + private DigitalInput m_DI = new DigitalInput(0); private DigitalOutput m_DO = new DigitalOutput(1); private AnalogInput m_AI = new AnalogInput(0); @@ -155,9 +138,9 @@ public void teleopInit() { public void teleopPeriodic() { m_Spark1.set(m_Controller.getLeftY()); m_Spark2.set(-m_Controller.getRightY()); - System.out.println(m_DI.get()); - // m_Spark1.set(0.25); - // m_Spark2.set(0.25); + System.out.println("IN: " + m_DI.get()); + System.out.println("OUT: " + m_DO.get()); + System.out.println("AI: " + m_AI.getVoltage()); m_Talon.set(-0.5); m_SparkMax1.set(-0.75); m_SparkMax2.set(-0.75); From e6d3522349e6f6343fdd75078fdfdcfdb518168f Mon Sep 17 00:00:00 2001 From: PepperLola Date: Mon, 26 Aug 2024 16:40:38 -0700 Subject: [PATCH 06/13] ran formatter and fixed lint errors --- .../simulation/wpilib_brain/SimInput.ts | 2 +- .../simulation/wpilib_brain/SimOutput.ts | 2 +- .../simulation/wpilib_brain/WPILibBrain.ts | 35 +++++++++---------- .../rio-config/RCConfigCANGroupModal.tsx | 2 +- fission/src/ui/panels/WSViewPanel.tsx | 14 ++++++-- .../ConfigureSubsystemsInterface.tsx | 2 +- 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index 974503b5b0..88e930e04d 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -137,7 +137,7 @@ export class SimDIO implements SimInput { } public SetValue(value: boolean) { - WSSimDIO.SetValue(this._device, value); + WSSimDIO.SetValue(this._device, value) } public GetValue(): boolean { diff --git a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts index 4a64f221f2..85521c7bed 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts @@ -91,5 +91,5 @@ export class SimAnalogOutput extends SimOutput { return SimAO.GetVoltage(this.name) } - public Update(_deltaT: number) { } + public Update(_deltaT: number) {} } diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index 7eaad915e8..ccd672e54a 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -6,8 +6,8 @@ import WPILibWSWorker from "./WPILibWSWorker?worker" import { SimulationLayer } from "../SimulationSystem" import World from "@/systems/World" -import { SimAnalogOutput, SimOutput, SimOutputGroup } from "./SimOutput" -import { SimAccelInput, SimInput, SimDIO as SimDIOIn, SimAnalogInput } from "./SimInput" +import { SimOutput } from "./SimOutput" +import { SimInput } from "./SimInput" const worker: Lazy = new Lazy(() => new WPILibWSWorker()) @@ -35,7 +35,7 @@ export enum SimType { Accel = "Accel", DIO = "DIO", AI = "AI", - AO = "AO" + AO = "AO", } enum FieldType { @@ -66,10 +66,10 @@ type DeviceData = Map export const simMap = new Map>() export class SimGeneric { - private constructor() { } + private constructor() {} - public static Get(simType: SimType, device: string, field: string): T | undefined; - public static Get(simType: SimType, device: string, field: string, defaultValue: T): T; + public static Get(simType: SimType, device: string, field: string): T | undefined + public static Get(simType: SimType, device: string, field: string, defaultValue: T): T public static Get(simType: SimType, device: string, field: string, defaultValue?: T): T | undefined { const fieldType = GetFieldType(field) if (fieldType != FieldType.Read && fieldType != FieldType.Both) { @@ -130,7 +130,7 @@ export class SimGeneric { } export class SimPWM { - private constructor() { } + private constructor() {} public static GetSpeed(device: string): number | undefined { return SimGeneric.Get(SimType.PWM, device, PWM_SPEED, 0.0) @@ -142,7 +142,7 @@ export class SimPWM { } export class SimCAN { - private constructor() { } + private constructor() {} public static GetDeviceWithID(id: number, type: SimType): DeviceData | undefined { const id_exp = /.*\[(\d+)\]/g @@ -161,7 +161,7 @@ export class SimCAN { } export class SimCANMotor { - private constructor() { } + private constructor() {} public static GetPercentOutput(device: string): number | undefined { return SimGeneric.Get(SimType.CANMotor, device, CANMOTOR_PERCENT_OUTPUT, 0.0) @@ -188,7 +188,7 @@ export class SimCANMotor { } } export class SimCANEncoder { - private constructor() { } + private constructor() {} public static SetVelocity(device: string, velocity: number): boolean { return SimGeneric.Set(SimType.CANEncoder, device, CANENCODER_VELOCITY, velocity) @@ -200,7 +200,7 @@ export class SimCANEncoder { } export class SimGyro { - private constructor() { } + private constructor() {} public static SetAngleX(device: string, angle: number): boolean { return SimGeneric.Set(SimType.Gyro, device, ">angle_x", angle) @@ -228,7 +228,7 @@ export class SimGyro { } export class SimAccel { - private constructor() { } + private constructor() {} public static SetX(device: string, accel: number): boolean { return SimGeneric.Set(SimType.Accel, device, ">x", accel) @@ -244,10 +244,10 @@ export class SimAccel { } export class SimDIO { - private constructor() { } + private constructor() {} public static SetValue(device: string, value: boolean): boolean { - return SimGeneric.Set(SimType.DIO, device, "<>value", +value); + return SimGeneric.Set(SimType.DIO, device, "<>value", +value) } public static GetValue(device: string): boolean { @@ -256,7 +256,7 @@ export class SimDIO { } export class SimAI { - constructor() { } + constructor() {} public static SetValue(device: string, value: number): boolean { return SimGeneric.Set(SimType.AI, device, ">voltage", value) @@ -313,7 +313,7 @@ export class SimAI { } export class SimAO { - constructor() { } + constructor() {} public static GetVoltage(device: string): number { return SimGeneric.Get(SimType.AI, device, ">voltage", 0.0) @@ -340,8 +340,7 @@ worker.getValue().addEventListener("message", (eventData: MessageEvent) => { } } - if (!data?.type || !(Object.values(SimType) as string[]).includes(data.type))// || data.device.split(" ")[0] != "SYN") - return + if (!data?.type || !(Object.values(SimType) as string[]).includes(data.type)) return UpdateSimMap(data.type as SimType, data.device, data.data) }) diff --git a/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx b/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx index 075eda2d2f..d3afc4e799 100644 --- a/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx +++ b/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx @@ -82,7 +82,7 @@ const RCConfigCANGroupModal: React.FC = ({ modalId }) => { {drivers.map((driver, idx) => ( { if (checked && !checkedDrivers.includes(driver)) { diff --git a/fission/src/ui/panels/WSViewPanel.tsx b/fission/src/ui/panels/WSViewPanel.tsx index 9dd2b6fbdd..91726b42a0 100644 --- a/fission/src/ui/panels/WSViewPanel.tsx +++ b/fission/src/ui/panels/WSViewPanel.tsx @@ -35,13 +35,23 @@ function formatMap(map: Map): string { } function generateTableBody() { - const names: SimType[] = [SimType.PWM, SimType.SimDevice, SimType.CANMotor, SimType.CANEncoder, SimType.Gyro, SimType.Accel, SimType.DIO, SimType.AI, SimType.AO] + const names: SimType[] = [ + SimType.PWM, + SimType.SimDevice, + SimType.CANMotor, + SimType.CANEncoder, + SimType.Gyro, + SimType.Accel, + SimType.DIO, + SimType.AI, + SimType.AO, + ] console.log(simMap) return ( - {names.map(name => + {names.map(name => simMap.has(name) ? ( [...simMap.get(name)!.entries()] // most devices don't have = ({ selected (selectedRobot.brain as SynthesisBrain).behaviors .filter(b => b instanceof SequenceableBehavior) .map(b => DefaultSequentialConfig(b.jointIndex, b instanceof GenericArmBehavior ? "Arm" : "Elevator")), - [] + [selectedRobot.assemblyName, selectedRobot.brain] ) const drivers = useMemo(() => { From 18cd843fd0a9cdcd5f2aeda74cca8e5b0d87f9ba Mon Sep 17 00:00:00 2001 From: PepperLola Date: Mon, 26 Aug 2024 17:51:51 -0700 Subject: [PATCH 07/13] ran formatter, added string as possible ws type --- .../simulation/wpilib_brain/SimInput.ts | 51 ++++++++++--------- .../simulation/wpilib_brain/SimOutput.ts | 44 ++++++++++------ .../simulation/wpilib_brain/WPILibBrain.ts | 12 ++--- .../rio-config/RCConfigCANGroupModal.tsx | 2 +- fission/src/ui/panels/WSViewPanel.tsx | 2 +- 5 files changed, 63 insertions(+), 48 deletions(-) diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index 88e930e04d..245bff176a 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -1,20 +1,25 @@ import World from "@/systems/World" import EncoderStimulus from "../stimulus/EncoderStimulus" -import { SimCANEncoder, SimGyro, SimAccel, SimDIO as WSSimDIO, SimAI } from "./WPILibBrain" +import { SimCANEncoder, SimGyro, SimAccel, SimDIO, SimAI } from "./WPILibBrain" import Mechanism from "@/systems/physics/Mechanism" import Jolt from "@barclah/jolt-physics" import JOLT from "@/util/loading/JoltSyncLoader" -export interface SimInput { - Update: (deltaT: number) => void +export abstract class SimInput { + constructor(protected _device: string) {} + + public abstract Update(deltaT: number): void + + public get device(): string { + return this._device + } } -export class SimEncoderInput implements SimInput { - private _device: string +export class SimEncoderInput extends SimInput { private _stimulus: EncoderStimulus constructor(device: string, stimulus: EncoderStimulus) { - this._device = device + super(device) this._stimulus = stimulus } @@ -24,8 +29,7 @@ export class SimEncoderInput implements SimInput { } } -export class SimGyroInput implements SimInput { - private _device: string +export class SimGyroInput extends SimInput { private _robot: Mechanism private _joltID?: Jolt.BodyID private _joltBody?: Jolt.Body @@ -35,7 +39,7 @@ export class SimGyroInput implements SimInput { private static AXIS_Z: Jolt.Vec3 = new JOLT.Vec3(0, 0, 1) constructor(device: string, robot: Mechanism) { - this._device = device + super(device) this._robot = robot this._joltID = this._robot.nodeToBody.get(this._robot.rootBody) @@ -86,14 +90,13 @@ export class SimGyroInput implements SimInput { } } -export class SimAccelInput implements SimInput { - private _device: string +export class SimAccelInput extends SimInput { private _robot: Mechanism private _joltID?: Jolt.BodyID private _joltBody?: Jolt.Body constructor(device: string, robot: Mechanism) { - this._device = device + super(device) this._robot = robot this._joltID = this._robot.nodeToBody.get(this._robot.rootBody) @@ -121,27 +124,26 @@ export class SimAccelInput implements SimInput { } } -export class SimDIO implements SimInput { - private _device: string - private _valueSupplier?: () => boolean +export class SimDigitalInput extends SimInput { + private _valueSupplier: () => boolean /** - * Creates a Simulation Digital Input/Output object. + * Creates a Simulation Digital Input object. * * @param device Device ID - * @param valueSupplier Called each frame and returns what the value should be set to. Don't specify if DIO should be treated as an output. + * @param valueSupplier Called each frame and returns what the value should be set to */ - constructor(device: string, valueSupplier?: () => boolean) { - this._device = device + constructor(device: string, valueSupplier: () => boolean) { + super(device) this._valueSupplier = valueSupplier } - public SetValue(value: boolean) { - WSSimDIO.SetValue(this._device, value) + private SetValue(value: boolean) { + SimDIO.SetValue(this._device, value) } public GetValue(): boolean { - return WSSimDIO.GetValue(this._device) + return SimDIO.GetValue(this._device) } public Update(_deltaT: number) { @@ -149,12 +151,11 @@ export class SimDIO implements SimInput { } } -export class SimAnalogInput implements SimInput { - private _device: string +export class SimAnalogInput extends SimInput { private _valueSupplier: () => number constructor(device: string, valueSupplier: () => number) { - this._device = device + super(device) this._valueSupplier = valueSupplier } diff --git a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts index 85521c7bed..c9c5c0f091 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts @@ -2,23 +2,16 @@ import Driver from "../driver/Driver" import HingeDriver from "../driver/HingeDriver" import SliderDriver from "../driver/SliderDriver" import WheelDriver from "../driver/WheelDriver" -import { SimAO, SimCAN, SimPWM, SimType } from "./WPILibBrain" - -// TODO: Averaging is probably not the right solution (if we want large output groups) -// We can keep averaging, but we need a better ui for creating one to one (or just small) output groups -// The issue is that if a drivetrain is one output group, then each driver is given the average of all the motors -// We instead want a system where every driver gets (a) unique motor(s) that control it -// That way a single driver might get the average of two motors or something, if it has two motors to control it -// A system where motors a drivers are visually "linked" with "threads" in the UI would work well in my opinion +import { SimAO, SimCAN, SimDIO, SimPWM, SimType } from "./WPILibBrain" export abstract class SimOutput { - public name: string - - constructor(name: string) { - this.name = name - } + constructor(protected _name: string) {} public abstract Update(deltaT: number): void + + public get name(): string { + return this._name + } } export abstract class SimOutputGroup extends SimOutput { @@ -68,7 +61,7 @@ export class CANOutputGroup extends SimOutputGroup { const average = this.ports.reduce((sum, port) => { const device = SimCAN.GetDeviceWithID(port, SimType.CANMotor) - return sum + (device?.get(" { @@ -82,13 +75,34 @@ export class CANOutputGroup extends SimOutputGroup { } } +export class SimDigitalOutput extends SimOutput { + /** + * Creates a Simulation Digital Input/Output object. + * + * @param device Device ID + */ + constructor(name: string) { + super(name) + } + + public SetValue(value: boolean) { + SimDIO.SetValue(this._name, value) + } + + public GetValue(): boolean { + return SimDIO.GetValue(this._name) + } + + public Update(_deltaT: number) {} +} + export class SimAnalogOutput extends SimOutput { public constructor(name: string) { super(name) } public GetVoltage(): number { - return SimAO.GetVoltage(this.name) + return SimAO.GetVoltage(this._name) } public Update(_deltaT: number) {} diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index ccd672e54a..2f51979084 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -61,7 +61,7 @@ function GetFieldType(field: string): FieldType { } type DeviceName = string -type DeviceData = Map +type DeviceData = Map export const simMap = new Map>() @@ -92,7 +92,7 @@ export class SimGeneric { return (data.get(field) as T | undefined) ?? defaultValue } - public static Set(simType: SimType, device: string, field: string, value: T): boolean { + public static Set(simType: SimType, device: string, field: string, value: T): boolean { const fieldType = GetFieldType(field) if (fieldType != FieldType.Write && fieldType != FieldType.Both) { console.warn(`Field '${field}' is not a write or both field type`) @@ -111,7 +111,7 @@ export class SimGeneric { return false } - const selectedData: { [key: string]: number } = {} + const selectedData: { [key: string]: number | boolean } = {} selectedData[field] = value data.set(field, value) @@ -247,7 +247,7 @@ export class SimDIO { private constructor() {} public static SetValue(device: string, value: boolean): boolean { - return SimGeneric.Set(SimType.DIO, device, "<>value", +value) + return SimGeneric.Set(SimType.DIO, device, "<>value", value) } public static GetValue(device: string): boolean { @@ -381,8 +381,8 @@ class WPILibBrain extends Brain { // this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) // this.addSimInput(new SimAccelInput("ADXL362[4]", mechanism)) - // this.addSimInput(new SimDIOIn("SYN DI[0]", () => Math.random() > 0.5)) - // this.addSimInput(new SimDIOIn("SYN DO[1]")) + // this.addSimInput(new SimDigitalInput("SYN DI[0]", () => Math.random() > 0.5)) + // this.addSimOutput(new SimDigitalOutput("SYN DO[1]")) // this.addSimInput(new SimAnalogInput("SYN AI[0]", () => Math.random() * 12)) // this.addSimOutput(new SimAnalogOutput("SYN AO[1]")) } diff --git a/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx b/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx index d3afc4e799..b2a1641d08 100644 --- a/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx +++ b/fission/src/ui/modals/configuring/rio-config/RCConfigCANGroupModal.tsx @@ -33,7 +33,7 @@ const RCConfigCANGroupModal: React.FC = ({ modalId }) => { } const cans = simMap.get(SimType.CANMotor) ?? new Map>() - const devices: [string, Map][] = [...cans.entries()] + const devices: [string, Map][] = [...cans.entries()] .filter(([_, data]) => data.get("): string { +function formatMap(map: Map): string { let entries: string = "" map.forEach((value, key) => { entries += `${key} : ${value}` From 4b0519e9c5b49d4fd529398dabdda4c55891be88 Mon Sep 17 00:00:00 2001 From: PepperLola Date: Wed, 28 Aug 2024 18:25:50 -0700 Subject: [PATCH 08/13] manually calculate acceleration --- .../simulation/wpilib_brain/SimInput.ts | 29 +++++++++---------- .../src/main/java/frc/robot/Robot.java | 5 ++++ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index 245bff176a..7013c10516 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -94,33 +94,30 @@ export class SimAccelInput extends SimInput { private _robot: Mechanism private _joltID?: Jolt.BodyID private _joltBody?: Jolt.Body + private _prevVel: Jolt.Vec3 constructor(device: string, robot: Mechanism) { super(device) this._robot = robot this._joltID = this._robot.nodeToBody.get(this._robot.rootBody) + this._prevVel = new JOLT.Vec3(0, 0, 0) if (this._joltID) this._joltBody = World.PhysicsSystem.GetBody(this._joltID) } - private GetAxis(axis: "x" | "y" | "z"): number { - const forces = this._joltBody?.GetAccumulatedForce() - if (!forces) return 0 + public Update(deltaT: number) { + const newVel = this._joltBody?.GetLinearVelocity() + if (!newVel) return; - switch (axis) { - case "x": - return forces.GetX() - case "y": - return forces.GetY() - case "z": - return forces.GetZ() - } - } + const x = (newVel.GetX() - this._prevVel.GetX()) / deltaT + const y = (newVel.GetY() - this._prevVel.GetY()) / deltaT + const z = (newVel.GetZ() - this._prevVel.GetZ()) / deltaT - public Update(_deltaT: number) { - SimAccel.SetX(this._device, this.GetAxis("x")) - SimAccel.SetY(this._device, this.GetAxis("y")) - SimAccel.SetZ(this._device, this.GetAxis("z")) + SimAccel.SetX(this._device, x) + SimAccel.SetY(this._device, y) + SimAccel.SetZ(this._device, z) + + this._prevVel = new JOLT.Vec3(newVel.GetX(), newVel.GetY(), newVel.GetZ()) } } diff --git a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java index 3f85f59bc4..28e4035ea9 100644 --- a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java +++ b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java @@ -8,6 +8,9 @@ import com.autodesk.synthesis.io.*; +import edu.wpi.first.wpilibj.SPI; + +import edu.wpi.first.wpilibj.ADXL362; import edu.wpi.first.wpilibj.TimedRobot; import edu.wpi.first.wpilibj.motorcontrol.Spark; import edu.wpi.first.wpilibj.smartdashboard.SendableChooser; @@ -37,6 +40,8 @@ public class Robot extends TimedRobot { private TalonFX m_Talon = new TalonFX(2); private XboxController m_Controller = new XboxController(0); + private ADXL362 m_Accelerometer = new ADXL362(SPI.Port.kMXP, ADXL362.Range.k8G); + private DigitalInput m_DI = new DigitalInput(0); private DigitalOutput m_DO = new DigitalOutput(1); private AnalogInput m_AI = new AnalogInput(0); From 7e8b646f4c739dd46d249d4676e00b997f68b4b5 Mon Sep 17 00:00:00 2001 From: PepperLola Date: Wed, 28 Aug 2024 18:26:40 -0700 Subject: [PATCH 09/13] ran formatter --- fission/src/systems/simulation/wpilib_brain/SimInput.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index 7013c10516..ae4b427efd 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -107,7 +107,7 @@ export class SimAccelInput extends SimInput { public Update(deltaT: number) { const newVel = this._joltBody?.GetLinearVelocity() - if (!newVel) return; + if (!newVel) return const x = (newVel.GetX() - this._prevVel.GetX()) / deltaT const y = (newVel.GetY() - this._prevVel.GetY()) / deltaT From 394cdea743ca11d01c68c8877396ce026ef9dd31 Mon Sep 17 00:00:00 2001 From: HunterBarclay Date: Mon, 30 Sep 2024 13:57:02 -0600 Subject: [PATCH 10/13] fix: Change ports for TalonFX in Java Sample. Verified that everything seems to be working. However, haven't been able to test Gyros yet. --- .../org.eclipse.buildship.core.prefs | 13 ------ .../.settings/org.eclipse.jdt.core.prefs | 4 -- simulation/SyntheSimJava/build.gradle | 9 +++++ .../com/autodesk/synthesis/CANEncoder.java | 2 + .../java/com/autodesk/synthesis/CANMotor.java | 1 + .../com/autodesk/synthesis/ctre/TalonFX.java | 1 + .../autodesk/synthesis/kauailabs/AHRS.java | 38 ++++++++++++++++++ .../synthesis/revrobotics/CANSparkMax.java | 2 +- simulation/SyntheSimJava/vendordeps/NavX.json | 40 +++++++++++++++++++ .../org.eclipse.buildship.core.prefs | 13 ------ .../.settings/org.eclipse.jdt.core.prefs | 4 -- .../src/main/java/frc/robot/Robot.java | 23 ++++++----- 12 files changed, 106 insertions(+), 44 deletions(-) delete mode 100644 simulation/SyntheSimJava/.settings/org.eclipse.buildship.core.prefs delete mode 100644 simulation/SyntheSimJava/.settings/org.eclipse.jdt.core.prefs create mode 100644 simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/kauailabs/AHRS.java create mode 100644 simulation/SyntheSimJava/vendordeps/NavX.json delete mode 100644 simulation/samples/JavaSample/.settings/org.eclipse.buildship.core.prefs delete mode 100644 simulation/samples/JavaSample/.settings/org.eclipse.jdt.core.prefs diff --git a/simulation/SyntheSimJava/.settings/org.eclipse.buildship.core.prefs b/simulation/SyntheSimJava/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index 424e44f630..0000000000 --- a/simulation/SyntheSimJava/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,13 +0,0 @@ -arguments=--init-script /Users/seth/.cache/jdtls/config/org.eclipse.osgi/331/0/.cp/gradle/init/init.gradle -auto.sync=false -build.scans.enabled=false -connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) -connection.project.dir= -eclipse.preferences.version=1 -gradle.user.home= -java.home=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home -jvm.arguments= -offline.mode=false -override.workspace.settings=true -show.console.view=true -show.executions.view=true diff --git a/simulation/SyntheSimJava/.settings/org.eclipse.jdt.core.prefs b/simulation/SyntheSimJava/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 626e0e1d5c..0000000000 --- a/simulation/SyntheSimJava/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.source=17 diff --git a/simulation/SyntheSimJava/build.gradle b/simulation/SyntheSimJava/build.gradle index 421980fb3d..e8631a287e 100644 --- a/simulation/SyntheSimJava/build.gradle +++ b/simulation/SyntheSimJava/build.gradle @@ -30,11 +30,17 @@ repositories { maven { url "https://maven.revrobotics.com/" } + + // KAUAI + maven { + url "https://dev.studica.com/maven/release/2024/" + } } def WPI_Version = '2024.3.2' def REV_Version = '2024.2.4' def CTRE_Version = '24.3.0' +def KAUAI_Version = '2024.1.0' dependencies { // This dependency is exported to consumers, that is to say found on their compile classpath. @@ -53,6 +59,9 @@ dependencies { // CTRE implementation "com.ctre.phoenix6:wpiapi-java:$CTRE_Version" + + // KAUAI + implementation "com.kauailabs.navx.frc:navx-frc-java:$KAUAI_Version" } java { diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/CANEncoder.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/CANEncoder.java index d00e5439b8..c15d448ef4 100644 --- a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/CANEncoder.java +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/CANEncoder.java @@ -31,6 +31,8 @@ public CANEncoder(String name, int deviceId) { m_init = m_device.createBoolean("init", Direction.kOutput, true); m_position = m_device.createDouble("position", Direction.kInput, 0.0); m_velocity = m_device.createDouble("velocity", Direction.kInput, 0.0); + + m_init.set(true); } /** diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/CANMotor.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/CANMotor.java index e4df23ba66..5116cd9fdb 100644 --- a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/CANMotor.java +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/CANMotor.java @@ -55,6 +55,7 @@ public CANMotor(String name, int deviceId, double defaultPercentOutput, boolean m_motorCurrent = m_device.createDouble("motorCurrent", Direction.kInput, 120.0); m_busVoltage = m_device.createDouble("busVoltage", Direction.kInput, 12.0); m_busVoltage.set(0.0); // disable CANMotor inputs + m_init.set(true); } /** diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/ctre/TalonFX.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/ctre/TalonFX.java index 5e671b86cd..3c67bbd1a5 100644 --- a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/ctre/TalonFX.java +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/ctre/TalonFX.java @@ -20,6 +20,7 @@ public TalonFX(int deviceNumber) { super(deviceNumber); this.m_motor = new CANMotor("SYN TalonFX", deviceNumber, 0.0, false, 0.3); + this.m_encoder = new CANEncoder("SYN TalonFX", deviceNumber); } /// I think we're getting percentOutput and speed mixed up diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/kauailabs/AHRS.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/kauailabs/AHRS.java new file mode 100644 index 0000000000..a69daec358 --- /dev/null +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/kauailabs/AHRS.java @@ -0,0 +1,38 @@ +package com.autodesk.synthesis.kauailabs; + +import com.autodesk.synthesis.Gyro; + +import edu.wpi.first.wpilibj.SPI; +import edu.wpi.first.wpilibj.I2C; +import edu.wpi.first.wpilibj.SerialPort; + +/** + * Outline for a NavX AHRS class. + * TODO + */ +public class AHRS extends com.kauailabs.navx.frc.AHRS { + private Gyro m_gyro; + + public AHRS() { + this(SPI.Port.kMXP); + } + + public AHRS(I2C.Port port) { + super(port); + init("I2C", port.value); + } + + public AHRS(SPI.Port port) { + super(port); + init("SPI", port.value); + } + + public AHRS(SerialPort.Port port) { + super(port); + init("SERIAL", port.value); + } + + private void init(String commType, int port) { + this.m_gyro = new Gyro("SYN AHRS " + commType, port); + } +} diff --git a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/revrobotics/CANSparkMax.java b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/revrobotics/CANSparkMax.java index 560cc5bc79..06ec14707b 100644 --- a/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/revrobotics/CANSparkMax.java +++ b/simulation/SyntheSimJava/src/main/java/com/autodesk/synthesis/revrobotics/CANSparkMax.java @@ -28,7 +28,7 @@ public CANSparkMax(int deviceId, MotorType motorType) { this.m_motor = new CANMotor("SYN CANSparkMax", deviceId, 0.0, false, 0.3); this.m_encoder = new CANEncoder("SYN CANSparkMax", deviceId); - this.followers = new ArrayList(); + this.followers = new ArrayList(); } // setting a follower doesn't break the simulated follower - leader relationship diff --git a/simulation/SyntheSimJava/vendordeps/NavX.json b/simulation/SyntheSimJava/vendordeps/NavX.json new file mode 100644 index 0000000000..e978a5f745 --- /dev/null +++ b/simulation/SyntheSimJava/vendordeps/NavX.json @@ -0,0 +1,40 @@ +{ + "fileName": "NavX.json", + "name": "NavX", + "version": "2024.1.0", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "frcYear": "2024", + "mavenUrls": [ + "https://dev.studica.com/maven/release/2024/" + ], + "jsonUrl": "https://dev.studica.com/releases/2024/NavX.json", + "javaDependencies": [ + { + "groupId": "com.kauailabs.navx.frc", + "artifactId": "navx-frc-java", + "version": "2024.1.0" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "com.kauailabs.navx.frc", + "artifactId": "navx-frc-cpp", + "version": "2024.1.0", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": false, + "libName": "navx_frc", + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "linuxraspbian", + "linuxarm32", + "linuxarm64", + "linuxx86-64", + "osxuniversal", + "windowsx86-64" + ] + } + ] +} \ No newline at end of file diff --git a/simulation/samples/JavaSample/.settings/org.eclipse.buildship.core.prefs b/simulation/samples/JavaSample/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index 424e44f630..0000000000 --- a/simulation/samples/JavaSample/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,13 +0,0 @@ -arguments=--init-script /Users/seth/.cache/jdtls/config/org.eclipse.osgi/331/0/.cp/gradle/init/init.gradle -auto.sync=false -build.scans.enabled=false -connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) -connection.project.dir= -eclipse.preferences.version=1 -gradle.user.home= -java.home=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home -jvm.arguments= -offline.mode=false -override.workspace.settings=true -show.console.view=true -show.executions.view=true diff --git a/simulation/samples/JavaSample/.settings/org.eclipse.jdt.core.prefs b/simulation/samples/JavaSample/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 626e0e1d5c..0000000000 --- a/simulation/samples/JavaSample/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.source=17 diff --git a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java index 28e4035ea9..302f80f47c 100644 --- a/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java +++ b/simulation/samples/JavaSample/src/main/java/frc/robot/Robot.java @@ -18,6 +18,7 @@ import edu.wpi.first.wpilibj.XboxController; import com.autodesk.synthesis.revrobotics.CANSparkMax; +import com.kauailabs.navx.frc.AHRS; import com.autodesk.synthesis.ctre.TalonFX; /** @@ -37,10 +38,11 @@ public class Robot extends TimedRobot { private Spark m_Spark1 = new Spark(0); private Spark m_Spark2 = new Spark(1); - private TalonFX m_Talon = new TalonFX(2); + private TalonFX m_Talon = new TalonFX(7); private XboxController m_Controller = new XboxController(0); private ADXL362 m_Accelerometer = new ADXL362(SPI.Port.kMXP, ADXL362.Range.k8G); + private AHRS m_Gyro = new AHRS(); private DigitalInput m_DI = new DigitalInput(0); private DigitalOutput m_DO = new DigitalOutput(1); @@ -141,18 +143,21 @@ public void teleopInit() { /** This function is called periodically during operator control. */ @Override public void teleopPeriodic() { - m_Spark1.set(m_Controller.getLeftY()); - m_Spark2.set(-m_Controller.getRightY()); - System.out.println("IN: " + m_DI.get()); - System.out.println("OUT: " + m_DO.get()); - System.out.println("AI: " + m_AI.getVoltage()); - m_Talon.set(-0.5); - m_SparkMax1.set(-0.75); - m_SparkMax2.set(-0.75); + m_SparkMax1.set(m_Controller.getLeftY()); + m_SparkMax2.set(-m_Controller.getRightY()); + m_Talon.set(m_Controller.getLeftX()); + System.out.println("LeftX: " + m_Controller.getLeftX()); + // System.out.println("OUT: " + m_DO.get()); + // System.out.println("AI: " + m_AI.getVoltage()); + // m_Talon.set(-0.5); + // m_SparkMax1.set(-0.75); + // m_SparkMax2.set(-0.75); m_SparkMax3.set(-0.75); m_SparkMax4.set(-0.75); m_SparkMax5.set(-0.75); m_SparkMax6.set(-0.75); + + m_SparkMax1.getEncoder().setPosition(0.0); } From 5347554bcd323787e6eeb4de58f590aed1bfb217 Mon Sep 17 00:00:00 2001 From: HunterBarclay Date: Mon, 30 Sep 2024 13:59:37 -0600 Subject: [PATCH 11/13] fix: Accelerometers metrics are relative, matching real devices. Also included some minor tweaks. --- .../simulation/wpilib_brain/SimInput.ts | 25 +++++++++++-------- .../simulation/wpilib_brain/SimOutput.ts | 2 +- .../simulation/wpilib_brain/WPILibBrain.ts | 16 ++++++------ .../rio-config/RCConfigEncoderModal.tsx | 2 +- fission/src/ui/panels/WSViewPanel.tsx | 25 +++++++++---------- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index ae4b427efd..637520a316 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -4,6 +4,8 @@ import { SimCANEncoder, SimGyro, SimAccel, SimDIO, SimAI } from "./WPILibBrain" import Mechanism from "@/systems/physics/Mechanism" import Jolt from "@barclah/jolt-physics" import JOLT from "@/util/loading/JoltSyncLoader" +import { JoltQuat_ThreeQuaternion, JoltVec3_ThreeVector3 } from "@/util/TypeConversions" +import * as THREE from 'three' export abstract class SimInput { constructor(protected _device: string) {} @@ -93,31 +95,32 @@ export class SimGyroInput extends SimInput { export class SimAccelInput extends SimInput { private _robot: Mechanism private _joltID?: Jolt.BodyID - private _joltBody?: Jolt.Body - private _prevVel: Jolt.Vec3 + private _prevVel: THREE.Vector3 constructor(device: string, robot: Mechanism) { super(device) this._robot = robot this._joltID = this._robot.nodeToBody.get(this._robot.rootBody) - this._prevVel = new JOLT.Vec3(0, 0, 0) - - if (this._joltID) this._joltBody = World.PhysicsSystem.GetBody(this._joltID) + this._prevVel = new THREE.Vector3(0,0,0) } public Update(deltaT: number) { - const newVel = this._joltBody?.GetLinearVelocity() - if (!newVel) return + if (!this._joltID) return + const body = World.PhysicsSystem.GetBody(this._joltID) + + const rot = JoltQuat_ThreeQuaternion(body.GetRotation()) + const mat = new THREE.Matrix4().makeRotationFromQuaternion(rot).transpose() + const newVel = JoltVec3_ThreeVector3(body.GetLinearVelocity()).applyMatrix4(mat) - const x = (newVel.GetX() - this._prevVel.GetX()) / deltaT - const y = (newVel.GetY() - this._prevVel.GetY()) / deltaT - const z = (newVel.GetZ() - this._prevVel.GetZ()) / deltaT + const x = (newVel.x - this._prevVel.x) / deltaT + const y = (newVel.y - this._prevVel.y) / deltaT + const z = (newVel.y - this._prevVel.y) / deltaT SimAccel.SetX(this._device, x) SimAccel.SetY(this._device, y) SimAccel.SetZ(this._device, z) - this._prevVel = new JOLT.Vec3(newVel.GetX(), newVel.GetY(), newVel.GetZ()) + this._prevVel = newVel } } diff --git a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts index c9c5c0f091..cefef5bf5d 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts @@ -61,7 +61,7 @@ export class CANOutputGroup extends SimOutputGroup { const average = this.ports.reduce((sum, port) => { const device = SimCAN.GetDeviceWithID(port, SimType.CANMotor) - return sum + +(device?.get(" { diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index 2f51979084..bce82be75d 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -6,8 +6,8 @@ import WPILibWSWorker from "./WPILibWSWorker?worker" import { SimulationLayer } from "../SimulationSystem" import World from "@/systems/World" -import { SimOutput } from "./SimOutput" -import { SimInput } from "./SimInput" +import { SimAnalogOutput, SimDigitalOutput, SimOutput } from "./SimOutput" +import { SimAccelInput, SimAnalogInput, SimDigitalInput, SimGyroInput, SimInput } from "./SimInput" const worker: Lazy = new Lazy(() => new WPILibWSWorker()) @@ -145,7 +145,7 @@ export class SimCAN { private constructor() {} public static GetDeviceWithID(id: number, type: SimType): DeviceData | undefined { - const id_exp = /.*\[(\d+)\]/g + const id_exp = /SYN.*\[(\d+)\]/g const entries = [...simMap.entries()].filter(([simType, _data]) => simType == type) for (const [_simType, data] of entries) { for (const key of data.keys()) { @@ -380,11 +380,11 @@ class WPILibBrain extends Brain { } // this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) - // this.addSimInput(new SimAccelInput("ADXL362[4]", mechanism)) - // this.addSimInput(new SimDigitalInput("SYN DI[0]", () => Math.random() > 0.5)) - // this.addSimOutput(new SimDigitalOutput("SYN DO[1]")) - // this.addSimInput(new SimAnalogInput("SYN AI[0]", () => Math.random() * 12)) - // this.addSimOutput(new SimAnalogOutput("SYN AO[1]")) + this.addSimInput(new SimAccelInput("ADXL362[4]", mechanism)) + this.addSimInput(new SimDigitalInput("SYN DI[0]", () => Math.random() > 0.5)) + this.addSimOutput(new SimDigitalOutput("SYN DO[1]")) + this.addSimInput(new SimAnalogInput("SYN AI[0]", () => Math.random() * 12)) + this.addSimOutput(new SimAnalogOutput("SYN AO[1]")) } public addSimOutput(device: SimOutput) { diff --git a/fission/src/ui/modals/configuring/rio-config/RCConfigEncoderModal.tsx b/fission/src/ui/modals/configuring/rio-config/RCConfigEncoderModal.tsx index c60af762f7..00e203565b 100644 --- a/fission/src/ui/modals/configuring/rio-config/RCConfigEncoderModal.tsx +++ b/fission/src/ui/modals/configuring/rio-config/RCConfigEncoderModal.tsx @@ -56,7 +56,7 @@ const RCConfigEncoderModal: React.FC = ({ modalId }) => { > - n[0])} onSelect={s => setSelectedDevice(s)} /> + n[0])} onSelect={s => setSelectedDevice(s)} /> {names.map(name => @@ -95,7 +95,9 @@ function setGeneric(simType: SimType, device: string, field: string, value: stri } const WSViewPanel: React.FC = ({ panelId }) => { - const [tb, setTb] = useState(generateTableBody()) + // const [tb, setTb] = useState(generateTableBody()) + + const [table, updateTable] = useReducer((_) => generateTableBody(), generateTableBody()) const [selectedType, setSelectedType] = useState() const [selectedDevice, setSelectedDevice] = useState() @@ -115,17 +117,14 @@ const WSViewPanel: React.FC = ({ panelId }) => { setSelectedDevice(undefined) }, [selectedType]) - const onSimMapUpdate = useCallback((_: Event) => { - setTb(generateTableBody()) - }, []) - useEffect(() => { - window.addEventListener(SimMapUpdateEvent.TYPE, onSimMapUpdate) + const func = () => { updateTable() } + const id: NodeJS.Timeout = setInterval(func, TABLE_UPDATE_INTERVAL) return () => { - window.removeEventListener(SimMapUpdateEvent.TYPE, onSimMapUpdate) + clearTimeout(id) } - }, [onSimMapUpdate]) + }, [updateTable]) return ( = ({ panelId }) => { - {tb} + {table} From cbc9033050b4a2043c02ae836b08649b2bc04cf9 Mon Sep 17 00:00:00 2001 From: HunterBarclay Date: Fri, 11 Oct 2024 10:58:04 -0600 Subject: [PATCH 12/13] chore: Format and cleanup --- .../src/systems/simulation/wpilib_brain/SimInput.ts | 4 ++-- .../systems/simulation/wpilib_brain/SimOutput.ts | 2 +- .../systems/simulation/wpilib_brain/WPILibBrain.ts | 2 +- fission/src/ui/panels/WSViewPanel.tsx | 6 ++++-- simulation/samples/CppSample/.gitignore | 2 ++ .../.settings/org.eclipse.buildship.core.prefs | 13 ------------- 6 files changed, 10 insertions(+), 19 deletions(-) delete mode 100644 simulation/samples/CppSample/.settings/org.eclipse.buildship.core.prefs diff --git a/fission/src/systems/simulation/wpilib_brain/SimInput.ts b/fission/src/systems/simulation/wpilib_brain/SimInput.ts index 637520a316..b4776f03a3 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimInput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimInput.ts @@ -5,7 +5,7 @@ import Mechanism from "@/systems/physics/Mechanism" import Jolt from "@barclah/jolt-physics" import JOLT from "@/util/loading/JoltSyncLoader" import { JoltQuat_ThreeQuaternion, JoltVec3_ThreeVector3 } from "@/util/TypeConversions" -import * as THREE from 'three' +import * as THREE from "three" export abstract class SimInput { constructor(protected _device: string) {} @@ -101,7 +101,7 @@ export class SimAccelInput extends SimInput { super(device) this._robot = robot this._joltID = this._robot.nodeToBody.get(this._robot.rootBody) - this._prevVel = new THREE.Vector3(0,0,0) + this._prevVel = new THREE.Vector3(0, 0, 0) } public Update(deltaT: number) { diff --git a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts index cefef5bf5d..04e9205c7c 100644 --- a/fission/src/systems/simulation/wpilib_brain/SimOutput.ts +++ b/fission/src/systems/simulation/wpilib_brain/SimOutput.ts @@ -61,7 +61,7 @@ export class CANOutputGroup extends SimOutputGroup { const average = this.ports.reduce((sum, port) => { const device = SimCAN.GetDeviceWithID(port, SimType.CANMotor) - return sum + (device?.get(" { diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index bce82be75d..e0bd2779d9 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -379,7 +379,7 @@ class WPILibBrain extends Brain { return } - // this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) + this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) this.addSimInput(new SimAccelInput("ADXL362[4]", mechanism)) this.addSimInput(new SimDigitalInput("SYN DI[0]", () => Math.random() > 0.5)) this.addSimOutput(new SimDigitalOutput("SYN DO[1]")) diff --git a/fission/src/ui/panels/WSViewPanel.tsx b/fission/src/ui/panels/WSViewPanel.tsx index e109c48382..693db7c25c 100644 --- a/fission/src/ui/panels/WSViewPanel.tsx +++ b/fission/src/ui/panels/WSViewPanel.tsx @@ -97,7 +97,7 @@ function setGeneric(simType: SimType, device: string, field: string, value: stri const WSViewPanel: React.FC = ({ panelId }) => { // const [tb, setTb] = useState(generateTableBody()) - const [table, updateTable] = useReducer((_) => generateTableBody(), generateTableBody()) + const [table, updateTable] = useReducer(_ => generateTableBody(), generateTableBody()) const [selectedType, setSelectedType] = useState() const [selectedDevice, setSelectedDevice] = useState() @@ -118,7 +118,9 @@ const WSViewPanel: React.FC = ({ panelId }) => { }, [selectedType]) useEffect(() => { - const func = () => { updateTable() } + const func = () => { + updateTable() + } const id: NodeJS.Timeout = setInterval(func, TABLE_UPDATE_INTERVAL) return () => { diff --git a/simulation/samples/CppSample/.gitignore b/simulation/samples/CppSample/.gitignore index 11c9fdd738..bae79ccf97 100644 --- a/simulation/samples/CppSample/.gitignore +++ b/simulation/samples/CppSample/.gitignore @@ -2,3 +2,5 @@ .vscode/ .wpilib/ build/ +.settings/ + diff --git a/simulation/samples/CppSample/.settings/org.eclipse.buildship.core.prefs b/simulation/samples/CppSample/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index bc1ff1181e..0000000000 --- a/simulation/samples/CppSample/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,13 +0,0 @@ -arguments=--init-script /Users/colbura/cache/jdtls/config/org.eclipse.osgi/55/0/.cp/gradle/init/init.gradle -auto.sync=false -build.scans.enabled=false -connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) -connection.project.dir= -eclipse.preferences.version=1 -gradle.user.home= -java.home=/opt/homebrew/Cellar/openjdk/22.0.2/libexec/openjdk.jdk/Contents/Home -jvm.arguments= -offline.mode=false -override.workspace.settings=true -show.console.view=true -show.executions.view=true From 267ee5926a664fddf2588564715db87c687af512 Mon Sep 17 00:00:00 2001 From: HunterBarclay Date: Fri, 11 Oct 2024 11:05:45 -0600 Subject: [PATCH 13/13] fix: Use custom random generation --- fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts index e0bd2779d9..7fa35eddaf 100644 --- a/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts +++ b/fission/src/systems/simulation/wpilib_brain/WPILibBrain.ts @@ -8,6 +8,7 @@ import World from "@/systems/World" import { SimAnalogOutput, SimDigitalOutput, SimOutput } from "./SimOutput" import { SimAccelInput, SimAnalogInput, SimDigitalInput, SimGyroInput, SimInput } from "./SimInput" +import { Random } from "@/util/Random" const worker: Lazy = new Lazy(() => new WPILibWSWorker()) @@ -381,9 +382,9 @@ class WPILibBrain extends Brain { this.addSimInput(new SimGyroInput("Test Gyro[1]", mechanism)) this.addSimInput(new SimAccelInput("ADXL362[4]", mechanism)) - this.addSimInput(new SimDigitalInput("SYN DI[0]", () => Math.random() > 0.5)) + this.addSimInput(new SimDigitalInput("SYN DI[0]", () => Random() > 0.5)) this.addSimOutput(new SimDigitalOutput("SYN DO[1]")) - this.addSimInput(new SimAnalogInput("SYN AI[0]", () => Math.random() * 12)) + this.addSimInput(new SimAnalogInput("SYN AI[0]", () => Random() * 12)) this.addSimOutput(new SimAnalogOutput("SYN AO[1]")) }