diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1a2c8214b..ca902e775 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 diff --git a/.gitignore b/.gitignore index b1690755a..38050b5fa 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ **/.idea/vcs.xml **/.idea/jsLibraryMappings.xml **/.idea/copilot +**/.idea/shelf # Sensitive or high-churn files: **/.idea/dataSources.ids diff --git a/.idea/runConfigurations/All_tests.xml b/.idea/runConfigurations/All_tests.xml deleted file mode 100644 index 2e910eef8..000000000 --- a/.idea/runConfigurations/All_tests.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/Openrocket_UI_Jar.xml b/.idea/runConfigurations/Openrocket_UI_Jar.xml deleted file mode 100644 index 45da998b1..000000000 --- a/.idea/runConfigurations/Openrocket_UI_Jar.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/SwingStartup.xml b/.idea/runConfigurations/SwingStartup.xml new file mode 100644 index 000000000..73705a124 --- /dev/null +++ b/.idea/runConfigurations/SwingStartup.xml @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/openrocket_jar.xml b/.idea/runConfigurations/openrocket_jar.xml new file mode 100644 index 000000000..32fd63118 --- /dev/null +++ b/.idea/runConfigurations/openrocket_jar.xml @@ -0,0 +1,27 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.idea/runConfigurations/openrocket_test.xml b/.idea/runConfigurations/openrocket_test.xml new file mode 100644 index 000000000..f7c291211 --- /dev/null +++ b/.idea/runConfigurations/openrocket_test.xml @@ -0,0 +1,25 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/core/src/main/java/info/openrocket/core/document/Simulation.java b/core/src/main/java/info/openrocket/core/document/Simulation.java index d9d1530fb..3ec5ae0f3 100644 --- a/core/src/main/java/info/openrocket/core/document/Simulation.java +++ b/core/src/main/java/info/openrocket/core/document/Simulation.java @@ -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(); diff --git a/core/src/main/java/info/openrocket/core/file/openrocket/OpenRocketSaver.java b/core/src/main/java/info/openrocket/core/file/openrocket/OpenRocketSaver.java index db22f6411..5e2bba244 100644 --- a/core/src/main/java/info/openrocket/core/file/openrocket/OpenRocketSaver.java +++ b/core/src/main/java/info/openrocket/core/file/openrocket/OpenRocketSaver.java @@ -483,7 +483,7 @@ public class OpenRocketSaver extends RocketSaver { // Build the tag StringBuilder sb = new StringBuilder(); sb.append(">Starting simulation of branch: " + currentStatus.getFlightData().getBranchName()); - - FlightDataBranch dataBranch = simulateLoop(); - flightData.addBranch(dataBranch); - flightData.getWarningSet().addAll(currentStatus.getWarnings()); - - log.info(String.format("<>Starting simulation of branch: " + currentStatus.getFlightDataBranch().getName()); + + simulateLoop(); + dataBranch.immute(); + flightData.getWarningSet().addAll(currentStatus.getWarnings()); + + log.info(String.format("< 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; + } } diff --git a/core/src/main/java/info/openrocket/core/simulation/FlightData.java b/core/src/main/java/info/openrocket/core/simulation/FlightData.java index ea6230184..3fae1cad8 100644 --- a/core/src/main/java/info/openrocket/core/simulation/FlightData.java +++ b/core/src/main/java/info/openrocket/core/simulation/FlightData.java @@ -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; diff --git a/core/src/main/java/info/openrocket/core/simulation/FlightDataBranch.java b/core/src/main/java/info/openrocket/core/simulation/FlightDataBranch.java index 644cd0f33..5a173e95e 100644 --- a/core/src/main/java/info/openrocket/core/simulation/FlightDataBranch.java +++ b/core/src/main/java/info/openrocket/core/simulation/FlightDataBranch.java @@ -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> 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()); } diff --git a/core/src/main/java/info/openrocket/core/simulation/RK4SimulationStepper.java b/core/src/main/java/info/openrocket/core/simulation/RK4SimulationStepper.java index 94923d0b0..8e41a20dc 100644 --- a/core/src/main/java/info/openrocket/core/simulation/RK4SimulationStepper.java +++ b/core/src/main/java/info/openrocket/core/simulation/RK4SimulationStepper.java @@ -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); } diff --git a/core/src/main/java/info/openrocket/core/simulation/SimulationEngine.java b/core/src/main/java/info/openrocket/core/simulation/SimulationEngine.java index fcda5efec..d4ddb3e8f 100644 --- a/core/src/main/java/info/openrocket/core/simulation/SimulationEngine.java +++ b/core/src/main/java/info/openrocket/core/simulation/SimulationEngine.java @@ -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(); + } diff --git a/core/src/main/java/info/openrocket/core/simulation/SimulationStatus.java b/core/src/main/java/info/openrocket/core/simulation/SimulationStatus.java index c954f227c..191cb6a01 100644 --- a/core/src/main/java/info/openrocket/core/simulation/SimulationStatus.java +++ b/core/src/main/java/info/openrocket/core/simulation/SimulationStatus.java @@ -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()); } diff --git a/core/src/main/java/info/openrocket/core/simulation/customexpression/CustomExpression.java b/core/src/main/java/info/openrocket/core/simulation/customexpression/CustomExpression.java index 6f104065b..3158cb1f5 100644 --- a/core/src/main/java/info/openrocket/core/simulation/customexpression/CustomExpression.java +++ b/core/src/main/java/info/openrocket/core/simulation/customexpression/CustomExpression.java @@ -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)); } diff --git a/core/src/main/java/info/openrocket/core/simulation/customexpression/CustomExpressionSimulationListener.java b/core/src/main/java/info/openrocket/core/simulation/customexpression/CustomExpressionSimulationListener.java index 024bc4673..43056b92a 100644 --- a/core/src/main/java/info/openrocket/core/simulation/customexpression/CustomExpressionSimulationListener.java +++ b/core/src/main/java/info/openrocket/core/simulation/customexpression/CustomExpressionSimulationListener.java @@ -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); } } diff --git a/core/src/main/java/info/openrocket/core/simulation/customexpression/IndexExpression.java b/core/src/main/java/info/openrocket/core/simulation/customexpression/IndexExpression.java index 6c35a84fe..bc3239e1f 100644 --- a/core/src/main/java/info/openrocket/core/simulation/customexpression/IndexExpression.java +++ b/core/src/main/java/info/openrocket/core/simulation/customexpression/IndexExpression.java @@ -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 data = status.getFlightData().get(myType); - List time = status.getFlightData().get(FlightDataType.TYPE_TIME); + FlightDataBranch dataBranch = status.getFlightDataBranch(); + List data = dataBranch.get(myType); + List 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)); } diff --git a/core/src/main/java/info/openrocket/core/simulation/customexpression/RangeExpression.java b/core/src/main/java/info/openrocket/core/simulation/customexpression/RangeExpression.java index 453cb0c9d..e7315fada 100644 --- a/core/src/main/java/info/openrocket/core/simulation/customexpression/RangeExpression.java +++ b/core/src/main/java/info/openrocket/core/simulation/customexpression/RangeExpression.java @@ -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 data = status.getFlightData().get(type); - List time = status.getFlightData().get(FlightDataType.TYPE_TIME); + List data = dataBranch.get(type); + List time = dataBranch.get(FlightDataType.TYPE_TIME); LinearInterpolator interp = new LinearInterpolator(time, data); // Evaluate the expression to get the start and end of the range diff --git a/core/src/main/java/info/openrocket/core/simulation/exception/SimulationCalculationException.java b/core/src/main/java/info/openrocket/core/simulation/exception/SimulationCalculationException.java index 5d73fdabe..296a23b56 100644 --- a/core/src/main/java/info/openrocket/core/simulation/exception/SimulationCalculationException.java +++ b/core/src/main/java/info/openrocket/core/simulation/exception/SimulationCalculationException.java @@ -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; + } } diff --git a/core/src/main/java/info/openrocket/core/simulation/exception/SimulationException.java b/core/src/main/java/info/openrocket/core/simulation/exception/SimulationException.java index b07ae8d42..ead701fc0 100644 --- a/core/src/main/java/info/openrocket/core/simulation/exception/SimulationException.java +++ b/core/src/main/java/info/openrocket/core/simulation/exception/SimulationException.java @@ -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; - } - } diff --git a/core/src/main/java/info/openrocket/core/simulation/extension/example/CSVSave.java b/core/src/main/java/info/openrocket/core/simulation/extension/example/CSVSave.java index 60992bae2..40eeaabeb 100644 --- a/core/src/main/java/info/openrocket/core/simulation/extension/example/CSVSave.java +++ b/core/src/main/java/info/openrocket/core/simulation/extension/example/CSVSave.java @@ -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); } } diff --git a/core/src/main/java/info/openrocket/core/simulation/extension/example/DampingMoment.java b/core/src/main/java/info/openrocket/core/simulation/extension/example/DampingMoment.java index 4196ae490..f64bbadd2 100644 --- a/core/src/main/java/info/openrocket/core/simulation/extension/example/DampingMoment.java +++ b/core/src/main/java/info/openrocket/core/simulation/extension/example/DampingMoment.java @@ -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 mpAll = data.get(FlightDataType.TYPE_MOTOR_MASS); - List time = data.get(FlightDataType.TYPE_TIME); + List mpAll = dataBranch.get(FlightDataType.TYPE_MOTOR_MASS); + List 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; diff --git a/core/src/main/java/info/openrocket/core/simulation/extension/example/PrintSimulation.java b/core/src/main/java/info/openrocket/core/simulation/extension/example/PrintSimulation.java index a17d6e7f7..e0485830b 100644 --- a/core/src/main/java/info/openrocket/core/simulation/extension/example/PrintSimulation.java +++ b/core/src/main/java/info/openrocket/core/simulation/extension/example/PrintSimulation.java @@ -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)); } } diff --git a/core/src/main/java/info/openrocket/core/simulation/extension/example/RollControl.java b/core/src/main/java/info/openrocket/core/simulation/extension/example/RollControl.java index cb3cecc59..976a232fb 100644 --- a/core/src/main/java/info/openrocket/core/simulation/extension/example/RollControl.java +++ b/core/src/main/java/info/openrocket/core/simulation/extension/example/RollControl.java @@ -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 diff --git a/swing/src/main/java/info/openrocket/swing/gui/plot/SimulationPlot.java b/swing/src/main/java/info/openrocket/swing/gui/plot/SimulationPlot.java index 3db8905dd..53b7f3336 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/plot/SimulationPlot.java +++ b/swing/src/main/java/info/openrocket/swing/gui/plot/SimulationPlot.java @@ -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 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()); } diff --git a/swing/src/main/java/info/openrocket/swing/gui/plot/Util.java b/swing/src/main/java/info/openrocket/swing/gui/plot/Util.java index c9c686fcf..76bb1bb31 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/plot/Util.java +++ b/swing/src/main/java/info/openrocket/swing/gui/plot/Util.java @@ -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++ ) { diff --git a/swing/src/main/java/info/openrocket/swing/gui/simulation/SimulationRunDialog.java b/swing/src/main/java/info/openrocket/swing/gui/simulation/SimulationRunDialog.java index 1ce5c11db..30f5e0220 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/simulation/SimulationRunDialog.java +++ b/swing/src/main/java/info/openrocket/swing/gui/simulation/SimulationRunDialog.java @@ -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: