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;
18 * A holder class for the dynamic status during the rocket's flight.
20 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
22 public class SimulationStatus implements Cloneable, Monitorable {
25 * NOTE! All fields must be added to copyFrom() method!!
28 private SimulationConditions simulationConditions;
29 private Configuration configuration;
30 private MotorInstanceConfiguration motorConfiguration;
31 private FlightDataBranch flightData;
35 private double previousTimeStep;
37 private Coordinate position;
38 private Coordinate velocity;
40 private Quaternion orientation;
41 private Coordinate rotationVelocity;
43 private double effectiveLaunchRodLength;
46 /** Nanosecond time when the simulation was started. */
47 private long simulationStartWallTime = Long.MIN_VALUE;
50 /** Set to true when a motor has ignited. */
51 private boolean motorIgnited = false;
53 /** Set to true when the rocket has risen from the ground. */
54 private boolean liftoff = false;
56 /** Set to true when the launch rod has been cleared. */
57 private boolean launchRodCleared = false;
59 /** Set to true when apogee has been detected. */
60 private boolean apogeeReached = false;
62 /** Contains a list of deployed recovery devices. */
63 private MonitorableSet<RecoveryDevice> deployedRecoveryDevices = new MonitorableSet<RecoveryDevice>();
65 /** The flight event queue */
66 private final EventQueue eventQueue = new EventQueue();
68 private WarningSet warnings;
70 /** Available for special purposes by the listeners. */
71 private final Map<String, Object> extraData = new HashMap<String, Object>();
74 private int modID = 0;
75 private int modIDadd = 0;
78 public void setSimulationTime(double time) {
84 public double getSimulationTime() {
89 public void setConfiguration(Configuration configuration) {
90 if (this.configuration != null)
91 this.modIDadd += this.configuration.getModID();
93 this.configuration = configuration;
97 public Configuration getConfiguration() {
102 public void setMotorConfiguration(MotorInstanceConfiguration motorConfiguration) {
103 if (this.motorConfiguration != null)
104 this.modIDadd += this.motorConfiguration.getModID();
106 this.motorConfiguration = motorConfiguration;
110 public MotorInstanceConfiguration getMotorConfiguration() {
111 return motorConfiguration;
115 public void setFlightData(FlightDataBranch flightData) {
116 if (this.flightData != null)
117 this.modIDadd += this.flightData.getModID();
119 this.flightData = flightData;
123 public FlightDataBranch getFlightData() {
128 public double getPreviousTimeStep() {
129 return previousTimeStep;
133 public void setPreviousTimeStep(double previousTimeStep) {
134 this.previousTimeStep = previousTimeStep;
139 public void setRocketPosition(Coordinate position) {
140 this.position = position;
145 public Coordinate getRocketPosition() {
150 public void setRocketVelocity(Coordinate velocity) {
151 this.velocity = velocity;
156 public Coordinate getRocketVelocity() {
164 public Quaternion getRocketOrientationQuaternion() {
169 public void setRocketOrientationQuaternion(Quaternion orientation) {
170 this.orientation = orientation;
175 public Coordinate getRocketRotationVelocity() {
176 return rotationVelocity;
180 public void setRocketRotationVelocity(Coordinate rotation) {
181 this.rotationVelocity = rotation;
185 public void setEffectiveLaunchRodLength(double effectiveLaunchRodLength) {
186 this.effectiveLaunchRodLength = effectiveLaunchRodLength;
191 public double getEffectiveLaunchRodLength() {
192 return effectiveLaunchRodLength;
196 public void setSimulationStartWallTime(long simulationStartWallTime) {
197 this.simulationStartWallTime = simulationStartWallTime;
202 public long getSimulationStartWallTime() {
203 return simulationStartWallTime;
207 public void setMotorIgnited(boolean motorIgnited) {
208 this.motorIgnited = motorIgnited;
213 public boolean isMotorIgnited() {
218 public void setLiftoff(boolean liftoff) {
219 this.liftoff = liftoff;
224 public boolean isLiftoff() {
229 public void setLaunchRodCleared(boolean launchRod) {
230 this.launchRodCleared = launchRod;
235 public boolean isLaunchRodCleared() {
236 return launchRodCleared;
240 public void setApogeeReached(boolean apogeeReached) {
241 this.apogeeReached = apogeeReached;
246 public boolean isApogeeReached() {
247 return apogeeReached;
251 public Set<RecoveryDevice> getDeployedRecoveryDevices() {
252 return deployedRecoveryDevices;
256 public void setWarnings(WarningSet warnings) {
257 if (this.warnings != null)
258 this.modIDadd += this.warnings.getModID();
260 this.warnings = warnings;
264 public WarningSet getWarnings() {
269 public EventQueue getEventQueue() {
274 public void setSimulationConditions(SimulationConditions simulationConditions) {
275 if (this.simulationConditions != null)
276 this.modIDadd += this.simulationConditions.getModID();
278 this.simulationConditions = simulationConditions;
282 public SimulationConditions getSimulationConditions() {
283 return simulationConditions;
288 * Store extra data available for use by simulation listeners. The data can be retrieved
289 * using {@link #getExtraData(String)}.
291 * @param key the data key
292 * @param value the value to store
294 public void putExtraData(String key, Object value) {
295 extraData.put(key, value);
299 * Retrieve extra data stored by simulation listeners. This data map is initially empty.
300 * Data can be stored using {@link #putExtraData(String, Object)}.
302 * @param key the data key to retrieve
303 * @return the data, or <code>null</code> if nothing has been set for the key
305 public Object getExtraData(String key) {
306 return extraData.get(key);
311 * Returns a copy of this object. The general purpose is that the conditions,
312 * rocket configuration, flight data etc. point to the same objects. However,
313 * subclasses are allowed to deep-clone specific objects, such as those pertaining
314 * to the current orientation of the rocket. The purpose is to allow creating intermediate
315 * copies of this object used during step computation.
317 * TODO: HIGH: Deep cloning required for branch saving.
320 public SimulationStatus clone() {
322 SimulationStatus clone = (SimulationStatus) super.clone();
324 } catch (CloneNotSupportedException e) {
325 throw new BugException("CloneNotSupportedException?!?", e);
331 * Copies the data from the provided object to this object. Most included object are
332 * deep-cloned, except for the flight data object.
334 * @param orig the object from which to copy
336 public void copyFrom(SimulationStatus orig) {
337 this.simulationConditions = orig.simulationConditions.clone();
338 this.configuration = orig.configuration.clone();
339 this.motorConfiguration = orig.motorConfiguration.clone();
340 this.flightData = orig.flightData;
341 this.time = orig.time;
342 this.previousTimeStep = orig.previousTimeStep;
343 this.position = orig.position;
344 this.velocity = orig.velocity;
345 this.orientation = orig.orientation;
346 this.rotationVelocity = orig.rotationVelocity;
347 this.effectiveLaunchRodLength = orig.effectiveLaunchRodLength;
348 this.simulationStartWallTime = orig.simulationStartWallTime;
349 this.motorIgnited = orig.motorIgnited;
350 this.liftoff = orig.liftoff;
351 this.launchRodCleared = orig.launchRodCleared;
352 this.apogeeReached = orig.apogeeReached;
354 this.deployedRecoveryDevices.clear();
355 this.deployedRecoveryDevices.addAll(orig.deployedRecoveryDevices);
357 this.eventQueue.clear();
358 this.eventQueue.addAll(orig.eventQueue);
360 this.warnings = orig.warnings;
362 this.extraData.clear();
363 this.extraData.putAll(orig.extraData);
365 this.modID = orig.modID;
366 this.modIDadd = orig.modIDadd;
371 public int getModID() {
372 return (modID + modIDadd + simulationConditions.getModID() + configuration.getModID() +
373 motorConfiguration.getModID() + flightData.getModID() + deployedRecoveryDevices.getModID() +
374 eventQueue.getModID() + warnings.getModID());