public static void ResetEditor() { Color crossSection = GUIColors.GetColor(3); crossSection.a = 0.8f; Color crossSectionDeriv = GUIColors.GetColor(2); crossSectionDeriv.a = 0.8f; instance._areaRulingOverlay.RestartOverlay(); //instance._areaRulingOverlay = new EditorAreaRulingOverlay(new Color(0.05f, 0.05f, 0.05f, 0.7f), crossSection, crossSectionDeriv, 10, 5); RequestUpdateVoxel(); }
void Start() { if (CompatibilityChecker.IsAllCompatible() && instance == null) { instance = this; } else { GameObject.Destroy(this); return; } _vehicleAero = new VehicleAerodynamics(); guiRect = new Rect(Screen.width / 4, Screen.height / 6, 10, 10); _instantSim = new InstantConditionSim(); GUIDropDown <int> flapSettingDropDown = new GUIDropDown <int>(new string[] { "0 (up)", "1 (init climb)", "2 (takeoff)", "3 (landing)" }, new int[] { 0, 1, 2, 3 }, 0); GUIDropDown <CelestialBody> celestialBodyDropdown = CreateBodyDropdown(); modeDropdown = new GUIDropDown <FAREditorMode>(FAReditorMode_str, new FAREditorMode[] { FAREditorMode.STATIC, FAREditorMode.STABILITY, FAREditorMode.SIMULATION, FAREditorMode.AREA_RULING }); _simManager = new EditorSimManager(_instantSim); _editorGraph = new StaticAnalysisGraphGUI(_simManager, flapSettingDropDown, celestialBodyDropdown); _stabDeriv = new StabilityDerivGUI(_simManager, flapSettingDropDown, celestialBodyDropdown); _stabDerivLinSim = new StabilityDerivSimulationGUI(_simManager); Color crossSection = GUIColors.GetColor(3); crossSection.a = 0.8f; Color crossSectionDeriv = GUIColors.GetColor(2); crossSectionDeriv.a = 0.8f; _areaRulingOverlay = new EditorAreaRulingOverlay(new Color(0.05f, 0.05f, 0.05f, 0.7f), crossSection, crossSectionDeriv, 10, 5); guiRect.height = 500; guiRect.width = 650; GameEvents.onEditorPartEvent.Add(UpdateGeometryEvent); GameEvents.onEditorUndo.Add(ResetEditorEvent); GameEvents.onEditorRedo.Add(ResetEditorEvent); GameEvents.onEditorShipModified.Add(ResetEditorEvent); GameEvents.onEditorLoad.Add(ResetEditorEvent); GameEvents.onGUIEngineersReportReady.Add(AddDesignConcerns); GameEvents.onGUIEngineersReportDestroy.Add(RemoveDesignConcerns); RequestUpdateVoxel(); }
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, 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); return(data); }
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 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 GraphData RunTransientSimLateral(StabilityDerivOutput vehicleData, double endTime, double initDt, double[] InitCond) { SimMatrix A = new SimMatrix(4, 4); A.PrintToConsole(); int i = 0; int j = 0; int num = 0; double[] Derivs = new double[27]; vehicleData.stabDerivs.CopyTo(Derivs, 0); Derivs[15] = Derivs[15] / vehicleData.nominalVelocity; Derivs[18] = Derivs[18] / vehicleData.nominalVelocity; Derivs[21] = Derivs[21] / vehicleData.nominalVelocity - 1; double Lb = Derivs[16] / (1 - Derivs[26] * Derivs[26] / (Derivs[0] * Derivs[2])); double Nb = Derivs[17] / (1 - Derivs[26] * Derivs[26] / (Derivs[0] * Derivs[2])); double Lp = Derivs[19] / (1 - Derivs[26] * Derivs[26] / (Derivs[0] * Derivs[2])); double Np = Derivs[20] / (1 - Derivs[26] * Derivs[26] / (Derivs[0] * Derivs[2])); double Lr = Derivs[22] / (1 - Derivs[26] * Derivs[26] / (Derivs[0] * Derivs[2])); double Nr = Derivs[23] / (1 - Derivs[26] * Derivs[26] / (Derivs[0] * Derivs[2])); Derivs[16] = Lb + Derivs[26] / Derivs[0] * Nb; Derivs[17] = Nb + Derivs[26] / Derivs[2] * Lb; Derivs[19] = Lp + Derivs[26] / Derivs[0] * Np; Derivs[20] = Np + Derivs[26] / Derivs[2] * Lp; Derivs[22] = Lr + Derivs[26] / Derivs[0] * Nr; Derivs[23] = Nr + Derivs[26] / Derivs[2] * Lr; for (int k = 0; k < Derivs.Length; k++) { double f = Derivs[k]; if (num < 15) { num++; //Avoid Ix, Iy, Iz and long derivs continue; } else { num++; } FARLogger.Info("" + i + "," + j); if (i <= 2) { A.Add(f, i, j); } if (j < 2) { j++; } else { j = 0; i++; } } A.Add(_instantCondition.CalculateAccelerationDueToGravity(vehicleData.body, vehicleData.altitude) * Math.Cos(vehicleData.stableAoA * Math.PI / 180) / vehicleData.nominalVelocity, 3, 0); A.Add(1, 1, 3); A.PrintToConsole(); //We should have an array that looks like this: /* i ---------------> * j [ Yb / u0 , Yp / u0 , -(1 - Yr/ u0) , g Cos(θ0) / u0 ] * | [ Lb , Lp , Lr , 0 ] * | [ Nb , Np , Nr , 0 ] * \ / [ 0 , 1 , 0 , 0 ] * V //And one that looks like this: * * [ Z e ] * [ X e ] * [ M e ] * [ 0 ] * * */ RungeKutta4 transSolve = new RungeKutta4(endTime, initDt, A, InitCond); transSolve.Solve(); GraphData lines = new GraphData(); lines.xValues = transSolve.time; double[] yVal = transSolve.GetSolution(0); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(3), "β", true); yVal = transSolve.GetSolution(1); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(2), "p", true); yVal = transSolve.GetSolution(2); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(1), "r", true); yVal = transSolve.GetSolution(3); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(0), "φ", true); /*graph.SetBoundaries(0, endTime, -10, 10); * graph.SetGridScaleUsingValues(1, 5); * graph.horizontalLabel = "time"; * graph.verticalLabel = "value"; * graph.Update();*/ return(lines); }
public GraphData RunTransientSimLongitudinal(StabilityDerivOutput vehicleData, double endTime, double initDt, double[] InitCond) { SimMatrix A = new SimMatrix(4, 4); SimMatrix B = new SimMatrix(1, 4); A.PrintToConsole(); int i = 0; int j = 0; int num = 0; double[] Derivs = new double[27]; for (int k = 0; k < vehicleData.stabDerivs.Length; k++) { double f = vehicleData.stabDerivs[k]; if (num < 3 || num >= 15) { num++; //Avoid Ix, Iy, Iz continue; } else { num++; } FARLogger.Info(i + "," + j); if (i <= 2) { if (num == 10) { A.Add(f + vehicleData.nominalVelocity, i, j); } else { A.Add(f, i, j); } } else { B.Add(f, 0, j); } if (j < 2) { j++; } else { j = 0; i++; } } A.Add(-_instantCondition.CalculateAccelerationDueToGravity(vehicleData.body, vehicleData.altitude), 3, 1); A.Add(1, 2, 3); A.PrintToConsole(); //We should have an array that looks like this: /* i ---------------> * j [ Z w , Z u , Z q + u, 0 ] * | [ X w , X u , X q , -g ] * | [ M w , M u , M q , 0 ] * \ / [ 0 , 0 , 1 , 0 ] * V //And one that looks like this: * * [ Z e ] * [ X e ] * [ M e ] * [ 0 ] * * */ RungeKutta4 transSolve = new RungeKutta4(endTime, initDt, A, InitCond); transSolve.Solve(); GraphData lines = new GraphData(); lines.xValues = transSolve.time; double[] yVal = transSolve.GetSolution(0); ScaleAndClampValues(yVal, 1, 50); lines.AddData(yVal, GUIColors.GetColor(3), "w", true); yVal = transSolve.GetSolution(1); ScaleAndClampValues(yVal, 1, 50); lines.AddData(yVal, GUIColors.GetColor(2), "u", true); yVal = transSolve.GetSolution(2); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(1), "q", true); yVal = transSolve.GetSolution(3); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(0), "θ", true); /*graph.SetBoundaries(0, endTime, -10, 10); * graph.SetGridScaleUsingValues(1, 5); * graph.horizontalLabel = "time"; * graph.verticalLabel = "value"; * graph.Update();*/ return(lines); }
public GraphData AngleOfAttackSweep(double machNumber, double pitch, double lowerBound, double upperBound, int numPoints, int flapSetting, bool spoilers, CelestialBody body) { if (machNumber == 0) { machNumber = 0.001; } InstantConditionSimInput input = new InstantConditionSimInput(0, 0, 0, 0, 0, 0, machNumber, pitch, flapSetting, spoilers); 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]; double[] ClValues2 = new double[(int)numPoints]; double[] CdValues2 = new double[(int)numPoints]; double[] CmValues2 = new double[(int)numPoints]; double[] LDValues2 = new double[(int)numPoints]; for (int i = 0; i < 2 * numPoints; i++) { double angle = 0; if (i < numPoints) { angle = i / (double)numPoints * (upperBound - lowerBound) + lowerBound; } else { angle = (i - (double)numPoints + 1) / (double)numPoints * (lowerBound - upperBound) + upperBound; } input.alpha = angle; InstantConditionSimOutput output; _instantCondition.GetClCdCmSteady(input, out output, i == 0); // MonoBehaviour.print("Cl: " + Cl + " Cd: " + Cd); if (i < numPoints) { AlphaValues[i] = angle; ClValues[i] = output.Cl; CdValues[i] = output.Cd; CmValues[i] = output.Cm; LDValues[i] = output.Cl * 0.1 / output.Cd; } else { ClValues2[numPoints * 2 - 1 - i] = output.Cl; CdValues2[numPoints * 2 - 1 - i] = output.Cd; CmValues2[numPoints * 2 - 1 - i] = output.Cm; LDValues2[numPoints * 2 - 1 - i] = output.Cl * 0.1 / output.Cd; } } GraphData data = new GraphData(); data.xValues = AlphaValues; data.AddData(ClValues2, GUIColors.GetColor(0) * 0.5f, "Cl2", false); data.AddData(ClValues, GUIColors.GetColor(0), "Cl", true); data.AddData(CdValues2, GUIColors.GetColor(1) * 0.5f, "Cd2", false); data.AddData(CdValues, GUIColors.GetColor(1), "Cd", true); data.AddData(CmValues2, GUIColors.GetColor(2) * 0.5f, "Cm2", false); data.AddData(CmValues, GUIColors.GetColor(2), "Cm", true); data.AddData(LDValues2, GUIColors.GetColor(3) * 0.5f, "L/D2", false); data.AddData(LDValues, GUIColors.GetColor(3), "L/D", true); return(data); }
private void UpdateAeroDisplay() { Vector3 worldDragArrow = Vector3.zero; Vector3 worldLiftArrow = Vector3.zero; if ((PhysicsGlobals.AeroForceDisplay || PhysicsGlobals.AeroDataDisplay) && !part.ShieldedFromAirstream) { Vector3 worldVelNorm = partTransform.localToWorldMatrix.MultiplyVector(partLocalVelNorm); worldDragArrow = Vector3.Dot(worldSpaceAeroForce, worldVelNorm) * worldVelNorm; worldLiftArrow = worldSpaceAeroForce - worldDragArrow; } if (PhysicsGlobals.AeroForceDisplay && !part.ShieldedFromAirstream) { if (liftArrow == null) { liftArrow = ArrowPointer.Create(partTransform, Vector3.zero, worldLiftArrow, worldLiftArrow.magnitude * FARKSPAddonFlightScene.FARAeroForceDisplayScale, GUIColors.GetColor(0), true); } else { liftArrow.Direction = worldLiftArrow; liftArrow.Length = worldLiftArrow.magnitude * FARKSPAddonFlightScene.FARAeroForceDisplayScale; } if (dragArrow == null) { dragArrow = ArrowPointer.Create(partTransform, Vector3.zero, worldDragArrow, worldDragArrow.magnitude * FARKSPAddonFlightScene.FARAeroForceDisplayScale, GUIColors.GetColor(1), true); } else { dragArrow.Direction = worldDragArrow; dragArrow.Length = worldDragArrow.magnitude * FARKSPAddonFlightScene.FARAeroForceDisplayScale; } if (FARDebugValues.showMomentArrows) { if (momentArrow == null) { momentArrow = ArrowPointer.Create(partTransform, Vector3.zero, worldSpaceTorque, worldSpaceTorque.magnitude * FARKSPAddonFlightScene.FARAeroForceDisplayScale, GUIColors.GetColor(2), true); } else { momentArrow.Direction = -worldSpaceTorque; momentArrow.Length = worldSpaceTorque.magnitude * FARKSPAddonFlightScene.FARAeroForceDisplayScale; } } } else { if (!(liftArrow is null)) { Destroy(liftArrow); liftArrow = null; } if (!(dragArrow is null)) { Destroy(dragArrow); dragArrow = null; } if (!(momentArrow is null)) { Destroy(momentArrow); momentArrow = null; } } if (PhysicsGlobals.AeroDataDisplay && !part.ShieldedFromAirstream) { if (!fieldsVisible) { Fields["dragForce"].guiActive = true; Fields["liftForce"].guiActive = true; fieldsVisible = true; } dragForce = worldDragArrow.magnitude; liftForce = worldLiftArrow.magnitude; } else if (fieldsVisible) { Fields["dragForce"].guiActive = false; Fields["liftForce"].guiActive = false; fieldsVisible = false; } }
public static GraphData RunTransientSimLongitudinal( StabilityDerivOutput vehicleData, double endTime, double initDt, double[] InitCond ) { var A = new SimMatrix(4, 4); var B = new SimMatrix(1, 4); A.PrintToConsole(); int i = 0; int j = 0; int num = 0; foreach (double f in vehicleData.stabDerivs) { if (num < 3 || num >= 15) { num++; //Avoid Ix, Iy, Iz continue; } num++; FARLogger.Info(i + "," + j); if (i <= 2) { if (num == 10) { A.Add(f + vehicleData.nominalVelocity, i, j); } else { A.Add(f, i, j); } } else { B.Add(f, 0, j); } if (j < 2) { j++; } else { j = 0; i++; } } A.Add(-InstantConditionSim.CalculateAccelerationDueToGravity(vehicleData.body, vehicleData.altitude), 3, 1); A.Add(1, 2, 3); A.PrintToConsole(); //We should have an array that looks like this: /* i ---------------> * j [ Z w , Z u , Z q + u, 0 ] * | [ X w , X u , X q , -g ] * | [ M w , M u , M q , 0 ] * \ / [ 0 , 0 , 1 , 0 ] * V //And one that looks like this: * * [ Z e ] * [ X e ] * [ M e ] * [ 0 ] * * */ var transSolve = new RungeKutta4(endTime, initDt, A, InitCond); transSolve.Solve(); var lines = new GraphData { xValues = transSolve.time }; double[] yVal = transSolve.GetSolution(0); ScaleAndClampValues(yVal, 1, 50); lines.AddData(yVal, GUIColors.GetColor(3), "w", true); yVal = transSolve.GetSolution(1); ScaleAndClampValues(yVal, 1, 50); lines.AddData(yVal, GUIColors.GetColor(2), "u", true); yVal = transSolve.GetSolution(2); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(1), "q", true); yVal = transSolve.GetSolution(3); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(0), "θ", true); return(lines); }
public GraphData AngleOfAttackSweep( double machNumber, double pitch, double lowerBound, double upperBound, int numPoints, int flapSetting, bool spoilers, CelestialBody body ) { if (machNumber.NearlyEqual(0)) { machNumber = 0.001; } var input = new InstantConditionSimInput(0, 0, 0, 0, 0, 0, machNumber, pitch, flapSetting, spoilers); 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 ClValues2 = new double[numPoints]; var CdValues2 = new double[numPoints]; var CmValues2 = new double[numPoints]; var LDValues2 = new double[numPoints]; for (int i = 0; i < 2 * numPoints; i++) { double angle; if (i < numPoints) { angle = i / (double)numPoints * (upperBound - lowerBound) + lowerBound; } else { angle = (i - (double)numPoints + 1) / numPoints * (lowerBound - upperBound) + upperBound; } input.alpha = angle; _instantCondition.GetClCdCmSteady(input, out InstantConditionSimOutput output, i == 0); if (i < numPoints) { AlphaValues[i] = angle; ClValues[i] = output.Cl; CdValues[i] = output.Cd; CmValues[i] = output.Cm; LDValues[i] = output.Cl * 0.1 / output.Cd; } else { ClValues2[numPoints * 2 - 1 - i] = output.Cl; CdValues2[numPoints * 2 - 1 - i] = output.Cd; CmValues2[numPoints * 2 - 1 - i] = output.Cm; LDValues2[numPoints * 2 - 1 - i] = output.Cl * 0.1 / output.Cd; } } var data = new GraphData { xValues = AlphaValues }; data.AddData(ClValues2, GUIColors.GetColor(0) * 0.5f, "Cl2", false); data.AddData(ClValues, GUIColors.GetColor(0), Localizer.Format("FARAbbrevCl"), true); data.AddData(CdValues2, GUIColors.GetColor(1) * 0.5f, "Cd2", false); data.AddData(CdValues, GUIColors.GetColor(1), Localizer.Format("FARAbbrevCd"), true); data.AddData(CmValues2, GUIColors.GetColor(2) * 0.5f, "Cm2", false); data.AddData(CmValues, GUIColors.GetColor(2), Localizer.Format("FARAbbrevCm"), true); data.AddData(LDValues2, GUIColors.GetColor(3) * 0.5f, "L/D2", false); data.AddData(LDValues, GUIColors.GetColor(3), Localizer.Format("FARAbbrevL_D"), true); return(data); }
private void Start() { if (CompatibilityChecker.IsAllCompatible() && Instance == null) { Instance = this; } else { Destroy(this); return; } showGUI = false; if (FARDebugAndSettings.FARDebugButtonStock) { FARDebugAndSettings.FARDebugButtonStock.SetFalse(false); } _vehicleAero = new VehicleAerodynamics(); // ReSharper disable PossibleLossOfFraction guiRect = new Rect(Screen.width / 4, Screen.height / 6, 10, 10); // ReSharper restore PossibleLossOfFraction _instantSim = new InstantConditionSim(); var flapSettingDropDown = new GUIDropDown <int>(new[] { Localizer.Format("FARFlapSetting0"), Localizer.Format("FARFlapSetting1"), Localizer.Format("FARFlapSetting2"), Localizer.Format("FARFlapSetting3") }, new[] { 0, 1, 2, 3 }); GUIDropDown <CelestialBody> celestialBodyDropdown = CreateBodyDropdown(); modeDropdown = new GUIDropDown <FAREditorMode>(FAReditorMode_str, new[] { FAREditorMode.STATIC, FAREditorMode.STABILITY, FAREditorMode.SIMULATION, FAREditorMode.AREA_RULING }); _simManager = new EditorSimManager(_instantSim); _editorGraph = new StaticAnalysisGraphGUI(_simManager, flapSettingDropDown, celestialBodyDropdown); _stabDeriv = new StabilityDerivGUI(_simManager, flapSettingDropDown, celestialBodyDropdown); _stabDerivLinSim = new StabilityDerivSimulationGUI(_simManager); Color crossSection = GUIColors.GetColor(3); crossSection.a = 0.8f; Color crossSectionDeriv = GUIColors.GetColor(2); crossSectionDeriv.a = 0.8f; _areaRulingOverlay = EditorAreaRulingOverlay.CreateNewAreaRulingOverlay(new Color(0.05f, 0.05f, 0.05f, 0.7f), crossSection, crossSectionDeriv, 10, 5); guiRect.height = 500; guiRect.width = 650; GameEvents.onEditorVariantApplied.Add(UpdateGeometryEvent); GameEvents.onEditorPartEvent.Add(UpdateGeometryEvent); GameEvents.onEditorUndo.Add(ResetEditorEvent); GameEvents.onEditorRedo.Add(ResetEditorEvent); GameEvents.onEditorShipModified.Add(ResetEditorEvent); GameEvents.onEditorLoad.Add(ResetEditorEvent); GameEvents.onGUIEngineersReportReady.Add(AddDesignConcerns); GameEvents.onGUIEngineersReportDestroy.Add(RemoveDesignConcerns); RequestUpdateVoxel(); }
public GraphData AngleOfAttackSweep(double machNumber, double pitch, double lowerBound, double upperBound, int numPoints, int flapSetting, bool spoilers, CelestialBody body) { if (machNumber < 1E-3) { machNumber = 1E-3; } 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]; double[] ClValues2 = new double[(int)numPoints]; double[] CdValues2 = new double[(int)numPoints]; double[] CmValues2 = new double[(int)numPoints]; double[] LDValues2 = new double[(int)numPoints]; InstantConditionSimInput input = new InstantConditionSimInput(0, 0, 0, 0, 0, 0, FlightEnv.NewDefaultVal(body), pitch, flapSetting, spoilers); input.fltenv.MachNumber = machNumber; for (int i = 0; i < 2 * numPoints; i++) { double angle = 0; if (i < numPoints) { angle = lowerBound + (upperBound - lowerBound) * (i == 0? 0 : i / (numPoints - 1.0)); } else { angle = upperBound + (lowerBound - upperBound) * (i == numPoints ? 0 : (i - numPoints) / (numPoints - 1.0)); } input.alpha = angle; InstantConditionSimOutput output; _instantCondition.GetClCdCmSteady(input, out output, i == 0, false); if (i < numPoints) { AlphaValues[i] = angle; ClValues[i] = output.Cl; CdValues[i] = output.Cd; CmValues[i] = output.Cm; LDValues[i] = output.Cl * 0.1 / output.Cd; } else { ClValues2[numPoints * 2 - 1 - i] = output.Cl; CdValues2[numPoints * 2 - 1 - i] = output.Cd; CmValues2[numPoints * 2 - 1 - i] = output.Cm; LDValues2[numPoints * 2 - 1 - i] = output.Cl * 0.1 / output.Cd; } } GraphData data = new GraphData(); data.xValues = AlphaValues; data.AddData(ClValues2, GUIColors.GetColor(0) * 0.5f, "Cl2", false); data.AddData(ClValues, GUIColors.GetColor(0), Localizer.Format("FARAbbrevCl"), true); data.AddData(CdValues2, GUIColors.GetColor(1) * 0.5f, "Cd2", false); data.AddData(CdValues, GUIColors.GetColor(1), Localizer.Format("FARAbbrevCd"), true); data.AddData(CmValues2, GUIColors.GetColor(2) * 0.5f, "Cm2", false); data.AddData(CmValues, GUIColors.GetColor(2), Localizer.Format("FARAbbrevCm"), true); data.AddData(LDValues2, GUIColors.GetColor(3) * 0.5f, "L/D2", false); data.AddData(LDValues, GUIColors.GetColor(3), Localizer.Format("FARAbbrevL_D"), true); data.exportdata.AddSizeVariables(_instantCondition, pitch, flapSetting, spoilers); data.exportdata.AddAoASweepXVariable(machNumber, AlphaValues); data.exportdata.AddYVariables(data); return(data); }
public GraphData RunTransientSimLateral(StabilityDerivOutput vehicleData, double endTime, double initDt, double[] InitCond) { SimMatrix A = new SimMatrix(4, 4); int i = 0; int j = 0; double[] Derivs = new double[27]; vehicleData.stabDerivs.CopyTo(Derivs, 0); double u0 = vehicleData.nominalVelocity; double b2u = vehicleData.b / (2 * u0); double effg = _instantCondition.CalculateEffectiveGravity(vehicleData.body, vehicleData.altitude, u0) * Math.Cos(vehicleData.stableCondition.stableAoA * Math.PI / 180); double factor_xz_x = Derivs[26] / Derivs[0]; double factor_xz_z = Derivs[26] / Derivs[2]; double factor_invxz = 1 / (1 - factor_xz_x * factor_xz_z); FARLogger.Info("u0= " + u0); FARLogger.Info("b/(2u)= " + b2u + " IGNORED!"); FARLogger.Info("effg= " + effg + ", after multiplication with cos(AoA)."); FARLogger.Info("Ixz/Ix= " + factor_xz_x + ", used to add yaw to roll-deriv."); FARLogger.Info("Ixz/Iz= " + factor_xz_z + ", used to add roll to yaw-deriv."); FARLogger.Info("(1 - Ixz^2/(IxIz))^-1= " + factor_invxz); // Rodhern: For possible backward compability the rotation (moment) derivatives can be // scaled by "b/(2u)" (for pitch rate "mac/(2u)"). //for (int h = 18; h <= 23; h++) // Derivs[h] = Derivs[h] * b2u; Derivs[15] = Derivs[15] / u0; Derivs[18] = Derivs[18] / u0; Derivs[21] = Derivs[21] / u0 - 1; double Lb = Derivs[16] * factor_invxz; double Nb = Derivs[17] * factor_invxz; double Lp = Derivs[19] * factor_invxz; double Np = Derivs[20] * factor_invxz; double Lr = Derivs[22] * factor_invxz; double Nr = Derivs[23] * factor_invxz; Derivs[16] = Lb + factor_xz_x * Nb; Derivs[17] = Nb + factor_xz_z * Lb; Derivs[19] = Lp + factor_xz_x * Np; Derivs[20] = Np + factor_xz_z * Lp; Derivs[22] = Lr + factor_xz_x * Nr; Derivs[23] = Nr + factor_xz_z * Lr; for (int k = 15; k < Derivs.Length; k++) { double f = Derivs[k]; if (i <= 2) { FARLogger.Info("A[" + i + "," + j + "]= f_" + k + " = " + f + ", after manipulation."); A.Add(f, i, j); } if (j < 2) { j++; } else { j = 0; i++; } } A.Add(effg / u0, 3, 0); A.Add(1, 1, 3); A.PrintToConsole(); //We should have an array that looks like this: /* i ---------------> * j [ Yb / u0 , Yp / u0 , -(1 - Yr/ u0) , g Cos(θ0) / u0 ] * | [ Lb , Lp , Lr , 0 ] * | [ Nb , Np , Nr , 0 ] * \ / [ 0 , 1 , 0 , 0 ] * V */ RungeKutta4 transSolve = new RungeKutta4(endTime, initDt, A, InitCond); transSolve.Solve(); GraphData lines = new GraphData(); lines.xValues = transSolve.time; double[] yVal = transSolve.GetSolution(0); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(3), "β", true); yVal = transSolve.GetSolution(1); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(2), "p", true); yVal = transSolve.GetSolution(2); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(1), "r", true); yVal = transSolve.GetSolution(3); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(0), "φ", true); /*graph.SetBoundaries(0, endTime, -10, 10); * graph.SetGridScaleUsingValues(1, 5); * graph.horizontalLabel = "time"; * graph.verticalLabel = "value"; * graph.Update();*/ return(lines); }
public GraphData RunTransientSimLongitudinal(StabilityDerivOutput vehicleData, double endTime, double initDt, double[] InitCond) { SimMatrix A = new SimMatrix(4, 4); int i = 0; int j = 0; double[] Derivs = new double[27]; vehicleData.stabDerivs.CopyTo(Derivs, 0); double MAC2u = vehicleData.MAC / (2 * vehicleData.nominalVelocity); double effg = _instantCondition.CalculateEffectiveGravity(vehicleData.body, vehicleData.altitude, vehicleData.nominalVelocity); FARLogger.Info("MAC/(2u)= " + MAC2u + " IGNORED!"); FARLogger.Info("effg= " + effg); // Rodhern: For possible backward compability the rotation (moment) derivatives can be // scaled by "mac/(2u)" (pitch) and "b/(2u)" (roll and yaw). //for (int h = 9; h <= 11; h++) // Derivs[h] = Derivs[h] * MAC2u; Derivs[9] = Derivs[9] + vehicleData.nominalVelocity; for (int k = 3; k < 15 && k < Derivs.Length; k++) { double f = Derivs[k]; if (i <= 2) { FARLogger.Info("A[" + i + "," + j + "]= f_" + k + " = " + f); A.Add(f, i, j); } else { FARLogger.Debug("Ignore B[0," + j + "]= " + f); } if (j < 2) { j++; } else { j = 0; i++; } } A.Add(-effg, 3, 1); A.Add(1, 2, 3); A.PrintToConsole(); //We should have an array that looks like this: /* i ---------------> * j [ Z w , Z u , Z q + u, 0 ] * | [ X w , X u , X q , -g ] * | [ M w , M u , M q , 0 ] * \ / [ 0 , 0 , 1 , 0 ] * V */ //And one that looks like this: (Unused) /* * [ Z e ] * [ X e ] * [ M e ] * [ 0 ] * */ RungeKutta4 transSolve = new RungeKutta4(endTime, initDt, A, InitCond); transSolve.Solve(); GraphData lines = new GraphData(); lines.xValues = transSolve.time; double[] yVal = transSolve.GetSolution(0); ScaleAndClampValues(yVal, 1, 50); lines.AddData(yVal, GUIColors.GetColor(3), "w", true); yVal = transSolve.GetSolution(1); ScaleAndClampValues(yVal, 1, 50); lines.AddData(yVal, GUIColors.GetColor(2), "u", true); yVal = transSolve.GetSolution(2); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(1), "q", true); yVal = transSolve.GetSolution(3); ScaleAndClampValues(yVal, 180 / Math.PI, 50); lines.AddData(yVal, GUIColors.GetColor(0), "θ", true); /*graph.SetBoundaries(0, endTime, -10, 10); * graph.SetGridScaleUsingValues(1, 5); * graph.horizontalLabel = "time"; * graph.verticalLabel = "value"; * graph.Update();*/ return(lines); }