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