protected override void Update() { if (!VSL.HasManeuverNode || Node != Solver.maneuverNodes[0] || NodeCB != Node.patch.referenceBody) { Message("Maneuver has been interrupted."); Disable(); return; } if (!VSL.Engines.HaveThrusters && !VSL.Engines.HaveNextStageEngines) { Message("Out of fuel"); Disable(); return; } //update the node NodeDeltaV = (TargetOrbit.GetFrameVelAtUT(NodeUT) - VSL.orbit.GetFrameVelAtUT(NodeUT)).xzy; Executor.ThrustWhenAligned = ThrustWhenAligned; ThrustWhenAligned = true; if (Executor.Execute(NodeDeltaV, MinDeltaV, StartCondition)) { return; } ManeuverStage = Stage.FINISHED; Node.RemoveSelf(); Disable(); }
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; }
RendezvousTrajectory new_trajectory(double StartUT, double transfer_time) { var solver = new LambertSolver(VesselOrbit, TargetOrbit.getRelativePositionAtUT(StartUT + transfer_time), StartUT); var dV = solver.dV4Transfer(transfer_time); return(new RendezvousTrajectory(VSL, dV, StartUT, CFG.Target, MinPeR, transfer_time)); }
void start_orbit() { ToOrbit = null; var dV = Vector3d.zero; var old = VesselOrbit; var StartUT = VSL.Physics.UT + CorrectionOffset; CFG.BR.OffIfOn(BearingMode.Auto); update_trajectory(); if (VesselOrbit.PeR < MinPeR) { StartUT = Math.Min(trajectory.AtTargetUT, VSL.Physics.UT + (VesselOrbit.ApAhead()? VesselOrbit.timeToAp : CorrectionOffset)); if (trajectory.DistanceToTarget < REN.ApproachThreshold * 2 && StartUT.Equals(trajectory.AtTargetUT)) { //approach is close enough to directly match orbits match_orbits(); return; } var transfer_time = Utils.ClampL(TargetOrbit.period * (0.25 - AngleDelta(VesselOrbit, TargetOrbit, StartUT) / 360), 1); var solver = new LambertSolver(VesselOrbit, TargetOrbit.getRelativePositionAtUT(StartUT + transfer_time), StartUT); dV = solver.dV4Transfer(transfer_time); var trj = new RendezvousTrajectory(VSL, dV, StartUT, CFG.Target, MinPeR, transfer_time); if (!dV.IsZero() && !trj.KillerOrbit) { //approach orbit is possible compute_start_orbit(StartUT); return; } //starting from circular orbit and proceeding to TTR fitting... StartUT = VesselOrbit.ApAhead()? VSL.Physics.UT + VesselOrbit.timeToAp : VSL.Physics.UT + CorrectionOffset; dV = dV4C(old, hV(StartUT), StartUT); old = NewOrbit(old, dV, StartUT); } else if (trajectory.RelDistanceToTarget < REN.CorrectionStart || TargetLoaded) { if (trajectory.RelDistanceToTarget > REN.CorrectionStart / 4 && !TargetLoaded) { fine_tune_approach(); } else { match_orbits(); } return; } //compute orbit with desired TTR and activate maneuver autopilot dV += dV4TTR(old, TargetOrbit, REN.MaxTTR, REN.MaxDeltaV, MinPeR, StartUT); if (!dV.IsZero()) { add_node(dV, StartUT); CFG.AP1.On(Autopilot1.Maneuver); } stage = Stage.StartOrbit; }
double correct_launch(bool allow_wait = true) { var TTR = AngleDelta(TargetOrbit, ToOrbit.Target, ToOrbit.ApAUT) / 360 * TargetOrbit.period; ToOrbit.LaunchUT += TTR; if (allow_wait && ToOrbit.LaunchUT - VSL.Physics.UT <= 0) { ToOrbit.LaunchUT += TargetOrbit.period; } ToOrbit.ApAUT = ToOrbit.LaunchUT + AtmoSim.FromSurfaceTTA(VSL, ToOrbit.TargetR - Body.Radius, ToOrbit.ArcDistance, GLB.ORB.GTurnCurve, Vector3d.Dot(SurfaceVel, Vector3d.Exclude(VesselOrbit.pos, ToOrbit.Target - VesselOrbit.pos).normalized)); ToOrbit.Target = QuaternionD.AngleAxis((VSL.Physics.UT - ToOrbit.LaunchUT) / Body.rotationPeriod * 360, Body.angularVelocity.xzy) * ToOrbitIniApV.normalized * TargetOrbit.getRelativePositionAtUT(ToOrbit.ApAUT).magnitude; // LogF("TTR: {}, LaunchT {}, ApAT {}", TTR, ToOrbit.LaunchUT-VSL.Physics.UT, ToOrbit.ApAUT-ToOrbit.LaunchUT);//debug return(TTR); }
private void update_node_deltaV() => NodeDeltaV = (TargetOrbit.GetFrameVelAtUT(NodeUT) - VSL.orbit.GetFrameVelAtUT(NodeUT)).xzy;