From b76af356fa02054dafd1a09e10f986325e2cf43e Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Mon, 17 Jun 2024 16:30:07 -0700 Subject: [PATCH 01/12] Basic input manager script that updates with the inputs modal --- engine/Assets/Scripts/Drivers/WheelDriver.cs | 132 +++++++++++------- .../Utilities/ColorManager/ColorManager.cs | 97 ++++++++----- .../modals/configuring/ChangeInputsModal.tsx | 41 ++---- fission/src/systems/World.ts | 5 + fission/src/systems/input/InputSystem.ts | 109 +++++++++++++++ .../systems/simulation/driver/SliderDriver.ts | 2 + .../systems/simulation/driver/WheelDriver.ts | 10 +- .../simulation/stimulus/WheelStimulus.ts | 2 +- 8 files changed, 281 insertions(+), 117 deletions(-) diff --git a/engine/Assets/Scripts/Drivers/WheelDriver.cs b/engine/Assets/Scripts/Drivers/WheelDriver.cs index 9eb524400f..4390e918ee 100644 --- a/engine/Assets/Scripts/Drivers/WheelDriver.cs +++ b/engine/Assets/Scripts/Drivers/WheelDriver.cs @@ -7,8 +7,10 @@ #nullable enable -namespace Synthesis { - public class WheelDriver : Driver { +namespace Synthesis +{ + public class WheelDriver : Driver + { private const float MIRABUF_TO_UNITY_FORCE = 40f; private CustomWheel _customWheel; @@ -18,33 +20,41 @@ public class WheelDriver : Driver { public JointInstance JointInstance => _jointInstance; private Vector3 _localAnchor = Vector3.zero; - public Vector3 Anchor { + public Vector3 Anchor + { get => _customWheel.Rb.transform.localToWorldMatrix.MultiplyPoint3x4(_localAnchor); - set { - _localAnchor = _customWheel.Rb.transform.worldToLocalMatrix.MultiplyPoint3x4(value); + set + { + _localAnchor = _customWheel.Rb.transform.worldToLocalMatrix.MultiplyPoint3x4(value); _customWheel.LocalAnchor = _localAnchor; } } - public Vector3 LocalAnchor { + public Vector3 LocalAnchor + { get => _localAnchor; - set { - _localAnchor = value; + set + { + _localAnchor = value; _customWheel.LocalAnchor = _localAnchor; } } private Vector3 _localAxis = Vector3.right; - public Vector3 Axis { + public Vector3 Axis + { get => _customWheel.Rb.transform.localToWorldMatrix.MultiplyVector(_localAxis); - set { - _localAxis = _customWheel.Rb.transform.worldToLocalMatrix.MultiplyVector(value); + set + { + _localAxis = _customWheel.Rb.transform.worldToLocalMatrix.MultiplyVector(value); _customWheel.LocalAxis = _localAxis; } } - public Vector3 LocalAxis { + public Vector3 LocalAxis + { get => _localAxis; - set { - _localAxis = value; + set + { + _localAxis = value; _customWheel.LocalAxis = _localAxis; } } @@ -52,32 +62,39 @@ public Vector3 LocalAxis { /// /// Specify a roller direction. NULL roller direction indicates no roller /// - public Vector3? LocalRoller { + public Vector3? LocalRoller + { get => _customWheel.LocalRollerRollingDirection; set { _customWheel.LocalRollerRollingDirection = value; } } private float _radius = 0.05f; - public float Radius { + public float Radius + { get => _radius; - set { - _radius = value; + set + { + _radius = value; _customWheel.Radius = _radius; } } - public float ImpulseMax { + public float ImpulseMax + { get => _customWheel.ImpulseMax; set => _customWheel.ImpulseMax = value; } - public enum RotationalControlMode { + public enum RotationalControlMode + { Position, Velocity } - public double MainInput { - get { + public double MainInput + { + get + { if (PhysicsManager.IsFrozen) return 0f; var val = State.GetValue(_inputs[0]); @@ -89,9 +106,11 @@ public double MainInput { public bool HasContacts => _customWheel.HasContacts; private JointMotor _motor; - public JointMotor Motor { + public JointMotor Motor + { get => _motor; - set { + set + { _motor = value; SimulationPreferences.SetRobotJointMotor((_simObject as RobotSimObject)!.RobotGUID, MotorRef, _motor); } @@ -122,31 +141,39 @@ public JointMotor Motor { public WheelDriver(string name, string[] inputs, string[] outputs, SimObject simObject, JointInstance jointInstance, CustomWheel customWheel, Vector3 anchor, Vector3 axis, float radius, string motorRef, JointInstance.WheelTypeEnum wheelType) - : base(name, inputs, outputs, simObject) { + : base(name, inputs, outputs, simObject) + { _jointInstance = jointInstance; - _customWheel = customWheel; - _wheelType = wheelType; + _customWheel = customWheel; + _wheelType = wheelType; Anchor = _customWheel.Rb.transform.localToWorldMatrix.MultiplyPoint3x4(anchor); - Axis = _customWheel.Rb.transform.localToWorldMatrix.MultiplyVector(axis); + Axis = _customWheel.Rb.transform.localToWorldMatrix.MultiplyVector(axis); MotorRef = motorRef; - if (float.IsNaN(radius)) { + if (float.IsNaN(radius)) + { Radius = _customWheel.Rb.transform.GetBounds().extents.y; - } else { + } + else + { Radius = radius; } var motor = SimulationPreferences.GetRobotJointMotor((simObject as RobotSimObject)!.RobotGUID, motorRef); - if (motor != null) { + if (motor != null) + { _motor = motor.Value; - } else { - Motor = new JointMotor() { + } + else + { + Motor = new JointMotor() + { // Default Motor. Slow but powerful enough. Also uses Motor to save it - force = 1, // About a Neo 550. Max is Falcon 550 at 4.67 - freeSpin = false, + force = 1, // About a Neo 550. Max is Falcon 550 at 4.67 + freeSpin = false, targetVelocity = 30, }; } @@ -157,18 +184,21 @@ public WheelDriver(string name, string[] inputs, string[] outputs, SimObject sim State.SetValue(_outputs[1], Value.ForNumber(1)); } - void EnableMotor() { + void EnableMotor() + { _useMotor = true; } - void DisableMotor() { + void DisableMotor() + { _useMotor = false; } private float _jointAngle = 0.0f; private float _lastUpdate = float.NaN; - public override void Update() { + public override void Update() + { VelocityControl(); _lastUpdate = Time.realtimeSinceStartup; @@ -178,34 +208,42 @@ public override void Update() { State.SetValue(_outputs[1], Value.ForNumber(PositiveMod(_jointAngle, Mathf.PI))); } - public float PositiveMod(float val, float mod) { + public float PositiveMod(float val, float mod) + { var res = val % mod; if (res < 0) res += mod; return res; } - public void WheelsPhysicsUpdate(float mod) { + public void WheelsPhysicsUpdate(float mod) + { _customWheel.CalculateAndApplyFriction(mod); } - public void MatchRollerToWheelType() { - if (_wheelType == JointInstance.WheelTypeEnum.Omni) { + public void MatchRollerToWheelType() + { + if (_wheelType == JointInstance.WheelTypeEnum.Omni) + { LocalRoller = LocalAxis; - } else { + } + else + { LocalRoller = null; } } - private void VelocityControl() { + private void VelocityControl() + { if (!_useMotor) return; - var val = (float) MainInput; - var lastRotSpeed = _customWheel.RotationSpeed; + var val = (float)MainInput; + var lastRotSpeed = _customWheel.RotationSpeed; _customWheel.RotationSpeed = val * _motor.targetVelocity; - if (!float.IsNaN(_lastUpdate)) { + if (!float.IsNaN(_lastUpdate)) + { var deltaT = Time.realtimeSinceStartup - _lastUpdate; if (deltaT == 0f) diff --git a/engine/Assets/Scripts/Utilities/ColorManager/ColorManager.cs b/engine/Assets/Scripts/Utilities/ColorManager/ColorManager.cs index 772a0248ab..eadc9eb452 100644 --- a/engine/Assets/Scripts/Utilities/ColorManager/ColorManager.cs +++ b/engine/Assets/Scripts/Utilities/ColorManager/ColorManager.cs @@ -9,19 +9,23 @@ using UI.Dynamic.Modals.Configuring.ThemeEditor; using UnityEngine; -namespace Utilities.ColorManager { - public static class ColorManager { +namespace Utilities.ColorManager +{ + public static class ColorManager + { public const string SELECTED_THEME_PREF = "color/selected_theme"; - public const string DEFAULT_THEME = "Default"; + public const string DEFAULT_THEME = "Default"; - public class OnThemeChanged : IEvent {} + public class OnThemeChanged : IEvent { } private static readonly Color UNASSIGNED_COLOR = new(200, 255, 0, 255); private static readonly char altSep = Path.AltDirectorySeparatorChar; - private static string THEMES_FOLDER_PATH { - get { + private static string THEMES_FOLDER_PATH + { + get + { string dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + altSep + "Autodesk" + altSep + "Synthesis" + altSep + "Themes"; @@ -39,9 +43,11 @@ private static string THEMES_FOLDER_PATH { public static Dictionary ActiveColors => _tempPreviewColors ?? LoadedColors; private static string _selectedTheme; - public static string SelectedTheme { + public static string SelectedTheme + { get => _selectedTheme; - set { + set + { if (value == _selectedTheme) return; @@ -57,8 +63,10 @@ public static string SelectedTheme { } /// A list of themes found in Appdata plus the default theme - public static string[] AvailableThemes { - get { + public static string[] AvailableThemes + { + get + { var themes = Directory.GetFiles(THEMES_FOLDER_PATH).Select(Path.GetFileNameWithoutExtension).ToList(); themes.Insert(0, DEFAULT_THEME); @@ -66,13 +74,16 @@ public static string[] AvailableThemes { } } - static ColorManager() { - EventBus.NewTypeListener(e => { + static ColorManager() + { + EventBus.NewTypeListener(e => + { string selectedTheme = PreferenceManager.GetPreference(SELECTED_THEME_PREF); - SelectedTheme = selectedTheme; + SelectedTheme = selectedTheme; }); _selectedTheme = PreferenceManager.GetPreference(SELECTED_THEME_PREF); - if (_selectedTheme is "" or null) { + if (_selectedTheme is "" or null) + { PreferenceManager.SetPreference(SELECTED_THEME_PREF, DEFAULT_THEME); _selectedTheme = DEFAULT_THEME; } @@ -84,29 +95,35 @@ static ColorManager() { /// Loads the default theme into the _colors dictionary. Will fill missing colors in a custom /// theme - private static void LoadDefaultColors() { + private static void LoadDefaultColors() + { DefaultColors.SYNTHESIS_DEFAULT.ForEach(c => { _loadedColors.TryAdd(c.name, c.color); }); } /// Loads a theme from the synthesis appdata folder. Will create a theme if it does not exist /// The theme to load - private static void LoadTheme(string themeName) { + private static void LoadTheme(string themeName) + { if (themeName is DEFAULT_THEME or "") return; string themePath = THEMES_FOLDER_PATH + altSep + themeName + ".json"; var dir = Path.GetFullPath(themePath).Replace(Path.GetFileName(themePath), ""); - if (!Directory.Exists(dir)) { + if (!Directory.Exists(dir)) + { Directory.CreateDirectory(dir); return; - } else if (!File.Exists(themePath)) { + } + else if (!File.Exists(themePath)) + { return; } var jsonColors = JsonConvert.DeserializeObject>(File.ReadAllText(themePath)); - jsonColors?.ForEach(x => { + jsonColors?.ForEach(x => + { if (Enum.TryParse(x.Key, out var colorName)) _loadedColors.Add(colorName, x.Value.ColorToHex()); }); @@ -114,7 +131,8 @@ private static void LoadTheme(string themeName) { /// Loads a theme to the synthesis appdata folder /// The theme to save - private static void SaveTheme(string themeName) { + private static void SaveTheme(string themeName) + { if (themeName is DEFAULT_THEME or "") return; @@ -122,14 +140,15 @@ private static void SaveTheme(string themeName) { var jsonColors = new Dictionary(); - _loadedColors.ForEach(x => { jsonColors.Add(x.Key.ToString(), ((Color) x.Value).ToHex()); }); + _loadedColors.ForEach(x => { jsonColors.Add(x.Key.ToString(), ((Color)x.Value).ToHex()); }); File.WriteAllText(themePath, JsonConvert.SerializeObject(jsonColors)); } /// Deletes a theme from the synthesis appdata folder /// The theme to delete - private static void DeleteTheme(string themeName) { + private static void DeleteTheme(string themeName) + { if (themeName is DEFAULT_THEME or "") return; @@ -139,19 +158,22 @@ private static void DeleteTheme(string themeName) { } /// Permanently deletes the selected theme unless it is Default - public static void DeleteSelectedTheme() { + public static void DeleteSelectedTheme() + { DeleteTheme(_selectedTheme); SelectedTheme = DEFAULT_THEME; } - public static void DeleteAllThemes() { + public static void DeleteAllThemes() + { AvailableThemes.ForEach(DeleteTheme); SelectedTheme = DEFAULT_THEME; } /// Modifies the colors of the selected theme /// A list of new colors. Does not have to contain every color - public static void ModifySelectedTheme(List<(SynthesisColor name, Color color)> changes) { + public static void ModifySelectedTheme(List<(SynthesisColor name, Color color)> changes) + { SetTempPreviewColors(null); if (_selectedTheme == null) @@ -167,11 +189,15 @@ public static void ModifySelectedTheme(List<(SynthesisColor name, Color color)> /// Returns a color, or UNASSIGNED_COLOR if it is not /// found The name of the color to get The corresponding /// color of the current theme - public static Color GetColor(SynthesisColor colorName) { - if (_tempPreviewColors != null) { + public static Color GetColor(SynthesisColor colorName) + { + if (_tempPreviewColors != null) + { if (_tempPreviewColors.TryGetValue(colorName, out Color color)) return color; - } else { + } + else + { if (_loadedColors.TryGetValue(colorName, out Color color)) return color; } @@ -182,7 +208,8 @@ public static Color GetColor(SynthesisColor colorName) { /// Temporarily preview colors without saving them. Call with null to switch back to loaded /// colors The colors to preview. If null, color manager will switch back to /// loaded colors - public static void SetTempPreviewColors(Dictionary colors) { + public static void SetTempPreviewColors(Dictionary colors) + { _tempPreviewColors = colors; EventBus.Push(new OnThemeChanged()); } @@ -190,9 +217,11 @@ public static void SetTempPreviewColors(Dictionary colors /// Finds the index of a theme /// A theme name /// The index of the given theme - public static int ThemeNameToIndex(string themeName) { + public static int ThemeNameToIndex(string themeName) + { int i = 0; - foreach (string theme in AvailableThemes) { + foreach (string theme in AvailableThemes) + { if (theme.Equals(themeName)) return i; i++; @@ -204,7 +233,8 @@ public static int ThemeNameToIndex(string themeName) { /// The theme name at that index, or default if it does not exist /// A theme index /// The name of the given theme - public static string ThemeIndexToName(int index) { + public static string ThemeIndexToName(int index) + { if (index >= AvailableThemes.Length || index == -1) return DEFAULT_THEME; else @@ -212,7 +242,8 @@ public static string ThemeIndexToName(int index) { } /// Each value represents a different color that can differ across themes - public enum SynthesisColor { + public enum SynthesisColor + { InteractiveElementSolid, InteractiveElementLeft, InteractiveElementRight, diff --git a/fission/src/modals/configuring/ChangeInputsModal.tsx b/fission/src/modals/configuring/ChangeInputsModal.tsx index e1344f492b..38d5abdc9e 100644 --- a/fission/src/modals/configuring/ChangeInputsModal.tsx +++ b/fission/src/modals/configuring/ChangeInputsModal.tsx @@ -4,35 +4,10 @@ import { FaGamepad } from "react-icons/fa6" import Stack, { StackDirection } from "../../components/Stack" import Label, { LabelSize } from "../../components/Label" import LabeledButton, { LabelPlacement } from "../../components/LabeledButton" - -type ModifierState = { - alt?: boolean - ctrl?: boolean - shift?: boolean - meta?: boolean -} - -type Control = { - name: string - key: string - modifiers?: ModifierState -} - -const globalControls: { [key: string]: Control } = { - "Intake": { name: "Intake", key: "E" }, - "Shoot Gamepiece": { name: "Shoot Gamepiece", key: "Q" }, - "Enable God Mode": { name: "Enable God Mode", key: "G" }, -} - -const robotControls: { [key: string]: Control } = { - "Arcade Forward": { name: "Arcade Forward", key: "W" }, - "Arcade Backward": { name: "Arcade Backward", key: "A" }, - "Arcade Left": { name: "Arcade Left", key: "S" }, - "Arcade Right": { name: "Arcade Right", key: "D" }, -} +import InputSystem from "@/systems/input/InputSystem" // capitalize first letter -const transformKeyName = (control: Control) => { +const transformKeyName = (control: Input) => { let suffix = "" if (control.modifiers) { if (control.modifiers.meta) suffix += " + Meta" @@ -40,7 +15,7 @@ const transformKeyName = (control: Control) => { if (control.modifiers.ctrl) suffix += " + Ctrl" if (control.modifiers.alt) suffix += " + Alt" } - return control.key[0].toUpperCase() + control.key.substring(1) + suffix + return control.keybind[0].toUpperCase() + control.keybind.substring(1) + suffix } const ChangeInputsModal: React.FC = ({ modalId }) => { @@ -54,8 +29,8 @@ const ChangeInputsModal: React.FC = ({ modalId }) => { }) if (selectedInput && chosenKey) { - const selected = globalControls[selectedInput] - selected.key = chosenKey + const selected = InputSystem.allInputs[selectedInput] + selected.keybind = chosenKey selected.modifiers = modifierState setChosenKey("") setSelectedInput("") @@ -80,8 +55,9 @@ const ChangeInputsModal: React.FC = ({ modalId }) => { {loadedRobot ? ( <> - {Object.values(robotControls).map(c => ( + {Object.values(InputSystem.robotInputs).map(c => ( = ({ modalId }) => { }} > - {Object.values(globalControls).map(c => ( + {Object.values(InputSystem.globalInputs).map(c => ( input.isGlobal)); + } + + public static get robotInputs(): { [key: string]: Input } { + return Object.fromEntries( + Object.entries(InputSystem.allInputs) + .filter(([_, input]) => !input.isGlobal)); + } + + // A list of keys currently being pressed + private static keysPressed: { [key: string]: boolean } = {}; + + constructor() { + super(); + + this.handleKeyDown = this.handleKeyDown.bind(this); + document.addEventListener('keydown', this.handleKeyDown); + + this.handleKeyUp = this.handleKeyUp.bind(this); + document.addEventListener('keyup', this.handleKeyUp); + + // TODO: Load saved global controls + + // TODO: Load saved robot specific controls + + for (let key in defaultInputs) { + if (defaultInputs.hasOwnProperty(key)) { + InputSystem.allInputs[key] = defaultInputs[key]; + } + } + } + + // #region WorldSystem Functions + + public Update(_: number): void { } + + public Destroy(): void { + document.removeEventListener('keydown', this.handleKeyDown); + document.removeEventListener('keyup', this.handleKeyUp); + } + + // #endregion + // #region Input Events + + handleKeyDown(event: KeyboardEvent) { + InputSystem.keysPressed[event.key] = true; + } + + handleKeyUp(event: KeyboardEvent) { + InputSystem.keysPressed[event.key] = false; + } + + // #endregion + // #region Get Inputs + + private static isKeyPressed(key: string): boolean { + return !!InputSystem.keysPressed[key]; + } + + public static getInput(inputName: string) : boolean { + // Checks if there is a global control for this action + if (inputName in this.allInputs) { + // TODO: support for control modifiers + return this.isKeyPressed(this.allInputs[inputName].keybind); + } + + // If the input does not exist, returns false + return false; + } + + // #endregion +} + +export default InputSystem; \ No newline at end of file diff --git a/fission/src/systems/simulation/driver/SliderDriver.ts b/fission/src/systems/simulation/driver/SliderDriver.ts index 9e6891f974..b6ace1ad60 100644 --- a/fission/src/systems/simulation/driver/SliderDriver.ts +++ b/fission/src/systems/simulation/driver/SliderDriver.ts @@ -2,6 +2,7 @@ import Jolt from "@barclah/jolt-physics"; import Driver from "./Driver"; import { SIMULATION_PERIOD } from "@/systems/physics/PhysicsSystem"; import JOLT from "@/util/loading/JoltSyncLoader"; +import InputSystem from "@/systems/input/InputSystem"; class SliderDriver extends Driver { @@ -44,6 +45,7 @@ class SliderDriver extends Driver { } public Update(_: number): void { + this._targetPosition += ((InputSystem.getInput("sliderUp") ? 1 : 0) - (InputSystem.getInput("sliderDown") ? 1 : 0))*3; this._constraint.SetTargetPosition(this._targetPosition); } } diff --git a/fission/src/systems/simulation/driver/WheelDriver.ts b/fission/src/systems/simulation/driver/WheelDriver.ts index d2b8c492ee..d7ed8de254 100644 --- a/fission/src/systems/simulation/driver/WheelDriver.ts +++ b/fission/src/systems/simulation/driver/WheelDriver.ts @@ -1,6 +1,7 @@ import Jolt from "@barclah/jolt-physics"; import Driver from "./Driver"; import JOLT from "@/util/loading/JoltSyncLoader"; +import InputSystem from "@/systems/input/InputSystem"; class WheelDriver extends Driver { @@ -21,16 +22,17 @@ class WheelDriver extends Driver { this._constraint = constraint; this._wheel = JOLT.castObject(this._constraint.GetWheel(0), JOLT.WheelWV); - - console.log(`Wheel X: ${constraint.GetVehicleBody().GetCenterOfMassPosition().GetX().toFixed(5)}`); + if (constraint.GetVehicleBody().GetCenterOfMassPosition().GetX() < 0) { - this._targetWheelSpeed = 10.0; + this._targetWheelSpeed = 0; } else { - this._targetWheelSpeed = 10.0; + this._targetWheelSpeed = 0; } } public Update(_: number): void { + this._targetWheelSpeed = InputSystem.getInput('arcadeForward') ? 50 : InputSystem.getInput('arcadeBackward') ? -50 : 0; + this._wheel.SetAngularVelocity(this._targetWheelSpeed); } } diff --git a/fission/src/systems/simulation/stimulus/WheelStimulus.ts b/fission/src/systems/simulation/stimulus/WheelStimulus.ts index 4edce43cd1..ca7e66e658 100644 --- a/fission/src/systems/simulation/stimulus/WheelStimulus.ts +++ b/fission/src/systems/simulation/stimulus/WheelStimulus.ts @@ -36,7 +36,7 @@ class WheelRotationStimulus extends EncoderStimulus { public Update(deltaT: number): void { if (this._accum) { - this._wheelRotationAccum += this._wheel.GetAngularVelocity() * deltaT; + this._wheelRotationAccum += 0; } } From ed7ca91ea6af7e31753e05a29671a88455a7bf15 Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Mon, 17 Jun 2024 17:14:21 -0700 Subject: [PATCH 02/12] getAxis method in InputSystem and arcade drive behavior --- fission/src/systems/input/InputSystem.ts | 4 +++ .../behavior/ArcadeDriveBehavior.ts | 32 +++++++++++++++++++ .../{synthesis_brain => behavior}/Behavior.ts | 2 ++ .../synthesis_brain/SynthesisBrain.ts | 2 +- 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts rename fission/src/systems/simulation/{synthesis_brain => behavior}/Behavior.ts (89%) diff --git a/fission/src/systems/input/InputSystem.ts b/fission/src/systems/input/InputSystem.ts index 902f1f8d0f..85dd1cff3f 100644 --- a/fission/src/systems/input/InputSystem.ts +++ b/fission/src/systems/input/InputSystem.ts @@ -103,6 +103,10 @@ class InputSystem extends WorldSystem { return false; } + public static getAxis(positive: string, negative: string) { + return (this.getInput(positive) ? 1 : 0) - (this.getInput(negative) ? 1 : 0); + } + // #endregion } diff --git a/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts b/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts new file mode 100644 index 0000000000..534bd6d010 --- /dev/null +++ b/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts @@ -0,0 +1,32 @@ +import { IoHandRightSharp } from "react-icons/io5"; +import WheelDriver from "../driver/WheelDriver"; +import WheelRotationStimulus from "../stimulus/WheelStimulus"; +import Behavior from "./Behavior"; +import InputSystem from "@/systems/input/InputSystem"; + +class ArcadeDriveBehavior extends Behavior { + leftWheels: WheelDriver[]; + rightWheels: WheelDriver[]; + + private driveSpeed = 1; + private turnSpeed = 1; + + constructor(leftWheels: WheelDriver[], rightWheels: WheelDriver[], leftStimuli: WheelRotationStimulus[], rightStimuli: WheelRotationStimulus[]) { + super(leftWheels.concat(rightWheels), leftStimuli.concat(rightStimuli)); + this.leftWheels = leftWheels; + this.rightWheels = rightWheels; + } + + driveSpeeds(linearVelocity: number, rotationVelocity: number) { + let leftSpeed = linearVelocity + rotationVelocity; + let rightSpeed = linearVelocity - rotationVelocity; + + this.leftWheels.forEach((wheel) => wheel.targetWheelSpeed = leftSpeed); + this.rightWheels.forEach((wheel) => wheel.targetWheelSpeed = rightSpeed); + } + + public Update(deltaT: number): void { + this.driveSpeeds(InputSystem.getAxis("arcadeForward", "arcadeBackward")*this.driveSpeed, + InputSystem.getAxis("arcadeRight", "arcadeLeft")*this.turnSpeed); + } +} \ No newline at end of file diff --git a/fission/src/systems/simulation/synthesis_brain/Behavior.ts b/fission/src/systems/simulation/behavior/Behavior.ts similarity index 89% rename from fission/src/systems/simulation/synthesis_brain/Behavior.ts rename to fission/src/systems/simulation/behavior/Behavior.ts index 90fb1b1bdc..d78c1a2362 100644 --- a/fission/src/systems/simulation/synthesis_brain/Behavior.ts +++ b/fission/src/systems/simulation/behavior/Behavior.ts @@ -13,6 +13,8 @@ abstract class Behavior { this._drivers = drivers; this._stimuli = stimuli; } + + public abstract Update(deltaT: number): void; } export default Behavior; \ No newline at end of file diff --git a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts index d17a1e993f..79668ede53 100644 --- a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts +++ b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts @@ -1,6 +1,6 @@ import Mechanism from "@/systems/physics/Mechanism"; import Brain from "../Brain"; -import Behavior from "./Behavior"; +import Behavior from "../behavior/Behavior"; class SynthesisBrain extends Brain { From 7d603ca0083113787fbbb34d468e68149cc1addd Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Tue, 18 Jun 2024 13:55:16 -0700 Subject: [PATCH 03/12] Arcade drive behavior and wheel debug information --- fission/src/mirabuf/MirabufSceneObject.ts | 3 +- fission/src/systems/input/InputSystem.ts | 1 + .../systems/simulation/SimulationSystem.ts | 8 +- .../behavior/ArcadeDriveBehavior.ts | 11 +-- .../systems/simulation/driver/WheelDriver.ts | 18 ++--- .../synthesis_brain/SynthesisBrain.ts | 79 ++++++++++++++++++- 6 files changed, 100 insertions(+), 20 deletions(-) diff --git a/fission/src/mirabuf/MirabufSceneObject.ts b/fission/src/mirabuf/MirabufSceneObject.ts index 34a98b539c..cd92814216 100644 --- a/fission/src/mirabuf/MirabufSceneObject.ts +++ b/fission/src/mirabuf/MirabufSceneObject.ts @@ -12,7 +12,7 @@ import { LayerReserve } from "@/systems/physics/PhysicsSystem"; import Mechanism from "@/systems/physics/Mechanism"; import SynthesisBrain from "@/systems/simulation/synthesis_brain/SynthesisBrain"; -const DEBUG_BODIES = true; +const DEBUG_BODIES = false; interface RnDebugMeshes { colliderMesh: THREE.Mesh; @@ -91,6 +91,7 @@ class MirabufSceneObject extends SceneObject { colliderMesh.rotation.setFromRotationMatrix(transform); const comTransform = JoltMat44_ThreeMatrix4(body.GetCenterOfMassTransform()); + comMesh.position.setFromMatrixPosition(comTransform); comMesh.rotation.setFromRotationMatrix(comTransform); } diff --git a/fission/src/systems/input/InputSystem.ts b/fission/src/systems/input/InputSystem.ts index 85dd1cff3f..0526b1c2cc 100644 --- a/fission/src/systems/input/InputSystem.ts +++ b/fission/src/systems/input/InputSystem.ts @@ -16,6 +16,7 @@ declare global { } } +// When a robot is loaded, default inputs replace any unassigned inputs const defaultInputs: { [key: string]: Input } = { "intake": { name: "intake", keybind: "e", isGlobal: true }, "shootGamepiece": { name: "shootGamepiece", keybind: "q", isGlobal: true }, diff --git a/fission/src/systems/simulation/SimulationSystem.ts b/fission/src/systems/simulation/SimulationSystem.ts index ce95d15d46..58190d9368 100644 --- a/fission/src/systems/simulation/SimulationSystem.ts +++ b/fission/src/systems/simulation/SimulationSystem.ts @@ -62,6 +62,8 @@ class SimulationLayer { private _stimuli: Stimulus[]; public get brain() { return this._brain; } + public get drivers() { return this._drivers; } + public get stimuli() { return this._stimuli; } constructor(mechanism: Mechanism) { this._mechanism = mechanism; @@ -105,9 +107,11 @@ class SimulationLayer { this._brain = brain; - if (this._brain) + if (this._brain) { this._brain.Enable(); + } } } -export default SimulationSystem; \ No newline at end of file +export default SimulationSystem; +export {SimulationLayer}; \ No newline at end of file diff --git a/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts b/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts index 534bd6d010..c704936121 100644 --- a/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts +++ b/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts @@ -1,4 +1,3 @@ -import { IoHandRightSharp } from "react-icons/io5"; import WheelDriver from "../driver/WheelDriver"; import WheelRotationStimulus from "../stimulus/WheelStimulus"; import Behavior from "./Behavior"; @@ -8,8 +7,8 @@ class ArcadeDriveBehavior extends Behavior { leftWheels: WheelDriver[]; rightWheels: WheelDriver[]; - private driveSpeed = 1; - private turnSpeed = 1; + private driveSpeed = 30; + private turnSpeed = 30; constructor(leftWheels: WheelDriver[], rightWheels: WheelDriver[], leftStimuli: WheelRotationStimulus[], rightStimuli: WheelRotationStimulus[]) { super(leftWheels.concat(rightWheels), leftStimuli.concat(rightStimuli)); @@ -25,8 +24,10 @@ class ArcadeDriveBehavior extends Behavior { this.rightWheels.forEach((wheel) => wheel.targetWheelSpeed = rightSpeed); } - public Update(deltaT: number): void { + public Update(_: number): void { this.driveSpeeds(InputSystem.getAxis("arcadeForward", "arcadeBackward")*this.driveSpeed, InputSystem.getAxis("arcadeRight", "arcadeLeft")*this.turnSpeed); } -} \ No newline at end of file +} + +export default ArcadeDriveBehavior; \ No newline at end of file diff --git a/fission/src/systems/simulation/driver/WheelDriver.ts b/fission/src/systems/simulation/driver/WheelDriver.ts index d7ed8de254..dd115b791f 100644 --- a/fission/src/systems/simulation/driver/WheelDriver.ts +++ b/fission/src/systems/simulation/driver/WheelDriver.ts @@ -1,7 +1,6 @@ import Jolt from "@barclah/jolt-physics"; import Driver from "./Driver"; import JOLT from "@/util/loading/JoltSyncLoader"; -import InputSystem from "@/systems/input/InputSystem"; class WheelDriver extends Driver { @@ -17,22 +16,23 @@ class WheelDriver extends Driver { this._targetWheelSpeed = radsPerSec; } + public get constraint(): Jolt.VehicleConstraint { return this._constraint } + public constructor(constraint: Jolt.VehicleConstraint) { super(); this._constraint = constraint; this._wheel = JOLT.castObject(this._constraint.GetWheel(0), JOLT.WheelWV); - if (constraint.GetVehicleBody().GetCenterOfMassPosition().GetX() < 0) { - this._targetWheelSpeed = 0; - } else { - this._targetWheelSpeed = 0; - } + // TODO: I think this was just for testing + // if (constraint.GetVehicleBody().GetCenterOfMassPosition().GetX() < 0) { + // this._targetWheelSpeed = 0; + // } else { + // this._targetWheelSpeed = 0; + // } } - public Update(_: number): void { - this._targetWheelSpeed = InputSystem.getInput('arcadeForward') ? 50 : InputSystem.getInput('arcadeBackward') ? -50 : 0; - + public Update(_: number): void { this._wheel.SetAngularVelocity(this._targetWheelSpeed); } } diff --git a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts index 79668ede53..248274a5ff 100644 --- a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts +++ b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts @@ -1,21 +1,94 @@ -import Mechanism from "@/systems/physics/Mechanism"; +import Mechanism, { MechanismConstraint } from "@/systems/physics/Mechanism"; import Brain from "../Brain"; import Behavior from "../behavior/Behavior"; +import World from "@/systems/World"; +import WheelDriver from "../driver/WheelDriver"; +import WheelRotationStimulus from "../stimulus/WheelStimulus"; +import ArcadeDriveBehavior from "../behavior/ArcadeDriveBehavior"; +import { SimulationLayer } from "../SimulationSystem"; +import * as THREE from 'three'; +import { JoltMat44_ThreeMatrix4 } from "@/util/TypeConversions"; +import Jolt from "@barclah/jolt-physics"; +import { JOLT_TYPES } from "@/util/loading/JoltAsyncLoader"; +import JOLT from "@/util/loading/JoltSyncLoader"; + class SynthesisBrain extends Brain { + private _behaviors: Behavior[] = []; + private _simLayer: SimulationLayer; - public _behaviors: Behavior[] = []; + private _debugBodies: Map; public constructor(mechanism: Mechanism) { super(mechanism); + + this._simLayer = World.SimulationSystem.GetSimulationLayer(mechanism)!; + + this._debugBodies = new Map(); + + if (!this._simLayer) { + console.log("Simulation Layer is undefined"); + return; + } + + console.log("config arcade drive"); + this.configureArcadeDriveBehavior(); + + // const comMesh = World.SceneRenderer.CreateSphere(0.05); + // World.SceneRenderer.scene.add(comMesh); + + // (comMesh.material as THREE.Material).depthTest = false; + + // this._debugMeshes.push(comMesh); + + // console.log(mechanism.nodeToBody); + //this._debugBodies!.set(rnName, { colliderMesh: colliderMesh, comMesh: comMesh }); + //comMesh.position = new THREE.Vector3(0, 0, 0); + + this._mechanism.constraints.forEach((c) => { + if (!(c.constraint instanceof JOLT.TwoBodyConstraint)) + return; + + const comMesh = World.SceneRenderer.CreateSphere(0.05); + (comMesh.material as THREE.Material).depthTest = false; + + World.SceneRenderer.scene.add(comMesh); + + this._debugBodies.set(c.constraint as Jolt.TwoBodyConstraint, comMesh); + }); + console.log("Number of constraints: " + this._debugBodies.size); } - public Update(_: number): void { } public Enable(): void { } + public Update(deltaT: number): void { + this._behaviors.forEach((b) => b.Update(deltaT)); +let i = 0; + this._debugBodies.forEach((value, key) => { + if (i != 0)return; + const transform = JoltMat44_ThreeMatrix4(key.GetConstraintToBody1Matrix()); + value!.position.setFromMatrixPosition(transform); + i++; + }); + } public Disable(): void { this._behaviors = []; } + configureArcadeDriveBehavior() { + let wheelDrivers: WheelDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof WheelDriver) as WheelDriver[]; + let wheelStimuli: WheelRotationStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof WheelRotationStimulus) as WheelRotationStimulus[]; + + let fixedConstraints: Jolt.TwoBodyConstraint[] = this._mechanism.constraints.filter((mechConstraint) => mechConstraint.constraint instanceof JOLT.TwoBodyConstraint).map((mechConstraint) => mechConstraint.constraint as Jolt.TwoBodyConstraint); + console.log(fixedConstraints.length); + + //wheelDrivers.forEach((w) => console.log(w.constraint)) + + this._behaviors.push(new ArcadeDriveBehavior([wheelDrivers[0], wheelDrivers[1], wheelDrivers[2]], [wheelDrivers[3], wheelDrivers[4], wheelDrivers[5]], [wheelStimuli[0], wheelStimuli[1], wheelStimuli[2]], [wheelStimuli[3], wheelStimuli[4], wheelStimuli[5]])); + } + + getLeftRightWheels() { + throw new Error("Method not implemented."); + } } export default SynthesisBrain; \ No newline at end of file From bbece64a5541a3c920f16ac701fcf5c09463622b Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Tue, 18 Jun 2024 14:59:39 -0700 Subject: [PATCH 04/12] Left right wheel solver --- fission/src/mirabuf/MirabufSceneObject.ts | 2 +- .../simulation/behavior/GenericArmBehavior.ts | 34 +++++++++++++++ .../synthesis_brain/SynthesisBrain.ts | 43 +++++++++++++++++-- 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 fission/src/systems/simulation/behavior/GenericArmBehavior.ts diff --git a/fission/src/mirabuf/MirabufSceneObject.ts b/fission/src/mirabuf/MirabufSceneObject.ts index cd92814216..da9b9faba6 100644 --- a/fission/src/mirabuf/MirabufSceneObject.ts +++ b/fission/src/mirabuf/MirabufSceneObject.ts @@ -12,7 +12,7 @@ import { LayerReserve } from "@/systems/physics/PhysicsSystem"; import Mechanism from "@/systems/physics/Mechanism"; import SynthesisBrain from "@/systems/simulation/synthesis_brain/SynthesisBrain"; -const DEBUG_BODIES = false; +const DEBUG_BODIES = true; interface RnDebugMeshes { colliderMesh: THREE.Mesh; diff --git a/fission/src/systems/simulation/behavior/GenericArmBehavior.ts b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts new file mode 100644 index 0000000000..acf6f8d460 --- /dev/null +++ b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts @@ -0,0 +1,34 @@ +// import HingeDriver from "../driver/HingeDriver"; +// import WheelDriver from "../driver/WheelDriver"; +// import HingeStimulus from "../stimulus/HingeStimulus"; +// import WheelRotationStimulus from "../stimulus/WheelStimulus"; +// import Behavior from "./Behavior"; +// import InputSystem from "@/systems/input/InputSystem"; + +// class ArcadeDriveBehavior extends Behavior { +// private _hingeDriver: HingeDriver; + +// private driveSpeed = 30; +// private turnSpeed = 30; + +// constructor(hingeDriver: HingeDriver, hingeStimulus: HingeStimulus) { +// super(leftWheels.concat(rightWheels), leftStimuli.concat(rightStimuli)); +// this.leftWheels = leftWheels; +// this.rightWheels = rightWheels; +// } + +// driveSpeeds(linearVelocity: number, rotationVelocity: number) { +// let leftSpeed = linearVelocity + rotationVelocity; +// let rightSpeed = linearVelocity - rotationVelocity; + +// this.leftWheels.forEach((wheel) => wheel.targetWheelSpeed = leftSpeed); +// this.rightWheels.forEach((wheel) => wheel.targetWheelSpeed = rightSpeed); +// } + +// public Update(_: number): void { +// this.driveSpeeds(InputSystem.getAxis("arcadeForward", "arcadeBackward")*this.driveSpeed, +// InputSystem.getAxis("arcadeRight", "arcadeLeft")*this.turnSpeed); +// } +// } + +// export default ArcadeDriveBehavior; \ No newline at end of file diff --git a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts index 248274a5ff..7d4cc5c8f4 100644 --- a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts +++ b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts @@ -19,6 +19,8 @@ class SynthesisBrain extends Brain { private _debugBodies: Map; + _leftWheelIndices: number[] = []; + public constructor(mechanism: Mechanism) { super(mechanism); @@ -60,11 +62,14 @@ class SynthesisBrain extends Brain { } public Enable(): void { } + public Update(deltaT: number): void { this._behaviors.forEach((b) => b.Update(deltaT)); -let i = 0; + + let i = 0; this._debugBodies.forEach((value, key) => { - if (i != 0)return; + if (!(this._leftWheelIndices.includes(i))) { i++; return;} + const transform = JoltMat44_ThreeMatrix4(key.GetConstraintToBody1Matrix()); value!.position.setFromMatrixPosition(transform); i++; @@ -74,16 +79,46 @@ let i = 0; this._behaviors = []; } + configureArcadeDriveBehavior() { let wheelDrivers: WheelDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof WheelDriver) as WheelDriver[]; let wheelStimuli: WheelRotationStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof WheelRotationStimulus) as WheelRotationStimulus[]; let fixedConstraints: Jolt.TwoBodyConstraint[] = this._mechanism.constraints.filter((mechConstraint) => mechConstraint.constraint instanceof JOLT.TwoBodyConstraint).map((mechConstraint) => mechConstraint.constraint as Jolt.TwoBodyConstraint); - console.log(fixedConstraints.length); + + let leftWheels: WheelDriver[] = []; + let leftStimuli: WheelRotationStimulus[] = []; + + let rightWheels: WheelDriver[] = []; + let rightStimuli: WheelRotationStimulus[] = []; + + for (let i = 0; i < wheelDrivers.length; i++) { + let wheelPos = fixedConstraints[i].GetConstraintToBody1Matrix().GetTranslation(); + + let robotCOM = World.PhysicsSystem.GetBody(this._mechanism.constraints[0].childBody).GetCenterOfMassPosition() as Jolt.Vec3; + let rightVector = new JOLT.Vec3(1, 0, 0); + + let dotProduct = rightVector.Dot(wheelPos.Sub(robotCOM)) + + if (dotProduct < 0) { + rightWheels.push(wheelDrivers[i]); + rightStimuli.push(wheelStimuli[i]); + } + else { + leftWheels.push(wheelDrivers[i]); + leftStimuli.push(wheelStimuli[i]); + this._leftWheelIndices.push(i); + console.log(i); + } + } + + fixedConstraints.forEach((c) => { + //console.log(c.GetBody1().GetRotation().GetEulerAngles()); + }) //wheelDrivers.forEach((w) => console.log(w.constraint)) - this._behaviors.push(new ArcadeDriveBehavior([wheelDrivers[0], wheelDrivers[1], wheelDrivers[2]], [wheelDrivers[3], wheelDrivers[4], wheelDrivers[5]], [wheelStimuli[0], wheelStimuli[1], wheelStimuli[2]], [wheelStimuli[3], wheelStimuli[4], wheelStimuli[5]])); + this._behaviors.push(new ArcadeDriveBehavior(leftWheels, rightWheels, leftStimuli, rightStimuli)); } getLeftRightWheels() { From ffc546ff6e4bda3386fa6878b1bdc2d1e329730c Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Tue, 18 Jun 2024 16:43:49 -0700 Subject: [PATCH 05/12] Control panel formatting, working input modifiers, elevator and arm behavior --- fission/src/mirabuf/MirabufSceneObject.ts | 2 +- .../modals/configuring/ChangeInputsModal.tsx | 22 ++--- fission/src/systems/input/InputSystem.ts | 64 ++++++++++----- .../behavior/ArcadeDriveBehavior.ts | 8 +- .../simulation/behavior/GenericArmBehavior.ts | 47 +++++------ .../behavior/GenericElevatorBehavior.ts | 28 +++++++ .../synthesis_brain/SynthesisBrain.ts | 81 +++++++------------ 7 files changed, 133 insertions(+), 119 deletions(-) create mode 100644 fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts diff --git a/fission/src/mirabuf/MirabufSceneObject.ts b/fission/src/mirabuf/MirabufSceneObject.ts index da9b9faba6..cd92814216 100644 --- a/fission/src/mirabuf/MirabufSceneObject.ts +++ b/fission/src/mirabuf/MirabufSceneObject.ts @@ -12,7 +12,7 @@ import { LayerReserve } from "@/systems/physics/PhysicsSystem"; import Mechanism from "@/systems/physics/Mechanism"; import SynthesisBrain from "@/systems/simulation/synthesis_brain/SynthesisBrain"; -const DEBUG_BODIES = true; +const DEBUG_BODIES = false; interface RnDebugMeshes { colliderMesh: THREE.Mesh; diff --git a/fission/src/modals/configuring/ChangeInputsModal.tsx b/fission/src/modals/configuring/ChangeInputsModal.tsx index 38d5abdc9e..45a75e98b3 100644 --- a/fission/src/modals/configuring/ChangeInputsModal.tsx +++ b/fission/src/modals/configuring/ChangeInputsModal.tsx @@ -8,24 +8,24 @@ import InputSystem from "@/systems/input/InputSystem" // capitalize first letter const transformKeyName = (control: Input) => { - let suffix = "" + let prefix = "" if (control.modifiers) { - if (control.modifiers.meta) suffix += " + Meta" - if (control.modifiers.shift) suffix += " + Shift" - if (control.modifiers.ctrl) suffix += " + Ctrl" - if (control.modifiers.alt) suffix += " + Alt" + if (control.modifiers.meta) prefix += "Meta + " + if (control.modifiers.shift) prefix += "Shift + " + if (control.modifiers.ctrl) prefix += "Ctrl + " + if (control.modifiers.alt) prefix += "Alt + " } - return control.keybind[0].toUpperCase() + control.keybind.substring(1) + suffix + return prefix + control.keybind[0].toUpperCase() + control.keybind.substring(1) } const ChangeInputsModal: React.FC = ({ modalId }) => { const [loadedRobot, setLoadedRobot] = useState("") const [selectedInput, setSelectedInput] = useState("") const [chosenKey, setChosenKey] = useState("") - const [modifierState, setModifierState] = useState({}) + const [modifierState, setModifierState] = useState({ctrl: false, alt: false, shift: false, meta: false}) useEffect(() => { - setTimeout(() => setLoadedRobot("Dozer v9"), 2_000) + setTimeout(() => setLoadedRobot("Dozer v9"), 1) }) if (selectedInput && chosenKey) { @@ -34,7 +34,7 @@ const ChangeInputsModal: React.FC = ({ modalId }) => { selected.modifiers = modifierState setChosenKey("") setSelectedInput("") - setModifierState({}) + setModifierState({ctrl: false, alt: false, shift: false, meta: false}) } return ( @@ -58,7 +58,7 @@ const ChangeInputsModal: React.FC = ({ modalId }) => { {Object.values(InputSystem.robotInputs).map(c => ( = ({ modalId }) => { {Object.values(InputSystem.globalInputs).map(c => ( wheel.targetWheelSpeed = leftSpeed); -// this.rightWheels.forEach((wheel) => wheel.targetWheelSpeed = rightSpeed); -// } + rotateArm(rotationalVelocity: number) { + this._hingeDriver.targetVelocity = rotationalVelocity; + } -// public Update(_: number): void { -// this.driveSpeeds(InputSystem.getAxis("arcadeForward", "arcadeBackward")*this.driveSpeed, -// InputSystem.getAxis("arcadeRight", "arcadeLeft")*this.turnSpeed); -// } -// } + public Update(_: number): void { + this.rotateArm(InputSystem.getAxis("armPositive", "armNegative")*this._rotationalSpeed); + } +} -// export default ArcadeDriveBehavior; \ No newline at end of file +export default GenericArmBehavior; \ No newline at end of file diff --git a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts new file mode 100644 index 0000000000..6ca4af3930 --- /dev/null +++ b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts @@ -0,0 +1,28 @@ +import SliderDriver from "../driver/SliderDriver"; +import SliderStimulus from "../stimulus/SliderStimulus"; +import Behavior from "./Behavior"; +import InputSystem from "@/systems/input/InputSystem"; + +class GenericElevatorBehavior extends Behavior { + private _sliderDriver: SliderDriver; + + private _linearSpeed = 1; + + private _inverted: boolean; + + constructor(sliderDriver: SliderDriver, sliderStimulus: SliderStimulus, inverted: boolean) { + super([sliderDriver], [sliderStimulus]); + this._sliderDriver = sliderDriver; + this._inverted = inverted; + } + + moveElevator(positionDelta: number) { + this._sliderDriver.targetPosition += positionDelta * (this._inverted ? -1 : 1); + } + + public Update(deltaT: number): void { + this.moveElevator(InputSystem.getAxis("elevatorPositive", "elevatorNegative")*this._linearSpeed*deltaT); + } +} + +export default GenericElevatorBehavior; \ No newline at end of file diff --git a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts index 7d4cc5c8f4..d06101d480 100644 --- a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts +++ b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts @@ -1,4 +1,4 @@ -import Mechanism, { MechanismConstraint } from "@/systems/physics/Mechanism"; +import Mechanism from "@/systems/physics/Mechanism"; import Brain from "../Brain"; import Behavior from "../behavior/Behavior"; import World from "@/systems/World"; @@ -6,19 +6,20 @@ import WheelDriver from "../driver/WheelDriver"; import WheelRotationStimulus from "../stimulus/WheelStimulus"; import ArcadeDriveBehavior from "../behavior/ArcadeDriveBehavior"; import { SimulationLayer } from "../SimulationSystem"; -import * as THREE from 'three'; -import { JoltMat44_ThreeMatrix4 } from "@/util/TypeConversions"; import Jolt from "@barclah/jolt-physics"; -import { JOLT_TYPES } from "@/util/loading/JoltAsyncLoader"; import JOLT from "@/util/loading/JoltSyncLoader"; +import HingeDriver from "../driver/HingeDriver"; +import HingeStimulus from "../stimulus/HingeStimulus"; +import GenericArmBehavior from "../behavior/GenericArmBehavior"; +import SliderDriver from "../driver/SliderDriver"; +import SliderStimulus from "../stimulus/SliderStimulus"; +import GenericElevatorBehavior from "../behavior/GenericElevatorBehavior"; class SynthesisBrain extends Brain { private _behaviors: Behavior[] = []; private _simLayer: SimulationLayer; - private _debugBodies: Map; - _leftWheelIndices: number[] = []; public constructor(mechanism: Mechanism) { @@ -26,60 +27,26 @@ class SynthesisBrain extends Brain { this._simLayer = World.SimulationSystem.GetSimulationLayer(mechanism)!; - this._debugBodies = new Map(); - if (!this._simLayer) { console.log("Simulation Layer is undefined"); return; } - console.log("config arcade drive"); this.configureArcadeDriveBehavior(); - - // const comMesh = World.SceneRenderer.CreateSphere(0.05); - // World.SceneRenderer.scene.add(comMesh); - - // (comMesh.material as THREE.Material).depthTest = false; - - // this._debugMeshes.push(comMesh); - - // console.log(mechanism.nodeToBody); - //this._debugBodies!.set(rnName, { colliderMesh: colliderMesh, comMesh: comMesh }); - //comMesh.position = new THREE.Vector3(0, 0, 0); - - this._mechanism.constraints.forEach((c) => { - if (!(c.constraint instanceof JOLT.TwoBodyConstraint)) - return; - - const comMesh = World.SceneRenderer.CreateSphere(0.05); - (comMesh.material as THREE.Material).depthTest = false; - - World.SceneRenderer.scene.add(comMesh); - - this._debugBodies.set(c.constraint as Jolt.TwoBodyConstraint, comMesh); - }); - console.log("Number of constraints: " + this._debugBodies.size); + this.configureArmBehaviors(); + this.configureElevatorBehaviors(); } public Enable(): void { } public Update(deltaT: number): void { this._behaviors.forEach((b) => b.Update(deltaT)); - - let i = 0; - this._debugBodies.forEach((value, key) => { - if (!(this._leftWheelIndices.includes(i))) { i++; return;} - - const transform = JoltMat44_ThreeMatrix4(key.GetConstraintToBody1Matrix()); - value!.position.setFromMatrixPosition(transform); - i++; - }); } + public Disable(): void { this._behaviors = []; } - configureArcadeDriveBehavior() { let wheelDrivers: WheelDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof WheelDriver) as WheelDriver[]; let wheelStimuli: WheelRotationStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof WheelRotationStimulus) as WheelRotationStimulus[]; @@ -107,23 +74,29 @@ class SynthesisBrain extends Brain { else { leftWheels.push(wheelDrivers[i]); leftStimuli.push(wheelStimuli[i]); - this._leftWheelIndices.push(i); - console.log(i); } } - - fixedConstraints.forEach((c) => { - //console.log(c.GetBody1().GetRotation().GetEulerAngles()); - }) - - //wheelDrivers.forEach((w) => console.log(w.constraint)) this._behaviors.push(new ArcadeDriveBehavior(leftWheels, rightWheels, leftStimuli, rightStimuli)); } - getLeftRightWheels() { - throw new Error("Method not implemented."); + configureArmBehaviors() { + let hingeDrivers: HingeDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof HingeDriver) as HingeDriver[]; + let hingeStimuli: HingeStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof HingeStimulus) as HingeStimulus[]; + + for (let i = 0; i < hingeDrivers.length; i++) { + this._behaviors.push(new GenericArmBehavior(hingeDrivers[i], hingeStimuli[i])); + } + } + + configureElevatorBehaviors() { + let sliderDrivers: SliderDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof SliderDriver) as SliderDriver[]; + let sliderStimuli: SliderStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof SliderStimulus) as SliderStimulus[]; + + for (let i = 0; i < sliderDrivers.length; i++) { + this._behaviors.push(new GenericElevatorBehavior(sliderDrivers[i], sliderStimuli[i], i==0 ? false : true)); + } } } -export default SynthesisBrain; \ No newline at end of file +export default SynthesisBrain;32 \ No newline at end of file From 9040df51c66a80a6b363e8f62db170d8cd83e167 Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Wed, 19 Jun 2024 10:47:45 -0700 Subject: [PATCH 06/12] Unique controls for different joints and cleanup + comments --- .../modals/configuring/ChangeInputsModal.tsx | 6 +-- fission/src/systems/input/InputSystem.ts | 51 +++++++++---------- .../behavior/ArcadeDriveBehavior.ts | 2 + .../simulation/behavior/GenericArmBehavior.ts | 18 +++++-- .../behavior/GenericElevatorBehavior.ts | 23 ++++++--- .../systems/simulation/driver/WheelDriver.ts | 7 --- .../synthesis_brain/SynthesisBrain.ts | 16 ++++-- 7 files changed, 72 insertions(+), 51 deletions(-) diff --git a/fission/src/modals/configuring/ChangeInputsModal.tsx b/fission/src/modals/configuring/ChangeInputsModal.tsx index 45a75e98b3..c649aac041 100644 --- a/fission/src/modals/configuring/ChangeInputsModal.tsx +++ b/fission/src/modals/configuring/ChangeInputsModal.tsx @@ -4,7 +4,7 @@ import { FaGamepad } from "react-icons/fa6" import Stack, { StackDirection } from "../../components/Stack" import Label, { LabelSize } from "../../components/Label" import LabeledButton, { LabelPlacement } from "../../components/LabeledButton" -import InputSystem from "@/systems/input/InputSystem" +import InputSystem, { emptyModifierState } from "@/systems/input/InputSystem" // capitalize first letter const transformKeyName = (control: Input) => { @@ -22,7 +22,7 @@ const ChangeInputsModal: React.FC = ({ modalId }) => { const [loadedRobot, setLoadedRobot] = useState("") const [selectedInput, setSelectedInput] = useState("") const [chosenKey, setChosenKey] = useState("") - const [modifierState, setModifierState] = useState({ctrl: false, alt: false, shift: false, meta: false}) + const [modifierState, setModifierState] = useState(emptyModifierState) useEffect(() => { setTimeout(() => setLoadedRobot("Dozer v9"), 1) @@ -34,7 +34,7 @@ const ChangeInputsModal: React.FC = ({ modalId }) => { selected.modifiers = modifierState setChosenKey("") setSelectedInput("") - setModifierState({ctrl: false, alt: false, shift: false, meta: false}) + setModifierState(emptyModifierState) } return ( diff --git a/fission/src/systems/input/InputSystem.ts b/fission/src/systems/input/InputSystem.ts index 1b12e746ea..3a85f99669 100644 --- a/fission/src/systems/input/InputSystem.ts +++ b/fission/src/systems/input/InputSystem.ts @@ -16,31 +16,32 @@ declare global { } } +export const emptyModifierState: ModifierState = { ctrl: false, alt: false, shift: false, meta: false }; + // When a robot is loaded, default inputs replace any unassigned inputs const defaultInputs: { [key: string]: Input } = { - "intake": { name: "intake", keybind: "e", isGlobal: true, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - "shootGamepiece": { name: "shootGamepiece", keybind: "q", isGlobal: true, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - "enableGodMode": { name: "enableGodMode", keybind: "g", isGlobal: true, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - - "arcadeForward": { name: "arcadeForward", keybind: "w", isGlobal: false, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - "arcadeBackward": { name: "arcadeBackward", keybind: "s", isGlobal: false, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - "arcadeLeft": { name: "arcadeLeft", keybind: "a", isGlobal: false, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - "arcadeRight": { name: "arcadeRight", keybind: "d", isGlobal: false, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - "armPositive": { name: "armPositive", keybind: "1", isGlobal: false, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - "armNegative": { name: "armNegative", keybind: "2", isGlobal: false, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - "elevatorNegative": { name: "elevatorNegative", keybind: "4", isGlobal: false, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, - "elevatorPositive": { name: "elevatorPositive", keybind: "3", isGlobal: false, modifiers: { ctrl: false, alt: false, shift: false, meta: false } }, + "intake": { name: "intake", keybind: "e", isGlobal: true, modifiers: emptyModifierState }, + "shootGamepiece": { name: "shootGamepiece", keybind: "q", isGlobal: true, modifiers: emptyModifierState }, + "enableGodMode": { name: "enableGodMode", keybind: "g", isGlobal: true, modifiers: emptyModifierState }, + + "arcadeForward": { name: "arcadeForward", keybind: "w", isGlobal: false, modifiers: emptyModifierState }, + "arcadeBackward": { name: "arcadeBackward", keybind: "s", isGlobal: false, modifiers: emptyModifierState }, + "arcadeLeft": { name: "arcadeLeft", keybind: "a", isGlobal: false, modifiers: emptyModifierState }, + "arcadeRight": { name: "arcadeRight", keybind: "d", isGlobal: false, modifiers: emptyModifierState }, } class InputSystem extends WorldSystem { public static allInputs: { [key: string]: Input } = { } + private static _currentModifierState: ModifierState; + // Inputs global to all of synthesis like camera controls public static get globalInputs(): { [key: string]: Input } { return Object.fromEntries( Object.entries(InputSystem.allInputs) .filter(([_, input]) => input.isGlobal)); } + // Robot specific controls like driving public static get robotInputs(): { [key: string]: Input } { return Object.fromEntries( Object.entries(InputSystem.allInputs) @@ -58,10 +59,8 @@ class InputSystem extends WorldSystem { this.handleKeyUp = this.handleKeyUp.bind(this); document.addEventListener('keyup', this.handleKeyUp); - - // TODO: Load saved global controls - // TODO: Load saved robot specific controls + // TODO: Load saved inputs from mira (robot specific) & global inputs for (let key in defaultInputs) { if (defaultInputs.hasOwnProperty(key)) { @@ -70,42 +69,37 @@ class InputSystem extends WorldSystem { } } - // #region WorldSystem Functions - static _currentModifierState: ModifierState; public Update(_: number): void {InputSystem InputSystem._currentModifierState = { ctrl: InputSystem.isKeyPressed("Control"), alt: InputSystem.isKeyPressed("Alt"), shift: InputSystem.isKeyPressed("Shift"), meta: InputSystem.isKeyPressed("Meta") } - } + } public Destroy(): void { document.removeEventListener('keydown', this.handleKeyDown); document.removeEventListener('keyup', this.handleKeyUp); } - // #endregion - // #region Input Events - + // Called when any key is pressed handleKeyDown(event: KeyboardEvent) { InputSystem._keysPressed[event.key] = true; } + // Called when any key is released handleKeyUp(event: KeyboardEvent) { InputSystem._keysPressed[event.key] = false; } - // #endregion - // #region Get Inputs - + // Returns true if the given key is currently down private static isKeyPressed(key: string): boolean { return !!InputSystem._keysPressed[key]; } + // If an input exists, return true if it is pressed public static getInput(inputName: string) : boolean { - // Checks if there is a global control for this action + // Checks if there is an input assigned to this action if (inputName in this.allInputs) { let targetInput = this.allInputs[inputName]; // Check for input modifiers - if (!this.compareModifiers(InputSystem._currentModifierState, targetInput.modifiers)) return false; @@ -116,18 +110,19 @@ class InputSystem extends WorldSystem { return false; } + // Combines two inputs into a positive/negative axis public static getAxis(positive: string, negative: string) { return (this.getInput(positive) ? 1 : 0) - (this.getInput(negative) ? 1 : 0); } + // Converts camelCase to Title Case for the inputs modal public static toTitleCase(camelCase: string) : string { const result = camelCase.replace(/([A-Z])/g, " $1"); const finalResult = result.charAt(0).toUpperCase() + result.slice(1); return finalResult; } - // #endregion - + // Returns true if two modifier states are identical private static compareModifiers(state1: ModifierState, state2: ModifierState) : boolean { return state1.alt == state2.alt && state1.ctrl == state2.ctrl && state1.meta == state2.meta && state1.shift == state2.shift; } diff --git a/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts b/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts index e708da8c00..67f4b8f679 100644 --- a/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts +++ b/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts @@ -12,10 +12,12 @@ class ArcadeDriveBehavior extends Behavior { constructor(leftWheels: WheelDriver[], rightWheels: WheelDriver[], leftStimuli: WheelRotationStimulus[], rightStimuli: WheelRotationStimulus[]) { super(leftWheels.concat(rightWheels), leftStimuli.concat(rightStimuli)); + this.leftWheels = leftWheels; this.rightWheels = rightWheels; } + // Sets the drivetrains target linear and rotational velocity driveSpeeds(linearVelocity: number, rotationVelocity: number) { let leftSpeed = linearVelocity + rotationVelocity; let rightSpeed = linearVelocity - rotationVelocity; diff --git a/fission/src/systems/simulation/behavior/GenericArmBehavior.ts b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts index 0f8bee5259..83ba64e892 100644 --- a/fission/src/systems/simulation/behavior/GenericArmBehavior.ts +++ b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts @@ -1,24 +1,36 @@ import HingeDriver from "../driver/HingeDriver"; import HingeStimulus from "../stimulus/HingeStimulus"; import Behavior from "./Behavior"; -import InputSystem from "@/systems/input/InputSystem"; +import InputSystem, { emptyModifierState } from "@/systems/input/InputSystem"; class GenericArmBehavior extends Behavior { private _hingeDriver: HingeDriver; + private _positiveInput: string; + private _negativeInput: string; + private _rotationalSpeed = 30; - constructor(hingeDriver: HingeDriver, hingeStimulus: HingeStimulus) { + constructor(hingeDriver: HingeDriver, hingeStimulus: HingeStimulus, jointIndex: number) { super([hingeDriver], [hingeStimulus]); this._hingeDriver = hingeDriver; + + this._positiveInput = "jointPositive" + jointIndex; + this._negativeInput = "jointNegative" + jointIndex; + + // TODO: load inputs from mira + InputSystem.allInputs[this._positiveInput] = { name: this._positiveInput, keybind: jointIndex.toString(), isGlobal: true, modifiers: emptyModifierState }; + InputSystem.allInputs[this._negativeInput] = { name: this._negativeInput, keybind: jointIndex.toString(), isGlobal: true, + modifiers: { ctrl: false, alt: true, shift: false, meta: false } }; } + // Sets the arms target rotational velocity rotateArm(rotationalVelocity: number) { this._hingeDriver.targetVelocity = rotationalVelocity; } public Update(_: number): void { - this.rotateArm(InputSystem.getAxis("armPositive", "armNegative")*this._rotationalSpeed); + this.rotateArm(InputSystem.getAxis(this._positiveInput, this._negativeInput)*this._rotationalSpeed); } } diff --git a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts index 6ca4af3930..9a0e83d790 100644 --- a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts +++ b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts @@ -1,27 +1,36 @@ import SliderDriver from "../driver/SliderDriver"; import SliderStimulus from "../stimulus/SliderStimulus"; import Behavior from "./Behavior"; -import InputSystem from "@/systems/input/InputSystem"; +import InputSystem, { emptyModifierState } from "@/systems/input/InputSystem"; class GenericElevatorBehavior extends Behavior { private _sliderDriver: SliderDriver; - private _linearSpeed = 1; + private _positiveInput: string; + private _negativeInput: string; - private _inverted: boolean; + private _linearSpeed = 1; - constructor(sliderDriver: SliderDriver, sliderStimulus: SliderStimulus, inverted: boolean) { + constructor(sliderDriver: SliderDriver, sliderStimulus: SliderStimulus, jointIndex: number) { super([sliderDriver], [sliderStimulus]); this._sliderDriver = sliderDriver; - this._inverted = inverted; + + this._positiveInput = "jointPositive" + jointIndex; + this._negativeInput = "jointNegative" + jointIndex; + + // TODO: load inputs from mira + InputSystem.allInputs[this._positiveInput] = { name: this._positiveInput, keybind: jointIndex.toString(), isGlobal: true, modifiers: emptyModifierState }; + InputSystem.allInputs[this._negativeInput] = { name: this._negativeInput, keybind: jointIndex.toString(), isGlobal: true, + modifiers: { ctrl: false, alt: true, shift: false, meta: false } }; } + // Changes the elevators target position moveElevator(positionDelta: number) { - this._sliderDriver.targetPosition += positionDelta * (this._inverted ? -1 : 1); + this._sliderDriver.targetPosition += positionDelta; } public Update(deltaT: number): void { - this.moveElevator(InputSystem.getAxis("elevatorPositive", "elevatorNegative")*this._linearSpeed*deltaT); + this.moveElevator(InputSystem.getAxis(this._positiveInput, this._negativeInput)*this._linearSpeed*deltaT); } } diff --git a/fission/src/systems/simulation/driver/WheelDriver.ts b/fission/src/systems/simulation/driver/WheelDriver.ts index dd115b791f..2de983a2d6 100644 --- a/fission/src/systems/simulation/driver/WheelDriver.ts +++ b/fission/src/systems/simulation/driver/WheelDriver.ts @@ -23,13 +23,6 @@ class WheelDriver extends Driver { this._constraint = constraint; this._wheel = JOLT.castObject(this._constraint.GetWheel(0), JOLT.WheelWV); - - // TODO: I think this was just for testing - // if (constraint.GetVehicleBody().GetCenterOfMassPosition().GetX() < 0) { - // this._targetWheelSpeed = 0; - // } else { - // this._targetWheelSpeed = 0; - // } } public Update(_: number): void { diff --git a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts index d06101d480..f0117b27c3 100644 --- a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts +++ b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts @@ -22,13 +22,16 @@ class SynthesisBrain extends Brain { _leftWheelIndices: number[] = []; + // Tracks how many joins have been made for unique controls + _currentJointIndex = 1; + public constructor(mechanism: Mechanism) { super(mechanism); this._simLayer = World.SimulationSystem.GetSimulationLayer(mechanism)!; if (!this._simLayer) { - console.log("Simulation Layer is undefined"); + console.log("SimulationLayer is undefined"); return; } @@ -47,10 +50,12 @@ class SynthesisBrain extends Brain { this._behaviors = []; } + // Creates an instance of ArcadeDriveBehavior and automatically configures it configureArcadeDriveBehavior() { let wheelDrivers: WheelDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof WheelDriver) as WheelDriver[]; let wheelStimuli: WheelRotationStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof WheelRotationStimulus) as WheelRotationStimulus[]; + // Two body constraints are part of wheels and are used to determine which way a wheel is facing let fixedConstraints: Jolt.TwoBodyConstraint[] = this._mechanism.constraints.filter((mechConstraint) => mechConstraint.constraint instanceof JOLT.TwoBodyConstraint).map((mechConstraint) => mechConstraint.constraint as Jolt.TwoBodyConstraint); let leftWheels: WheelDriver[] = []; @@ -59,6 +64,7 @@ class SynthesisBrain extends Brain { let rightWheels: WheelDriver[] = []; let rightStimuli: WheelRotationStimulus[] = []; + // Determines which wheels and stimuli belong to which side of the robot for (let i = 0; i < wheelDrivers.length; i++) { let wheelPos = fixedConstraints[i].GetConstraintToBody1Matrix().GetTranslation(); @@ -80,21 +86,25 @@ class SynthesisBrain extends Brain { this._behaviors.push(new ArcadeDriveBehavior(leftWheels, rightWheels, leftStimuli, rightStimuli)); } + // Creates instances of ArmBehavior and automatically configures them configureArmBehaviors() { let hingeDrivers: HingeDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof HingeDriver) as HingeDriver[]; let hingeStimuli: HingeStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof HingeStimulus) as HingeStimulus[]; for (let i = 0; i < hingeDrivers.length; i++) { - this._behaviors.push(new GenericArmBehavior(hingeDrivers[i], hingeStimuli[i])); + this._behaviors.push(new GenericArmBehavior(hingeDrivers[i], hingeStimuli[i], this._currentJointIndex)); + this._currentJointIndex++; } } + // Creates instances of ElevatorBehavior and automatically configures them configureElevatorBehaviors() { let sliderDrivers: SliderDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof SliderDriver) as SliderDriver[]; let sliderStimuli: SliderStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof SliderStimulus) as SliderStimulus[]; for (let i = 0; i < sliderDrivers.length; i++) { - this._behaviors.push(new GenericElevatorBehavior(sliderDrivers[i], sliderStimuli[i], i==0 ? false : true)); + this._behaviors.push(new GenericElevatorBehavior(sliderDrivers[i], sliderStimuli[i], this._currentJointIndex)); + this._currentJointIndex++; } } } From 22ee891e7016570db1cbeffd1b916cc9bd2a5f42 Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Wed, 19 Jun 2024 10:57:35 -0700 Subject: [PATCH 07/12] undid accidental changes to old cs files --- engine/Assets/Scripts/Drivers/WheelDriver.cs | 134 +++++++----------- .../Utilities/ColorManager/ColorManager.cs | 99 +++++-------- .../synthesis_brain/SynthesisBrain.ts | 2 +- 3 files changed, 83 insertions(+), 152 deletions(-) diff --git a/engine/Assets/Scripts/Drivers/WheelDriver.cs b/engine/Assets/Scripts/Drivers/WheelDriver.cs index 4390e918ee..a4593561a8 100644 --- a/engine/Assets/Scripts/Drivers/WheelDriver.cs +++ b/engine/Assets/Scripts/Drivers/WheelDriver.cs @@ -7,10 +7,8 @@ #nullable enable -namespace Synthesis -{ - public class WheelDriver : Driver - { +namespace Synthesis { + public class WheelDriver : Driver { private const float MIRABUF_TO_UNITY_FORCE = 40f; private CustomWheel _customWheel; @@ -20,41 +18,33 @@ public class WheelDriver : Driver public JointInstance JointInstance => _jointInstance; private Vector3 _localAnchor = Vector3.zero; - public Vector3 Anchor - { + public Vector3 Anchor { get => _customWheel.Rb.transform.localToWorldMatrix.MultiplyPoint3x4(_localAnchor); - set - { - _localAnchor = _customWheel.Rb.transform.worldToLocalMatrix.MultiplyPoint3x4(value); + set { + _localAnchor = _customWheel.Rb.transform.worldToLocalMatrix.MultiplyPoint3x4(value); _customWheel.LocalAnchor = _localAnchor; } } - public Vector3 LocalAnchor - { + public Vector3 LocalAnchor { get => _localAnchor; - set - { - _localAnchor = value; + set { + _localAnchor = value; _customWheel.LocalAnchor = _localAnchor; } } private Vector3 _localAxis = Vector3.right; - public Vector3 Axis - { + public Vector3 Axis { get => _customWheel.Rb.transform.localToWorldMatrix.MultiplyVector(_localAxis); - set - { - _localAxis = _customWheel.Rb.transform.worldToLocalMatrix.MultiplyVector(value); + set { + _localAxis = _customWheel.Rb.transform.worldToLocalMatrix.MultiplyVector(value); _customWheel.LocalAxis = _localAxis; } } - public Vector3 LocalAxis - { + public Vector3 LocalAxis { get => _localAxis; - set - { - _localAxis = value; + set { + _localAxis = value; _customWheel.LocalAxis = _localAxis; } } @@ -62,39 +52,32 @@ public Vector3 LocalAxis /// /// Specify a roller direction. NULL roller direction indicates no roller /// - public Vector3? LocalRoller - { + public Vector3? LocalRoller { get => _customWheel.LocalRollerRollingDirection; set { _customWheel.LocalRollerRollingDirection = value; } } private float _radius = 0.05f; - public float Radius - { + public float Radius { get => _radius; - set - { - _radius = value; + set { + _radius = value; _customWheel.Radius = _radius; } } - public float ImpulseMax - { + public float ImpulseMax { get => _customWheel.ImpulseMax; set => _customWheel.ImpulseMax = value; } - public enum RotationalControlMode - { + public enum RotationalControlMode { Position, Velocity } - public double MainInput - { - get - { + public double MainInput { + get { if (PhysicsManager.IsFrozen) return 0f; var val = State.GetValue(_inputs[0]); @@ -106,11 +89,9 @@ public double MainInput public bool HasContacts => _customWheel.HasContacts; private JointMotor _motor; - public JointMotor Motor - { + public JointMotor Motor { get => _motor; - set - { + set { _motor = value; SimulationPreferences.SetRobotJointMotor((_simObject as RobotSimObject)!.RobotGUID, MotorRef, _motor); } @@ -141,39 +122,31 @@ public JointMotor Motor public WheelDriver(string name, string[] inputs, string[] outputs, SimObject simObject, JointInstance jointInstance, CustomWheel customWheel, Vector3 anchor, Vector3 axis, float radius, string motorRef, JointInstance.WheelTypeEnum wheelType) - : base(name, inputs, outputs, simObject) - { + : base(name, inputs, outputs, simObject) { _jointInstance = jointInstance; - _customWheel = customWheel; - _wheelType = wheelType; + _customWheel = customWheel; + _wheelType = wheelType; Anchor = _customWheel.Rb.transform.localToWorldMatrix.MultiplyPoint3x4(anchor); - Axis = _customWheel.Rb.transform.localToWorldMatrix.MultiplyVector(axis); + Axis = _customWheel.Rb.transform.localToWorldMatrix.MultiplyVector(axis); MotorRef = motorRef; - if (float.IsNaN(radius)) - { + if (float.IsNaN(radius)) { Radius = _customWheel.Rb.transform.GetBounds().extents.y; - } - else - { + } else { Radius = radius; } var motor = SimulationPreferences.GetRobotJointMotor((simObject as RobotSimObject)!.RobotGUID, motorRef); - if (motor != null) - { + if (motor != null) { _motor = motor.Value; - } - else - { - Motor = new JointMotor() - { + } else { + Motor = new JointMotor() { // Default Motor. Slow but powerful enough. Also uses Motor to save it - force = 1, // About a Neo 550. Max is Falcon 550 at 4.67 - freeSpin = false, + force = 1, // About a Neo 550. Max is Falcon 550 at 4.67 + freeSpin = false, targetVelocity = 30, }; } @@ -184,21 +157,18 @@ public WheelDriver(string name, string[] inputs, string[] outputs, SimObject sim State.SetValue(_outputs[1], Value.ForNumber(1)); } - void EnableMotor() - { + void EnableMotor() { _useMotor = true; } - void DisableMotor() - { + void DisableMotor() { _useMotor = false; } private float _jointAngle = 0.0f; private float _lastUpdate = float.NaN; - public override void Update() - { + public override void Update() { VelocityControl(); _lastUpdate = Time.realtimeSinceStartup; @@ -208,42 +178,34 @@ public override void Update() State.SetValue(_outputs[1], Value.ForNumber(PositiveMod(_jointAngle, Mathf.PI))); } - public float PositiveMod(float val, float mod) - { + public float PositiveMod(float val, float mod) { var res = val % mod; if (res < 0) res += mod; return res; } - public void WheelsPhysicsUpdate(float mod) - { + public void WheelsPhysicsUpdate(float mod) { _customWheel.CalculateAndApplyFriction(mod); } - public void MatchRollerToWheelType() - { - if (_wheelType == JointInstance.WheelTypeEnum.Omni) - { + public void MatchRollerToWheelType() { + if (_wheelType == JointInstance.WheelTypeEnum.Omni) { LocalRoller = LocalAxis; - } - else - { + } else { LocalRoller = null; } } - private void VelocityControl() - { + private void VelocityControl() { if (!_useMotor) return; - var val = (float)MainInput; - var lastRotSpeed = _customWheel.RotationSpeed; + var val = (float) MainInput; + var lastRotSpeed = _customWheel.RotationSpeed; _customWheel.RotationSpeed = val * _motor.targetVelocity; - if (!float.IsNaN(_lastUpdate)) - { + if (!float.IsNaN(_lastUpdate)) { var deltaT = Time.realtimeSinceStartup - _lastUpdate; if (deltaT == 0f) @@ -256,4 +218,4 @@ private void VelocityControl() } } } -} +} \ No newline at end of file diff --git a/engine/Assets/Scripts/Utilities/ColorManager/ColorManager.cs b/engine/Assets/Scripts/Utilities/ColorManager/ColorManager.cs index eadc9eb452..3c0ffe9bf1 100644 --- a/engine/Assets/Scripts/Utilities/ColorManager/ColorManager.cs +++ b/engine/Assets/Scripts/Utilities/ColorManager/ColorManager.cs @@ -9,23 +9,19 @@ using UI.Dynamic.Modals.Configuring.ThemeEditor; using UnityEngine; -namespace Utilities.ColorManager -{ - public static class ColorManager - { +namespace Utilities.ColorManager { + public static class ColorManager { public const string SELECTED_THEME_PREF = "color/selected_theme"; - public const string DEFAULT_THEME = "Default"; + public const string DEFAULT_THEME = "Default"; - public class OnThemeChanged : IEvent { } + public class OnThemeChanged : IEvent {} private static readonly Color UNASSIGNED_COLOR = new(200, 255, 0, 255); private static readonly char altSep = Path.AltDirectorySeparatorChar; - private static string THEMES_FOLDER_PATH - { - get - { + private static string THEMES_FOLDER_PATH { + get { string dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + altSep + "Autodesk" + altSep + "Synthesis" + altSep + "Themes"; @@ -43,11 +39,9 @@ private static string THEMES_FOLDER_PATH public static Dictionary ActiveColors => _tempPreviewColors ?? LoadedColors; private static string _selectedTheme; - public static string SelectedTheme - { + public static string SelectedTheme { get => _selectedTheme; - set - { + set { if (value == _selectedTheme) return; @@ -63,10 +57,8 @@ public static string SelectedTheme } /// A list of themes found in Appdata plus the default theme - public static string[] AvailableThemes - { - get - { + public static string[] AvailableThemes { + get { var themes = Directory.GetFiles(THEMES_FOLDER_PATH).Select(Path.GetFileNameWithoutExtension).ToList(); themes.Insert(0, DEFAULT_THEME); @@ -74,16 +66,13 @@ public static string[] AvailableThemes } } - static ColorManager() - { - EventBus.NewTypeListener(e => - { + static ColorManager() { + EventBus.NewTypeListener(e => { string selectedTheme = PreferenceManager.GetPreference(SELECTED_THEME_PREF); - SelectedTheme = selectedTheme; + SelectedTheme = selectedTheme; }); _selectedTheme = PreferenceManager.GetPreference(SELECTED_THEME_PREF); - if (_selectedTheme is "" or null) - { + if (_selectedTheme is "" or null) { PreferenceManager.SetPreference(SELECTED_THEME_PREF, DEFAULT_THEME); _selectedTheme = DEFAULT_THEME; } @@ -95,35 +84,29 @@ static ColorManager() /// Loads the default theme into the _colors dictionary. Will fill missing colors in a custom /// theme - private static void LoadDefaultColors() - { + private static void LoadDefaultColors() { DefaultColors.SYNTHESIS_DEFAULT.ForEach(c => { _loadedColors.TryAdd(c.name, c.color); }); } /// Loads a theme from the synthesis appdata folder. Will create a theme if it does not exist /// The theme to load - private static void LoadTheme(string themeName) - { + private static void LoadTheme(string themeName) { if (themeName is DEFAULT_THEME or "") return; string themePath = THEMES_FOLDER_PATH + altSep + themeName + ".json"; var dir = Path.GetFullPath(themePath).Replace(Path.GetFileName(themePath), ""); - if (!Directory.Exists(dir)) - { + if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); return; - } - else if (!File.Exists(themePath)) - { + } else if (!File.Exists(themePath)) { return; } var jsonColors = JsonConvert.DeserializeObject>(File.ReadAllText(themePath)); - jsonColors?.ForEach(x => - { + jsonColors?.ForEach(x => { if (Enum.TryParse(x.Key, out var colorName)) _loadedColors.Add(colorName, x.Value.ColorToHex()); }); @@ -131,8 +114,7 @@ private static void LoadTheme(string themeName) /// Loads a theme to the synthesis appdata folder /// The theme to save - private static void SaveTheme(string themeName) - { + private static void SaveTheme(string themeName) { if (themeName is DEFAULT_THEME or "") return; @@ -140,15 +122,14 @@ private static void SaveTheme(string themeName) var jsonColors = new Dictionary(); - _loadedColors.ForEach(x => { jsonColors.Add(x.Key.ToString(), ((Color)x.Value).ToHex()); }); + _loadedColors.ForEach(x => { jsonColors.Add(x.Key.ToString(), ((Color) x.Value).ToHex()); }); File.WriteAllText(themePath, JsonConvert.SerializeObject(jsonColors)); } /// Deletes a theme from the synthesis appdata folder /// The theme to delete - private static void DeleteTheme(string themeName) - { + private static void DeleteTheme(string themeName) { if (themeName is DEFAULT_THEME or "") return; @@ -158,22 +139,19 @@ private static void DeleteTheme(string themeName) } /// Permanently deletes the selected theme unless it is Default - public static void DeleteSelectedTheme() - { + public static void DeleteSelectedTheme() { DeleteTheme(_selectedTheme); SelectedTheme = DEFAULT_THEME; } - public static void DeleteAllThemes() - { + public static void DeleteAllThemes() { AvailableThemes.ForEach(DeleteTheme); SelectedTheme = DEFAULT_THEME; } /// Modifies the colors of the selected theme /// A list of new colors. Does not have to contain every color - public static void ModifySelectedTheme(List<(SynthesisColor name, Color color)> changes) - { + public static void ModifySelectedTheme(List<(SynthesisColor name, Color color)> changes) { SetTempPreviewColors(null); if (_selectedTheme == null) @@ -189,15 +167,11 @@ public static void ModifySelectedTheme(List<(SynthesisColor name, Color color)> /// Returns a color, or UNASSIGNED_COLOR if it is not /// found The name of the color to get The corresponding /// color of the current theme - public static Color GetColor(SynthesisColor colorName) - { - if (_tempPreviewColors != null) - { + public static Color GetColor(SynthesisColor colorName) { + if (_tempPreviewColors != null) { if (_tempPreviewColors.TryGetValue(colorName, out Color color)) return color; - } - else - { + } else { if (_loadedColors.TryGetValue(colorName, out Color color)) return color; } @@ -208,8 +182,7 @@ public static Color GetColor(SynthesisColor colorName) /// Temporarily preview colors without saving them. Call with null to switch back to loaded /// colors The colors to preview. If null, color manager will switch back to /// loaded colors - public static void SetTempPreviewColors(Dictionary colors) - { + public static void SetTempPreviewColors(Dictionary colors) { _tempPreviewColors = colors; EventBus.Push(new OnThemeChanged()); } @@ -217,11 +190,9 @@ public static void SetTempPreviewColors(Dictionary colors /// Finds the index of a theme /// A theme name /// The index of the given theme - public static int ThemeNameToIndex(string themeName) - { + public static int ThemeNameToIndex(string themeName) { int i = 0; - foreach (string theme in AvailableThemes) - { + foreach (string theme in AvailableThemes) { if (theme.Equals(themeName)) return i; i++; @@ -233,8 +204,7 @@ public static int ThemeNameToIndex(string themeName) /// The theme name at that index, or default if it does not exist /// A theme index /// The name of the given theme - public static string ThemeIndexToName(int index) - { + public static string ThemeIndexToName(int index) { if (index >= AvailableThemes.Length || index == -1) return DEFAULT_THEME; else @@ -242,8 +212,7 @@ public static string ThemeIndexToName(int index) } /// Each value represents a different color that can differ across themes - public enum SynthesisColor - { + public enum SynthesisColor { InteractiveElementSolid, InteractiveElementLeft, InteractiveElementRight, @@ -269,4 +238,4 @@ public enum SynthesisColor AcceptCancelButtonText } } -} +} \ No newline at end of file diff --git a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts index f0117b27c3..54a32234f6 100644 --- a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts +++ b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts @@ -109,4 +109,4 @@ class SynthesisBrain extends Brain { } } -export default SynthesisBrain;32 \ No newline at end of file +export default SynthesisBrain; \ No newline at end of file From c7ea0b960ba60fe92d3b73c4b0877139e951bd0e Mon Sep 17 00:00:00 2001 From: Hunter Barclay Date: Wed, 19 Jun 2024 13:00:46 -0700 Subject: [PATCH 08/12] Fixing style and format issues --- fission/src/aps/APS.ts | 3 +- fission/src/systems/input/InputSystem.ts | 30 ++++++------- .../behavior/ArcadeDriveBehavior.ts | 10 ++--- .../simulation/behavior/GenericArmBehavior.ts | 2 +- .../behavior/GenericElevatorBehavior.ts | 2 +- .../simulation/stimulus/WheelStimulus.ts | 2 +- .../synthesis_brain/SynthesisBrain.ts | 42 +++++++++---------- fission/src/ui/components/MainHUD.tsx | 6 +-- fission/src/ui/components/Tooltip.tsx | 2 +- .../modals/configuring/ChangeInputsModal.tsx | 4 +- 10 files changed, 49 insertions(+), 54 deletions(-) diff --git a/fission/src/aps/APS.ts b/fission/src/aps/APS.ts index 233fc2099a..0711a8ad66 100644 --- a/fission/src/aps/APS.ts +++ b/fission/src/aps/APS.ts @@ -1,4 +1,3 @@ -import { MainHUD_AddToast } from "@/components/MainHUD" import { Random } from "@/util/Random" const APS_AUTH_KEY = 'aps_auth' @@ -125,7 +124,7 @@ class APS { if (this.auth) { this.loadUserInfo(this.auth!).then(async () => { if (APS.userInfo) { - MainHUD_AddToast('info', 'ADSK Login', `Hello, ${APS.userInfo.givenName}`) + console.log(`Hello, ${APS.userInfo.givenName}`) } }) } diff --git a/fission/src/systems/input/InputSystem.ts b/fission/src/systems/input/InputSystem.ts index 3a85f99669..56471db87b 100644 --- a/fission/src/systems/input/InputSystem.ts +++ b/fission/src/systems/input/InputSystem.ts @@ -54,16 +54,16 @@ class InputSystem extends WorldSystem { constructor() { super(); - this.handleKeyDown = this.handleKeyDown.bind(this); - document.addEventListener('keydown', this.handleKeyDown); + this.HandleKeyDown = this.HandleKeyDown.bind(this); + document.addEventListener('keydown', this.HandleKeyDown); - this.handleKeyUp = this.handleKeyUp.bind(this); - document.addEventListener('keyup', this.handleKeyUp); + this.HandleKeyUp = this.HandleKeyUp.bind(this); + document.addEventListener('keyup', this.HandleKeyUp); // TODO: Load saved inputs from mira (robot specific) & global inputs - for (let key in defaultInputs) { - if (defaultInputs.hasOwnProperty(key)) { + for (const key in defaultInputs) { + if (Object.prototype.hasOwnProperty.call(defaultInputs, key)) { InputSystem.allInputs[key] = defaultInputs[key]; } } @@ -74,17 +74,17 @@ class InputSystem extends WorldSystem { } public Destroy(): void { - document.removeEventListener('keydown', this.handleKeyDown); - document.removeEventListener('keyup', this.handleKeyUp); + document.removeEventListener('keydown', this.HandleKeyDown); + document.removeEventListener('keyup', this.HandleKeyUp); } // Called when any key is pressed - handleKeyDown(event: KeyboardEvent) { + private HandleKeyDown(event: KeyboardEvent) { InputSystem._keysPressed[event.key] = true; } // Called when any key is released - handleKeyUp(event: KeyboardEvent) { + private HandleKeyUp(event: KeyboardEvent) { InputSystem._keysPressed[event.key] = false; } @@ -97,10 +97,10 @@ class InputSystem extends WorldSystem { public static getInput(inputName: string) : boolean { // Checks if there is an input assigned to this action if (inputName in this.allInputs) { - let targetInput = this.allInputs[inputName]; + const targetInput = this.allInputs[inputName]; // Check for input modifiers - if (!this.compareModifiers(InputSystem._currentModifierState, targetInput.modifiers)) + if (!this.CompareModifiers(InputSystem._currentModifierState, targetInput.modifiers)) return false; return this.isKeyPressed(targetInput.keybind); @@ -111,19 +111,19 @@ class InputSystem extends WorldSystem { } // Combines two inputs into a positive/negative axis - public static getAxis(positive: string, negative: string) { + public static GetAxis(positive: string, negative: string) { return (this.getInput(positive) ? 1 : 0) - (this.getInput(negative) ? 1 : 0); } // Converts camelCase to Title Case for the inputs modal - public static toTitleCase(camelCase: string) : string { + public static ToTitleCase(camelCase: string) : string { const result = camelCase.replace(/([A-Z])/g, " $1"); const finalResult = result.charAt(0).toUpperCase() + result.slice(1); return finalResult; } // Returns true if two modifier states are identical - private static compareModifiers(state1: ModifierState, state2: ModifierState) : boolean { + private static CompareModifiers(state1: ModifierState, state2: ModifierState) : boolean { return state1.alt == state2.alt && state1.ctrl == state2.ctrl && state1.meta == state2.meta && state1.shift == state2.shift; } } diff --git a/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts b/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts index 67f4b8f679..4d5ed5497c 100644 --- a/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts +++ b/fission/src/systems/simulation/behavior/ArcadeDriveBehavior.ts @@ -18,17 +18,17 @@ class ArcadeDriveBehavior extends Behavior { } // Sets the drivetrains target linear and rotational velocity - driveSpeeds(linearVelocity: number, rotationVelocity: number) { - let leftSpeed = linearVelocity + rotationVelocity; - let rightSpeed = linearVelocity - rotationVelocity; + private DriveSpeeds(linearVelocity: number, rotationVelocity: number) { + const leftSpeed = linearVelocity + rotationVelocity; + const rightSpeed = linearVelocity - rotationVelocity; this.leftWheels.forEach((wheel) => wheel.targetWheelSpeed = leftSpeed); this.rightWheels.forEach((wheel) => wheel.targetWheelSpeed = rightSpeed); } public Update(_: number): void { - this.driveSpeeds(InputSystem.getAxis("arcadeForward", "arcadeBackward")*this._driveSpeed, - InputSystem.getAxis("arcadeRight", "arcadeLeft")*this._turnSpeed); + this.DriveSpeeds(InputSystem.GetAxis("arcadeForward", "arcadeBackward")*this._driveSpeed, + InputSystem.GetAxis("arcadeRight", "arcadeLeft")*this._turnSpeed); } } diff --git a/fission/src/systems/simulation/behavior/GenericArmBehavior.ts b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts index 83ba64e892..eeac693216 100644 --- a/fission/src/systems/simulation/behavior/GenericArmBehavior.ts +++ b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts @@ -30,7 +30,7 @@ class GenericArmBehavior extends Behavior { } public Update(_: number): void { - this.rotateArm(InputSystem.getAxis(this._positiveInput, this._negativeInput)*this._rotationalSpeed); + this.rotateArm(InputSystem.GetAxis(this._positiveInput, this._negativeInput)*this._rotationalSpeed); } } diff --git a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts index 9a0e83d790..d76ebb6cac 100644 --- a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts +++ b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts @@ -30,7 +30,7 @@ class GenericElevatorBehavior extends Behavior { } public Update(deltaT: number): void { - this.moveElevator(InputSystem.getAxis(this._positiveInput, this._negativeInput)*this._linearSpeed*deltaT); + this.moveElevator(InputSystem.GetAxis(this._positiveInput, this._negativeInput)*this._linearSpeed*deltaT); } } diff --git a/fission/src/systems/simulation/stimulus/WheelStimulus.ts b/fission/src/systems/simulation/stimulus/WheelStimulus.ts index ca7e66e658..260e1386c0 100644 --- a/fission/src/systems/simulation/stimulus/WheelStimulus.ts +++ b/fission/src/systems/simulation/stimulus/WheelStimulus.ts @@ -34,7 +34,7 @@ class WheelRotationStimulus extends EncoderStimulus { this._wheel = wheel; } - public Update(deltaT: number): void { + public Update(_: number): void { if (this._accum) { this._wheelRotationAccum += 0; } diff --git a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts index 54a32234f6..7c815b7eb5 100644 --- a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts +++ b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts @@ -35,9 +35,9 @@ class SynthesisBrain extends Brain { return; } - this.configureArcadeDriveBehavior(); - this.configureArmBehaviors(); - this.configureElevatorBehaviors(); + this.ConfigureArcadeDriveBehavior(); + this.ConfigureArmBehaviors(); + this.ConfigureElevatorBehaviors(); } public Enable(): void { } @@ -51,27 +51,27 @@ class SynthesisBrain extends Brain { } // Creates an instance of ArcadeDriveBehavior and automatically configures it - configureArcadeDriveBehavior() { - let wheelDrivers: WheelDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof WheelDriver) as WheelDriver[]; - let wheelStimuli: WheelRotationStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof WheelRotationStimulus) as WheelRotationStimulus[]; + public ConfigureArcadeDriveBehavior() { + const wheelDrivers: WheelDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof WheelDriver) as WheelDriver[]; + const wheelStimuli: WheelRotationStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof WheelRotationStimulus) as WheelRotationStimulus[]; // Two body constraints are part of wheels and are used to determine which way a wheel is facing - let fixedConstraints: Jolt.TwoBodyConstraint[] = this._mechanism.constraints.filter((mechConstraint) => mechConstraint.constraint instanceof JOLT.TwoBodyConstraint).map((mechConstraint) => mechConstraint.constraint as Jolt.TwoBodyConstraint); + const fixedConstraints: Jolt.TwoBodyConstraint[] = this._mechanism.constraints.filter((mechConstraint) => mechConstraint.constraint instanceof JOLT.TwoBodyConstraint).map((mechConstraint) => mechConstraint.constraint as Jolt.TwoBodyConstraint); - let leftWheels: WheelDriver[] = []; - let leftStimuli: WheelRotationStimulus[] = []; + const leftWheels: WheelDriver[] = []; + const leftStimuli: WheelRotationStimulus[] = []; - let rightWheels: WheelDriver[] = []; - let rightStimuli: WheelRotationStimulus[] = []; + const rightWheels: WheelDriver[] = []; + const rightStimuli: WheelRotationStimulus[] = []; // Determines which wheels and stimuli belong to which side of the robot for (let i = 0; i < wheelDrivers.length; i++) { - let wheelPos = fixedConstraints[i].GetConstraintToBody1Matrix().GetTranslation(); + const wheelPos = fixedConstraints[i].GetConstraintToBody1Matrix().GetTranslation(); - let robotCOM = World.PhysicsSystem.GetBody(this._mechanism.constraints[0].childBody).GetCenterOfMassPosition() as Jolt.Vec3; - let rightVector = new JOLT.Vec3(1, 0, 0); + const robotCOM = World.PhysicsSystem.GetBody(this._mechanism.constraints[0].childBody).GetCenterOfMassPosition() as Jolt.Vec3; + const rightVector = new JOLT.Vec3(1, 0, 0); - let dotProduct = rightVector.Dot(wheelPos.Sub(robotCOM)) + const dotProduct = rightVector.Dot(wheelPos.Sub(robotCOM)) if (dotProduct < 0) { rightWheels.push(wheelDrivers[i]); @@ -87,9 +87,9 @@ class SynthesisBrain extends Brain { } // Creates instances of ArmBehavior and automatically configures them - configureArmBehaviors() { - let hingeDrivers: HingeDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof HingeDriver) as HingeDriver[]; - let hingeStimuli: HingeStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof HingeStimulus) as HingeStimulus[]; + public ConfigureArmBehaviors() { + const hingeDrivers: HingeDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof HingeDriver) as HingeDriver[]; + const hingeStimuli: HingeStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof HingeStimulus) as HingeStimulus[]; for (let i = 0; i < hingeDrivers.length; i++) { this._behaviors.push(new GenericArmBehavior(hingeDrivers[i], hingeStimuli[i], this._currentJointIndex)); @@ -98,9 +98,9 @@ class SynthesisBrain extends Brain { } // Creates instances of ElevatorBehavior and automatically configures them - configureElevatorBehaviors() { - let sliderDrivers: SliderDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof SliderDriver) as SliderDriver[]; - let sliderStimuli: SliderStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof SliderStimulus) as SliderStimulus[]; + public ConfigureElevatorBehaviors() { + const sliderDrivers: SliderDriver[] = this._simLayer.drivers.filter((driver) => driver instanceof SliderDriver) as SliderDriver[]; + const sliderStimuli: SliderStimulus[] = this._simLayer.stimuli.filter((stimulus) => stimulus instanceof SliderStimulus) as SliderStimulus[]; for (let i = 0; i < sliderDrivers.length; i++) { this._behaviors.push(new GenericElevatorBehavior(sliderDrivers[i], sliderStimuli[i], this._currentJointIndex)); diff --git a/fission/src/ui/components/MainHUD.tsx b/fission/src/ui/components/MainHUD.tsx index baacd7dc84..722c6ba896 100644 --- a/fission/src/ui/components/MainHUD.tsx +++ b/fission/src/ui/components/MainHUD.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from "react" import { BsCodeSquare } from "react-icons/bs" -import { FaCar, FaGear, FaHouse, FaMagnifyingGlass, FaPlus } from "react-icons/fa6" +import { FaCar, FaGear, FaMagnifyingGlass, FaPlus } from "react-icons/fa6" import { BiMenuAltLeft } from "react-icons/bi" import { GrFormClose } from "react-icons/gr" import { GiSteeringWheel } from "react-icons/gi" @@ -55,8 +55,6 @@ const MainHUDButton: React.FC = ({ ) } -export let MainHUD_AddToast: (type: ToastType, title: string, description: string) => void = (a, b, c) => { } - const variants = { open: { opacity: 1, y: "-50%", x: 0 }, closed: { opacity: 0, y: "-50%", x: "-100%" }, @@ -71,8 +69,6 @@ const MainHUD: React.FC = () => { const { addToast } = useToastContext() const [isOpen, setIsOpen] = useState(false) - MainHUD_AddToast = addToast - const [userInfo, setUserInfo] = useState(APS.userInfo); useEffect(() => { diff --git a/fission/src/ui/components/Tooltip.tsx b/fission/src/ui/components/Tooltip.tsx index fa3146a585..28ec78277b 100644 --- a/fission/src/ui/components/Tooltip.tsx +++ b/fission/src/ui/components/Tooltip.tsx @@ -1,4 +1,4 @@ -import { TooltipControl, TooltipType } from "@/TooltipContext" +import { TooltipControl, TooltipType } from "@/ui/TooltipContext" import { FaInfoCircle } from "react-icons/fa" import Label, { LabelSize } from "./Label" import Stack, { StackDirection } from "./Stack" diff --git a/fission/src/ui/modals/configuring/ChangeInputsModal.tsx b/fission/src/ui/modals/configuring/ChangeInputsModal.tsx index c54ccec348..2a801a3e1c 100644 --- a/fission/src/ui/modals/configuring/ChangeInputsModal.tsx +++ b/fission/src/ui/modals/configuring/ChangeInputsModal.tsx @@ -58,7 +58,7 @@ const ChangeInputsModal: React.FC = ({ modalId }) => { {Object.values(InputSystem.robotInputs).map(c => ( = ({ modalId }) => { {Object.values(InputSystem.globalInputs).map(c => ( Date: Thu, 20 Jun 2024 11:08:41 -0700 Subject: [PATCH 09/12] Fixed joint inputs being global and modifier keys changing button bindings (ex: shift+1 -> shift+!) --- fission/src/systems/input/InputSystem.ts | 33 ++++++------- .../simulation/behavior/GenericArmBehavior.ts | 10 ++-- .../behavior/GenericElevatorBehavior.ts | 12 ++--- .../modals/configuring/ChangeInputsModal.tsx | 46 +++++++++++++++++-- 4 files changed, 65 insertions(+), 36 deletions(-) diff --git a/fission/src/systems/input/InputSystem.ts b/fission/src/systems/input/InputSystem.ts index 56471db87b..d64bb19d85 100644 --- a/fission/src/systems/input/InputSystem.ts +++ b/fission/src/systems/input/InputSystem.ts @@ -10,7 +10,7 @@ declare global { type Input = { name: string - keybind: string + keyCode: string isGlobal: boolean modifiers: ModifierState } @@ -20,14 +20,14 @@ export const emptyModifierState: ModifierState = { ctrl: false, alt: false, shif // When a robot is loaded, default inputs replace any unassigned inputs const defaultInputs: { [key: string]: Input } = { - "intake": { name: "intake", keybind: "e", isGlobal: true, modifiers: emptyModifierState }, - "shootGamepiece": { name: "shootGamepiece", keybind: "q", isGlobal: true, modifiers: emptyModifierState }, - "enableGodMode": { name: "enableGodMode", keybind: "g", isGlobal: true, modifiers: emptyModifierState }, - - "arcadeForward": { name: "arcadeForward", keybind: "w", isGlobal: false, modifiers: emptyModifierState }, - "arcadeBackward": { name: "arcadeBackward", keybind: "s", isGlobal: false, modifiers: emptyModifierState }, - "arcadeLeft": { name: "arcadeLeft", keybind: "a", isGlobal: false, modifiers: emptyModifierState }, - "arcadeRight": { name: "arcadeRight", keybind: "d", isGlobal: false, modifiers: emptyModifierState }, + "intake": { name: "intake", keyCode: "KeyE", isGlobal: true, modifiers: emptyModifierState }, + "shootGamepiece": { name: "shootGamepiece", keyCode: "KeyQ", isGlobal: true, modifiers: emptyModifierState }, + "enableGodMode": { name: "enableGodMode", keyCode: "KeyG", isGlobal: true, modifiers: emptyModifierState }, + + "arcadeForward": { name: "arcadeForward", keyCode: "KeyW", isGlobal: false, modifiers: emptyModifierState }, + "arcadeBackward": { name: "arcadeBackward", keyCode: "KeyS", isGlobal: false, modifiers: emptyModifierState }, + "arcadeLeft": { name: "arcadeLeft", keyCode: "KeyA", isGlobal: false, modifiers: emptyModifierState }, + "arcadeRight": { name: "arcadeRight", keyCode: "KeyD", isGlobal: false, modifiers: emptyModifierState }, } class InputSystem extends WorldSystem { @@ -70,7 +70,7 @@ class InputSystem extends WorldSystem { } public Update(_: number): void {InputSystem - InputSystem._currentModifierState = { ctrl: InputSystem.isKeyPressed("Control"), alt: InputSystem.isKeyPressed("Alt"), shift: InputSystem.isKeyPressed("Shift"), meta: InputSystem.isKeyPressed("Meta") } + InputSystem._currentModifierState = { ctrl: InputSystem.isKeyPressed("ControlLeft") || InputSystem.isKeyPressed("ControlRight"), alt: InputSystem.isKeyPressed("AltLeft") || InputSystem.isKeyPressed("AltRight"), shift: InputSystem.isKeyPressed("ShiftLeft") || InputSystem.isKeyPressed("ShiftRight"), meta: InputSystem.isKeyPressed("MetaLeft") || InputSystem.isKeyPressed("MetaRight") } } public Destroy(): void { @@ -80,12 +80,12 @@ class InputSystem extends WorldSystem { // Called when any key is pressed private HandleKeyDown(event: KeyboardEvent) { - InputSystem._keysPressed[event.key] = true; + InputSystem._keysPressed[event.code] = true; } // Called when any key is released private HandleKeyUp(event: KeyboardEvent) { - InputSystem._keysPressed[event.key] = false; + InputSystem._keysPressed[event.code] = false; } // Returns true if the given key is currently down @@ -103,7 +103,7 @@ class InputSystem extends WorldSystem { if (!this.CompareModifiers(InputSystem._currentModifierState, targetInput.modifiers)) return false; - return this.isKeyPressed(targetInput.keybind); + return this.isKeyPressed(targetInput.keyCode); } // If the input does not exist, returns false @@ -115,13 +115,6 @@ class InputSystem extends WorldSystem { return (this.getInput(positive) ? 1 : 0) - (this.getInput(negative) ? 1 : 0); } - // Converts camelCase to Title Case for the inputs modal - public static ToTitleCase(camelCase: string) : string { - const result = camelCase.replace(/([A-Z])/g, " $1"); - const finalResult = result.charAt(0).toUpperCase() + result.slice(1); - return finalResult; - } - // Returns true if two modifier states are identical private static CompareModifiers(state1: ModifierState, state2: ModifierState) : boolean { return state1.alt == state2.alt && state1.ctrl == state2.ctrl && state1.meta == state2.meta && state1.shift == state2.shift; diff --git a/fission/src/systems/simulation/behavior/GenericArmBehavior.ts b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts index eeac693216..6e5a0b7c0c 100644 --- a/fission/src/systems/simulation/behavior/GenericArmBehavior.ts +++ b/fission/src/systems/simulation/behavior/GenericArmBehavior.ts @@ -15,13 +15,13 @@ class GenericArmBehavior extends Behavior { super([hingeDriver], [hingeStimulus]); this._hingeDriver = hingeDriver; - this._positiveInput = "jointPositive" + jointIndex; - this._negativeInput = "jointNegative" + jointIndex; + this._positiveInput = "joint " + jointIndex + " Positive"; + this._negativeInput = "joint " + jointIndex + " Negative"; // TODO: load inputs from mira - InputSystem.allInputs[this._positiveInput] = { name: this._positiveInput, keybind: jointIndex.toString(), isGlobal: true, modifiers: emptyModifierState }; - InputSystem.allInputs[this._negativeInput] = { name: this._negativeInput, keybind: jointIndex.toString(), isGlobal: true, - modifiers: { ctrl: false, alt: true, shift: false, meta: false } }; + InputSystem.allInputs[this._positiveInput] = { name: this._positiveInput, keyCode: "Digit" + jointIndex.toString(), isGlobal: false, modifiers: emptyModifierState }; + InputSystem.allInputs[this._negativeInput] = { name: this._negativeInput, keyCode: "Digit" + jointIndex.toString(), isGlobal: false, + modifiers: { ctrl: false, alt: false, shift: true, meta: false } }; } // Sets the arms target rotational velocity diff --git a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts index d76ebb6cac..1190cff16a 100644 --- a/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts +++ b/fission/src/systems/simulation/behavior/GenericElevatorBehavior.ts @@ -15,18 +15,18 @@ class GenericElevatorBehavior extends Behavior { super([sliderDriver], [sliderStimulus]); this._sliderDriver = sliderDriver; - this._positiveInput = "jointPositive" + jointIndex; - this._negativeInput = "jointNegative" + jointIndex; + this._positiveInput = "joint " + jointIndex + " Positive"; + this._negativeInput = "joint " + jointIndex + " Negative"; // TODO: load inputs from mira - InputSystem.allInputs[this._positiveInput] = { name: this._positiveInput, keybind: jointIndex.toString(), isGlobal: true, modifiers: emptyModifierState }; - InputSystem.allInputs[this._negativeInput] = { name: this._negativeInput, keybind: jointIndex.toString(), isGlobal: true, - modifiers: { ctrl: false, alt: true, shift: false, meta: false } }; + InputSystem.allInputs[this._positiveInput] = { name: this._positiveInput, keyCode: "Digit" + jointIndex.toString(), isGlobal: false, modifiers: emptyModifierState }; + InputSystem.allInputs[this._negativeInput] = { name: this._negativeInput, keyCode: "Digit" + jointIndex.toString(), isGlobal: false, + modifiers: { ctrl: false, alt: false, shift: true, meta: false } }; } // Changes the elevators target position moveElevator(positionDelta: number) { - this._sliderDriver.targetPosition += positionDelta; + this._sliderDriver.targetPosition += positionDelta; } public Update(deltaT: number): void { diff --git a/fission/src/ui/modals/configuring/ChangeInputsModal.tsx b/fission/src/ui/modals/configuring/ChangeInputsModal.tsx index 2a801a3e1c..55c0a42475 100644 --- a/fission/src/ui/modals/configuring/ChangeInputsModal.tsx +++ b/fission/src/ui/modals/configuring/ChangeInputsModal.tsx @@ -15,7 +15,43 @@ const transformKeyName = (control: Input) => { if (control.modifiers.ctrl) prefix += "Ctrl + " if (control.modifiers.alt) prefix += "Alt + " } - return prefix + control.keybind[0].toUpperCase() + control.keybind.substring(1) + + return prefix + keyCodeToCharacter(control.keyCode); +} + +// Converts camelCase to Title Case for the inputs modal +const toTitleCase = (camelCase: string) => { +const result = camelCase.replace(/([A-Z])/g, " $1"); +const finalResult = result.charAt(0).toUpperCase() + result.slice(1); + return finalResult; +} + +const codeToCharacterMap: { [code: string]: string } = { + "Slash": "/", + "Comma": ",", + "Period": ".", + "BracketLeft": "{", + "BracketRight": "}", + "BackQuote": "`", + "Minus": "-", + "Equal": "=", + "Backslash": "\\", //TODO + "Semicolon": ";", + "Quote": "\"" +}; + +// Converts a key code to displayable character (ex: KeyA -> "A") +const keyCodeToCharacter = (code: string) => { + if (code.startsWith("Key")) + return code.charAt(3); + + if (code.startsWith("Digit")) + return code.charAt(5); + + if (code in codeToCharacterMap) + return codeToCharacterMap[code]; + + return code; } const ChangeInputsModal: React.FC = ({ modalId }) => { @@ -30,7 +66,7 @@ const ChangeInputsModal: React.FC = ({ modalId }) => { if (selectedInput && chosenKey) { const selected = InputSystem.allInputs[selectedInput] - selected.keybind = chosenKey + selected.keyCode = chosenKey selected.modifiers = modifierState setChosenKey("") setSelectedInput("") @@ -43,7 +79,7 @@ const ChangeInputsModal: React.FC = ({ modalId }) => {
{ - setChosenKey(selectedInput ? e.key : "") + setChosenKey(selectedInput ? e.code : "") setModifierState({ ctrl: e.ctrlKey, alt: e.altKey, @@ -58,7 +94,7 @@ const ChangeInputsModal: React.FC = ({ modalId }) => { {Object.values(InputSystem.robotInputs).map(c => ( = ({ modalId }) => { {Object.values(InputSystem.globalInputs).map(c => ( Date: Fri, 21 Jun 2024 14:43:09 -0700 Subject: [PATCH 10/12] Fixed issue with key modifiers staying when the document loses focus --- fission/src/systems/input/InputSystem.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fission/src/systems/input/InputSystem.ts b/fission/src/systems/input/InputSystem.ts index d64bb19d85..07e3e02338 100644 --- a/fission/src/systems/input/InputSystem.ts +++ b/fission/src/systems/input/InputSystem.ts @@ -69,7 +69,13 @@ class InputSystem extends WorldSystem { } } - public Update(_: number): void {InputSystem + public Update(_: number): void { + if (!document.hasFocus()) { + for (var keyCode in InputSystem._keysPressed) + delete InputSystem._keysPressed[keyCode]; + return; + } + InputSystem._currentModifierState = { ctrl: InputSystem.isKeyPressed("ControlLeft") || InputSystem.isKeyPressed("ControlRight"), alt: InputSystem.isKeyPressed("AltLeft") || InputSystem.isKeyPressed("AltRight"), shift: InputSystem.isKeyPressed("ShiftLeft") || InputSystem.isKeyPressed("ShiftRight"), meta: InputSystem.isKeyPressed("MetaLeft") || InputSystem.isKeyPressed("MetaRight") } } From 5eb0d632a70459b91038b6973521c733d58c3cd2 Mon Sep 17 00:00:00 2001 From: LucaHaverty Date: Mon, 24 Jun 2024 09:08:57 -0700 Subject: [PATCH 11/12] Added wheel rotation accum back --- fission/src/systems/simulation/stimulus/WheelStimulus.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fission/src/systems/simulation/stimulus/WheelStimulus.ts b/fission/src/systems/simulation/stimulus/WheelStimulus.ts index ae7d22ca0d..29ccbf4cc8 100644 --- a/fission/src/systems/simulation/stimulus/WheelStimulus.ts +++ b/fission/src/systems/simulation/stimulus/WheelStimulus.ts @@ -34,9 +34,9 @@ class WheelRotationStimulus extends EncoderStimulus { this._wheel = wheel } - public Update(_: number): void { + public Update(deltaT: number): void { if (this._accum) { - this._wheelRotationAccum += 0; + this._wheelRotationAccum += this._wheelRotationAccum += this._wheel.GetAngularVelocity() * deltaT; } } From e541fab9ff3a4dfd5cd818e554ccb2b16330102d Mon Sep 17 00:00:00 2001 From: Hunter Barclay Date: Mon, 24 Jun 2024 10:44:17 -0600 Subject: [PATCH 12/12] Removed extra field in addition of wheel angle accum --- fission/src/systems/simulation/stimulus/WheelStimulus.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fission/src/systems/simulation/stimulus/WheelStimulus.ts b/fission/src/systems/simulation/stimulus/WheelStimulus.ts index 29ccbf4cc8..27426933bd 100644 --- a/fission/src/systems/simulation/stimulus/WheelStimulus.ts +++ b/fission/src/systems/simulation/stimulus/WheelStimulus.ts @@ -36,7 +36,7 @@ class WheelRotationStimulus extends EncoderStimulus { public Update(deltaT: number): void { if (this._accum) { - this._wheelRotationAccum += this._wheelRotationAccum += this._wheel.GetAngularVelocity() * deltaT; + this._wheelRotationAccum += this._wheel.GetAngularVelocity() * deltaT; } }