public void Launch() { StageController.topFairingDeployed = false; if (StageManager.CurrentStage == StageManager.StageCount) { StageManager.ActivateNextStage(); } InitializeNumbers(getVessel); getVessel.OnFlyByWire += new FlightInputCallback(fly); Launching = true; PitchSet = false; DebugShow = false; program = AscentProgram.Landed; SaveParameters(); LaunchName = new string(getVessel.vesselName.ToCharArray()); LaunchBody = getVessel.mainBody; }
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 += "-"; } }