2 // Copyright (c) 2010 Anthony Towns
8 import java.util.ArrayList;
10 import javax.swing.JFrame;
11 import java.awt.Color;
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;
20 public class AltosGraphUI extends JFrame
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);
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());
37 AltosGraphTime.Element speed =
38 new AltosGraphTime.TimeSeries("Speed (m/s)", "Vertical Speed", green) {
39 public void gotTimeData(double time, AltosDataPoint d) {
41 if (d.state() < Altos.ao_flight_drogue && d.has_accel()) {
42 speed = d.accel_speed();
44 speed = d.baro_speed();
46 if (speed != AltosRecord.MISSING)
47 series.add(time, speed);
51 AltosGraphTime.Element acceleration =
52 new AltosGraphTime.TimeSeries("Acceleration (m/s\u00B2)",
53 "Axial Acceleration", blue)
55 public void gotTimeData(double time, AltosDataPoint d) {
56 double acceleration = d.acceleration();
57 if (acceleration != AltosRecord.MISSING)
58 series.add(time, acceleration);
62 AltosGraphTime.Element temperature =
63 new AltosGraphTime.TimeSeries("Temperature (\u00B0C)",
64 "Board temperature", red)
66 public void gotTimeData(double time, AltosDataPoint d) {
67 double temp = d.temperature();
68 if (temp != AltosRecord.MISSING)
69 series.add(time, d.temperature());
73 AltosGraphTime.Element drogue_voltage =
74 new AltosGraphTime.TimeSeries("Voltage (V)", "Drogue Continuity", blue)
76 public void gotTimeData(double time, AltosDataPoint d) {
77 double v = d.drogue_voltage();
78 if (v != AltosRecord.MISSING)
83 AltosGraphTime.Element main_voltage =
84 new AltosGraphTime.TimeSeries("Voltage (V)", "Main Continuity", green)
86 public void gotTimeData(double time, AltosDataPoint d) {
87 double v = d.main_voltage();
88 if (v != AltosRecord.MISSING)
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");
101 protected AltosGraphTime myAltosGraphTime(String suffix) {
102 return (new AltosGraphTime("Overall " + suffix))
104 .addElement(e_drogue)
106 .addElement(e_landed);
109 public ArrayList<AltosGraph> graphs() {
110 ArrayList<AltosGraph> graphs = new ArrayList<AltosGraph>();
112 graphs.add( myAltosGraphTime("Summary")
115 .addElement(acceleration)
116 .addElement(drogue_voltage)
117 .addElement(main_voltage) );
119 graphs.add( myAltosGraphTime("Summary")
123 graphs.add( myAltosGraphTime("Altitude")
124 .addElement(height) );
126 graphs.add( myAltosGraphTime("Speed")
127 .addElement(speed) );
129 graphs.add( myAltosGraphTime("Acceleration")
130 .addElement(acceleration) );
132 graphs.add( myAltosGraphTime("Temperature")
133 .addElement(temperature) );
135 graphs.add( myAltosGraphTime("Continuity")
136 .addElement(drogue_voltage)
137 .addElement(main_voltage) );
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) {
152 }).addElement(e_boost)
154 .addElement(e_coast);
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) {
167 }).addElement(e_drogue)
169 // ((XYGraph)graph[8]).ymin = new Double(-50);
173 public AltosGraphUI(AltosRecordIterable records) {
174 super("Altos Graph");
176 AltosDataPointReader reader = new AltosDataPointReader (records);
180 if (reader.has_accel)
186 public AltosGraphUI(AltosDataPointReader data, int which)
188 super("Altos Graph");
192 private void init(AltosDataPointReader data, int which) {
193 AltosGraph graph = createGraph(data, which);
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);
203 RefineryUtilities.centerFrameOnScreen(this);
205 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
209 private static AltosGraph createGraph(Iterable<AltosDataPoint> data,
212 return createGraphsWhich(data, which).get(0);
215 private static ArrayList<AltosGraph> createGraphs(
216 Iterable<AltosDataPoint> data)
218 return createGraphsWhich(data, -1);
221 private static ArrayList<AltosGraph> createGraphsWhich(
222 Iterable<AltosDataPoint> data, int which)
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());
230 if (which >= graph.size()) {
233 AltosGraph g = graph.get(which);
234 graph = new ArrayList<AltosGraph>();
238 for (AltosDataPoint dp : data) {
239 for (AltosGraph g : graph) {
252 --------------------------------------------------------
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)
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
265 set term png tiny size 700,700 enhanced
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"
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"
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"