From 27d6322f09d796272e00579238bbadd5d1cd114f Mon Sep 17 00:00:00 2001 From: kruland2607 Date: Wed, 24 Oct 2012 22:28:40 -0500 Subject: [PATCH] Refactored the initialization and copying of SimulationStatus objects. Initialization is now done in the constructor instead of BasicEventSimulationEngine. Copying SimulationStatus is implemented in copy constructors instead of using SimulationStatus.copyFrom(). --- .../BasicEventSimulationEngine.java | 82 +-------- .../simulation/RK4SimulationStatus.java | 22 ++- .../simulation/RK4SimulationStepper.java | 4 +- .../simulation/SimulationStatus.java | 158 +++++++++++++----- 4 files changed, 135 insertions(+), 131 deletions(-) diff --git a/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java b/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java index c311444e3..4a1ff4fe1 100644 --- a/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java +++ b/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java @@ -66,7 +66,7 @@ public class BasicEventSimulationEngine implements SimulationEngine { throw new MotorIgnitionException("No motors defined in the simulation."); } - status = initialStatus(configuration, motorConfiguration, simulationConditions, flightData); + status = new SimulationStatus(configuration, motorConfiguration, simulationConditions, flightData.getWarningSet()); stages.add(status); SimulationListenerHelper.fireStartSimulation(status); @@ -200,83 +200,6 @@ public class BasicEventSimulationEngine implements SimulationEngine { return status.getFlightData(); } - - - private SimulationStatus initialStatus(Configuration configuration, - MotorInstanceConfiguration motorConfiguration, - SimulationConditions simulationConditions, FlightData flightData) { - - SimulationStatus init = new SimulationStatus(); - init.setSimulationConditions(simulationConditions); - init.setConfiguration(configuration); - init.setMotorConfiguration(motorConfiguration); - - init.setSimulationTime(0); - init.setPreviousTimeStep(simulationConditions.getTimeStep()); - init.setRocketPosition(Coordinate.NUL); - init.setRocketVelocity(Coordinate.NUL); - init.setRocketWorldPosition(simulationConditions.getLaunchSite()); - - // Initialize to roll angle with least stability w.r.t. the wind - Quaternion o; - FlightConditions cond = new FlightConditions(configuration); - simulationConditions.getAerodynamicCalculator().getWorstCP(configuration, cond, null); - double angle = -cond.getTheta() - simulationConditions.getLaunchRodDirection(); - o = Quaternion.rotation(new Coordinate(0, 0, angle)); - - // Launch rod angle and direction - o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, simulationConditions.getLaunchRodAngle(), 0))); - o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, 0, simulationConditions.getLaunchRodDirection()))); - - init.setRocketOrientationQuaternion(o); - init.setRocketRotationVelocity(Coordinate.NUL); - - - /* - * Calculate the effective launch rod length taking into account launch lugs. - * If no lugs are found, assume a tower launcher of full length. - */ - double length = simulationConditions.getLaunchRodLength(); - double lugPosition = Double.NaN; - for (RocketComponent c : configuration) { - if (c instanceof LaunchLug) { - double pos = c.toAbsolute(new Coordinate(c.getLength()))[0].x; - if (Double.isNaN(lugPosition) || pos > lugPosition) { - lugPosition = pos; - } - } - } - if (!Double.isNaN(lugPosition)) { - double maxX = 0; - for (Coordinate c : configuration.getBounds()) { - if (c.x > maxX) - maxX = c.x; - } - if (maxX >= lugPosition) { - length = Math.max(0, length - (maxX - lugPosition)); - } - } - init.setEffectiveLaunchRodLength(length); - - - - init.setSimulationStartWallTime(System.nanoTime()); - - init.setMotorIgnited(false); - init.setLiftoff(false); - init.setLaunchRodCleared(false); - init.setApogeeReached(false); - - init.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket())); - - init.setFlightData(new FlightDataBranch("MAIN", FlightDataType.TYPE_TIME)); - init.setWarnings(flightData.getWarningSet()); - - return init; - } - - - /** * Create a rocket configuration from the launch conditions. * @@ -484,8 +407,7 @@ public class BasicEventSimulationEngine implements SimulationEngine { int n = stage.getStageNumber(); // Prepare the booster status for simulation. - SimulationStatus boosterStatus = new SimulationStatus(); - boosterStatus.copyFrom(status); + SimulationStatus boosterStatus = new SimulationStatus(status); FlightDataBranch boosterFlightData = new FlightDataBranch( "Stage-" + n, FlightDataType.TYPE_TIME); boosterStatus.setFlightData(boosterFlightData); diff --git a/core/src/net/sf/openrocket/simulation/RK4SimulationStatus.java b/core/src/net/sf/openrocket/simulation/RK4SimulationStatus.java index 505ff77ca..ced75edb3 100644 --- a/core/src/net/sf/openrocket/simulation/RK4SimulationStatus.java +++ b/core/src/net/sf/openrocket/simulation/RK4SimulationStatus.java @@ -1,6 +1,9 @@ package net.sf.openrocket.simulation; +import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.models.atmosphere.AtmosphericConditions; +import net.sf.openrocket.motor.MotorInstanceConfiguration; +import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.util.Coordinate; public class RK4SimulationStatus extends SimulationStatus { @@ -13,7 +16,22 @@ public class RK4SimulationStatus extends SimulationStatus { private double maxZVelocity = 0; private double startWarningTime = -1; - + public RK4SimulationStatus(Configuration configuration, + MotorInstanceConfiguration motorConfiguration, + SimulationConditions simulationConditions, WarningSet warnings) { + super(configuration, motorConfiguration, simulationConditions, warnings); + } + + public RK4SimulationStatus( SimulationStatus other ) { + super(other); + if ( other instanceof RK4SimulationStatus ) { + this.launchRodDirection = ((RK4SimulationStatus) other).launchRodDirection; + this.previousAcceleration = ((RK4SimulationStatus) other).previousAcceleration; + this.maxZVelocity = ((RK4SimulationStatus) other).maxZVelocity; + this.startWarningTime = ((RK4SimulationStatus) other).startWarningTime; + this.previousAtmosphericConditions = ((RK4SimulationStatus) other).previousAtmosphericConditions; + } + } public void setLaunchRodDirection(Coordinate launchRodDirection) { this.launchRodDirection = launchRodDirection; } @@ -65,8 +83,6 @@ public class RK4SimulationStatus extends SimulationStatus { this.startWarningTime = startWarningTime; } - - @Override public RK4SimulationStatus clone() { return (RK4SimulationStatus) super.clone(); } diff --git a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java index fdc4ba626..178018d65 100644 --- a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java +++ b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java @@ -66,9 +66,7 @@ public class RK4SimulationStepper extends AbstractSimulationStepper { @Override public RK4SimulationStatus initialize(SimulationStatus original) { - RK4SimulationStatus status = new RK4SimulationStatus(); - - status.copyFrom(original); + RK4SimulationStatus status = new RK4SimulationStatus(original); SimulationConditions sim = original.getSimulationConditions(); diff --git a/core/src/net/sf/openrocket/simulation/SimulationStatus.java b/core/src/net/sf/openrocket/simulation/SimulationStatus.java index 6c357c772..0dd4bb2f4 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationStatus.java +++ b/core/src/net/sf/openrocket/simulation/SimulationStatus.java @@ -5,11 +5,14 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import net.sf.openrocket.aerodynamics.FlightConditions; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.motor.MotorId; import net.sf.openrocket.motor.MotorInstanceConfiguration; import net.sf.openrocket.rocketcomponent.Configuration; +import net.sf.openrocket.rocketcomponent.LaunchLug; import net.sf.openrocket.rocketcomponent.RecoveryDevice; +import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Monitorable; @@ -22,7 +25,7 @@ import net.sf.openrocket.util.WorldCoordinate; * * @author Sampo Niskanen */ -public class SimulationStatus implements Cloneable, Monitorable { +public class SimulationStatus implements Monitorable { /* * NOTE! All fields must be added to copyFrom() method!! @@ -81,6 +84,115 @@ public class SimulationStatus implements Cloneable, Monitorable { private int modID = 0; private int modIDadd = 0; + public SimulationStatus( Configuration configuration, + MotorInstanceConfiguration motorConfiguration, + SimulationConditions simulationConditions, WarningSet warnings ) { + + this.setSimulationConditions(simulationConditions); + this.setConfiguration(configuration); + this.setMotorConfiguration(motorConfiguration); + + this.setSimulationTime(0); + this.setPreviousTimeStep(simulationConditions.getTimeStep()); + this.setRocketPosition(Coordinate.NUL); + this.setRocketVelocity(Coordinate.NUL); + this.setRocketWorldPosition(simulationConditions.getLaunchSite()); + + // Initialize to roll angle with least stability w.r.t. the wind + Quaternion o; + FlightConditions cond = new FlightConditions(configuration); + simulationConditions.getAerodynamicCalculator().getWorstCP(configuration, cond, null); + double angle = -cond.getTheta() - simulationConditions.getLaunchRodDirection(); + o = Quaternion.rotation(new Coordinate(0, 0, angle)); + + // Launch rod angle and direction + o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, simulationConditions.getLaunchRodAngle(), 0))); + o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, 0, simulationConditions.getLaunchRodDirection()))); + + this.setRocketOrientationQuaternion(o); + this.setRocketRotationVelocity(Coordinate.NUL); + + + /* + * Calculate the effective launch rod length taking into account launch lugs. + * If no lugs are found, assume a tower launcher of full length. + */ + double length = simulationConditions.getLaunchRodLength(); + double lugPosition = Double.NaN; + for (RocketComponent c : configuration) { + if (c instanceof LaunchLug) { + double pos = c.toAbsolute(new Coordinate(c.getLength()))[0].x; + if (Double.isNaN(lugPosition) || pos > lugPosition) { + lugPosition = pos; + } + } + } + if (!Double.isNaN(lugPosition)) { + double maxX = 0; + for (Coordinate c : configuration.getBounds()) { + if (c.x > maxX) + maxX = c.x; + } + if (maxX >= lugPosition) { + length = Math.max(0, length - (maxX - lugPosition)); + } + } + this.setEffectiveLaunchRodLength(length); + + this.setSimulationStartWallTime(System.nanoTime()); + + this.setMotorIgnited(false); + this.setLiftoff(false); + this.setLaunchRodCleared(false); + this.setApogeeReached(false); + + this.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket())); + + this.setFlightData(new FlightDataBranch("MAIN", FlightDataType.TYPE_TIME)); + this.setWarnings(warnings); + + } + + /** + * Copies the data from the provided object to this object. Most included object are + * deep-cloned, except for the flight data object. + * + * @param orig the object from which to copy + */ + public SimulationStatus( SimulationStatus orig ) { + this.simulationConditions = orig.simulationConditions.clone(); + this.configuration = orig.configuration.clone(); + this.motorConfiguration = orig.motorConfiguration.clone(); + this.flightData = orig.flightData; + this.time = orig.time; + this.previousTimeStep = orig.previousTimeStep; + this.position = orig.position; + this.worldPosition = orig.worldPosition; + this.velocity = orig.velocity; + this.orientation = orig.orientation; + this.rotationVelocity = orig.rotationVelocity; + this.effectiveLaunchRodLength = orig.effectiveLaunchRodLength; + this.simulationStartWallTime = orig.simulationStartWallTime; + this.motorIgnited = orig.motorIgnited; + this.liftoff = orig.liftoff; + this.launchRodCleared = orig.launchRodCleared; + this.apogeeReached = orig.apogeeReached; + this.motorBurntOut = orig.motorBurntOut; + + this.deployedRecoveryDevices.clear(); + this.deployedRecoveryDevices.addAll(orig.deployedRecoveryDevices); + + this.eventQueue.clear(); + this.eventQueue.addAll(orig.eventQueue); + + this.warnings = orig.warnings; + + this.extraData.clear(); + this.extraData.putAll(orig.extraData); + + this.modID = orig.modID; + this.modIDadd = orig.modIDadd; + } public void setSimulationTime(double time) { this.time = time; @@ -323,7 +435,6 @@ public class SimulationStatus implements Cloneable, Monitorable { return extraData.get(key); } - /** * Returns a copy of this object. The general purpose is that the conditions, * rocket configuration, flight data etc. point to the same objects. However, @@ -331,7 +442,6 @@ public class SimulationStatus implements Cloneable, Monitorable { * to the current orientation of the rocket. The purpose is to allow creating intermediate * copies of this object used during step computation. * - * TODO: HIGH: Deep cloning required for branch saving. */ @Override public SimulationStatus clone() { @@ -344,48 +454,6 @@ public class SimulationStatus implements Cloneable, Monitorable { } - /** - * Copies the data from the provided object to this object. Most included object are - * deep-cloned, except for the flight data object. - * - * @param orig the object from which to copy - */ - public void copyFrom(SimulationStatus orig) { - this.simulationConditions = orig.simulationConditions.clone(); - this.configuration = orig.configuration.clone(); - this.motorConfiguration = orig.motorConfiguration.clone(); - this.flightData = orig.flightData; - this.time = orig.time; - this.previousTimeStep = orig.previousTimeStep; - this.position = orig.position; - this.worldPosition = orig.worldPosition; - this.velocity = orig.velocity; - this.orientation = orig.orientation; - this.rotationVelocity = orig.rotationVelocity; - this.effectiveLaunchRodLength = orig.effectiveLaunchRodLength; - this.simulationStartWallTime = orig.simulationStartWallTime; - this.motorIgnited = orig.motorIgnited; - this.liftoff = orig.liftoff; - this.launchRodCleared = orig.launchRodCleared; - this.apogeeReached = orig.apogeeReached; - this.motorBurntOut = orig.motorBurntOut; - - this.deployedRecoveryDevices.clear(); - this.deployedRecoveryDevices.addAll(orig.deployedRecoveryDevices); - - this.eventQueue.clear(); - this.eventQueue.addAll(orig.eventQueue); - - this.warnings = orig.warnings; - - this.extraData.clear(); - this.extraData.putAll(orig.extraData); - - this.modID = orig.modID; - this.modIDadd = orig.modIDadd; - } - - @Override public int getModID() { return (modID + modIDadd + simulationConditions.getModID() + configuration.getModID() +