public ComputeForces ( double altitude, UnityEngine.Vector3d airVelocity, UnityEngine.Vector3d vup, double angleOfAttack ) : UnityEngine.Vector3d | ||
altitude | double | |
airVelocity | UnityEngine.Vector3d | |
vup | UnityEngine.Vector3d | |
angleOfAttack | double | |
return | UnityEngine.Vector3d |
private Vector2d ComputeCacheEntry(int v, int a, int m) { double vel = MaxVelocity * (double)v / (double)(InternalArray.GetLength(0) - 1); Vector3d velocity = new Vector3d(vel, 0, 0); double AoA = MaxAoA * ((double)a / (double)(InternalArray.GetLength(1) - 1) * 2.0 - 1.0); double currentAltitude = MaxAltitude * (double)m / (double)(InternalArray.GetLength(2) - 1); Vector2d packedForce = Model.PackForces(Model.ComputeForces(currentAltitude, velocity, new Vector3d(0, 1, 0), AoA), currentAltitude, vel); return(InternalArray[v, a, m] = packedForce); }
internal static void DebugTelemetry() { if (!Util.IsFlight) { return; } double now = Planetarium.GetUniversalTime(); double dt = now - PreviousFrameTime; if (dt > 0.5 || dt < 0.0) { Vector3d bodySpacePosition = new Vector3d(); Vector3d bodySpaceVelocity = new Vector3d(); if (aerodynamicModel_ != null && Trajectories.IsVesselAttached) { CelestialBody body = Trajectories.AttachedVessel.orbit.referenceBody; bodySpacePosition = Trajectories.AttachedVessel.GetWorldPos3D() - body.position; bodySpaceVelocity = Trajectories.AttachedVessel.obt_velocity; double altitudeAboveSea = bodySpacePosition.magnitude - body.Radius; Vector3d airVelocity = bodySpaceVelocity - body.getRFrmVel(body.position + bodySpacePosition); double R = PreviousFramePos.magnitude; Vector3d gravityForce = PreviousFramePos * (-body.gravParameter / (R * R * R) * Trajectories.AttachedVessel.totalMass); Quaternion inverseRotationFix = body.inverseRotation ? Quaternion.AngleAxis((float)(body.angularVelocity.magnitude / Math.PI * 180.0 * dt), Vector3.up) : Quaternion.identity; Vector3d TotalForce = (bodySpaceVelocity - inverseRotationFix * PreviousFrameVelocity) * (Trajectories.AttachedVessel.totalMass / dt); TotalForce += bodySpaceVelocity * (dt * 0.000015); // numeric precision fix Vector3d ActualForce = TotalForce - gravityForce; Transform vesselTransform = Trajectories.AttachedVessel.ReferenceTransform; Vector3d vesselBackward = (Vector3d)(-vesselTransform.up.normalized); Vector3d vesselForward = -vesselBackward; Vector3d vesselUp = (Vector3d)(-vesselTransform.forward.normalized); Vector3d vesselRight = Vector3d.Cross(vesselUp, vesselBackward).normalized; double AoA = Math.Acos(Vector3d.Dot(airVelocity.normalized, vesselForward.normalized)); if (Vector3d.Dot(airVelocity, vesselUp) > 0) { AoA = -AoA; } VesselAerodynamicModel.DebugParts = true; Vector3d referenceForce = aerodynamicModel_.ComputeForces(20000, new Vector3d(0, 0, 1500), new Vector3d(0, 1, 0), 0); VesselAerodynamicModel.DebugParts = false; Vector3d predictedForce = aerodynamicModel_.ComputeForces(altitudeAboveSea, airVelocity, vesselUp, AoA); //VesselAerodynamicModel.Verbose = true; Vector3d predictedForceWithCache = aerodynamicModel_.GetForces(body, bodySpacePosition, airVelocity, AoA); //VesselAerodynamicModel.Verbose = false; Vector3d localTotalForce = new Vector3d( Vector3d.Dot(TotalForce, vesselRight), Vector3d.Dot(TotalForce, vesselUp), Vector3d.Dot(TotalForce, vesselBackward)); Vector3d localActualForce = new Vector3d( Vector3d.Dot(ActualForce, vesselRight), Vector3d.Dot(ActualForce, vesselUp), Vector3d.Dot(ActualForce, vesselBackward)); Vector3d localPredictedForce = new Vector3d( Vector3d.Dot(predictedForce, vesselRight), Vector3d.Dot(predictedForce, vesselUp), Vector3d.Dot(predictedForce, vesselBackward)); Vector3d localPredictedForceWithCache = new Vector3d( Vector3d.Dot(predictedForceWithCache, vesselRight), Vector3d.Dot(predictedForceWithCache, vesselUp), Vector3d.Dot(predictedForceWithCache, vesselBackward)); Telemetry.Send("ut", now); Telemetry.Send("altitude", Trajectories.AttachedVessel.altitude); Telemetry.Send("airspeed", Math.Floor(airVelocity.magnitude)); Telemetry.Send("aoa", (AoA * 180.0 / Math.PI)); Telemetry.Send("force_actual", localActualForce.magnitude); Telemetry.Send("force_actual.x", localActualForce.x); Telemetry.Send("force_actual.y", localActualForce.y); Telemetry.Send("force_actual.z", localActualForce.z); //Telemetry.Send("force_total", localTotalForce.magnitude); //Telemetry.Send("force_total.x", localTotalForce.x); //Telemetry.Send("force_total.y", localTotalForce.y); //Telemetry.Send("force_total.z", localTotalForce.z); Telemetry.Send("force_predicted", localPredictedForce.magnitude); Telemetry.Send("force_predicted.x", localPredictedForce.x); Telemetry.Send("force_predicted.y", localPredictedForce.y); Telemetry.Send("force_predicted.z", localPredictedForce.z); Telemetry.Send("force_predicted_cache", localPredictedForceWithCache.magnitude); //Telemetry.Send("force_predicted_cache.x", localPredictedForceWithCache.x); //Telemetry.Send("force_predicted_cache.y", localPredictedForceWithCache.y); //Telemetry.Send("force_predicted_cache.z", localPredictedForceWithCache.z); //Telemetry.Send("force_reference", referenceForce.magnitude); //Telemetry.Send("force_reference.x", referenceForce.x); //Telemetry.Send("force_reference.y", referenceForce.y); //Telemetry.Send("force_reference.z", referenceForce.z); //Telemetry.Send("velocity.x", bodySpaceVelocity.x); //Telemetry.Send("velocity.y", bodySpaceVelocity.y); //Telemetry.Send("velocity.z", bodySpaceVelocity.z); //Vector3d velocity_pos = (bodySpacePosition - PreviousFramePos) / dt; //Telemetry.Send("velocity_pos.x", velocity_pos.x); //Telemetry.Send("velocity_pos.y", velocity_pos.y); //Telemetry.Send("velocity_pos.z", velocity_pos.z); Telemetry.Send("drag", Trajectories.AttachedVessel.rootPart.rb.drag); Telemetry.Send("density", Trajectories.AttachedVessel.atmDensity); Telemetry.Send("density_calc", StockAeroUtil.GetDensity(altitudeAboveSea, body)); Telemetry.Send("density_calc_precise", StockAeroUtil.GetDensity(Trajectories.AttachedVessel.GetWorldPos3D(), body)); Telemetry.Send("temperature", Trajectories.AttachedVessel.atmosphericTemperature); Telemetry.Send("temperature_calc", StockAeroUtil.GetTemperature(Trajectories.AttachedVessel.GetWorldPos3D(), body)); } PreviousFrameVelocity = bodySpaceVelocity; PreviousFramePos = bodySpacePosition; PreviousFrameTime = now; } }
public void FixedUpdate() { if (HighLogic.LoadedScene != GameScenes.FLIGHT) { return; } double now = Planetarium.GetUniversalTime(); double dt = now - PreviousFrameTime; if (dt > 0.5 || dt < 0.0) { Vector3d bodySpacePosition = new Vector3d(); Vector3d bodySpaceVelocity = new Vector3d(); if (aerodynamicModel_ != null && vessel_ != null) { CelestialBody body = vessel_.orbit.referenceBody; bodySpacePosition = vessel_.GetWorldPos3D() - body.position; bodySpaceVelocity = vessel_.obt_velocity; double altitudeAboveSea = bodySpacePosition.magnitude - body.Radius; Vector3d airVelocity = bodySpaceVelocity - body.getRFrmVel(body.position + bodySpacePosition); #if DEBUG_COMPARE_FORCES double R = PreviousFramePos.magnitude; Vector3d gravityForce = PreviousFramePos * (-body.gravParameter / (R * R * R) * vessel_.totalMass); Quaternion inverseRotationFix = body.inverseRotation ? Quaternion.AngleAxis((float)(body.angularVelocity.magnitude / Math.PI * 180.0 * dt), Vector3.up) : Quaternion.identity; Vector3d TotalForce = (bodySpaceVelocity - inverseRotationFix * PreviousFrameVelocity) * (vessel_.totalMass / dt); TotalForce += bodySpaceVelocity * (dt * 0.000015); // numeric precision fix Vector3d ActualForce = TotalForce - gravityForce; Transform vesselTransform = vessel_.ReferenceTransform; Vector3d vesselBackward = (Vector3d)(-vesselTransform.up.normalized); Vector3d vesselForward = -vesselBackward; Vector3d vesselUp = (Vector3d)(-vesselTransform.forward.normalized); Vector3d vesselRight = Vector3d.Cross(vesselUp, vesselBackward).normalized; double AoA = Math.Acos(Vector3d.Dot(airVelocity.normalized, vesselForward.normalized)); if (Vector3d.Dot(airVelocity, vesselUp) > 0) { AoA = -AoA; } VesselAerodynamicModel.DebugParts = true; Vector3d referenceForce = aerodynamicModel_.ComputeForces(20000, new Vector3d(0, 0, 1500), new Vector3d(0, 1, 0), 0); VesselAerodynamicModel.DebugParts = false; Vector3d predictedForce = aerodynamicModel_.ComputeForces(altitudeAboveSea, airVelocity, vesselUp, AoA); //VesselAerodynamicModel.Verbose = true; Vector3d predictedForceWithCache = aerodynamicModel_.GetForces(body, bodySpacePosition, airVelocity, AoA); //VesselAerodynamicModel.Verbose = false; Vector3d localTotalForce = new Vector3d(Vector3d.Dot(TotalForce, vesselRight), Vector3d.Dot(TotalForce, vesselUp), Vector3d.Dot(TotalForce, vesselBackward)); Vector3d localActualForce = new Vector3d(Vector3d.Dot(ActualForce, vesselRight), Vector3d.Dot(ActualForce, vesselUp), Vector3d.Dot(ActualForce, vesselBackward)); Vector3d localPredictedForce = new Vector3d(Vector3d.Dot(predictedForce, vesselRight), Vector3d.Dot(predictedForce, vesselUp), Vector3d.Dot(predictedForce, vesselBackward)); Vector3d localPredictedForceWithCache = new Vector3d(Vector3d.Dot(predictedForceWithCache, vesselRight), Vector3d.Dot(predictedForceWithCache, vesselUp), Vector3d.Dot(predictedForceWithCache, vesselBackward)); Util.PostSingleScreenMessage("actual/predict comparison", "air vel=" + Math.Floor(airVelocity.magnitude) + " ; AoA=" + (AoA * 180.0 / Math.PI)); //Util.PostSingleScreenMessage("total force", "actual total force=" + localTotalForce.ToString("0.000")); Util.PostSingleScreenMessage("actual force", "actual force=" + localActualForce.ToString("0.000")); Util.PostSingleScreenMessage("predicted force", "predicted force=" + localPredictedForce.ToString("0.000")); Util.PostSingleScreenMessage("predict with cache", "predicted force with cache=" + localPredictedForceWithCache.ToString("0.000")); Util.PostSingleScreenMessage("reference force", "reference force=" + referenceForce.ToString("0.000")); Util.PostSingleScreenMessage("current vel", "current vel=" + bodySpaceVelocity.ToString("0.00") + " (mag=" + bodySpaceVelocity.magnitude.ToString("0.00") + ")"); //Util.PostSingleScreenMessage("vel from pos", "vel from pos=" + ((bodySpacePosition - PreviousFramePos) / dt).ToString("0.000") + " (mag=" + ((bodySpacePosition - PreviousFramePos) / dt).magnitude.ToString("0.00") + ")"); Util.PostSingleScreenMessage("force diff", "force ratio=" + (localActualForce.z / localPredictedForce.z).ToString("0.000")); Util.PostSingleScreenMessage("drag", "physics drag=" + vessel_.rootPart.rb.drag); #endif double approximateRho = StockAeroUtil.GetDensity(altitudeAboveSea, body); double preciseRho = StockAeroUtil.GetDensity(vessel_.GetWorldPos3D(), body); double actualRho = vessel_.atmDensity; Util.PostSingleScreenMessage("rho info", /*"preciseRho=" + preciseRho.ToString("0.0000") + " ; " +*/ "rho=" + approximateRho.ToString("0.0000") + " ; actual=" + actualRho.ToString("0.0000") + " ; ratio=" + (actualRho / approximateRho).ToString("0.00")); } PreviousFrameVelocity = bodySpaceVelocity; PreviousFramePos = bodySpacePosition; PreviousFrameTime = now; } }