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; }
protected override void Reset() { base.Reset(); update_limits(); ToOrbit = null; Target = Vector3d.zero; stage = Stage.None; }
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; }
public void ToOrbitCallback(Multiplexer.Command cmd) { switch (cmd) { case Multiplexer.Command.Resume: if (!check_patched_conics()) { return; } ToOrbit = new ToOrbitExecutor(TCA); ToOrbit.CorrectOnlyAltitude = true; ToOrbit.Target = Target; break; case Multiplexer.Command.On: Reset(); if (!check_patched_conics()) { return; } Vector3d hVdir; if (TargetOrbit.Inclination.Range > 1e-5f) { var angle = Utils.Clamp((TargetOrbit.Inclination.Value - TargetOrbit.Inclination.Min) / TargetOrbit.Inclination.Range * 180, 0, 180); if (TargetOrbit.DescendingNode) { angle = -angle; } hVdir = QuaternionD.AngleAxis(angle, VesselOrbit.pos) * Vector3d.Cross(Vector3d.forward, VesselOrbit.pos).normalized; } else { hVdir = Vector3d.Cross(VesselOrbit.pos, Body.orbit.vel).normalized; } if (TargetOrbit.RetrogradeOrbit) { hVdir *= -1; } var ApR0 = Utils.ClampH(ApR, MinPeR + ORB.RadiusOffset); var ascO = AscendingOrbit(ApR0, hVdir, Mathf.Lerp(ORB.MinSlope, ORB.MaxSlope, TargetOrbit.Slope.Value / 100)); Target = ascO.getRelativePositionAtUT(VSL.Physics.UT + ascO.timeToAp); stage = Stage.Start; goto case Multiplexer.Command.Resume; case Multiplexer.Command.Off: Reset(); break; } }
protected override void reset() { base.reset(); update_limits(); ToOrbit = null; Target = Vector3d.zero; stage = Stage.None; }
public void ToOrbitCallback(Multiplexer.Command cmd) { switch(cmd) { case Multiplexer.Command.Resume: if(!check_patched_conics()) return; ToOrbit = new ToOrbitExecutor(TCA); ToOrbit.CorrectOnlyAltitude = true; ToOrbit.Target = Target; break; case Multiplexer.Command.On: reset(); if(!check_patched_conics()) return; Vector3d hVdir; if(TargetOrbit.Inclination.Range > 1e-5f) { var angle = Utils.Clamp((TargetOrbit.Inclination.Value-TargetOrbit.Inclination.Min)/TargetOrbit.Inclination.Range*180, 0, 180); if(TargetOrbit.DescendingNode) angle = -angle; hVdir = QuaternionD.AngleAxis(angle, VesselOrbit.pos) * Vector3d.Cross(Vector3d.forward, VesselOrbit.pos).normalized; } else hVdir = Vector3d.Cross(VesselOrbit.pos, Body.orbit.vel).normalized; if(TargetOrbit.RetrogradeOrbit) hVdir *= -1; var ascO = AscendingOrbit(Utils.ClampH(ApR, MinPeR+ORB.RadiusOffset), hVdir, ORB.LaunchTangentK); Target = ascO.getRelativePositionAtUT(VSL.Physics.UT+ascO.timeToAp); stage = Stage.Start; goto case Multiplexer.Command.Resume; case Multiplexer.Command.Off: reset(); break; } }
void resume_to_orbit() { ToOrbit = new ToOrbitExecutor(TCA); ToOrbit.Target = ToOrbitTarget; }