From 9d24cecbef4c2b13fd938d4ca323d4e3db39a915 Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Tue, 15 Nov 2022 09:46:05 -0700 Subject: [PATCH 1/2] Move recovery device check to simulation startup. It doesn't need to be checked on every iteration. --- .../simulation/BasicEventSimulationEngine.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java b/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java index 339c0704b..38e5c487b 100644 --- a/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java +++ b/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java @@ -73,6 +73,14 @@ public class BasicEventSimulationEngine implements SimulationEngine { } currentStatus = new SimulationStatus(simulationConfig, simulationConditions); + + // Sanity checks on design and configuration + + // No recovery device + if (!currentStatus.getConfiguration().hasRecoveryDevice()) { + currentStatus.getWarnings().add(Warning.NO_RECOVERY_DEVICE); + } + currentStatus.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket())); { // main simulation branch @@ -341,11 +349,6 @@ public class BasicEventSimulationEngine implements SimulationEngine { event.getTime() + Math.max(0.001, deployConfig.getDeployDelay()), c)); } } - - // Add a warning if there is no recovery device defined. - if (!currentStatus.getConfiguration().hasRecoveryDevice()) { - currentStatus.getWarnings().add(Warning.NO_RECOVERY_DEVICE); - } // Handle event log.trace("Handling event " + event); From 21987ce411476f70402a3a7e94043a881512abca Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Tue, 15 Nov 2022 10:43:00 -0700 Subject: [PATCH 2/2] Make sanity check code at start of simulation clearer On SimulationException, record the abort in the flight data but then rethrow the exception --- core/resources/l10n/messages.properties | 1 + .../BasicEventSimulationEngine.java | 24 +++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index d1462bf8a..864d21d9c 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -554,6 +554,7 @@ SimuRunDlg.msg.errorOccurred = An error occurred during the simulation: BasicEventSimulationEngine.error.noMotorsDefined = No motors defined in the simulation. BasicEventSimulationEngine.error.earlyMotorBurnout = Motor burnout without liftoff. +BasicEventSimulationEngine.error.noConfiguredIgnition = No motors configured to ignite at liftoff BasicEventSimulationEngine.error.noIgnition = No motors ignited. BasicEventSimulationEngine.error.NaNResult = Simulation resulted in not-a-number (NaN) value, please report a bug. diff --git a/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java b/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java index 38e5c487b..59c4fe25d 100644 --- a/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java +++ b/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java @@ -1,6 +1,7 @@ package net.sf.openrocket.simulation; import java.util.ArrayDeque; +import java.util.Collection; import java.util.Deque; import org.slf4j.Logger; @@ -8,6 +9,7 @@ import org.slf4j.LoggerFactory; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.motor.IgnitionEvent; import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.motor.MotorConfigurationId; import net.sf.openrocket.rocketcomponent.AxialStage; @@ -68,16 +70,22 @@ public class BasicEventSimulationEngine implements SimulationEngine { FlightConfiguration origConfig = simulationConditions.getRocket().getFlightConfiguration(this.fcid); FlightConfiguration simulationConfig = origConfig.clone(); simulationConfig.copyStages(origConfig); // Clone the stage activation configuration - if ( ! simulationConfig.hasMotors() ) { - throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noMotorsDefined")); - } currentStatus = new SimulationStatus(simulationConfig, simulationConditions); // Sanity checks on design and configuration - + + // Problems that keep us from simulating at all + + // No motors in configuration + if (!simulationConfig.hasMotors() ) { + throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noMotorsDefined")); + } + + // Problems that let us simulate, but result is likely bad + // No recovery device - if (!currentStatus.getConfiguration().hasRecoveryDevice()) { + if (!simulationConfig.hasRecoveryDevice()) { currentStatus.getWarnings().add(Warning.NO_RECOVERY_DEVICE); } @@ -116,7 +124,7 @@ public class BasicEventSimulationEngine implements SimulationEngine { return flightData; } - private FlightDataBranch simulateLoop() { + private FlightDataBranch simulateLoop() throws SimulationException { // Initialize the simulation. We'll use the flight stepper unless we're already on the ground if (currentStatus.isLanded()) @@ -248,9 +256,11 @@ public class BasicEventSimulationEngine implements SimulationEngine { } catch (SimulationException e) { SimulationListenerHelper.fireEndSimulation(currentStatus, e); + // Add FlightEvent for Abort. currentStatus.getFlightData().addEvent(new FlightEvent(FlightEvent.Type.EXCEPTION, currentStatus.getSimulationTime(), currentStatus.getConfiguration().getRocket(), e.getLocalizedMessage())); - currentStatus.getWarnings().add(e.getLocalizedMessage()); + + throw e; } return currentStatus.getFlightData();