Inheritance: UnityEngine.MonoBehaviour
Exemplo n.º 1
0
        public void ForceSimunlation()
        {
            try
            {
                simulationRunning = true;
                stopwatch.Start(); //starts a timer that times how long the simulation takes

                //Create two FuelFlowSimulations, one for vacuum and one for atmosphere
                List <Part> parts = (HighLogic.LoadedSceneIsEditor ? EditorLogic.fetch.ship.parts : vessel.parts);

                sims[0].Init(parts, dVLinearThrust);
                sims[1].Init(parts, dVLinearThrust);

                RunSimulation(sims);
            }
            catch (Exception e)
            {
                GravityTurner.Log("Exception in StageStats.ForceSimunlation(): {0}", e.ToString());
                // Stop timing the simulation
                stopwatch.Stop();
                millisecondsBetweenSimulations = 500;
                stopwatch.Reset();

                // Start counting down the time to the next simulation
                stopwatch.Start();
                simulationRunning = false;
            }
        }
Exemplo n.º 2
0
        protected void RunSimulation(object o)
        {
            try
            {
                CelestialBody simBody           = HighLogic.LoadedSceneIsEditor ? editorBody : vessel.mainBody;
                double        staticPressureKpa = (HighLogic.LoadedSceneIsEditor || !liveSLT ? (simBody.atmosphere ? simBody.GetPressure(0) : 0) : vessel.staticPressurekPa);
                double        atmDensity        = (HighLogic.LoadedSceneIsEditor || !liveSLT ? simBody.GetDensity(simBody.GetPressure(0), simBody.GetTemperature(0)) : vessel.atmDensity) / 1.225;
                double        mach = HighLogic.LoadedSceneIsEditor ? 1 : vessel.mach;

                //Run the simulation
                FuelFlowSimulation[]       sims         = (FuelFlowSimulation[])o;
                FuelFlowSimulation.Stats[] newAtmoStats = sims[0].SimulateAllStages(1.0f, staticPressureKpa, atmDensity, mach);
                FuelFlowSimulation.Stats[] newVacStats  = sims[1].SimulateAllStages(1.0f, 0.0, 0.0, mach);
                atmoStats = newAtmoStats;
                vacStats  = newVacStats;
            }
            catch (Exception e)
            {
                GravityTurner.Log("Exception in StageStats.RunSimulation(): {0}", e.ToString());
            }

            //see how long the simulation took
            stopwatch.Stop();
            long millisecondsToCompletion = stopwatch.ElapsedMilliseconds;

            stopwatch.Reset();

            //set the delay before the next simulation
            millisecondsBetweenSimulations = 2 * millisecondsToCompletion;

            //start the stopwatch that will count off this delay
            stopwatch.Start();
            simulationRunning = false;
        }
Exemplo n.º 3
0
 public FlightMap(GravityTurner turner,int width=800,int height=400)
 {
     this.turner = turner; 
     texture = new Texture2D(width, height);
     for (int x = 0; x < texture.width; x++)
         for (int y = 0; y < texture.height; y++)
             texture.SetPixel(x, y, Color.black);
     texture.Apply();
 }
Exemplo n.º 4
0
        public static float MaxAngle(Vessel vessel, GravityTurner turner)
        {
            float angle    = 100000 / (float)turner.vesselState.dynamicPressure;
            float vertical = 90 + vessel.Pitch();

            angle = Mathf.Clamp(angle, 0, 35);
            if (angle > vertical)
            {
                return(vertical);
            }
            return(angle);
        }
Exemplo n.º 5
0
 public FlightMap(GravityTurner turner, int width = 800, int height = 400)
 {
     this.turner = turner;
     texture     = new Texture2D(width, height);
     for (int x = 0; x < texture.width; x++)
     {
         for (int y = 0; y < texture.height; y++)
         {
             texture.SetPixel(x, y, Color.black);
         }
     }
     texture.Apply();
 }
Exemplo n.º 6
0
        public void CircularizeAtAP()
        {
            double UT = Planetarium.GetUniversalTime();

            UT += vessel.orbit.timeToAp;
            System.Type OrbitalManeuverCalculatorType = FindMechJebModule("MuMech.OrbitalManeuverCalculator");

            MethodInfo CircularizeMethod = OrbitalManeuverCalculatorType.GetMethod("DeltaVToCircularize", BindingFlags.Public | BindingFlags.Static);
            Vector3d   deltav            = (Vector3d)CircularizeMethod.Invoke(null, new object[] { vessel.orbit, UT });

            GravityTurner.Log(string.Format("Circularization burn {0:0.0} m/s", deltav.magnitude));
            vessel.PlaceManeuverNode(vessel.orbit, deltav, UT);
            ExecuteNode();
        }
Exemplo n.º 7
0
        ///<summary>
        ///Get or create a new DBEntry based on angle, speed and destination height, so we don't have duplicates.
        ///</summary>
        DBEntry GetEntry()
        {
            DBEntry foundEntry = FindEntry(turner.StartSpeed, turner.TurnAngle, turner.DestinationHeight);

            if (foundEntry != null)
            {
                return(foundEntry);
            }
            GravityTurner.Log("Recording new launch record #{0}", DB.Count);

            DBEntry newentry = new DBEntry();

            DB.Add(newentry);
            return(newentry);
        }
Exemplo n.º 8
0
 public static FlightMap Load(string filename, GravityTurner turner)
 {
     try
     {
         Texture2D texture = new Texture2D(800, 400);
         texture.LoadImage(System.IO.File.ReadAllBytes(filename));
         FlightMap flightmap = new FlightMap(turner, texture.width, texture.height);
         flightmap.texture = texture;
         GravityTurner.Log("FlightMap loaded with {0:0.00} loss", args: flightmap.TotalLoss());
         return(flightmap);
     }
     catch (Exception)
     {
         return(null);
     }
 }
Exemplo n.º 9
0
 public void Load()
 {
     try
     {
         root = ConfigNode.Load(GetFilename());
         if (root != null)
         {
             ConfigNode.LoadObjectFromConfig(this, root);
         }
         DB.Sort();
     }
     catch (Exception ex)
     {
         GravityTurner.Log("Vessel DB Load error {0}", ex.ToString());
     }
 }
Exemplo n.º 10
0
        public static string GetBaseFilePath(Type t, string sub)
        {
            try
            {
#if DEBUG
                return(System.IO.Directory.GetCurrentDirectory() + @"\GameData\GravityTurn\Plugins\PluginData\GravityTurn\" + sub);
#else
                return(IOUtils.GetFilePathFor(t, sub));
#endif
            }
            catch (Exception ex)
            {
                GravityTurner.Log("Exception: {0}", ex.ToString());
                return(System.IO.Directory.GetCurrentDirectory() + @"\GameData\GravityTurn\Plugins\PluginData\GravityTurn\" + sub);
            }
        }
Exemplo n.º 11
0
 ///<summary>
 ///Just replay the best launch, no learning to be done.
 ///</summary>
 public bool BestSettings(out double TurnAngle, out double StartSpeed)
 {
     GravityTurner.DebugMessage = String.Format("LaunchDB entries: {0}", DB.Count);
     DB.Sort();
     TurnAngle  = 0;
     StartSpeed = 0;
     GravityTurner.Log("DB[0]: mh={0:0.00}, ok={1}", DB[0].MaxHeat, DB[0].LaunchSuccess);
     if (DB.Count < 1 || DB[0].MaxHeat >= 1 || !DB[0].LaunchSuccess)
     {
         return(false);
     }
     TurnAngle  = DB[0].TurnAngle;
     StartSpeed = DB[0].StartSpeed;
     GravityTurner.Log("Best Guess: s={0:0.00}, a={1:0.00}", StartSpeed, TurnAngle);
     return(true);
 }
Exemplo n.º 12
0
        public float MaxHeat()
        {
            float max = 0;

            for (int x = 0; x < texture.width; x++)
            {
                for (int y = 0; y < texture.height; y++)
                {
                    if (texture.GetPixel(x, y).r > max)
                    {
                        max = texture.GetPixel(x, y).r;
                    }
                }
            }
            GravityTurner.Log("Previous max heat {0:0.000}", max);
            return(max);
        }
Exemplo n.º 13
0
        void Start()
        {
            instance = this;
            Log("Starting");
            try
            {
                mucore.init();
                vesselState = new VesselState();
                attitude    = new AttitudeController(this);
                stage       = new StageController(this);
                attitude.OnStart();
                stagestats            = new StageStats(stage);
                stagestats.editorBody = getVessel.mainBody;
                stagestats.OnModuleEnabled();
                stagestats.OnFixedUpdate();
                stagestats.RequestUpdate(this);
                stagestats.OnFixedUpdate();
                CreateButtonIcon();
                LaunchName = new string(getVessel.vesselName.ToCharArray());
                LaunchBody = getVessel.mainBody;
                launchdb   = new LaunchDB(this);
                launchdb.Load();

                mainWindow      = new Window.MainWindow(this, 6378070);
                flightMapWindow = new Window.FlightMapWindow(this, 548302);
                statsWindow     = new Window.StatsWindow(this, 6378070 + 4);
                double h = 80f;
                if (FlightGlobals.ActiveVessel.mainBody.atmosphere)
                {
                    h = Math.Max(h, FlightGlobals.ActiveVessel.mainBody.atmosphereDepth + 10000f);
                    DestinationHeight = new EditableValue(h, locked: true) / 1000;
                }

                delayUT = double.NaN;

                GameEvents.onShowUI.Add(ShowGUI);
                GameEvents.onHideUI.Add(HideGUI);

                LoadKeybind();
            }
            catch (Exception ex)
            {
                Log(ex.ToString());
            }
        }
Exemplo n.º 14
0
        public bool init()
        {
            if (Initialized)
            {
                return(true);
            }
            CoreType = FindMechJebModule("MuMech.MechJebCore");

            if (CoreType == null)
            {
                GravityTurner.Log("MechJeb assembly not found");
                return(false);
            }
            if (!GetCore())
            {
                GravityTurner.Log("MechJeb core not found");
                return(false);
            }
            GravityTurner.Log("Found MechJeb core");
            Initialized = true;
            return(true);
        }
Exemplo n.º 15
0
 public bool Equals(GravityTurner turner)
 {
     return(StartSpeed == turner.StartSpeed && TurnAngle == turner.TurnAngle && MaxHeat == turner.MaxHeat && TotalLoss == turner.TotalLoss);
 }
Exemplo n.º 16
0
 public static FlightMap Load(string filename, GravityTurner turner)
 {
     try
     {
         Texture2D texture = new Texture2D(800, 400);
         texture.LoadImage(System.IO.File.ReadAllBytes(filename));
         FlightMap flightmap = new FlightMap(turner, texture.width, texture.height);
         flightmap.texture = texture;
         GravityTurner.Log("FlightMap loaded with {0:0.00} loss", args:flightmap.TotalLoss());
         return flightmap;
     }
     catch (Exception)
     {
         return null;
     }
 }
Exemplo n.º 17
0
        ///<summary>
        ///Do the real work to analyze previous results and get recommended settings.
        ///</summary>
        public bool GuessSettings(out double TurnAngle, out double StartSpeed)
        {
            try
            {
                GravityTurner.Log("Guessing settings");
                // sort by most aggressive
                DB.Sort();
                if (GameSettings.MODIFIER_KEY.GetKey())
                {
                    TurnAngle  = 10;
                    StartSpeed = 100;
                    GravityTurner.Log("Reset results");
                    return(false);
                }
                TurnAngle  = 0;
                StartSpeed = 0;
                if (DB.Count == 0)
                {
                    GravityTurner.Log("No previous result");
                    return(false);
                }
                if (DB.Count == 1)
                {
                    GravityTurner.Log("Only one previous result");
                    if (DB[0].MaxHeat < 0.90)
                    {
                        float Adjust = Mathf.Clamp((float)DB[0].MaxHeat + (float)(1 - DB[0].MaxHeat) / 2, 0.8f, 0.95f);
                        TurnAngle  = DB[0].TurnAngle / Adjust;
                        StartSpeed = DB[0].StartSpeed * Adjust;
                    }
                    else if (DB[0].MaxHeat > 0.95)
                    {
                        TurnAngle  = DB[0].TurnAngle * 0.95;
                        StartSpeed = DB[0].StartSpeed * 1.05;
                    }
                    else
                    {
                        TurnAngle  = DB[0].TurnAngle;
                        StartSpeed = DB[0].StartSpeed;
                    }
                    return(true);
                }

                // more than one result, now we can do real work

                // Simple linear progression 2nd best -> best -> next

                TurnAngle  = DB[0].TurnAngle + DB[0].TurnAngle - DB[1].TurnAngle;
                StartSpeed = DB[0].StartSpeed + DB[0].StartSpeed - DB[1].StartSpeed;

                // check if this launch was already tried and failed
                DBEntry check = FindEntry(StartSpeed, TurnAngle, turner.DestinationHeight);
                if (check != null && !check.LaunchSuccess)
                {
                    TurnAngle  = (DB[0].TurnAngle + check.TurnAngle) / 2;
                    StartSpeed = (DB[0].StartSpeed + check.StartSpeed) / 2;
                    GravityTurner.Log("Found failed run, set between {0} and {1}",
                                      DB[0].ToString(), check.ToString()
                                      );
                }

                // Check for overheated launches so we don't make that mistake again
                DBEntry hotrun = LeastCritical();
                if (hotrun != null && TurnAngle / StartSpeed >= hotrun.TurnAngle / hotrun.StartSpeed * 0.99) // Close to a previous overheating run
                {
                    TurnAngle  = (DB[0].TurnAngle + hotrun.TurnAngle) / 2;
                    StartSpeed = (DB[0].StartSpeed + hotrun.StartSpeed) / 2;
                    GravityTurner.Log("Found hot run, set between {0} and {1}",
                                      DB[0].ToString(), hotrun.ToString()
                                      );
                }

                // Need to check to see if we're past the point of max efficiency
                DBEntry toomuch = EfficiencyTippingPoint();
                // If we're within 1% of a launch that was inefficient (or beyond)...
                if (toomuch != null && TurnAngle / StartSpeed >= toomuch.TurnAngle / toomuch.StartSpeed * 0.99)
                {
                    // Go halfway between the best and too much
                    TurnAngle  = (DB[0].TurnAngle + toomuch.TurnAngle) / 2;
                    StartSpeed = (DB[0].StartSpeed + toomuch.StartSpeed) / 2;
                }
            }
            catch (Exception ex)
            {
                GravityTurner.Log(ex.Message);
                TurnAngle  = 0;
                StartSpeed = 0;
                return(false);
            }

            return(true);
        }
Exemplo n.º 18
0
 public StageController(GravityTurner turner)
 {
     this.turner = turner;
 }
Exemplo n.º 19
0
        public static float APThrottle(double timeToAP, GravityTurner turner)
        {
            Vessel vessel = GravityTurner.getVessel;
            if (vessel.speed < turner.StartSpeed)
                turner.Throttle.value = 1.0f;
            else
            {
                if (timeToAP > vessel.orbit.timeToPe) // We're falling
                    timeToAP = 0;
                float diff = 0.1f * (float)Math.Abs(turner.HoldAPTime - timeToAP) * 0.5f;
                turner.TimeSpeed = (turner.PrevTime - timeToAP) / (Time.time - turner.lastTimeMeasured);
                if (Math.Abs(turner.TimeSpeed) < 0.02 && turner.PitchAdjustment == 0)
                    turner.NeutralThrottle = (float)turner.Throttle.value;
                if (Math.Abs(timeToAP - turner.HoldAPTime) < 0.1)
                {
                    if (turner.PitchAdjustment > 0)
                        turner.PitchAdjustment.value -= 0.1f;
                    else
                        turner.Throttle.force(turner.NeutralThrottle);
                }
                else if (timeToAP < turner.HoldAPTime)
                {
                    if (turner.Throttle.value >= 1 && (timeToAP < turner.PrevTime || (timeToAP - turner.HoldAPTime) / turner.TimeSpeed > 20))
                    {
                        turner.NeutralThrottle = 1;
                        turner.PitchAdjustment.value += 0.1f;
                    }
                    turner.Throttle.value += diff;

                    if (0 < (timeToAP - turner.HoldAPTime) / turner.TimeSpeed && (timeToAP - turner.HoldAPTime) / turner.TimeSpeed < 20)  // We will reach desired AP time in <20 second
                    {
                        turner.PitchAdjustment.value -= 0.1f;
                    }
                }
                else if (timeToAP > turner.HoldAPTime)
                {
                    if (turner.PitchAdjustment > 0)
                        turner.PitchAdjustment.value -= 0.1f;
                    else
                        turner.Throttle.value -= diff;
                }
            }
            if (turner.PitchAdjustment < 0)
                turner.PitchAdjustment.value = 0;
            if (turner.PitchAdjustment > MaxAngle(vessel,turner))
                turner.PitchAdjustment.value = MaxAngle(vessel,turner);

            // We don't want to do any pitch correction during the initial lift
            if (vessel.ProgradePitch(true) < -45)
                turner.PitchAdjustment.force(0);
            turner.PrevTime = vessel.orbit.timeToAp;
            turner.lastTimeMeasured = Time.time;
            if (turner.Throttle.value < turner.Sensitivity)
                turner.Throttle.force(turner.Sensitivity);
            if (turner.Throttle.value > 1)
                turner.Throttle.force(1);

            // Inrease the AP time if needed for SRB lifter stages
            if (vessel.HasActiveSRB() && vessel.orbit.timeToAp > turner.HoldAPTime && turner.TimeSpeed < 0)
            {
                double StopHeight = GravityTurner.getVessel.mainBody.atmosphereDepth;
                if (StopHeight <= 0)
                    StopHeight = turner.DestinationHeight * 1000;
                turner.APTimeStart = (StopHeight * vessel.orbit.timeToAp - vessel.altitude * turner.APTimeFinish) / (StopHeight - vessel.altitude);
                turner.APTimeStart *= 0.99; // We want to be just a bit less than what we calculate, so we don't stay throttled up
            }

            return (float)turner.Throttle.value;
        }
Exemplo n.º 20
0
        public void CalculateSettings(Vessel vessel, bool UseBest = false)
        {
            float baseFactor = Mathf.Round((float)vessel.mainBody.GeeASL * 100.0f) / 10.0f;

            Log("Base turn speed factor {0:0.00}", baseFactor);

            // reset the settings to defaults
            if (GameSettings.MODIFIER_KEY.GetKey())
            {
                launchdb.Clear();
                TurnAngle         = 10;
                StartSpeed        = baseFactor * 10.0;
                DestinationHeight = (vessel.StableOrbitHeight() + 10000) / 1000;
                GravityTurner.Log("Reset results");
                return;
            }
            Log("Min orbit height: {0}", vessel.StableOrbitHeight());

            stagestats.ForceSimunlation();
            double TWR = 0;

            for (int i = stagestats.atmoStats.Length - 1; i >= 0; i--)
            {
                double stagetwr = stagestats.atmoStats[i].StartTWR(vessel.mainBody.GeeASL);
                if (stagetwr > 0)
                {
                    if (vessel.StageHasSolidEngine(i))
                    {
                        TWR = (stagetwr + stagestats.atmoStats[i].MaxTWR(vessel.mainBody.GeeASL)) / 2.3;
                    }
                    else
                    {
                        TWR = stagetwr;
                    }
                    break;
                }
            }
            if (TWR > 1.2)
            {
                Log("First guess for TWR > 1.2 {0:0.00}", TWR);
                TWR -= 1.2;
                if (!TurnAngle.locked)
                {
                    TurnAngle = Mathf.Clamp((float)(10 + TWR * 5), 10, 80);
                }
                if (!StartSpeed.locked)
                {
                    StartSpeed = Mathf.Clamp((float)(baseFactor * 10 - TWR * baseFactor * 3), baseFactor, baseFactor * 10);
                    if (StartSpeed < 10)
                    {
                        StartSpeed = 10;
                    }
                }
            }

            double guessTurn, guessSpeed;

            if (UseBest && launchdb.BestSettings(out guessTurn, out guessSpeed))
            {
                Log("UseBest && launchdb.BestSettings");
                if (!StartSpeed.locked)
                {
                    StartSpeed = guessSpeed;
                }
                if (!TurnAngle.locked)
                {
                    TurnAngle = guessTurn;
                }
            }
            else if (launchdb.GuessSettings(out guessTurn, out guessSpeed))
            {
                Log("GuessSettings");
                if (!StartSpeed.locked)
                {
                    StartSpeed = guessSpeed;
                }
                if (!TurnAngle.locked)
                {
                    TurnAngle = guessTurn;
                }
            }

            if (!APTimeStart.locked)
            {
                APTimeStart = 50;
            }
            if (!APTimeFinish.locked)
            {
                APTimeFinish = 50;
            }
            if (!Sensitivity.locked)
            {
                Sensitivity = 0.3;
            }
            if (!DestinationHeight.locked)
            {
                DestinationHeight  = vessel.StableOrbitHeight() + 10000;
                DestinationHeight /= 1000;
            }
            if (!Roll.locked)
            {
                Roll = 0;
            }
            if (!Inclination.locked)
            {
                Inclination = 0;
            }
            if (!PressureCutoff.locked)
            {
                PressureCutoff = 1200;
            }
            SaveParameters();
        }
Exemplo n.º 21
0
 public static float MaxAngle(Vessel vessel, GravityTurner turner)
 {
     float angle = 100000 / (float)turner.vesselState.dynamicPressure;
     float vertical = 90 + vessel.Pitch();
     angle = Mathf.Clamp(angle, 0, 35);
     if (angle > vertical)
         return vertical;
     return angle;
 }
Exemplo n.º 22
0
        public void Update()
        {
            if (!vessel.isActiveVessel)
            {
                return;
            }

            GravityTurner.DebugMessage += String.Format("StageController is active {0}, {1}\n", StageManager.CurrentStage, vessel.currentStage);

            //if autostage enabled, and if we are not waiting on the pad, and if there are stages left,
            //and if we are allowed to continue staging, and if we didn't just fire the previous stage
            if (!vessel.LiftedOff() || StageManager.CurrentStage <= 0 || StageManager.CurrentStage <= turner.autostageLimit ||
                Math.Abs(vesselState.time - lastStageTime) < turner.autostagePostDelay)
            {
                return;
            }

            GravityTurner.DebugMessage += "  Lifted off\n";

            //only decouple fairings if the dynamic pressure and altitude conditions are respected
            if (!topFairingDeployed)
            {
                Part fairing = GetTopmostFairing(vessel);
                bool fairingReadyToDeploy = false;
                if (fairing == null)
                {
                    GravityTurner.DebugMessage += "  No top fairing\n";
                }
                else
                {
                    GravityTurner.DebugMessage += "  Has top fairing\n";

                    fairingReadyToDeploy = (vesselState.dynamicPressure <turner.FairingPressure && Math.Abs(vesselState.dynamicPressure - vesselState.maxQ)> 0.1) && ((VesselState.isLoadedFAR && (vesselState.maxQ > vessel.mainBody.GetPressure(0) * 1000 / 5)) || (vesselState.maxQ > vessel.mainBody.atmospherePressureSeaLevel / 2));

                    if (fairingReadyToDeploy)
                    {
                        GravityTurner.DebugMessage += "  Fairing ready to be deployed\n";
                    }
                }

                if (fairing != null && fairing.IsUnfiredDecoupler() && fairingReadyToDeploy)
                {
                    topFairingDeployed = true;
                    fairing.DeployFairing();
                    GravityTurner.Log("Top Fairing deployed.");
                    GravityTurner.Log("  fairing pressure: {0:0.0}", turner.FairingPressure);
                    GravityTurner.Log("  dynamic pressure: {0:0.0}", vesselState.dynamicPressure);
                    GravityTurner.Log("  vessel maxQ: {0:0.0}", vesselState.maxQ);
                    GravityTurner.DebugMessage += "  Deploying top Fairing!!!\n";
                    return;
                }
            }

            //don't decouple active or idle engines or tanks
            List <int> burnedResources = FindBurnedResources();

            if (InverseStageDecouplesActiveOrIdleEngineOrTank(StageManager.CurrentStage - 1, vessel, burnedResources))
            {
                return;
            }

            GravityTurner.DebugMessage += "  active/idle Engine\n";

            //Don't fire a stage that will activate a parachute, unless that parachute gets decoupled:
            if (HasStayingChutes(StageManager.CurrentStage - 1, vessel))
            {
                return;
            }

            GravityTurner.DebugMessage += "  HasStayingChute\n";

            //only fire decouplers to drop deactivated engines or tanks
            bool firesDecoupler = InverseStageFiresDecoupler(StageManager.CurrentStage - 1, vessel);

            if (firesDecoupler && !InverseStageDecouplesDeactivatedEngineOrTank(StageManager.CurrentStage - 1, vessel))
            {
                return;
            }

            GravityTurner.DebugMessage += "  deactivated Engine/Tank\n";

            //When we find that we're allowed to stage, start a countdown (with a
            //length given by autostagePreDelay) and only stage once that countdown finishes,
            if (countingDown)
            {
                GravityTurner.DebugMessage += "  Counting down\n";
                if (Math.Abs(vesselState.time - stageCountdownStart) > turner.autostagePreDelay)
                {
                    GravityTurner.DebugMessage += "    Countdown finished\n";
                    if (firesDecoupler)
                    {
                        //if we decouple things, delay the next stage a bit to avoid exploding the debris
                        lastStageTime = vesselState.time;
                    }
                    GravityTurner.DebugMessage += "    ActivateNextStage\n";
                    GravityTurner.Log("Activate next stage.");
                    StageManager.ActivateNextStage();
                    countingDown = false;
                    GravityTurner.RestoreTimeWarp();
                }
            }
            else
            {
                GravityTurner.DebugMessage += "  Stage Countdown\n";
                GravityTurner.StoreTimeWarp();
                GravityTurner.StopSpeedup();
                stageCountdownStart = vesselState.time;
                countingDown        = true;
            }
        }
Exemplo n.º 23
0
        public StageController(GravityTurner turner)

        {
            this.turner = turner;
        }
Exemplo n.º 24
0
 public LaunchDB(GravityTurner inTurner)
 {
     turner = inTurner;
 }
Exemplo n.º 25
0
 public AttitudeController(GravityTurner turner)
 {
     this.turner = turner;
 }
Exemplo n.º 26
0
        public static float APThrottle(double timeToAP, GravityTurner turner)
        {
            Vessel vessel = GravityTurner.getVessel;

            GravityTurner.DebugMessage += "-\n";
            if (vessel.speed < turner.StartSpeed)
            {
                turner.Throttle.value = 1.0f;
            }
            else
            {
                if (timeToAP > vessel.orbit.timeToPe) // We're falling
                {
                    timeToAP = 0;
                }
                float diff = 0.1f * (float)Math.Abs(turner.HoldAPTime - timeToAP) * 0.5f;
                turner.TimeSpeed = (turner.PrevTime - timeToAP) / (Time.time - turner.lastTimeMeasured);
                if (Math.Abs(turner.TimeSpeed) < 0.02 && turner.PitchAdjustment == 0)
                {
                    turner.NeutralThrottle = (float)turner.Throttle.value;
                }
                if (Math.Abs(timeToAP - turner.HoldAPTime) < 0.1)
                {
                    if (turner.PitchAdjustment > 0)
                    {
                        turner.PitchAdjustment.value -= 0.1f;
                    }
                    else
                    {
                        turner.Throttle.force(turner.NeutralThrottle);
                    }
                }
                else if (timeToAP < turner.HoldAPTime)
                {
                    if (turner.Throttle.value >= 1 && (timeToAP < turner.PrevTime || (timeToAP - turner.HoldAPTime) / turner.TimeSpeed > 20))
                    {
                        turner.NeutralThrottle        = 1;
                        turner.PitchAdjustment.value += 0.1f;
                    }
                    turner.Throttle.value += diff;

                    if (0 < (timeToAP - turner.HoldAPTime) / turner.TimeSpeed && (timeToAP - turner.HoldAPTime) / turner.TimeSpeed < 20)  // We will reach desired AP time in <20 second
                    {
                        turner.PitchAdjustment.value -= 0.1f;
                    }
                }
                else if (timeToAP > turner.HoldAPTime)
                {
                    if (turner.PitchAdjustment > 0)
                    {
                        turner.PitchAdjustment.value -= 0.1f;
                    }
                    else
                    {
                        turner.Throttle.value -= diff;
                    }
                }
                if (Math.Abs(maxAoA) < Math.Abs(turner.vesselState.AoA))
                {
                    maxAoA = turner.vesselState.AoA;
                }

                GravityTurner.DebugMessage += String.Format("max Angle of Attack: {0:0.00}\n", maxAoA);
                GravityTurner.DebugMessage += String.Format("cur Angle of Attack: {0:0.00}\n", turner.vesselState.AoA.value);
                GravityTurner.DebugMessage += String.Format("-\n");
            }
            if (turner.PitchAdjustment < 0)
            {
                turner.PitchAdjustment.value = 0;
            }
            if (turner.PitchAdjustment > MaxAngle(vessel, turner))
            {
                turner.PitchAdjustment.value = MaxAngle(vessel, turner);
            }

            // We don't want to do any pitch correction during the initial lift
            if (vessel.ProgradePitch(true) < -45)
            {
                turner.PitchAdjustment.force(0);
            }

            turner.PrevTime         = vessel.orbit.timeToAp;
            turner.lastTimeMeasured = Time.time;
            if (turner.Throttle.value < turner.Sensitivity)
            {
                turner.Throttle.force(turner.Sensitivity);
            }
            if (turner.Throttle.value > 1)
            {
                turner.Throttle.force(1);
            }

            // calculate Yaw correction for inclination
            if (vessel.ProgradePitch(true) > -45 &&
                Math.Abs(turner.Inclination) > 2 &&
                turner.program != GravityTurner.AscentProgram.InLaunch)
            {
                float heading = (Mathf.Sign(turner.Inclination) * (float)turner.vesselState.orbitInclination.value - turner.Inclination);
                GravityTurner.DebugMessage += String.Format("  Heading: {0:0.00}\n", heading);
                heading *= 1.2f;
                if (Math.Abs(heading) < 0.3)
                {
                    heading = 0;
                }
                else if (Mathf.Abs(turner.YawAdjustment) > 0.1)
                {
                    heading = (turner.YawAdjustment * 7.0f + heading) / 8.0f;
                }

                if (Mathf.Abs(turner.YawAdjustment) > Mathf.Abs(heading) || turner.YawAdjustment == 0.0)
                {
                    turner.YawAdjustment = heading;
                }
                GravityTurner.DebugMessage += String.Format("  YawCorrection: {0:0.00}\n", turner.YawAdjustment);
            }
            else
            {
                turner.YawAdjustment = 0;
            }

            // Inrease the AP time if needed for SRB lifter stages
            if (vessel.HasActiveSRB() && vessel.orbit.timeToAp > turner.HoldAPTime && turner.TimeSpeed < 0)
            {
                double StopHeight = GravityTurner.getVessel.mainBody.atmosphereDepth;
                if (StopHeight <= 0)
                {
                    StopHeight = turner.DestinationHeight * 1000;
                }
                turner.APTimeStart  = (StopHeight * vessel.orbit.timeToAp - vessel.altitude * turner.APTimeFinish) / (StopHeight - vessel.altitude);
                turner.APTimeStart *= 0.99; // We want to be just a bit less than what we calculate, so we don't stay throttled up
            }

            return((float)turner.Throttle.value);
        }
Exemplo n.º 27
0
        private void fly(FlightCtrlState s)
        {
            if (!Launching)
            {
                Kill();
                return;
            }
            DebugMessage = "";
            Vessel vessel = getVessel;

            if (program != AscentProgram.InCoasting && vessel.orbit.ApA > DestinationHeight * 1000 && vessel.altitude < vessel.StableOrbitHeight())
            {
                CalculateLosses(getVessel);
                // save launch, ignoring losses due to coasting losses, but so we get results earlier
                launchdb.RecordLaunch();
                launchdb.Save();
                program       = AscentProgram.InCoasting;
                DebugMessage += "In Coasting program\n";
                Throttle.force(0);
                Log("minorbit {0}, {1}", vessel.mainBody.minOrbitalDistance, vessel.StableOrbitHeight());
                // time warp to speed up things (if enabled)
                ApplySpeedup(2);
            }
            else if (vessel.orbit.ApA > DestinationHeight * 1000 && vessel.altitude > vessel.StableOrbitHeight())
            {
                Log("minorbit {0}, {1}", vessel.mainBody.minOrbitalDistance, vessel.StableOrbitHeight());
                program = AscentProgram.InCircularisation;
                StopSpeedup();
                GravityTurner.Log("Saving launchDB");
                launchdb.RecordLaunch();
                launchdb.Save();
                Kill();
                DebugMessage += "In Circularisation program\n";
                if (mucore.Initialized)
                {
                    program = AscentProgram.InCircularisation;
                    mucore.CircularizeAtAP();
                }

                button.SetFalse();
            }
            else
            {
                double minInsertionHeight = vessel.mainBody.atmosphere ? vessel.StableOrbitHeight() / 4 : Math.Max(DestinationHeight * 667, vessel.StableOrbitHeight() * 0.667);

                if (EnableStageManager && stage != null)
                {
                    stage.Update();
                }

                if (vessel.orbit.ApA < DestinationHeight * 1000)
                {
                    s.mainThrottle = Calculations.APThrottle(vessel.orbit.timeToAp, this);
                }
                else
                {
                    s.mainThrottle = 0;
                }
                if (program == AscentProgram.InInitialPitch && PitchSet)
                {
                    if (vessel.ProgradePitch() + 90 >= TurnAngle - 0.1)
                    {
                        delayUT = double.NaN;
                        // continue any previous timewarp
                        RestoreTimeWarp();
                        ApplySpeedup(1);
                        program       = AscentProgram.InTurn;
                        DebugMessage += "Turning now\n";
                    }
                }
                if (vessel.speed < StartSpeed)
                {
                    DebugMessage += "In Launch program\n";
                    program       = AscentProgram.InLaunch;
                    if (vesselState.altitudeBottom > vesselState.vesselHeight)
                    {
                        attitude.attitudeTo(Quaternion.Euler(-90, LaunchHeading(vessel), 0) * RollRotation(), AttitudeReference.SURFACE_NORTH, this);
                    }
                    else
                    {
                        attitude.attitudeTo(Quaternion.Euler(-90, 0, vesselState.vesselHeading), AttitudeReference.SURFACE_NORTH, this);
                    }
                }
                else if (program == AscentProgram.InLaunch || program == AscentProgram.InInitialPitch)
                {
                    if (!PitchSet)
                    {
                        // remember and stop timewarp for pitching
                        StoreTimeWarp();
                        StopSpeedup();
                        PitchSet = true;
                        program  = AscentProgram.InInitialPitch;
                        delayUT  = Planetarium.GetUniversalTime();
                    }
                    DebugMessage += "In Pitch program\n";
                    double diffUT   = Planetarium.GetUniversalTime() - delayUT;
                    float  newPitch = Mathf.Min((float)(((double)TurnAngle * diffUT) / 5.0d + 2.0d), TurnAngle);
                    double pitch    = (90d - vesselState.vesselPitch + vessel.ProgradePitch() + 90) / 2;
                    attitude.attitudeTo(Quaternion.Euler(-90 + newPitch, LaunchHeading(vessel), 0) * RollRotation(), AttitudeReference.SURFACE_NORTH, this);
                    DebugMessage += String.Format("TurnAngle: {0:0.00}\n", TurnAngle.value);
                    DebugMessage += String.Format("Target pitch: {0:0.00}\n", newPitch);
                    DebugMessage += String.Format("Current pitch: {0:0.00}\n", pitch);
                    DebugMessage += String.Format("Prograde pitch: {0:0.00}\n", vessel.ProgradePitch() + 90);
                }
                else if (vesselState.dynamicPressure > vesselState.maxQ * 0.5 || vesselState.dynamicPressure > PressureCutoff || vessel.altitude < minInsertionHeight)
                { // Still ascending, or not yet below the cutoff pressure or below min insertion heigt
                    DebugMessage += "In Turn program\n";
                    attitude.attitudeTo(Quaternion.Euler(vessel.ProgradePitch() - PitchAdjustment, LaunchHeading(vessel), 0) * RollRotation(), AttitudeReference.SURFACE_NORTH, this);
                }
                else
                {
                    // did we reach the desired inclination?
                    DebugMessage += String.Format("Insertion program\n");
                    Quaternion q = Quaternion.Euler(0 - PitchAdjustment, YawAdjustment, Roll);
                    // smooth out change from surface to orbital prograde
                    if (program != AscentProgram.InInsertion && program != AscentProgram.InCoasting)
                    {
                        // start timer
                        if (Double.IsNaN(delayUT))
                        {
                            // slow down timewarp
                            delayUT = Planetarium.GetUniversalTime();
                            StoreTimeWarp();
                            StopSpeedup();
                            // switch NavBall UI
                            FlightGlobals.SetSpeedMode(FlightGlobals.SpeedDisplayModes.Orbit);
                        }
                        double diffUT = Planetarium.GetUniversalTime() - delayUT;
                        //attitude.attitudeTo(q, AttitudeReference.ORBIT, this);
                        q.x = (attitude.lastAct.x * 8.0f + q.x) / 9.0f;
                        if (diffUT > 10 || (attitude.lastAct.x > 0.02 && diffUT > 2.0))
                        {
                            program = AscentProgram.InInsertion;
                            delayUT = double.NaN;
                            RestoreTimeWarp();
                            ApplySpeedup(2);
                        }
                    }
                    attitude.attitudeTo(q, AttitudeReference.ORBIT, this);
                }
                attitude.enabled = true;
                attitude.Drive(s);
                CalculateLosses(getVessel);
                DebugMessage += "-";
            }
        }
Exemplo n.º 28
0
 public AttitudeController(GravityTurner turner)
 {
     this.turner = turner;
 }