diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 328713a3a..41023442f 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 d3d61b829..63e3f1d7b 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,11 +70,25 @@ 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 (!simulationConfig.hasRecoveryDevice()) { + currentStatus.getWarnings().add(Warning.NO_RECOVERY_DEVICE); + } + currentStatus.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket())); { // main simulation branch @@ -114,7 +130,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()) @@ -246,9 +262,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(); @@ -347,11 +365,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);