void CalculateLosses(Vessel vessel) { if (vesselState.mass == 0) { return; } double fwdAcceleration = Vector3d.Dot(vessel.acceleration, vesselState.forward.normalized); double GravityDrag = Vector3d.Dot(vesselState.gravityForce, -vessel.obt_velocity.normalized); double TimeInterval = Time.time - FlyTimeInterval; FlyTimeInterval = Time.time; HorizontalDistance += Vector3d.Exclude(vesselState.up, vesselState.orbitalVelocity).magnitude *TimeInterval; VelocityLost += ((vesselState.thrustCurrent / vesselState.mass) - fwdAcceleration) * TimeInterval; DragLoss += vesselState.drag * TimeInterval; GravityDragLoss += GravityDrag * TimeInterval; double VectorDrag = vesselState.thrustCurrent - Vector3d.Dot(vesselState.thrustVectorLastFrame, vessel.obt_velocity.normalized); VectorDrag = VectorDrag / vesselState.mass; VectorLoss += VectorDrag * TimeInterval; TotalBurn += vesselState.thrustCurrent / vesselState.mass * TimeInterval; double GravityDragLossAtAp = GravityDragLoss + vessel.obt_velocity.magnitude - vessel.orbit.getOrbitalVelocityAtUT(vessel.orbit.timeToAp + Planetarium.GetUniversalTime()).magnitude; TotalLoss = DragLoss + GravityDragLossAtAp + VectorLoss; if (vessel.CriticalHeatPart().CriticalHeat() > MaxHeat) { MaxHeat = vessel.CriticalHeatPart().CriticalHeat(); } Message = string.Format( "Air Drag:\t\t{0:0.00} m/s²\n" + "GravityDrag:\t{1:0.00} m/s²\n" + "Thrust Vector Drag:\t{5:0.00} m/s²\n" + "Air Drag Loss:\t{2:0.00} m/s\n" + "Gravity Drag Loss:\t{3:0.00} -> {4:0.00} m/s @AP\n\n" + "Total Vector Loss:\t{6:0.00} m/s\n" + "Total Loss:\t{7:0.00} m/s\n" + "Total Burn:\t\t{8:0.0}\n\n" + "Apoapsis:\t\t{9}\n" + "Periapsis:\t\t{10}\n" + "Inclination:\t\t{11:0.0} °\n\n" + "Dynamic Pressure:\t{12:0.00} Pa\n" + "Max Q:\t\t{13:0.00} Pa\n\n", vesselState.drag, GravityDrag, DragLoss, GravityDragLoss, GravityDragLossAtAp, VectorDrag, VectorLoss, TotalLoss, TotalBurn, OrbitExtensions.FormatOrbitInfo(vessel.orbit.ApA, vessel.orbit.timeToAp), OrbitExtensions.FormatOrbitInfo(vessel.orbit.PeA, vessel.orbit.timeToPe), vessel.orbit.inclination, vesselState.dynamicPressure, vesselState.maxQ ); }
public static Orbit OrbitFromStateVectors(Vector3d pos, Vector3d vel, CelestialBody body, double UT) { Orbit ret = new Orbit(); ret.UpdateFromStateVectors(OrbitExtensions.SwapYZ(pos - body.position), OrbitExtensions.SwapYZ(vel), body, UT); if (double.IsNaN(ret.argumentOfPeriapsis)) { Vector3d vectorToAN = Quaternion.AngleAxis(-(float)ret.LAN, Planetarium.up) * Planetarium.right; Vector3d vectorToPe = OrbitExtensions.SwapYZ(ret.eccVec); double cosArgumentOfPeriapsis = Vector3d.Dot(vectorToAN, vectorToPe) / (vectorToAN.magnitude * vectorToPe.magnitude); //Squad's UpdateFromStateVectors is missing these checks, which are needed due to finite precision arithmetic: if (cosArgumentOfPeriapsis > 1) { ret.argumentOfPeriapsis = 0; } else if (cosArgumentOfPeriapsis < -1) { ret.argumentOfPeriapsis = 180; } else { ret.argumentOfPeriapsis = Math.Acos(cosArgumentOfPeriapsis); } } return(ret); }
void FixedUpdate() { if (Launching) { stagestats.editorBody = getVessel.mainBody; vesselState.Update(getVessel); attitude.OnFixedUpdate(); stagestats.OnFixedUpdate(); stagestats.RequestUpdate(this); if (flightMapWindow.flightMap != null && Launching) { flightMapWindow.flightMap.UpdateMap(getVessel); } } else if (EnableStats && !getVessel.Landed && !getVessel.IsInStableOrbit()) { CalculateLosses(getVessel); stagestats.editorBody = getVessel.mainBody; vesselState.Update(getVessel); attitude.OnFixedUpdate(); stagestats.OnFixedUpdate(); stagestats.RequestUpdate(this); } else if (EnableStats && !getVessel.Landed && getVessel.IsInStableOrbit()) { if (VectorLoss > 0.01) { Message = string.Format( "Total Vector Loss:\t{0:0.00} m/s\n" + "Total Loss:\t{1:0.00} m/s\n" + "Total Burn:\t\t{2:0.0}\n\n", VectorLoss, TotalLoss, TotalBurn ); } else { Message = ""; } Message += string.Format( "Apoapsis:\t\t{0}\n" + "Periapsis:\t\t{1}\n" + "Inclination:\t\t{2:0.0} °\n", OrbitExtensions.FormatOrbitInfo(getVessel.orbit.ApA, getVessel.orbit.timeToAp), OrbitExtensions.FormatOrbitInfo(getVessel.orbit.PeA, getVessel.orbit.timeToPe), getVessel.orbit.inclination ); } else if (EnableStats && getVessel.Landed) { double diffUT = Planetarium.GetUniversalTime() - delayUT; if (diffUT > 1 || Double.IsNaN(delayUT)) { vesselState.Update(getVessel); stagestats.OnFixedUpdate(); stagestats.RequestUpdate(this); Message = PreflightInfo(getVessel); delayUT = Planetarium.GetUniversalTime(); } } }