1 package net.sf.openrocket.simulation;
3 import java.util.HashMap;
4 import java.util.Locale;
7 import net.sf.openrocket.l10n.Translator;
8 import net.sf.openrocket.logging.LogHelper;
9 import net.sf.openrocket.startup.Application;
10 import net.sf.openrocket.unit.UnitGroup;
13 * A class defining a storable simulation variable type. This class defined numerous ready
14 * types, and allows also creating new types with any name. When retrieving types based on
15 * a name, you should use {@link #getType(String, UnitGroup)} to return the default unit type,
16 * or a new type if the name does not currently exist.
18 * Each type has a type name (description), a unit group and a priority. The type is identified
19 * purely by its name case-insensitively. The unit group provides the units for the type.
20 * The priority is used to order the types. The pre-existing types are defined specific priority
21 * numbers, and other types have a default priority number that is after all other types.
23 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
25 public class FlightDataType implements Comparable<FlightDataType> {
26 private static final Translator trans = Application.getTranslator();
27 private static final LogHelper log = Application.getLogger();
29 /** Priority of custom-created variables */
30 private static final int DEFAULT_PRIORITY = 999;
32 /** List of existing types. MUST BE DEFINED BEFORE ANY TYPES!! */
33 /** NOTE: The String key here is now the symbol */
34 private static final Map<String, FlightDataType> EXISTING_TYPES = new HashMap<String, FlightDataType>();
38 public static final FlightDataType TYPE_TIME = newType(trans.get("FlightDataType.TYPE_TIME"), "t", UnitGroup.UNITS_FLIGHT_TIME, 1);
40 //// Vertical position and motion
42 public static final FlightDataType TYPE_ALTITUDE = newType(trans.get("FlightDataType.TYPE_ALTITUDE"), "h", UnitGroup.UNITS_DISTANCE, 10);
43 //// Vertical velocity
44 public static final FlightDataType TYPE_VELOCITY_Z = newType(trans.get("FlightDataType.TYPE_VELOCITY_Z"), "Vz", UnitGroup.UNITS_VELOCITY, 11);
45 //// Vertical acceleration
46 public static final FlightDataType TYPE_ACCELERATION_Z = newType(trans.get("FlightDataType.TYPE_ACCELERATION_Z"), "Az", UnitGroup.UNITS_ACCELERATION, 12);
51 public static final FlightDataType TYPE_VELOCITY_TOTAL = newType(trans.get("FlightDataType.TYPE_VELOCITY_TOTAL"), "Vt", UnitGroup.UNITS_VELOCITY, 20);
52 //// Total acceleration
53 public static final FlightDataType TYPE_ACCELERATION_TOTAL = newType(trans.get("FlightDataType.TYPE_ACCELERATION_TOTAL"), "At", UnitGroup.UNITS_ACCELERATION, 21);
56 //// Lateral position and motion
58 public static final FlightDataType TYPE_POSITION_X = newType(trans.get("FlightDataType.TYPE_POSITION_X"), "Px", UnitGroup.UNITS_DISTANCE, 30);
59 //// Position parallel to wind
60 public static final FlightDataType TYPE_POSITION_Y = newType(trans.get("FlightDataType.TYPE_POSITION_Y"), "Py", UnitGroup.UNITS_DISTANCE, 31);
62 public static final FlightDataType TYPE_POSITION_XY = newType(trans.get("FlightDataType.TYPE_POSITION_XY"), "Pl", UnitGroup.UNITS_DISTANCE, 32);
63 //// Lateral direction
64 public static final FlightDataType TYPE_POSITION_DIRECTION = newType(trans.get("FlightDataType.TYPE_POSITION_DIRECTION"), "\u03b8l", UnitGroup.UNITS_ANGLE, 33);
66 public static final FlightDataType TYPE_VELOCITY_XY = newType(trans.get("FlightDataType.TYPE_VELOCITY_XY"), "Vl", UnitGroup.UNITS_VELOCITY, 34);
67 //// Lateral acceleration
68 public static final FlightDataType TYPE_ACCELERATION_XY = newType(trans.get("FlightDataType.TYPE_ACCELERATION_XY"), "Al", UnitGroup.UNITS_ACCELERATION, 35);
70 public static final FlightDataType TYPE_LATITUDE = newType(trans.get("FlightDataType.TYPE_LATITUDE"), "\u03c6", UnitGroup.UNITS_ANGLE, 36);
72 public static final FlightDataType TYPE_LONGITUDE = newType(trans.get("FlightDataType.TYPE_LONGITUDE"), "\u03bb", UnitGroup.UNITS_ANGLE, 37);
75 public static final FlightDataType TYPE_GRAVITY = newType(trans.get("FlightDataType.TYPE_GRAVITY"), "g", UnitGroup.UNITS_ACCELERATION, 38);
79 public static final FlightDataType TYPE_AOA = newType(trans.get("FlightDataType.TYPE_AOA"), "\u03b1", UnitGroup.UNITS_ANGLE, 40);
81 public static final FlightDataType TYPE_ROLL_RATE = newType(trans.get("FlightDataType.TYPE_ROLL_RATE"), "d\u03a6", UnitGroup.UNITS_ROLL, 41);
83 public static final FlightDataType TYPE_PITCH_RATE = newType(trans.get("FlightDataType.TYPE_PITCH_RATE"), "d\u03b8", UnitGroup.UNITS_ROLL, 42);
85 public static final FlightDataType TYPE_YAW_RATE = newType(trans.get("FlightDataType.TYPE_YAW_RATE"), "d\u03a8", UnitGroup.UNITS_ROLL, 43);
88 //// Stability information
90 public static final FlightDataType TYPE_MASS = newType(trans.get("FlightDataType.TYPE_MASS"), "m", UnitGroup.UNITS_MASS, 50);
92 public static final FlightDataType TYPE_PROPELLANT_MASS = newType(trans.get("FlightDataType.TYPE_PROPELLANT_MASS"), "mp", UnitGroup.UNITS_MASS, 51);
93 //// Longitudinal moment of inertia
94 public static final FlightDataType TYPE_LONGITUDINAL_INERTIA = newType(trans.get("FlightDataType.TYPE_LONGITUDINAL_INERTIA"), "Il", UnitGroup.UNITS_INERTIA, 52);
95 //// Rotational moment of inertia
96 public static final FlightDataType TYPE_ROTATIONAL_INERTIA = newType(trans.get("FlightDataType.TYPE_ROTATIONAL_INERTIA"), "Ir", UnitGroup.UNITS_INERTIA, 53);
98 public static final FlightDataType TYPE_CP_LOCATION = newType(trans.get("FlightDataType.TYPE_CP_LOCATION"), "Cp", UnitGroup.UNITS_LENGTH, 54);
100 public static final FlightDataType TYPE_CG_LOCATION = newType(trans.get("FlightDataType.TYPE_CG_LOCATION"), "Cg", UnitGroup.UNITS_LENGTH, 55);
101 //// Stability margin calibers
102 public static final FlightDataType TYPE_STABILITY = newType(trans.get("FlightDataType.TYPE_STABILITY"), "S", UnitGroup.UNITS_COEFFICIENT, 56);
105 //// Characteristic numbers
107 public static final FlightDataType TYPE_MACH_NUMBER = newType(trans.get("FlightDataType.TYPE_MACH_NUMBER"), "M", UnitGroup.UNITS_COEFFICIENT, 60);
109 public static final FlightDataType TYPE_REYNOLDS_NUMBER = newType(trans.get("FlightDataType.TYPE_REYNOLDS_NUMBER"), "R", UnitGroup.UNITS_COEFFICIENT, 61);
114 public static final FlightDataType TYPE_THRUST_FORCE = newType(trans.get("FlightDataType.TYPE_THRUST_FORCE"), "Ft", UnitGroup.UNITS_FORCE, 70);
116 public static final FlightDataType TYPE_DRAG_FORCE = newType(trans.get("FlightDataType.TYPE_DRAG_FORCE"), "Fd", UnitGroup.UNITS_FORCE, 71);
117 //// Drag coefficient
118 public static final FlightDataType TYPE_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_DRAG_COEFF"), "Cd", UnitGroup.UNITS_COEFFICIENT, 72);
119 //// Axial drag coefficient
120 public static final FlightDataType TYPE_AXIAL_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_AXIAL_DRAG_COEFF"), "Cda", UnitGroup.UNITS_COEFFICIENT, 73);
123 //// Component drag coefficients
124 //// Friction drag coefficient
125 public static final FlightDataType TYPE_FRICTION_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_FRICTION_DRAG_COEFF"), "Cdf", UnitGroup.UNITS_COEFFICIENT, 80);
126 //// Pressure drag coefficient
127 public static final FlightDataType TYPE_PRESSURE_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_PRESSURE_DRAG_COEFF"), "Cdp", UnitGroup.UNITS_COEFFICIENT, 81);
128 //// Base drag coefficient
129 public static final FlightDataType TYPE_BASE_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_BASE_DRAG_COEFF"), "Cdb", UnitGroup.UNITS_COEFFICIENT, 82);
132 //// Other coefficients
133 //// Normal force coefficient
134 public static final FlightDataType TYPE_NORMAL_FORCE_COEFF = newType(trans.get("FlightDataType.TYPE_NORMAL_FORCE_COEFF"), "Cn", UnitGroup.UNITS_COEFFICIENT, 90);
135 //// Pitch moment coefficient
136 public static final FlightDataType TYPE_PITCH_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_PITCH_MOMENT_COEFF"), "C\u03b8", UnitGroup.UNITS_COEFFICIENT, 91);
137 //// Yaw moment coefficient
138 public static final FlightDataType TYPE_YAW_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_YAW_MOMENT_COEFF"), "C\u03c4\u03a8", UnitGroup.UNITS_COEFFICIENT, 92);
139 //// Side force coefficient
140 public static final FlightDataType TYPE_SIDE_FORCE_COEFF = newType(trans.get("FlightDataType.TYPE_SIDE_FORCE_COEFF"), "C\u03c4s", UnitGroup.UNITS_COEFFICIENT, 93);
141 //// Roll moment coefficient
142 public static final FlightDataType TYPE_ROLL_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_ROLL_MOMENT_COEFF"), "C\u03c4\u03a6", UnitGroup.UNITS_COEFFICIENT, 94);
143 //// Roll forcing coefficient
144 public static final FlightDataType TYPE_ROLL_FORCING_COEFF = newType(trans.get("FlightDataType.TYPE_ROLL_FORCING_COEFF"), "Cf\u03a6", UnitGroup.UNITS_COEFFICIENT, 95);
145 //// Roll damping coefficient
146 public static final FlightDataType TYPE_ROLL_DAMPING_COEFF = newType(trans.get("FlightDataType.TYPE_ROLL_DAMPING_COEFF"), "C\u03b6\u03a6", UnitGroup.UNITS_COEFFICIENT, 96);
148 //// Pitch damping coefficient
149 public static final FlightDataType TYPE_PITCH_DAMPING_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_PITCH_DAMPING_MOMENT_COEFF"), "C\u03b6\u03b8", UnitGroup.UNITS_COEFFICIENT, 97);
150 //// Yaw damping coefficient
151 public static final FlightDataType TYPE_YAW_DAMPING_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_YAW_DAMPING_MOMENT_COEFF"), "C\u03b6\u03a8", UnitGroup.UNITS_COEFFICIENT, 98);
153 //// Coriolis acceleration
154 public static final FlightDataType TYPE_CORIOLIS_ACCELERATION = newType(trans.get("FlightDataType.TYPE_CORIOLIS_ACCELERATION"), "Ac", UnitGroup.UNITS_ACCELERATION, 99);
157 //// Reference length + area
158 //// Reference length
159 public static final FlightDataType TYPE_REFERENCE_LENGTH = newType(trans.get("FlightDataType.TYPE_REFERENCE_LENGTH"), "Lr", UnitGroup.UNITS_LENGTH, 100);
161 public static final FlightDataType TYPE_REFERENCE_AREA = newType(trans.get("FlightDataType.TYPE_REFERENCE_AREA"), "Ar", UnitGroup.UNITS_AREA, 101);
165 //// Vertical orientation (zenith)
166 public static final FlightDataType TYPE_ORIENTATION_THETA = newType(trans.get("FlightDataType.TYPE_ORIENTATION_THETA"), "\u0398", UnitGroup.UNITS_ANGLE, 106);
167 //// Lateral orientation (azimuth)
168 public static final FlightDataType TYPE_ORIENTATION_PHI = newType(trans.get("FlightDataType.TYPE_ORIENTATION_PHI"), "\u03a6", UnitGroup.UNITS_ANGLE, 107);
171 //// Atmospheric conditions
173 public static final FlightDataType TYPE_WIND_VELOCITY = newType(trans.get("FlightDataType.TYPE_WIND_VELOCITY"), "Vw", UnitGroup.UNITS_VELOCITY, 110);
175 public static final FlightDataType TYPE_AIR_TEMPERATURE = newType(trans.get("FlightDataType.TYPE_AIR_TEMPERATURE"), "T", UnitGroup.UNITS_TEMPERATURE, 111);
177 public static final FlightDataType TYPE_AIR_PRESSURE = newType(trans.get("FlightDataType.TYPE_AIR_PRESSURE"), "P", UnitGroup.UNITS_PRESSURE, 112);
179 public static final FlightDataType TYPE_SPEED_OF_SOUND = newType(trans.get("FlightDataType.TYPE_SPEED_OF_SOUND"), "Vs", UnitGroup.UNITS_VELOCITY, 113);
181 //// Simulation information
182 //// Simulation time step
183 public static final FlightDataType TYPE_TIME_STEP = newType(trans.get("FlightDataType.TYPE_TIME_STEP"), "dt", UnitGroup.UNITS_TIME_STEP, 200);
184 //// Computation time
185 public static final FlightDataType TYPE_COMPUTATION_TIME = newType(trans.get("FlightDataType.TYPE_COMPUTATION_TIME"), "tc", UnitGroup.UNITS_SHORT_TIME, 201);
187 // An array of all the built in types
188 public static final FlightDataType[] ALL_TYPES = {
194 TYPE_ACCELERATION_TOTAL,
198 TYPE_POSITION_DIRECTION,
200 TYPE_ACCELERATION_XY,
209 TYPE_PROPELLANT_MASS,
210 TYPE_LONGITUDINAL_INERTIA,
211 TYPE_ROTATIONAL_INERTIA,
216 TYPE_REYNOLDS_NUMBER,
220 TYPE_AXIAL_DRAG_COEFF,
221 TYPE_FRICTION_DRAG_COEFF,
222 TYPE_PRESSURE_DRAG_COEFF,
223 TYPE_BASE_DRAG_COEFF,
224 TYPE_NORMAL_FORCE_COEFF,
225 TYPE_PITCH_MOMENT_COEFF,
226 TYPE_YAW_MOMENT_COEFF,
227 TYPE_SIDE_FORCE_COEFF,
228 TYPE_ROLL_MOMENT_COEFF,
229 TYPE_ROLL_FORCING_COEFF,
230 TYPE_ROLL_DAMPING_COEFF,
231 TYPE_PITCH_DAMPING_MOMENT_COEFF,
232 TYPE_YAW_DAMPING_MOMENT_COEFF,
233 TYPE_CORIOLIS_ACCELERATION,
234 TYPE_REFERENCE_LENGTH,
236 TYPE_ORIENTATION_THETA,
237 TYPE_ORIENTATION_PHI,
239 TYPE_AIR_TEMPERATURE,
243 TYPE_COMPUTATION_TIME
247 * Return a {@link FlightDataType} with a given string description, symbol and unitgroup.
248 * This returns an existing data type if the symbol matches that of an existing type.
250 * If the symbol matches but the unit and description information differ, then the old stored datatype
251 * is erased and the updated version based on the given parametes is returned.
252 * The only exception is if the description or unitgroup are undefined (null or empty string). In this case
253 * we just get these parameters from the existing type when making the new one.
255 * @param s the string description of the type.
256 * @param u the unit group the new type should belong to if a new group is created.
257 * @return a data type.
259 @SuppressWarnings("null")
260 public static synchronized FlightDataType getType(String s, String symbol, UnitGroup u) {
262 // if symbol is null : try finding by name
263 // if unit is null : don't do anything to the unit if found, just return datatype if found and generate an error and an empty unit otherwise
264 int oldPriority = DEFAULT_PRIORITY;
266 //FlightDataType type = findFromSymbol(symbol);
267 FlightDataType type = EXISTING_TYPES.get(symbol);
270 // found it from symbol
272 // if name was not give (empty string), can use the one we found name
273 if ( s.equals("") || s == null ){
277 u = type.getUnitGroup();
280 // if something has changed, then we need to remove the old one
281 // otherwise, just return what we found
282 if ( !u.equals(type.getUnitGroup()) ||
283 !s.equals(type.getName())
286 oldPriority = type.priority;
288 EXISTING_TYPES.remove(type);
289 log.info("Something changed with the type "+type.getName()+", removed old version.");
297 u = UnitGroup.UNITS_NONE;
298 log.error("Made a new flightdatatype, but did not know what units to use.");
302 type = newType(s, symbol, u, oldPriority);
307 * Get the flightdatatype from existing types based on the symbol.
310 private static FlightDataType findFromSymbol(String symbol){
311 for (FlightDataType t : EXISTING_TYPES.values()){
312 if (t.getSymbol().equals(symbol)){
321 * Used while initializing the class.
323 private static synchronized FlightDataType newType(String s, String symbol, UnitGroup u, int priority) {
324 FlightDataType type = new FlightDataType(s, symbol, u, priority);
325 //EXISTING_TYPES.put(s.toLowerCase(Locale.ENGLISH), type);
326 EXISTING_TYPES.put(symbol, type);
331 private final String name;
332 private final String symbol;
333 private final UnitGroup units;
334 private final int priority;
335 private final int hashCode;
338 private FlightDataType(String typeName, String symbol, UnitGroup units, int priority) {
339 if (typeName == null)
340 throw new IllegalArgumentException("typeName is null");
342 throw new IllegalArgumentException("units is null");
343 this.name = typeName;
344 this.symbol = symbol;
346 this.priority = priority;
347 this.hashCode = this.name.toLowerCase(Locale.ENGLISH).hashCode();
351 public void setPriority(int p){
356 public String getName() {
360 public String getSymbol(){
364 public UnitGroup getUnitGroup() {
369 public String toString() {
370 return name; //+" ("+symbol+") "+units.getDefaultUnit().toString();
374 public boolean equals(Object other) {
375 if (!(other instanceof FlightDataType))
377 return this.name.equalsIgnoreCase(((FlightDataType) other).name);
381 public int hashCode() {
386 public int compareTo(FlightDataType o) {
387 if (this.priority != o.priority)
388 return this.priority - o.priority;
389 return this.name.compareToIgnoreCase(o.name);