8d0307c6b4cd5216ebd7cd0bdd9d20aae7b344b5
[debian/openrocket] / src / net / sf / openrocket / simulation / FlightData.java
1 package net.sf.openrocket.simulation;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import net.sf.openrocket.aerodynamics.WarningSet;
7 import net.sf.openrocket.util.MathUtil;
8
9
10 public class FlightData {
11         
12         /**
13          * An immutable FlightData object with NaN data.
14          */
15         public static final FlightData NaN_DATA;
16         static {
17                 FlightData data = new FlightData();
18                 data.immute();
19                 NaN_DATA = data;
20         }
21
22         private boolean mutable = true;
23         private final ArrayList<FlightDataBranch> branches = new ArrayList<FlightDataBranch>();
24         
25         private final WarningSet warnings = new WarningSet();
26         
27         private double maxAltitude = Double.NaN;
28         private double maxVelocity = Double.NaN;
29         private double maxAcceleration = Double.NaN;
30         private double maxMachNumber = Double.NaN;
31         private double timeToApogee = Double.NaN;
32         private double flightTime = Double.NaN;
33         private double groundHitVelocity = Double.NaN;
34
35         
36         /**
37          * Create a FlightData object with no content.  The resulting object is mutable.
38          */
39         public FlightData() {
40                 
41         }
42         
43         
44         /**
45          * Construct an immutable FlightData object with no data branches but the specified
46          * summary information.
47          * 
48          * @param maxAltitude                   maximum altitude.
49          * @param maxVelocity                   maximum velocity.
50          * @param maxAcceleration               maximum acceleration.
51          * @param maxMachNumber                 maximum Mach number.
52          * @param timeToApogee                  time to apogee.
53          * @param flightTime                    total flight time.
54          * @param groundHitVelocity             ground hit velocity.
55          */
56         public FlightData(double maxAltitude, double maxVelocity, double maxAcceleration,
57                         double maxMachNumber, double timeToApogee, double flightTime,
58                         double groundHitVelocity) {
59                 this.maxAltitude = maxAltitude;
60                 this.maxVelocity = maxVelocity;
61                 this.maxAcceleration = maxAcceleration;
62                 this.maxMachNumber = maxMachNumber;
63                 this.timeToApogee = timeToApogee;
64                 this.flightTime = flightTime;
65                 this.groundHitVelocity = groundHitVelocity;
66                 
67                 this.immute();
68         }
69
70
71         /**
72          * Create an immutable FlightData object with the specified branches.
73          * 
74          * @param branches      the branches.
75          */
76         public FlightData(FlightDataBranch ... branches) {
77                 this();
78                 
79                 for (FlightDataBranch b: branches)
80                         this.addBranch(b);
81                 
82                 calculateIntrestingValues();
83                 this.immute();
84         }
85         
86         
87         
88         
89         /**
90          * Returns the warning set associated with this object.  This WarningSet cannot be
91          * set, so simulations must use this warning set to store their warnings.
92          * The returned WarningSet should not be modified otherwise.
93          * 
94          * @return      the warnings generated during this simulation.
95          */
96         public WarningSet getWarningSet() {
97                 return warnings;
98         }
99         
100         
101         public void addBranch(FlightDataBranch branch) {
102                 if (!mutable)
103                         throw new IllegalStateException("FlightData has been made immutable");
104
105                 branch.immute();
106                 branches.add(branch);
107                 
108                 if (branches.size() == 1) {
109                         calculateIntrestingValues();
110                 }
111         }
112
113         public int getBranchCount() {
114                 return branches.size();
115         }
116         
117         public FlightDataBranch getBranch(int n) {
118                 return branches.get(n);
119         }
120         
121         
122         
123         public double getMaxAltitude() {
124                 return maxAltitude;
125         }
126         
127         public double getMaxVelocity() {
128                 return maxVelocity;
129         }
130         
131         public double getMaxAcceleration() {
132                 return maxAcceleration;
133         }
134         
135         public double getMaxMachNumber() {
136                 return maxMachNumber;
137         }
138         
139         public double getTimeToApogee() {
140                 return timeToApogee;
141         }
142         
143         public double getFlightTime() {
144                 return flightTime;
145         }
146         
147         public double getGroundHitVelocity() {
148                 return groundHitVelocity;
149         }
150         
151         
152         
153         /**
154          * Calculate the max. altitude/velocity/acceleration, time to apogee, flight time
155          * and ground hit velocity.
156          */
157         private void calculateIntrestingValues() {
158                 if (branches.isEmpty())
159                         return;
160                 
161                 FlightDataBranch branch = branches.get(0);
162                 maxAltitude = branch.getMaximum(FlightDataBranch.TYPE_ALTITUDE);
163                 maxVelocity = branch.getMaximum(FlightDataBranch.TYPE_VELOCITY_TOTAL);
164                 maxAcceleration = branch.getMaximum(FlightDataBranch.TYPE_ACCELERATION_TOTAL);
165                 maxMachNumber = branch.getMaximum(FlightDataBranch.TYPE_MACH_NUMBER);
166
167                 flightTime = branch.getLast(FlightDataBranch.TYPE_TIME);
168                 if (branch.getLast(FlightDataBranch.TYPE_ALTITUDE) < 10) {
169                         groundHitVelocity = branch.getLast(FlightDataBranch.TYPE_VELOCITY_TOTAL);
170                 } else {
171                         groundHitVelocity = Double.NaN;
172                 }
173                 
174                 // Time to apogee
175                 List<Double> time = branch.get(FlightDataBranch.TYPE_TIME);
176                 List<Double> altitude = branch.get(FlightDataBranch.TYPE_ALTITUDE);
177                 
178                 if (time == null || altitude == null) {
179                         timeToApogee = Double.NaN;
180                         return;
181                 }
182                 int index = 0;
183                 for (Double alt: altitude) {
184                         if (alt != null) {
185                                 if (MathUtil.equals(alt, maxAltitude))
186                                         break;
187                         }
188
189                         index++;
190                 }
191                 if (index < time.size())
192                         timeToApogee = time.get(index);
193                 else
194                         timeToApogee = Double.NaN;
195         }
196
197
198         public void immute() {
199                 mutable = false;
200         }
201         public boolean isMutable() {
202                 return mutable;
203         }
204         
205         
206 }