Jump to content

Deltac

Members
  • Posts

    885
  • Joined

  • Last visited

Everything posted by Deltac

  1. *performs dark magic to raise the thread from the dead* *cough cough* oh man, that dead thread smell. Don't breath this. Anyway, the download link isn't working. Leads to a "Not found on accelerator" page. Oh wait, bcink hasn't been on since March 10....
  2. one thing I'm not seeing asked is whether or not we can store sub assemblies into the storage container, like a folded up rover, and then set it on the ground without the kraken stepping in.
  3. So basically something I don't see discussed much is the affect of having aerodynamic surfaces at the front of your COM (Center of Mass). So back in 1903, the Wright Flyer first took off and flew. However the Brothers noticed a strange phenomenon. When you pitch up, the aircraft really wants to pitch up badly. Same with pitching down. The cause? When you pulled the lever to pitch up, the elevator of course changes it's Angle of Attack (AOA). But then the whole aircraft changes its AoA, which changes the Elevator's AoA even more... thus giving you a positive feedback loop. The Brothers attempted to fix this by adding weight to the front of the aircraft, and elongating later aircraft to move that COM forward for better stability. With the COM forward and the Center of Lift (COL) offset to the back, the new aircraft was much more stable. In the end though, elevator controls would be traditionally moved to the tail end for many future aircraft. So how does this apply to rockets? In the case of a Spaceplane in front, or on top (I'll just say in front), you have aerodynamic surfaces ahead of the COM, thus the COL is more than likely in front of the COM. Change the AoA of the rocket, and boom, positive feedback loop and flippy rocket. I think the most recent images of the Dream Chaser's launch configuration have it completely enveloped in a fairing. This ends up moving the COL to the back with the COM being forward for stable flight. Another way to move that pesky COL back is to add wings to the back of your rocket. So if you're ever given a space plane that sits on top of a rocket, consider where that COL is in relation to the COM. Only you can prevent flippy rockets! If I buggered something up here, let me know! I'm doing this based off of memory, so I probably got something wrong.
  4. Here's the code I could come up with so far using System; using UnityEngine; using System.Collections.Generic; using System.Linq; using System.Text; namespace Gimbal_Auto_Trim { [KSPModule("Auto-Trim")] public class ModuleGimbalAutoTrim : ModuleGimbal { // Backup of the backup of the default engine rotation public List<Quaternion> initalRots; public List<Quaternion> ZeroGimbal; //probable don't need public struct ThrustInfo { public Vector3 com; // Center of Mass public Vector3 cotAll; // Center of Thrust for all Engines public Vector3 dotOther; // Direction of Thrust for engines without AutoTrim Active public Vector3 dotAligned; // Direction of Thrust for engines with AutoTrim Active public float thrustOther; // Total Thrust or engines without AutoTrim Active public float thrustAligned; // Total Thrust or engines with AutoTrim Active } private static float lastFixedTime = 0; private static Dictionary<Guid, ThrustInfo> vesselsThrustInfo = new Dictionary<Guid, ThrustInfo>(); public override void OnStart(PartModule.StartState state) { base.OnStart(state); //get the initial rotation initalRots = new List<Quaternion>(); foreach (Quaternion q in initRots) initalRots.Add(q); //I think this is the same as initRots. ZeroGimbal = new List<Quaternion>(); for (int i = 0; i < gimbalTransforms.Count(); i++) { ZeroGimbal.Add(gimbalTransforms[i].localRotation); } } [KSPField(isPersistant = true, guiActive = true, guiActiveEditor = true, guiName = "Auto-Trim"), UI_Toggle(scene = UI_Scene.All)] public bool gimbalAutoTrim = false; //Was trying to see if I could refine the gimbal, but failed. [KSPField(isPersistant = true, guiActive = true, guiActiveEditor = true, guiName = "Auto-Trim Limit"), UI_FloatRange(minValue = 80f, maxValue = 90f, scene = UI_Scene.All, stepIncrement = .1f)] public float trimLimit = 90f; //leftover code [KSPField(isPersistant = false, guiActive = false, guiName = "Angle")] public string trimStatus = ""; [KSPField(isPersistant = false, guiActive = true, guiName = "correction")] public string correction = ""; [KSPField(isPersistant = false, guiActive = true, guiName = "trimAngle")] public string trimAngle = ""; public override string GetInfo() { return base.GetInfo(); } public override void OnFixedUpdate() { //If we're in the editor, move on, nothing to see here. //if (HighLogic.LoadedSceneIsEditor || this.vessel == null) //return; //Fields["trimStatus"].guiActive = this.gimbalAutoTrim; //If the user turned on auto trim if (this.gimbalAutoTrim) { // If we moved to a new phyisic frame then clear the cache if (lastFixedTime != Time.fixedTime) { vesselsThrustInfo = new Dictionary<Guid, ThrustInfo>(); lastFixedTime = Time.fixedTime; } //this thrustTransform stuff we probably don't need. ModuleEngines engine = part.Modules.OfType<ModuleEngines>().FirstOrDefault(); ModuleEnginesFX enginefx = part.Modules.OfType<ModuleEnginesFX>().Where(e => e.isEnabled).FirstOrDefault(); List<Transform> thrustTransforms; //Some engines can have more than 1 thrusttransform //Get the list of thrust transforms from the current engine. if (engine != null) thrustTransforms = engine.thrustTransforms; else // ModuleEnginesFX thrustTransforms = enginefx.thrustTransforms; Vector3 com; com = this.vessel.localCoM; Quaternion target_rot; for (int i = 0; i < this.initRots.Count(); i++) { //thrustTransforms[i].rotation = Quaternion.Euler(x, 0, 0); //gimbalTransforms[i].localRotation = Quaternion.FromToRotation(gimbalTransforms[i].localPosition, com); //Debug.Log("ZeroGimbal " + ZeroGimbal[i].eulerAngles); Debug.Log("initRots " + this.initRots[i].eulerAngles); Debug.Log("Transform " + gimbalTransforms[i].localRotation.eulerAngles); //Debug.Log("Thrust Transform " + thrustTransforms[i].localRotation.eulerAngles); //Get the rotation from the gimbalTransform to the Center of Mass target_rot = Quaternion.FromToRotation(gimbalTransforms[i].localPosition, com); //Then we do some fancy math to get close, but torque still exists >.< this.initRots[i] = (initalRots[i] * (ZeroGimbal[i] * Quaternion.Inverse(target_rot))) * Quaternion.Euler(trimLimit, 0f, 0f); //gimbalTransforms[i].LookAt(com); //this.initRots[i] = initalRots[i] * (ZeroGimbal[i] * Quaternion.Inverse(target_rot)); Debug.Log("target rot " + target_rot.eulerAngles); Debug.Log("Difference " + (initalRots[i] * (ZeroGimbal[i] * Quaternion.Inverse(target_rot))).eulerAngles); //this.initRots[i] = ZeroGimbal[i] * Quaternion.Inverse(target_rot); } } else //Reset the engine gimbal { for (int i = 0; i < this.initalRots.Count(); i++) { this.initRots[i] = initalRots[i]; Debug.Log("Gimbal Transform Rotation " + gimbalTransforms[i].eulerAngles); } } base.OnFixedUpdate(); } //public override void OnUpdate() //{ // base.OnUpdate(); //} public static string PrettyPrint(Vector3d vector, string format = "F3") { return "[" + (vector.x >= 0 ? " " : "") + vector.x.ToString(format) + ", " + (vector.y >= 0 ? " " : "") + vector.y.ToString(format) + ", " + (vector.z >= 0 ? " " : "") + vector.z.ToString(format) + "]"; } public static new void print(object message) { MonoBehaviour.print("[ModuleGimbalAligned] " + message); } } } This only works for the MainSail engine and engines that were modeled like it. For some reason the Gimbal Transform (I guess) has no standardization to how it's rotated. Anyway, since there's no interest in this project, I'm calling it quits. If someone wants to mess around with my code, feel free. I'm going to take a break from KSP for a little while but I'll be back. I'll always be back...
  5. I'm trying to programatically change the gimbal of an Engine to point at the center of mass, however ModuleGimbal is throwing me for a loop. So far I can't rotate the gimbal transform by itself (though I can rotate the thrust transform, however that doesn't produce a visual effect). I have to change initRots, but I can't figure out what initRots is supposed to be. In the MainSail engine, the initRots starts off as 0,180,0, but in the new poodle, it's 0,90,0. so I don't know what math I'm supposed to do to set the initrots. (or perhaps there's a better method?)
  6. So I've decided to rewrite the Gimbal Auto Trim code. My current dilemma is I want to set the gimbal rotation into the center of mass, but everything I've tried so far isn't perfect. So my module inherits from ModuleGimbal. I've tried rotating the gimbaltransforms, but that produces no results. I also did the following: vector3 com; com = this.vessel.localCoM; for (int i = 0; i < this.initRots.Count(); i++) { this.initRots[i] = Quaternion.FromToRotation(gimbalTransforms[i].localPosition, com); } However I think initRots is rotation relative to the gimbal transform. I can get the new poodle engine to rotate at a correct angle, but the user would have to turn the part around in the VAB. And the Main Sail engine gimbals perpendicular to the COM so I need a solution for all engines at any rotation. Should I get the FromToRotation from the Gimbal transform to the COM, and do something complicated to affect the initRots? I'm not sure how that would look.
  7. I think Beale wants to avoid space planes. The biggest issue would be having a space plane on the front of your soyuz. It will flip the rocket! The solution would be to have a folding wing Kliper that can then fit in a custom fairing assembly. That of course would require that plugin that turns off the aerodynamic forces for wings, and Beale doesn't want to require other mods.
  8. Would anyone be interested in the engines pointing directly at the center of thrust at all times? I'm currently trying to resurrect Sarbian's old Gimbal Auto Trim mod (actually it's now looking like a rewrite!) and I could use help figuring out how to code with KSP. I'm advertising the mod here because I thought some of the people who enjoy the shuttle might want a plugin to point the engines at the center of mass at all times automatically. And of course I'm hoping to get the word out that I'm looking for someone more familiar with KSP Plugin development to help me figure out how to use the KSP API. I'm on topic because I want shuttle engine gimbal auto trimming! >:O
  9. (oh no double post) At the moment, after looking over Sarb's code, I'm thinking about rewriting the code to simplify it. However, I have some questions: 1. Does each engine in a vessel have their own Center of Thrust vector? I know there's the total COT for the whole vessel, but I only want the COT of 1 engine so I can tell the engine to gimbal in a certain direction. Or do I just use the location of the part as a whole to then do maths with the COM location to find the rotation needed? 2. How would I get the engine's thrust's current rotation? Or the gimbal's current rotation? Or is it the thrust transform specifically? Psuedo code ahead! Quaternion Current_Rot = 0 Quaternion Rot_needed = 0 Vector3 COM = (0,0,0) Vector3 COT = (0,0,0) COM = Get Vessel COM //this.vessle.localCOM? COT = This parts Center of Thrust, not the whole vessel's. Current_Rot = current rotation of the engine's thrust transform? Code and math to get the Rot_needed value Math to find out the difference between Current_Rot and Rot_needed. //If it's within a certain error, don't reset it? We still want the engines to have //some gimbal. Is there a way to know when the user or mechjeb are acting on the //control inputs? Set the Engine's thrust's rotation to Rot_needed. //Problem: What happens if the user rotates the engine in the editor? Will that throw things off? I certainly hope someone can help me out with this. I'll look at the API, but I'm not sure where to start to find out what I need to rotate.
  10. I'm trying my best to resurrect the old Gimbal Auto Trim that Sarbian created long ago in a distant land. Unfortunately my unfamiliarity with the KSP API has me in vector river without a paddle. Here is the code so far: using System; using UnityEngine; using System.Collections.Generic; using System.Linq; using System.Text; namespace GimbalAutoTrim { [KSPModule("Auto-Trim")] public class ModuleGimbalAutoTrim : ModuleGimbal { // Backup of the backup of the default engine rotation public List<Quaternion> initalRots; public struct ThrustInfo { public Vector3 com; // Center of Mass public Vector3 cotAll; // Center of Thrust for all Engines public Vector3 dotOther; // Direction of Thrust for engines without AutoTrim Active public Vector3 dotAligned; // Direction of Thrust for engines with AutoTrim Active public float thrustOther; // Total Thrust or engines without AutoTrim Active public float thrustAligned; // Total Thrust or engines with AutoTrim Active } private static float lastFixedTime = 0; private static Dictionary<Guid, ThrustInfo> vesselsThrustInfo = new Dictionary<Guid, ThrustInfo>(); public override void OnStart(PartModule.StartState state) { base.OnStart(state); initalRots = new List<Quaternion>(); foreach (Quaternion q in initRots) initalRots.Add(q); } [KSPField(isPersistant = true, guiActive = true, guiActiveEditor = true, guiName = "Auto-Trim"), UI_Toggle(scene = UI_Scene.All)] public bool gimbalAutoTrim = false; [KSPField(isPersistant = true, guiActive = false, guiActiveEditor = true, guiName = "Auto-Trim Limit"), UI_FloatRange(minValue = 0f, maxValue = 90f, scene = UI_Scene.Editor, stepIncrement = 5f)] public float trimLimit = 45f; [KSPField(isPersistant = false, guiActive = false, guiName = "Angle")] public string trimStatus = ""; [KSPField(isPersistant = false, guiActive = true, guiName = "correction")] public string correction = ""; [KSPField(isPersistant = false, guiActive = true, guiName = "trimAngle")] public string trimAngle = ""; public override string GetInfo() { return base.GetInfo(); } public ThrustInfo updateThrust() { ThrustInfo ti = new ThrustInfo(); ti.cotAll = Vector3.zero; ti.dotOther = Vector3.zero; ti.dotAligned = Vector3.zero; ti.thrustOther = 0; ti.thrustAligned = 0; foreach (Part p in vessel.Parts) { Vector3 coT = Vector3.zero; Vector3 doT = Vector3.zero; float thrust = 0; Vector3 thurstForward = Vector3.zero; ModuleEngines engine = p.Modules.OfType<ModuleEngines>().FirstOrDefault(); ModuleEnginesFX enginefx = p.Modules.OfType<ModuleEnginesFX>().Where(e => e.isEnabled).FirstOrDefault(); if (enginefx != null || engine != null) { List<Transform> thrustTransforms; ModuleGimbal gimbal = p.Modules.OfType<ModuleGimbal>().FirstOrDefault(); if (engine != null) thrustTransforms = engine.thrustTransforms; else // ModuleEnginesFX thrustTransforms = enginefx.thrustTransforms; List<Vector3> forwards; if (gimbal != null) { List<Quaternion> initRots = gimbal.initRots; forwards = new List<Vector3>(initRots.Count); for (int i = 0; i < initRots.Count; i++) { Transform tt = thrustTransforms[i]; Quaternion ori = tt.localRotation; tt.localRotation = (gimbal is ModuleGimbalAutoTrim) ? (gimbal as ModuleGimbalAutoTrim).initalRots[i] : initRots[i]; forwards.Add(tt.forward); tt.localRotation = ori; } } else { forwards = new List<Vector3>(thrustTransforms.Count); foreach (Transform thrustTransform in thrustTransforms) forwards.Add(thrustTransform.forward); } for (int i = 0; i < thrustTransforms.Count; i++) foreach (Transform thrustTransform in thrustTransforms) { coT = coT + (thrustTransforms[i].position - p.transform.position); doT = doT + forwards[i]; } coT = (coT / (float)thrustTransforms.Count) + p.transform.position; doT = doT / (float)thrustTransforms.Count; thrust = (engine != null) ? engine.finalThrust : enginefx.finalThrust; if (gimbal != null && (gimbal is ModuleGimbalAutoTrim) && (gimbal as ModuleGimbalAutoTrim).gimbalAutoTrim) { ti.dotAligned += doT * thrust; ti.thrustAligned += thrust; } else { ti.dotOther += doT * thrust; ti.thrustOther += thrust; } ti.cotAll += coT * thrust; } } ti.cotAll = ti.cotAll / (ti.thrustOther + ti.thrustAligned); ti.com = this.vessel.localCoM; return ti; } public override void OnFixedUpdate() { if (HighLogic.LoadedSceneIsEditor || this.vessel == null) return; Fields["trimStatus"].guiActive = this.gimbalAutoTrim; if (this.gimbalAutoTrim) { ThrustInfo ti; // If we moved to a new phyisic frame then clear the cache if (lastFixedTime != Time.fixedTime) { vesselsThrustInfo = new Dictionary<Guid, ThrustInfo>(); lastFixedTime = Time.fixedTime; } if (!vesselsThrustInfo.ContainsKey(vessel.id)) { ti = updateThrust(); vesselsThrustInfo.Add(vessel.id, ti); } else ti = vesselsThrustInfo[vessel.id]; if (ti.thrustAligned > 0f) { Vector3 optimalDot = ti.cotAll - ti.com; Vector3 currentDot = ti.dotOther + ti.dotAligned; // CoT in front of CoM if (Vector3.Dot(optimalDot, currentDot) < 0f) optimalDot = -optimalDot; // We work in a 2D plane whose axis are correction and optimalDot // correction is the perpendicular to optimalDot in the plane defined by optimalDot/currentDot //Vector3 correction = Vector3.ProjectOnPlane(optimalDot, currentDot); //.Exclude(optimalDot, currentDot); Vector3 correction = Vector3.Exclude(optimalDot, currentDot); this.correction = PrettyPrint(correction, "F2"); //float thrustAlignedX = Vector3.ProjectOnPlane(optimalDot, ti.dotAligned).magnitude; //Vector3.Exclude(optimalDot, ti.dotAligned).magnitude; float thrustAlignedX = Vector3.Exclude(optimalDot, ti.dotAligned).magnitude; float x = Mathf.Clamp(thrustAlignedX - correction.magnitude, -ti.thrustAligned, ti.thrustAligned); float y = Mathf.Sqrt(ti.thrustAligned * ti.thrustAligned - x * x); Vector3 trimedDotAligned = correction.normalized * x + optimalDot.normalized * y; float trimAngle = Vector3.Angle(ti.dotAligned, trimedDotAligned); this.trimAngle = trimAngle.ToString("F2"); Quaternion trimRotation = Quaternion.FromToRotation(ti.dotAligned, trimedDotAligned); //print("optimalDir " + PrettyPrint(optimalDir) + " currentDir " + PrettyPrint(currentDir) + " correction " + PrettyPrint(correction) + " angle " + Vector3.Angle(currentDir, optimalDir).ToString("F2") + " cAngle " + trimAngle.ToString("F3")); float trimRatio = Mathf.Min(trimLimit / trimAngle, 1f); this.trimStatus = (trimAngle * trimRatio).ToString("F1") + " deg"; for (int i = 0; i < this.initRots.Count(); i++) { gimbalTransforms[i].localRotation = initalRots[i]; gimbalTransforms[i].forward = Quaternion.Lerp(Quaternion.identity, trimRotation, trimRatio) * gimbalTransforms[i].forward; this.initRots[i] = gimbalTransforms[i].localRotation; } } else { for (int i = 0; i < this.initalRots.Count(); i++) { this.initRots[i] = initalRots[i]; } } } else { for (int i = 0; i < this.initalRots.Count(); i++) { this.initRots[i] = initalRots[i]; } } base.OnFixedUpdate(); } //public override void OnUpdate() //{ // base.OnUpdate(); //} public static string PrettyPrint(Vector3d vector, string format = "F3") { return "[" + (vector.x >= 0 ? " " : "") + vector.x.ToString(format) + ", " + (vector.y >= 0 ? " " : "") + vector.y.ToString(format) + ", " + (vector.z >= 0 ? " " : "") + vector.z.ToString(format) + "]"; } public static new void print(object message) { MonoBehaviour.print("[ModuleGimbalAligned] " + message); } } } Now I have it "working" in KSP, however the engine doesn't gimbal into the center of mass, as evidenced by these pictures: I'm hoping the community can help me understand this code so I can make the corrections necessary and give back to this community.
  11. We have results! Just not correct results xD So it looks like it's gimbaling at the right angle, just not into the center of mass. Unfortunately I'm not sure where it's getting the wrong rotation, or vector.
  12. So I'm trying to get some old code working for myself, however I'm brand new to Plugin development and may not have my Visual Studio set up properly. I did get the example "Hello World" code to work in KSP, so that simple little thing is okay. The code I'm trying to recompile for myself is found here As you can see, it's very old, so I'm not 100% sure if everything would work, but at the moment Vis Studio is only giving me 1 error and 2 warnings. Error CS1061 'Vessel' does not contain a definition for 'findLocalCenterOfMass' and no accessible extension method 'findLocalCenterOfMass' accepting a first argument of type 'Vessel' could be found (are you missing a using directive or an assembly reference?) Warning CS0618 'Vector3.Exclude(Vector3, Vector3)' is obsolete: 'Use Vector3.ProjectOnPlane instead.' I can't find anything about FindLocalCenterOfMass or FindWorldCenterOfMass in the API documentation other than I should use it to get the center of mass....
  13. Yeah, Fuel tanks, RCS blocks, and the MIR Gyros from Tantares, and it all moves smoothly into place. Then KIS/KAS comes into play to take parts off and dump them into space for tracking station cleanup!
  14. So far the only thing I've really got to work perfectly is the Manuever Auto pilot in space. Even though TCA doesn't force gimbal the engines into the COM, it can still handle a shuttle with little problems and very little "Chasing the rabbit". Course that's my next request: Force the gimbal of an engine group into the COM, and then read that thrust trajectory to point the craft in the proper direction. That way you don't have to throttle engines down to maintain balance, but this might be key for just shuttles.
  15. I've done my best to try and find info on Mechjeb and Space Shuttles' offset center of mass/thrust in space, but I'm finding a lack of info. If the center of thrust and mass are aligned in a space shuttle, but off center from the rest of the craft, can Mechjeb point the shuttle so that the center of thrust/mass are pointing at the maneuver node?
  16. I've completely switched to 1.6.1 due to the memory leak fix. I still have older versions but they'll be trashed soon And for 1.7, doesn't look like it has much other than quality of life fixes, so I'll probably look at it but not worry about modding it for some time after it's released.
  17. I can only imagine you have several notes set on top of that one xD So I ran into a bug I think with Auto strutting: Whenever i tried to dock the Dragon V2 with Mir, Kessler Syndrome. Then I switched to a shuttle, and docking went fine... but undocking would Kessler Syndrome it again. But undocking the Soyuz wouldn't? I decided to reduce the amount of auto strutting down to just 4 or 5 parts, and now it seems stable. I'm also using rigid attachment on several parts as well, including the docking ports. And the auto strutting is to the heaviest part. So maybe someone can tell me how to auto strut better? C:
  18. Ah yeah, that makes sense. The normal user might not know about KIS/KAS. Anyway screw the rules I have Module Manager. This was a test to see how it would fit in the orbiter. Also WOOT new page!
×
×
  • Create New...