altos: Clean up serial initialization
[fw/altos] / altosui / AltosGraphUI.java
1
2 // Copyright (c) 2010 Anthony Towns
3 // GPL v2 or later
4
5 package altosui;
6
7 import java.io.*;
8 import java.util.ArrayList;
9
10 import javax.swing.JFrame;
11 import java.awt.Color;
12
13 import org.jfree.chart.ChartPanel;
14 import org.jfree.chart.ChartUtilities;
15 import org.jfree.chart.JFreeChart;
16 import org.jfree.chart.axis.AxisLocation;
17 import org.jfree.ui.ApplicationFrame;
18 import org.jfree.ui.RefineryUtilities;
19
20 public class AltosGraphUI extends JFrame 
21 {
22     static final private Color red = new Color(194,31,31);
23     static final private Color green = new Color(31,194,31);
24     static final private Color blue = new Color(31,31,194);
25     static final private Color black = new Color(31,31,31);
26
27     static private class OverallGraphs {
28         AltosGraphTime.Element height = 
29             new AltosGraphTime.TimeSeries("Height (m)", "Height (AGL)", red) {
30                 public void gotTimeData(double time, AltosDataPoint d) {
31                     series.add(time, d.height()); 
32                 } 
33             };
34     
35         AltosGraphTime.Element speed =
36             new AltosGraphTime.TimeSeries("Speed (m/s)", "Vertical Speed", green) { 
37                 public void gotTimeData(double time, AltosDataPoint d) {
38                     if (d.state() < Altos.ao_flight_drogue) {
39                         series.add(time, d.accel_speed());
40                     } else {
41                         series.add(time, d.baro_speed());
42                     }
43                 }
44             };
45     
46         AltosGraphTime.Element acceleration =
47             new AltosGraphTime.TimeSeries("Acceleration (m/s\u00B2)", 
48                     "Axial Acceleration", blue) 
49             {
50                 public void gotTimeData(double time, AltosDataPoint d) {
51                     series.add(time, d.acceleration());
52                 }
53             };
54     
55         AltosGraphTime.Element temperature =
56             new AltosGraphTime.TimeSeries("Temperature (\u00B0C)", 
57                     "Board temperature", red) 
58             {
59                 public void gotTimeData(double time, AltosDataPoint d) {
60                     series.add(time, d.temperature());
61                 }
62             };
63     
64         AltosGraphTime.Element drogue_voltage =
65             new AltosGraphTime.TimeSeries("Voltage (V)", "Drogue Continuity", blue) 
66             {
67                 public void gotTimeData(double time, AltosDataPoint d) {
68                     series.add(time, d.drogue_voltage());
69                 }
70             };
71     
72         AltosGraphTime.Element main_voltage =
73             new AltosGraphTime.TimeSeries("Voltage (V)", "Main Continuity", green) 
74             {
75                 public void gotTimeData(double time, AltosDataPoint d) {
76                     series.add(time, d.main_voltage());
77                 }
78             };
79     
80         AltosGraphTime.Element e_pad    = new AltosGraphTime.StateMarker(Altos.ao_flight_pad, "Pad");
81         AltosGraphTime.Element e_boost  = new AltosGraphTime.StateMarker(Altos.ao_flight_boost, "Boost");
82         AltosGraphTime.Element e_fast   = new AltosGraphTime.StateMarker(Altos.ao_flight_fast, "Fast");
83         AltosGraphTime.Element e_coast  = new AltosGraphTime.StateMarker(Altos.ao_flight_coast, "Coast");
84         AltosGraphTime.Element e_drogue = new AltosGraphTime.StateMarker(Altos.ao_flight_drogue, "Drogue");
85         AltosGraphTime.Element e_main   = new AltosGraphTime.StateMarker(Altos.ao_flight_main, "Main");
86         AltosGraphTime.Element e_landed = new AltosGraphTime.StateMarker(Altos.ao_flight_landed, "Landed");
87     
88         protected AltosGraphTime myAltosGraphTime(String suffix) {
89             return (new AltosGraphTime("Overall " + suffix))
90                 .addElement(e_boost)
91                 .addElement(e_drogue)
92                 .addElement(e_main)
93                 .addElement(e_landed);
94         }
95     
96         public ArrayList<AltosGraph> graphs() {
97             ArrayList<AltosGraph> graphs = new ArrayList<AltosGraph>();
98     
99             graphs.add( myAltosGraphTime("Summary")
100                         .addElement(height)
101                         .addElement(speed)
102                         .addElement(acceleration) );
103
104             graphs.add( myAltosGraphTime("Summary")
105                         .addElement(height)
106                         .addElement(speed));
107     
108             graphs.add( myAltosGraphTime("Altitude")
109                     .addElement(height) );
110     
111             graphs.add( myAltosGraphTime("Speed")
112                     .addElement(speed) );
113     
114             graphs.add( myAltosGraphTime("Acceleration")
115                         .addElement(acceleration) );
116     
117             graphs.add( myAltosGraphTime("Temperature")
118                     .addElement(temperature) );
119     
120             graphs.add( myAltosGraphTime("Continuity")
121                         .addElement(drogue_voltage)
122                         .addElement(main_voltage) );
123     
124             return graphs;
125         }
126     }
127     
128     static private class AscentGraphs extends OverallGraphs {
129         protected AltosGraphTime myAltosGraphTime(String suffix) {
130             return (new AltosGraphTime("Ascent " + suffix) {
131                 public void addData(AltosDataPoint d) {
132                     int state = d.state();
133                     if (Altos.ao_flight_boost <= state && state <= Altos.ao_flight_coast) {
134                         super.addData(d);
135                     }
136                 }
137             }).addElement(e_boost)
138               .addElement(e_fast)
139               .addElement(e_coast);
140         }
141     }
142     
143     static private class DescentGraphs extends OverallGraphs {
144         protected AltosGraphTime myAltosGraphTime(String suffix) {
145             return (new AltosGraphTime("Descent " + suffix) {
146                 public void addData(AltosDataPoint d) {
147                     int state = d.state();
148                     if (Altos.ao_flight_drogue <= state && state <= Altos.ao_flight_main) {
149                         super.addData(d);
150                     }
151                 }
152             }).addElement(e_drogue)
153               .addElement(e_main);
154             // ((XYGraph)graph[8]).ymin = new Double(-50);
155         }
156     }
157
158         public AltosGraphUI(AltosRecordIterable records) {
159                 super("Altos Graph");
160
161                 AltosDataPointReader reader = new AltosDataPointReader (records);
162                 if (reader == null)
163                         return;
164         
165                 if (reader.has_accel)
166                         init(reader, 0);
167                 else
168                         init(reader, 1);
169         }
170
171     public AltosGraphUI(AltosDataPointReader data, int which)
172     {
173         super("Altos Graph");
174         init(data, which);
175     }
176
177     private void init(AltosDataPointReader data, int which) {
178         AltosGraph graph = createGraph(data, which);
179
180         JFreeChart chart = graph.createChart();
181         ChartPanel chartPanel = new ChartPanel(chart);
182         chartPanel.setMouseWheelEnabled(true);
183         chartPanel.setPreferredSize(new java.awt.Dimension(800, 500));
184         setContentPane(chartPanel);
185
186         pack();
187
188         RefineryUtilities.centerFrameOnScreen(this);
189
190         setDefaultCloseOperation(DISPOSE_ON_CLOSE);
191         setVisible(true);
192     }
193
194     private static AltosGraph createGraph(Iterable<AltosDataPoint> data,
195             int which)
196     {
197         return createGraphsWhich(data, which).get(0);
198     }
199
200     private static ArrayList<AltosGraph> createGraphs(
201             Iterable<AltosDataPoint> data)
202     {
203         return createGraphsWhich(data, -1);
204     }
205
206     private static ArrayList<AltosGraph> createGraphsWhich(
207             Iterable<AltosDataPoint> data, int which)
208     {
209         ArrayList<AltosGraph> graph = new ArrayList<AltosGraph>();
210         graph.addAll((new OverallGraphs()).graphs());
211         graph.addAll((new AscentGraphs()).graphs());
212         graph.addAll((new DescentGraphs()).graphs());
213
214         if (which > 0) {
215             if (which >= graph.size()) {
216                 which = 0;
217             }
218             AltosGraph g = graph.get(which);
219             graph = new ArrayList<AltosGraph>();
220             graph.add(g);
221         }
222
223         for (AltosDataPoint dp : data) {
224             for (AltosGraph g : graph) {
225                 g.addData(dp);
226             }
227         }
228
229         return graph;
230     }
231 }
232
233 /* gnuplot bits...
234  *
235 300x400
236
237 --------------------------------------------------------
238 TOO HARD! :)
239
240 "ascent-gps-accuracy.png" "Vertical error margin to apogee - GPS v Baro (m)"
241     5:($7 < 6 ? $24-$11 : 1/0)
242 "descent-gps-accuracy.png" "Vertical error margin during descent - GPS v Baro (m)"
243     5:($7 < 6 ? 1/0 : $24-$11)
244
245 set output "overall-gps-accuracy.png"
246 set ylabel "distance above sea level (m)"
247 plot "telemetry.csv" using 5:11 with lines ti "baro altitude" axis x1y1, \
248     "telemetry.csv" using 5:24 with lines ti "gps altitude" axis x1y1
249
250 set term png tiny size 700,700 enhanced
251 set xlabel "m"
252 set ylabel "m"
253 set polar
254 set grid polar
255 set rrange[*:*]
256 set angles degrees
257
258 set output "overall-gps-path.png"
259 #:30 with yerrorlines
260 plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0) with lines ti "pad", \
261     "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0) with lines ti "boost", \
262     "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0) with lines ti "fast", \
263     "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0) with lines ti "coast", \
264     "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \
265     "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \
266     "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed"
267
268 set output "ascent-gps-path.png"
269 plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0):30 with lines ti "pad", \
270     "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0):20 with lines ti "boost", \
271     "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0):10 with lines ti "fast", \
272     "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0):5 with lines ti "coast"
273
274 set output "descent-gps-path.png"
275 plot "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \
276     "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \
277     "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed"
278
279  */
280
281