1 package net.sf.openrocket.simulation;
3 import java.util.ArrayList;
6 import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
7 import net.sf.openrocket.document.Simulation;
8 import net.sf.openrocket.masscalc.MassCalculator;
9 import net.sf.openrocket.models.atmosphere.AtmosphericModel;
10 import net.sf.openrocket.models.gravity.GravityModel;
11 import net.sf.openrocket.models.wind.WindModel;
12 import net.sf.openrocket.rocketcomponent.Rocket;
13 import net.sf.openrocket.simulation.listeners.SimulationListener;
14 import net.sf.openrocket.util.BugException;
15 import net.sf.openrocket.util.GeodeticComputationStrategy;
16 import net.sf.openrocket.util.Monitorable;
17 import net.sf.openrocket.util.WorldCoordinate;
20 * A holder class for the simulation conditions. These include conditions that do not change
21 * during the flight of a rocket, for example launch rod parameters, atmospheric models,
22 * aerodynamic calculators etc.
24 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
26 public class SimulationConditions implements Monitorable, Cloneable {
28 private Rocket rocket;
29 private String motorID = null;
31 private Simulation simulation; // The parent simulation
33 private double launchRodLength = 1;
35 /** Launch rod angle >= 0, radians from vertical */
36 private double launchRodAngle = 0;
38 /** Launch rod direction, 0 = upwind, PI = downwind. */
39 private double launchRodDirection = 0;
41 // TODO: Depreciate these and use worldCoordinate only.
42 //private double launchAltitude = 0;
43 //private double launchLatitude = 45;
44 //private double launchLongitude = 0;
45 private WorldCoordinate launchSite = new WorldCoordinate(0, 0, 0);
46 private GeodeticComputationStrategy geodeticComputation = GeodeticComputationStrategy.SPHERICAL;
49 private WindModel windModel;
50 private AtmosphericModel atmosphericModel;
51 private GravityModel gravityModel;
53 private AerodynamicCalculator aerodynamicCalculator;
54 private MassCalculator massCalculator;
57 private double timeStep = RK4SimulationStepper.RECOMMENDED_TIME_STEP;
58 private double maximumAngleStep = RK4SimulationStepper.RECOMMENDED_ANGLE_STEP;
60 /* Whether to calculate additional data or only primary simulation figures */
61 private boolean calculateExtras = true;
64 private List<SimulationListener> simulationListeners = new ArrayList<SimulationListener>();
67 private int randomSeed = 0;
69 private int modID = 0;
70 private int modIDadd = 0;
75 public AerodynamicCalculator getAerodynamicCalculator() {
76 return aerodynamicCalculator;
80 public void setAerodynamicCalculator(AerodynamicCalculator aerodynamicCalculator) {
81 if (this.aerodynamicCalculator != null)
82 this.modIDadd += this.aerodynamicCalculator.getModID();
84 this.aerodynamicCalculator = aerodynamicCalculator;
87 public MassCalculator getMassCalculator() {
88 return massCalculator;
92 public void setMassCalculator(MassCalculator massCalculator) {
93 if (this.massCalculator != null)
94 this.modIDadd += this.massCalculator.getModID();
96 this.massCalculator = massCalculator;
100 public Rocket getRocket() {
105 public void setRocket(Rocket rocket) {
106 if (this.rocket != null)
107 this.modIDadd += this.rocket.getModID();
109 this.rocket = rocket;
113 public String getMotorConfigurationID() {
118 public void setMotorConfigurationID(String motorID) {
119 this.motorID = motorID;
124 public double getLaunchRodLength() {
125 return launchRodLength;
129 public void setLaunchRodLength(double launchRodLength) {
130 this.launchRodLength = launchRodLength;
135 public double getLaunchRodAngle() {
136 return launchRodAngle;
140 public void setLaunchRodAngle(double launchRodAngle) {
141 this.launchRodAngle = launchRodAngle;
146 public double getLaunchRodDirection() {
147 return launchRodDirection;
151 public void setLaunchRodDirection(double launchRodDirection) {
152 this.launchRodDirection = launchRodDirection;
157 public WorldCoordinate getLaunchSite() {
158 return this.launchSite;
161 public void setLaunchSite(WorldCoordinate site) {
162 if (this.launchSite.equals(site))
164 this.launchSite = site;
169 public GeodeticComputationStrategy getGeodeticComputation() {
170 return geodeticComputation;
173 public void setGeodeticComputation(GeodeticComputationStrategy geodeticComputation) {
174 if (this.geodeticComputation == geodeticComputation)
176 if (geodeticComputation == null) {
177 throw new IllegalArgumentException("strategy cannot be null");
179 this.geodeticComputation = geodeticComputation;
184 public WindModel getWindModel() {
189 public void setWindModel(WindModel windModel) {
190 if (this.windModel != null)
191 this.modIDadd += this.windModel.getModID();
193 this.windModel = windModel;
197 public AtmosphericModel getAtmosphericModel() {
198 return atmosphericModel;
202 public void setAtmosphericModel(AtmosphericModel atmosphericModel) {
203 if (this.atmosphericModel != null)
204 this.modIDadd += this.atmosphericModel.getModID();
206 this.atmosphericModel = atmosphericModel;
210 public GravityModel getGravityModel() {
215 public void setGravityModel(GravityModel gravityModel) {
216 //if (this.gravityModel != null)
217 // this.modIDadd += this.gravityModel.getModID();
219 this.gravityModel = gravityModel;
223 public double getTimeStep() {
228 public void setTimeStep(double timeStep) {
229 this.timeStep = timeStep;
234 public double getMaximumAngleStep() {
235 return maximumAngleStep;
239 public void setMaximumAngleStep(double maximumAngle) {
240 this.maximumAngleStep = maximumAngle;
245 public boolean isCalculateExtras() {
246 return calculateExtras;
250 public void setCalculateExtras(boolean calculateExtras) {
251 this.calculateExtras = calculateExtras;
257 public int getRandomSeed() {
262 public void setRandomSeed(int randomSeed) {
263 this.randomSeed = randomSeed;
267 public void setSimulation(Simulation sim) {
268 this.simulation = sim;
271 public Simulation getSimulation(){
272 return this.simulation;
275 // TODO: HIGH: Make cleaner
276 public List<SimulationListener> getSimulationListenerList() {
277 return simulationListeners;
282 public int getModID() {
283 //return (modID + modIDadd + rocket.getModID() + windModel.getModID() + atmosphericModel.getModID() +
284 // gravityModel.getModID() + aerodynamicCalculator.getModID() + massCalculator.getModID());
285 return (modID + modIDadd + rocket.getModID() + windModel.getModID() + atmosphericModel.getModID() +
286 aerodynamicCalculator.getModID() + massCalculator.getModID());
291 public SimulationConditions clone() {
293 // TODO: HIGH: Deep clone models
294 return (SimulationConditions) super.clone();
295 } catch (CloneNotSupportedException e) {
296 throw new BugException(e);