From 5322c78dae7e2ef18cc3931a14708f1dfb8f1a8a Mon Sep 17 00:00:00 2001 From: Crzyrndm Date: Sat, 14 Mar 2015 12:29:29 +1300 Subject: [PATCH] Fixed torque recovery bug, added window --- GameData/RW Saturatable/SaturatableRW.dll | Bin 10752 -> 14336 bytes SaturatableRW/RWSaturatable.cs | 109 ++++++++++++++-------- SaturatableRW/SaturatableRW.csproj | 1 + SaturatableRW/Window.cs | 90 ++++++++++++++++++ 4 files changed, 160 insertions(+), 40 deletions(-) create mode 100644 SaturatableRW/Window.cs diff --git a/GameData/RW Saturatable/SaturatableRW.dll b/GameData/RW Saturatable/SaturatableRW.dll index f493843698511321ffc168846988cb4f352b1ef9..2d089b5a1c9670b87cf029080deaa73722ddf985 100644 GIT binary patch literal 14336 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 BCb$3q diff --git a/SaturatableRW/RWSaturatable.cs b/SaturatableRW/RWSaturatable.cs index e087fe2..2d1ef10 100644 --- a/SaturatableRW/RWSaturatable.cs +++ b/SaturatableRW/RWSaturatable.cs @@ -8,16 +8,16 @@ namespace SaturatableRW { public class RWSaturatable : ModuleReactionWheel { - /////////////////////////////////////////////////////////////////////////////// - /* This is not and is never intended to be a realistic representation of how reaction wheels work. That woud involve simulating + /*////////////////////////////////////////////////////////////////////////////// + * This is not and is never intended to be a realistic representation of how reaction wheels work. That woud involve simulating * effects such as gyroscopic stabilisation and precession that are not dependent only on the internal state of the part and current * command inputs, but the rate of rotation of the vessel and would require applying forces without using the input system * - * Instead, a reaction wheel is simulated as an arbitrary object in a fixed position and orientation in space. Momentum is + * Instead, a reaction wheel is simulated as an arbitrary object in a fixed orientation in space. Momentum is * attributed to and decayed from these objects based on vessel alignment with their arbitrary axes. This system allows for * a reasonable approximation of RW effects on control input but there are very noticeable inconsistencies with a realistic - * system. Most of these are design choices or bugs. - */////////////////////////////////////////////////////////////////////////////// + * system. + /*/////////////////////////////////////////////////////////////////////////////// /// /// Storable axis momentum = average axis torque * saturationScale @@ -46,7 +46,7 @@ public class RWSaturatable : ModuleReactionWheel /// /// Maximum momentum storable on an axis /// - float saturationLimit; + public float saturationLimit; /// /// Average torque over each axis (quick hack to make calculating the limit easy) @@ -54,27 +54,27 @@ public class RWSaturatable : ModuleReactionWheel float averageTorque; // Storing module torque for reference since this module overrides the base values to take effect - float maxRollTorque; - float maxPitchTorque; - float maxYawTorque; + public float maxRollTorque; + public float maxPitchTorque; + public float maxYawTorque; /// /// torque available on the roll axis at current saturation /// [KSPField(guiActive = true, guiFormat = "F1")] - float availableRollTorque; + public float availableRollTorque; /// /// torque available on the pitch axis at current saturation /// [KSPField(guiActive = true, guiFormat = "F1")] - float availablePitchTorque; + public float availablePitchTorque; /// /// torque available on the yaw axis at current saturation /// [KSPField(guiActive = true, guiFormat = "F1")] - float availableYawTorque; + public float availableYawTorque; /// /// Torque available dependent on % saturation @@ -88,14 +88,22 @@ public class RWSaturatable : ModuleReactionWheel [KSPField] public FloatCurve bleedRate; - static KSP.IO.PluginConfiguration config; + public bool drawWheel = false; + + public static KSP.IO.PluginConfiguration config; + + [KSPEvent(guiActive = true, active = true, guiName = "Toggle Window")] + public void ToggleWindow() + { + Window.Instance.showWindow = !Window.Instance.showWindow; + } public override void OnAwake() { base.OnAwake(); // I need a better way to make this module work at any time this.part.force_activate(); - + // Float curve initialisation if (torqueCurve == null) torqueCurve = new FloatCurve(); @@ -103,6 +111,11 @@ public override void OnAwake() bleedRate = new FloatCurve(); } + public void OnDestroy() + { + Window.Instance.wheelsToDraw.Remove(this); + } + public override void OnStart(StartState state) { base.OnStart(state); @@ -125,17 +138,33 @@ public override void OnStart(StartState state) //////////////////////////////////////////////////////////////////////////// /// logging worker ///////////////////////////////////////////////////////// - if (config == null) - config = KSP.IO.PluginConfiguration.CreateForType(); - config.load(); + LoadConfig(); if (config.GetValue("LogDump", false)) StartCoroutine(loggingRoutine()); + if (!config.GetValue("DefaultStateIsActive", true)) + this.State = ModuleReactionWheel.WheelState.Disabled; // save the file so it can be activated by anyone config["LogDump"] = config.GetValue("LogDump", false); + config["DefaultStateIsActive"] = config.GetValue("DefaultStateIsActive", true); config.save(); } + StartCoroutine(registerWheel()); + } + + IEnumerator registerWheel() + { + for (int i = 0; i < 10; i++) + yield return null; + Window.Instance.wheelsToDraw.Add(this); + } + + public static void LoadConfig() + { + if (config == null) + config = KSP.IO.PluginConfiguration.CreateForType(); + config.load(); } public override string GetInfo() @@ -154,7 +183,7 @@ public override string GetInfo() if (min == max) info += string.Format("\r\nBleed Rate: {0:F1}%", max * 100); else - info += string.Format("\r\nBleed Rate:\r\n\tMin: {0:F1}%\r\n\tMax: {1:F1}%", min * 100, max * 100); + info += string.Format("\r\nBleed Rate:\r\n\tMin: {0:0.#%}\r\n\tMax: {1:0.#%}", min, max); // resource consumption info += "\r\n\r\nRequires:"; @@ -174,31 +203,31 @@ public override void OnFixedUpdate() if (!HighLogic.LoadedSceneIsFlight || !FlightGlobals.ready) return; - - if (this.State != WheelState.Active) - return; // update stored momentum updateMomentum(); + // update module torque outputs updateTorque(); } private void updateMomentum() { - // input torque scale. Available torque gives exponential decay and will always have some torque available (should asymptotically approach bleed rate) - float rollInput = TimeWarp.fixedDeltaTime * this.vessel.ctrlState.roll * availableRollTorque; - float pitchInput = TimeWarp.fixedDeltaTime * this.vessel.ctrlState.pitch * availablePitchTorque; - float yawInput = TimeWarp.fixedDeltaTime * this.vessel.ctrlState.yaw * availableYawTorque; - - // increase momentum stored according to relevant inputs - // transform is based on the vessel not the part. 0 Pitch torque gives no pitch response for any part orientation - // roll == up vector - // yaw == forward vector - // pitch == right vector - inputMoment(this.vessel.transform.up, rollInput); - inputMoment(this.vessel.transform.right, pitchInput); - inputMoment(this.vessel.transform.forward, yawInput); + if (this.State == WheelState.Active) + { + // input torque scale. Available torque gives exponential decay and will always have some torque available (should asymptotically approach bleed rate) + float rollInput = TimeWarp.fixedDeltaTime * this.vessel.ctrlState.roll * availableRollTorque; + float pitchInput = TimeWarp.fixedDeltaTime * this.vessel.ctrlState.pitch * availablePitchTorque; + float yawInput = TimeWarp.fixedDeltaTime * this.vessel.ctrlState.yaw * availableYawTorque; + // increase momentum stored according to relevant inputs + // transform is based on the vessel not the part. 0 Pitch torque gives no pitch response for any part orientation + // roll == up vector + // yaw == forward vector + // pitch == right vector + inputMoment(this.vessel.transform.up, rollInput); + inputMoment(this.vessel.transform.right, pitchInput); + inputMoment(this.vessel.transform.forward, yawInput); + } // reduce momentum stored by decay factor x_Moment = decayMoment(x_Moment, Planetarium.forward); @@ -241,9 +270,9 @@ private void inputMoment(Vector3 vesselAxis, float input) /// private float decayMoment(float moment, Vector3 refAxis) { - float torqueMag = new Vector3(Vector3.Dot(this.vessel.transform.right, refAxis) * this.PitchTorque - , Vector3.Dot(this.vessel.transform.forward, refAxis) * this.YawTorque - , Vector3.Dot(this.vessel.transform.up, refAxis) * this.RollTorque).magnitude; + float torqueMag = new Vector3(Vector3.Dot(this.vessel.transform.right, refAxis) * maxPitchTorque + , Vector3.Dot(this.vessel.transform.forward, refAxis) * maxYawTorque + , Vector3.Dot(this.vessel.transform.up, refAxis) * maxRollTorque).magnitude; float decay = torqueMag * (bleedRate.Evaluate(pctSaturation(moment, saturationLimit))) * TimeWarp.fixedDeltaTime; if (moment > decay) @@ -293,9 +322,9 @@ IEnumerator loggingRoutine() while (HighLogic.LoadedSceneIsFlight) { yield return new WaitForSeconds(1); - Debug.Log(string.Format("Saturation Limit: {0}\r\nMomentume X: {1}\r\nMomentum Y: {2}\r\nMomentum Z: {3}\r\nMax Roll Torque: {4}\r\nMax Pitch Torque: {5}" - + "\r\nMax Yaw Torque: {6}\r\nAvailable Roll Torque: {7}\r\nAvailable Pitch Torque: {8}\r\nAvailable Yaw Torque: {9}\r\nWheel State: {10}" - , saturationLimit, x_Moment, y_Moment, z_Moment, maxRollTorque, maxPitchTorque, maxYawTorque, availableRollTorque, availablePitchTorque, availableYawTorque, this.wheelState)); + Debug.Log(string.Format("Vessel Name: {0}\r\nPart Name: {1}\r\nSaturation Limit: {2}\r\nMomentume X: {3}\r\nMomentum Y: {4}\r\nMomentum Z: {5}\r\nMax Roll Torque: {6}\r\nMax Pitch Torque: {7}" + + "\r\nMax Yaw Torque: {8}\r\nAvailable Roll Torque: {9}\r\nAvailable Pitch Torque: {10}\r\nAvailable Yaw Torque: {11}\r\nWheel State: {12}" + ,this.vessel.vesselName, this.part.partInfo.title, saturationLimit, x_Moment, y_Moment, z_Moment, maxRollTorque, maxPitchTorque, maxYawTorque, availableRollTorque, availablePitchTorque, availableYawTorque, this.wheelState)); } } } diff --git a/SaturatableRW/SaturatableRW.csproj b/SaturatableRW/SaturatableRW.csproj index 72ade4a..e30277b 100644 --- a/SaturatableRW/SaturatableRW.csproj +++ b/SaturatableRW/SaturatableRW.csproj @@ -52,6 +52,7 @@ + diff --git a/SaturatableRW/Window.cs b/SaturatableRW/Window.cs new file mode 100644 index 0000000..c90c9ee --- /dev/null +++ b/SaturatableRW/Window.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace SaturatableRW +{ + [KSPAddon(KSPAddon.Startup.Flight, false)] + class Window : MonoBehaviour + { + static Window instance; + public static Window Instance + { + get + { + return instance; + } + } + + + // UI Stuff + public List wheelsToDraw = new List(); + Rect windowRect = new Rect(); + public bool showWindow = false; + + void Start() + { + instance = this; + InitWindow(); + } + + private void InitWindow() + { + instance = this; + + RWSaturatable.LoadConfig(); + loadConfig(); + + RenderingManager.AddToPostDrawQueue(5, draw); + Debug.Log("Draw call added"); + } + + void loadConfig() + { + windowRect = RWSaturatable.config.GetValue("windowRect", new Rect(500, 500, 300, 0)); + RWSaturatable.config["windowRect"] = windowRect; + } + + void OnDestroy() + { + RWSaturatable.config["windowRect"] = windowRect; + RWSaturatable.config.save(); + } + + void draw() + { + GUI.skin = HighLogic.Skin; + + if (showWindow) + windowRect = GUILayout.Window(573638, windowRect, drawWindow, "Semi-Saturatable Reaction Wheels", GUILayout.Height(0)); + } + + void drawWindow(int id) + { + foreach (RWSaturatable rw in wheelsToDraw) + drawWheel(rw); + + GUI.DragWindow(); + } + + void drawWheel(RWSaturatable rw) + { + Color backgroundColour = GUI.backgroundColor; + if (rw.vessel == FlightGlobals.ActiveVessel) + GUI.backgroundColor = XKCDColors.Green; + rw.drawWheel = GUILayout.Toggle(rw.drawWheel, rw.part.partInfo.title, GUI.skin.button); + GUI.backgroundColor = backgroundColour; + + if (!rw.drawWheel) + return; + bool state = GUILayout.Toggle(rw.State == ModuleReactionWheel.WheelState.Active ? true : false, "Toggle Torque"); + rw.State = state ? ModuleReactionWheel.WheelState.Active : ModuleReactionWheel.WheelState.Disabled; + + GUILayout.Label("\t\tAxis\t\tAvailable\t\tMax"); + GUILayout.Label(string.Format("\t\t{0}\t\t{1:0.0}kN\t\t\t{2:0.0}kN", "Pitch", rw.availablePitchTorque, rw.maxPitchTorque)); + GUILayout.Label(string.Format("\t\t{0}\t\t{1:0.0}kN\t\t\t{2:0.0}kN", "Yaw", rw.availableYawTorque, rw.maxYawTorque)); + GUILayout.Label(string.Format("\t\t{0}\t\t{1:0.0}kN\t\t\t{2:0.0}kN", "Roll", rw.availableRollTorque, rw.maxRollTorque)); + } + } +}