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;
        }
Example #2
0
 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;
        }
Example #4
0
        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;
 }