protected override bool check_target()
        {
            if (!base.check_target())
            {
                return(false);
            }
            if (VesselOrbit.PeR > Body.Radius)
            {
                Status("yellow", "Cannot perform <b>Ballistic Jump</b> from orbit.\n" +
                       "Use <b>Land at Target</b> instead.");
                return(false);
            }
            //compute initial orbit estimation using LambertSolver
            var solver = new LambertSolver(VesselOrbit, CFG.Target.RelOrbPos(Body), VSL.Physics.UT);
            var dV     = solver.dV4TransferME();

            if (Vector3d.Dot(VesselOrbit.vel + dV, VesselOrbit.pos) < 0)
            {
                dV = -2 * VesselOrbit.vel - dV;
            }
            var trj = new LandingTrajectory(VSL, dV, VSL.Physics.UT, CFG.Target, TargetAltitude, false);

            if (trj.TransferTime < TRJ.ManeuverOffset)
            {
                Status("yellow", "The target is too close for the jump.\n" +
                       "Use <b>Go To</b> instead.");
                return(false);
            }
            return(true);
        }
Exemple #2
0
        protected override bool check_target()
        {
            if (!base.check_target())
            {
                return(false);
            }
            if (VesselOrbit.PeR > Body.Radius)
            {
                Status("yellow", "Cannot perform <b>Ballistic Jump</b> from orbit.\n" +
                       "Use <b>Land at Target</b> instead.");
                return(false);
            }
            //compute initial orbit estimation using LambertSolver
            var dV  = compute_intial_jump_velocity() - VesselOrbit.vel;
            var trj = new LandingTrajectory(VSL, dV, VSL.Physics.UT, CFG.Target, TargetAltitude, false);

            if (trj.TransferTime < ManeuverOffset)
            {
                #if DEBUG
                Log("Too close jump trajectory: {}", trj);
                #endif
                Status("yellow", "The target is too close for the jump.\n" +
                       "Use <b>Go To</b> instead.");
                return(false);
            }
            return(true);
        }
Exemple #3
0
        protected LandingTrajectory fixed_Ecc_orbit(LandingTrajectory old, LandingTrajectory best, ref Vector3d NodeDeltaV, double ecc)
        {
            double StartUT;
            double targetAlt;

            if (old != null)
            {
                targetAlt = old.TargetAltitude;
                StartUT   = AngleDelta2StartUT(old, Math.Abs(VesselOrbit.inclination) <= 45 ? old.DeltaLon : old.DeltaLat,
                                               TRJ.ManeuverOffset, VesselOrbit.period, VesselOrbit.period);
                NodeDeltaV += PlaneCorrection(old);
                if (old.BrakeEndDeltaAlt < LTRJ.FlyOverAlt)                //correct fly-over altitude
                {
                    NodeDeltaV += new Vector3d((LTRJ.FlyOverAlt - old.BrakeEndDeltaAlt) / 100, 0, 0);
                }
            }
            else
            {
                StartUT   = VSL.Physics.UT + TRJ.ManeuverOffset;
                targetAlt = TargetAltitude;
            }
            return(new LandingTrajectory(VSL,
                                         dV4Ecc(VesselOrbit, ecc, StartUT, Body.Radius * 0.9) +
                                         Node2OrbitDeltaV(NodeDeltaV, StartUT),
                                         StartUT, CFG.Target, targetAlt));
        }
Exemple #4
0
            IEnumerable <LandingTrajectory> optimize_DeltaFi()
            {
                var dFi     = ScanDeltaFi? 10.0 * Math.Sign(Best.DeltaFi) : Best.DeltaFi;
                var fi      = 0.0;
                var bestFi  = fi;
                var cur     = Best;
                var scanned = !ScanDeltaFi;

                while (Math.Abs(dFi) > 1e-3)
                {
                    cur = new LandingTrajectory(m.VSL,
                                                (QuaternionD.AngleAxis(fi + angle, m.VesselOrbit.getRelativePositionAtUT(startUT)) * dir) * velocity -
                                                m.VesselOrbit.getOrbitalVelocityAtUT(startUT),
                                                startUT, m.CFG.Target, cur.TargetAltitude);
                    if (cur.DistanceToTarget < Best.DistanceToTarget)
                    {
                        Best   = cur;
                        bestFi = fi;
                    }
                    else if (scanned || Math.Abs(fi + angle) > 120)
                    {
                        dFi    /= -2.1;
                        fi      = bestFi;
                        scanned = true;
                    }
                    fi += dFi;
//                    Utils.Log("D {}, fi {} ({}), dfi {}, DeltaFi {}, trajectory {}",
//                              cur.DistanceToTarget, fi, fi+angle, dFi, cur.DeltaFi, cur);//debug
                    yield return(cur);
                }
                angle += bestFi;
            }
Exemple #5
0
            IEnumerable <LandingTrajectory> optimize_DeltaV()
            {
                var dV = dR2dV(Best.DeltaR);
//                Utils.Log("dR {}, Angle2Tgt {}, G {}", Best.DeltaR, m.CFG.Target.AngleTo(m.VSL), m.Body.GeeASL);//debug
                var bestV = velocity;
                var dVEnd = Math.Abs(dV) / 100;
                LandingTrajectory cur = Best, prev;

                while (Math.Abs(dV) > dVEnd)
                {
                    prev = cur;
                    cur  = new LandingTrajectory(m.VSL,
                                                 (QuaternionD.AngleAxis(angle, m.VesselOrbit.getRelativePositionAtUT(startUT)) * dir) * velocity -
                                                 m.VesselOrbit.getOrbitalVelocityAtUT(startUT),
                                                 startUT, m.CFG.Target, cur.TargetAltitude);
                    if (cur.DistanceToTarget < Best.DistanceToTarget)
                    {
                        Best  = cur;
                        bestV = velocity;
                    }
                    if (cur.DistanceToTarget > prev.DistanceToTarget)
                    {
                        dV      /= -2.1;
                        velocity = bestV;
                    }
                    velocity += dV;
//                    Utils.Log("D {}, dR {}, dV {}, V {}", cur.DistanceToTarget, cur.DeltaR, dV, velocity);//debug
                    yield return(cur);
                }
                velocity = bestV;
            }
Exemple #6
0
            public override IEnumerator <LandingTrajectory> GetEnumerator()
            {
                Best = newT(m.VSL.Physics.UT + m.CorrectionOffset + TimeWarp.CurrentRate + 1, 0, Vector3d.zero);
                LandingTrajectory cur = null;

                while (continue_calculation(cur, Best))
                {
                    cur = Best;
                    var ddV = Utils.ClampSignedL(dR2dV(Best.DeltaR), 1);
                    foreach (var t in optimize_prograde(ddV))
                    {
                        yield return(t);
                    }
                    var dI = Utils.Clamp((float)Best.DeltaFi / 2, -1, 1);
                    if (Best.ManeuverDuration <= 0)
                    {
                        continue;
                    }
                    var dV = m.hV(Best.StartUT).normalized *prograde_dV;
                    foreach (var t in optimize_inclination(dI, dV))
                    {
                        yield return(t);
                    }
                }
            }
Exemple #7
0
            public IEnumerator <LandingTrajectory> GetEnumerator()
            {
//                m.Log("Calculating initial orbit eccentricity...");//debug
                var tPos = m.CFG.Target.OrbPos(m.Body);
                var UT   = m.VSL.Physics.UT +
                           TrajectoryCalculator.AngleDelta(m.VesselOrbit, tPos, m.VSL.Physics.UT) / 360 * m.VesselOrbit.period;

                if (UT < m.VSL.Physics.UT)
                {
                    UT += m.VesselOrbit.period;
                }
                var vPos   = m.VesselOrbit.getRelativePositionAtUT(UT);
                var vVel   = m.VesselOrbit.getOrbitalVelocityAtUT(UT);
                var incl   = Math.Abs(90 - Utils.Angle2(tPos, m.VesselOrbit.GetOrbitNormal()));
                var ini_dV = TrajectoryCalculator.dV4Pe(m.VesselOrbit, (m.Body.Radius + m.TargetAltitude * 0.9), UT);

                ini_dV = QuaternionD.AngleAxis(incl, vPos) * (ini_dV + vVel);
                var dir  = -ini_dV.normalized;
                var maxV = ini_dV.magnitude;

                ini_dV -= vVel;
                Best    = new LandingTrajectory(m.VSL, ini_dV, UT, m.CFG.Target, m.TargetAltitude);
                yield return(Best);

                //if there's not enough fuel, just go with the smallest maneuver possible
                if (Best.FullManeuver)
                {
                    //search for the best trajectory using current comparer
                    var start = Best;
                    var bestV = 0.0;
                    var dV    = maxV / 10;
                    var V     = dV;
                    while (Math.Abs(dV) > TrajectoryCalculator.C.dVtol)
                    {
                        var cur = new LandingTrajectory(m.VSL, start.ManeuverDeltaV + dir * V, start.StartUT, m.CFG.Target, start.TargetAltitude);
//                        m.Log("V {}, dV {}, is better {}\ncur {}\nbest {}",
//                              V, dV, comparer.isBetter(cur, Best), cur, Best);//debug
                        if (comparer.isBetter(cur, Best))
                        {
                            Best  = cur;
                            bestV = V;
                        }
                        V += dV;
                        if (V < 0 || V > maxV || cur != Best)
                        {
                            dV /= -2.1;
                            V   = bestV;
                        }
                        yield return(cur);
                    }
                }
                m.initialEcc = Best.Orbit.eccentricity;
//                m.Log("initialEcc: {}", m.initialEcc);//debug
            }
        protected LandingTrajectory fixed_inclination_orbit(LandingTrajectory old, LandingTrajectory best,
                                                            ref Vector3d dir, ref double V, float start_offset)
        {
            var StartUT = VSL.Physics.UT + start_offset;

            if (old != null)
            {
                V  += old.DeltaR * (1 - CFG.Target.AngleTo(VSL) / Math.PI * 0.9) * Body.GeeASL;
                dir = Quaternion.AngleAxis((float)old.DeltaFi, VSL.Physics.Up.xzy) * dir;
            }
            return(new LandingTrajectory(VSL, dir * V - VesselOrbit.getOrbitalVelocityAtUT(StartUT), StartUT,
                                         CFG.Target, old == null? TargetAltitude : old.TargetAltitude));
        }
Exemple #9
0
		protected LandingTrajectory horizontal_correction(LandingTrajectory old, LandingTrajectory best, ref Vector3d NodeDeltaV, double start_offset)
		{
			var StartUT = VSL.Physics.UT+start_offset;
			if(old != null) 
			{
				if(Math.Abs(old.DeltaR) > Math.Abs(old.DeltaFi)) 
                    NodeDeltaV += new Vector3d(0, 0, ProgradeCorrection(old));
				else 
					NodeDeltaV += PlaneCorrection(old);
			}
			return new LandingTrajectory(VSL, Node2OrbitDeltaV(NodeDeltaV, StartUT), 
			                             StartUT, CFG.Target, old == null? TargetAltitude : old.TargetAltitude);
		}
        protected LandingTrajectory orbit_correction(LandingTrajectory old, LandingTrajectory best, ref double angle, ref double V, float start_offset)
        {
            var StartUT = VSL.Physics.UT + start_offset;

            if (old != null)
            {
                V     += old.DeltaR * (1 - CFG.Target.AngleTo(VSL) / Math.PI * 0.9) * Body.GeeASL;
                angle += old.DeltaFi;
            }
            var vel = VesselOrbit.getOrbitalVelocityAtUT(StartUT);

            return(new LandingTrajectory(VSL, QuaternionD.AngleAxis(angle, VSL.Physics.Up.xzy) * vel.normalized * V - vel, StartUT,
                                         CFG.Target, old == null? TargetAltitude : old.TargetAltitude));
        }
Exemple #11
0
		protected LandingTrajectory fixed_Ecc_orbit(LandingTrajectory old, LandingTrajectory best, ref Vector3d NodeDeltaV, double ecc)
		{
			double StartUT;
			double targetAlt;
			if(old != null) 
			{
				targetAlt = old.TargetAltitude;
                var deltaAngle = Math.Abs(90-VesselOrbit.inclination) > 45 ? old.DeltaLon : old.DeltaLat;
                var inv_target_lat = 90-Math.Abs(Coordinates.NormalizeLatitude(old.Target.Pos.Lat));
                var target_at_pole = inv_target_lat < 5;
                deltaAngle *= inv_target_lat/90;
                //if target is at a pole, just use its longitude as start UT
                if(target_at_pole)
                    StartUT = VSL.Physics.UT+
                        Math.Max(Utils.ClampAngle(Utils.AngleDelta(old.Target.Pos.Lon, VSL.vessel.longitude))/360*VesselOrbit.period,
                                 ManeuverOffset);
                //otherwise correct start UT according to lat-lon delta between target and landing site
                else 
                    StartUT = AngleDelta2StartUT(old, deltaAngle, 
                                                 ManeuverOffset, VesselOrbit.period, VesselOrbit.period);
                //if start UT is good enough, correct orbital plane and landing site
                if(target_at_pole || Math.Abs(deltaAngle) < 1)
                {
                    NodeDeltaV += PlaneCorrection(old);
                    //correct fly-over altitude if needed
    				if(old.BrakeEndDeltaAlt < LTRJ.FlyOverAlt)
                        NodeDeltaV += new Vector3d((LTRJ.FlyOverAlt-old.BrakeEndDeltaAlt)*Body.GeeASL/100, 0, 0);
                    //if close enough, start tuning deltaR
                    if(Math.Abs(old.DeltaFi) < 1)
                        NodeDeltaV += Orbit2NodeDeltaV(old.StartVel.normalized * ProgradeCorrection(old), old.StartUT);
                }
//                Log("target_at_pole {}, inv_target_lat {}/{}/{}, deltaAngle {}, deltaFi {}, vsl-target-deltaLon {}, StartT {}", 
//                    target_at_pole, inv_target_lat, Coordinates.NormalizeLatitude(old.Target.Pos.Lat), old.Target.Pos.Lat,
//                    deltaAngle, old.DeltaFi, 
//                    Utils.ClampAngle(Utils.AngleDelta(old.Target.Pos.Lon, VSL.vessel.longitude)),
//                    StartUT-VSL.Physics.UT);//debug
			}
			else 
			{
				StartUT = VSL.Physics.UT+ManeuverOffset;
				targetAlt = TargetAltitude;
			}
			return new LandingTrajectory(VSL, 
			                             dV4Ecc(VesselOrbit, ecc, StartUT, Body.Radius+targetAlt-10)+
			                             Node2OrbitDeltaV(NodeDeltaV, StartUT), 
                                         StartUT, CFG.Target, targetAlt);
		}
Exemple #12
0
        protected LandingTrajectory horizontal_correction(LandingTrajectory old, LandingTrajectory best, ref Vector3d NodeDeltaV, double start_offset)
        {
            var StartUT = VSL.Physics.UT + start_offset;

            if (old != null)
            {
                if (Math.Abs(old.DeltaR) > Math.Abs(old.DeltaFi))
                {
                    NodeDeltaV += new Vector3d(0, 0, old.DeltaR *
                                               Utils.ClampH(old.Orbit.period / 16 / old.TimeToSurface, 1));
                }
                else
                {
                    NodeDeltaV += PlaneCorrection(old);
                }
            }
            return(new LandingTrajectory(VSL, Node2OrbitDeltaV(NodeDeltaV, StartUT),
                                         StartUT, CFG.Target, old == null? TargetAltitude : old.TargetAltitude));
        }
Exemple #13
0
            public override IEnumerator <LandingTrajectory> GetEnumerator()
            {
                Best = new LandingTrajectory(m.VSL,
                                             dir * velocity - m.VesselOrbit.getOrbitalVelocityAtUT(startUT),
                                             startUT, m.CFG.Target, m.TargetAltitude);
                LandingTrajectory prev = null;

                while (continue_calculation(prev, Best))
                {
                    prev = Best;
                    foreach (var t in optimize_DeltaV())
                    {
                        yield return(t);
                    }
                    foreach (var t in optimize_DeltaFi())
                    {
                        yield return(t);
                    }
                    Utils.Log("Best so far: {}", Best.DistanceToTarget);
                }
            }
Exemple #14
0
            public override IEnumerator <LandingTrajectory> GetEnumerator()
            {
                var startUT = m.VSL.Physics.UT + m.ManeuverOffset;

                Best = newT(startUT, inclination, deorbit(startUT));
                foreach (var t in scan_startUT())
                {
                    yield return(t);
                }
                LandingTrajectory prev = null;

                while (continue_calculation(prev, Best))
                {
                    prev    = Best;
                    startUT = Best.StartUT;
                    var dR = Math.Abs(Best.DeltaR);
                    var dT = (float)Math.Max(Math.Abs(Best.DeltaR) / 360 * m.VesselOrbit.period, 1);
                    foreach (var t in optimize_startUT(dT))
                    {
                        yield return(t);
                    }
                    var dI = (float)Utils.Clamp(Utils.ClampSignedL(Best.DeltaFi, 0.1), -10, 10);
                    foreach (var t in optimize_inclination(dI, deorbit(Best.StartUT)))
                    {
                        yield return(t);
                    }
                    var dR1 = Math.Abs(Best.DeltaR);
                    if (!Best.FullBrake || dR1 < 1 || Math.Abs(dR - dR1) < 1)
                    {
                        var ddV = -Utils.ClampSignedL(dR2dV(Best.DeltaR), 1);
                        foreach (var t in optimize_ecc(ddV))
                        {
                            yield return(t);
                        }
                    }
//                    if(Math.Abs(dR-Math.Abs(Best.DeltaR)) < 1)
//                        Ecc = Math.Max(Ecc-dEcc, 0);
                }
            }
Exemple #15
0
		IEnumerator<YieldInstruction> compute_initial_eccentricity()
		{
//			Log("Calculating initial orbit eccentricity...");//debug
			var tPos = CFG.Target.RelOrbPos(Body);
			var UT = VSL.Physics.UT +
				AngleDelta(VesselOrbit, tPos, VSL.Physics.UT)/360*VesselOrbit.period;
			var vPos = VesselOrbit.getRelativePositionAtUT(UT);
			var vVel = VesselOrbit.getOrbitalVelocityAtUT(UT);
			var dir = Vector3d.Exclude(vPos, vVel);
            var ini_dV = dV4Pe(VesselOrbit, (Body.Radius+TargetAltitude)*0.999, UT);
			var trj = new LandingTrajectory(VSL, ini_dV, UT, CFG.Target, TargetAltitude);
			var atmo_curve = trj.GetAtmosphericCurve(5);
			var maxV = vVel.magnitude;
			var minV = 0.0;
			var dV = 0.0;
			dir = -dir.normalized;
			var in_plane = Math.Abs(90-Vector3.Angle(tPos, VesselOrbit.GetOrbitNormal())) < 5;
//			Log("in plane {}, ini dV {}\nini trj:\n{}", in_plane, ini_dV, trj);//debug
			yield return null;
			while(maxV-minV > 1)
			{
				dV = (maxV+minV)/2;
				trj = new LandingTrajectory(VSL, ini_dV+dir*dV, UT, CFG.Target, trj.TargetAltitude);
				atmo_curve = trj.GetAtmosphericCurve(5);
//				Log("dV: {} : {} : {} m/s\ntrj:\n{}", minV, dV, maxV, trj);//debug
				if(!trj.NotEnoughFuel && (in_plane || trj.DeltaR < 0) &&
				   (atmo_curve != null &&
				    (will_overheat(atmo_curve) ||
				     atmo_curve[atmo_curve.Count-1].DynamicPressure > DEO.MaxDynPressure) ||
				    !Body.atmosphere && trj.LandingAngle < DEO.MinLandingAngle))
					minV = dV;
				else maxV = dV;
				yield return null;
			}
			currentEcc = trj.Orbit.eccentricity;
			dEcc = currentEcc/DEO.EccSteps;
//			Log("currentEcc: {}, dEcc {}", currentEcc, dEcc);//debug
		}
Exemple #16
0
        public void DeorbitCallback(Multiplexer.Command cmd)
        {
            switch (cmd)
            {
            case Multiplexer.Command.Resume:
//				Utils.Log("Resuming: stage {}, landing_stage {}, landing {}", stage, landing_stage, landing);//debug
                if (!check_patched_conics())
                {
                    return;
                }
                NeedRadarWhenMooving();
                if (stage == Stage.None && !landing)
                {
                    goto case Multiplexer.Command.On;
                }
                else if (VSL.HasManeuverNode)
                {
                    CFG.AP1.OnIfNot(Autopilot1.Maneuver);
                }
                break;

            case Multiplexer.Command.On:
                reset();
                if (!check_patched_conics())
                {
                    return;
                }
                if (!setup())
                {
                    CFG.AP2.Off(); return;
                }
                if (VesselOrbit.PeR < Body.Radius)
                {
                    Status("red", "Already deorbiting. Trying to correct course and land.");
                    fine_tune_approach();
                }
                else
                {
//					Log("Calculating initial orbit eccentricity...");//debug
                    var tPos = CFG.Target.RelOrbPos(Body);
                    var UT   = VSL.Physics.UT +
                               AngleDelta(VesselOrbit, tPos, VSL.Physics.UT) / 360 * VesselOrbit.period;
                    var vPos    = VesselOrbit.getRelativePositionAtUT(UT);
                    var dir     = Vector3d.Exclude(vPos, tPos - vPos);
                    var ini_orb = CircularOrbit(dir, UT);
                    var ini_dV  = ini_orb.getOrbitalVelocityAtUT(UT) - VesselOrbit.getOrbitalVelocityAtUT(UT) + dV4Pe(ini_orb, Body.Radius * 0.9, UT);
                    var trj     = new LandingTrajectory(VSL, ini_dV, UT, CFG.Target, TargetAltitude);
                    var dV      = 10.0;
                    dir = -dir.normalized;
                    while (trj.Orbit.eccentricity < DEO.StartEcc)
                    {
//						Log("\ndV: {}m/s\nini trj:\n{}", dV, trj);//debug
                        if (trj.DeltaR > 0)
                        {
                            break;
                        }
                        trj = new LandingTrajectory(VSL, ini_dV + dir * dV, UT, CFG.Target, trj.TargetAltitude);
                        dV += 10;
                    }
                    if (trj.Orbit.eccentricity > DEO.StartEcc)
                    {
                        currentEcc = DEO.StartEcc;
                        if (Body.atmosphere)
                        {
                            currentEcc =
                                Utils.ClampH(currentEcc * (2.1 - Utils.ClampH(VSL.Torque.MaxPossible.AngularDragResistance / Body.atmDensityASL * DEO.AngularDragF, 1)), DEO.MaxEcc);
                        }
                    }
                    else
                    {
                        currentEcc = Utils.ClampL(trj.Orbit.eccentricity - DEO.dEcc, DEO.dEcc);
                    }
//					Log("currentEcc: {}, dEcc {}", currentEcc, DEO.dEcc);//debug
                    if (Globals.Instance.AutosaveBeforeLanding)
                    {
                        Utils.SaveGame(VSL.vessel.vesselName.Replace(" ", "_") + "-before_landing");
                    }
                    compute_landing_trajectory();
                }
                goto case Multiplexer.Command.Resume;

            case Multiplexer.Command.Off:
                UnregisterFrom <Radar>();
                reset();
                break;
            }
        }
Exemple #17
0
 double ProgradeCorrection(LandingTrajectory old)
 {
     return(old.DeltaR *
            Utils.ClampH(old.Orbit.period / old.TimeToTarget * Body.GeeASL, 1));
 }