summaryrefslogtreecommitdiff
path: root/altosui
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2012-10-22 21:35:06 -0700
committerKeith Packard <keithp@keithp.com>2012-10-22 21:35:06 -0700
commitfe00d1169c65cb289f77093cf281efbd0a5d4e64 (patch)
treebd896bf00b610a08ac7fc6fdc2dcfff660c94ad4 /altosui
parentfd619a01bf3489b1df017aca20362757b087ec11 (diff)
altosui/altoslib: Add support for configuring pyro channels
This provides a UI on devices which have pyro channels other than main/apogee. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'altosui')
-rw-r--r--altosui/AltosConfig.java32
-rw-r--r--altosui/AltosConfigPyroUI.java288
-rw-r--r--altosui/AltosConfigUI.java68
-rw-r--r--altosui/AltosDialog.java6
-rw-r--r--altosui/Makefile.am1
5 files changed, 385 insertions, 10 deletions
diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java
index 44e5a3fa..be9ab8bf 100644
--- a/altosui/AltosConfig.java
+++ b/altosui/AltosConfig.java
@@ -22,6 +22,7 @@ import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
import org.altusmetrum.AltosLib.*;
+import java.text.*;
public class AltosConfig implements ActionListener {
@@ -78,6 +79,8 @@ public class AltosConfig implements ActionListener {
string_ref version;
string_ref product;
string_ref callsign;
+ int_ref npyro;
+ AltosPyro[] pyros;
AltosConfigUI config_ui;
boolean serial_started;
boolean made_visible;
@@ -162,6 +165,8 @@ public class AltosConfig implements ActionListener {
config_ui.set_ignite_mode(ignite_mode.get());
config_ui.set_pad_orientation(pad_orientation.get());
config_ui.set_callsign(callsign.get());
+ config_ui.set_pyros(pyros);
+ config_ui.set_has_pyro(npyro.get() > 0);
config_ui.set_clean();
if (!made_visible) {
made_visible = true;
@@ -169,6 +174,8 @@ public class AltosConfig implements ActionListener {
}
}
+ int pyro;
+
void process_line(String line) {
if (line == null) {
abort();
@@ -179,6 +186,18 @@ public class AltosConfig implements ActionListener {
update_ui();
return;
}
+ if (pyro < npyro.get()) {
+ if (pyros == null)
+ pyros = new AltosPyro[npyro.get()];
+
+ try {
+ pyros[pyro] = new AltosPyro(pyro, line);
+ } catch (ParseException e) {
+ System.out.printf ("pyro parse failed %s\n", line);
+ }
+ ++pyro;
+ return;
+ }
get_int(line, "serial-number", serial);
get_int(line, "log-format", log_format);
get_int(line, "Main deploy:", main_deploy);
@@ -200,6 +219,7 @@ public class AltosConfig implements ActionListener {
get_string(line, "Callsign:", callsign);
get_string(line,"software-version", version);
get_string(line,"product", product);
+ get_int(line, "Pyro-count:", npyro);
}
final static int serial_mode_read = 0;
@@ -243,6 +263,8 @@ public class AltosConfig implements ActionListener {
callsign.set("N0CALL");
version.set("unknown");
product.set("unknown");
+ pyro = 0;
+ npyro.set(0);
}
void get_data() {
@@ -304,6 +326,12 @@ public class AltosConfig implements ActionListener {
serial_line.printf("c i %d\n", ignite_mode.get());
if (pad_orientation.get() >= 0)
serial_line.printf("c o %d\n", pad_orientation.get());
+ if (pyros.length > 0) {
+ for (int p = 0; p < pyros.length; p++) {
+ serial_line.printf("c P %s\n",
+ pyros[p].toString());
+ }
+ }
serial_line.printf("c w\n");
} catch (InterruptedException ie) {
} catch (TimeoutException te) {
@@ -431,6 +459,9 @@ public class AltosConfig implements ActionListener {
if (pad_orientation.get() >= 0)
pad_orientation.set(config_ui.pad_orientation());
callsign.set(config_ui.callsign());
+ if (npyro.get() > 0) {
+ pyros = config_ui.pyros();
+ }
run_serial_thread(serial_mode_save);
}
@@ -477,6 +508,7 @@ public class AltosConfig implements ActionListener {
callsign = new string_ref("N0CALL");
version = new string_ref("unknown");
product = new string_ref("unknown");
+ npyro = new int_ref(0);
device = AltosDeviceDialog.show(owner, Altos.product_any);
if (device != null) {
diff --git a/altosui/AltosConfigPyroUI.java b/altosui/AltosConfigPyroUI.java
new file mode 100644
index 00000000..17adb15f
--- /dev/null
+++ b/altosui/AltosConfigPyroUI.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package altosui;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import org.altusmetrum.AltosLib.*;
+
+public class AltosConfigPyroUI
+ extends AltosDialog
+ implements ItemListener, DocumentListener
+{
+ AltosConfigUI owner;
+ Container pane;
+
+ static Insets il = new Insets(4,4,4,4);
+ static Insets ir = new Insets(4,4,4,4);
+
+ static String[] state_names;
+
+ static void make_state_names() {
+ if (state_names == null) {
+
+ state_names = new String[AltosLib.ao_flight_landed - AltosLib.ao_flight_boost + 1];
+ for (int state = AltosLib.ao_flight_boost; state <= AltosLib.ao_flight_landed; state++)
+ state_names[state - AltosLib.ao_flight_boost] = AltosLib.state_name_capital(state);
+ }
+ }
+
+ class PyroItem implements ItemListener, DocumentListener
+ {
+ public int flag;
+ public JRadioButton enable;
+ public JTextField value;
+ public JComboBox combo;
+ AltosConfigPyroUI ui;
+
+ public void set_enable(boolean enable) {
+ if (value != null)
+ value.setEnabled(enable);
+ if (combo != null)
+ combo.setEnabled(enable);
+ }
+
+ public void itemStateChanged(ItemEvent e) {
+ set_enable(enable.isSelected());
+ ui.set_dirty();
+ }
+
+ public void changedUpdate(DocumentEvent e) {
+ ui.set_dirty();
+ }
+
+ public void insertUpdate(DocumentEvent e) {
+ ui.set_dirty();
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+ ui.set_dirty();
+ }
+
+ public void set(boolean new_enable, double new_value) {
+ enable.setSelected(new_enable);
+ set_enable(new_enable);
+ if (value != null) {
+ double scale = AltosPyro.pyro_to_scale(flag);
+ String format = "%6.0f";
+ if (scale >= 10)
+ format = "%6.1f";
+ else if (scale >= 100)
+ format = "%6.2f";
+ value.setText(String.format(format, new_value));
+ }
+ if (combo != null)
+ if (new_value >= AltosLib.ao_flight_boost && new_value <= AltosLib.ao_flight_landed)
+ combo.setSelectedIndex((int) new_value - AltosLib.ao_flight_boost);
+ }
+
+ public boolean enabled() {
+ return enable.isSelected();
+ }
+
+ public double value() {
+ if (value != null)
+ return Double.parseDouble(value.getText());
+ if (combo != null)
+ return combo.getSelectedIndex() + AltosLib.ao_flight_boost;
+ return 0;
+ }
+
+ public PyroItem(AltosConfigPyroUI in_ui, int in_flag, int x, int y) {
+
+ ui = in_ui;
+ flag = in_flag;
+
+ GridBagConstraints c;
+ c = new GridBagConstraints();
+ c.gridx = x; c.gridy = y;
+ c.gridwidth = 1;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ enable = new JRadioButton();
+ enable.addItemListener(this);
+ pane.add(enable, c);
+
+ if ((flag & AltosPyro.pyro_no_value) == 0) {
+ c = new GridBagConstraints();
+ c.gridx = x+1; c.gridy = y;
+ c.gridwidth = 1;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ if ((flag & AltosPyro.pyro_state_value) != 0) {
+ make_state_names();
+ combo = new JComboBox(state_names);
+ combo.addItemListener(this);
+ pane.add(combo, c);
+ } else {
+ value = new JTextField(10);
+ value.getDocument().addDocumentListener(this);
+ pane.add(value, c);
+ }
+ }
+ }
+ }
+
+ class PyroColumn {
+ public PyroItem[] items;
+ public JLabel label;
+ int channel;
+
+ public void set(AltosPyro pyro) {
+ int row = 0;
+ for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
+ if ((AltosPyro.pyro_all & flag) != 0) {
+ items[row].set((pyro.flags & flag) != 0,
+ pyro.get_value(flag));
+ row++;
+ }
+ }
+ }
+
+ public AltosPyro get() {
+ AltosPyro p = new AltosPyro(channel);
+
+ int row = 0;
+ for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
+ if ((AltosPyro.pyro_all & flag) != 0) {
+ if (items[row].enabled()) {
+ System.out.printf ("Flag %x enabled\n", flag);
+ p.flags |= flag;
+ p.set_value(flag, items[row].value());
+ }
+ row++;
+ }
+ }
+ System.out.printf ("Pyro %x %s\n", p.flags, p.toString());
+ return p;
+ }
+
+ public PyroColumn(AltosConfigPyroUI ui, int x, int y, int in_channel) {
+
+ channel = in_channel;
+
+ int nrow = 0;
+ for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
+ if ((flag & AltosPyro.pyro_all) != 0)
+ nrow++;
+
+ items = new PyroItem[nrow];
+ int row = 0;
+
+ GridBagConstraints c;
+ c = new GridBagConstraints();
+ c.gridx = x; c.gridy = y;
+ c.gridwidth = 2;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = il;
+ label = new JLabel(String.format("Pyro Channel %d", channel));
+ pane.add(label, c);
+ y++;
+
+ for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
+ if ((flag & AltosPyro.pyro_all) != 0) {
+ items[row] = new PyroItem(ui, flag, x, y + row);
+ row++;
+ }
+ }
+ }
+
+ PyroColumn[] columns;
+
+ public void set_pyros(AltosPyro[] pyros) {
+ for (int i = 0; i < pyros.length; i++) {
+ if (pyros[i].channel < columns.length)
+ columns[pyros[i].channel].set(pyros[i]);
+ }
+ }
+
+ public AltosPyro[] get_pyros() {
+ AltosPyro[] pyros = new AltosPyro[columns.length];
+ for (int c = 0; c < columns.length; c++)
+ pyros[c] = columns[c].get();
+ return pyros;
+ }
+
+ public void set_dirty() {
+ owner.set_dirty();
+ }
+
+ public void itemStateChanged(ItemEvent e) {
+ owner.set_dirty();
+ }
+
+ public void changedUpdate(DocumentEvent e) {
+ owner.set_dirty();
+ }
+
+ public void insertUpdate(DocumentEvent e) {
+ owner.set_dirty();
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+ owner.set_dirty();
+ }
+
+ public AltosConfigPyroUI(AltosConfigUI in_owner, AltosPyro[] pyros) {
+
+ super(in_owner, "Configure Pyro Channels", false);
+
+ owner = in_owner;
+
+ GridBagConstraints c;
+
+ pane = getContentPane();
+ pane.setLayout(new GridBagLayout());
+
+ int row = 1;
+
+ for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) {
+ String n;
+
+ n = AltosPyro.pyro_to_name(flag);
+ if (n != null) {
+ c = new GridBagConstraints();
+ c.gridx = 0; c.gridy = row;
+ c.gridwidth = 1;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ JLabel label = new JLabel(n);
+ pane.add(label, c);
+ row++;
+ }
+ }
+
+ columns = new PyroColumn[pyros.length];
+
+ for (int i = 0; i < pyros.length; i++) {
+ columns[i] = new PyroColumn(this, i*2 + 1, 0, i);
+ columns[i].set(pyros[i]);
+ }
+ }
+
+ public void make_visible() {
+ pack();
+ setVisible(true);
+ }
+}
diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java
index dd34a9cf..feac053b 100644
--- a/altosui/AltosConfigUI.java
+++ b/altosui/AltosConfigUI.java
@@ -29,7 +29,6 @@ public class AltosConfigUI
{
Container pane;
- Box box;
JLabel product_label;
JLabel version_label;
JLabel serial_label;
@@ -62,11 +61,15 @@ public class AltosConfigUI
JComboBox pad_orientation_value;
JTextField callsign_value;
+ JButton pyro;
+
JButton save;
JButton reset;
JButton reboot;
JButton close;
+ AltosPyro[] pyros;
+
ActionListener listener;
static String[] main_deploy_values = {
@@ -510,6 +513,20 @@ public class AltosConfigUI
set_pad_orientation_tool_tip();
row++;
+ /* Pyro channels */
+ c = new GridBagConstraints();
+ c.gridx = 4; c.gridy = row;
+ c.gridwidth = 4;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ c.ipady = 5;
+ pyro = new JButton("Configure Pyro Channels");
+ pane.add(pyro, c);
+ pyro.addActionListener(this);
+ pyro.setActionCommand("Pyro");
+ row++;
+
/* Buttons */
c = new GridBagConstraints();
c.gridx = 0; c.gridy = row;
@@ -582,10 +599,30 @@ public class AltosConfigUI
return true;
}
+ void set_dirty() {
+ dirty = true;
+ save.setEnabled(true);
+ }
+
+ public void set_clean() {
+ dirty = false;
+ save.setEnabled(false);
+ }
+
+ AltosConfigPyroUI pyro_ui;
+
/* Listen for events from our buttons */
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
+ if (cmd.equals("Pyro")) {
+ if (pyro_ui == null && pyros != null) {
+ pyro_ui = new AltosConfigPyroUI(this, pyros);
+ pyro_ui.make_visible();
+ }
+ return;
+ }
+
if (cmd.equals("Close") || cmd.equals("Reboot"))
if (!check_dirty(cmd))
return;
@@ -594,25 +631,25 @@ public class AltosConfigUI
setVisible(false);
dispose();
}
- dirty = false;
+ set_clean();
}
/* ItemListener interface method */
public void itemStateChanged(ItemEvent e) {
- dirty = true;
+ set_dirty();
}
/* DocumentListener interface methods */
public void changedUpdate(DocumentEvent e) {
- dirty = true;
+ set_dirty();
}
public void insertUpdate(DocumentEvent e) {
- dirty = true;
+ set_dirty();
}
public void removeUpdate(DocumentEvent e) {
- dirty = true;
+ set_dirty();
}
/* Let the config code hook on a listener */
@@ -725,8 +762,7 @@ public class AltosConfigUI
}
public void set_flight_log_max(int new_flight_log_max) {
- if (new_flight_log_max == 0)
- flight_log_max_value.setEnabled(false);
+ flight_log_max_value.setEnabled(new_flight_log_max > 0);
flight_log_max_value.setSelectedItem(Integer.toString(new_flight_log_max));
set_flight_log_max_tool_tip();
}
@@ -793,7 +829,19 @@ public class AltosConfigUI
return -1;
}
- public void set_clean() {
- dirty = false;
+ public void set_has_pyro(boolean has_pyro) {
+ pyro.setEnabled(has_pyro);
+ }
+
+ public void set_pyros(AltosPyro[] new_pyros) {
+ pyros = new_pyros;
+ if (pyro_ui != null)
+ pyro_ui.set_pyros(pyros);
+ }
+
+ public AltosPyro[] pyros() {
+ if (pyro_ui != null)
+ pyros = pyro_ui.get_pyros();
+ return pyros;
}
}
diff --git a/altosui/AltosDialog.java b/altosui/AltosDialog.java
index eac371aa..c2a9d6e6 100644
--- a/altosui/AltosDialog.java
+++ b/altosui/AltosDialog.java
@@ -45,6 +45,12 @@ public class AltosDialog extends JDialog implements AltosUIListener {
addWindowListener(new AltosDialogListener());
}
+ public AltosDialog(Dialog dialog, String label, boolean modal) {
+ super(dialog, label, modal);
+ AltosUIPreferences.register_ui_listener(this);
+ addWindowListener(new AltosDialogListener());
+ }
+
public AltosDialog(Frame frame, boolean modal) {
super(frame, modal);
AltosUIPreferences.register_ui_listener(this);
diff --git a/altosui/Makefile.am b/altosui/Makefile.am
index 9f03ceb6..2c46da4a 100644
--- a/altosui/Makefile.am
+++ b/altosui/Makefile.am
@@ -24,6 +24,7 @@ altosui_JAVA = \
AltosConfig.java \
AltosConfigFreqUI.java \
AltosConfigUI.java \
+ AltosConfigPyroUI.java \
AltosConfigureUI.java \
AltosConfigTD.java \
AltosConfigTDUI.java \