simulation listener enhancements
[debian/openrocket] / src / net / sf / openrocket / simulation / BasicEventSimulationEngine.java
index 13122a7f10735e1c0b8425afcba07d6e943db3e5..21ccb2665391a491ca4a9148335526dea3133392 100644 (file)
@@ -6,7 +6,6 @@ import java.util.Set;
 
 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;
@@ -41,6 +40,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
        private SimulationStatus status;
        
        
+       @Override
        public FlightData simulate(SimulationConditions simulationConditions) throws SimulationException {
                Set<MotorId> motorBurntOut = new HashSet<MotorId>();
                
@@ -56,13 +56,17 @@ public class BasicEventSimulationEngine implements SimulationEngine {
                
                // 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()) {
@@ -77,7 +81,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
                                        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);
@@ -91,17 +95,24 @@ public class BasicEventSimulationEngine implements SimulationEngine {
                                                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()));
                                        }
                                        
@@ -118,13 +129,13 @@ public class BasicEventSimulationEngine implements SimulationEngine {
                                
                                // 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()));
                                }
@@ -160,7 +171,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
 
        private SimulationStatus initialStatus(Configuration configuration,
                        MotorInstanceConfiguration motorConfiguration,
-                       SimulationConditions simulationConditions) {
+                       SimulationConditions simulationConditions, FlightData flightData) {
                
                SimulationStatus init = new SimulationStatus();
                init.setSimulationConditions(simulationConditions);
@@ -226,7 +237,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
                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;
        }
@@ -294,7 +305,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
                        }
                        
                        if (event.getType() != FlightEvent.Type.ALTITUDE) {
-                               log.debug("BasicEventSimulationEngine:  Handling event " + event);
+                               log.verbose("BasicEventSimulationEngine:  Handling event " + event);
                        }
                        
                        if (event.getType() == FlightEvent.Type.IGNITION) {
@@ -409,7 +420,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
                                
                        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);
@@ -542,6 +553,14 @@ public class BasicEventSimulationEngine implements SimulationEngine {
                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.");
                }
        }