Initial commit
[debian/openrocket] / src / net / sf / openrocket / simulation / listeners / CSVSaveListener.java
1 package net.sf.openrocket.simulation.listeners;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.PrintStream;
6 import java.util.Collection;
7 import java.util.Iterator;
8
9 import net.sf.openrocket.rocketcomponent.FinSet;
10 import net.sf.openrocket.rocketcomponent.RocketComponent;
11 import net.sf.openrocket.simulation.FlightDataBranch;
12 import net.sf.openrocket.simulation.FlightEvent;
13 import net.sf.openrocket.simulation.SimulationStatus;
14
15
16 public class CSVSaveListener extends AbstractSimulationListener {
17
18         private static enum Types {
19                 TIME {
20                         @Override
21                         public double getValue(SimulationStatus status) {
22                                 return status.time;
23                         }
24                 },
25                 POSITION_X {
26                         @Override
27                         public double getValue(SimulationStatus status) {
28                                 return status.position.x;
29                         }
30                 },
31                 POSITION_Y {
32                         @Override
33                         public double getValue(SimulationStatus status) {
34                                 return status.position.y;
35                         }
36                 },
37                 ALTITUDE {
38                         @Override
39                         public double getValue(SimulationStatus status) {
40                                 return status.position.z;
41                         }
42                 },
43                 VELOCITY_X {
44                         @Override
45                         public double getValue(SimulationStatus status) {
46                                 return status.velocity.x;
47                         }
48                 },
49                 VELOCITY_Y {
50                         @Override
51                         public double getValue(SimulationStatus status) {
52                                 return status.velocity.y;
53                         }
54                 },
55                 VELOCITY_Z {
56                         @Override
57                         public double getValue(SimulationStatus status) {
58                                 return status.velocity.z;
59                         }
60                 },
61                 THETA {
62                         @Override
63                         public double getValue(SimulationStatus status) {
64                                 return status.flightData.getLast(FlightDataBranch.TYPE_ORIENTATION_THETA);
65                         }
66                 },
67                 PHI {
68                         @Override
69                         public double getValue(SimulationStatus status) {
70                                 return status.flightData.getLast(FlightDataBranch.TYPE_ORIENTATION_PHI);
71                         }
72                 },
73                 AOA {
74                         @Override
75                         public double getValue(SimulationStatus status) {
76                                 return status.flightData.getLast(FlightDataBranch.TYPE_AOA);
77                         }
78                 },
79                 ROLLRATE {
80                         @Override
81                         public double getValue(SimulationStatus status) {
82                                 return status.flightData.getLast(FlightDataBranch.TYPE_ROLL_RATE);
83                         }
84                 },
85                 PITCHRATE {
86                         @Override
87                         public double getValue(SimulationStatus status) {
88                                 return status.flightData.getLast(FlightDataBranch.TYPE_PITCH_RATE);
89                         }
90                 },
91                 
92                 PITCHMOMENT {
93                         @Override
94                         public double getValue(SimulationStatus status) {
95                                 return status.flightData.getLast(FlightDataBranch.TYPE_PITCH_MOMENT_COEFF);
96                         }
97                 },
98                 YAWMOMENT {
99                         @Override
100                         public double getValue(SimulationStatus status) {
101                                 return status.flightData.getLast(FlightDataBranch.TYPE_YAW_MOMENT_COEFF);
102                         }
103                 },
104                 ROLLMOMENT {
105                         @Override
106                         public double getValue(SimulationStatus status) {
107                                 return status.flightData.getLast(FlightDataBranch.TYPE_ROLL_MOMENT_COEFF);
108                         }
109                 },
110                 NORMALFORCE {
111                         @Override
112                         public double getValue(SimulationStatus status) {
113                                 return status.flightData.getLast(FlightDataBranch.TYPE_NORMAL_FORCE_COEFF);
114                         }
115                 },
116                 SIDEFORCE {
117                         @Override
118                         public double getValue(SimulationStatus status) {
119                                 return status.flightData.getLast(FlightDataBranch.TYPE_SIDE_FORCE_COEFF);
120                         }
121                 },
122                 AXIALFORCE {
123                         @Override
124                         public double getValue(SimulationStatus status) {
125                                 return status.flightData.getLast(FlightDataBranch.TYPE_DRAG_FORCE);
126                         }
127                 },
128                 WINDSPEED {
129                         @Override
130                         public double getValue(SimulationStatus status) {
131                                 return status.flightData.getLast(FlightDataBranch.TYPE_WIND_VELOCITY);
132                         }
133                 },
134                 PITCHDAMPING {
135                         @Override
136                         public double getValue(SimulationStatus status) {
137                                 return status.flightData.getLast(FlightDataBranch.
138                                                 TYPE_PITCH_DAMPING_MOMENT_COEFF);
139                         }
140                 },
141                 CA {
142                         @Override
143                         public double getValue(SimulationStatus status) {
144                                 return status.flightData.getLast(FlightDataBranch.TYPE_AXIAL_DRAG_COEFF);
145                         }
146                 },
147                 CD {
148                         @Override
149                         public double getValue(SimulationStatus status) {
150                                 return status.flightData.getLast(FlightDataBranch.TYPE_DRAG_COEFF);
151                         }
152                 },
153                 CDpressure {
154                         @Override
155                         public double getValue(SimulationStatus status) {
156                                 return status.flightData.getLast(FlightDataBranch.TYPE_PRESSURE_DRAG_COEFF);
157                         }
158                 },
159                 CDfriction {
160                         @Override
161                         public double getValue(SimulationStatus status) {
162                                 return status.flightData.getLast(FlightDataBranch.TYPE_FRICTION_DRAG_COEFF);
163                         }
164                 },
165                 CDbase {
166                         @Override
167                         public double getValue(SimulationStatus status) {
168                                 return status.flightData.getLast(FlightDataBranch.TYPE_BASE_DRAG_COEFF);
169                         }
170                 },
171                 MACH {
172                         @Override
173                         public double getValue(SimulationStatus status) {
174                                 return status.flightData.getLast(FlightDataBranch.TYPE_MACH_NUMBER);
175                         }
176                 },
177                 RE {
178                         @Override
179                         public double getValue(SimulationStatus status) {
180                                 return status.flightData.getLast(FlightDataBranch.TYPE_REYNOLDS_NUMBER);
181                         }
182                 },
183                 
184                 CONTROL_ANGLE {
185                         @Override
186                         public double getValue(SimulationStatus status) {
187                                 Iterator<RocketComponent> iterator = 
188                                         status.configuration.getRocket().deepIterator();
189                                 FinSet fin = null;
190                                 
191                                 while (iterator.hasNext()) {
192                                         RocketComponent c = iterator.next();
193                                         if (c instanceof FinSet && c.getName().equals("CONTROL")) {
194                                                 fin = (FinSet)c;
195                                                 break;
196                                         }
197                                 }
198                                 if (fin==null)
199                                         return 0;
200                                 return fin.getCantAngle();
201                         }
202                 },
203                 
204                 EXTRA {
205                         @Override
206                         public double getValue(SimulationStatus status) {
207                                 if (status.extra instanceof Double)
208                                         return (Double)status.extra;
209                                 else
210                                         return Double.NaN;
211                         }
212                 },
213                 
214                 MASS {
215                         @Override
216                         public double getValue(SimulationStatus status) {
217                                 return status.flightData.getLast(FlightDataBranch.TYPE_MASS);
218                         }
219                 }
220                 
221                 ;
222                 
223                 public abstract double getValue(SimulationStatus status);
224         }
225         
226         
227         public static final String FILENAME_FORMAT = "simulation-%03d.csv";
228         
229         private File file;
230         private PrintStream output = null;
231         
232                 
233         
234         @Override
235         public Collection<FlightEvent> handleEvent(FlightEvent event,
236                         SimulationStatus status) {
237
238                 if (event.getType() == FlightEvent.Type.LAUNCH) {
239                         int n = 1;
240
241                         if (output != null) {
242                                 System.err.println("WARNING: Ending simulation logging to CSV file " +
243                                                 "(SIMULATION_END not encountered).");
244                                 output.close();
245                                 output = null;
246                         }
247                         
248                         do {
249                                 file = new File(String.format(FILENAME_FORMAT, n));
250                                 n++;
251                         } while (file.exists());
252                         
253                         System.err.println("Opening file "+file+" for CSV output.");
254                         try {
255                                 output = new PrintStream(file);
256                         } catch (FileNotFoundException e) {
257                                 System.err.println("ERROR OPENING FILE: "+e);
258                         }
259                         
260                         final Types[] types = Types.values();
261                         StringBuilder s = new StringBuilder("# " + types[0].toString());
262                         for (int i=1; i<types.length; i++) {
263                                 s.append("," + types[i].toString());
264                         }
265                         output.println(s);
266                         
267                 } else if (event.getType() == FlightEvent.Type.SIMULATION_END && output != null) {
268                         
269                         System.err.println("Ending simulation logging to CSV file: "+file);
270                         output.close();
271                         output = null;
272                         
273                 } else if (event.getType() != FlightEvent.Type.ALTITUDE){
274                         
275                         if (output != null) {
276                                 output.println("# Event "+event);
277                         } else {
278                                 System.err.println("WARNING: Event "+event+" encountered without open file");
279                         }
280                         
281                 }
282                 
283                 return null;
284         }
285
286         
287         @Override
288         public Collection<FlightEvent> stepTaken(SimulationStatus status) {
289
290                 final Types[] types = Types.values();
291                 StringBuilder s;
292                 
293                 if (output != null) {
294                         
295                         s = new StringBuilder("" + types[0].getValue(status));
296                         for (int i=1; i<types.length; i++) {
297                                 s.append("," + types[i].getValue(status));
298                         }
299                         output.println(s);
300                 
301                 } else {
302                         
303                         System.err.println("WARNING: stepTaken called with no open file " +
304                                         "(t="+status.time+")");
305                 }
306
307                 return null;
308         }
309 }