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 import altosui.AltosCsvReader;
21 import altosui.AltosDataPoint;
22 import altosui.AltosGraphTime;
24 public class AltosGraphUI extends JFrame
26 static final private Color red = new Color(194,31,31);
27 static final private Color green = new Color(31,194,31);
28 static final private Color blue = new Color(31,31,194);
29 static final private Color black = new Color(31,31,31);
31 static private class OverallGraphs {
32 AltosGraphTime.Element height =
33 new AltosGraphTime.TimeSeries("Height (m)", "Height (AGL)", red) {
34 public void gotTimeData(double time, AltosDataPoint d) {
35 series.add(time, d.height());
39 AltosGraphTime.Element speed =
40 new AltosGraphTime.TimeSeries("Speed (m/s)", "Vertical Speed", green) {
41 public void gotTimeData(double time, AltosDataPoint d) {
43 series.add(time, d.accel_speed());
45 series.add(time, d.baro_speed());
50 AltosGraphTime.Element acceleration =
51 new AltosGraphTime.TimeSeries("Acceleration (m/s\u00B2)",
52 "Axial Acceleration", blue)
54 public void gotTimeData(double time, AltosDataPoint d) {
55 series.add(time, d.acceleration());
59 AltosGraphTime.Element temperature =
60 new AltosGraphTime.TimeSeries("Temperature (\u00B0C)",
61 "Board temperature", red)
63 public void gotTimeData(double time, AltosDataPoint d) {
64 series.add(time, d.temperature());
68 AltosGraphTime.Element drogue_voltage =
69 new AltosGraphTime.TimeSeries("Voltage (V)", "Drogue Continuity", blue)
71 public void gotTimeData(double time, AltosDataPoint d) {
72 series.add(time, d.drogue_voltage());
76 AltosGraphTime.Element main_voltage =
77 new AltosGraphTime.TimeSeries("Voltage (V)", "Main Continuity", green)
79 public void gotTimeData(double time, AltosDataPoint d) {
80 series.add(time, d.main_voltage());
84 AltosGraphTime.Element e_pad = new AltosGraphTime.StateMarker(2, "Pad");
85 AltosGraphTime.Element e_boost = new AltosGraphTime.StateMarker(3, "Boost");
86 AltosGraphTime.Element e_fast = new AltosGraphTime.StateMarker(4, "Fast");
87 AltosGraphTime.Element e_coast = new AltosGraphTime.StateMarker(5, "Coast");
88 AltosGraphTime.Element e_drogue = new AltosGraphTime.StateMarker(6, "Drogue");
89 AltosGraphTime.Element e_main = new AltosGraphTime.StateMarker(7, "Main");
90 AltosGraphTime.Element e_landed = new AltosGraphTime.StateMarker(8, "Landed");
92 protected AltosGraphTime myAltosGraphTime(String suffix) {
93 return (new AltosGraphTime("Overall " + suffix))
97 .addElement(e_landed);
100 public ArrayList<AltosGraph> graphs() {
101 ArrayList<AltosGraph> graphs = new ArrayList<AltosGraph>();
103 graphs.add( myAltosGraphTime("Summary")
106 .addElement(acceleration) );
108 graphs.add( myAltosGraphTime("Altitude")
109 .addElement(height) );
111 graphs.add( myAltosGraphTime("Speed")
112 .addElement(speed) );
114 graphs.add( myAltosGraphTime("Acceleration")
115 .addElement(acceleration) );
117 graphs.add( myAltosGraphTime("Temperature")
118 .addElement(temperature) );
120 graphs.add( myAltosGraphTime("Continuity")
121 .addElement(drogue_voltage)
122 .addElement(main_voltage) );
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 (3 <= state && state <= 5) {
137 }).addElement(e_boost)
139 .addElement(e_coast);
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 (6 <= state && state <= 7) {
152 }).addElement(e_drogue)
154 // ((XYGraph)graph[8]).ymin = new Double(-50);
158 public AltosGraphUI(JFrame frame)
160 super("Altos Graph");
162 AltosGraphDataChooser chooser;
163 chooser = new AltosGraphDataChooser(frame);
164 Iterable<AltosDataPoint> reader = chooser.runDialog();
171 public AltosGraphUI(Iterable<AltosDataPoint> data, int which)
173 super("Altos Graph");
177 private void init(Iterable<AltosDataPoint> data, int which) {
178 AltosGraph graph = createGraph(data, which);
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);
188 RefineryUtilities.centerFrameOnScreen(this);
190 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
194 private static AltosGraph createGraph(Iterable<AltosDataPoint> data,
197 return createGraphsWhich(data, which).get(0);
200 private static ArrayList<AltosGraph> createGraphs(
201 Iterable<AltosDataPoint> data)
203 return createGraphsWhich(data, -1);
206 private static ArrayList<AltosGraph> createGraphsWhich(
207 Iterable<AltosDataPoint> data, int which)
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());
215 if (which >= graph.size()) {
218 AltosGraph g = graph.get(which);
219 graph = new ArrayList<AltosGraph>();
223 for (AltosDataPoint dp : data) {
224 for (AltosGraph g : graph) {
232 public static void main(String[] args)
233 throws java.io.FileNotFoundException, java.io.IOException
235 if (args.length < 1 || 2 < args.length)
237 System.out.println("Please specify telemetry csv");
241 AltosCsvReader csv = new AltosCsvReader(args[0]);
242 if (args.length == 1) {
243 for (AltosGraph g : createGraphs(csv)) {
247 int which = Integer.parseInt(args[1].trim());
248 AltosGraphUI demo = new AltosGraphUI(csv, which);
257 --------------------------------------------------------
260 "ascent-gps-accuracy.png" "Vertical error margin to apogee - GPS v Baro (m)"
261 5:($7 < 6 ? $24-$11 : 1/0)
262 "descent-gps-accuracy.png" "Vertical error margin during descent - GPS v Baro (m)"
263 5:($7 < 6 ? 1/0 : $24-$11)
265 set output "overall-gps-accuracy.png"
266 set ylabel "distance above sea level (m)"
267 plot "telemetry.csv" using 5:11 with lines ti "baro altitude" axis x1y1, \
268 "telemetry.csv" using 5:24 with lines ti "gps altitude" axis x1y1
270 set term png tiny size 700,700 enhanced
278 set output "overall-gps-path.png"
279 #:30 with yerrorlines
280 plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0) with lines ti "pad", \
281 "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0) with lines ti "boost", \
282 "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0) with lines ti "fast", \
283 "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0) with lines ti "coast", \
284 "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \
285 "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \
286 "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed"
288 set output "ascent-gps-path.png"
289 plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0):30 with lines ti "pad", \
290 "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0):20 with lines ti "boost", \
291 "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0):10 with lines ti "fast", \
292 "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0):5 with lines ti "coast"
294 set output "descent-gps-path.png"
295 plot "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \
296 "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \
297 "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed"