1 package net.sf.openrocket.simulation.listeners;
4 import java.io.FileNotFoundException;
5 import java.io.PrintStream;
6 import java.util.Collection;
7 import java.util.Iterator;
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;
16 public class CSVSaveListener extends AbstractSimulationListener {
18 private static enum Types {
21 public double getValue(SimulationStatus status) {
27 public double getValue(SimulationStatus status) {
28 return status.position.x;
33 public double getValue(SimulationStatus status) {
34 return status.position.y;
39 public double getValue(SimulationStatus status) {
40 return status.position.z;
45 public double getValue(SimulationStatus status) {
46 return status.velocity.x;
51 public double getValue(SimulationStatus status) {
52 return status.velocity.y;
57 public double getValue(SimulationStatus status) {
58 return status.velocity.z;
63 public double getValue(SimulationStatus status) {
64 return status.flightData.getLast(FlightDataBranch.TYPE_ORIENTATION_THETA);
69 public double getValue(SimulationStatus status) {
70 return status.flightData.getLast(FlightDataBranch.TYPE_ORIENTATION_PHI);
75 public double getValue(SimulationStatus status) {
76 return status.flightData.getLast(FlightDataBranch.TYPE_AOA);
81 public double getValue(SimulationStatus status) {
82 return status.flightData.getLast(FlightDataBranch.TYPE_ROLL_RATE);
87 public double getValue(SimulationStatus status) {
88 return status.flightData.getLast(FlightDataBranch.TYPE_PITCH_RATE);
94 public double getValue(SimulationStatus status) {
95 return status.flightData.getLast(FlightDataBranch.TYPE_PITCH_MOMENT_COEFF);
100 public double getValue(SimulationStatus status) {
101 return status.flightData.getLast(FlightDataBranch.TYPE_YAW_MOMENT_COEFF);
106 public double getValue(SimulationStatus status) {
107 return status.flightData.getLast(FlightDataBranch.TYPE_ROLL_MOMENT_COEFF);
112 public double getValue(SimulationStatus status) {
113 return status.flightData.getLast(FlightDataBranch.TYPE_NORMAL_FORCE_COEFF);
118 public double getValue(SimulationStatus status) {
119 return status.flightData.getLast(FlightDataBranch.TYPE_SIDE_FORCE_COEFF);
124 public double getValue(SimulationStatus status) {
125 return status.flightData.getLast(FlightDataBranch.TYPE_DRAG_FORCE);
130 public double getValue(SimulationStatus status) {
131 return status.flightData.getLast(FlightDataBranch.TYPE_WIND_VELOCITY);
136 public double getValue(SimulationStatus status) {
137 return status.flightData.getLast(FlightDataBranch.
138 TYPE_PITCH_DAMPING_MOMENT_COEFF);
143 public double getValue(SimulationStatus status) {
144 return status.flightData.getLast(FlightDataBranch.TYPE_AXIAL_DRAG_COEFF);
149 public double getValue(SimulationStatus status) {
150 return status.flightData.getLast(FlightDataBranch.TYPE_DRAG_COEFF);
155 public double getValue(SimulationStatus status) {
156 return status.flightData.getLast(FlightDataBranch.TYPE_PRESSURE_DRAG_COEFF);
161 public double getValue(SimulationStatus status) {
162 return status.flightData.getLast(FlightDataBranch.TYPE_FRICTION_DRAG_COEFF);
167 public double getValue(SimulationStatus status) {
168 return status.flightData.getLast(FlightDataBranch.TYPE_BASE_DRAG_COEFF);
173 public double getValue(SimulationStatus status) {
174 return status.flightData.getLast(FlightDataBranch.TYPE_MACH_NUMBER);
179 public double getValue(SimulationStatus status) {
180 return status.flightData.getLast(FlightDataBranch.TYPE_REYNOLDS_NUMBER);
186 public double getValue(SimulationStatus status) {
187 Iterator<RocketComponent> iterator =
188 status.configuration.getRocket().deepIterator();
191 while (iterator.hasNext()) {
192 RocketComponent c = iterator.next();
193 if (c instanceof FinSet && c.getName().equals("CONTROL")) {
200 return fin.getCantAngle();
206 public double getValue(SimulationStatus status) {
207 if (status.extra instanceof Double)
208 return (Double)status.extra;
216 public double getValue(SimulationStatus status) {
217 return status.flightData.getLast(FlightDataBranch.TYPE_MASS);
223 public abstract double getValue(SimulationStatus status);
227 public static final String FILENAME_FORMAT = "simulation-%03d.csv";
230 private PrintStream output = null;
235 public Collection<FlightEvent> handleEvent(FlightEvent event,
236 SimulationStatus status) {
238 if (event.getType() == FlightEvent.Type.LAUNCH) {
241 if (output != null) {
242 System.err.println("WARNING: Ending simulation logging to CSV file " +
243 "(SIMULATION_END not encountered).");
249 file = new File(String.format(FILENAME_FORMAT, n));
251 } while (file.exists());
253 System.err.println("Opening file "+file+" for CSV output.");
255 output = new PrintStream(file);
256 } catch (FileNotFoundException e) {
257 System.err.println("ERROR OPENING FILE: "+e);
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());
267 } else if (event.getType() == FlightEvent.Type.SIMULATION_END && output != null) {
269 System.err.println("Ending simulation logging to CSV file: "+file);
273 } else if (event.getType() != FlightEvent.Type.ALTITUDE){
275 if (output != null) {
276 output.println("# Event "+event);
278 System.err.println("WARNING: Event "+event+" encountered without open file");
288 public Collection<FlightEvent> stepTaken(SimulationStatus status) {
290 final Types[] types = Types.values();
293 if (output != null) {
295 s = new StringBuilder("" + types[0].getValue(status));
296 for (int i=1; i<types.length; i++) {
297 s.append("," + types[i].getValue(status));
303 System.err.println("WARNING: stepTaken called with no open file " +
304 "(t="+status.time+")");