1 package net.sf.openrocket.simulation;
3 import java.util.HashMap;
7 import net.sf.openrocket.aerodynamics.WarningSet;
8 import net.sf.openrocket.motor.MotorInstanceConfiguration;
9 import net.sf.openrocket.rocketcomponent.Configuration;
10 import net.sf.openrocket.rocketcomponent.RecoveryDevice;
11 import net.sf.openrocket.util.BugException;
12 import net.sf.openrocket.util.Coordinate;
13 import net.sf.openrocket.util.Monitorable;
14 import net.sf.openrocket.util.MonitorableSet;
15 import net.sf.openrocket.util.Quaternion;
16 import net.sf.openrocket.util.WorldCoordinate;
19 * A holder class for the dynamic status during the rocket's flight.
21 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
23 public class SimulationStatus implements Cloneable, Monitorable {
26 * NOTE! All fields must be added to copyFrom() method!!
29 private SimulationConditions simulationConditions;
30 private Configuration configuration;
31 private MotorInstanceConfiguration motorConfiguration;
32 private FlightDataBranch flightData;
36 private double previousTimeStep;
38 private Coordinate position;
39 private WorldCoordinate worldPosition;
40 private Coordinate velocity;
42 private Quaternion orientation;
43 private Coordinate rotationVelocity;
45 private double effectiveLaunchRodLength;
48 /** Nanosecond time when the simulation was started. */
49 private long simulationStartWallTime = Long.MIN_VALUE;
52 /** Set to true when a motor has ignited. */
53 private boolean motorIgnited = false;
55 /** Set to true when the rocket has risen from the ground. */
56 private boolean liftoff = false;
58 /** Set to true when the launch rod has been cleared. */
59 private boolean launchRodCleared = false;
61 /** Set to true when apogee has been detected. */
62 private boolean apogeeReached = false;
64 /** Contains a list of deployed recovery devices. */
65 private MonitorableSet<RecoveryDevice> deployedRecoveryDevices = new MonitorableSet<RecoveryDevice>();
67 /** The flight event queue */
68 private final EventQueue eventQueue = new EventQueue();
70 private WarningSet warnings;
72 /** Available for special purposes by the listeners. */
73 private final Map<String, Object> extraData = new HashMap<String, Object>();
76 private int modID = 0;
77 private int modIDadd = 0;
80 public void setSimulationTime(double time) {
86 public double getSimulationTime() {
91 public void setConfiguration(Configuration configuration) {
92 if (this.configuration != null)
93 this.modIDadd += this.configuration.getModID();
95 this.configuration = configuration;
99 public Configuration getConfiguration() {
100 return configuration;
104 public void setMotorConfiguration(MotorInstanceConfiguration motorConfiguration) {
105 if (this.motorConfiguration != null)
106 this.modIDadd += this.motorConfiguration.getModID();
108 this.motorConfiguration = motorConfiguration;
112 public MotorInstanceConfiguration getMotorConfiguration() {
113 return motorConfiguration;
117 public void setFlightData(FlightDataBranch flightData) {
118 if (this.flightData != null)
119 this.modIDadd += this.flightData.getModID();
121 this.flightData = flightData;
125 public FlightDataBranch getFlightData() {
130 public double getPreviousTimeStep() {
131 return previousTimeStep;
135 public void setPreviousTimeStep(double previousTimeStep) {
136 this.previousTimeStep = previousTimeStep;
141 public void setRocketPosition(Coordinate position) {
142 this.position = position;
147 public Coordinate getRocketPosition() {
151 public void setRocketWorldPosition(WorldCoordinate wc) {
152 this.worldPosition = wc;
156 public WorldCoordinate getRocketWorldPosition() {
157 return worldPosition;
160 public void setRocketVelocity(Coordinate velocity) {
161 this.velocity = velocity;
166 public Coordinate getRocketVelocity() {
174 public Quaternion getRocketOrientationQuaternion() {
179 public void setRocketOrientationQuaternion(Quaternion orientation) {
180 this.orientation = orientation;
185 public Coordinate getRocketRotationVelocity() {
186 return rotationVelocity;
190 public void setRocketRotationVelocity(Coordinate rotation) {
191 this.rotationVelocity = rotation;
195 public void setEffectiveLaunchRodLength(double effectiveLaunchRodLength) {
196 this.effectiveLaunchRodLength = effectiveLaunchRodLength;
201 public double getEffectiveLaunchRodLength() {
202 return effectiveLaunchRodLength;
206 public void setSimulationStartWallTime(long simulationStartWallTime) {
207 this.simulationStartWallTime = simulationStartWallTime;
212 public long getSimulationStartWallTime() {
213 return simulationStartWallTime;
217 public void setMotorIgnited(boolean motorIgnited) {
218 this.motorIgnited = motorIgnited;
223 public boolean isMotorIgnited() {
228 public void setLiftoff(boolean liftoff) {
229 this.liftoff = liftoff;
234 public boolean isLiftoff() {
239 public void setLaunchRodCleared(boolean launchRod) {
240 this.launchRodCleared = launchRod;
245 public boolean isLaunchRodCleared() {
246 return launchRodCleared;
250 public void setApogeeReached(boolean apogeeReached) {
251 this.apogeeReached = apogeeReached;
256 public boolean isApogeeReached() {
257 return apogeeReached;
261 public Set<RecoveryDevice> getDeployedRecoveryDevices() {
262 return deployedRecoveryDevices;
266 public void setWarnings(WarningSet warnings) {
267 if (this.warnings != null)
268 this.modIDadd += this.warnings.getModID();
270 this.warnings = warnings;
274 public WarningSet getWarnings() {
279 public EventQueue getEventQueue() {
284 public void setSimulationConditions(SimulationConditions simulationConditions) {
285 if (this.simulationConditions != null)
286 this.modIDadd += this.simulationConditions.getModID();
288 this.simulationConditions = simulationConditions;
292 public SimulationConditions getSimulationConditions() {
293 return simulationConditions;
298 * Store extra data available for use by simulation listeners. The data can be retrieved
299 * using {@link #getExtraData(String)}.
301 * @param key the data key
302 * @param value the value to store
304 public void putExtraData(String key, Object value) {
305 extraData.put(key, value);
309 * Retrieve extra data stored by simulation listeners. This data map is initially empty.
310 * Data can be stored using {@link #putExtraData(String, Object)}.
312 * @param key the data key to retrieve
313 * @return the data, or <code>null</code> if nothing has been set for the key
315 public Object getExtraData(String key) {
316 return extraData.get(key);
321 * Returns a copy of this object. The general purpose is that the conditions,
322 * rocket configuration, flight data etc. point to the same objects. However,
323 * subclasses are allowed to deep-clone specific objects, such as those pertaining
324 * to the current orientation of the rocket. The purpose is to allow creating intermediate
325 * copies of this object used during step computation.
327 * TODO: HIGH: Deep cloning required for branch saving.
330 public SimulationStatus clone() {
332 SimulationStatus clone = (SimulationStatus) super.clone();
334 } catch (CloneNotSupportedException e) {
335 throw new BugException("CloneNotSupportedException?!?", e);
341 * Copies the data from the provided object to this object. Most included object are
342 * deep-cloned, except for the flight data object.
344 * @param orig the object from which to copy
346 public void copyFrom(SimulationStatus orig) {
347 this.simulationConditions = orig.simulationConditions.clone();
348 this.configuration = orig.configuration.clone();
349 this.motorConfiguration = orig.motorConfiguration.clone();
350 this.flightData = orig.flightData;
351 this.time = orig.time;
352 this.previousTimeStep = orig.previousTimeStep;
353 this.position = orig.position;
354 this.worldPosition = orig.worldPosition;
355 this.velocity = orig.velocity;
356 this.orientation = orig.orientation;
357 this.rotationVelocity = orig.rotationVelocity;
358 this.effectiveLaunchRodLength = orig.effectiveLaunchRodLength;
359 this.simulationStartWallTime = orig.simulationStartWallTime;
360 this.motorIgnited = orig.motorIgnited;
361 this.liftoff = orig.liftoff;
362 this.launchRodCleared = orig.launchRodCleared;
363 this.apogeeReached = orig.apogeeReached;
365 this.deployedRecoveryDevices.clear();
366 this.deployedRecoveryDevices.addAll(orig.deployedRecoveryDevices);
368 this.eventQueue.clear();
369 this.eventQueue.addAll(orig.eventQueue);
371 this.warnings = orig.warnings;
373 this.extraData.clear();
374 this.extraData.putAll(orig.extraData);
376 this.modID = orig.modID;
377 this.modIDadd = orig.modIDadd;
382 public int getModID() {
383 return (modID + modIDadd + simulationConditions.getModID() + configuration.getModID() +
384 motorConfiguration.getModID() + flightData.getModID() + deployedRecoveryDevices.getModID() +
385 eventQueue.getModID() + warnings.getModID());