1 package net.sf.openrocket.simulation;
3 import java.util.ArrayList;
6 import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
7 import net.sf.openrocket.masscalc.MassCalculator;
8 import net.sf.openrocket.models.atmosphere.AtmosphericModel;
9 import net.sf.openrocket.models.gravity.GravityModel;
10 import net.sf.openrocket.models.wind.WindModel;
11 import net.sf.openrocket.rocketcomponent.Rocket;
12 import net.sf.openrocket.simulation.listeners.SimulationListener;
13 import net.sf.openrocket.util.BugException;
14 import net.sf.openrocket.util.GeodeticComputationStrategy;
15 import net.sf.openrocket.util.Monitorable;
16 import net.sf.openrocket.util.WorldCoordinate;
19 * A holder class for the simulation conditions. These include conditions that do not change
20 * during the flight of a rocket, for example launch rod parameters, atmospheric models,
21 * aerodynamic calculators etc.
23 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
25 public class SimulationConditions implements Monitorable, Cloneable {
27 private Rocket rocket;
28 private String motorID = null;
31 private double launchRodLength = 1;
33 /** Launch rod angle >= 0, radians from vertical */
34 private double launchRodAngle = 0;
36 /** Launch rod direction, 0 = upwind, PI = downwind. */
37 private double launchRodDirection = 0;
39 // TODO: Depreciate these and use worldCoordinate only.
40 //private double launchAltitude = 0;
41 //private double launchLatitude = 45;
42 //private double launchLongitude = 0;
43 private WorldCoordinate launchSite = new WorldCoordinate(0, 0, 0);
44 private GeodeticComputationStrategy geodeticComputation = GeodeticComputationStrategy.SPHERICAL;
47 private WindModel windModel;
48 private AtmosphericModel atmosphericModel;
49 private GravityModel gravityModel;
51 private AerodynamicCalculator aerodynamicCalculator;
52 private MassCalculator massCalculator;
55 private double timeStep = RK4SimulationStepper.RECOMMENDED_TIME_STEP;
56 private double maximumAngleStep = RK4SimulationStepper.RECOMMENDED_ANGLE_STEP;
58 /* Whether to calculate additional data or only primary simulation figures */
59 private boolean calculateExtras = true;
62 private List<SimulationListener> simulationListeners = new ArrayList<SimulationListener>();
65 private int randomSeed = 0;
67 private int modID = 0;
68 private int modIDadd = 0;
73 public AerodynamicCalculator getAerodynamicCalculator() {
74 return aerodynamicCalculator;
78 public void setAerodynamicCalculator(AerodynamicCalculator aerodynamicCalculator) {
79 if (this.aerodynamicCalculator != null)
80 this.modIDadd += this.aerodynamicCalculator.getModID();
82 this.aerodynamicCalculator = aerodynamicCalculator;
85 public MassCalculator getMassCalculator() {
86 return massCalculator;
90 public void setMassCalculator(MassCalculator massCalculator) {
91 if (this.massCalculator != null)
92 this.modIDadd += this.massCalculator.getModID();
94 this.massCalculator = massCalculator;
98 public Rocket getRocket() {
103 public void setRocket(Rocket rocket) {
104 if (this.rocket != null)
105 this.modIDadd += this.rocket.getModID();
107 this.rocket = rocket;
111 public String getMotorConfigurationID() {
116 public void setMotorConfigurationID(String motorID) {
117 this.motorID = motorID;
122 public double getLaunchRodLength() {
123 return launchRodLength;
127 public void setLaunchRodLength(double launchRodLength) {
128 this.launchRodLength = launchRodLength;
133 public double getLaunchRodAngle() {
134 return launchRodAngle;
138 public void setLaunchRodAngle(double launchRodAngle) {
139 this.launchRodAngle = launchRodAngle;
144 public double getLaunchRodDirection() {
145 return launchRodDirection;
149 public void setLaunchRodDirection(double launchRodDirection) {
150 this.launchRodDirection = launchRodDirection;
155 public WorldCoordinate getLaunchSite() {
156 return this.launchSite;
159 public void setLaunchSite(WorldCoordinate site) {
160 if (this.launchSite.equals(site))
162 this.launchSite = site;
167 public GeodeticComputationStrategy getGeodeticComputation() {
168 return geodeticComputation;
171 public void setGeodeticComputation(GeodeticComputationStrategy geodeticComputation) {
172 if (this.geodeticComputation == geodeticComputation)
174 if (geodeticComputation == null) {
175 throw new IllegalArgumentException("strategy cannot be null");
177 this.geodeticComputation = geodeticComputation;
182 public WindModel getWindModel() {
187 public void setWindModel(WindModel windModel) {
188 if (this.windModel != null)
189 this.modIDadd += this.windModel.getModID();
191 this.windModel = windModel;
195 public AtmosphericModel getAtmosphericModel() {
196 return atmosphericModel;
200 public void setAtmosphericModel(AtmosphericModel atmosphericModel) {
201 if (this.atmosphericModel != null)
202 this.modIDadd += this.atmosphericModel.getModID();
204 this.atmosphericModel = atmosphericModel;
208 public GravityModel getGravityModel() {
213 public void setGravityModel(GravityModel gravityModel) {
214 //if (this.gravityModel != null)
215 // this.modIDadd += this.gravityModel.getModID();
217 this.gravityModel = gravityModel;
221 public double getTimeStep() {
226 public void setTimeStep(double timeStep) {
227 this.timeStep = timeStep;
232 public double getMaximumAngleStep() {
233 return maximumAngleStep;
237 public void setMaximumAngleStep(double maximumAngle) {
238 this.maximumAngleStep = maximumAngle;
243 public boolean isCalculateExtras() {
244 return calculateExtras;
248 public void setCalculateExtras(boolean calculateExtras) {
249 this.calculateExtras = calculateExtras;
255 public int getRandomSeed() {
260 public void setRandomSeed(int randomSeed) {
261 this.randomSeed = randomSeed;
268 // TODO: HIGH: Make cleaner
269 public List<SimulationListener> getSimulationListenerList() {
270 return simulationListeners;
275 public int getModID() {
276 //return (modID + modIDadd + rocket.getModID() + windModel.getModID() + atmosphericModel.getModID() +
277 // gravityModel.getModID() + aerodynamicCalculator.getModID() + massCalculator.getModID());
278 return (modID + modIDadd + rocket.getModID() + windModel.getModID() + atmosphericModel.getModID() +
279 aerodynamicCalculator.getModID() + massCalculator.getModID());
284 public SimulationConditions clone() {
286 // TODO: HIGH: Deep clone models
287 return (SimulationConditions) super.clone();
288 } catch (CloneNotSupportedException e) {
289 throw new BugException(e);