Merge branch 'refs/heads/unstable' into sphinx-docs
This commit is contained in:
commit
df396228aa
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -40,5 +40,5 @@ jobs:
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: openrocket_build_${{ github.run_number }}
|
||||
path: ${{github.workspace}}/build/lib/openrocket*.jar
|
||||
path: ${{github.workspace}}/build/libs/OpenRocket*.jar
|
||||
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -46,6 +46,7 @@
|
||||
**/.idea/vcs.xml
|
||||
**/.idea/jsLibraryMappings.xml
|
||||
**/.idea/copilot
|
||||
**/.idea/shelf
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
**/.idea/dataSources.ids
|
||||
|
10
.idea/runConfigurations/All_tests.xml
generated
10
.idea/runConfigurations/All_tests.xml
generated
@ -1,10 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="All tests" type="JUnit" factoryName="JUnit">
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
12
.idea/runConfigurations/Openrocket_UI_Jar.xml
generated
12
.idea/runConfigurations/Openrocket_UI_Jar.xml
generated
@ -1,12 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Openrocket UI Jar" type="JarApplication">
|
||||
<option name="JAR_PATH" value="$PROJECT_DIR$/build/jar/OpenRocket.jar" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="17" />
|
||||
<method v="2">
|
||||
<option name="BuildArtifacts" enabled="true">
|
||||
<artifact name="openrocket:jar" />
|
||||
</option>
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
15
.idea/runConfigurations/SwingStartup.xml
generated
Normal file
15
.idea/runConfigurations/SwingStartup.xml
generated
Normal file
@ -0,0 +1,15 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="SwingStartup" type="Application" factoryName="Application" nameIsGenerated="true">
|
||||
<option name="MAIN_CLASS_NAME" value="info.openrocket.swing.startup.SwingStartup" />
|
||||
<module name="info.openrocket.swing.main" />
|
||||
<extension name="coverage">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="info.openrocket.swing.startup.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
27
.idea/runConfigurations/openrocket_jar.xml
generated
Normal file
27
.idea/runConfigurations/openrocket_jar.xml
generated
Normal file
@ -0,0 +1,27 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="openrocket-jar" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="clean" />
|
||||
<option value="check" />
|
||||
<option value="build" />
|
||||
<option value="dist" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
25
.idea/runConfigurations/openrocket_test.xml
generated
Normal file
25
.idea/runConfigurations/openrocket_test.xml
generated
Normal file
@ -0,0 +1,25 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="openrocket-test" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="clean" />
|
||||
<option value="check" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
@ -399,14 +399,14 @@ public class Simulation implements ChangeSource, Cloneable {
|
||||
public void simulate(SimulationListener... additionalListeners)
|
||||
throws SimulationException {
|
||||
mutex.lock("simulate");
|
||||
SimulationEngine simulator = null;
|
||||
simulatedData = null;
|
||||
try {
|
||||
|
||||
if (this.status == Status.EXTERNAL) {
|
||||
throw new SimulationException("Cannot simulate imported simulation.");
|
||||
}
|
||||
|
||||
SimulationEngine simulator;
|
||||
|
||||
try {
|
||||
simulator = simulationEngineClass.getConstructor().newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
@ -430,18 +430,20 @@ public class Simulation implements ChangeSource, Cloneable {
|
||||
long t1, t2;
|
||||
log.debug("Simulation: calling simulator");
|
||||
t1 = System.currentTimeMillis();
|
||||
simulatedData = simulator.simulate(simulationConditions);
|
||||
simulator.simulate(simulationConditions);
|
||||
t2 = System.currentTimeMillis();
|
||||
log.debug("Simulation: returning from simulator, simulation took " + (t2 - t1) + "ms");
|
||||
|
||||
} catch (SimulationException e) {
|
||||
simulatedData = e.getFlightData();
|
||||
throw e;
|
||||
} finally {
|
||||
// Set simulated info after simulation
|
||||
simulatedConditions = options.clone();
|
||||
simulatedConfigurationDescription = descriptor.format(this.rocket, getId());
|
||||
simulatedConfigurationID = getActiveConfiguration().getModID();
|
||||
if (simulator != null) {
|
||||
simulatedData = simulator.getFlightData();
|
||||
}
|
||||
|
||||
status = Status.UPTODATE;
|
||||
fireChangeEvent();
|
||||
|
@ -483,7 +483,7 @@ public class OpenRocketSaver extends RocketSaver {
|
||||
// Build the <databranch> tag
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<databranch name=\"");
|
||||
sb.append(TextUtil.escapeXML(branch.getBranchName()));
|
||||
sb.append(TextUtil.escapeXML(branch.getName()));
|
||||
sb.append("\" ");
|
||||
|
||||
// Kevins version where typekeys are used
|
||||
|
@ -169,69 +169,69 @@ public abstract class AbstractEulerStepper extends AbstractSimulationStepper {
|
||||
status.setRocketWorldPosition(w);
|
||||
|
||||
// Store data
|
||||
final FlightDataBranch data = status.getFlightData();
|
||||
final FlightDataBranch dataBranch = status.getFlightDataBranch();
|
||||
|
||||
// Values looked up or calculated at start of time step
|
||||
data.setValue(FlightDataType.TYPE_REFERENCE_LENGTH, status.getConfiguration().getReferenceLength());
|
||||
data.setValue(FlightDataType.TYPE_REFERENCE_AREA, status.getConfiguration().getReferenceArea());
|
||||
data.setValue(FlightDataType.TYPE_WIND_VELOCITY, windSpeed.length());
|
||||
data.setValue(FlightDataType.TYPE_AIR_TEMPERATURE, atmosphere.getTemperature());
|
||||
data.setValue(FlightDataType.TYPE_AIR_PRESSURE, atmosphere.getPressure());
|
||||
data.setValue(FlightDataType.TYPE_SPEED_OF_SOUND, atmosphere.getMachSpeed());
|
||||
data.setValue(FlightDataType.TYPE_MACH_NUMBER, mach);
|
||||
dataBranch.setValue(FlightDataType.TYPE_REFERENCE_LENGTH, status.getConfiguration().getReferenceLength());
|
||||
dataBranch.setValue(FlightDataType.TYPE_REFERENCE_AREA, status.getConfiguration().getReferenceArea());
|
||||
dataBranch.setValue(FlightDataType.TYPE_WIND_VELOCITY, windSpeed.length());
|
||||
dataBranch.setValue(FlightDataType.TYPE_AIR_TEMPERATURE, atmosphere.getTemperature());
|
||||
dataBranch.setValue(FlightDataType.TYPE_AIR_PRESSURE, atmosphere.getPressure());
|
||||
dataBranch.setValue(FlightDataType.TYPE_SPEED_OF_SOUND, atmosphere.getMachSpeed());
|
||||
dataBranch.setValue(FlightDataType.TYPE_MACH_NUMBER, mach);
|
||||
|
||||
if (status.getSimulationConditions().getGeodeticComputation() != GeodeticComputationStrategy.FLAT) {
|
||||
data.setValue(FlightDataType.TYPE_CORIOLIS_ACCELERATION, coriolisAcceleration.length());
|
||||
dataBranch.setValue(FlightDataType.TYPE_CORIOLIS_ACCELERATION, coriolisAcceleration.length());
|
||||
}
|
||||
data.setValue(FlightDataType.TYPE_GRAVITY, gravity);
|
||||
dataBranch.setValue(FlightDataType.TYPE_GRAVITY, gravity);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_DRAG_COEFF, getCD());
|
||||
data.setValue(FlightDataType.TYPE_PRESSURE_DRAG_COEFF, getCD());
|
||||
data.setValue(FlightDataType.TYPE_FRICTION_DRAG_COEFF, 0);
|
||||
data.setValue(FlightDataType.TYPE_BASE_DRAG_COEFF, 0);
|
||||
data.setValue(FlightDataType.TYPE_AXIAL_DRAG_COEFF, getCD());
|
||||
data.setValue(FlightDataType.TYPE_THRUST_FORCE, 0);
|
||||
data.setValue(FlightDataType.TYPE_DRAG_FORCE, dragForce);
|
||||
dataBranch.setValue(FlightDataType.TYPE_DRAG_COEFF, getCD());
|
||||
dataBranch.setValue(FlightDataType.TYPE_PRESSURE_DRAG_COEFF, getCD());
|
||||
dataBranch.setValue(FlightDataType.TYPE_FRICTION_DRAG_COEFF, 0);
|
||||
dataBranch.setValue(FlightDataType.TYPE_BASE_DRAG_COEFF, 0);
|
||||
dataBranch.setValue(FlightDataType.TYPE_AXIAL_DRAG_COEFF, getCD());
|
||||
dataBranch.setValue(FlightDataType.TYPE_THRUST_FORCE, 0);
|
||||
dataBranch.setValue(FlightDataType.TYPE_DRAG_FORCE, dragForce);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_MASS, mass);
|
||||
data.setValue(FlightDataType.TYPE_MOTOR_MASS, motorMass);
|
||||
data.setValue(FlightDataType.TYPE_THRUST_WEIGHT_RATIO, 0);
|
||||
dataBranch.setValue(FlightDataType.TYPE_MASS, mass);
|
||||
dataBranch.setValue(FlightDataType.TYPE_MOTOR_MASS, motorMass);
|
||||
dataBranch.setValue(FlightDataType.TYPE_THRUST_WEIGHT_RATIO, 0);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_ACCELERATION_XY,
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_XY,
|
||||
MathUtil.hypot(linearAcceleration.x, linearAcceleration.y));
|
||||
data.setValue(FlightDataType.TYPE_ACCELERATION_Z, linearAcceleration.z);
|
||||
data.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, linearAcceleration.length());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_Z, linearAcceleration.z);
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, linearAcceleration.length());
|
||||
|
||||
data.setValue(FlightDataType.TYPE_TIME_STEP, timeStep);
|
||||
dataBranch.setValue(FlightDataType.TYPE_TIME_STEP, timeStep);
|
||||
|
||||
// Values calculated on this step
|
||||
data.addPoint();
|
||||
data.setValue(FlightDataType.TYPE_TIME, status.getSimulationTime());
|
||||
data.setValue(FlightDataType.TYPE_ALTITUDE, status.getRocketPosition().z);
|
||||
data.setValue(FlightDataType.TYPE_POSITION_X, status.getRocketPosition().x);
|
||||
data.setValue(FlightDataType.TYPE_POSITION_Y, status.getRocketPosition().y);
|
||||
dataBranch.addPoint();
|
||||
dataBranch.setValue(FlightDataType.TYPE_TIME, status.getSimulationTime());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ALTITUDE, status.getRocketPosition().z);
|
||||
dataBranch.setValue(FlightDataType.TYPE_POSITION_X, status.getRocketPosition().x);
|
||||
dataBranch.setValue(FlightDataType.TYPE_POSITION_Y, status.getRocketPosition().y);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_POSITION_XY,
|
||||
dataBranch.setValue(FlightDataType.TYPE_POSITION_XY,
|
||||
MathUtil.hypot(status.getRocketPosition().x, status.getRocketPosition().y));
|
||||
data.setValue(FlightDataType.TYPE_POSITION_DIRECTION,
|
||||
dataBranch.setValue(FlightDataType.TYPE_POSITION_DIRECTION,
|
||||
Math.atan2(status.getRocketPosition().y, status.getRocketPosition().x));
|
||||
data.setValue(FlightDataType.TYPE_LATITUDE, status.getRocketWorldPosition().getLatitudeRad());
|
||||
data.setValue(FlightDataType.TYPE_LONGITUDE, status.getRocketWorldPosition().getLongitudeRad());
|
||||
dataBranch.setValue(FlightDataType.TYPE_LATITUDE, status.getRocketWorldPosition().getLatitudeRad());
|
||||
dataBranch.setValue(FlightDataType.TYPE_LONGITUDE, status.getRocketWorldPosition().getLongitudeRad());
|
||||
|
||||
data.setValue(FlightDataType.TYPE_VELOCITY_XY,
|
||||
dataBranch.setValue(FlightDataType.TYPE_VELOCITY_XY,
|
||||
MathUtil.hypot(status.getRocketVelocity().x, status.getRocketVelocity().y));
|
||||
data.setValue(FlightDataType.TYPE_VELOCITY_Z, status.getRocketVelocity().z);
|
||||
data.setValue(FlightDataType.TYPE_VELOCITY_TOTAL, airSpeed.length());
|
||||
dataBranch.setValue(FlightDataType.TYPE_VELOCITY_Z, status.getRocketVelocity().z);
|
||||
dataBranch.setValue(FlightDataType.TYPE_VELOCITY_TOTAL, airSpeed.length());
|
||||
|
||||
airSpeed = status.getRocketVelocity().add(windSpeed);
|
||||
final double Re = airSpeed.length() *
|
||||
status.getConfiguration().getLengthAerodynamic() /
|
||||
atmosphere.getKinematicViscosity();
|
||||
data.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re);
|
||||
dataBranch.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_COMPUTATION_TIME,
|
||||
dataBranch.setValue(FlightDataType.TYPE_COMPUTATION_TIME,
|
||||
(System.nanoTime() - status.getSimulationStartWallTime()) / 1000000000.0);
|
||||
log.trace("time " + data.getLast(FlightDataType.TYPE_TIME) + ", altitude " + data.getLast(FlightDataType.TYPE_ALTITUDE) + ", velocity " + data.getLast(FlightDataType.TYPE_VELOCITY_Z));
|
||||
log.trace("time " + dataBranch.getLast(FlightDataType.TYPE_TIME) + ", altitude " + dataBranch.getLast(FlightDataType.TYPE_ALTITUDE) + ", velocity " + dataBranch.getLast(FlightDataType.TYPE_VELOCITY_Z));
|
||||
}
|
||||
|
||||
private static class EulerValues {
|
||||
|
@ -62,93 +62,99 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
FlightData flightData;
|
||||
|
||||
@Override
|
||||
public FlightData simulate(SimulationConditions simulationConditions) throws SimulationException {
|
||||
|
||||
public void simulate(SimulationConditions simulationConditions) throws SimulationException {
|
||||
|
||||
// Set up flight data
|
||||
flightData = new FlightData();
|
||||
|
||||
// Set up rocket configuration
|
||||
this.fcid = simulationConditions.getFlightConfigurationID();
|
||||
FlightConfiguration origConfig = simulationConditions.getRocket().getFlightConfiguration(this.fcid);
|
||||
FlightConfiguration simulationConfig = origConfig.clone(simulationConditions.getRocket().copyWithOriginalID());
|
||||
simulationConfig.copyStages(origConfig); // Clone the stage activation configuration
|
||||
|
||||
currentStatus = new SimulationStatus(simulationConfig, simulationConditions);
|
||||
// main simulation branch. Need to watch for pathological case with no stages defined
|
||||
final AxialStage topStage = simulationConfig.getRocket().getTopmostStage(currentStatus.getConfiguration());
|
||||
final String branchName;
|
||||
|
||||
try {
|
||||
// Set up rocket configuration
|
||||
this.fcid = simulationConditions.getFlightConfigurationID();
|
||||
FlightConfiguration origConfig = simulationConditions.getRocket().getFlightConfiguration(this.fcid);
|
||||
FlightConfiguration simulationConfig = origConfig.clone(simulationConditions.getRocket().copyWithOriginalID());
|
||||
simulationConfig.copyStages(origConfig); // Clone the stage activation configuration
|
||||
|
||||
currentStatus = new SimulationStatus(simulationConfig, simulationConditions);
|
||||
// main simulation branch. Need to watch for pathological case with no stages defined
|
||||
final AxialStage topStage = simulationConfig.getRocket().getTopmostStage(currentStatus.getConfiguration());
|
||||
final String branchName;
|
||||
if (topStage != null) {
|
||||
branchName = topStage.getName();
|
||||
} else {
|
||||
branchName = trans.get("BasicEventSimulationEngine.nullBranchName");
|
||||
}
|
||||
FlightDataBranch initialBranch = new FlightDataBranch( branchName, FlightDataType.TYPE_TIME);
|
||||
|
||||
// put a point on it so we can plot if we get an early abort event
|
||||
initialBranch.addPoint();
|
||||
initialBranch.setValue(FlightDataType.TYPE_TIME, 0.0);
|
||||
initialBranch.setValue(FlightDataType.TYPE_ALTITUDE, 0.0);
|
||||
currentStatus.setFlightData(initialBranch);
|
||||
|
||||
|
||||
// Sanity checks on design and configuration
|
||||
|
||||
// Problems that keep us from simulating at all
|
||||
|
||||
// No active stages
|
||||
if (topStage == null) {
|
||||
currentStatus.abortSimulation(SimulationAbort.Cause.NO_ACTIVE_STAGES);
|
||||
}
|
||||
|
||||
// No motors in configuration
|
||||
if (!simulationConfig.hasMotors() ) {
|
||||
currentStatus.abortSimulation(SimulationAbort.Cause.NO_MOTORS_DEFINED);
|
||||
}
|
||||
|
||||
// Problems that let us simulate, but result is likely bad
|
||||
FlightDataBranch initialBranch = new FlightDataBranch( branchName, FlightDataType.TYPE_TIME);
|
||||
|
||||
// No recovery device
|
||||
if (!simulationConfig.hasRecoveryDevice()) {
|
||||
currentStatus.getWarnings().add(Warning.NO_RECOVERY_DEVICE);
|
||||
}
|
||||
|
||||
currentStatus.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket()));
|
||||
toSimulate.push(currentStatus);
|
||||
|
||||
SimulationListenerHelper.fireStartSimulation(currentStatus);
|
||||
do {
|
||||
if (toSimulate.peek() == null) {
|
||||
break;
|
||||
// put a point on it so we can plot if we get an early abort event
|
||||
initialBranch.addPoint();
|
||||
initialBranch.setValue(FlightDataType.TYPE_TIME, 0.0);
|
||||
initialBranch.setValue(FlightDataType.TYPE_ALTITUDE, 0.0);
|
||||
|
||||
currentStatus.setFlightDataBranch(initialBranch);
|
||||
|
||||
// Sanity checks on design and configuration
|
||||
|
||||
// Problems that keep us from simulating at all
|
||||
|
||||
// No active stages
|
||||
if (topStage == null) {
|
||||
currentStatus.abortSimulation(SimulationAbort.Cause.NO_ACTIVE_STAGES);
|
||||
}
|
||||
currentStatus = toSimulate.pop();
|
||||
log.info(">>Starting simulation of branch: " + currentStatus.getFlightData().getBranchName());
|
||||
|
||||
FlightDataBranch dataBranch = simulateLoop();
|
||||
flightData.addBranch(dataBranch);
|
||||
flightData.getWarningSet().addAll(currentStatus.getWarnings());
|
||||
|
||||
log.info(String.format("<<Finished simulating branch: %s curTime:%s finTime:%s",
|
||||
dataBranch.getBranchName(),
|
||||
currentStatus.getSimulationTime(),
|
||||
dataBranch.getLast(FlightDataType.TYPE_TIME)));
|
||||
|
||||
|
||||
// Did the branch generate any data?
|
||||
if (dataBranch.getLength() == 0) {
|
||||
flightData.getWarningSet().add(Warning.EMPTY_BRANCH, dataBranch.getBranchName());
|
||||
|
||||
// No motors in configuration
|
||||
if (!simulationConfig.hasMotors() ) {
|
||||
currentStatus.abortSimulation(SimulationAbort.Cause.NO_MOTORS_DEFINED);
|
||||
}
|
||||
} while (!toSimulate.isEmpty());
|
||||
|
||||
// Problems that let us simulate, but result is likely bad
|
||||
|
||||
// No recovery device
|
||||
if (!simulationConfig.hasRecoveryDevice()) {
|
||||
currentStatus.getWarnings().add(Warning.NO_RECOVERY_DEVICE);
|
||||
}
|
||||
|
||||
currentStatus.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket()));
|
||||
toSimulate.push(currentStatus);
|
||||
|
||||
SimulationListenerHelper.fireEndSimulation(currentStatus, null);
|
||||
|
||||
if (!flightData.getWarningSet().isEmpty()) {
|
||||
log.info("Warnings at the end of simulation: " + flightData.getWarningSet());
|
||||
SimulationListenerHelper.fireStartSimulation(currentStatus);
|
||||
do {
|
||||
if (toSimulate.peek() == null) {
|
||||
break;
|
||||
}
|
||||
currentStatus = toSimulate.pop();
|
||||
FlightDataBranch dataBranch = currentStatus.getFlightDataBranch();
|
||||
flightData.addBranch(dataBranch);
|
||||
log.info(">>Starting simulation of branch: " + currentStatus.getFlightDataBranch().getName());
|
||||
|
||||
simulateLoop();
|
||||
dataBranch.immute();
|
||||
flightData.getWarningSet().addAll(currentStatus.getWarnings());
|
||||
|
||||
log.info(String.format("<<Finished simulating branch: %s curTime:%s finTime:%s",
|
||||
dataBranch.getName(),
|
||||
currentStatus.getSimulationTime(),
|
||||
dataBranch.getLast(FlightDataType.TYPE_TIME)));
|
||||
|
||||
|
||||
// Did the branch generate any data?
|
||||
if (dataBranch.getLength() == 0) {
|
||||
flightData.getWarningSet().add(Warning.EMPTY_BRANCH, dataBranch.getName());
|
||||
}
|
||||
} while (!toSimulate.isEmpty());
|
||||
|
||||
SimulationListenerHelper.fireEndSimulation(currentStatus, null);
|
||||
|
||||
if (!flightData.getWarningSet().isEmpty()) {
|
||||
log.info("Warnings at the end of simulation: " + flightData.getWarningSet());
|
||||
}
|
||||
} catch (SimulationException e) {
|
||||
throw e;
|
||||
} finally {
|
||||
flightData.calculateInterestingValues();
|
||||
}
|
||||
|
||||
return flightData;
|
||||
}
|
||||
|
||||
private FlightDataBranch simulateLoop() throws SimulationException {
|
||||
private void simulateLoop() throws SimulationException {
|
||||
|
||||
// Initialize the simulation. We'll use the flight stepper unless we're already
|
||||
// on the ground
|
||||
@ -264,9 +270,9 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
// and aoa > AOA_TUMBLE_CONDITION threshold
|
||||
|
||||
if (!currentStatus.isTumbling()) {
|
||||
final double cp = currentStatus.getFlightData().getLast(FlightDataType.TYPE_CP_LOCATION);
|
||||
final double cg = currentStatus.getFlightData().getLast(FlightDataType.TYPE_CG_LOCATION);
|
||||
final double aoa = currentStatus.getFlightData().getLast(FlightDataType.TYPE_AOA);
|
||||
final double cp = currentStatus.getFlightDataBranch().getLast(FlightDataType.TYPE_CP_LOCATION);
|
||||
final double cg = currentStatus.getFlightDataBranch().getLast(FlightDataType.TYPE_CG_LOCATION);
|
||||
final double aoa = currentStatus.getFlightDataBranch().getLast(FlightDataType.TYPE_AOA);
|
||||
|
||||
if (cg > cp && aoa > AOA_TUMBLE_CONDITION) {
|
||||
currentStatus.addEvent(new FlightEvent(FlightEvent.Type.TUMBLE, currentStatus.getSimulationTime()));
|
||||
@ -281,21 +287,16 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
}
|
||||
|
||||
} catch (SimulationException e) {
|
||||
|
||||
SimulationListenerHelper.fireEndSimulation(currentStatus, e);
|
||||
|
||||
// Add FlightEvent for exception.
|
||||
currentStatus.getFlightData().addEvent(new FlightEvent(FlightEvent.Type.EXCEPTION, currentStatus.getSimulationTime(), currentStatus.getConfiguration().getRocket(), e.getLocalizedMessage()));
|
||||
currentStatus.getFlightDataBranch().addEvent(new FlightEvent(FlightEvent.Type.EXCEPTION, currentStatus.getSimulationTime(), currentStatus.getConfiguration().getRocket(), e.getLocalizedMessage()));
|
||||
|
||||
flightData.addBranch(currentStatus.getFlightData());
|
||||
flightData.getWarningSet().addAll(currentStatus.getWarnings());
|
||||
|
||||
e.setFlightData(flightData);
|
||||
e.setFlightDataBranch(currentStatus.getFlightData());
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
return currentStatus.getFlightData();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -307,7 +308,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
boolean ret = true;
|
||||
FlightEvent event;
|
||||
|
||||
log.trace("HandleEvents: current branch = " + currentStatus.getFlightData().getBranchName());
|
||||
log.trace("HandleEvents: current branch = " + currentStatus.getFlightDataBranch().getName());
|
||||
for (event = nextEvent(); event != null; event = nextEvent()) {
|
||||
log.trace("Obtained event from queue: " + event.toString());
|
||||
log.trace("Remaining EventQueue = " + currentStatus.getEventQueue().toString());
|
||||
@ -390,7 +391,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
switch (event.getType()) {
|
||||
|
||||
case LAUNCH: {
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -412,7 +413,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
// Ignite the motor
|
||||
currentStatus.setMotorIgnited(true);
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
|
||||
// ... ignite ...uhh, again?
|
||||
// TBH, I'm not sure what this call is for. It seems to be mostly a bunch of
|
||||
@ -442,14 +443,14 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
case LIFTOFF: {
|
||||
// Mark lift-off as occurred
|
||||
currentStatus.setLiftoff(true);
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
case LAUNCHROD: {
|
||||
// Mark launch rod as cleared
|
||||
currentStatus.setLaunchRodCleared(true);
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -472,14 +473,14 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
currentStatus.addEvent(new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, currentStatus.getSimulationTime() + delay,
|
||||
stage, event.getData()));
|
||||
}
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
case EJECTION_CHARGE: {
|
||||
MotorClusterState motorState = (MotorClusterState) event.getData();
|
||||
motorState.expend( event.getTime() );
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -490,7 +491,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
if (currentStatus.getConfiguration().isStageActive(stageNumber - 1)) {
|
||||
// Record the event.
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
|
||||
// If I've got something other than one active stage below the separation point,
|
||||
// flag a warning
|
||||
@ -513,8 +514,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
SimulationStatus boosterStatus = new SimulationStatus(currentStatus);
|
||||
|
||||
// Prepare the new simulation branch
|
||||
boosterStatus.setFlightData(new FlightDataBranch(boosterStage.getName(), boosterStage, currentStatus.getFlightData()));
|
||||
boosterStatus.getFlightData().addEvent(event);
|
||||
boosterStatus.setFlightDataBranch(new FlightDataBranch(boosterStage.getName(), boosterStage, currentStatus.getFlightDataBranch()));
|
||||
boosterStatus.getFlightDataBranch().addEvent(event);
|
||||
|
||||
// Mark the current status as having dropped the current stage and all stages
|
||||
// below it
|
||||
@ -530,7 +531,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
log.info(String.format("==>> @ %g; from Branch: %s ---- Branching: %s ---- \n",
|
||||
currentStatus.getSimulationTime(),
|
||||
currentStatus.getFlightData().getBranchName(), boosterStatus.getFlightData().getBranchName()));
|
||||
currentStatus.getFlightDataBranch().getName(), boosterStatus.getFlightDataBranch().getName()));
|
||||
} else {
|
||||
log.debug("upper stage is not active; not performing separation");
|
||||
}
|
||||
@ -541,11 +542,11 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
case APOGEE:
|
||||
// Mark apogee as reached
|
||||
currentStatus.setApogeeReached(true);
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
// This apogee event might be the optimum if recovery has not already happened.
|
||||
if (currentStatus.getDeployedRecoveryDevices().size() == 0) {
|
||||
currentStatus.getFlightData().setOptimumAltitude(currentStatus.getMaxAlt());
|
||||
currentStatus.getFlightData().setTimeToOptimumAltitude(currentStatus.getMaxAltTime());
|
||||
currentStatus.getFlightDataBranch().setOptimumAltitude(currentStatus.getMaxAlt());
|
||||
currentStatus.getFlightDataBranch().setTimeToOptimumAltitude(currentStatus.getMaxAltTime());
|
||||
}
|
||||
break;
|
||||
|
||||
@ -582,8 +583,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
if (!currentStatus.isApogeeReached()) {
|
||||
FlightData coastStatus = computeCoastTime();
|
||||
|
||||
currentStatus.getFlightData().setOptimumAltitude(coastStatus.getMaxAltitude());
|
||||
currentStatus.getFlightData().setTimeToOptimumAltitude(coastStatus.getTimeToApogee());
|
||||
currentStatus.getFlightDataBranch().setOptimumAltitude(coastStatus.getMaxAltitude());
|
||||
currentStatus.getFlightDataBranch().setTimeToOptimumAltitude(coastStatus.getTimeToApogee());
|
||||
}
|
||||
|
||||
// switch to landing stepper (unless we're already on the ground)
|
||||
@ -592,7 +593,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
currentStatus = currentStepper.initialize(currentStatus);
|
||||
}
|
||||
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
}
|
||||
log.debug("deployed recovery devices: " + currentStatus.getDeployedRecoveryDevices().size() );
|
||||
break;
|
||||
@ -603,17 +604,17 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
currentStepper = groundStepper;
|
||||
currentStatus = currentStepper.initialize(currentStatus);
|
||||
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
break;
|
||||
|
||||
case SIM_ABORT:
|
||||
ret = false;
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
break;
|
||||
|
||||
case SIMULATION_END:
|
||||
ret = false;
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
break;
|
||||
|
||||
case ALTITUDE:
|
||||
@ -628,13 +629,13 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
currentStepper = tumbleStepper;
|
||||
currentStatus = currentStepper.initialize(currentStatus);
|
||||
|
||||
final boolean tooMuchThrust = currentStatus.getFlightData().getLast(FlightDataType.TYPE_THRUST_FORCE) > THRUST_TUMBLE_CONDITION;
|
||||
final boolean tooMuchThrust = currentStatus.getFlightDataBranch().getLast(FlightDataType.TYPE_THRUST_FORCE) > THRUST_TUMBLE_CONDITION;
|
||||
if (tooMuchThrust) {
|
||||
currentStatus.abortSimulation(SimulationAbort.Cause.TUMBLE_UNDER_THRUST);
|
||||
}
|
||||
|
||||
currentStatus.setTumbling(true);
|
||||
currentStatus.getFlightData().addEvent(event);
|
||||
currentStatus.getFlightDataBranch().addEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -645,7 +646,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
if (1200 < currentStatus.getSimulationTime()) {
|
||||
ret = false;
|
||||
log.error("Simulation hit max time (1200s): aborting.");
|
||||
currentStatus.getFlightData()
|
||||
currentStatus.getFlightDataBranch()
|
||||
.addEvent(new FlightEvent(FlightEvent.Type.SIMULATION_END, currentStatus.getSimulationTime()));
|
||||
}
|
||||
|
||||
@ -697,7 +698,12 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
if (currentStatus.getConfiguration().getLengthAerodynamic() < MathUtil.EPSILON) {
|
||||
currentStatus.abortSimulation(SimulationAbort.Cause.ACTIVE_LENGTH_ZERO);
|
||||
}
|
||||
|
||||
|
||||
// test -- force an exception if we aren't the sustainer
|
||||
// if (currentStatus.getConfiguration().isStageActive(0)) {
|
||||
// throw new SimulationCalculationException("test", currentStatus.getFlightDataBranch());
|
||||
// }
|
||||
|
||||
// Can't calculate stability. If it's the sustainer we'll abort; if a booster
|
||||
// we'll just transition to tumbling (if it's a booster and under thrust code elsewhere
|
||||
// will abort).
|
||||
@ -731,7 +737,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
" rocketOrientationQuaternion=" + currentStatus.getRocketOrientationQuaternion() +
|
||||
" rocketRotationVelocity=" + currentStatus.getRocketRotationVelocity() +
|
||||
" effectiveLaunchRodLength=" + currentStatus.getEffectiveLaunchRodLength());
|
||||
throw new SimulationCalculationException(trans.get("BasicEventSimulationEngine.error.NaNResult"));
|
||||
throw new SimulationCalculationException(trans.get("BasicEventSimulationEngine.error.NaNResult"),
|
||||
currentStatus.getFlightDataBranch());
|
||||
}
|
||||
}
|
||||
|
||||
@ -739,10 +746,10 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
try {
|
||||
SimulationConditions conds = currentStatus.getSimulationConditions().clone();
|
||||
conds.getSimulationListenerList().add(OptimumCoastListener.INSTANCE);
|
||||
BasicEventSimulationEngine e = new BasicEventSimulationEngine();
|
||||
BasicEventSimulationEngine coastEngine = new BasicEventSimulationEngine();
|
||||
|
||||
FlightData d = e.simulate(conds);
|
||||
return d;
|
||||
coastEngine.simulate(conds);
|
||||
return coastEngine.getFlightData();
|
||||
} catch (SimulationException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
@ -750,4 +757,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public FlightData getFlightData() {
|
||||
return flightData;
|
||||
}
|
||||
}
|
||||
|
@ -126,12 +126,7 @@ public class FlightData {
|
||||
public void addBranch(FlightDataBranch branch) {
|
||||
mutable.check();
|
||||
|
||||
branch.immute();
|
||||
branches.add(branch);
|
||||
|
||||
if (branches.size() == 1) {
|
||||
calculateInterestingValues();
|
||||
}
|
||||
}
|
||||
|
||||
public int getBranchCount() {
|
||||
@ -201,7 +196,7 @@ public class FlightData {
|
||||
* Calculate the max. altitude/velocity/acceleration, time to apogee, flight time
|
||||
* and ground hit velocity.
|
||||
*/
|
||||
private void calculateInterestingValues() {
|
||||
public void calculateInterestingValues() {
|
||||
if (branches.isEmpty())
|
||||
return;
|
||||
|
||||
|
@ -31,7 +31,7 @@ import info.openrocket.core.util.Mutable;
|
||||
public class FlightDataBranch implements Monitorable {
|
||||
|
||||
/** The name of this flight data branch. */
|
||||
private final String branchName;
|
||||
private final String name;
|
||||
|
||||
private final Map<FlightDataType, ArrayList<Double>> values = new LinkedHashMap<>();
|
||||
|
||||
@ -64,7 +64,7 @@ public class FlightDataBranch implements Monitorable {
|
||||
throw new IllegalArgumentException("Must specify at least one data type.");
|
||||
}
|
||||
|
||||
this.branchName = name;
|
||||
this.name = name;
|
||||
|
||||
for (FlightDataType t : types) {
|
||||
if (values.containsKey(t)) {
|
||||
@ -83,12 +83,12 @@ public class FlightDataBranch implements Monitorable {
|
||||
* when creating a new branch upon stage separation, so the data at separation is present
|
||||
* in both branches (and if the new branch has an immediate exception, it can be plotted)
|
||||
*
|
||||
* @param branchName the name of the new branch.
|
||||
* @param name the name of the new branch.
|
||||
* @param srcComponent the component that is the source of the new branch.
|
||||
* @param parent the parent branch to copy data from.
|
||||
*/
|
||||
public FlightDataBranch(String branchName, RocketComponent srcComponent, FlightDataBranch parent) {
|
||||
this.branchName = branchName;
|
||||
public FlightDataBranch(String name, RocketComponent srcComponent, FlightDataBranch parent) {
|
||||
this.name = name;
|
||||
|
||||
// Copy all the values from the parent
|
||||
copyValuesFromBranch(parent, srcComponent);
|
||||
@ -98,7 +98,7 @@ public class FlightDataBranch implements Monitorable {
|
||||
* Makes an 'empty' flight data branch which has no data but all built in data types are defined.
|
||||
*/
|
||||
public FlightDataBranch() {
|
||||
branchName = "Empty branch";
|
||||
name = "Empty branch";
|
||||
for (FlightDataType type : FlightDataType.ALL_TYPES) {
|
||||
this.setValue(type, Double.NaN);
|
||||
}
|
||||
@ -230,8 +230,8 @@ public class FlightDataBranch implements Monitorable {
|
||||
/**
|
||||
* Return the branch name.
|
||||
*/
|
||||
public String getBranchName() {
|
||||
return branchName;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -447,7 +447,7 @@ public class FlightDataBranch implements Monitorable {
|
||||
|
||||
public FlightDataBranch clone() {
|
||||
FlightDataType[] types = getTypes();
|
||||
FlightDataBranch clone = new FlightDataBranch(branchName, types);
|
||||
FlightDataBranch clone = new FlightDataBranch(name, types);
|
||||
for (FlightDataType type : values.keySet()) {
|
||||
clone.values.put(type, values.get(type).clone());
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
if (status.getRocketVelocity().length2() > 1e18 ||
|
||||
status.getRocketPosition().length2() > 1e18 ||
|
||||
status.getRocketRotationVelocity().length2() > 1e18) {
|
||||
throw new SimulationCalculationException(trans.get("error.valuesTooLarge"));
|
||||
throw new SimulationCalculationException(trans.get("error.valuesTooLarge"), status.getFlightDataBranch());
|
||||
}
|
||||
}
|
||||
|
||||
@ -526,117 +526,117 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
|
||||
private void storeData(RK4SimulationStatus status, DataStore store) {
|
||||
|
||||
FlightDataBranch data = status.getFlightData();
|
||||
FlightDataBranch dataBranch = status.getFlightDataBranch();
|
||||
|
||||
data.addPoint();
|
||||
data.setValue(FlightDataType.TYPE_TIME, status.getSimulationTime());
|
||||
data.setValue(FlightDataType.TYPE_ALTITUDE, status.getRocketPosition().z);
|
||||
data.setValue(FlightDataType.TYPE_POSITION_X, status.getRocketPosition().x);
|
||||
data.setValue(FlightDataType.TYPE_POSITION_Y, status.getRocketPosition().y);
|
||||
dataBranch.addPoint();
|
||||
dataBranch.setValue(FlightDataType.TYPE_TIME, status.getSimulationTime());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ALTITUDE, status.getRocketPosition().z);
|
||||
dataBranch.setValue(FlightDataType.TYPE_POSITION_X, status.getRocketPosition().x);
|
||||
dataBranch.setValue(FlightDataType.TYPE_POSITION_Y, status.getRocketPosition().y);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_LATITUDE, status.getRocketWorldPosition().getLatitudeRad());
|
||||
data.setValue(FlightDataType.TYPE_LONGITUDE, status.getRocketWorldPosition().getLongitudeRad());
|
||||
dataBranch.setValue(FlightDataType.TYPE_LATITUDE, status.getRocketWorldPosition().getLatitudeRad());
|
||||
dataBranch.setValue(FlightDataType.TYPE_LONGITUDE, status.getRocketWorldPosition().getLongitudeRad());
|
||||
if (status.getSimulationConditions().getGeodeticComputation() != GeodeticComputationStrategy.FLAT) {
|
||||
data.setValue(FlightDataType.TYPE_CORIOLIS_ACCELERATION, store.coriolisAcceleration.length());
|
||||
dataBranch.setValue(FlightDataType.TYPE_CORIOLIS_ACCELERATION, store.coriolisAcceleration.length());
|
||||
}
|
||||
|
||||
data.setValue(FlightDataType.TYPE_POSITION_XY,
|
||||
dataBranch.setValue(FlightDataType.TYPE_POSITION_XY,
|
||||
MathUtil.hypot(status.getRocketPosition().x, status.getRocketPosition().y));
|
||||
data.setValue(FlightDataType.TYPE_POSITION_DIRECTION,
|
||||
dataBranch.setValue(FlightDataType.TYPE_POSITION_DIRECTION,
|
||||
Math.atan2(status.getRocketPosition().y, status.getRocketPosition().x));
|
||||
|
||||
data.setValue(FlightDataType.TYPE_VELOCITY_XY,
|
||||
dataBranch.setValue(FlightDataType.TYPE_VELOCITY_XY,
|
||||
MathUtil.hypot(status.getRocketVelocity().x, status.getRocketVelocity().y));
|
||||
|
||||
if (store.linearAcceleration != null) {
|
||||
data.setValue(FlightDataType.TYPE_ACCELERATION_XY,
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_XY,
|
||||
MathUtil.hypot(store.linearAcceleration.x, store.linearAcceleration.y));
|
||||
|
||||
data.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, store.linearAcceleration.length());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, store.linearAcceleration.length());
|
||||
}
|
||||
|
||||
if (store.flightConditions != null) {
|
||||
double Re = (store.flightConditions.getVelocity() *
|
||||
status.getConfiguration().getLengthAerodynamic() /
|
||||
store.flightConditions.getAtmosphericConditions().getKinematicViscosity());
|
||||
data.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re);
|
||||
dataBranch.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re);
|
||||
}
|
||||
|
||||
data.setValue(FlightDataType.TYPE_VELOCITY_Z, status.getRocketVelocity().z);
|
||||
dataBranch.setValue(FlightDataType.TYPE_VELOCITY_Z, status.getRocketVelocity().z);
|
||||
if (store.linearAcceleration != null) {
|
||||
data.setValue(FlightDataType.TYPE_ACCELERATION_Z, store.linearAcceleration.z);
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_Z, store.linearAcceleration.z);
|
||||
}
|
||||
|
||||
if (store.flightConditions != null) {
|
||||
data.setValue(FlightDataType.TYPE_VELOCITY_TOTAL, status.getRocketVelocity().length());
|
||||
data.setValue(FlightDataType.TYPE_MACH_NUMBER, store.flightConditions.getMach());
|
||||
dataBranch.setValue(FlightDataType.TYPE_VELOCITY_TOTAL, status.getRocketVelocity().length());
|
||||
dataBranch.setValue(FlightDataType.TYPE_MACH_NUMBER, store.flightConditions.getMach());
|
||||
}
|
||||
|
||||
if (store.rocketMass != null) {
|
||||
data.setValue(FlightDataType.TYPE_CG_LOCATION, store.rocketMass.getCM().x);
|
||||
dataBranch.setValue(FlightDataType.TYPE_CG_LOCATION, store.rocketMass.getCM().x);
|
||||
}
|
||||
if (status.isLaunchRodCleared()) {
|
||||
// Don't include CP and stability with huge launch AOA
|
||||
if (store.forces != null) {
|
||||
data.setValue(FlightDataType.TYPE_CP_LOCATION, store.forces.getCP().x);
|
||||
dataBranch.setValue(FlightDataType.TYPE_CP_LOCATION, store.forces.getCP().x);
|
||||
}
|
||||
if (store.forces != null && store.flightConditions != null && store.rocketMass != null) {
|
||||
data.setValue(FlightDataType.TYPE_STABILITY,
|
||||
dataBranch.setValue(FlightDataType.TYPE_STABILITY,
|
||||
(store.forces.getCP().x - store.rocketMass.getCM().x) / store.flightConditions.getRefLength());
|
||||
}
|
||||
}
|
||||
|
||||
if (null != store.motorMass) {
|
||||
data.setValue(FlightDataType.TYPE_MOTOR_MASS, store.motorMass.getMass());
|
||||
//data.setValue(FlightDataType.TYPE_MOTOR_LONGITUDINAL_INERTIA, store.motorMassData.getLongitudinalInertia());
|
||||
//data.setValue(FlightDataType.TYPE_MOTOR_ROTATIONAL_INERTIA, store.motorMassData.getRotationalInertia());
|
||||
dataBranch.setValue(FlightDataType.TYPE_MOTOR_MASS, store.motorMass.getMass());
|
||||
//dataBranch.setValue(FlightDataType.TYPE_MOTOR_LONGITUDINAL_INERTIA, store.motorMassData.getLongitudinalInertia());
|
||||
//dataBranch.setValue(FlightDataType.TYPE_MOTOR_ROTATIONAL_INERTIA, store.motorMassData.getRotationalInertia());
|
||||
}
|
||||
if (store.rocketMass != null) {
|
||||
// N.B.: These refer to total mass
|
||||
data.setValue(FlightDataType.TYPE_MASS, store.rocketMass.getMass());
|
||||
data.setValue(FlightDataType.TYPE_LONGITUDINAL_INERTIA, store.rocketMass.getLongitudinalInertia());
|
||||
data.setValue(FlightDataType.TYPE_ROTATIONAL_INERTIA, store.rocketMass.getRotationalInertia());
|
||||
dataBranch.setValue(FlightDataType.TYPE_MASS, store.rocketMass.getMass());
|
||||
dataBranch.setValue(FlightDataType.TYPE_LONGITUDINAL_INERTIA, store.rocketMass.getLongitudinalInertia());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ROTATIONAL_INERTIA, store.rocketMass.getRotationalInertia());
|
||||
}
|
||||
|
||||
data.setValue(FlightDataType.TYPE_THRUST_FORCE, store.thrustForce);
|
||||
dataBranch.setValue(FlightDataType.TYPE_THRUST_FORCE, store.thrustForce);
|
||||
double weight = store.rocketMass.getMass() * store.gravity;
|
||||
data.setValue(FlightDataType.TYPE_THRUST_WEIGHT_RATIO, store.thrustForce / weight);
|
||||
data.setValue(FlightDataType.TYPE_DRAG_FORCE, store.dragForce);
|
||||
data.setValue(FlightDataType.TYPE_GRAVITY, store.gravity);
|
||||
dataBranch.setValue(FlightDataType.TYPE_THRUST_WEIGHT_RATIO, store.thrustForce / weight);
|
||||
dataBranch.setValue(FlightDataType.TYPE_DRAG_FORCE, store.dragForce);
|
||||
dataBranch.setValue(FlightDataType.TYPE_GRAVITY, store.gravity);
|
||||
|
||||
if (status.isLaunchRodCleared() && store.forces != null) {
|
||||
if (store.rocketMass != null && store.flightConditions != null) {
|
||||
data.setValue(FlightDataType.TYPE_PITCH_MOMENT_COEFF,
|
||||
dataBranch.setValue(FlightDataType.TYPE_PITCH_MOMENT_COEFF,
|
||||
store.forces.getCm() - store.forces.getCN() * store.rocketMass.getCM().x / store.flightConditions.getRefLength());
|
||||
data.setValue(FlightDataType.TYPE_YAW_MOMENT_COEFF,
|
||||
dataBranch.setValue(FlightDataType.TYPE_YAW_MOMENT_COEFF,
|
||||
store.forces.getCyaw() - store.forces.getCside() * store.rocketMass.getCM().x / store.flightConditions.getRefLength());
|
||||
}
|
||||
data.setValue(FlightDataType.TYPE_NORMAL_FORCE_COEFF, store.forces.getCN());
|
||||
data.setValue(FlightDataType.TYPE_SIDE_FORCE_COEFF, store.forces.getCside());
|
||||
data.setValue(FlightDataType.TYPE_ROLL_MOMENT_COEFF, store.forces.getCroll());
|
||||
data.setValue(FlightDataType.TYPE_ROLL_FORCING_COEFF, store.forces.getCrollForce());
|
||||
data.setValue(FlightDataType.TYPE_ROLL_DAMPING_COEFF, store.forces.getCrollDamp());
|
||||
data.setValue(FlightDataType.TYPE_PITCH_DAMPING_MOMENT_COEFF,
|
||||
dataBranch.setValue(FlightDataType.TYPE_NORMAL_FORCE_COEFF, store.forces.getCN());
|
||||
dataBranch.setValue(FlightDataType.TYPE_SIDE_FORCE_COEFF, store.forces.getCside());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ROLL_MOMENT_COEFF, store.forces.getCroll());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ROLL_FORCING_COEFF, store.forces.getCrollForce());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ROLL_DAMPING_COEFF, store.forces.getCrollDamp());
|
||||
dataBranch.setValue(FlightDataType.TYPE_PITCH_DAMPING_MOMENT_COEFF,
|
||||
store.forces.getPitchDampingMoment());
|
||||
}
|
||||
|
||||
if (store.forces != null) {
|
||||
data.setValue(FlightDataType.TYPE_DRAG_COEFF, store.forces.getCD());
|
||||
data.setValue(FlightDataType.TYPE_AXIAL_DRAG_COEFF, store.forces.getCDaxial());
|
||||
data.setValue(FlightDataType.TYPE_FRICTION_DRAG_COEFF, store.forces.getFrictionCD());
|
||||
data.setValue(FlightDataType.TYPE_PRESSURE_DRAG_COEFF, store.forces.getPressureCD());
|
||||
data.setValue(FlightDataType.TYPE_BASE_DRAG_COEFF, store.forces.getBaseCD());
|
||||
dataBranch.setValue(FlightDataType.TYPE_DRAG_COEFF, store.forces.getCD());
|
||||
dataBranch.setValue(FlightDataType.TYPE_AXIAL_DRAG_COEFF, store.forces.getCDaxial());
|
||||
dataBranch.setValue(FlightDataType.TYPE_FRICTION_DRAG_COEFF, store.forces.getFrictionCD());
|
||||
dataBranch.setValue(FlightDataType.TYPE_PRESSURE_DRAG_COEFF, store.forces.getPressureCD());
|
||||
dataBranch.setValue(FlightDataType.TYPE_BASE_DRAG_COEFF, store.forces.getBaseCD());
|
||||
}
|
||||
|
||||
if (store.flightConditions != null) {
|
||||
data.setValue(FlightDataType.TYPE_REFERENCE_LENGTH, store.flightConditions.getRefLength());
|
||||
data.setValue(FlightDataType.TYPE_REFERENCE_AREA, store.flightConditions.getRefArea());
|
||||
dataBranch.setValue(FlightDataType.TYPE_REFERENCE_LENGTH, store.flightConditions.getRefLength());
|
||||
dataBranch.setValue(FlightDataType.TYPE_REFERENCE_AREA, store.flightConditions.getRefArea());
|
||||
|
||||
data.setValue(FlightDataType.TYPE_PITCH_RATE, store.flightConditions.getPitchRate());
|
||||
data.setValue(FlightDataType.TYPE_YAW_RATE, store.flightConditions.getYawRate());
|
||||
data.setValue(FlightDataType.TYPE_ROLL_RATE, store.flightConditions.getRollRate());
|
||||
dataBranch.setValue(FlightDataType.TYPE_PITCH_RATE, store.flightConditions.getPitchRate());
|
||||
dataBranch.setValue(FlightDataType.TYPE_YAW_RATE, store.flightConditions.getYawRate());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ROLL_RATE, store.flightConditions.getRollRate());
|
||||
|
||||
data.setValue(FlightDataType.TYPE_AOA, store.flightConditions.getAOA());
|
||||
dataBranch.setValue(FlightDataType.TYPE_AOA, store.flightConditions.getAOA());
|
||||
}
|
||||
|
||||
Coordinate c = status.getRocketOrientationQuaternion().rotateZ();
|
||||
@ -644,23 +644,23 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
double phi = Math.atan2(c.y, c.x);
|
||||
if (phi < -(Math.PI - 0.0001))
|
||||
phi = Math.PI;
|
||||
data.setValue(FlightDataType.TYPE_ORIENTATION_THETA, theta);
|
||||
data.setValue(FlightDataType.TYPE_ORIENTATION_PHI, phi);
|
||||
dataBranch.setValue(FlightDataType.TYPE_ORIENTATION_THETA, theta);
|
||||
dataBranch.setValue(FlightDataType.TYPE_ORIENTATION_PHI, phi);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_WIND_VELOCITY, store.windSpeed);
|
||||
dataBranch.setValue(FlightDataType.TYPE_WIND_VELOCITY, store.windSpeed);
|
||||
|
||||
if (store.flightConditions != null) {
|
||||
data.setValue(FlightDataType.TYPE_AIR_TEMPERATURE,
|
||||
dataBranch.setValue(FlightDataType.TYPE_AIR_TEMPERATURE,
|
||||
store.flightConditions.getAtmosphericConditions().getTemperature());
|
||||
data.setValue(FlightDataType.TYPE_AIR_PRESSURE,
|
||||
dataBranch.setValue(FlightDataType.TYPE_AIR_PRESSURE,
|
||||
store.flightConditions.getAtmosphericConditions().getPressure());
|
||||
data.setValue(FlightDataType.TYPE_SPEED_OF_SOUND,
|
||||
dataBranch.setValue(FlightDataType.TYPE_SPEED_OF_SOUND,
|
||||
store.flightConditions.getAtmosphericConditions().getMachSpeed());
|
||||
}
|
||||
|
||||
|
||||
data.setValue(FlightDataType.TYPE_TIME_STEP, store.timestep);
|
||||
data.setValue(FlightDataType.TYPE_COMPUTATION_TIME,
|
||||
dataBranch.setValue(FlightDataType.TYPE_TIME_STEP, store.timestep);
|
||||
dataBranch.setValue(FlightDataType.TYPE_COMPUTATION_TIME,
|
||||
(System.nanoTime() - status.getSimulationStartWallTime()) / 1000000000.0);
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,16 @@ public interface SimulationEngine {
|
||||
* Simulate the flight of a rocket.
|
||||
*
|
||||
* @param simulation the simulation conditions which to simulate.
|
||||
* @return a FlightData object containing the simulated data.
|
||||
* @throws SimulationException if an error occurs during simulation
|
||||
*/
|
||||
public FlightData simulate(SimulationConditions simulation)
|
||||
public void simulate(SimulationConditions simulation)
|
||||
throws SimulationException;
|
||||
|
||||
/**
|
||||
* Obtain data generated by simulation
|
||||
*
|
||||
* @return flight data
|
||||
*/
|
||||
public FlightData getFlightData();
|
||||
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class SimulationStatus implements Monitorable {
|
||||
|
||||
private SimulationConditions simulationConditions;
|
||||
private FlightConfiguration configuration;
|
||||
private FlightDataBranch flightData;
|
||||
private FlightDataBranch flightDataBranch;
|
||||
|
||||
private double time;
|
||||
|
||||
@ -169,8 +169,8 @@ public class SimulationStatus implements Monitorable {
|
||||
public SimulationStatus(SimulationStatus orig) {
|
||||
this.simulationConditions = orig.simulationConditions.clone();
|
||||
this.configuration = orig.configuration.clone();
|
||||
// FlightData is not cloned.
|
||||
this.flightData = orig.flightData;
|
||||
// FlightDataBranch is not cloned.
|
||||
this.flightDataBranch = orig.flightDataBranch;
|
||||
this.time = orig.time;
|
||||
this.position = orig.position;
|
||||
this.acceleration = orig.acceleration;
|
||||
@ -247,15 +247,15 @@ public class SimulationStatus implements Monitorable {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public void setFlightData(FlightDataBranch flightData) {
|
||||
if (this.flightData != null)
|
||||
this.modIDadd += this.flightData.getModID();
|
||||
public void setFlightDataBranch(FlightDataBranch flightDataBranch) {
|
||||
if (this.flightDataBranch != null)
|
||||
this.modIDadd += this.flightDataBranch.getModID();
|
||||
this.modID++;
|
||||
this.flightData = flightData;
|
||||
this.flightDataBranch = flightDataBranch;
|
||||
}
|
||||
|
||||
public FlightDataBranch getFlightData() {
|
||||
return flightData;
|
||||
public FlightDataBranch getFlightDataBranch() {
|
||||
return flightDataBranch;
|
||||
}
|
||||
|
||||
public void setRocketPosition(Coordinate position) {
|
||||
@ -481,7 +481,7 @@ public class SimulationStatus implements Monitorable {
|
||||
@Override
|
||||
public int getModID() {
|
||||
return (modID + modIDadd + simulationConditions.getModID() + configuration.getModID() +
|
||||
flightData.getModID() + deployedRecoveryDevices.getModID() +
|
||||
flightDataBranch.getModID() + deployedRecoveryDevices.getModID() +
|
||||
eventQueue.getModID() + warnings.getModID());
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import info.openrocket.core.document.OpenRocketDocument;
|
||||
import info.openrocket.core.logging.Markers;
|
||||
import info.openrocket.core.simulation.FlightDataBranch;
|
||||
import info.openrocket.core.simulation.FlightDataType;
|
||||
import info.openrocket.core.simulation.SimulationStatus;
|
||||
import info.openrocket.core.unit.FixedUnitGroup;
|
||||
@ -431,8 +432,9 @@ public class CustomExpression implements Cloneable {
|
||||
// Set all the built-in variables. Strictly we surely won't need all of them
|
||||
// Going through and checking them to include only the ones used *might* give a
|
||||
// speedup
|
||||
for (FlightDataType type : status.getFlightData().getTypes()) {
|
||||
double value = status.getFlightData().getLast(type);
|
||||
FlightDataBranch dataBranch = status.getFlightDataBranch();
|
||||
for (FlightDataType type : dataBranch.getTypes()) {
|
||||
double value = dataBranch.getLast(type);
|
||||
calc.setVariable(new Variable(type.getSymbol(), value));
|
||||
}
|
||||
|
||||
|
@ -26,12 +26,12 @@ public class CustomExpressionSimulationListener extends AbstractSimulationListen
|
||||
return;
|
||||
}
|
||||
// Calculate values for custom expressions
|
||||
FlightDataBranch data = status.getFlightData();
|
||||
FlightDataBranch dataBranch = status.getFlightDataBranch();
|
||||
for (CustomExpression expression : expressions) {
|
||||
double value = expression.evaluateDouble(status);
|
||||
// log.debug("Setting value of custom expression "+expression.toString()+" =
|
||||
// "+value);
|
||||
data.setValue(expression.getType(), value);
|
||||
dataBranch.setValue(expression.getType(), value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import de.congrace.exp4j.Variable;
|
||||
import info.openrocket.core.document.OpenRocketDocument;
|
||||
import info.openrocket.core.logging.Markers;
|
||||
import info.openrocket.core.simulation.customexpression.CustomExpression;
|
||||
import info.openrocket.core.simulation.FlightDataBranch;
|
||||
import info.openrocket.core.simulation.FlightDataType;
|
||||
import info.openrocket.core.simulation.SimulationStatus;
|
||||
import info.openrocket.core.util.LinearInterpolator;
|
||||
@ -41,13 +42,14 @@ public class IndexExpression extends CustomExpression {
|
||||
// Otherwise there will be a type conflict when we get the new data.
|
||||
FlightDataType myType = FlightDataType.getType(null, getSymbol(), null);
|
||||
|
||||
List<Double> data = status.getFlightData().get(myType);
|
||||
List<Double> time = status.getFlightData().get(FlightDataType.TYPE_TIME);
|
||||
FlightDataBranch dataBranch = status.getFlightDataBranch();
|
||||
List<Double> data = dataBranch.get(myType);
|
||||
List<Double> time = dataBranch.get(FlightDataType.TYPE_TIME);
|
||||
LinearInterpolator interp = new LinearInterpolator(time, data);
|
||||
|
||||
// Set the variables in the expression to evaluate
|
||||
for (FlightDataType etype : status.getFlightData().getTypes()) {
|
||||
double value = status.getFlightData().getLast(etype);
|
||||
for (FlightDataType etype : dataBranch.getTypes()) {
|
||||
double value = dataBranch.getLast(etype);
|
||||
calc.setVariable(new Variable(etype.getSymbol(), value));
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import de.congrace.exp4j.ExpressionBuilder;
|
||||
import de.congrace.exp4j.Variable;
|
||||
import info.openrocket.core.document.OpenRocketDocument;
|
||||
import info.openrocket.core.logging.Markers;
|
||||
import info.openrocket.core.simulation.FlightDataBranch;
|
||||
import info.openrocket.core.simulation.FlightDataType;
|
||||
import info.openrocket.core.simulation.SimulationStatus;
|
||||
import info.openrocket.core.util.ArrayUtils;
|
||||
@ -66,9 +67,10 @@ public class RangeExpression extends CustomExpression {
|
||||
return new Variable("Unknown");
|
||||
}
|
||||
|
||||
FlightDataBranch dataBranch = status.getFlightDataBranch();
|
||||
// Set the variables in the start and end calculators
|
||||
for (FlightDataType type : status.getFlightData().getTypes()) {
|
||||
double value = status.getFlightData().getLast(type);
|
||||
for (FlightDataType type : dataBranch.getTypes()) {
|
||||
double value = dataBranch.getLast(type);
|
||||
startCalc.setVariable(new Variable(type.getSymbol(), value));
|
||||
endCalc.setVariable(new Variable(type.getSymbol(), value));
|
||||
}
|
||||
@ -80,8 +82,8 @@ public class RangeExpression extends CustomExpression {
|
||||
// Otherwise there will be a type conflict when we get the new data.
|
||||
FlightDataType type = FlightDataType.getType(null, getSymbol(), null);
|
||||
|
||||
List<Double> data = status.getFlightData().get(type);
|
||||
List<Double> time = status.getFlightData().get(FlightDataType.TYPE_TIME);
|
||||
List<Double> data = dataBranch.get(type);
|
||||
List<Double> time = dataBranch.get(FlightDataType.TYPE_TIME);
|
||||
LinearInterpolator interp = new LinearInterpolator(time, data);
|
||||
|
||||
// Evaluate the expression to get the start and end of the range
|
||||
|
@ -1,5 +1,7 @@
|
||||
package info.openrocket.core.simulation.exception;
|
||||
|
||||
import info.openrocket.core.simulation.FlightDataBranch;
|
||||
|
||||
/**
|
||||
* An exception that indicates that a computation problem has occurred during
|
||||
* the simulation, for example that some values have exceed reasonable bounds.
|
||||
@ -8,19 +10,27 @@ package info.openrocket.core.simulation.exception;
|
||||
*/
|
||||
public class SimulationCalculationException extends SimulationException {
|
||||
|
||||
private FlightDataBranch flightDataBranch;
|
||||
|
||||
public SimulationCalculationException() {
|
||||
}
|
||||
|
||||
public SimulationCalculationException(String message) {
|
||||
public SimulationCalculationException(String message, FlightDataBranch dataBranch) {
|
||||
super(message);
|
||||
flightDataBranch = dataBranch;
|
||||
}
|
||||
|
||||
public SimulationCalculationException(Throwable cause) {
|
||||
public SimulationCalculationException(Throwable cause, FlightDataBranch dataBranch) {
|
||||
super(cause);
|
||||
flightDataBranch = dataBranch;
|
||||
}
|
||||
|
||||
public SimulationCalculationException(String message, Throwable cause) {
|
||||
public SimulationCalculationException(String message, Throwable cause, FlightDataBranch dataBranch) {
|
||||
super(message, cause);
|
||||
flightDataBranch = dataBranch;
|
||||
}
|
||||
|
||||
public FlightDataBranch getFlightDataBranch() {
|
||||
return flightDataBranch;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,9 @@
|
||||
package info.openrocket.core.simulation.exception;
|
||||
|
||||
import info.openrocket.core.simulation.FlightData;
|
||||
import info.openrocket.core.simulation.FlightDataBranch;
|
||||
|
||||
public class SimulationException extends Exception {
|
||||
|
||||
private FlightData flightData = null;
|
||||
private FlightDataBranch flightDataBranch = null;
|
||||
|
||||
public SimulationException() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
public SimulationException(String message) {
|
||||
@ -23,21 +17,4 @@ public class SimulationException extends Exception {
|
||||
public SimulationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public void setFlightData(FlightData f) {
|
||||
flightData = f;
|
||||
}
|
||||
|
||||
public FlightData getFlightData() {
|
||||
return flightData;
|
||||
}
|
||||
|
||||
public void setFlightDataBranch(FlightDataBranch f) {
|
||||
flightDataBranch = f;
|
||||
}
|
||||
|
||||
public FlightDataBranch getFlightDataBranch() {
|
||||
return flightDataBranch;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -63,122 +63,122 @@ public class CSVSave extends AbstractSimulationExtension {
|
||||
THETA {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_ORIENTATION_THETA);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_ORIENTATION_THETA);
|
||||
}
|
||||
},
|
||||
PHI {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_ORIENTATION_PHI);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_ORIENTATION_PHI);
|
||||
}
|
||||
},
|
||||
AOA {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_AOA);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_AOA);
|
||||
}
|
||||
},
|
||||
ROLLRATE {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_ROLL_RATE);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_ROLL_RATE);
|
||||
}
|
||||
},
|
||||
PITCHRATE {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_PITCH_RATE);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_PITCH_RATE);
|
||||
}
|
||||
},
|
||||
|
||||
PITCHMOMENT {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_PITCH_MOMENT_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_PITCH_MOMENT_COEFF);
|
||||
}
|
||||
},
|
||||
YAWMOMENT {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_YAW_MOMENT_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_YAW_MOMENT_COEFF);
|
||||
}
|
||||
},
|
||||
ROLLMOMENT {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_ROLL_MOMENT_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_ROLL_MOMENT_COEFF);
|
||||
}
|
||||
},
|
||||
NORMALFORCE {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_NORMAL_FORCE_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_NORMAL_FORCE_COEFF);
|
||||
}
|
||||
},
|
||||
SIDEFORCE {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_SIDE_FORCE_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_SIDE_FORCE_COEFF);
|
||||
}
|
||||
},
|
||||
AXIALFORCE {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_DRAG_FORCE);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_DRAG_FORCE);
|
||||
}
|
||||
},
|
||||
WINDSPEED {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_WIND_VELOCITY);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_WIND_VELOCITY);
|
||||
}
|
||||
},
|
||||
PITCHDAMPING {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_PITCH_DAMPING_MOMENT_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_PITCH_DAMPING_MOMENT_COEFF);
|
||||
}
|
||||
},
|
||||
CA {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_AXIAL_DRAG_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_AXIAL_DRAG_COEFF);
|
||||
}
|
||||
},
|
||||
CD {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_DRAG_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_DRAG_COEFF);
|
||||
}
|
||||
},
|
||||
CDpressure {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_PRESSURE_DRAG_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_PRESSURE_DRAG_COEFF);
|
||||
}
|
||||
},
|
||||
CDfriction {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_FRICTION_DRAG_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_FRICTION_DRAG_COEFF);
|
||||
}
|
||||
},
|
||||
CDbase {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_BASE_DRAG_COEFF);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_BASE_DRAG_COEFF);
|
||||
}
|
||||
},
|
||||
MACH {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_MACH_NUMBER);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_MACH_NUMBER);
|
||||
}
|
||||
},
|
||||
RE {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_REYNOLDS_NUMBER);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_REYNOLDS_NUMBER);
|
||||
}
|
||||
},
|
||||
|
||||
@ -204,7 +204,7 @@ public class CSVSave extends AbstractSimulationExtension {
|
||||
MASS {
|
||||
@Override
|
||||
public double getValue(SimulationStatus status) {
|
||||
return status.getFlightData().getLast(FlightDataType.TYPE_MASS);
|
||||
return status.getFlightDataBranch().getLast(FlightDataType.TYPE_MASS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,8 @@ public class DampingMoment extends AbstractSimulationExtension {
|
||||
public FlightConditions postFlightConditions(SimulationStatus status, FlightConditions flightConditions)
|
||||
throws SimulationException {
|
||||
|
||||
// status.getFlightData().setValue(cdm, aerodynamicPart + propulsivePart);
|
||||
status.getFlightData().setValue(cdm, calculate(status, flightConditions));
|
||||
// status.getFlightDataBranch().setValue(cdm, aerodynamicPart + propulsivePart);
|
||||
status.getFlightDataBranch().setValue(cdm, calculate(status, flightConditions));
|
||||
|
||||
return flightConditions;
|
||||
}
|
||||
@ -72,10 +72,10 @@ public class DampingMoment extends AbstractSimulationExtension {
|
||||
// Work out the propulsive/jet damping part of the moment.
|
||||
|
||||
// dm/dt = (thrust - ma)/v
|
||||
FlightDataBranch data = status.getFlightData();
|
||||
FlightDataBranch dataBranch = status.getFlightDataBranch();
|
||||
|
||||
List<Double> mpAll = data.get(FlightDataType.TYPE_MOTOR_MASS);
|
||||
List<Double> time = data.get(FlightDataType.TYPE_TIME);
|
||||
List<Double> mpAll = dataBranch.get(FlightDataType.TYPE_MOTOR_MASS);
|
||||
List<Double> time = dataBranch.get(FlightDataType.TYPE_TIME);
|
||||
if (mpAll == null || time == null) {
|
||||
return Double.NaN;
|
||||
}
|
||||
@ -98,7 +98,7 @@ public class DampingMoment extends AbstractSimulationExtension {
|
||||
mdot = (mpAll.get(len - 1) - mpAll.get(len - 2)) / (time.get(len - 1) - time.get(len - 2));
|
||||
}
|
||||
|
||||
double cg = data.getLast(FlightDataType.TYPE_CG_LOCATION);
|
||||
double cg = dataBranch.getLast(FlightDataType.TYPE_CG_LOCATION);
|
||||
|
||||
// find the maximum distance from nose to nozzle.
|
||||
double nozzleDistance = 0;
|
||||
|
@ -37,17 +37,17 @@ public class PrintSimulation extends AbstractSimulationExtension {
|
||||
|
||||
@Override
|
||||
public void postStep(SimulationStatus status) throws SimulationException {
|
||||
FlightDataBranch data = status.getFlightData();
|
||||
FlightDataBranch dataBranch = status.getFlightDataBranch();
|
||||
System.out.printf("*** stepTaken *** time=%.3f position=" + status.getRocketPosition() +
|
||||
" velocity=" + status.getRocketVelocity() + "=%.3f\n", status.getSimulationTime(),
|
||||
status.getRocketVelocity().length());
|
||||
System.out.printf(" thrust=%.3fN drag==%.3fN mass=%.3fkg " +
|
||||
"accZ=%.3fm/s2 acc=%.3fm/s2\n",
|
||||
data.getLast(FlightDataType.TYPE_THRUST_FORCE),
|
||||
data.getLast(FlightDataType.TYPE_DRAG_FORCE),
|
||||
data.getLast(FlightDataType.TYPE_MASS),
|
||||
data.getLast(FlightDataType.TYPE_ACCELERATION_Z),
|
||||
data.getLast(FlightDataType.TYPE_ACCELERATION_TOTAL));
|
||||
dataBranch.getLast(FlightDataType.TYPE_THRUST_FORCE),
|
||||
dataBranch.getLast(FlightDataType.TYPE_DRAG_FORCE),
|
||||
dataBranch.getLast(FlightDataType.TYPE_MASS),
|
||||
dataBranch.getLast(FlightDataType.TYPE_ACCELERATION_Z),
|
||||
dataBranch.getLast(FlightDataType.TYPE_ACCELERATION_TOTAL));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,7 +198,7 @@ public class RollControl extends AbstractSimulationExtension {
|
||||
|
||||
// Set the control fin cant and store the data
|
||||
finset.setCantAngle(finPosition);
|
||||
status.getFlightData().setValue(FIN_CANT_TYPE, finPosition);
|
||||
status.getFlightDataBranch().setValue(FIN_CANT_TYPE, finPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -216,13 +216,13 @@ public class SimulationPlot {
|
||||
if (thisBranch.getLength() == 0) {
|
||||
// Add an empty series to keep the series count consistent
|
||||
XYSeries series = new XYSeries(seriesCount++, false, true);
|
||||
series.setDescription(thisBranch.getBranchName() + ": " + name);
|
||||
series.setDescription(thisBranch.getName() + ": " + name);
|
||||
data[axis].addSeries(series);
|
||||
continue;
|
||||
}
|
||||
|
||||
XYSeries series = new XYSeries(seriesCount++, false, true);
|
||||
series.setDescription(thisBranch.getBranchName() + ": " + name);
|
||||
series.setDescription(thisBranch.getName() + ": " + name);
|
||||
|
||||
// Copy all the data from the secondary branch
|
||||
List<Double> plotx = thisBranch.get(domainType);
|
||||
@ -848,7 +848,7 @@ public class SimulationPlot {
|
||||
abortString = new StringBuilder(trans.get("simulationplot.abort.title"));
|
||||
}
|
||||
abortString.append("\n")
|
||||
.append(trans.get("simulationplot.abort.stage")).append(": ").append(branch.getBranchName()).append("; ")
|
||||
.append(trans.get("simulationplot.abort.stage")).append(": ").append(branch.getName()).append("; ")
|
||||
.append(trans.get("simulationplot.abort.time")).append(": ").append(abortEvent.getTime()).append(" s; ")
|
||||
.append(trans.get("simulationplot.abort.cause")).append(": ").append(((SimulationAbort) abortEvent.getData()).getMessageDescription());
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public abstract class Util {
|
||||
// on the stage name there is no guarantee they are unique. In order to address this, we first assume
|
||||
// all the names are unique, then go through them looking for duplicates.
|
||||
for (int i = 0; i < simulation.getSimulatedData().getBranchCount(); i++) {
|
||||
stages.add(simulation.getSimulatedData().getBranch(i).getBranchName());
|
||||
stages.add(simulation.getSimulatedData().getBranch(i).getName());
|
||||
}
|
||||
// check for duplicates:
|
||||
for( int i = 0; i< stages.size(); i++ ) {
|
||||
|
@ -36,6 +36,7 @@ import info.openrocket.core.simulation.FlightEvent;
|
||||
import info.openrocket.core.simulation.SimulationStatus;
|
||||
import info.openrocket.core.simulation.customexpression.CustomExpression;
|
||||
import info.openrocket.core.simulation.customexpression.CustomExpressionSimulationListener;
|
||||
import info.openrocket.core.simulation.exception.SimulationCalculationException;
|
||||
import info.openrocket.core.simulation.exception.SimulationCancelledException;
|
||||
import info.openrocket.core.simulation.exception.SimulationException;
|
||||
import info.openrocket.core.simulation.listeners.AbstractSimulationListener;
|
||||
@ -426,14 +427,16 @@ public class SimulationRunDialog extends JDialog {
|
||||
// Analyze the exception type
|
||||
if (t instanceof SimulationException) {
|
||||
String title = simulation.getName();
|
||||
FlightDataBranch dataBranch = ((SimulationException) t).getFlightDataBranch();
|
||||
|
||||
FlightDataBranch dataBranch = null;
|
||||
if (t instanceof SimulationCalculationException) {
|
||||
dataBranch = ((SimulationCalculationException) t).getFlightDataBranch();
|
||||
}
|
||||
String message;
|
||||
if (dataBranch != null) {
|
||||
message = trans.get("SimuRunDlg.msg.branchErrorOccurred") + "\"" + dataBranch.getBranchName() + "\"";
|
||||
message = trans.get("SimuRunDlg.msg.branchErrorOccurred") + " \"" + dataBranch.getName() + "\"";
|
||||
} else {
|
||||
message = trans.get("SimuRunDlg.msg.errorOccurred");
|
||||
}
|
||||
}
|
||||
DetailDialog.showDetailedMessageDialog(SimulationRunDialog.this,
|
||||
new Object[] {
|
||||
//// A error occurred during the simulation:
|
||||
|
Loading…
x
Reference in New Issue
Block a user