2 * Copyright © 2011 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 import java.awt.event.*;
23 import javax.swing.filechooser.FileNameExtensionFilter;
24 import javax.swing.table.*;
25 import javax.swing.event.*;
29 import java.util.prefs.*;
30 import java.util.concurrent.LinkedBlockingQueue;
32 public class AltosTerra
34 implements ActionListener
39 JButton prev, next, enter;
41 static final int info_tab = 1;
42 static final int pad_tab = 2;
43 static final int ascent_tab = 3;
44 static final int descent_tab = 4;
45 static final int landing_tab = 5;
49 AltosState current_state;
51 public void actionPerformed(ActionEvent e) {
52 String cmd = e.getActionCommand();
53 if (cmd.equals("prev")) {
54 displayed_tab = displayed_tab - 1;
55 if (displayed_tab < info_tab)
56 displayed_tab = landing_tab;
59 if (cmd.equals("next")) {
60 displayed_tab = displayed_tab + 1;
61 if (displayed_tab > landing_tab)
62 displayed_tab = info_tab;
67 int which_tab(AltosState state) {
68 if (state.state < Altos.ao_flight_boost)
70 if (state.state <= Altos.ao_flight_coast)
72 if (state.state <= Altos.ao_flight_main)
77 String[] lines = { "", "" };
79 public void setLine(int line, String format, Object... args) {
80 lines[line] = String.format(format, args);
81 String result = lines[0].concat("\n").concat(lines[1]);
82 text_area.setText(result);
85 public int state_char(AltosState state) {
86 switch (state.state) {
87 case Altos.ao_flight_startup: return 'S';
88 case Altos.ao_flight_idle: return 'I';
89 case Altos.ao_flight_pad: return 'P';
90 case Altos.ao_flight_boost: return 'B';
91 case Altos.ao_flight_fast: return 'F';
92 case Altos.ao_flight_coast: return 'C';
93 case Altos.ao_flight_drogue: return 'D';
94 case Altos.ao_flight_main: return 'M';
95 case Altos.ao_flight_landed: return 'L';
97 case Altos.ao_flight_invalid: return '*';
101 int boolchar(boolean b) {
107 String pos(double p, String pos, String neg) {
113 int deg = (int) Math.floor(p);
114 double min = (p - Math.floor(p)) * 60.0;
115 return String.format("%s%3d°%9.6f'", h, deg, min);
118 public void display() {
119 switch (displayed_tab) {
122 setLine(0, "%-7sN %-5d %c",
123 current_state.data.callsign,
124 current_state.data.serial,
125 state_char(current_state));
126 setLine(1, "F %-4d RSSI %3d",
127 current_state.data.flight,
128 current_state.data.rssi);
131 setLine(0, "D%c M%c B%c G%c %c",
132 boolchar(current_state.drogue_sense > 3.2),
133 boolchar(current_state.main_sense > 3.2),
134 boolchar(current_state.battery > 3.7),
135 boolchar(current_state.gps.locked),
136 state_char(current_state));
137 setLine(1, "SAT %2d RSSI %3d",
138 current_state.gps.nsat,
139 current_state.data.rssi);
142 setLine(0, "S:%5d S⌈%5d%c",
143 (int) Math.floor(current_state.speed + 0.5),
144 (int) Math.floor(current_state.max_speed + 0.5),
145 state_char(current_state));
146 setLine(1, "H:%5d H⌈%5d",
147 (int) Math.floor(current_state.height + 0.5),
148 (int) Math.floor(current_state.max_height + 0.5));
151 setLine(0, "→%5d ↑%5d %c",
152 (int) Math.floor (current_state.from_pad.bearing + 0.5),
153 (int) Math.floor (current_state.elevation + 0.5),
154 state_char(current_state));
155 setLine(1, "H%5d S%5d",
156 (int) Math.floor(current_state.height + 0.5),
157 (int) Math.floor(current_state.baro_speed + 0.5));
160 setLine(0, "%s%c", pos(current_state.gps.lat, "N", "S"),
161 state_char(current_state));
162 setLine(1, "%s", pos(current_state.gps.lon, "E", "W"));
166 public void display(AltosState state) {
167 int tab = which_tab(state);
168 if (tab != current_tab)
169 current_tab = displayed_tab = tab;
170 current_state = state;
174 public AltosTerra(JFrame in_owner) {
175 super(in_owner, "AltosTerra", false);
177 GridBagConstraints c;
179 Insets insets = new Insets(4,4,4,4);
183 pane = getContentPane();
184 pane.setLayout(new GridBagLayout());
186 c = new GridBagConstraints();
188 c.fill = GridBagConstraints.NONE;
189 c.anchor = GridBagConstraints.WEST;
191 text_area = new JTextArea(2, 16);
192 text_area.setFont(new Font("Monospaced", Font.PLAIN, 22));
193 text_area.setEditable(false);
200 c.fill = GridBagConstraints.NONE;
201 c.anchor = GridBagConstraints.CENTER;
202 pane.add(text_area, c);
205 prev = new JButton("Prev");
206 prev.addActionListener(this);
207 prev.setActionCommand("prev");
212 c.fill = GridBagConstraints.BOTH;
213 c.anchor = GridBagConstraints.CENTER;
217 next = new JButton("Next");
218 next.addActionListener(this);
219 next.setActionCommand("next");
224 c.fill = GridBagConstraints.BOTH;
225 c.anchor = GridBagConstraints.CENTER;
229 enter = new JButton("Enter");
230 enter.addActionListener(this);
231 enter.setActionCommand("enter");
236 c.fill = GridBagConstraints.BOTH;
237 c.anchor = GridBagConstraints.CENTER;