Merge pull request #2110 from JoePfeiffer/fix-2058
[#2058] Create simulation exception for zero-length stages; improve exception reporting
This commit is contained in:
commit
14db274d42
@ -574,9 +574,11 @@ SimuRunDlg.lbl.Altitude = Altitude:
|
|||||||
SimuRunDlg.lbl.Velocity = Velocity:
|
SimuRunDlg.lbl.Velocity = Velocity:
|
||||||
SimuRunDlg.msg.Unabletosim = Unable to simulate:
|
SimuRunDlg.msg.Unabletosim = Unable to simulate:
|
||||||
SimuRunDlg.msg.errorOccurred = An error occurred during the simulation:
|
SimuRunDlg.msg.errorOccurred = An error occurred during the simulation:
|
||||||
|
SimuRunDlg.msg.branchErrorOccurred = An error occurred during simulation branch
|
||||||
|
|
||||||
BasicEventSimulationEngine.error.noMotorsDefined = No motors defined in the simulation.
|
BasicEventSimulationEngine.error.noMotorsDefined = No motors defined in the simulation.
|
||||||
BasicEventSimulationEngine.error.cantCalculateStability = Can't calculate rocket stability.
|
BasicEventSimulationEngine.error.activeLengthZero = Active airframe has length 0
|
||||||
|
BasicEventSimulationEngine.error.cantCalculateStability = Can't calculate stability
|
||||||
BasicEventSimulationEngine.error.earlyMotorBurnout = Motor burnout without liftoff.
|
BasicEventSimulationEngine.error.earlyMotorBurnout = Motor burnout without liftoff.
|
||||||
BasicEventSimulationEngine.error.noConfiguredIgnition = No motors configured to ignite at liftoff
|
BasicEventSimulationEngine.error.noConfiguredIgnition = No motors configured to ignite at liftoff
|
||||||
BasicEventSimulationEngine.error.noIgnition = No motors ignited.
|
BasicEventSimulationEngine.error.noIgnition = No motors ignited.
|
||||||
|
BIN
core/resources/pix/eventicons/event-exception.png
Normal file
BIN
core/resources/pix/eventicons/event-exception.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 700 B |
@ -86,13 +86,6 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noMotorsDefined"));
|
throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noMotorsDefined"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't calculate stability
|
|
||||||
if (currentStatus.getSimulationConditions().getAerodynamicCalculator()
|
|
||||||
.getCP(currentStatus.getConfiguration(),
|
|
||||||
new FlightConditions(currentStatus.getConfiguration()),
|
|
||||||
new WarningSet()).weight < MathUtil.EPSILON)
|
|
||||||
throw new SimulationException(trans.get("BasicEventSimulationEngine.error.cantCalculateStability"));
|
|
||||||
|
|
||||||
// Problems that let us simulate, but result is likely bad
|
// Problems that let us simulate, but result is likely bad
|
||||||
|
|
||||||
// No recovery device
|
// No recovery device
|
||||||
@ -158,6 +151,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
checkGeometry(currentStatus);
|
||||||
|
|
||||||
// Start the simulation
|
// Start the simulation
|
||||||
while (handleEvents()) {
|
while (handleEvents()) {
|
||||||
// Take the step
|
// Take the step
|
||||||
@ -284,6 +279,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
flightData.getWarningSet().addAll(currentStatus.getWarnings());
|
flightData.getWarningSet().addAll(currentStatus.getWarnings());
|
||||||
|
|
||||||
e.setFlightData(flightData);
|
e.setFlightData(flightData);
|
||||||
|
e.setFlightDataBranch(currentStatus.getFlightData());
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -495,7 +491,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
SimulationStatus boosterStatus = new SimulationStatus(currentStatus);
|
SimulationStatus boosterStatus = new SimulationStatus(currentStatus);
|
||||||
|
|
||||||
// Prepare the new simulation branch
|
// Prepare the new simulation branch
|
||||||
boosterStatus.setFlightData(new FlightDataBranch(boosterStage.getName(), FlightDataType.TYPE_TIME));
|
boosterStatus.setFlightData(new FlightDataBranch(boosterStage.getName(), currentStatus.getFlightData()));
|
||||||
|
boosterStatus.getFlightData().addEvent(event);
|
||||||
|
|
||||||
// Mark the current status as having dropped the current stage and all stages below it
|
// Mark the current status as having dropped the current stage and all stages below it
|
||||||
currentStatus.getConfiguration().clearStagesBelow( stageNumber);
|
currentStatus.getConfiguration().clearStagesBelow( stageNumber);
|
||||||
@ -504,6 +501,10 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
boosterStatus.getConfiguration().clearStagesAbove(stageNumber);
|
boosterStatus.getConfiguration().clearStagesAbove(stageNumber);
|
||||||
|
|
||||||
toSimulate.push(boosterStatus);
|
toSimulate.push(boosterStatus);
|
||||||
|
|
||||||
|
// Make sure upper stages can still be simulated
|
||||||
|
checkGeometry(currentStatus);
|
||||||
|
|
||||||
log.info(String.format("==>> @ %g; from Branch: %s ---- Branching: %s ---- \n",
|
log.info(String.format("==>> @ %g; from Branch: %s ---- Branching: %s ---- \n",
|
||||||
currentStatus.getSimulationTime(),
|
currentStatus.getSimulationTime(),
|
||||||
currentStatus.getFlightData().getBranchName(), boosterStatus.getFlightData().getBranchName()));
|
currentStatus.getFlightData().getBranchName(), boosterStatus.getFlightData().getBranchName()));
|
||||||
@ -666,7 +667,23 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need to check geometry to make sure we can simulation the active
|
||||||
|
// stages in a simulation branch when the branch starts executing, and
|
||||||
|
// whenever a stage separation occurs
|
||||||
|
private void checkGeometry(SimulationStatus currentStatus) throws SimulationException {
|
||||||
|
|
||||||
|
// Active stages have total length of 0.
|
||||||
|
if (currentStatus.getConfiguration().getLengthAerodynamic() < MathUtil.EPSILON) {
|
||||||
|
throw new SimulationException(trans.get("BasicEventSimulationEngine.error.activeLengthZero"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't calculate stability
|
||||||
|
if (currentStatus.getSimulationConditions().getAerodynamicCalculator()
|
||||||
|
.getCP(currentStatus.getConfiguration(),
|
||||||
|
new FlightConditions(currentStatus.getConfiguration()),
|
||||||
|
new WarningSet()).weight < MathUtil.EPSILON)
|
||||||
|
throw new SimulationException(trans.get("BasicEventSimulationEngine.error.cantCalculateStability"));
|
||||||
|
}
|
||||||
|
|
||||||
private void checkNaN() throws SimulationException {
|
private void checkNaN() throws SimulationException {
|
||||||
double d = 0;
|
double d = 0;
|
||||||
|
@ -76,6 +76,26 @@ public class FlightDataBranch implements Monitorable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a flight data branch with one data point copied from its parent. Intended for use
|
||||||
|
* 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)
|
||||||
|
*/
|
||||||
|
public FlightDataBranch(String branchName, FlightDataBranch parent) {
|
||||||
|
this.branchName = branchName;
|
||||||
|
|
||||||
|
// need to have at least one type to set up values
|
||||||
|
values.put(FlightDataType.TYPE_TIME, new ArrayList<Double>());
|
||||||
|
minValues.put(FlightDataType.TYPE_TIME, Double.NaN);
|
||||||
|
maxValues.put(FlightDataType.TYPE_TIME, Double.NaN);
|
||||||
|
|
||||||
|
// copy all values into new FlightDataBranch
|
||||||
|
this.addPoint();
|
||||||
|
for (FlightDataType t : parent.getTypes()) {
|
||||||
|
this.setValue(t, parent.getLast(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes an 'empty' flight data branch which has no data but all built in data types are defined.
|
* Makes an 'empty' flight data branch which has no data but all built in data types are defined.
|
||||||
*/
|
*/
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package net.sf.openrocket.simulation.exception;
|
package net.sf.openrocket.simulation.exception;
|
||||||
|
|
||||||
import net.sf.openrocket.simulation.FlightData;
|
import net.sf.openrocket.simulation.FlightData;
|
||||||
|
import net.sf.openrocket.simulation.FlightDataBranch;
|
||||||
|
|
||||||
public class SimulationException extends Exception {
|
public class SimulationException extends Exception {
|
||||||
|
|
||||||
private FlightData flightData = null;
|
private FlightData flightData = null;
|
||||||
|
private FlightDataBranch flightDataBranch = null;
|
||||||
|
|
||||||
public SimulationException() {
|
public SimulationException() {
|
||||||
|
|
||||||
@ -29,4 +31,13 @@ public class SimulationException extends Exception {
|
|||||||
public FlightData getFlightData() {
|
public FlightData getFlightData() {
|
||||||
return flightData;
|
return flightData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFlightDataBranch(FlightDataBranch f) {
|
||||||
|
flightDataBranch = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlightDataBranch getFlightDataBranch() {
|
||||||
|
return flightDataBranch;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1104,6 +1104,26 @@ public class TestRockets {
|
|||||||
return rocket;
|
return rocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Several simulations need the Falcon9Heavy, but with fins added to the
|
||||||
|
// core stage (without them, there is a simulation exception at stage separation
|
||||||
|
// This method is intended to add those fins to the F9H, but will in fact
|
||||||
|
// add them to the second stage of a rocket
|
||||||
|
public static void addCoreFins(Rocket rocket) {
|
||||||
|
final int bodyFinCount = 4;
|
||||||
|
final double bodyFinRootChord = 0.05;
|
||||||
|
final double bodyFinTipChord = bodyFinRootChord;
|
||||||
|
final double bodyFinHeight = 0.025;
|
||||||
|
final double bodyFinSweep = 0.0;
|
||||||
|
final AxialMethod bodyFinAxialMethod = AxialMethod.BOTTOM;
|
||||||
|
final double bodyFinAxialOffset = 0.0;
|
||||||
|
|
||||||
|
final TrapezoidFinSet finSet = new TrapezoidFinSet(bodyFinCount, bodyFinRootChord, bodyFinTipChord, bodyFinSweep, bodyFinHeight);
|
||||||
|
finSet.setName("Body Tube FinSet");
|
||||||
|
finSet.setAxialMethod(bodyFinAxialMethod);
|
||||||
|
|
||||||
|
rocket.getChild(1).getChild(0).addChild(finSet);
|
||||||
|
}
|
||||||
|
|
||||||
// This is a simple four-fin rocket with large endplates on the
|
// This is a simple four-fin rocket with large endplates on the
|
||||||
// fins, for testing CG and CP calculations with fins on pods.
|
// fins, for testing CG and CP calculations with fins on pods.
|
||||||
// not a complete rocket (no motor mount nor recovery system)
|
// not a complete rocket (no motor mount nor recovery system)
|
||||||
|
@ -148,8 +148,12 @@ public class DisableStageTest extends BaseTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testBooster1() {
|
public void testBooster1() {
|
||||||
//// Test disabling the stage
|
//// Test disabling the stage
|
||||||
|
|
||||||
Rocket rocketRemoved = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage removed
|
Rocket rocketRemoved = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage removed
|
||||||
|
TestRockets.addCoreFins(rocketRemoved);
|
||||||
|
|
||||||
Rocket rocketDisabled = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage disabled
|
Rocket rocketDisabled = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage disabled
|
||||||
|
TestRockets.addCoreFins(rocketDisabled);
|
||||||
|
|
||||||
FlightConfigurationId fcid = new FlightConfigurationId(TestRockets.FALCON_9H_FCID_1);
|
FlightConfigurationId fcid = new FlightConfigurationId(TestRockets.FALCON_9H_FCID_1);
|
||||||
int stageNr = 2; // Stage 2 is the Parallel Booster Stage
|
int stageNr = 2; // Stage 2 is the Parallel Booster Stage
|
||||||
@ -171,6 +175,8 @@ public class DisableStageTest extends BaseTestCase {
|
|||||||
|
|
||||||
//// Test re-enableing the stage.
|
//// Test re-enableing the stage.
|
||||||
Rocket rocketOriginal = TestRockets.makeFalcon9Heavy();
|
Rocket rocketOriginal = TestRockets.makeFalcon9Heavy();
|
||||||
|
TestRockets.addCoreFins(rocketOriginal);
|
||||||
|
|
||||||
Simulation simOriginal = new Simulation(rocketOriginal);
|
Simulation simOriginal = new Simulation(rocketOriginal);
|
||||||
simOriginal.setFlightConfigurationId(fcid);
|
simOriginal.setFlightConfigurationId(fcid);
|
||||||
simOriginal.getOptions().setISAAtmosphere(true);
|
simOriginal.getOptions().setISAAtmosphere(true);
|
||||||
@ -188,7 +194,10 @@ public class DisableStageTest extends BaseTestCase {
|
|||||||
public void testBooster2() {
|
public void testBooster2() {
|
||||||
//// Test disabling the stage
|
//// Test disabling the stage
|
||||||
Rocket rocketRemoved = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage removed
|
Rocket rocketRemoved = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage removed
|
||||||
|
TestRockets.addCoreFins(rocketRemoved);
|
||||||
|
|
||||||
Rocket rocketDisabled = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage disabled
|
Rocket rocketDisabled = TestRockets.makeFalcon9Heavy(); // Rocket with the last stage disabled
|
||||||
|
TestRockets.addCoreFins(rocketDisabled);
|
||||||
|
|
||||||
FlightConfigurationId fid = new FlightConfigurationId(TestRockets.FALCON_9H_FCID_1);
|
FlightConfigurationId fid = new FlightConfigurationId(TestRockets.FALCON_9H_FCID_1);
|
||||||
int stageNr = 1; // Stage 1 is the Parallel Booster Stage's parent stage
|
int stageNr = 1; // Stage 1 is the Parallel Booster Stage's parent stage
|
||||||
@ -225,6 +234,8 @@ public class DisableStageTest extends BaseTestCase {
|
|||||||
|
|
||||||
//// Test re-enableing the stage.
|
//// Test re-enableing the stage.
|
||||||
Rocket rocketOriginal = TestRockets.makeFalcon9Heavy();
|
Rocket rocketOriginal = TestRockets.makeFalcon9Heavy();
|
||||||
|
TestRockets.addCoreFins(rocketOriginal);
|
||||||
|
|
||||||
Simulation simOriginal = new Simulation(rocketOriginal);
|
Simulation simOriginal = new Simulation(rocketOriginal);
|
||||||
simOriginal.setFlightConfigurationId(fid);
|
simOriginal.setFlightConfigurationId(fid);
|
||||||
simOriginal.getOptions().setISAAtmosphere(true);
|
simOriginal.getOptions().setISAAtmosphere(true);
|
||||||
|
@ -85,6 +85,8 @@ public class FlightEventsTest extends BaseTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testMultiStage() throws SimulationException {
|
public void testMultiStage() throws SimulationException {
|
||||||
final Rocket rocket = TestRockets.makeFalcon9Heavy();
|
final Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||||
|
TestRockets.addCoreFins(rocket);
|
||||||
|
|
||||||
final Simulation sim = new Simulation(rocket);
|
final Simulation sim = new Simulation(rocket);
|
||||||
sim.getOptions().setISAAtmosphere(true);
|
sim.getOptions().setISAAtmosphere(true);
|
||||||
sim.getOptions().setTimeStep(0.05);
|
sim.getOptions().setTimeStep(0.05);
|
||||||
@ -98,32 +100,49 @@ public class FlightEventsTest extends BaseTestCase {
|
|||||||
final int branchCount = sim.getSimulatedData().getBranchCount();
|
final int branchCount = sim.getSimulatedData().getBranchCount();
|
||||||
assertEquals(" Multi-stage simulation invalid branch count", 3, branchCount);
|
assertEquals(" Multi-stage simulation invalid branch count", 3, branchCount);
|
||||||
|
|
||||||
|
final AxialStage coreStage = rocket.getStage(1);
|
||||||
|
final ParallelStage boosterStage = (ParallelStage) rocket.getStage(2);
|
||||||
|
final InnerTube boosterMotorTubes = (InnerTube) boosterStage.getChild(1).getChild(0);
|
||||||
|
final BodyTube coreBody = (BodyTube) coreStage.getChild(0);
|
||||||
|
|
||||||
|
// events whose time is too variable to check are given a time of 1200
|
||||||
for (int b = 0; b < 3; b++) {
|
for (int b = 0; b < 3; b++) {
|
||||||
final FlightEvent.Type[] expectedEventTypes;
|
FlightEvent[] expectedEvents;
|
||||||
final double[] expectedEventTimes;
|
|
||||||
final RocketComponent[] expectedSources;
|
final RocketComponent[] expectedSources;
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case 0:
|
case 0:
|
||||||
expectedEventTypes = new FlightEvent.Type[]{FlightEvent.Type.LAUNCH, FlightEvent.Type.IGNITION, FlightEvent.Type.IGNITION,
|
expectedEvents = new FlightEvent[] {
|
||||||
FlightEvent.Type.LIFTOFF, FlightEvent.Type.LAUNCHROD, FlightEvent.Type.APOGEE,
|
new FlightEvent(FlightEvent.Type.LAUNCH, 0.0, rocket),
|
||||||
FlightEvent.Type.BURNOUT, FlightEvent.Type.EJECTION_CHARGE, FlightEvent.Type.STAGE_SEPARATION,
|
new FlightEvent(FlightEvent.Type.IGNITION, 0.0, boosterMotorTubes),
|
||||||
FlightEvent.Type.BURNOUT, FlightEvent.Type.EJECTION_CHARGE, FlightEvent.Type.STAGE_SEPARATION,
|
new FlightEvent(FlightEvent.Type.IGNITION, 0.0, coreBody),
|
||||||
FlightEvent.Type.TUMBLE, FlightEvent.Type.GROUND_HIT, FlightEvent.Type.SIMULATION_END};
|
new FlightEvent(FlightEvent.Type.LIFTOFF, 0.1225, null),
|
||||||
expectedEventTimes = new double[]{0.0, 0.0, 0.0, 0.1225, 0.125, 1.735, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0}; // Tumble and ground hit time are too variable, so don't include it
|
new FlightEvent(FlightEvent.Type.LAUNCHROD, 0.125, null),
|
||||||
final AxialStage coreStage = rocket.getStage(1);
|
new FlightEvent(FlightEvent.Type.APOGEE, 1.86, rocket),
|
||||||
final ParallelStage boosterStage = (ParallelStage) rocket.getStage(2);
|
new FlightEvent(FlightEvent.Type.BURNOUT, 2.0, boosterMotorTubes),
|
||||||
final InnerTube boosterMotorTubes = (InnerTube) boosterStage.getChild(1).getChild(0);
|
new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, 2.0, boosterStage),
|
||||||
final BodyTube coreBody = (BodyTube) coreStage.getChild(0);
|
new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, 2.0, boosterStage),
|
||||||
expectedSources = new RocketComponent[]{rocket, boosterMotorTubes, coreBody, null, null, rocket,
|
new FlightEvent(FlightEvent.Type.BURNOUT, 2.0, coreBody),
|
||||||
boosterMotorTubes, boosterStage, boosterStage, coreBody, coreStage, coreStage,
|
new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, 2.0, coreStage),
|
||||||
null, null, null};
|
new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, 2.0, coreStage),
|
||||||
|
new FlightEvent(FlightEvent.Type.TUMBLE, 2.4127, null),
|
||||||
|
new FlightEvent(FlightEvent.Type.GROUND_HIT, 1200, null),
|
||||||
|
new FlightEvent(FlightEvent.Type.SIMULATION_END, 1200, null)
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
expectedEvents = new FlightEvent[] {
|
||||||
|
new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, 2.0, coreStage),
|
||||||
|
new FlightEvent(FlightEvent.Type.GROUND_HIT, 1200, null),
|
||||||
|
new FlightEvent(FlightEvent.Type.SIMULATION_END, 1200, null)
|
||||||
|
};
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
expectedEventTypes = new FlightEvent.Type[]{FlightEvent.Type.TUMBLE, FlightEvent.Type.GROUND_HIT,
|
expectedEvents = new FlightEvent[] {
|
||||||
FlightEvent.Type.SIMULATION_END};
|
new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, 2.0, boosterStage),
|
||||||
expectedEventTimes = new double[]{}; // Tumble and ground hit time are too variable, so don't include it
|
new FlightEvent(FlightEvent.Type.TUMBLE, 3.551, null),
|
||||||
expectedSources = new RocketComponent[]{null, null, null};
|
new FlightEvent(FlightEvent.Type.GROUND_HIT, 1200, null),
|
||||||
|
new FlightEvent(FlightEvent.Type.SIMULATION_END, 1200, null)
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Invalid branch number " + b);
|
throw new IllegalStateException("Invalid branch number " + b);
|
||||||
@ -131,28 +150,28 @@ public class FlightEventsTest extends BaseTestCase {
|
|||||||
|
|
||||||
// Test event count
|
// Test event count
|
||||||
final FlightDataBranch branch = sim.getSimulatedData().getBranch(b);
|
final FlightDataBranch branch = sim.getSimulatedData().getBranch(b);
|
||||||
final List<FlightEvent> eventList = branch.getEvents();
|
final FlightEvent[] events = (FlightEvent[]) branch.getEvents().toArray(new FlightEvent[0]);
|
||||||
final List<FlightEvent.Type> eventTypes = eventList.stream().map(FlightEvent::getType).collect(Collectors.toList());
|
for (int i = 0; i < events.length; i++) {
|
||||||
assertEquals(" Multi-stage simulation, branch " + b + " invalid number of events", expectedEventTypes.length, eventTypes.size());
|
System.out.println("branch " + b + " index " + i + " event " + events[i]);
|
||||||
|
}
|
||||||
|
assertEquals(" Multi-stage simulation, branch " + b + " invalid number of events", expectedEvents.length, events.length);
|
||||||
|
|
||||||
// Test that all expected events are present, and in the right order
|
// Test that all expected events are present, in the right order, at the right time, from the right sources
|
||||||
for (int i = 0; i < expectedEventTypes.length; i++) {
|
for (int i = 0; i < events.length; i++) {
|
||||||
assertSame(" Flight type " + expectedEventTypes[i] + ", branch " + b + " not found in multi-stage simulation",
|
final FlightEvent expected = expectedEvents[i];
|
||||||
expectedEventTypes[i], eventTypes.get(i));
|
final FlightEvent actual = events[i];
|
||||||
}
|
assertSame("Branch " + b + " FlightEvent " + i + " type " + expected.getType() + " not found; FlightEvent " + actual.getType() + " found instead",
|
||||||
|
expected.getType(), actual.getType());
|
||||||
|
|
||||||
// Test that the event times are correct
|
if (1200 != expected.getTime()) {
|
||||||
for (int i = 0; i < expectedEventTimes.length; i++) {
|
assertEquals("Branch " + b + " FlightEvent " + i + " type " + expected.getType() + " has wrong time",
|
||||||
assertEquals(" Flight type " + expectedEventTypes[i] + " has wrong time",
|
expected.getTime(), actual.getTime(), EPSILON);
|
||||||
expectedEventTimes[i], eventList.get(i).getTime(), EPSILON);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Test that the event sources are correct
|
// Test that the event sources are correct
|
||||||
for (int i = 0; i < expectedSources.length; i++) {
|
assertEquals("Branch " + b + " FlightEvent " + i + " type " + expected.getType() + " has wrong source",
|
||||||
assertEquals(" Flight type " + expectedEventTypes[i] + " has wrong source",
|
expected.getSource(), actual.getSource());
|
||||||
expectedSources[i], eventList.get(i).getSource());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ public class EventGraphics {
|
|||||||
"pix/eventicons/event-recovery-device-deployment.png");
|
"pix/eventicons/event-recovery-device-deployment.png");
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadImage(FlightEvent.Type type, String file) {
|
private static void loadImage(FlightEvent.Type type, String file) {
|
||||||
|
@ -38,6 +38,7 @@ import net.sf.openrocket.l10n.Translator;
|
|||||||
import net.sf.openrocket.motor.IgnitionEvent;
|
import net.sf.openrocket.motor.IgnitionEvent;
|
||||||
import net.sf.openrocket.motor.MotorConfiguration;
|
import net.sf.openrocket.motor.MotorConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
|
import net.sf.openrocket.simulation.FlightDataBranch;
|
||||||
import net.sf.openrocket.simulation.FlightEvent;
|
import net.sf.openrocket.simulation.FlightEvent;
|
||||||
import net.sf.openrocket.simulation.SimulationStatus;
|
import net.sf.openrocket.simulation.SimulationStatus;
|
||||||
import net.sf.openrocket.simulation.customexpression.CustomExpression;
|
import net.sf.openrocket.simulation.customexpression.CustomExpression;
|
||||||
@ -433,12 +434,20 @@ public class SimulationRunDialog extends JDialog {
|
|||||||
null, simulation.getName(), JOptionPane.ERROR_MESSAGE);
|
null, simulation.getName(), JOptionPane.ERROR_MESSAGE);
|
||||||
|
|
||||||
} else if (t instanceof SimulationException) {
|
} else if (t instanceof SimulationException) {
|
||||||
|
String title = simulation.getName();
|
||||||
|
FlightDataBranch dataBranch = ((SimulationException) t).getFlightDataBranch();
|
||||||
|
|
||||||
|
String message;
|
||||||
|
if (dataBranch != null) {
|
||||||
|
message = trans.get("SimuRunDlg.msg.branchErrorOccurred") + "\"" + dataBranch.getBranchName() + "\"";
|
||||||
|
} else {
|
||||||
|
message = trans.get("SimuRunDlg.msg.errorOccurred");
|
||||||
|
}
|
||||||
DetailDialog.showDetailedMessageDialog(SimulationRunDialog.this,
|
DetailDialog.showDetailedMessageDialog(SimulationRunDialog.this,
|
||||||
new Object[] {
|
new Object[] {
|
||||||
//// A error occurred during the simulation:
|
//// A error occurred during the simulation:
|
||||||
trans.get("SimuRunDlg.msg.errorOccurred"), t.getMessage() },
|
message, t.getMessage() },
|
||||||
null, simulation.getName(), JOptionPane.ERROR_MESSAGE);
|
null, simulation.getName(), JOptionPane.ERROR_MESSAGE);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user