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_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"; }
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; }
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 }
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 }