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";
        }
示例#2
0
        void update_landing_site(LandingPath path)
        {
            var at_target_rot = TrajectoryCalculator.BodyRotationAtdT(Body, -TimeToTarget);

            approach     = new Coordinates((at_target_rot * path.PointAtUT(path.EndUT - 1).pos).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";
 }
示例#4
0
        public Point FlyAbovePoint(Vector3d pos)
        {
            if (Utils.ProjectionAngle(Orbit.getRelativePositionAtUT(StartUT), pos,
                                      Orbit.getOrbitalVelocityAtUT(StartUT)) < 0)
            {
                return(newP(StartUT));
            }
            if (!HavePoints ||
                Utils.ProjectionAngle(Orbit.getRelativePositionAtUT(AtmoStartUT),
                                      TrajectoryCalculator.BodyRotationAtdT(Orbit.referenceBody, AtmoStartUT - UT0) * pos,
                                      Orbit.getOrbitalVelocityAtUT(AtmoStartUT)) < 0)
            {
                return(newP(TrajectoryCalculator.FlyAboveUT(Orbit, pos, StartUT)));
            }
            var p0     = Points[0];
            var angle0 = Utils.ProjectionAngle(p0.pos,
                                               TrajectoryCalculator
                                               .BodyRotationAtdT(Orbit.referenceBody, p0.UT - UT0) * pos,
                                               p0.vel);

            for (int i = 1, count = Points.Count; i < count; i++)
            {
                var p1     = Points[i];
                var angle1 = Utils.ProjectionAngle(p1.pos,
                                                   TrajectoryCalculator
                                                   .BodyRotationAtdT(Orbit.referenceBody, p1.UT - UT0) * pos,
                                                   p1.vel);
                if (angle1 > 0)
                {
                    angle0 = angle1;
                    continue;
                }
                p0 = Points[i - 1];
                var p = p0;
                var t = angle0 / (angle0 - angle1);
                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);
        }
 void update(bool with_brake)
 {
     update_from_orbit(Orbit, StartUT);
     //correct for brake maneuver
     if (with_brake)
     {
         BrakeEndUT    = AtTargetUT - GLB.LTRJ.CorrectionOffset;
         BrakeStartUT  = BrakeEndUT - MatchVelocityAutopilot.BrakingOffset((float)AtTargetVel.magnitude, VSL, out BrakeDuration);
         brake_delta_v = -0.9 * Orbit.getOrbitalVelocityAtUT(BrakeEndUT);
         update_from_orbit(TrajectoryCalculator.NewOrbit(Orbit, BrakeDeltaV, BrakeEndUT), BrakeEndUT);
     }
     else
     {
         brake_delta_v = -(AtTargetVel + Vector3d.Cross(Body.zUpAngularVelocity, AtTargetPos));
         BrakeEndUT    = TrajectoryCalculator.FlyAboveUT(Orbit, Target.RelSurfPos(Body).xzy, StartUT);
         BrakeStartUT  = BrakeEndUT - MatchVelocityAutopilot.BrakingOffset((float)BrakeDeltaV.magnitude, VSL, out BrakeDuration);
     }
     //compute vessel coordinates at maneuver start
     if (VSL.LandedOrSplashed)
     {
         VslStartLat = Utils.ClampAngle(VSL.vessel.latitude);
         VslStartLon = Utils.ClampAngle(VSL.vessel.longitude);
     }
     else
     {
         var start_pos = (TrajectoryCalculator.BodyRotationAtdT(Body, -TimeToStart) * StartPos).xzy + Body.position;
         VslStartLat = Utils.ClampAngle(Body.GetLatitude(start_pos));
         VslStartLon = Utils.ClampAngle(Body.GetLongitude(start_pos));
     }
     //compute distance to target
     DistanceToTarget = Target.AngleTo(SurfacePoint) * Body.Radius;
     BrakeEndDeltaAlt = Orbit.getRelativePositionAtUT(BrakeEndUT).magnitude - Body.Radius - TargetAltitude;
     //compute distance in lat-lon coordinates
     DeltaLat = Utils.AngleDelta(SurfacePoint.Pos.Lat, Target.Pos.Lat) *
                Math.Sign(Utils.AngleDelta(Utils.ClampAngle(VslStartLat), SurfacePoint.Pos.Lat));
     DeltaLon = Utils.AngleDelta(SurfacePoint.Pos.Lon, Target.Pos.Lon) *
                Math.Sign(Utils.AngleDelta(Utils.ClampAngle(VslStartLon), SurfacePoint.Pos.Lon));
     //compute distance in radial coordinates
     DeltaFi = 90 - Vector3d.Angle(Orbit.GetOrbitNormal(),
                                   TrajectoryCalculator.BodyRotationAtdT(Body, TimeToSurface) *
                                   Body.GetRelSurfacePosition(Target.Pos.Lat, Target.Pos.Lon, TargetAltitude).xzy);
     DeltaR = Utils.RadDelta(SurfacePoint.AngleTo(VslStartLat, VslStartLon), Target.AngleTo(VslStartLat, VslStartLon)) * Mathf.Rad2Deg;
 }
示例#6
0
            public void Update()
            {
                Altitude    = pos.magnitude - Body.Radius;
                Atmosphere  = Body.atmosphere && Altitude < Body.atmosphereDepth;
                rel_pos     = Body.BodyFrame.WorldToLocal(TrajectoryCalculator.BodyRotationAtdT(Body, Path.UT0 - UT) * pos);
                srf_vel     = vel + Vector3d.Cross(Body.zUpAngularVelocity, pos);
                HorSrfSpeed = Vector3d.Exclude(rel_pos, srf_vel).magnitude;
                SrfSpeed    = srf_vel.magnitude;

                if (Atmosphere)
                {
                    Pressure = Body.GetPressure(Altitude);
                    AtmosphereTemperature = Body.GetTemperature(Altitude);
                    Density = Body.GetDensity(Pressure, AtmosphereTemperature);
                    Mach1   = Body.GetSpeedOfSound(Pressure, Density);

                    var Rho_v = Density * SrfSpeed;
                    DynamicPressure = Rho_v * SrfSpeed / 2;
                    Mach            = SrfSpeed / Mach1;
                    SpecificDrag    = AtmoSim.Cd * DynamicPressure *
                                      PhysicsGlobals.DragCurveValue(PhysicsGlobals.SurfaceCurves, VSL.OnPlanetParams.DragCurveK, (float)Mach) *
                                      PhysicsGlobals.DragCurvePseudoReynolds.Evaluate((float)(Rho_v));

                    var convectiveMachLerp = Math.Pow(UtilMath.Clamp01((Mach - PhysicsGlobals.NewtonianMachTempLerpStartMach) /
                                                                       (PhysicsGlobals.NewtonianMachTempLerpEndMach - PhysicsGlobals.NewtonianMachTempLerpStartMach)),
                                                      PhysicsGlobals.NewtonianMachTempLerpExponent);
                    ShockTemperature = SrfSpeed * PhysicsGlobals.NewtonianTemperatureFactor;
                    if (convectiveMachLerp > 0.0)
                    {
                        double b = PhysicsGlobals.MachTemperatureScalar * Math.Pow(SrfSpeed, PhysicsGlobals.MachTemperatureVelocityExponent);
                        ShockTemperature = UtilMath.LerpUnclamped(ShockTemperature, b, convectiveMachLerp);
                    }
                    ShockTemperature *= (double)HighLogic.CurrentGame.Parameters.Difficulty.ReentryHeatScale * Body.shockTemperatureMultiplier;
                    ShockTemperature  = Math.Max(AtmosphereTemperature, ShockTemperature);
                    //calculate convective coefficient for speed > Mach1; lower speed is not a concern
                    ConvectiveCoefficient  = 1E-10 * PhysicsGlobals.MachConvectionFactor;
                    ConvectiveCoefficient *= Density > 1 ? Density : Math.Pow(Density, PhysicsGlobals.MachConvectionDensityExponent);
                    ConvectiveCoefficient *= Math.Pow(SrfSpeed, PhysicsGlobals.MachConvectionVelocityExponent) * Body.convectionMultiplier;
                }
            }
        void update(bool with_brake)
        {
            update_from_orbit(Orbit, StartUT);
            LandingAngle = 90 - Vector3d.Angle(AtTargetPos, -AtTargetVel);
            //correct for brake maneuver
            if (with_brake)
            {
                //estimate time needed to rotate the ship downwards
                var rotation_time = VSL.Torque.NoEngines?
                                    VSL.Torque.NoEngines.MinRotationTime(90) :
                                    VSL.Torque.MaxPossible.RotationTime(90, 0.1f);
                //estimate amount fuel needed for the maneuver
                var vertical_vel = Vector3d.Project(AtTargetVel, AtTargetPos);
                SetBrakeEndUT(Math.Max(AtTargetUT - GLB.LTRJ.CorrectionOffset + rotation_time, StartUT));
                SetBrakeDeltaV(vertical_vel);
                if (BrakeFuel > 0)
                {
                    //calculate braking maneuver
                    var dV = (float)BrakeDeltaV.magnitude;
                    BrakeDuration  = VSL.Engines.AntigravTTB(dV);
                    BrakeDuration += rotation_time;
                    //find the appropriate point to perform the maneuver
                    var    brake_end_UT   = Math.Max(AtTargetUT - Mathf.Max(GLB.LTRJ.CorrectionOffset, BrakeDuration * 1.1f), StartUT);
                    var    vertical_speed = vertical_vel.magnitude;
                    double fly_over_error;
                    do
                    {
                        SetBrakeEndUT(brake_end_UT);
                        fly_over_error = BrakeEndDeltaAlt - GLB.LTRJ.FlyOverAlt;
                        brake_end_UT  -= Math.Abs(fly_over_error / vertical_speed);
                    } while(brake_end_UT > StartUT && fly_over_error < -1);
                    SetBrakeDeltaV(-0.9 * Orbit.getOrbitalVelocityAtUT(BrakeEndUT));
                    //calculate maneuver start time and update landing site
                    BrakeStartUT = Math.Max(BrakeEndUT - MatchVelocityAutopilot.BrakingOffset((float)BrakeDeltaV.magnitude, VSL, out BrakeDuration), StartUT);
                    update_from_orbit(TrajectoryCalculator.NewOrbit(Orbit, BrakeDeltaV, BrakeEndUT), BrakeEndUT);
                }
                else
                {
                    BrakeStartUT  = BrakeEndUT;
                    BrakeDuration = 0;
                }
            }
            else
            {
                SetBrakeEndUT(TrajectoryCalculator.FlyAboveUT(Orbit, Target.RelOrbPos(Body), StartUT));
                SetBrakeDeltaV(-(AtTargetVel + Vector3d.Cross(Body.zUpAngularVelocity, AtTargetPos)));
                if (BrakeFuel > 0)
                {
                    var offset = MatchVelocityAutopilot.BrakingOffset((float)BrakeDeltaV.magnitude, VSL, out BrakeDuration);
                    BrakeStartUT = Math.Max(BrakeEndUT - offset, StartUT);
                }
                else
                {
                    BrakeStartUT  = BrakeEndUT;
                    BrakeDuration = 0;
                }
            }
            BrakeOffset = (float)Utils.ClampL(BrakeEndUT - BrakeStartUT, 0);
            //compute vessel coordinates at maneuver start
            if (VSL.LandedOrSplashed)
            {
                VslStartLat = Utils.ClampAngle(VSL.vessel.latitude);
                VslStartLon = Utils.ClampAngle(VSL.vessel.longitude);
            }
            else
            {
                var start_pos = (TrajectoryCalculator.BodyRotationAtdT(Body, -TimeToStart) * StartPos).xzy + Body.position;
                VslStartLat = Utils.ClampAngle(Body.GetLatitude(start_pos));
                VslStartLon = Utils.ClampAngle(Body.GetLongitude(start_pos));
            }
            //compute distance to target
            DistanceToTarget   = Target.AngleTo(SurfacePoint) * Body.Radius;
            SurfacePoint.Name += string.Format("\n{0} from target", Utils.formatBigValue((float)DistanceToTarget, "m"));
            //compute distance in lat-lon coordinates
            DeltaLat = Utils.AngleDelta(SurfacePoint.Pos.Lat, Target.Pos.Lat) *
                       Math.Sign(Utils.AngleDelta(approach.Lat, SurfacePoint.Pos.Lat));
            DeltaLon = Utils.AngleDelta(SurfacePoint.Pos.Lon, Target.Pos.Lon) *
                       Math.Sign(Utils.AngleDelta(approach.Lon, SurfacePoint.Pos.Lon));
            //compute distance in radial coordinates
            DeltaFi = 90 - Vector3d.Angle(Orbit.GetOrbitNormal(),
                                          TrajectoryCalculator.BodyRotationAtdT(Body, TimeToTarget) *
                                          Body.GetRelSurfacePosition(Target.Pos.Lat, Target.Pos.Lon, TargetAltitude).xzy);
            DeltaR = Utils.RadDelta(SurfacePoint.AngleTo(VslStartLat, VslStartLon), Target.AngleTo(VslStartLat, VslStartLon)) * Mathf.Rad2Deg;
//            Utils.Log("{}", this);//debug
        }
示例#8
0
        void update(bool with_brake, bool brake_at_fly_above)
        {
            reset();
            //update everything
            update_from_orbit();
            update_landing_steepness();
            ActualLandingAngle = 90 - Utils.Angle2(AtTargetPos, -AtTargetVel);
            var AerobrakeStartUT = Path.Atmosphere ? Path.AtmoStartUT : AtTargetUT - 1;

            //correct for brake maneuver
            if (with_brake)
            {
                //estimate time needed to rotate the ship downwards
                var rotation_time = VSL.Torque.NoEngines ?
                                    VSL.Torque.NoEngines.RotationTime2Phase(90) :
                                    VSL.Torque.MaxPossible.RotationTime2Phase(90, 0.1f);
                //estimate amount of fuel needed for the maneuver
                var vertical_vel = Vector3d.Project(AtTargetVel, AtTargetPos);
                SetBrakeEndUT(Math.Max(AtTargetUT - LandingTrajectoryAutopilot.C.CorrectionOffset + rotation_time, StartUT));
                SetBrakeDeltaV(vertical_vel);
                if (BrakeFuel > 0)
                {
                    //calculate braking maneuver
                    BrakeDuration = VSL.Engines.OnPlanetTTB(BrakeDeltaV,
                                                            Orbit.getRelativePositionAtUT(BrakeEndPoint.UT),
                                                            (float)(BrakeEndPointDeltaAlt + TargetAltitude));
                    BrakeDuration += rotation_time;
                    if (FullBrake)
                    {
                        if (brake_at_fly_above)
                        {
                            FlyAbovePoint = Path.FlyAbovePoint(Target.OrbPos(Body));
                            if (WillOverheat)
                            {
                                SetBrakeEndPoint(Path.PointAtShipTemp(VSL.Physics.MinMaxTemperature - 100));
                            }
                            else
                            {
                                SetBrakeEndPoint(FlyAbovePoint);
                            }
                        }
                        else
                        {
                            //find appropriate point to perform the maneuver
                            var brake_end_UT = Math.Max(AtTargetUT - Mathf.Max(LandingTrajectoryAutopilot.C.CorrectionOffset, BrakeDuration * 1.1f), StartUT);
                            var fly_over_alt = TargetAltitude + LandingTrajectoryAutopilot.C.FlyOverAlt;
                            if (WillOverheat)
                            {
                                SetBrakeEndPoint(Path.PointAtShipTemp(VSL.Physics.MinMaxTemperature - 100));
                            }
                            else if (Path.UT2Altitude(brake_end_UT) < fly_over_alt)
                            {
                                SetBrakeEndPoint(Path.PointAtAltitude(fly_over_alt));
                            }
                            else
                            {
                                SetBrakeEndUT(brake_end_UT);
                            }
                        }
                    }
                    else
                    {
                        SetBrakeEndUT(AerobrakeStartUT);
                    }
                    //update landing site
                    update_landing_site_after_brake();
                }
                else //no brake maneuver
                {
                    SetBrakeEndUT(AerobrakeStartUT);
                    BrakeStartPoint = BrakeEndPoint;
                    BrakeDuration   = 0;
                }
            }
            else
            {
                FlyAbovePoint = Path.FlyAbovePoint(Target.OrbPos(Body));
                if (WillOverheat)
                {
                    SetBrakeEndPoint(Path.PointAtShipTemp(VSL.Physics.MinMaxTemperature - 100));
                }
                else
                {
                    SetBrakeEndPoint(FlyAbovePoint);
                }
                SetBrakeDeltaV(-AtTargetVel - Vector3d.Cross(Body.zUpAngularVelocity, AtTargetPos));
                if (BrakeFuel > 0)
                {
                    var offset = MatchVelocityAutopilot.BrakingOffset((float)BrakeDeltaV.magnitude, VSL, out BrakeDuration);
                    BrakeStartPoint = Path.PointAtUT(Math.Max(BrakeEndPoint.UT - offset, StartUT));
                }
                else
                {
                    SetBrakeEndUT(AerobrakeStartUT);
                    BrakeStartPoint = BrakeStartPoint;
                    BrakeDuration   = 0;
                }
            }
            BrakeOffset = (float)Utils.ClampL(BrakeEndPoint.UT - BrakeStartPoint.UT, 0);
            //compute vessel coordinates at maneuver start
            if (VSL.LandedOrSplashed)
            {
                VslStartLat = Utils.ClampAngle(VSL.vessel.latitude);
                VslStartLon = Utils.ClampAngle(VSL.vessel.longitude);
            }
            else
            {
                var start_pos = (TrajectoryCalculator.BodyRotationAtdT(Body, -TimeToStart) * StartPos).xzy + Body.position;
                VslStartLat = Utils.ClampAngle(Body.GetLatitude(start_pos));
                VslStartLon = Utils.ClampAngle(Body.GetLongitude(start_pos));
            }
            //compute distance to target
            DistanceToTarget   = Target.AngleTo(SurfacePoint) * Body.Radius;
            SurfacePoint.Name += string.Format("\n{0} from target", Utils.formatBigValue((float)DistanceToTarget, "m"));
            //compute distance in lat-lon coordinates
            DeltaLat = Utils.AngleDelta(SurfacePoint.Pos.Lat, Target.Pos.Lat) *
                       Math.Sign(Utils.AngleDelta(approach.Lat, SurfacePoint.Pos.Lat));
            DeltaLon = Utils.AngleDelta(SurfacePoint.Pos.Lon, Target.Pos.Lon) *
                       Math.Sign(Utils.AngleDelta(approach.Lon, SurfacePoint.Pos.Lon));
            //compute distance in radial coordinates
            DeltaFi = 90 - Utils.Angle2(Orbit.GetOrbitNormal(),
                                        TrajectoryCalculator.BodyRotationAtdT(Body, TimeToTarget) * Target.OrbPos(Body));
            DeltaR = Utils.RadDelta(SurfacePoint.AngleTo(VslStartLat, VslStartLon), Target.AngleTo(VslStartLat, VslStartLon)) * Mathf.Rad2Deg;
//            Utils.Log("{}", this);//debug
        }