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().
This commit is contained in:
parent
6d8b27068f
commit
27d6322f09
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
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() +
|
||||
|
Loading…
x
Reference in New Issue
Block a user