public void UpdateState() { //update onPlanet state var on_planet = _OnPlanet(); var in_orbit = _InOrbit(); if (on_planet != OnPlanet) { CFG.EnginesProfiles.OnPlanetChanged(on_planet); if (!on_planet) { if (CFG.BlockThrottle) { var THR = TCA.GetModule <ThrottleControl>(); if (THR != null) { THR.Throttle = 0f; } } CFG.DisableVSC(); CFG.Nav.Off(); CFG.HF.Off(); } } OnPlanet = on_planet; InOrbit = in_orbit; IsActiveVessel = vessel != null && vessel == FlightGlobals.ActiveVessel; }
void to_orbit() { if (!LiftoffPossible) { return; } //calculate target vector var ApR = Math.Max(MinPeR, (TargetOrbit.PeR + TargetOrbit.ApR) / 2); var hVdir = Vector3d.Cross(TargetOrbit.GetOrbitNormal(), VesselOrbit.pos).normalized; var ascO = AscendingOrbit(ApR, hVdir, GLB.ORB.LaunchSlope); //tune target vector ToOrbit = new ToOrbitExecutor(TCA); ToOrbit.LaunchUT = VSL.Physics.UT; ToOrbit.ApAUT = VSL.Physics.UT + ascO.timeToAp; ToOrbit.Target = ToOrbitIniApV = ascO.getRelativePositionAtUT(ToOrbit.ApAUT); if (VSL.LandedOrSplashed) { double TTR; do { TTR = correct_launch(); }while(Math.Abs(TTR) > 1); } //setup launch CFG.DisableVSC(); stage = VSL.LandedOrSplashed? Stage.Launch : Stage.ToOrbit; }
public void ManeuverCallback(Multiplexer.Command cmd) { switch (cmd) { case Multiplexer.Command.Resume: case Multiplexer.Command.On: ManeuverStage = Stage.WAITING; if (!TCAScenario.HavePatchedConics) { Status("yellow", "WARNING: maneuver nodes are not yet available. Upgrade the Tracking Station."); CFG.AP1.Off(); return; } if (!VSL.HasManeuverNode) { CFG.AP1.Off(); return; } VSL.Controls.StopWarp(); CFG.AT.On(Attitude.ManeuverNode); update_maneuver_node(); THR.Throttle = 0; CFG.DisableVSC(); break; case Multiplexer.Command.Off: VSL.Controls.StopWarp(); if (!CFG.WarpToNode && TimeWarp.CurrentRateIndex > 0) { TimeWarp.SetRate(0, false); } CFG.AT.On(Attitude.KillRotation); Reset(); break; } }
public void PreUpdateState(FlightCtrlState s) { //update control info PreUpdateControls = s; IsActiveVessel = vessel != null && vessel == FlightGlobals.ActiveVessel; HasUserInput = !Mathfx.Approx(PreUpdateControls.pitch, PreUpdateControls.pitchTrim, 0.01f) || !Mathfx.Approx(PreUpdateControls.roll, PreUpdateControls.rollTrim, 0.01f) || !Mathfx.Approx(PreUpdateControls.yaw, PreUpdateControls.yawTrim, 0.01f); AutopilotDisabled = HasUserInput; //update onPlanet state var on_planet = vessel.OnPlanet(); var in_orbit = vessel.InOrbit(); if(on_planet != OnPlanet) { if(CFG.Enabled) CFG.EnginesProfiles.OnPlanetChanged(on_planet); if(!on_planet) { if(CFG.BlockThrottle) { var THR = TCA.GetModule<ThrottleControl>(); if(THR != null) THR.Throttle = 0f; } CFG.DisableVSC(); CFG.Nav.Off(); CFG.HF.Off(); if(IsActiveVessel && TCAGui.Instance.ORB != null) TCAGui.Instance.ActiveTab = TCAGui.Instance.ORB; } } OnPlanet = on_planet; InOrbit = in_orbit; }
public void ManeuverCallback(Multiplexer.Command cmd) { switch (cmd) { case Multiplexer.Command.Resume: case Multiplexer.Command.On: if (!TCAScenario.HavePatchedConics) { Status("yellow", "WARNING: maneuver nodes are not yet available. Upgrade the Tracking Station."); CFG.AP1.Off(); return; } if (!VSL.HasManeuverNode) { CFG.AP1.Off(); return; } VSL.Controls.StopWarp(); CFG.AT.On(Attitude.ManeuverNode); Node = Solver.maneuverNodes[0]; if (VSL.Engines.MaxDeltaV < (float)Node.DeltaV.magnitude) { Status("yellow", "WARNING: there may be not enough propellant for the maneuver"); } THR.Throttle = 0; CFG.DisableVSC(); break; case Multiplexer.Command.Off: TimeWarp.SetRate(0, false); CFG.AT.On(Attitude.KillRotation); reset(); break; } }
public bool Liftoff() { UpdateTargetPosition(); VSL.Engines.ActivateEngines(); VSL.OnPlanetParams.ActivateLaunchClamps(); if (VSL.VerticalSpeed.Absolute / VSL.Physics.G < MinClimbTime) { Status("Liftoff..."); CFG.DisableVSC(); CFG.VTOLAssistON = true; THR.Throttle = 1; return(true); } StartGravityTurn(); return(false); }
public virtual bool Liftoff() { UpdateTargetPosition(); VSL.Engines.ActivateEngines(); VSL.OnPlanetParams.ActivateLaunchClamps(); if (VSL.VerticalSpeed.Absolute / VSL.Physics.G < Config.INST.MinClimbTime) { Status("Liftoff..."); CFG.DisableVSC(); CFG.VTOLAssistON = true; THR.Throttle = max_G_throttle(); CFG.AT.OnIfNot(Attitude.Custom); var vel = VSL.Physics.Up; vel = tune_needed_vel(vel, vel, 1); ATC.SetThrustDirW(vel); return(true); } StartGravityTurn(); return(false); }
public bool Liftoff() { UpdateTargetPosition(); VSL.Engines.ActivateEngines(); if (VSL.VerticalSpeed.Absolute / VSL.Physics.G < MinClimbTime) { Status("Liftoff..."); CFG.DisableVSC(); CFG.VTOLAssistON = true; THR.Throttle = 1; return(true); } GravityTurnStart = VSL.Altitude.Absolute; ApoapsisReached = false; GearAction.Run(); CFG.VTOLAssistON = false; CFG.StabilizeFlight = false; CFG.HF.Off(); return(false); }
public override void Disable() { CFG.DisableVSC(); }
protected override void Update() { if (!IsActive) { CFG.AP2.OffIfOn(Autopilot2.BallisticJump); return; } if (landing) { do_land(); return; } switch (stage) { case Stage.Start: CFG.HF.OnIfNot(HFlight.Stop); CFG.AltitudeAboveTerrain = true; CFG.VF.OnIfNot(VFlight.AltitudeControl); if (VSL.LandedOrSplashed || VSL.Altitude.Relative < StartAltitude) { CFG.DesiredAltitude = StartAltitude; } else { CFG.DesiredAltitude = VSL.Altitude.Relative; } if (VSL.Altitude.Relative > StartAltitude - 5) { compute_initial_trajectory(); } else { Status("Gaining initial altitude..."); } break; case Stage.Compute: if (!trajectory_computed()) { break; } var obst = obstacle_ahead(trajectory); if (obst > 0) { StartAltitude += (float)obst + BJ.ObstacleOffset; stage = Stage.Start; } else if (check_initial_trajectory()) { accelerate(); } else { stage = Stage.Wait; } break; case Stage.Wait: if (!string.IsNullOrEmpty(TCAGui.StatusMessage)) { break; } accelerate(); break; case Stage.Accelerate: if (!VSL.HasManeuverNode) { CFG.AP2.Off(); break; } if (VSL.Controls.AlignmentFactor > 0.9 || !CFG.VSCIsActive) { CFG.DisableVSC(); if (!Executor.Execute(VSL.FirstManeuverNode.GetBurnVector(VesselOrbit), 10)) { fine_tune_approach(); } Status("white", "Accelerating..."); } break; case Stage.CorrectTrajectory: if (!trajectory_computed()) { break; } add_correction_node_if_needed(); stage = Stage.Coast; break; case Stage.Coast: var ap_ahead = VesselOrbit.ApAhead(); if (CFG.AP1[Autopilot1.Maneuver]) { if (ap_ahead) { Status("Correcting trajectory..."); break; } } Status("Coasting..."); if (ap_ahead && !correct_trajectory()) { break; } stage = Stage.None; start_landing(); break; } }
protected override void Update() { if (landing) { do_land(); return; } switch (stage) { case Stage.Start: VSC_ON(HFlight.Stop); if (VSL.LandedOrSplashed || VSL.Altitude.Relative < StartAltitude) { CFG.DesiredAltitude = StartAltitude; } else { CFG.DesiredAltitude = VSL.Altitude.Relative; } if (!VSL.LandedOrSplashed) { compute_initial_trajectory(); } break; case Stage.GainAltitude: Status("Gaining altitude..."); VSC_ON(HFlight.Level); if (VSL.Altitude.Relative > CFG.DesiredAltitude - 10) { compute_initial_trajectory(); } break; case Stage.Compute: double obstacle; if (!trajectory_computed()) { break; } if (find_biggest_obstacle_ahead(BJ.StartAltitude, out obstacle)) { break; } if (obstacle > 0) { StartAltitude += (float)obstacle + BJ.ObstacleOffset; CFG.DesiredAltitude = StartAltitude; stage = Stage.GainAltitude; } else if (VSL.Altitude.Relative < BJ.StartAltitude - 10) { stage = Stage.GainAltitude; } else if (check_initial_trajectory()) { accelerate(); } else { stage = Stage.Wait; } break; case Stage.Wait: if (!string.IsNullOrEmpty(TCAGui.StatusMessage)) { break; } accelerate(); break; case Stage.Accelerate: CFG.AT.OnIfNot(Attitude.Custom); var dV = (trajectory.Orbit.GetFrameVelAtUT(trajectory.StartUT) - VSL.orbit.GetFrameVelAtUT(trajectory.StartUT)).xzy; if (VSL.Controls.AlignmentFactor > 0.9 || !CFG.VSCIsActive) { CFG.DisableVSC(); var dVv = -VSL.Altitude.Absolute;//Vector3d.Dot(dV, VSL.Physics.Up); if (RAD != null) { var dH = VSL.Altitude.Relative - VSL.Altitude.Ahead - VSL.Geometry.H; if (dH < 0) { dVv -= dH / RAD.TimeAhead * 1.1f; } } if (dVv > 0) { fall_correction.I = BJ.FallCorrectionPID.I * Utils.ClampL(100 / VSL.Altitude.Relative, 1); fall_correction.Update(-VSL.Altitude.Absolute); } else { fall_correction.IntegralError *= Utils.ClampL(1 - fall_correction.I / 10 * TimeWarp.fixedDeltaTime, 0); fall_correction.Update(0); } // Log("dV {}, dVv {}, correction {}, I {}", dV, dVv, fall_correction.Action, fall_correction.I);//debug if (Executor.Execute(dV + fall_correction * VSL.Physics.Up, 10)) { Status("white", "Accelerating: <color=yellow><b>{0}</b> m/s</color>", (dV.magnitude - 10).ToString("F1")); } else { fine_tune_approach(); } } else { ATC.SetThrustDirW(-dV); } break; case Stage.CorrectTrajectory: VSL.Info.Countdown = landing_trajectory.BrakeStartPoint.UT - VSL.Physics.UT - ManeuverOffset; if (VSL.Info.Countdown > 0) { warp_to_coundown(); if (!trajectory_computed()) { break; } add_correction_node_if_needed(); stage = Stage.Coast; } else { stage = Stage.None; start_landing(); } break; case Stage.Coast: if (!coast_to_start()) { stage = Stage.None; } break; } }