public int ExportSweep(CelestialBody body, double pitch, int flapSetting, bool spoilers) { if (!IsReady()) { return(0); } FARAeroUtil.UpdateCurrentActiveBody(body); FARAeroUtil.ResetEditorParts(); StaticAnalysisExportFile exportdata = new StaticAnalysisExportFile(); InstantConditionSimInput input = new InstantConditionSimInput(0, 0, 0, 0, 0, 0, FlightEnv.NewDefaultVal(body), pitch, flapSetting, spoilers); InstantConditionSimOutput output; Vector3d centerofmass = _instantCondition.GetCoM(); // Loop through each combination (two dimensions). foreach (float mach in exportdata.MachNumberList) { input.fltenv.MachNumber = mach; input.alpha = 0; // zero is used as a neutral value for the reset _instantCondition.ResetClCdCmSteady(centerofmass, input); // reset old results (particularly cossweep) that may not reflect the current mach number foreach (float aoadeg in exportdata.AoADegreeList) { input.alpha = aoadeg; _instantCondition.GetClCdCmSteady(input, out output, true, true); exportdata.AddDatapoint(mach, aoadeg, output.Cl, output.Cd, output.Cm); } } exportdata.Export(); return(exportdata.DataCount); }
public override void FixedUpdate() { currentDrag = 0; // With unity objects, "foo" or "foo != null" calls a method to check if // it's destroyed. (object)foo != null just checks if it is actually null. if (start != StartState.Editor && (object)part != null) { if (animatingPart) { UpdatePropertiesWithAnimation(); } if (!isShielded) { Rigidbody rb = part.Rigidbody; Vessel vessel = part.vessel; // Check that rb is not destroyed, but vessel is just not null if (rb && (object)vessel != null && vessel.atmDensity > 0) { Vector3d velocity = rb.velocity + Krakensbane.GetFrameVelocity(); double soundspeed, v_scalar = velocity.magnitude; double rho = FARAeroUtil.GetCurrentDensity(vessel, out soundspeed); if (rho > 0 && v_scalar > 0.1) { Vector3d force = RunDragCalculation(velocity, v_scalar / soundspeed, rho); rb.AddForceAtPosition(force, GetCoD()); } } } } }
public void SimulateAeroProperties(out Vector3 aeroForce, out Vector3 aeroTorque, Vector3 velocityWorldVector, double altitude) { // Rodhern: It seems that this method, 'SimulateAeroProperties', is only used in FARAPI, which in turn can be used by say KSPTrajectories. // The parameter 'FARCenterQuery dummy' is from a code fix by Benjamin Chung (commit 18fbb9d29431679a4de9dfc22a443f400d2d4f8b). FARCenterQuery center = new FARCenterQuery(); FARCenterQuery dummy = new FARCenterQuery(); float pressure; float density; float temperature; float speedOfSound; CelestialBody body = vessel.mainBody; //Calculate main gas properties pressure = (float)body.GetPressure(altitude); temperature = (float)body.GetTemperature(altitude); density = (float)body.GetDensity(pressure, temperature); speedOfSound = (float)body.GetSpeedOfSound(pressure, density); if (pressure <= 0 || temperature <= 0 || density <= 0 || speedOfSound <= 0) { aeroForce = Vector3.zero; aeroTorque = Vector3.zero; return; } float velocityMag = velocityWorldVector.magnitude; float machNumber = velocityMag / speedOfSound; float reynoldsNumber = (float)FARAeroUtil.CalculateReynoldsNumber(density, Length, velocityMag, machNumber, temperature, body.atmosphereAdiabaticIndex); float reynoldsPerLength = reynoldsNumber / (float)Length; float pseudoKnudsenNumber = machNumber / (reynoldsNumber + machNumber); float skinFriction = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber); FlightEnv fenv = FlightEnv.NewPredicted(vessel.mainBody, altitude, machNumber); if (_currentAeroSections != null) { for (int i = 0; i < _currentAeroSections.Count; i++) { FARAeroSection curSection = _currentAeroSections[i]; if (curSection != null) { curSection.PredictionCalculateAeroForces(density, machNumber, reynoldsPerLength, pseudoKnudsenNumber, skinFriction, velocityWorldVector, center); } } for (int i = 0; i < _legacyWingModels.Count; i++) { FARWingAerodynamicModel curWing = _legacyWingModels[i]; if ((object)curWing != null) { Vector3d force = curWing.PrecomputeCenterOfLift(velocityWorldVector, fenv, dummy); center.AddForce(curWing.transform.position, force); } } } aeroForce = center.force; aeroTorque = center.TorqueAt(vessel.CoM); }
public void FixedUpdate() { if (aerodynamicModel_ != null && vessel_ != null) { CelestialBody body = vessel_.orbit.referenceBody; Vector3d bodySpacePosition = vessel_.GetWorldPos3D() - body.position; Vector3d bodySpaceVelocity = vessel_.obt_velocity; double altitudeAboveSea = bodySpacePosition.magnitude - body.Radius; Vector3d airVelocity = bodySpaceVelocity - body.getRFrmVel(body.position + bodySpacePosition); #if DEBUG_COMPARE_FORCES Vector3d FARForce = FARBasicDragModel.debugForceAccumulator + FARWingAerodynamicModel.debugForceAccumulator; FARBasicDragModel.debugForceAccumulator = new Vector3d(0, 0, 0); FARWingAerodynamicModel.debugForceAccumulator = new Vector3d(0, 0, 0); double rho = FARAeroUtil.GetCurrentDensity(body, altitudeAboveSea); //double rho = vessel_.atmDensity; //double pressure = FlightGlobals.getStaticPressure(altitudeAboveSea, body); //double rho = FlightGlobals.getAtmDensity(pressure); double machNumber = FARAeroUtil.GetMachNumber(body, altitudeAboveSea, airVelocity); //double machNumber = airVelocity.magnitude / 300.0; 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; } Vector3d predictedForce = aerodynamicModel_.computeForces_FAR(rho, machNumber, airVelocity, vesselUp, AoA, 0.05); aerodynamicModel_.Verbose = true; Vector3d predictedForceWithCache = aerodynamicModel_.computeForces(body, bodySpacePosition, airVelocity, AoA, 0.05); aerodynamicModel_.Verbose = false; Vector3d localFARForce = new Vector3d(Vector3d.Dot(FARForce, vesselRight), Vector3d.Dot(FARForce, vesselUp), Vector3d.Dot(FARForce, 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("FAR/predict comparison", "air vel=" + Math.Floor(airVelocity.magnitude) + ", AoA=" + (AoA * 180.0 / Math.PI) + ", FAR force=" + localFARForce + ", predicted force=" + localPredictedForce); Util.PostSingleScreenMessage("predict with cache", "predicted force with cache=" + localPredictedForceWithCache); #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") + " ; approximateRho=" + approximateRho.ToString("0.0000") + " ; actualRho=" + actualRho.ToString("0.0000")); } }
public void LateUpdate() { FARAeroUtil.ResetEditorParts(); FARBaseAerodynamics.GlobalCoLReady = false; if (EditorLogic.fetch) { if (editorGUI == null) { editorGUI = new FAREditorGUI(); //editorGUI.LoadGUIParameters(); editorGUI.RestartCtrlGUI(); } if (EditorLogic.startPod != null) { var editorShip = FARAeroUtil.AllEditorParts; if (FARAeroUtil.EditorAboutToAttach() && count++ >= 10) { EditorPartsChanged = true; count = 0; } if (part_count_all != editorShip.Count || part_count_ship != EditorLogic.SortedShipList.Count || EditorPartsChanged) { FindPartsWithoutFARModel(editorShip); foreach (Part p in editorShip) { foreach (PartModule m in p.Modules) { if (m is FARBaseAerodynamics) { (m as FARBaseAerodynamics).ClearShielding(); } } } foreach (Part p in editorShip) { foreach (PartModule m in p.Modules) { if (m is FARPartModule) { (m as FARPartModule).ForceOnVesselPartsChange(); } } } part_count_all = editorShip.Count; part_count_ship = EditorLogic.SortedShipList.Count; EditorPartsChanged = false; } } } }
public void SimulateAeroProperties(out Vector3 aeroForce, out Vector3 aeroTorque, Vector3 velocityWorldVector, double altitude) { FARCenterQuery center = new FARCenterQuery(); float pressure; float density; float temperature; float speedOfSound; CelestialBody body = vessel.mainBody; //Calculate main gas properties pressure = (float)body.GetPressure(altitude); temperature = (float)body.GetTemperature(altitude); density = (float)body.GetDensity(pressure, temperature); speedOfSound = (float)body.GetSpeedOfSound(pressure, density); if (pressure <= 0 || temperature <= 0 || density <= 0 || speedOfSound <= 0) { aeroForce = Vector3.zero; aeroTorque = Vector3.zero; return; } float velocityMag = velocityWorldVector.magnitude; float machNumber = velocityMag / speedOfSound; float reynoldsNumber = (float)FARAeroUtil.CalculateReynoldsNumber(density, Length, velocityMag, machNumber, temperature, body.atmosphereAdiabaticIndex); float reynoldsPerLength = reynoldsNumber / (float)Length; float skinFriction = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber); float pseudoKnudsenNumber = machNumber / (reynoldsNumber + machNumber); if (_currentAeroSections != null) { for (int i = 0; i < _currentAeroSections.Count; i++) { FARAeroSection curSection = _currentAeroSections[i]; if (curSection != null) { curSection.PredictionCalculateAeroForces(density, machNumber, reynoldsPerLength, pseudoKnudsenNumber, skinFriction, velocityWorldVector, center); } } for (int i = 0; i < _legacyWingModels.Count; i++) { FARWingAerodynamicModel curWing = _legacyWingModels[i]; if ((object)curWing != null) { curWing.PrecomputeCenterOfLift(velocityWorldVector, machNumber, density, center); } } } aeroForce = center.force; aeroTorque = center.TorqueAt(vessel.CoM); }
private void CalculateAndApplyVesselAeroProperties() { float atmDensity = (float)_vessel.atmDensity; if (atmDensity <= 0) { machNumber = 0; reynoldsNumber = 0; return; } machNumber = _vessel.mach; reynoldsNumber = FARAeroUtil.CalculateReynoldsNumber(_vessel.atmDensity, Length, _vessel.srfSpeed, machNumber, FlightGlobals.getExternalTemperature((float)_vessel.altitude, _vessel.mainBody), _vessel.mainBody.atmosphereAdiabaticIndex); float skinFrictionDragCoefficient = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber); Vector3 frameVel = Krakensbane.GetFrameVelocityV3f(); if (_updateQueued) //only happens if we have an voxelization scheduled, then we need to check for null { for (int i = _currentAeroModules.Count - 1; i >= 0; i--) //start from the top and come down to improve performance if it needs to remove anything { FARAeroPartModule m = _currentAeroModules[i]; if (m != null) { m.UpdateVelocityAndAngVelocity(frameVel); } else { _currentAeroModules.RemoveAt(i); i++; } } } else //otherwise, we don't need to do Unity's expensive "is this part dead" null-check { for (int i = _currentAeroModules.Count - 1; i >= 0; i--) //start from the top and come down to improve performance if it needs to remove anything { FARAeroPartModule m = _currentAeroModules[i]; m.UpdateVelocityAndAngVelocity(frameVel); } } for (int i = 0; i < _currentAeroSections.Count; i++) { _currentAeroSections[i].FlightCalculateAeroForces(atmDensity, (float)machNumber, (float)(reynoldsNumber / Length), skinFrictionDragCoefficient); } _vesselIntakeRamDrag.ApplyIntakeRamDrag((float)machNumber, _vessel.srf_velocity.normalized, (float)_vessel.dynamicPressurekPa); for (int i = 0; i < _currentAeroModules.Count; i++) { FARAeroPartModule m = _currentAeroModules[i]; m.ApplyForces(); } }
private void StabDerivCalcButtonAction(CalcAndExportEnum exportflag) { CelestialBody body = _bodySettingDropdown.ActiveSelection; FARAeroUtil.UpdateCurrentActiveBody(body); altitude = Regex.Replace(altitude, @"[^-?[0-9]*(\.[0-9]*)?]", ""); double altitudeDouble = Convert.ToDouble(altitude) * 1000; machNumber = Regex.Replace(machNumber, @"[^-?[0-9]*(\.[0-9]*)?]", ""); double machDouble = FARMathUtil.Clamp(Convert.ToSingle(machNumber), 0.001, float.PositiveInfinity); int flapsettingInt = _flapSettingDropdown.ActiveSelection; bool spoilersDeployedBool = spoilersDeployed; if (exportflag == CalcAndExportEnum.LoopExport) { int n = 0; ExportTextFileCache filecache = new ExportTextFileCache(); foreach (Vector2 altmach in StabilityDerivativeExportFile.LoadConfigList()) { StabilityDerivExportOutput output = simManager.StabDerivCalculator.CalculateStabilityDerivs(body, (double)altmach.x, (double)altmach.y, flapsettingInt, spoilersDeployedBool); if (AoAOk(output, exportflag) && StabilityDerivativeExportFile.Export(output, filecache)) { n++; } } if (n > 0) { filecache.FlushTextFileLines(); PopupDialog.SpawnPopupDialog(new Vector2(0, 0), new Vector2(0, 0), "FARStabDerivLoopCount", Localizer.Format("FAREditorStabDerivLoopDone"), Localizer.Format("FAREditorStabDerivLoopDoneExp", n), Localizer.Format("FARGUIOKButton"), true, HighLogic.UISkin); } else { PopupDialog.SpawnPopupDialog(new Vector2(0, 0), new Vector2(0, 0), "FARStabDerivSaveError", Localizer.Format("FAREditorStabDerivSaveError"), Localizer.Format("FAREditorStabDerivSaveErrorExp"), Localizer.Format("FARGUIOKButton"), true, HighLogic.UISkin); } return; // in the LoopExport case skip the usual calculation } StabilityDerivExportOutput stabDerivResult = simManager.StabDerivCalculator.CalculateStabilityDerivs(body, altitudeDouble, machDouble, flapsettingInt, spoilersDeployedBool); if (!AoAOk(stabDerivResult, exportflag)) { PopupDialog.SpawnPopupDialog(new Vector2(0, 0), new Vector2(0, 0), "FARStabDerivError", Localizer.Format("FAREditorStabDerivError"), Localizer.Format("FAREditorStabDerivErrorExp"), Localizer.Format("FARGUIOKButton"), true, HighLogic.UISkin); } else { stabDerivOutput = stabDerivResult.outputvals; simManager.vehicleData = stabDerivResult.outputvals; SetAngleVectors(stabDerivResult.outputvals.stableCondition.stableAoA); if (exportflag == CalcAndExportEnum.CalculateAndExport && !StabilityDerivativeExportFile.Export(stabDerivResult)) { PopupDialog.SpawnPopupDialog(new Vector2(0, 0), new Vector2(0, 0), "FARStabDerivSaveError", Localizer.Format("FAREditorStabDerivSaveError"), Localizer.Format("FAREditorStabDerivSaveErrorExp"), Localizer.Format("FARGUIOKButton"), true, HighLogic.UISkin); } } }
private void CalculateAndApplyVesselAeroProperties() { float atmDensity = (float)vessel.atmDensity; if (atmDensity <= 0) { MachNumber = 0; ReynoldsNumber = 0; return; } MachNumber = vessel.mach; ReynoldsNumber = FARAeroUtil.CalculateReynoldsNumber(vessel.atmDensity, Length, vessel.srfSpeed, MachNumber, FlightGlobals.getExternalTemperature((float)vessel .altitude, vessel.mainBody), vessel.mainBody.atmosphereAdiabaticIndex); float skinFrictionDragCoefficient = (float)FARAeroUtil.SkinFrictionDrag(ReynoldsNumber, MachNumber); float pseudoKnudsenNumber = (float)(MachNumber / (ReynoldsNumber + MachNumber)); Vector3 frameVel = Krakensbane.GetFrameVelocityV3f(); //start from the top and come down to improve performance if it needs to remove anything for (int i = _currentAeroModules.Count - 1; i >= 0; i--) { FARAeroPartModule m = _currentAeroModules[i]; if (m != null && m.part != null && m.part.partTransform != null) { m.UpdateVelocityAndAngVelocity(frameVel); } else { _currentAeroModules.RemoveAt(i); } } foreach (FARAeroSection aeroSection in _currentAeroSections) { aeroSection.FlightCalculateAeroForces((float)MachNumber, (float)(ReynoldsNumber / Length), pseudoKnudsenNumber, skinFrictionDragCoefficient); } _vesselIntakeRamDrag.ApplyIntakeRamDrag((float)MachNumber, vessel.srf_velocity.normalized); foreach (FARAeroPartModule m in _currentAeroModules) { m.ApplyForces(); } }
public double CalculateIAS() { double pressureRatio = FARAeroUtil.RayleighPitotTubeStagPressure(_vessel.mach); //stag pressure at pitot tube face / ambient pressure double velocity = pressureRatio - 1; velocity *= _vessel.staticPressurekPa * 1000 * 2; velocity /= 1.225; velocity = Math.Sqrt(velocity); return(velocity); }
public void LateUpdate() { if (!CompatibilityChecker.IsAllCompatible()) { return; } FARAeroUtil.ResetEditorParts(); FARBaseAerodynamics.GlobalCoLReady = false; if (EditorLogic.fetch) { if (editorGUI == null) { editorGUI = new FAREditorGUI(); //editorGUI.LoadGUIParameters(); editorGUI.RestartCtrlGUI(); GameEvents.onEditorUndo.Add(editorGUI.ResetAll); GameEvents.onEditorRedo.Add(editorGUI.ResetAll); } if (EditorLogic.RootPart != null) { editorShip = FARAeroUtil.AllEditorParts; if (buttonsNeedInitializing) { InitializeButtons(); } /*if (EditorLogic.RootPart != lastRootPart) * { * lastRootPart = EditorLogic.RootPart; * EditorPartsChanged = true; * }*/ if (FARAeroUtil.EditorAboutToAttach() && count++ >= 20) { EditorPartsChanged = true; count = 0; } if (part_count_all != editorShip.Count || part_count_ship != EditorLogic.SortedShipList.Count || EditorPartsChanged) { UpdateEditorShipModules(); } } else if (!buttonsNeedInitializing) { DestroyButtons(); } } }
private void UpdateCargoParts() { if (HighLogic.LoadedSceneIsEditor && FARAeroUtil.EditorAboutToAttach(false) && !FARAeroUtil.CurEditorParts.Contains(part)) { return; } if (bayAnim == null || !bayOpen || HighLogic.LoadedSceneIsEditor) { FindShieldedParts(); } }
private void UpdateCargoParts() { if (start == StartState.Editor && FARAeroUtil.EditorAboutToAttach(false) && !FARAeroUtil.CurEditorParts.Contains(part)) { return; } if (bayAnim == null || !bayOpen || start == StartState.Editor) { FindShieldedParts(); } }
public double CalculateIAS() { // Rodhern: Presumably _vessel.mach ignores FARWind, which might not be the intended behaviour. double pressureRatio = FARAeroUtil.RayleighPitotTubeStagPressure(_vessel.mach); //stag pressure at pitot tube face / ambient pressure double velocity = pressureRatio - 1; velocity *= _vessel.staticPressurekPa * 1000 * 2; velocity /= 1.225; velocity = Math.Sqrt(velocity); return(velocity); }
public double CalculateIAS() { //stag pressure at pitot tube face / ambient pressure double pressureRatio = FARAeroUtil.RayleighPitotTubeStagPressure(_vessel.mach); double velocity = pressureRatio - 1; velocity *= FARAtmosphere.GetPressure(_vessel) * 2; velocity /= 1.225; velocity = Math.Sqrt(velocity); return(velocity); }
public GraphData MachNumberSweep( double aoAdegrees, double pitch, double lowerBound, double upperBound, int numPoints, int flapSetting, bool spoilers, CelestialBody body ) { FARAeroUtil.UpdateCurrentActiveBody(body); FARAeroUtil.ResetEditorParts(); var ClValues = new double[numPoints]; var CdValues = new double[numPoints]; var CmValues = new double[numPoints]; var LDValues = new double[numPoints]; var AlphaValues = new double[numPoints]; var input = new InstantConditionSimInput(aoAdegrees, 0, 0, 0, 0, 0, 0, pitch, flapSetting, spoilers); for (int i = 0; i < numPoints; i++) { input.machNumber = i / (double)numPoints * (upperBound - lowerBound) + lowerBound; if (input.machNumber.NearlyEqual(0)) { input.machNumber = 0.001; } _instantCondition.GetClCdCmSteady(input, out InstantConditionSimOutput output, i == 0); AlphaValues[i] = input.machNumber; ClValues[i] = output.Cl; CdValues[i] = output.Cd; CmValues[i] = output.Cm; LDValues[i] = output.Cl * 0.1 / output.Cd; } var data = new GraphData { xValues = AlphaValues }; data.AddData(ClValues, FARConfig.GUIColors.ClColor, Localizer.Format("FARAbbrevCl"), true); data.AddData(CdValues, FARConfig.GUIColors.CdColor, Localizer.Format("FARAbbrevCd"), true); data.AddData(CmValues, FARConfig.GUIColors.CmColor, Localizer.Format("FARAbbrevCm"), true); data.AddData(LDValues, FARConfig.GUIColors.LdColor, Localizer.Format("FARAbbrevL_D"), true); return(data); }
public static void SaveConfigs() { config.SetValue("displayForces", FARDebugValues.displayForces.ToString()); config.SetValue("displayCoefficients", FARDebugValues.displayCoefficients.ToString()); config.SetValue("displayShielding", FARDebugValues.displayShielding.ToString()); config.SetValue("useSplinesForSupersonicMath", FARDebugValues.useSplinesForSupersonicMath.ToString()); config.SetValue("allowStructuralFailures", FARDebugValues.allowStructuralFailures.ToString()); FARAeroUtil.SaveCustomAeroDataToConfig(); FARPartClassification.SaveCustomClassificationTemplates(); FARAeroStress.SaveCustomStressTemplates(); config.save(); }
public static void LoadConfigs() { config = KSP.IO.PluginConfiguration.CreateForType <FARDebugOptions>(); config.load(); FARDebugValues.displayForces = Convert.ToBoolean(config.GetValue("displayForces", "false")); FARDebugValues.displayCoefficients = Convert.ToBoolean(config.GetValue("displayCoefficients", "false")); FARDebugValues.displayShielding = Convert.ToBoolean(config.GetValue("displayShielding", "false")); FARDebugValues.useSplinesForSupersonicMath = Convert.ToBoolean(config.GetValue("useSplinesForSupersonicMath", "true")); FARDebugValues.allowStructuralFailures = Convert.ToBoolean(config.GetValue("allowStructuralFailures", "true")); FARAeroStress.LoadStressTemplates(); FARPartClassification.LoadClassificationTemplates(); FARAeroUtil.LoadAeroDataFromConfig(); }
private void ResetEditorEvent(ShipConstruct construct) { FARAeroUtil.ResetEditorParts(); // Rodhern: Partial fix to https://github.com/ferram4/Ferram-Aerospace-Research/issues/177 . if (EditorLogic.RootPart != null) { List <Part> partsList = EditorLogic.SortedShipList; for (int i = 0; i < partsList.Count; i++) { UpdateGeometryModule(partsList[i]); } } RequestUpdateVoxel(); }
private double MachDragEffect(double M) { double multiplier = 1; if (M <= 1) { multiplier = 1 + 0.4 * FARAeroUtil.ExponentialApproximation(10 * M - 10); } //multiplier = 1f + 0.4f * Mathf.Exp(10 * M - 10f); //Exponentially increases, mostly from 0.8 to 1; Models Drag divergence due to locally supersonic flow around object at flight Mach Numbers < 1 else { multiplier = 0.15 / M + 1.25; //Cd drops after Mach 1 } return(multiplier); }
private void ResetEditorEvent(ShipConstruct construct) { FARAeroUtil.ResetEditorParts(); if (EditorLogic.RootPart != null) { List <Part> partsList = EditorLogic.SortedShipList; for (int i = 0; i < partsList.Count; i++) { UpdateGeometryModule(partsList[i]); } } RequestUpdateVoxel(); }
public static void LoadConfigs() { config = KSP.IO.PluginConfiguration.CreateForType <FAREditorGUI>(); config.load(); FARControlSys.windowPos = config.GetValue("FlightWindowPos", new Rect(100, 100, 150, 100)); FARControlSys.AutopilotWinPos = config.GetValue("AutopilotWinPos", new Rect()); FARControlSys.HelpWindowPos = config.GetValue("HelpWindowPos", new Rect()); FARControlSys.FlightDataPos = config.GetValue("FlightDataPos", new Rect()); FARControlSys.FlightDataHelpPos = config.GetValue("FlightDataHelpPos", new Rect()); FARControlSys.AirSpeedPos = config.GetValue("AirSpeedPos", new Rect()); FARControlSys.AirSpeedHelpPos = config.GetValue("AirSpeedHelpPos", new Rect()); FARControlSys.AeroForceTintingPos = config.GetValue("AeroForceTintingPos", new Rect()); //FARControlSys.minimize = config.GetValue<bool>("FlightGUIBool", false); FARControlSys.k_wingleveler_str = config.GetValue("k_wingleveler", "0.05"); FARControlSys.k_wingleveler = Convert.ToDouble(FARControlSys.k_wingleveler_str); FARControlSys.kd_wingleveler_str = config.GetValue("kd_wingleveler", "0.002"); FARControlSys.kd_wingleveler = Convert.ToDouble(FARControlSys.kd_wingleveler_str); FARControlSys.k_yawdamper_str = config.GetValue("k_yawdamper", "0.1"); FARControlSys.k_yawdamper = Convert.ToDouble(FARControlSys.k_yawdamper_str); FARControlSys.k_pitchdamper_str = config.GetValue("k_pitchdamper", "0.25"); FARControlSys.k_pitchdamper = Convert.ToDouble(FARControlSys.k_pitchdamper_str); FARControlSys.k2_pitchdamper_str = config.GetValue("k2_pitchdamper", "0.06"); FARControlSys.k2_pitchdamper = Convert.ToDouble(FARControlSys.k2_pitchdamper_str); FARControlSys.scaleVelocity_str = config.GetValue("scaleVelocity", "150"); FARControlSys.scaleVelocity = Convert.ToDouble(FARControlSys.scaleVelocity_str); FARControlSys.alt_str = config.GetValue("alt", "0"); FARControlSys.alt = Convert.ToDouble(FARControlSys.alt_str); FARControlSys.upperLim_str = config.GetValue("upperLim", "25"); FARControlSys.upperLim = Convert.ToDouble(FARControlSys.upperLim_str); FARControlSys.lowerLim_str = config.GetValue("lowerLim", "-25"); FARControlSys.lowerLim = Convert.ToDouble(FARControlSys.lowerLim_str); FARControlSys.k_limiter_str = config.GetValue("k_limiter", "0.25"); FARControlSys.k_limiter = Convert.ToDouble(FARControlSys.k_limiter_str); FARControlSys.unitMode = (FARControlSys.SurfaceVelUnit)config.GetValue("unitMode", 0); FARControlSys.velMode = (FARControlSys.SurfaceVelMode)config.GetValue("velMode", 0); FARDebugValues.displayForces = Convert.ToBoolean(config.GetValue("displayForces", "false")); FARDebugValues.displayCoefficients = Convert.ToBoolean(config.GetValue("displayCoefficients", "false")); FARDebugValues.displayShielding = Convert.ToBoolean(config.GetValue("displayShielding", "false")); FARDebugValues.useSplinesForSupersonicMath = Convert.ToBoolean(config.GetValue("useSplinesForSupersonicMath", "true")); FARDebugValues.allowStructuralFailures = Convert.ToBoolean(config.GetValue("allowStructuralFailures", "true")); FARAeroStress.LoadStressTemplates(); FARPartClassification.LoadClassificationTemplates(); FARAeroUtil.LoadAeroDataFromConfig(); }
public GraphData MachNumberSweep(double aoAdegrees, double pitch, double lowerBound, double upperBound, int numPoints, int flapSetting, bool spoilers, CelestialBody body) { FARAeroUtil.UpdateCurrentActiveBody(body); FARAeroUtil.ResetEditorParts(); double[] ClValues = new double[(int)numPoints]; double[] CdValues = new double[(int)numPoints]; double[] CmValues = new double[(int)numPoints]; double[] LDValues = new double[(int)numPoints]; double[] AlphaValues = new double[(int)numPoints]; InstantConditionSimInput input = new InstantConditionSimInput(aoAdegrees, 0, 0, 0, 0, 0, FlightEnv.NewDefaultVal(body), pitch, flapSetting, spoilers); for (int i = 0; i < numPoints; i++) { input.fltenv.MachNumber = lowerBound + (upperBound - lowerBound) * (i == 0? 0 : i / (numPoints - 1.0)); if (input.fltenv.MachNumber < 1E-3) { input.fltenv.MachNumber = 1E-3; } InstantConditionSimOutput output; _instantCondition.GetClCdCmSteady(input, out output, i == 0, false); AlphaValues[i] = input.fltenv.MachNumber; ClValues[i] = output.Cl; CdValues[i] = output.Cd; CmValues[i] = output.Cm; LDValues[i] = output.Cl * 0.1 / output.Cd; } GraphData data = new GraphData(); data.xValues = AlphaValues; data.AddData(ClValues, GUIColors.GetColor(0), Localizer.Format("FARAbbrevCl"), true); data.AddData(CdValues, GUIColors.GetColor(1), Localizer.Format("FARAbbrevCd"), true); data.AddData(CmValues, GUIColors.GetColor(2), Localizer.Format("FARAbbrevCm"), true); data.AddData(LDValues, GUIColors.GetColor(3), Localizer.Format("FARAbbrevL_D"), true); data.exportdata.AddSizeVariables(_instantCondition, pitch, flapSetting, spoilers); data.exportdata.AddMachSweepXVariable(aoAdegrees, AlphaValues); data.exportdata.AddYVariables(data); return(data); }
public void GetCoMAndSize(out Vector3d CoM, out double mass, out double area, out double MAC, out double b) { CoM = Vector3d.zero; mass = 0; area = 0; MAC = 0; b = 0; List <Part> partsList = EditorLogic.SortedShipList; for (int i = 0; i < partsList.Count; i++) { Part p = partsList[i]; if (FARAeroUtil.IsNonphysical(p)) { continue; } double partMass = p.mass; if (p.Resources.Count > 0) { partMass += p.GetResourceMass(); } //partMass += p.GetModuleMass(p.mass); // If you want to use GetModuleMass, you need to start from p.partInfo.mass, not p.mass CoM += partMass * (Vector3d)p.transform.TransformPoint(p.CoMOffset); mass += partMass; FARWingAerodynamicModel w = p.GetComponent <FARWingAerodynamicModel>(); if (w != null && !w.isShielded) { area += w.S; MAC += w.GetMAC() * w.S; b += w.Getb_2() * w.S; } } if (area > 0) { MAC /= area; b /= area; } else { area = _maxCrossSectionFromBody; MAC = _bodyLength; b = 1; } CoM /= mass; mass *= 1000; }
private void CalculateAndApplyVesselAeroProperties() { float atmDensity = (float)_vessel.atmDensity; if (atmDensity <= 0) { machNumber = 0; reynoldsNumber = 0; return; } machNumber = _vessel.mach; reynoldsNumber = FARAeroUtil.CalculateReynoldsNumber(_vessel.atmDensity, Length, _vessel.srfSpeed, machNumber, FlightGlobals.getExternalTemperature((float)_vessel.altitude, _vessel.mainBody), _vessel.mainBody.atmosphereAdiabaticIndex); float skinFrictionDragCoefficient = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber); Vector3 frameVel = Krakensbane.GetFrameVelocityV3f(); for (int i = 0; i < _currentAeroModules.Count; i++) { FARAeroPartModule m = _currentAeroModules[i]; if (m != null) { m.UpdateVelocityAndAngVelocity(frameVel); } else { _currentAeroModules.RemoveAt(i); i--; } } for (int i = 0; i < _currentAeroSections.Count; i++) { _currentAeroSections[i].FlightCalculateAeroForces(atmDensity, (float)machNumber, (float)(reynoldsNumber / Length), skinFrictionDragCoefficient); } _vesselIntakeRamDrag.ApplyIntakeRamDrag((float)machNumber, _vessel.srf_velocity.normalized, (float)_vessel.dynamicPressurekPa); for (int i = 0; i < _currentAeroModules.Count; i++) { FARAeroPartModule m = _currentAeroModules[i]; if ((object)m != null) { m.ApplyForces(); } } }
private void UpdatePropertiesWithAnimation() { if (anim) { if (anim.isPlaying && !currentlyAnimating) { currentlyAnimating = true; } else if (currentlyAnimating && !anim.isPlaying) { currentlyAnimating = false; FARAeroUtil.SetBasicDragModuleProperties(this.part); //By doing this, we update the properties of this object AttachNodeCdAdjust(); //In case the node properties somehow update with the node; also to deal with changes in part reference area } // bayProgress = bayAnim[bayAnimationName].normalizedTime; } }
public double GetMachNumber(CelestialBody body, double altitude, Vector3d velocity) { if (start != StartState.Editor) { if (FARControl != null) { return(FARControl.MachNumber); } else { return(FARAeroUtil.GetMachNumber(body, altitude, velocity)); } } else { print("GetMachNumber called in editor"); return(0); } }
public static void LoadConfigs() { config = KSP.IO.PluginConfiguration.CreateForType <FAREditorGUI>(); config.load(); FARDebugValues.displayForces = Convert.ToBoolean(config.GetValue("displayForces", "false")); FARDebugValues.displayCoefficients = Convert.ToBoolean(config.GetValue("displayCoefficients", "false")); FARDebugValues.displayShielding = Convert.ToBoolean(config.GetValue("displayShielding", "false")); FAREditorGUI.windowPos = config.GetValue("windowPos", new Rect()); //FAREditorGUI.minimize = config.GetValue("EditorGUIBool", true); if (FAREditorGUI.windowPos.y < 75) { FAREditorGUI.windowPos.y = 75; } FARPartClassification.LoadClassificationTemplates(); FARAeroUtil.LoadAeroDataFromConfig(); }
public GraphData MachNumberSweep(double aoAdegrees, double pitch, double lowerBound, double upperBound, int numPoints, int flapSetting, bool spoilers, CelestialBody body) { FARAeroUtil.UpdateCurrentActiveBody(body); FARAeroUtil.ResetEditorParts(); double[] ClValues = new double[(int)numPoints]; double[] CdValues = new double[(int)numPoints]; double[] CmValues = new double[(int)numPoints]; double[] LDValues = new double[(int)numPoints]; double[] AlphaValues = new double[(int)numPoints]; InstantConditionSimInput input = new InstantConditionSimInput(aoAdegrees, 0, 0, 0, 0, 0, 0, pitch, flapSetting, spoilers); for (int i = 0; i < numPoints; i++) { input.machNumber = i / (double)numPoints * (upperBound - lowerBound) + lowerBound; if (input.machNumber == 0) { input.machNumber = 0.001; } InstantConditionSimOutput output; _instantCondition.GetClCdCmSteady(input, out output, i == 0); AlphaValues[i] = input.machNumber; ClValues[i] = output.Cl; CdValues[i] = output.Cd; CmValues[i] = output.Cm; LDValues[i] = output.Cl * 0.1 / output.Cd; } GraphData data = new GraphData(); data.xValues = AlphaValues; data.AddData(ClValues, GUIColors.GetColor(0), "Cl", true); data.AddData(CdValues, GUIColors.GetColor(1), "Cd", true); data.AddData(CmValues, GUIColors.GetColor(2), "Cm", true); data.AddData(LDValues, GUIColors.GetColor(3), "L/D", true); return(data); }
public double GetMachNumber(CelestialBody body, double altitude, Vector3d velocity) { if (HighLogic.LoadedSceneIsFlight) { if (FARControl != null) { return(FARControl.MachNumber); } else { return(FARAeroUtil.GetMachNumber(body, altitude, velocity)); } } else { print("GetMachNumber called in editor"); return(0); } }