1 package net.sf.openrocket.simulation;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.HashMap;
6 import java.util.LinkedHashMap;
10 import net.sf.openrocket.unit.UnitGroup;
11 import net.sf.openrocket.util.Pair;
14 public class FlightDataBranch {
17 public static final Type TYPE_TIME =
18 new Type("Time", UnitGroup.UNITS_FLIGHT_TIME, 1);
21 //// Vertical position and motion
22 public static final Type TYPE_ALTITUDE =
23 new Type("Altitude", UnitGroup.UNITS_DISTANCE, 10);
24 public static final Type TYPE_VELOCITY_Z =
25 new Type("Vertical velocity", UnitGroup.UNITS_VELOCITY, 11);
26 public static final Type TYPE_ACCELERATION_Z =
27 new Type("Vertical acceleration", UnitGroup.UNITS_ACCELERATION, 12);
31 public static final Type TYPE_VELOCITY_TOTAL =
32 new Type("Total velocity", UnitGroup.UNITS_VELOCITY, 20);
33 public static final Type TYPE_ACCELERATION_TOTAL =
34 new Type("Total acceleration", UnitGroup.UNITS_ACCELERATION, 21);
37 //// Lateral position and motion
39 public static final Type TYPE_POSITION_X =
40 new Type("Position upwind", UnitGroup.UNITS_DISTANCE, 30);
41 public static final Type TYPE_POSITION_Y =
42 new Type("Position parallel to wind", UnitGroup.UNITS_DISTANCE, 31);
43 public static final Type TYPE_POSITION_XY =
44 new Type("Lateral distance", UnitGroup.UNITS_DISTANCE, 32);
45 public static final Type TYPE_POSITION_DIRECTION =
46 new Type("Lateral direction", UnitGroup.UNITS_ANGLE, 33);
48 public static final Type TYPE_VELOCITY_XY =
49 new Type("Lateral velocity", UnitGroup.UNITS_VELOCITY, 34);
50 public static final Type TYPE_ACCELERATION_XY =
51 new Type("Lateral acceleration", UnitGroup.UNITS_ACCELERATION, 35);
55 public static final Type TYPE_AOA = new Type("Angle of attack", UnitGroup.UNITS_ANGLE, 40);
56 public static final Type TYPE_ROLL_RATE = new Type("Roll rate", UnitGroup.UNITS_ROLL, 41);
57 public static final Type TYPE_PITCH_RATE = new Type("Pitch rate", UnitGroup.UNITS_ROLL, 42);
58 public static final Type TYPE_YAW_RATE = new Type("Yaw rate", UnitGroup.UNITS_ROLL, 43);
61 //// Stability information
62 public static final Type TYPE_MASS =
63 new Type("Mass", UnitGroup.UNITS_MASS, 50);
64 public static final Type TYPE_CP_LOCATION =
65 new Type("CP location", UnitGroup.UNITS_LENGTH, 51);
66 public static final Type TYPE_CG_LOCATION =
67 new Type("CG location", UnitGroup.UNITS_LENGTH, 52);
68 public static final Type TYPE_STABILITY =
69 new Type("Stability margin calibers", UnitGroup.UNITS_COEFFICIENT, 53);
72 //// Characteristic numbers
73 public static final Type TYPE_MACH_NUMBER =
74 new Type("Mach number", UnitGroup.UNITS_COEFFICIENT, 60);
75 public static final Type TYPE_REYNOLDS_NUMBER =
76 new Type("Reynolds number", UnitGroup.UNITS_COEFFICIENT, 61);
80 public static final Type TYPE_THRUST_FORCE =
81 new Type("Thrust", UnitGroup.UNITS_FORCE, 70);
82 public static final Type TYPE_DRAG_FORCE =
83 new Type("Drag force", UnitGroup.UNITS_FORCE, 71);
85 public static final Type TYPE_DRAG_COEFF =
86 new Type("Drag coefficient", UnitGroup.UNITS_COEFFICIENT, 72);
87 public static final Type TYPE_AXIAL_DRAG_COEFF =
88 new Type("Axial drag coefficient", UnitGroup.UNITS_COEFFICIENT, 73);
91 //// Component drag coefficients
92 public static final Type TYPE_FRICTION_DRAG_COEFF =
93 new Type("Friction drag coefficient", UnitGroup.UNITS_COEFFICIENT, 80);
94 public static final Type TYPE_PRESSURE_DRAG_COEFF =
95 new Type("Pressure drag coefficient", UnitGroup.UNITS_COEFFICIENT, 81);
96 public static final Type TYPE_BASE_DRAG_COEFF =
97 new Type("Base drag coefficient", UnitGroup.UNITS_COEFFICIENT, 82);
100 //// Other coefficients
101 public static final Type TYPE_NORMAL_FORCE_COEFF =
102 new Type("Normal force coefficient", UnitGroup.UNITS_COEFFICIENT, 90);
103 public static final Type TYPE_PITCH_MOMENT_COEFF =
104 new Type("Pitch moment coefficient", UnitGroup.UNITS_COEFFICIENT, 91);
105 public static final Type TYPE_YAW_MOMENT_COEFF =
106 new Type("Yaw moment coefficient", UnitGroup.UNITS_COEFFICIENT, 92);
107 public static final Type TYPE_SIDE_FORCE_COEFF =
108 new Type("Side force coefficient", UnitGroup.UNITS_COEFFICIENT, 93);
109 public static final Type TYPE_ROLL_MOMENT_COEFF =
110 new Type("Roll moment coefficient", UnitGroup.UNITS_COEFFICIENT, 94);
111 public static final Type TYPE_ROLL_FORCING_COEFF =
112 new Type("Roll forcing coefficient", UnitGroup.UNITS_COEFFICIENT, 95);
113 public static final Type TYPE_ROLL_DAMPING_COEFF =
114 new Type("Roll damping coefficient", UnitGroup.UNITS_COEFFICIENT, 96);
116 public static final Type TYPE_PITCH_DAMPING_MOMENT_COEFF =
117 new Type("Pitch damping coefficient", UnitGroup.UNITS_COEFFICIENT, 97);
118 public static final Type TYPE_YAW_DAMPING_MOMENT_COEFF =
119 new Type("Yaw damping coefficient", UnitGroup.UNITS_COEFFICIENT, 98);
122 //// Reference length + area
123 public static final Type TYPE_REFERENCE_LENGTH =
124 new Type("Reference length", UnitGroup.UNITS_LENGTH, 100);
125 public static final Type TYPE_REFERENCE_AREA =
126 new Type("Reference area", UnitGroup.UNITS_AREA, 101);
130 public static final Type TYPE_ORIENTATION_THETA =
131 new Type("Vertical orientation (zenith)", UnitGroup.UNITS_ANGLE, 106);
132 public static final Type TYPE_ORIENTATION_PHI =
133 new Type("Lateral orientation (azimuth)", UnitGroup.UNITS_ANGLE, 107);
136 //// Atmospheric conditions
137 public static final Type TYPE_WIND_VELOCITY = new Type("Wind velocity",
138 UnitGroup.UNITS_VELOCITY, 110);
139 public static final Type TYPE_AIR_TEMPERATURE = new Type("Air temperature",
140 UnitGroup.UNITS_TEMPERATURE, 111);
141 public static final Type TYPE_AIR_PRESSURE = new Type("Air pressure",
142 UnitGroup.UNITS_PRESSURE, 112);
143 public static final Type TYPE_SPEED_OF_SOUND = new Type("Speed of sound",
144 UnitGroup.UNITS_VELOCITY, 113);
147 //// Simulation information
148 public static final Type TYPE_TIME_STEP = new Type("Simulation time step",
149 UnitGroup.UNITS_TIME_STEP, 200);
150 public static final Type TYPE_COMPUTATION_TIME = new Type("Computation time",
151 UnitGroup.UNITS_SHORT_TIME, 201);
155 * Array of known data types for String -> Type conversion.
157 private static final Type[] TYPES = {
159 TYPE_ALTITUDE, TYPE_VELOCITY_Z, TYPE_ACCELERATION_Z,
160 TYPE_VELOCITY_TOTAL, TYPE_ACCELERATION_TOTAL,
161 TYPE_POSITION_X, TYPE_POSITION_Y, TYPE_POSITION_XY, TYPE_POSITION_DIRECTION,
162 TYPE_VELOCITY_XY, TYPE_ACCELERATION_XY,
163 TYPE_AOA, TYPE_ROLL_RATE, TYPE_PITCH_RATE, TYPE_YAW_RATE,
164 TYPE_MASS, TYPE_CP_LOCATION, TYPE_CG_LOCATION, TYPE_STABILITY,
165 TYPE_MACH_NUMBER, TYPE_REYNOLDS_NUMBER,
166 TYPE_THRUST_FORCE, TYPE_DRAG_FORCE,
167 TYPE_DRAG_COEFF, TYPE_AXIAL_DRAG_COEFF,
168 TYPE_FRICTION_DRAG_COEFF, TYPE_PRESSURE_DRAG_COEFF, TYPE_BASE_DRAG_COEFF,
169 TYPE_NORMAL_FORCE_COEFF, TYPE_PITCH_MOMENT_COEFF, TYPE_YAW_MOMENT_COEFF, TYPE_SIDE_FORCE_COEFF,
170 TYPE_ROLL_MOMENT_COEFF, TYPE_ROLL_FORCING_COEFF, TYPE_ROLL_DAMPING_COEFF,
171 TYPE_PITCH_DAMPING_MOMENT_COEFF, TYPE_YAW_DAMPING_MOMENT_COEFF,
172 TYPE_REFERENCE_LENGTH, TYPE_REFERENCE_AREA,
173 TYPE_ORIENTATION_THETA, TYPE_ORIENTATION_PHI,
174 TYPE_WIND_VELOCITY, TYPE_AIR_TEMPERATURE, TYPE_AIR_PRESSURE, TYPE_SPEED_OF_SOUND,
175 TYPE_TIME_STEP, TYPE_COMPUTATION_TIME
179 * Return a {@link Type} based on a string description. This returns known data types
180 * if possible, or a new type otherwise.
182 * @param s the string description of the type.
183 * @param u the unit group the new type should belong to if a new group is created.
184 * @return a data type.
186 public static Type getType(String s, UnitGroup u) {
187 for (Type t: TYPES) {
188 if (t.getName().equalsIgnoreCase(s))
191 return new Type(s, u);
196 public static class Type implements Comparable<Type> {
197 private final String name;
198 private final UnitGroup units;
199 private final int priority;
200 private final int hashCode;
202 private Type(String typeName, UnitGroup units) {
203 this(typeName, units, 999);
206 public Type(String typeName, UnitGroup units, int priority) {
207 if (typeName == null)
208 throw new IllegalArgumentException("typeName is null");
209 this.name = typeName;
211 this.priority = priority;
212 this.hashCode = this.name.toLowerCase().hashCode();
215 public String getName() {
219 public UnitGroup getUnitGroup() {
224 public String toString() {
229 public boolean equals(Object other) {
230 if (!(other instanceof Type))
232 return this.name.equalsIgnoreCase(((Type)other).name);
235 public int hashCode() {
240 public int compareTo(Type o) {
241 return this.priority - o.priority;
248 /** The name of this flight data branch. */
249 private final String branchName;
251 private final Map<Type, ArrayList<Double>> values =
252 new LinkedHashMap<Type, ArrayList<Double>>();
254 private final Map<Type, Double> maxValues = new HashMap<Type, Double>();
255 private final Map<Type, Double> minValues = new HashMap<Type, Double>();
258 private final ArrayList<Pair<Double,FlightEvent>> events =
259 new ArrayList<Pair<Double,FlightEvent>>();
261 private boolean mutable = true;
264 public FlightDataBranch(String name, Type... types) {
265 if (types.length == 0) {
266 throw new IllegalArgumentException("Must specify at least one data type.");
269 this.branchName = name;
271 for (Type t: types) {
272 if (values.containsKey(t)) {
273 throw new IllegalArgumentException("Value type "+t+" specified multiple " +
274 "times in constructor.");
277 values.put(t, new ArrayList<Double>());
278 minValues.put(t, Double.NaN);
279 maxValues.put(t, Double.NaN);
284 public String getBranchName() {
288 public Type[] getTypes() {
289 Type[] array = values.keySet().toArray(new Type[0]);
294 public int getLength() {
295 for (Type t: values.keySet()) {
296 return values.get(t).size();
303 public void addPoint() {
305 throw new IllegalStateException("FlightDataBranch has been made immutable.");
306 for (Type t: values.keySet()) {
307 values.get(t).add(Double.NaN);
311 public void setValue(Type type, double value) {
313 throw new IllegalStateException("FlightDataBranch has been made immutable.");
314 ArrayList<Double> list = values.get(type);
317 list = new ArrayList<Double>();
319 for (int i=0; i < n; i++) {
320 list.add(Double.NaN);
322 values.put(type, list);
323 minValues.put(type, value);
324 maxValues.put(type, value);
327 list.set(list.size()-1, value);
328 double min = minValues.get(type);
329 double max = maxValues.get(type);
331 if (Double.isNaN(min) || (value < min)) {
332 minValues.put(type, value);
334 if (Double.isNaN(max) || (value > max)) {
335 maxValues.put(type, value);
340 @SuppressWarnings("unchecked")
341 public List<Double> get(Type type) {
342 ArrayList<Double> list = values.get(type);
345 return (List<Double>)list.clone();
349 public double get(Type type, int index) {
350 ArrayList<Double> list = values.get(type);
353 return list.get(index);
358 * Return the last value of the specified type in the branch, or NaN if the type is
361 * @param type the parameter type.
362 * @return the last value in this branch, or NaN.
364 public double getLast(Type type) {
365 ArrayList<Double> list = values.get(type);
366 if (list==null || list.isEmpty())
368 return list.get(list.size()-1);
372 * Return the minimum value of the specified type in the branch, or NaN if the type
375 * @param type the parameter type.
376 * @return the minimum value in this branch, or NaN.
378 public double getMinimum(Type type) {
379 Double v = minValues.get(type);
386 * Return the maximum value of the specified type in the branch, or NaN if the type
389 * @param type the parameter type.
390 * @return the maximum value in this branch, or NaN.
392 public double getMaximum(Type type) {
393 Double v = maxValues.get(type);
400 public void addEvent(double time, FlightEvent event) {
402 throw new IllegalStateException("FlightDataBranch has been made immutable.");
403 events.add(new Pair<Double,FlightEvent>(time,event));
408 * Return the list of events. The list is a list of (time, event) pairs.
410 * @return the list of events during the flight.
412 @SuppressWarnings("unchecked")
413 public List<Pair<Double, FlightEvent>> getEvents() {
414 return (List<Pair<Double, FlightEvent>>) events.clone();
419 * Make this FlightDataBranch immutable. Any calls to the set methods that would
420 * modify this object will after this call throw an <code>IllegalStateException</code>.
422 public void immute() {
426 public boolean isMutable() {