import net.sf.openrocket.aerodynamics.FlightConditions;
import net.sf.openrocket.aerodynamics.Warning;
-import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorId;
private SimulationStatus status;
+ @Override
public FlightData simulate(SimulationConditions simulationConditions) throws SimulationException {
Set<MotorId> motorBurntOut = new HashSet<MotorId>();
// Initialize the simulation
currentStepper = flightStepper;
- status = initialStatus(configuration, motorConfiguration, simulationConditions);
+ status = initialStatus(configuration, motorConfiguration, simulationConditions, flightData);
status = currentStepper.initialize(status);
SimulationListenerHelper.fireStartSimulation(status);
+ // Get originating position (in case listener has modified launch position)
+ Coordinate origin = status.getRocketPosition();
+ Coordinate originVelocity = status.getRocketVelocity();
try {
+ double maxAlt = Double.NEGATIVE_INFINITY;
// Start the simulation
while (handleEvents()) {
if (nextEvent != null) {
maxStepTime = MathUtil.max(nextEvent.getTime() - status.getSimulationTime(), 0.001);
}
- log.debug("BasicEventSimulationEngine: Taking simulation step at t=" + status.getSimulationTime());
+ log.verbose("BasicEventSimulationEngine: Taking simulation step at t=" + status.getSimulationTime());
currentStepper.step(status, maxStepTime);
}
SimulationListenerHelper.firePostStep(status);
status.getConfiguration().getRocket(),
new Pair<Double, Double>(oldAlt, status.getRocketPosition().z)));
+ if (status.getRocketPosition().z > maxAlt) {
+ maxAlt = status.getRocketPosition().z;
+ }
+
+ // Position relative to start location
+ Coordinate relativePosition = status.getRocketPosition().sub(origin);
+
// Add appropriate events
if (!status.isLiftoff()) {
// Avoid sinking into ground before liftoff
- if (status.getRocketPosition().z < 0) {
- status.setRocketPosition(Coordinate.NUL);
- status.setRocketVelocity(Coordinate.NUL);
+ if (relativePosition.z < 0) {
+ status.setRocketPosition(origin);
+ status.setRocketVelocity(originVelocity);
}
// Detect lift-off
- if (status.getRocketPosition().z > 0.01) {
+ if (relativePosition.z > 0.02) {
addEvent(new FlightEvent(FlightEvent.Type.LIFTOFF, status.getSimulationTime()));
}
// Check for launch guide clearance
if (!status.isLaunchRodCleared() &&
- status.getRocketPosition().length() > status.getSimulationConditions().getLaunchRodLength()) {
+ relativePosition.length() > status.getSimulationConditions().getLaunchRodLength()) {
addEvent(new FlightEvent(FlightEvent.Type.LAUNCHROD, status.getSimulationTime(), null));
}
// Check for apogee
- if (!status.isApogeeReached() && status.getRocketPosition().z < oldAlt - 0.001) {
+ if (!status.isApogeeReached() && status.getRocketPosition().z < maxAlt - 0.01) {
addEvent(new FlightEvent(FlightEvent.Type.APOGEE, status.getSimulationTime(),
status.getConfiguration().getRocket()));
}
private SimulationStatus initialStatus(Configuration configuration,
MotorInstanceConfiguration motorConfiguration,
- SimulationConditions simulationConditions) {
+ SimulationConditions simulationConditions, FlightData flightData) {
SimulationStatus init = new SimulationStatus();
init.setSimulationConditions(simulationConditions);
init.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket()));
init.setFlightData(new FlightDataBranch("MAIN", FlightDataType.TYPE_TIME));
- init.setWarnings(new WarningSet());
+ init.setWarnings(flightData.getWarningSet());
return init;
}
}
if (event.getType() != FlightEvent.Type.ALTITUDE) {
- log.debug("BasicEventSimulationEngine: Handling event " + event);
+ log.verbose("BasicEventSimulationEngine: Handling event " + event);
}
if (event.getType() == FlightEvent.Type.IGNITION) {
case STAGE_SEPARATION: {
// TODO: HIGH: Store lower stages to be simulated later
- RocketComponent stage = (RocketComponent) event.getSource();
+ RocketComponent stage = event.getSource();
int n = stage.getStageNumber();
status.getConfiguration().setToStage(n);
status.getFlightData().addEvent(event);
d += status.getEffectiveLaunchRodLength();
if (Double.isNaN(d) || b) {
+ log.error("Simulation resulted in NaN value:" +
+ " simulationTime=" + status.getSimulationTime() +
+ " previousTimeStep=" + status.getPreviousTimeStep() +
+ " rocketPosition=" + status.getRocketPosition() +
+ " rocketVelocity=" + status.getRocketVelocity() +
+ " rocketOrientationQuaternion=" + status.getRocketOrientationQuaternion() +
+ " rocketRotationVelocity=" + status.getRocketRotationVelocity() +
+ " effectiveLaunchRodLength=" + status.getEffectiveLaunchRodLength());
throw new SimulationException("Simulation resulted in not-a-number (NaN) value, please report a bug.");
}
}