Integrate SIM_ABORT into code across OR

This commit is contained in:
JoePfeiffer 2023-12-24 10:32:10 -07:00
parent 2123531f14
commit 173a3d38e2
6 changed files with 56 additions and 30 deletions

View File

@ -662,7 +662,7 @@ SimulationAbort.noIgnition = No motors ignited
SimulationAbort.noLiftOff = <html>Motor burnout without liftoff.<br>Use more (powerful) motors, or decrease the rocket mass.</html> SimulationAbort.noLiftOff = <html>Motor burnout without liftoff.<br>Use more (powerful) motors, or decrease the rocket mass.</html>
SimulationAbort.activeLengthZero = Active airframe has length 0 SimulationAbort.activeLengthZero = Active airframe has length 0
SimulationAbort.noCP = Can't calculate Center of Pressure SimulationAbort.noCP = Can't calculate Center of Pressure
SimulationAbort.totalMassZero = Total mass of active stages is 0 SimulationAbort.activeMassZero = Total mass of active stages is 0
SimulationModifierTree.OptimizationParameters = Optimization Parameters SimulationModifierTree.OptimizationParameters = Optimization Parameters

View File

@ -37,12 +37,12 @@ public class SimulationAbort extends Message {
public static final SimulationAbort NOCONFIGUREDIGNITION = new SimulationAbort(trans.get("SimulationAbort.noConfiguredIgnition")); public static final SimulationAbort NOCONFIGUREDIGNITION = new SimulationAbort(trans.get("SimulationAbort.noConfiguredIgnition"));
// No motors fired (can this really happen without getting a NoMotorsDefined?) // No motors fired (can this really happen without getting a NoMotorsDefined?)
public static final SimulationAbort NOMOTORSFIRED = new SimulationAbort(trans.get("SimulationAbort.noMotorsIgnited")); public static final SimulationAbort NOMOTORSFIRED = new SimulationAbort(trans.get("SimulationAbort.noIgnition"));
// Motors ignited, but rocket did not lift off // Motors ignited, but rocket did not lift off
public static final SimulationAbort NOLIFTOFF = new SimulationAbort(trans.get("SimulationAbort.noLiftOff")); public static final SimulationAbort NOLIFTOFF = new SimulationAbort(trans.get("SimulationAbort.noLiftOff"));
// It is impossible to calculate the stage's center of pressure // It is impossible to calculate the active components' center of pressure
public static final SimulationAbort NOCP = new SimulationAbort(trans.get("SimulationAbort.noCP")); public static final SimulationAbort NOCP = new SimulationAbort(trans.get("SimulationAbort.noCP"));
// The currently active components have a total length of 0 // The currently active components have a total length of 0

View File

@ -7,6 +7,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import net.sf.openrocket.aerodynamics.FlightConditions; import net.sf.openrocket.aerodynamics.FlightConditions;
import net.sf.openrocket.logging.SimulationAbort;
import net.sf.openrocket.logging.Warning; import net.sf.openrocket.logging.Warning;
import net.sf.openrocket.logging.WarningSet; import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
@ -178,7 +179,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
// If we haven't hit the ground, add altitude event // If we haven't hit the ground, add altitude event
if (!currentStatus.isLanded()) if (!currentStatus.isLanded())
addEvent(new FlightEvent(FlightEvent.Type.ALTITUDE, currentStatus.getSimulationTime(), currentStatus.addEvent(new FlightEvent(FlightEvent.Type.ALTITUDE, currentStatus.getSimulationTime(),
currentStatus.getConfiguration().getRocket(), currentStatus.getConfiguration().getRocket(),
new Pair<Double, Double>(oldAlt, currentStatus.getRocketPosition().z))); new Pair<Double, Double>(oldAlt, currentStatus.getRocketPosition().z)));
@ -200,16 +201,16 @@ public class BasicEventSimulationEngine implements SimulationEngine {
} }
// Detect lift-off // Detect lift-off
if (relativePosition.z > 0.02) { if (relativePosition.z > 0.02) {
addEvent(new FlightEvent(FlightEvent.Type.LIFTOFF, currentStatus.getSimulationTime())); currentStatus.addEvent(new FlightEvent(FlightEvent.Type.LIFTOFF, currentStatus.getSimulationTime()));
} }
} else { } else {
// Check ground hit after liftoff // Check ground hit after liftoff
if ((currentStatus.getRocketPosition().z < MathUtil.EPSILON) && !currentStatus.isLanded()) { if ((currentStatus.getRocketPosition().z < MathUtil.EPSILON) && !currentStatus.isLanded()) {
addEvent(new FlightEvent(FlightEvent.Type.GROUND_HIT, currentStatus.getSimulationTime())); currentStatus.addEvent(new FlightEvent(FlightEvent.Type.GROUND_HIT, currentStatus.getSimulationTime()));
// addEvent(new FlightEvent(FlightEvent.Type.SIMULATION_END, currentStatus.getSimulationTime())); // currentStatus.addEvent(new FlightEvent(FlightEvent.Type.SIMULATION_END, currentStatus.getSimulationTime()));
} }
} }
@ -218,14 +219,14 @@ public class BasicEventSimulationEngine implements SimulationEngine {
if (currentStatus.isLiftoff() && if (currentStatus.isLiftoff() &&
!currentStatus.isLaunchRodCleared() && !currentStatus.isLaunchRodCleared() &&
relativePosition.length() > currentStatus.getSimulationConditions().getLaunchRodLength()) { relativePosition.length() > currentStatus.getSimulationConditions().getLaunchRodLength()) {
addEvent(new FlightEvent(FlightEvent.Type.LAUNCHROD, currentStatus.getSimulationTime(), null)); currentStatus.addEvent(new FlightEvent(FlightEvent.Type.LAUNCHROD, currentStatus.getSimulationTime(), null));
} }
// Check for apogee // Check for apogee
if (!currentStatus.isApogeeReached() && currentStatus.getRocketPosition().z < currentStatus.getMaxAlt() - 0.01) { if (!currentStatus.isApogeeReached() && currentStatus.getRocketPosition().z < currentStatus.getMaxAlt() - 0.01) {
currentStatus.setMaxAltTime(previousSimulationTime); currentStatus.setMaxAltTime(previousSimulationTime);
addEvent(new FlightEvent(FlightEvent.Type.APOGEE, previousSimulationTime, currentStatus.addEvent(new FlightEvent(FlightEvent.Type.APOGEE, previousSimulationTime,
currentStatus.getConfiguration().getRocket())); currentStatus.getConfiguration().getRocket()));
} }
@ -234,7 +235,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
// // Check for burnt out motors // // Check for burnt out motors
// for( MotorClusterState state : currentStatus.getActiveMotors()){ // for( MotorClusterState state : currentStatus.getActiveMotors()){
// if ( state.isSpent()){ // if ( state.isSpent()){
// addEvent(new FlightEvent(FlightEvent.Type.BURNOUT, currentStatus.getSimulationTime(), // currentStatus.addEvent(new FlightEvent(FlightEvent.Type.BURNOUT, currentStatus.getSimulationTime(),
// (RocketComponent) state.getMount(), state)); // (RocketComponent) state.getMount(), state));
// } // }
// } // }
@ -256,13 +257,13 @@ public class BasicEventSimulationEngine implements SimulationEngine {
final boolean isSustainer = currentStatus.getConfiguration().isStageActive(0); final boolean isSustainer = currentStatus.getConfiguration().isStageActive(0);
final boolean isApogee = currentStatus.isApogeeReached(); final boolean isApogee = currentStatus.isApogeeReached();
if (wantToTumble && (isApogee || !isSustainer)) { if (wantToTumble && (isApogee || !isSustainer)) {
addEvent(new FlightEvent(FlightEvent.Type.TUMBLE, currentStatus.getSimulationTime())); currentStatus.addEvent(new FlightEvent(FlightEvent.Type.TUMBLE, currentStatus.getSimulationTime()));
} }
} }
// If I'm on the ground and have no events in the queue, I'm done // If I'm on the ground and have no events in the queue, I'm done
if (currentStatus.isLanded() && currentStatus.getEventQueue().isEmpty()) if (currentStatus.isLanded() && currentStatus.getEventQueue().isEmpty())
addEvent(new FlightEvent(FlightEvent.Type.SIMULATION_END, currentStatus.getSimulationTime())); currentStatus.addEvent(new FlightEvent(FlightEvent.Type.SIMULATION_END, currentStatus.getSimulationTime()));
previousSimulationTime = currentStatus.getSimulationTime(); previousSimulationTime = currentStatus.getSimulationTime();
} }
@ -270,7 +271,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
} catch (SimulationException e) { } catch (SimulationException e) {
SimulationListenerHelper.fireEndSimulation(currentStatus, e); SimulationListenerHelper.fireEndSimulation(currentStatus, e);
// Add FlightEvent for Abort. // Add FlightEvent for exception.
currentStatus.getFlightData().addEvent(new FlightEvent(FlightEvent.Type.EXCEPTION, currentStatus.getSimulationTime(), currentStatus.getConfiguration().getRocket(), e.getLocalizedMessage())); currentStatus.getFlightData().addEvent(new FlightEvent(FlightEvent.Type.EXCEPTION, currentStatus.getSimulationTime(), currentStatus.getConfiguration().getRocket(), e.getLocalizedMessage()));
flightData.addBranch(currentStatus.getFlightData()); flightData.addBranch(currentStatus.getFlightData());
@ -325,7 +326,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
log.info("Queueing Ignition Event for: "+state.toDescription()+" @: "+ignitionTime); log.info("Queueing Ignition Event for: "+state.toDescription()+" @: "+ignitionTime);
//log.info(" Because of "+event.getShapeType().name()+" @"+event.getTime()+" from: "+event.getSource().getName()); //log.info(" Because of "+event.getShapeType().name()+" @"+event.getTime()+" from: "+event.getSource().getName());
addEvent(new FlightEvent(FlightEvent.Type.IGNITION, ignitionTime, (RocketComponent) mount, state )); currentStatus.addEvent(new FlightEvent(FlightEvent.Type.IGNITION, ignitionTime, (RocketComponent) mount, state ));
} }
} }
@ -360,7 +361,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
StageSeparationConfiguration separationConfig = stage.getSeparationConfigurations().get(this.fcid); StageSeparationConfiguration separationConfig = stage.getSeparationConfigurations().get(this.fcid);
if (separationConfig.getSeparationEvent().isSeparationEvent(event, stage)) { if (separationConfig.getSeparationEvent().isSeparationEvent(event, stage)) {
addEvent(new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, currentStatus.addEvent(new FlightEvent(FlightEvent.Type.STAGE_SEPARATION,
event.getTime() + separationConfig.getSeparationDelay(), stage)); event.getTime() + separationConfig.getSeparationDelay(), stage));
} }
} }
@ -374,7 +375,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
DeploymentConfiguration deployConfig = ((RecoveryDevice) c).getDeploymentConfigurations().get(this.fcid); DeploymentConfiguration deployConfig = ((RecoveryDevice) c).getDeploymentConfigurations().get(this.fcid);
if (deployConfig.isActivationEvent(event, c)) { if (deployConfig.isActivationEvent(event, c)) {
// Delay event by at least 1ms to allow stage separation to occur first // Delay event by at least 1ms to allow stage separation to occur first
addEvent(new FlightEvent(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT, currentStatus.addEvent(new FlightEvent(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT,
event.getTime() + Math.max(0.001, deployConfig.getDeployDelay()), c)); event.getTime() + Math.max(0.001, deployConfig.getDeployDelay()), c));
} }
} }
@ -415,7 +416,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
// and queue up the burnout for this motor, as well. // and queue up the burnout for this motor, as well.
double duration = motorState.getBurnTime(); double duration = motorState.getBurnTime();
double burnout = currentStatus.getSimulationTime() + duration; double burnout = currentStatus.getSimulationTime() + duration;
addEvent(new FlightEvent(FlightEvent.Type.BURNOUT, burnout, currentStatus.addEvent(new FlightEvent(FlightEvent.Type.BURNOUT, burnout,
event.getSource(), motorState )); event.getSource(), motorState ));
break; break;
} }
@ -450,7 +451,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
double delay = motorState.getEjectionDelay(); double delay = motorState.getEjectionDelay();
if ( motorState.hasEjectionCharge() ){ if ( motorState.hasEjectionCharge() ){
addEvent(new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, currentStatus.getSimulationTime() + delay, currentStatus.addEvent(new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, currentStatus.getSimulationTime() + delay,
stage, event.getData())); stage, event.getData()));
} }
currentStatus.getFlightData().addEvent(event); currentStatus.getFlightData().addEvent(event);
@ -586,6 +587,11 @@ public class BasicEventSimulationEngine implements SimulationEngine {
currentStatus.getFlightData().addEvent(event); currentStatus.getFlightData().addEvent(event);
break; break;
case SIM_ABORT:
ret = false;
currentStatus.getFlightData().addEvent(event);
break;
case SIMULATION_END: case SIMULATION_END:
ret = false; ret = false;
currentStatus.getFlightData().addEvent(event); currentStatus.getFlightData().addEvent(event);
@ -632,17 +638,6 @@ public class BasicEventSimulationEngine implements SimulationEngine {
return ret; return ret;
} }
/**
* Add a flight event to the event queue unless a listener aborts adding it.
*
* @param event the event to add to the queue.
*/
private void addEvent(FlightEvent event) throws SimulationException {
if (SimulationListenerHelper.fireAddFlightEvent(currentStatus, event)) {
currentStatus.getEventQueue().add(event);
}
}
/** /**

View File

@ -8,6 +8,9 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import net.sf.openrocket.aerodynamics.FlightConditions; import net.sf.openrocket.aerodynamics.FlightConditions;
import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.listeners.SimulationListenerHelper;
import net.sf.openrocket.logging.SimulationAbort;
import net.sf.openrocket.logging.WarningSet; import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.motor.MotorConfiguration;
import net.sf.openrocket.motor.MotorConfigurationId; import net.sf.openrocket.motor.MotorConfigurationId;
@ -550,4 +553,22 @@ public class SimulationStatus implements Monitorable {
} }
} }
/**
* Add a flight event to the event queue unless a listener aborts adding it.
*
* @param event the event to add to the queue.
*/
public void addEvent(FlightEvent event) throws SimulationException {
if (SimulationListenerHelper.fireAddFlightEvent(this, event)) {
getEventQueue().add(event);
}
}
/**
* Abort the current simulation branch
*/
public void abortSimulation(SimulationAbort cause) throws SimulationException {
addEvent(new FlightEvent(FlightEvent.Type.SIM_ABORT, getSimulationTime(), null, cause));
}
} }

View File

@ -58,6 +58,7 @@ public class EventGraphics {
loadImage(FlightEvent.Type.GROUND_HIT, "pix/eventicons/event-ground-hit.png"); loadImage(FlightEvent.Type.GROUND_HIT, "pix/eventicons/event-ground-hit.png");
loadImage(FlightEvent.Type.SIMULATION_END, "pix/eventicons/event-simulation-end.png"); loadImage(FlightEvent.Type.SIMULATION_END, "pix/eventicons/event-simulation-end.png");
loadImage(FlightEvent.Type.EXCEPTION, "pix/eventicons/event-exception.png"); loadImage(FlightEvent.Type.EXCEPTION, "pix/eventicons/event-exception.png");
loadImage(FlightEvent.Type.SIM_ABORT, "pix/eventicons/event-exception.png");
} }
private static void loadImage(FlightEvent.Type type, String file) { private static void loadImage(FlightEvent.Type type, String file) {

View File

@ -39,6 +39,7 @@ public class PlotConfiguration implements Cloneable {
config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true);
config.setEvent(FlightEvent.Type.TUMBLE, true); config.setEvent(FlightEvent.Type.TUMBLE, true);
config.setEvent(FlightEvent.Type.EXCEPTION, true); config.setEvent(FlightEvent.Type.EXCEPTION, true);
config.setEvent(FlightEvent.Type.SIM_ABORT, true);
configs.add(config); configs.add(config);
//// Total motion vs. time //// Total motion vs. time
@ -54,6 +55,7 @@ public class PlotConfiguration implements Cloneable {
config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true);
config.setEvent(FlightEvent.Type.TUMBLE, true); config.setEvent(FlightEvent.Type.TUMBLE, true);
config.setEvent(FlightEvent.Type.EXCEPTION, true); config.setEvent(FlightEvent.Type.EXCEPTION, true);
config.setEvent(FlightEvent.Type.SIM_ABORT, true);
configs.add(config); configs.add(config);
//// Flight side profile //// Flight side profile
@ -67,6 +69,7 @@ public class PlotConfiguration implements Cloneable {
config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true);
config.setEvent(FlightEvent.Type.TUMBLE, true); config.setEvent(FlightEvent.Type.TUMBLE, true);
config.setEvent(FlightEvent.Type.EXCEPTION, true); config.setEvent(FlightEvent.Type.EXCEPTION, true);
config.setEvent(FlightEvent.Type.SIM_ABORT, true);
configs.add(config); configs.add(config);
@ -79,6 +82,8 @@ public class PlotConfiguration implements Cloneable {
config.setEvent(FlightEvent.Type.APOGEE, true); config.setEvent(FlightEvent.Type.APOGEE, true);
config.setEvent(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT, true); config.setEvent(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT, true);
config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true);
config.setEvent(FlightEvent.Type.EXCEPTION, true);
config.setEvent(FlightEvent.Type.SIM_ABORT, true);
configs.add(config); configs.add(config);
//// Stability vs. time //// Stability vs. time
@ -93,7 +98,7 @@ public class PlotConfiguration implements Cloneable {
config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true); config.setEvent(FlightEvent.Type.STAGE_SEPARATION, true);
config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true);
config.setEvent(FlightEvent.Type.TUMBLE, true); config.setEvent(FlightEvent.Type.TUMBLE, true);
config.setEvent(FlightEvent.Type.EXCEPTION, true); config.setEvent(FlightEvent.Type.SIM_ABORT, true);
configs.add(config); configs.add(config);
//// Drag coefficients vs. Mach number //// Drag coefficients vs. Mach number
@ -104,6 +109,7 @@ public class PlotConfiguration implements Cloneable {
config.addPlotDataType(FlightDataType.TYPE_BASE_DRAG_COEFF, 0); config.addPlotDataType(FlightDataType.TYPE_BASE_DRAG_COEFF, 0);
config.addPlotDataType(FlightDataType.TYPE_PRESSURE_DRAG_COEFF, 0); config.addPlotDataType(FlightDataType.TYPE_PRESSURE_DRAG_COEFF, 0);
config.setEvent(FlightEvent.Type.EXCEPTION, true); config.setEvent(FlightEvent.Type.EXCEPTION, true);
config.setEvent(FlightEvent.Type.SIM_ABORT, true);
configs.add(config); configs.add(config);
//// Roll characteristics //// Roll characteristics
@ -121,6 +127,7 @@ public class PlotConfiguration implements Cloneable {
config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true);
config.setEvent(FlightEvent.Type.TUMBLE, true); config.setEvent(FlightEvent.Type.TUMBLE, true);
config.setEvent(FlightEvent.Type.EXCEPTION, true); config.setEvent(FlightEvent.Type.EXCEPTION, true);
config.setEvent(FlightEvent.Type.SIM_ABORT, true);
configs.add(config); configs.add(config);
//// Angle of attack and orientation vs. time //// Angle of attack and orientation vs. time
@ -136,6 +143,7 @@ public class PlotConfiguration implements Cloneable {
config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true);
config.setEvent(FlightEvent.Type.TUMBLE, true); config.setEvent(FlightEvent.Type.TUMBLE, true);
config.setEvent(FlightEvent.Type.EXCEPTION, true); config.setEvent(FlightEvent.Type.EXCEPTION, true);
config.setEvent(FlightEvent.Type.SIM_ABORT, true);
configs.add(config); configs.add(config);
//// Simulation time step and computation time //// Simulation time step and computation time
@ -150,6 +158,7 @@ public class PlotConfiguration implements Cloneable {
config.setEvent(FlightEvent.Type.GROUND_HIT, true); config.setEvent(FlightEvent.Type.GROUND_HIT, true);
config.setEvent(FlightEvent.Type.TUMBLE, true); config.setEvent(FlightEvent.Type.TUMBLE, true);
config.setEvent(FlightEvent.Type.EXCEPTION, true); config.setEvent(FlightEvent.Type.EXCEPTION, true);
config.setEvent(FlightEvent.Type.SIM_ABORT, true);
configs.add(config); configs.add(config);
DEFAULT_CONFIGURATIONS = configs.toArray(new PlotConfiguration[0]); DEFAULT_CONFIGURATIONS = configs.toArray(new PlotConfiguration[0]);