altos: Check for full log and complain
[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("Altitude")
105                     .addElement(height) );
106     
107             graphs.add( myAltosGraphTime("Speed")
108                     .addElement(speed) );
109     
110             graphs.add( myAltosGraphTime("Acceleration")
111                     .addElement(acceleration) );
112     
113             graphs.add( myAltosGraphTime("Temperature")
114                     .addElement(temperature) );
115     
116             graphs.add( myAltosGraphTime("Continuity")
117                     .addElement(drogue_voltage)
118                     .addElement(main_voltage) );
119     
120             return graphs;
121         }
122     }
123     
124     static private class AscentGraphs extends OverallGraphs {
125         protected AltosGraphTime myAltosGraphTime(String suffix) {
126             return (new AltosGraphTime("Ascent " + suffix) {
127                 public void addData(AltosDataPoint d) {
128                     int state = d.state();
129                     if (Altos.ao_flight_boost <= state && state <= Altos.ao_flight_coast) {
130                         super.addData(d);
131                     }
132                 }
133             }).addElement(e_boost)
134               .addElement(e_fast)
135               .addElement(e_coast);
136         }
137     }
138     
139     static private class DescentGraphs extends OverallGraphs {
140         protected AltosGraphTime myAltosGraphTime(String suffix) {
141             return (new AltosGraphTime("Descent " + suffix) {
142                 public void addData(AltosDataPoint d) {
143                     int state = d.state();
144                     if (Altos.ao_flight_drogue <= state && state <= Altos.ao_flight_main) {
145                         super.addData(d);
146                     }
147                 }
148             }).addElement(e_drogue)
149               .addElement(e_main);
150             // ((XYGraph)graph[8]).ymin = new Double(-50);
151         }
152     }
153
154         public AltosGraphUI(AltosRecordIterable records) {
155                 super("Altos Graph");
156
157                 Iterable<AltosDataPoint> reader = new AltosDataPointReader (records);
158                 if (reader == null)
159                         return;
160         
161                 init(reader, 0);
162         }
163
164     public AltosGraphUI(Iterable<AltosDataPoint> data, int which) 
165     {
166         super("Altos Graph");
167         init(data, which);
168     }
169
170     private void init(Iterable<AltosDataPoint> data, int which) {
171         AltosGraph graph = createGraph(data, which);
172
173         JFreeChart chart = graph.createChart();
174         ChartPanel chartPanel = new ChartPanel(chart);
175         chartPanel.setMouseWheelEnabled(true);
176         chartPanel.setPreferredSize(new java.awt.Dimension(800, 500));
177         setContentPane(chartPanel);
178
179         pack();
180
181         RefineryUtilities.centerFrameOnScreen(this);
182
183         setDefaultCloseOperation(DISPOSE_ON_CLOSE);
184         setVisible(true);
185     }
186
187     private static AltosGraph createGraph(Iterable<AltosDataPoint> data,
188             int which)
189     {
190         return createGraphsWhich(data, which).get(0);
191     }
192
193     private static ArrayList<AltosGraph> createGraphs(
194             Iterable<AltosDataPoint> data)
195     {
196         return createGraphsWhich(data, -1);
197     }
198
199     private static ArrayList<AltosGraph> createGraphsWhich(
200             Iterable<AltosDataPoint> data, int which)
201     {
202         ArrayList<AltosGraph> graph = new ArrayList<AltosGraph>();
203         graph.addAll((new OverallGraphs()).graphs());
204         graph.addAll((new AscentGraphs()).graphs());
205         graph.addAll((new DescentGraphs()).graphs());
206
207         if (which > 0) {
208             if (which >= graph.size()) {
209                 which = 0;
210             }
211             AltosGraph g = graph.get(which);
212             graph = new ArrayList<AltosGraph>();
213             graph.add(g);
214         }
215
216         for (AltosDataPoint dp : data) {
217             for (AltosGraph g : graph) {
218                 g.addData(dp);
219             }
220         }
221
222         return graph;
223     }
224 }
225
226 /* gnuplot bits...
227  *
228 300x400
229
230 --------------------------------------------------------
231 TOO HARD! :)
232
233 "ascent-gps-accuracy.png" "Vertical error margin to apogee - GPS v Baro (m)"
234     5:($7 < 6 ? $24-$11 : 1/0)
235 "descent-gps-accuracy.png" "Vertical error margin during descent - GPS v Baro (m)"
236     5:($7 < 6 ? 1/0 : $24-$11)
237
238 set output "overall-gps-accuracy.png"
239 set ylabel "distance above sea level (m)"
240 plot "telemetry.csv" using 5:11 with lines ti "baro altitude" axis x1y1, \
241     "telemetry.csv" using 5:24 with lines ti "gps altitude" axis x1y1
242
243 set term png tiny size 700,700 enhanced
244 set xlabel "m"
245 set ylabel "m"
246 set polar
247 set grid polar
248 set rrange[*:*]
249 set angles degrees
250
251 set output "overall-gps-path.png"
252 #:30 with yerrorlines
253 plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0) with lines ti "pad", \
254     "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0) with lines ti "boost", \
255     "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0) with lines ti "fast", \
256     "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0) with lines ti "coast", \
257     "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \
258     "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \
259     "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed"
260
261 set output "ascent-gps-path.png"
262 plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0):30 with lines ti "pad", \
263     "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0):20 with lines ti "boost", \
264     "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0):10 with lines ti "fast", \
265     "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0):5 with lines ti "coast"
266
267 set output "descent-gps-path.png"
268 plot "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \
269     "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \
270     "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed"
271
272  */
273
274