public List <AtmosphericConditions> GetAtmosphericCurve(double dT, double endUT = -1)
        {
            if (!Body.atmosphere)
            {
                return(null);
            }
            var atmoR   = Body.Radius + Body.atmosphereDepth;
            var startUT = StartPos.magnitude < atmoR? StartUT : TrajectoryCalculator.NearestRadiusUT(Orbit, atmoR, StartUT);

            if (endUT < 0)
            {
                endUT = BrakeEndUT;
            }
            if (startUT > endUT)
            {
                return(null);
            }
            var samples = (int)Math.Ceiling((endUT - startUT) / dT) + 1;
            var curve   = new List <AtmosphericConditions>(samples);

            dT = (endUT - startUT) / samples;
            for (int i = 1; i <= samples; i++)
            {
                var cond = new AtmosphericConditions(Orbit, startUT + dT * i);
                cond.Duration = dT;
                curve.Add(cond);
            }
            return(curve);
        }
        void update_from_orbit(Orbit orb, double UT)
        {
            //calculate the position of a landing site
            if (orb.ApA <= TargetAltitude)
            {
                AtTargetUT = orb.StartUT + (orb.ApAhead()? orb.timeToAp : 1);
            }
            else if (orb.PeA < TargetAltitude)
            {
                AtTargetUT = TrajectoryCalculator.NearestRadiusUT(orb, Body.Radius + TargetAltitude, UT);
            }
            else
            {
                AtTargetUT = orb.StartUT + orb.timeToPe;
            }
            TransferTime = AtTargetUT - StartUT;
            AtTargetPos  = orb.getRelativePositionAtUT(AtTargetUT);
            AtTargetVel  = orb.getOrbitalVelocityAtUT(AtTargetUT);
            var at_target_rot = TrajectoryCalculator.BodyRotationAtdT(Body, -TimeToTarget);

            approach     = new Coordinates((at_target_rot * (AtTargetPos - AtTargetVel * 10)).xzy + Body.position, Body);
            SurfacePoint = new WayPoint((at_target_rot * AtTargetPos).xzy + Body.position, Body);
            SurfacePoint.Pos.SetAlt2Surface(Body);
            SurfacePoint.Name = "Landing Site";
        }
 void update_from_orbit(Orbit orb, double UT)
 {
     //calculate the position of a landing site
     if (orb.ApA <= TargetAltitude)
     {
         AtTargetUT = orb.StartUT + (orb.ApAhead()? orb.timeToAp : 1);
     }
     else
     {
         AtTargetUT = TrajectoryCalculator.NearestRadiusUT(orb, Body.Radius + TargetAltitude, UT);
     }
     TransferTime      = AtTargetUT - StartUT;
     AtTargetPos       = orb.getRelativePositionAtUT(AtTargetUT);
     AtTargetVel       = orb.getOrbitalVelocityAtUT(AtTargetUT);
     SurfacePoint      = new WayPoint((TrajectoryCalculator.BodyRotationAtdT(Body, -TimeToSurface) * AtTargetPos).xzy + Body.position, Body);
     SurfacePoint.Name = "Landing Site";
 }
Beispiel #4
0
 public double Altitude2UT(double altitude)
 {
     if (!HavePoints || altitude > Points[0].Altitude)
     {
         return(TrajectoryCalculator.NearestRadiusUT(Orbit, altitude + Orbit.referenceBody.Radius, StartUT));
     }
     for (int i = 1, count = Points.Count; i < count; i++)
     {
         var p1 = Points[i];
         if (p1.Altitude > altitude)
         {
             continue;
         }
         var p0 = Points[i - 1];
         return(p0.UT + p0.Duration * (altitude - p0.Altitude) / (p1.Altitude - p0.Altitude));
     }
     return(EndUT);
 }
Beispiel #5
0
        void update_from_orbit()
        {
            AtTargetUT = Body.atmosphere && Orbit.altitude > Body.atmosphereDepth ?
                         TrajectoryCalculator.NearestRadiusUT(Orbit, Body.Radius + Body.atmosphereDepth, StartUT) + 1 : StartUT;
            var end_alt = Math.Max(Orbit.PeA + 10, TargetAltitude);

            Path = new LandingPath(VSL, Orbit, end_alt,
                                   AtTargetUT,
                                   Math.Min(LandingTrajectoryAutopilot.C.AtmoTrajectoryResolution,
                                            Utils.ClampL((VSL.Altitude.Absolute - TargetAltitude) / Math.Abs(VSL.VerticalSpeed.Absolute) / 20, 0.1)),
                                   VSL.Physics.M - ManeuverFuel);
            update_overheat_info(Path, VSL.TCA.part.temperature);
            AtTargetVel  = Path.LastPoint.vel;
            AtTargetPos  = Path.LastPoint.pos;
            AtTargetUT   = Path.LastPoint.UT;
            TransferTime = AtTargetUT - StartUT;
            update_landing_site(Path);
        }
Beispiel #6
0
 public Point PointAtAltitude(double altitude)
 {
     if (!HavePoints || altitude > Points[0].Altitude)
     {
         return(newP(TrajectoryCalculator.NearestRadiusUT(Orbit, altitude + Orbit.referenceBody.Radius, StartUT)));
     }
     for (int i = 1, count = Points.Count; i < count; i++)
     {
         var p1 = Points[i];
         if (p1.Altitude > altitude)
         {
             continue;
         }
         var p0 = Points[i - 1];
         var p  = p0;
         var t  = (p0.Altitude - altitude) / (p0.Altitude - p1.Altitude);
         p.UT      += p0.Duration * t;
         p.Duration = p1.UT - p.UT;
         p.pos      = Vector3d.Lerp(p0.pos, p1.pos, t);
         p.Update();
         return(p);
     }
     return(LastPoint);
 }
Beispiel #7
0
 public LandingPath(VesselWrapper vsl, Orbit orb, double target_altitude, double startUT, double dt,
                    double start_mass, double fuel = 0, double brake_vel = 0)
 {
     VSL            = vsl;
     Orbit          = orb;
     TargetAltitude = target_altitude;
     StartUT        = startUT;
     UT0            = VSL.Physics.UT;
     EndMass        = start_mass;
     FuelUsed       = 0;
     FuelLeft       = fuel;
     BrakeDeltaV    = brake_vel;
     if (Orbit.referenceBody.atmosphere || brake_vel > 0 && fuel > 0)
     {
         EndUT      = startUT + orb.timeToPe;
         HavePoints = brake_vel > 0 && fuel > 0;
         var p         = newP(StartUT);
         var m         = start_mass;
         var s         = Math.Max(VSL.Geometry.MinArea, VSL.Geometry.AreaWithBrakes);
         var ascending = p.Ascending;
         var orig_dt   = dt;
         p.Duration = dt;
         while ((ascending || p.Altitude > TargetAltitude) && p.UT < EndUT)
         {
             var dAlt        = p.Altitude - TargetAltitude;
             var linear_time = dAlt / p.SrfSpeed;
             if (!ascending && dt > 0.01 && linear_time / 2 < dt)
             {
                 p.Duration = dt = linear_time / 2;
             }
             var drag_accel = p.SpecificDrag * s / m;
             var prev_alt   = p.Altitude;
             Atmosphere |= drag_accel > 0;
             HavePoints |= Atmosphere;
             if (HavePoints)
             {
                 if (Points.Count == 0)
                 {
                     FirstPointUT = p.UT;
                     if (Atmosphere)
                     {
                         AtmoStartUT = p.UT;
                     }
                 }
                 Points.Add(p);
                 //                    VSL.Log("drag dV {}, m {}, fm {}, brake_vel {}, p {}",
                 //                            drag_dv, m, fuel, brake_vel, p);//debug
                 var r = p.pos.magnitude;
                 if (p.HorSrfSpeed > 1 && brake_vel > 0 && fuel > 0)
                 {
                     //adjust dt to capture most of the thrust
                     float mflow;
                     var   thrust = VSL.Engines.ThrustAtAlt((float)p.SrfSpeed, (float)p.Altitude, out mflow);
                     var   dV_cm  = thrust / m * dt;
                     if (dt > 0.01 && dV_cm > p.SrfSpeed / 10)
                     {
                         dt = p.SrfSpeed / 10 * m / thrust * 0.9;
                     }
                     //compute thrust direction
                     var vV    = Utils.ClampL(Vector3d.Dot(p.vel, p.pos / r), 1e-5);
                     var b_dir = LandingTrajectoryAutopilot.CorrectedBrakeVelocity(VSL, p.vel, p.pos,
                                                                                   p.DynamicPressure / 1000 / LandingTrajectoryAutopilot.C.MinDPressure,
                                                                                   (p.Altitude - TargetAltitude) / vV).normalized;
                     //compute change in velocity and mass
                     var Ve = thrust / mflow;
                     var dm = mflow * dt;
                     if (dm > fuel)
                     {
                         dm = fuel;
                     }
                     var bV = (double)VSL.Engines.DeltaV(Ve, (float)dm);
                     if (bV > brake_vel)
                     {
                         bV = brake_vel;
                         dm = EnginesProps.FuelNeeded((float)bV, Ve, (float)m);
                     }
                     p.vel     -= b_dir * bV;
                     brake_vel -= bV;
                     //                        VSL.Log("vV {}, vB {}, thrust {}, mflow {}, Ve {}, dm {}\nb_dir {}\nvel {}\npos {}",
                     //                                vV, bV, thrust, mflow, Ve, dm, b_dir, p.vel, p.pos);//debug
                     //spend fuel
                     fuel -= dm;
                     m    -= dm;
                 }
                 //adjust dt if its too small
                 else if (!ascending && dt < orig_dt && linear_time / 50 > dt)
                 {
                     dt = Math.Min(linear_time / 50, orig_dt);
                 }
                 if (Atmosphere)
                 {
                     p.vel -= p.srf_vel / p.SrfSpeed * Math.Min(drag_accel * dt, p.SrfSpeed);
                 }
                 p.vel -= p.pos * p.Body.gMagnitudeAtCenter / r / r / r * dt;
                 p.pos += p.vel * dt;
                 p.UT  += dt;
                 p.Update();
                 if (Atmosphere && AtmoStopUT < 0 && p.SrfSpeed < 10)
                 {
                     AtmoStopUT = p.UT;
                 }
             }
             else
             {
                 p.Update(p.UT + dt);
             }
             ascending &= p.Altitude > prev_alt;
         }
         if (HavePoints)
         {
             Points.Add(p);
             if (Atmosphere && AtmoStopUT < 0)
             {
                 AtmoStopUT = p.UT;
             }
         }
         EndUT     = p.UT;
         LastPoint = p;
         EndMass   = m;
         FuelUsed  = start_mass - m;
         FuelLeft  = Math.Max(fuel, 0);
         if (brake_vel > 0)
         {
             BrakeDeltaV -= brake_vel;
         }
     }
     else
     {
         EndUT     = TrajectoryCalculator.NearestRadiusUT(Orbit, Orbit.referenceBody.Radius + TargetAltitude, StartUT);
         LastPoint = newP(EndUT);
     }
 }