diff --git a/core/src/net/sf/openrocket/simulation/SimulationConditions.java b/core/src/net/sf/openrocket/simulation/SimulationConditions.java index ffd9e003a..f068db35f 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationConditions.java +++ b/core/src/net/sf/openrocket/simulation/SimulationConditions.java @@ -12,6 +12,7 @@ import net.sf.openrocket.models.wind.WindModel; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.simulation.listeners.SimulationListener; import net.sf.openrocket.util.BugException; +import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.GeodeticComputationStrategy; import net.sf.openrocket.util.Monitorable; import net.sf.openrocket.util.WorldCoordinate; @@ -29,7 +30,7 @@ public class SimulationConditions implements Monitorable, Cloneable { private String motorID = null; private Simulation simulation; // The parent simulation - + private double launchRodLength = 1; /** Launch rod angle >= 0, radians from vertical */ @@ -38,14 +39,17 @@ public class SimulationConditions implements Monitorable, Cloneable { /** Launch rod direction, 0 = upwind, PI = downwind. */ private double launchRodDirection = 0; - // TODO: Depreciate these and use worldCoordinate only. - //private double launchAltitude = 0; - //private double launchLatitude = 45; - //private double launchLongitude = 0; + // Launch site location (lat, lon, alt) private WorldCoordinate launchSite = new WorldCoordinate(0, 0, 0); + + // Launch location in simulation coordinates (normally always 0, air-start would override this) + private Coordinate launchPosition = Coordinate.NUL; + + private Coordinate launchVelocity = Coordinate.NUL; + private GeodeticComputationStrategy geodeticComputation = GeodeticComputationStrategy.SPHERICAL; - + private WindModel windModel; private AtmosphericModel atmosphericModel; private GravityModel gravityModel; @@ -53,25 +57,25 @@ public class SimulationConditions implements Monitorable, Cloneable { private AerodynamicCalculator aerodynamicCalculator; private MassCalculator massCalculator; - + private double timeStep = RK4SimulationStepper.RECOMMENDED_TIME_STEP; private double maximumAngleStep = RK4SimulationStepper.RECOMMENDED_ANGLE_STEP; /* Whether to calculate additional data or only primary simulation figures */ private boolean calculateExtras = true; - + private List simulationListeners = new ArrayList(); - + private int randomSeed = 0; private int modID = 0; private int modIDadd = 0; - - + + public AerodynamicCalculator getAerodynamicCalculator() { return aerodynamicCalculator; } @@ -166,6 +170,29 @@ public class SimulationConditions implements Monitorable, Cloneable { } + public Coordinate getLaunchPosition() { + return launchPosition; + } + + public void setLaunchPosition(Coordinate launchPosition) { + if (this.launchPosition.equals(launchPosition)) + return; + this.launchPosition = launchPosition; + this.modID++; + } + + public Coordinate getLaunchVelocity() { + return launchVelocity; + } + + public void setLaunchVelocity(Coordinate launchVelocity) { + if (this.launchVelocity.equals(launchVelocity)) + return; + this.launchVelocity = launchVelocity; + this.modID++; + } + + public GeodeticComputationStrategy getGeodeticComputation() { return geodeticComputation; } @@ -253,7 +280,7 @@ public class SimulationConditions implements Monitorable, Cloneable { } - + public int getRandomSeed() { return randomSeed; } @@ -267,8 +294,8 @@ public class SimulationConditions implements Monitorable, Cloneable { public void setSimulation(Simulation sim) { this.simulation = sim; } - - public Simulation getSimulation(){ + + public Simulation getSimulation() { return this.simulation; } diff --git a/core/src/net/sf/openrocket/simulation/SimulationStatus.java b/core/src/net/sf/openrocket/simulation/SimulationStatus.java index 30fce5772..acff4d4ff 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationStatus.java +++ b/core/src/net/sf/openrocket/simulation/SimulationStatus.java @@ -30,7 +30,7 @@ public class SimulationStatus implements Monitorable { /* * NOTE! All fields must be added to copyFrom() method!! */ - + private SimulationConditions simulationConditions; private Configuration configuration; private MotorInstanceConfiguration motorConfiguration; @@ -51,12 +51,12 @@ public class SimulationStatus implements Monitorable { // Set of burnt out motors Set motorBurntOut = new HashSet(); - - + + /** Nanosecond time when the simulation was started. */ private long simulationStartWallTime = Long.MIN_VALUE; - + /** Set to true when a motor has ignited. */ private boolean motorIgnited = false; @@ -83,38 +83,38 @@ public class SimulationStatus implements Monitorable { /** Available for special purposes by the listeners. */ private final Map extraData = new HashMap(); - + private int modID = 0; private int modIDadd = 0; - public SimulationStatus( Configuration configuration, + public SimulationStatus(Configuration configuration, MotorInstanceConfiguration motorConfiguration, - SimulationConditions simulationConditions ) { + SimulationConditions simulationConditions) { this.simulationConditions = simulationConditions; this.configuration = configuration; this.motorConfiguration = motorConfiguration; - + this.time = 0; this.previousTimeStep = this.simulationConditions.getTimeStep(); - this.position = Coordinate.NUL; - this.velocity = Coordinate.NUL; + this.position = this.simulationConditions.getLaunchPosition(); + this.velocity = this.simulationConditions.getLaunchVelocity(); this.worldPosition = this.simulationConditions.getLaunchSite(); - + // Initialize to roll angle with least stability w.r.t. the wind Quaternion o; FlightConditions cond = new FlightConditions(this.configuration); this.simulationConditions.getAerodynamicCalculator().getWorstCP(this.configuration, cond, null); double angle = -cond.getTheta() - this.simulationConditions.getLaunchRodDirection(); o = Quaternion.rotation(new Coordinate(0, 0, angle)); - + // Launch rod angle and direction o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, this.simulationConditions.getLaunchRodAngle(), 0))); o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, 0, this.simulationConditions.getLaunchRodDirection()))); - + this.orientation = o; this.rotationVelocity = 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. @@ -140,16 +140,16 @@ public class SimulationStatus implements Monitorable { } } this.effectiveLaunchRodLength = length; - + this.simulationStartWallTime = System.nanoTime(); - + this.motorIgnited = false; this.liftoff = false; this.launchRodCleared = false; this.apogeeReached = false; - + this.warnings = new WarningSet(); - + } /** @@ -163,7 +163,7 @@ public class SimulationStatus implements Monitorable { * * @param orig the object from which to copy */ - public SimulationStatus( SimulationStatus orig ) { + public SimulationStatus(SimulationStatus orig) { this.simulationConditions = orig.simulationConditions.clone(); this.configuration = orig.configuration.clone(); this.motorConfiguration = orig.motorConfiguration.clone(); @@ -292,11 +292,11 @@ public class SimulationStatus implements Monitorable { } - public boolean addBurntOutMotor( MotorId motor ) { + public boolean addBurntOutMotor(MotorId motor) { return motorBurntOut.add(motor); } - - + + public Quaternion getRocketOrientationQuaternion() { return orientation; } @@ -384,7 +384,7 @@ public class SimulationStatus implements Monitorable { } - public void setTumbling( boolean tumbling ) { + public void setTumbling(boolean tumbling) { this.tumbling = tumbling; this.modID++; } @@ -477,5 +477,5 @@ public class SimulationStatus implements Monitorable { eventQueue.getModID() + warnings.getModID()); } - + }