void FixedUpdate() { if (use_climo) { //Retrieve climatological data kwind = _kwx_climo.get3DWind(); vel_list = _kwx_climo.getAero(); wx_list3d = _kwx_climo.getWx3D(); wx_list2d = _kwx_climo.getWx2D(); } else if (use_point) { //Retrieve point forecast data lsite = Util.get_last_lsite_short(); kwind = _kwx_point.get3DWind(); vel_list = _kwx_point.getAero(); wx_list3d = _kwx_point.getWx3D(); wx_list2d = _kwx_point.getWx2D(); } //Check to see if outside of Kerbin's SOI if (((FlightGlobals.ActiveVessel.mainBody != kerbin))) { Util.Log("Destroy toolbar as we're outside Kerbin's SOI"); //Don't display toolbar button or GUI when out of Kerbin SOI ToolbarButtonOnFalse(); Destroy(); gui_removed = true; } else { //If we're back in Kerbin's SOI add the toolbar button and enable GUI oncemore. if (gui_removed) { Util.Log("Re-add toolbar as we're back in Kerbin's SOI"); AddToolbarButton(); gui_removed = false; } } aero_sdata = GetAeroStats(); }
Util.aero_stats GetAeroStats() { //Get current vessel Vessel v = FlightGlobals.ActiveVessel; Util.aero_stats aero_data = new Util.aero_stats(); Vector3d nVel = v.srf_velocity.normalized; //normalized velocity double alpha = Vector3d.Dot(v.transform.forward, nVel); alpha = Math.Asin(alpha) * RAD2DEG; // angle of attack re: velocity double sideslip = Vector3d.Dot(v.transform.up, Vector3d.Exclude(v.transform.forward, nVel).normalized); sideslip = Math.Acos(sideslip) * RAD2DEG; // sideslip re: velocity if (double.IsNaN(sideslip)) { sideslip = 0; } if (sideslip < 0) { sideslip = 180 + sideslip; } double shockTemp = v.externalTemperature; //External (air) temperature //Get current vessel Vector3d vLift = Vector3d.zero; // the sum of lift from all parts Vector3d vDrag = Vector3d.zero; // the sum of drag from all parts double sqrMag = v.srf_velocity.sqrMagnitude; //Square magnitude of vessel surface velocity double Q = 0.5 * v.atmDensity * sqrMag; // dynamic pressure, aka Q // i.e. your airspeed at sea level with the same Q double soundSpeed = v.speedOfSound; //Speed of sound (m/s) double mach = v.mach; // Loop through all parts, checking modules in each part, to get sum of drag and lift. for (int i = 0; i < v.Parts.Count; ++i) { Part p = v.Parts[i]; // get part drag (but not wing/surface drag) vDrag += -p.dragVectorDir * p.dragScalar; if (!p.hasLiftModule) { //Get body lift Vector3 bodyLift = p.transform.rotation * (p.bodyLiftScalar * p.DragCubes.LiftForce); bodyLift = Vector3.ProjectOnPlane(bodyLift, -p.dragVectorDir); vLift += bodyLift; } // now find modules for (int j = 0; j < p.Modules.Count; ++j) { var m = p.Modules[j]; if (m is ModuleLiftingSurface) // control surface derives from this { //Retrieve wind lift/drag ModuleLiftingSurface wing = (ModuleLiftingSurface)m; vLift += wing.liftForce; vDrag += wing.dragForce; } } } Vector3d force = vLift + vDrag; // sum of all forces on the craft Vector3d liftDir = -Vector3d.Cross(v.transform.right, nVel); // we need the "lift" direction, which // is "up" from our current velocity vector and roll angle. // Now we can compute the dots. double lift = Vector3d.Dot(force, liftDir); // just the force in the 'lift' direction double drag = Vector3d.Dot(force, -nVel); // drag force, = pDrag + lift-induced drag double ldRatio = lift / drag; // Lift / Drag ratio aero_data.alpha = alpha; aero_data.sideslip = sideslip; aero_data.soundSpeed = soundSpeed; aero_data.mach = mach; aero_data.Q = Q; aero_data.lift = lift; aero_data.drag = drag; aero_data.ldRatio = ldRatio; aero_data.shockTemp = shockTemp; return(aero_data); }