summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-08-11 23:42:53 -0400
committerKeith Packard <keithp@keithp.com>2017-09-01 13:22:58 -0700
commit558a143315f0345b79cc4f22aa4b643fedcded9c (patch)
tree7a667970da65b40ab7136e7bb158b75cd0a49b79
parentc9a742db2497d07079f3d4bf383c6246cf80507c (diff)
altosui: Accel calibration UI
Provides a GUI for re-calibrating accelerometers Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--altoslib/AltosAccelCal.java217
-rw-r--r--altoslib/AltosAccelCalListener.java34
-rw-r--r--altoslib/AltosConfigData.java10
-rw-r--r--altoslib/AltosConfigValues.java10
-rw-r--r--altoslib/AltosLink.java19
-rw-r--r--altoslib/Makefile.am2
-rw-r--r--altosui/AltosConfigFC.java7
-rw-r--r--altosui/AltosConfigFCUI.java118
-rw-r--r--altosuilib/AltosUIAccelCal.java243
-rw-r--r--altosuilib/Makefile.am1
10 files changed, 656 insertions, 5 deletions
diff --git a/altoslib/AltosAccelCal.java b/altoslib/AltosAccelCal.java
new file mode 100644
index 00000000..03d9fbf2
--- /dev/null
+++ b/altoslib/AltosAccelCal.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2017 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, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.io.*;
+import java.util.concurrent.*;
+
+public class AltosAccelCal implements Runnable {
+
+ AltosLink link;
+ AltosAccelCalListener listener;
+
+ boolean remote;
+ boolean close_on_exit;
+ double frequency;
+ String callsign;
+
+ Thread accel_thread;
+
+ AltosConfigData config_data;
+
+ public static final int phase_antenna_up = 0;
+ public static final int phase_antenna_down = 1;
+
+ void start_link() throws InterruptedException, TimeoutException {
+ if (remote) {
+ link.set_radio_frequency(frequency);
+ link.set_callsign(callsign);
+ link.start_remote();
+ } else
+ link.flush_input();
+ }
+
+ boolean stop_link() throws InterruptedException, TimeoutException {
+ if (remote)
+ link.stop_remote();
+ return link.reply_abort;
+ }
+
+ public void set_frequency(double in_frequency) {
+ frequency = in_frequency;
+ link.abort_reply();
+ }
+
+ public void set_callsign(String in_callsign) {
+ callsign = in_callsign;
+ link.abort_reply();
+ }
+
+ public void abort() throws InterruptedException {
+ while (accel_thread.isAlive()) {
+ accel_thread.interrupt();
+ link.abort_reply();
+ Thread.sleep(100);
+ }
+ accel_thread.join();
+ }
+
+ static private final String press_msg = "press a key...";
+
+ private Semaphore ui_signal_semaphore;
+ private boolean ui_signal_reply;
+
+ public void signal(boolean reply) {
+ System.out.printf("Signal cal semaphore %b\n", reply);
+ ui_signal_reply = reply;
+ ui_signal_semaphore.release();
+ }
+
+ private boolean wait_signal() throws InterruptedException {
+ System.out.printf("\twait for cal signal...\n");
+ ui_signal_semaphore.acquire();
+ System.out.printf("\tgot cal signal %b\n", ui_signal_reply);
+ return ui_signal_reply;
+ }
+
+ private boolean wait_press(int timeout) throws InterruptedException {
+ for (;;) {
+ String line = link.get_reply(timeout);
+ if (line == null) {
+ System.out.printf("get_reply timeout\n");
+ return false;
+ }
+ System.out.printf("got line %s\n", line);
+ if (line.contains(press_msg))
+ return true;
+ if (line.contains("Invalid"))
+ return false;
+ if (line.contains("Syntax"))
+ return false;
+ if (line.contains("Calibrating"))
+ listener.message(this, line);
+ }
+ }
+
+ static final int cal_timeout = 20 * 1000;
+
+ public void run() {
+ System.out.printf("start accel cal procedure\n");
+ try {
+ AltosConfigData new_config = null;
+
+ try {
+ start_link();
+ config_data = link.config_data();
+
+ /* set back to antenna up for calibration */
+ if (config_data.pad_orientation != 0)
+ link.printf("c o 0\n");
+
+ /* Start calibration */
+ try {
+ System.out.printf("*** start cal\n");
+ link.set_match(press_msg);
+ link.printf("c a 0\n");
+ System.out.printf("*** wait press\n");
+ if (!wait_press(cal_timeout))
+ throw new TimeoutException("timeout");
+ System.out.printf("*** set_phase antenna_up\n");
+ listener.set_phase(this, phase_antenna_up);
+ System.out.printf("*** wait_signal\n");
+ if (!wait_signal())
+ throw new InterruptedException("aborted");
+ link.set_match(press_msg);
+ System.out.printf("*** send newline\n");
+ link.printf("\n");
+ System.out.printf("*** wait press\n");
+ if (!wait_press(cal_timeout))
+ throw new TimeoutException("timeout");
+ System.out.printf("***set_phase antenna_down\n");
+ listener.set_phase(this, phase_antenna_down);
+ System.out.printf("*** wait_signal\n");
+ if (!wait_signal())
+ throw new InterruptedException("aborted");
+ System.out.printf("*** send newline and version command\n");
+ link.printf("\nv\n");
+ } catch (TimeoutException e) {
+ throw e;
+ } catch (InterruptedException e) {
+ throw e;
+ }
+ link.set_match(null);
+
+ boolean worked = true;
+ for (;;) {
+ String line = link.get_reply(cal_timeout);
+ if (line == null)
+ throw new TimeoutException();
+ System.out.printf("*** waiting for finish: %s\n", line);
+ if (line.contains("Invalid"))
+ worked = false;
+ if (line.contains("software-version"))
+ break;
+ if (line.contains("Calibrating"))
+ listener.message(this, line);
+ }
+ System.out.printf("*** worked: %b\n", worked);
+ if (worked)
+ new_config = new AltosConfigData(link);
+ } finally {
+ System.out.printf("Restore orientation %d +g %d -g %d\n",
+ config_data.pad_orientation,
+ config_data.accel_cal_plus,
+ config_data.accel_cal_minus);
+ if (config_data.pad_orientation != AltosLib.MISSING && config_data.pad_orientation != 0)
+ link.printf("c o %d\n", config_data.pad_orientation);
+ if (config_data.accel_cal_plus != AltosLib.MISSING && config_data.accel_cal_minus != AltosLib.MISSING)
+ link.printf("c a %d %d\n",
+ config_data.accel_cal_plus, config_data.accel_cal_minus);
+ stop_link();
+ }
+ if (new_config != null) {
+ System.out.printf("*** +1g %d -1g %d\n",
+ new_config.accel_cal_plus,
+ new_config.accel_cal_minus);
+ listener.cal_done(this, new_config.accel_cal_plus, new_config.accel_cal_minus);
+ if (!wait_signal())
+ throw new InterruptedException("aborted");
+ } else
+ listener.error(this, "Calibration failed");
+ } catch (TimeoutException te) {
+ System.out.printf("timeout");
+ listener.error(this, "timeout");
+ } catch (InterruptedException ie) {
+ System.out.printf("interrupted\n");
+ listener.error(this, "interrupted");
+ }
+ }
+
+ public void start() {
+ accel_thread = new Thread(this);
+ listener.set_thread(this, accel_thread);
+ accel_thread.start();
+ }
+
+ public AltosAccelCal(AltosLink link, AltosAccelCalListener listener) {
+ this.link = link;
+ this.listener = listener;
+ ui_signal_semaphore = new Semaphore(0);
+ }
+}
diff --git a/altoslib/AltosAccelCalListener.java b/altoslib/AltosAccelCalListener.java
new file mode 100644
index 00000000..17359245
--- /dev/null
+++ b/altoslib/AltosAccelCalListener.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2017 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, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.altusmetrum.altoslib_12;
+
+import java.io.*;
+import java.util.concurrent.*;
+
+public interface AltosAccelCalListener {
+ public void set_thread(AltosAccelCal cal, Thread thread);
+
+ public void set_phase(AltosAccelCal cal, int phase);
+
+ public void cal_done(AltosAccelCal cal, int plus, int minus);
+
+ public void error(AltosAccelCal cal, String msg);
+
+ public void message(AltosAccelCal cal, String msg);
+}
diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java
index 63c34310..d85f735b 100644
--- a/altoslib/AltosConfigData.java
+++ b/altoslib/AltosConfigData.java
@@ -525,6 +525,12 @@ public class AltosConfigData {
if (pad_orientation != AltosLib.MISSING)
pad_orientation = source.pad_orientation();
+ if (accel_cal_plus != AltosLib.MISSING)
+ accel_cal_plus = source.accel_cal_plus();
+
+ if (accel_cal_minus != AltosLib.MISSING)
+ accel_cal_minus = source.accel_cal_minus();
+
/* HAS_LOG */
if (flight_log_max != AltosLib.MISSING)
flight_log_max = source.flight_log_max();
@@ -592,6 +598,7 @@ public class AltosConfigData {
dest.set_flight_log_max(flight_log_max);
dest.set_ignite_mode(ignite_mode);
dest.set_pad_orientation(pad_orientation);
+ dest.set_accel_cal(accel_cal_plus, accel_cal_minus);
dest.set_callsign(callsign);
if (npyro != AltosLib.MISSING)
dest.set_pyros(pyros);
@@ -669,9 +676,10 @@ public class AltosConfigData {
link.printf("c e %d\n", radio_enable);
/* HAS_ACCEL */
- /* UI doesn't support accel cal */
if (pad_orientation != AltosLib.MISSING)
link.printf("c o %d\n", pad_orientation);
+ if (accel_cal_plus != AltosLib.MISSING && accel_cal_minus != AltosLib.MISSING)
+ link.printf("c a %d %d\n", accel_cal_plus, accel_cal_minus);
/* HAS_LOG */
if (flight_log_max != 0)
diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java
index 170b1112..10478fd4 100644
--- a/altoslib/AltosConfigValues.java
+++ b/altoslib/AltosConfigValues.java
@@ -74,6 +74,16 @@ public interface AltosConfigValues {
public abstract int pad_orientation();
+ public abstract void set_accel_cal(int accel_cal_plus, int accel_cal_minus);
+
+ public abstract int accel_cal_plus();
+
+ public abstract int accel_cal_minus();
+
+ public abstract void set_dirty();
+
+ public abstract void set_clean();
+
public abstract void set_pyros(AltosPyro[] new_pyros);
public abstract AltosPyro[] pyros() throws AltosConfigDataException;
diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java
index 5a802ef1..5413de9d 100644
--- a/altoslib/AltosLink.java
+++ b/altoslib/AltosLink.java
@@ -43,6 +43,8 @@ public abstract class AltosLink implements Runnable {
public LinkedBlockingQueue<AltosLine> reply_queue = new LinkedBlockingQueue<AltosLine>();
public LinkedBlockingQueue<byte[]> binary_queue = new LinkedBlockingQueue<byte[]>();
+ private String match_string = null;
+
public synchronized void add_monitor(LinkedBlockingQueue<AltosLine> q) {
set_monitor(true);
monitors.add(q);
@@ -112,6 +114,15 @@ public abstract class AltosLink implements Runnable {
private int len_read = 0;
+ private boolean match_bytes(byte[] bytes, int byte_count, String match) {
+ if (byte_count < match.length())
+ return false;
+ String line = new String(bytes, 0, byte_count, AltosLib.unicode_set);
+ if (line == null)
+ return false;
+ return line.indexOf(match) >= 0;
+ }
+
public void run () {
int c;
byte[] line_bytes = null;
@@ -159,6 +170,11 @@ public abstract class AltosLink implements Runnable {
line_count = 0;
len_read = 0;
}
+ if (match_string != null && match_bytes(line_bytes, line_count, match_string)) {
+ match_string = null;
+ add_bytes(line_bytes, line_count);
+ line_count = 0;
+ }
}
}
}
@@ -166,6 +182,9 @@ public abstract class AltosLink implements Runnable {
}
}
+ public void set_match(String match) {
+ match_string = match;
+ }
public String get_reply(int timeout) throws InterruptedException {
boolean can_cancel = can_cancel_reply();
diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am
index 11b5d562..08af9496 100644
--- a/altoslib/Makefile.am
+++ b/altoslib/Makefile.am
@@ -26,6 +26,8 @@ record_files = \
altoslib_JAVA = \
AltosLib.java \
+ AltosAccelCal.java \
+ AltosAccelCalListener.java \
AltosCalData.java \
AltosCompanion.java \
AltosConfigData.java \
diff --git a/altosui/AltosConfigFC.java b/altosui/AltosConfigFC.java
index beff71b7..5e2aa7f4 100644
--- a/altosui/AltosConfigFC.java
+++ b/altosui/AltosConfigFC.java
@@ -268,6 +268,13 @@ public class AltosConfigFC implements ActionListener {
if (serial_line != null)
serial_line.close();
}
+ else if (cmd.equals("Accel")) {
+ if (data.pad_orientation != AltosLib.MISSING) {
+ AltosUIAccelCal accel_ui = new AltosUIAccelCal(owner, serial_line, config_ui);
+ if (accel_ui != null)
+ accel_ui.doit();
+ }
+ }
} catch (InterruptedException ie) {
abort();
} catch (TimeoutException te) {
diff --git a/altosui/AltosConfigFCUI.java b/altosui/AltosConfigFCUI.java
index c0c37254..3fe6cf94 100644
--- a/altosui/AltosConfigFCUI.java
+++ b/altosui/AltosConfigFCUI.java
@@ -49,6 +49,8 @@ public class AltosConfigFCUI
JLabel flight_log_max_label;
JLabel ignite_mode_label;
JLabel pad_orientation_label;
+ JLabel accel_plus_label;
+ JLabel accel_minus_label;
JLabel callsign_label;
JLabel beep_label;
JLabel tracker_motion_label;
@@ -73,12 +75,15 @@ public class AltosConfigFCUI
JComboBox<String> flight_log_max_value;
JComboBox<String> ignite_mode_value;
JComboBox<String> pad_orientation_value;
+ JTextField accel_plus_value;
+ JTextField accel_minus_value;
JTextField callsign_value;
JComboBox<String> beep_value;
JComboBox<String> tracker_motion_value;
JComboBox<String> tracker_interval_value;
JButton pyro;
+ JButton accel_cal;
JButton save;
JButton reset;
@@ -250,9 +255,9 @@ public class AltosConfigFCUI
}
void set_pad_orientation_tool_tip() {
- if (pad_orientation_value.isVisible())
+ if (pad_orientation_value.isVisible()) {
pad_orientation_value.setToolTipText("How will the computer be mounted in the airframe");
- else {
+ } else {
if (is_telemetrum())
pad_orientation_value.setToolTipText("Older TeleMetrum firmware must fly antenna forward");
else if (is_telemini() || is_easymini())
@@ -262,6 +267,16 @@ public class AltosConfigFCUI
}
}
+ void set_accel_tool_tips() {
+ if (accel_plus_value.isVisible()) {
+ accel_plus_value.setToolTipText("Pad acceleration value in flight orientation");
+ accel_minus_value.setToolTipText("Upside-down acceleration value");
+ } else {
+ accel_plus_value.setToolTipText("No accelerometer");
+ accel_minus_value.setToolTipText("No accelerometer");
+ }
+ }
+
void set_beep_tool_tip() {
if (beep_value.isVisible())
beep_value.setToolTipText("What frequency the beeper will sound at");
@@ -709,6 +724,57 @@ public class AltosConfigFCUI
set_pad_orientation_tool_tip();
row++;
+ /* Accel plus */
+ c = new GridBagConstraints();
+ c.gridx = 0; c.gridy = row;
+ c.gridwidth = 4;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ c.ipady = 5;
+ accel_plus_label = new JLabel("Accel Plus:");
+ pane.add(accel_plus_label, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 4; c.gridy = row;
+ c.gridwidth = 4;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.weightx = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = ir;
+ c.ipady = 5;
+ accel_plus_value = new JTextField(10);
+ accel_plus_value.setEditable(true);
+ accel_plus_value.getDocument().addDocumentListener(this);
+ pane.add(accel_plus_value, c);
+ row++;
+
+ /* Accel minus */
+ c = new GridBagConstraints();
+ c.gridx = 0; c.gridy = row;
+ c.gridwidth = 4;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ c.ipady = 5;
+ accel_minus_label = new JLabel("Accel Minus:");
+ pane.add(accel_minus_label, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 4; c.gridy = row;
+ c.gridwidth = 4;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.weightx = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = ir;
+ c.ipady = 5;
+ accel_minus_value = new JTextField(10);
+ accel_minus_value.setEditable(true);
+ accel_minus_value.getDocument().addDocumentListener(this);
+ pane.add(accel_minus_value, c);
+ row++;
+ set_accel_tool_tips();
+
/* Beeper */
c = new GridBagConstraints();
c.gridx = 0; c.gridy = row;
@@ -800,6 +866,20 @@ public class AltosConfigFCUI
pyro.setActionCommand("Pyro");
row++;
+ /* Accel cal */
+ c = new GridBagConstraints();
+ c.gridx = 5; c.gridy = row;
+ c.gridwidth = 5;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.insets = il;
+ c.ipady = 5;
+ accel_cal = new JButton("Calibrate Accelerometer");
+ pane.add(accel_cal, c);
+ accel_cal.addActionListener(this);
+ accel_cal.setActionCommand("Accel");
+ row++;
+
/* Buttons */
c = new GridBagConstraints();
c.gridx = 0; c.gridy = row;
@@ -873,12 +953,14 @@ public class AltosConfigFCUI
return true;
}
- void set_dirty() {
+ public void set_dirty() {
+ System.out.printf("set dirty\n");
dirty = true;
save.setEnabled(true);
}
public void set_clean() {
+ System.out.printf("set clean\n");
dirty = false;
save.setEnabled(false);
}
@@ -912,7 +994,8 @@ public class AltosConfigFCUI
setVisible(false);
dispose();
}
- set_clean();
+ if (cmd.equals("Save") || cmd.equals("Reset"))
+ set_clean();
}
/* ItemListener interface method */
@@ -943,6 +1026,7 @@ public class AltosConfigFCUI
radio_frequency_value.set_product(product);
product_value.setText(product);
set_pad_orientation_tool_tip();
+ set_accel_tool_tips();
set_flight_log_max_tool_tip();
}
@@ -1196,6 +1280,7 @@ public class AltosConfigFCUI
}
pad_orientation_value.setVisible(new_pad_orientation != AltosLib.MISSING);
pad_orientation_label.setVisible(new_pad_orientation != AltosLib.MISSING);
+ accel_cal.setVisible(new_pad_orientation != AltosLib.MISSING);
set_pad_orientation_tool_tip();
}
@@ -1207,6 +1292,31 @@ public class AltosConfigFCUI
return AltosLib.MISSING;
}
+ public void set_accel_cal(int accel_plus, int accel_minus) {
+ if (accel_plus != AltosLib.MISSING) {
+ accel_plus_value.setText(String.format("%d", accel_plus));
+ accel_minus_value.setText(String.format("%d", accel_minus));
+ }
+ accel_plus_value.setVisible(accel_plus != AltosLib.MISSING);
+ accel_plus_label.setVisible(accel_plus != AltosLib.MISSING);
+ accel_minus_value.setVisible(accel_minus != AltosLib.MISSING);
+ accel_minus_label.setVisible(accel_minus != AltosLib.MISSING);
+
+ set_accel_tool_tips();
+ }
+
+ public int accel_cal_plus() {
+ if (accel_plus_value.isVisible())
+ return Integer.parseInt(accel_plus_value.getText());
+ return AltosLib.MISSING;
+ }
+
+ public int accel_cal_minus() {
+ if (accel_minus_value.isVisible())
+ return Integer.parseInt(accel_minus_value.getText());
+ return AltosLib.MISSING;
+ }
+
public void set_beep(int new_beep) {
if (new_beep != AltosLib.MISSING) {
int new_freq = (int) Math.floor (AltosConvert.beep_value_to_freq(new_beep) + 0.5);
diff --git a/altosuilib/AltosUIAccelCal.java b/altosuilib/AltosUIAccelCal.java
new file mode 100644
index 00000000..ea1869d0
--- /dev/null
+++ b/altosuilib/AltosUIAccelCal.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright © 2017 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, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.altusmetrum.altosuilib_12;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.beans.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import org.altusmetrum.altoslib_12.*;
+
+public class AltosUIAccelCal
+ extends AltosUIDialog
+ implements AltosAccelCalListener, ActionListener
+{
+ Frame owner;
+ AltosLink link;
+ AltosAccelCal cal;
+ AltosConfigValues config_values;
+ Thread thread;
+ Container pane;
+ JTextField message;
+ JButton antenna_up;
+ JButton antenna_down;
+ JButton ok;
+ JButton cancel;
+ boolean success;
+ int accel_plus, accel_minus;
+
+ private void make_visible() {
+ System.out.printf("Make calibration dialog visible\n");
+ pack();
+ cal.start();
+ setVisible(true);
+ }
+
+ public boolean doit() {
+ success = false;
+ make_visible();
+ return success;
+ }
+
+ public int accel_cal_plus() {
+ if (success)
+ return accel_plus;
+ return AltosLib.MISSING;
+ }
+
+ public int accel_cal_minus() {
+ if (success)
+ return accel_minus;
+ return AltosLib.MISSING;
+ }
+
+ /* AltosAccelCalListener interface */
+ public void set_thread(AltosAccelCal cal, Thread thread) {
+ this.thread = thread;
+ }
+
+ public void set_phase(AltosAccelCal cal, final int phase) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ switch (phase) {
+ case AltosAccelCal.phase_antenna_up:
+ message.setText("Orient antenna upwards and click on Antenna Up");
+ antenna_up.setEnabled(true);
+ antenna_down.setEnabled(false);
+ ok.setEnabled(false);
+ break;
+ case AltosAccelCal.phase_antenna_down:
+ message.setText("Orient antenna downwards and click on Antenna Down");
+ antenna_up.setEnabled(false);
+ antenna_down.setEnabled(true);
+ ok.setEnabled(false);
+ break;
+ }
+ }
+ });
+ }
+
+ public void cal_done(AltosAccelCal cal, int plus, int minus) {
+ accel_plus = plus;
+ accel_minus = minus;
+ success = true;
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ message.setText(String.format("Calibration succeeded, plus %d minus %d, press OK to continue", accel_plus, accel_minus));
+ antenna_up.setEnabled(false);
+ antenna_down.setEnabled(false);
+ ok.setEnabled(true);
+ }
+ });
+ }
+
+ public void message(AltosAccelCal cal, final String msg) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ message.setText(msg);
+ }
+ });
+ }
+
+ public void error(AltosAccelCal cal, String msg) {
+ message(cal, msg);
+ }
+
+ /* ActionListener interface */
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+
+ if ("up".equals(cmd)) {
+ cal.signal(true);
+ antenna_up.setEnabled(false);
+ } else if ("down".equals(cmd)) {
+ cal.signal(true);
+ antenna_down.setEnabled(false);
+ } else if ("ok".equals(cmd)) {
+ cal.signal(true);
+ this.setVisible(false);
+ if (success) {
+ System.out.printf("set accel cal to %d/%d\n", accel_plus, accel_minus);
+ config_values.set_accel_cal(accel_plus, accel_minus);
+ config_values.set_dirty();
+ }
+ try {
+ cal.abort();
+ } catch (InterruptedException ie) {
+ }
+ } else if ("cancel".equals(cmd)) {
+ cal.signal(false);
+ this.setVisible(false);
+ try {
+ cal.abort();
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+ public AltosUIAccelCal(Frame owner, AltosLink link, AltosConfigValues config_values) {
+ super(owner, "Calibrate Accelerometer", true);
+
+ this.owner = owner;
+ this.link = link;
+ this.config_values = config_values;
+
+ pane = getContentPane();
+ pane.setLayout(new GridBagLayout());
+
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(4,4,4,4);
+
+ int x = 0;
+ int y = 0;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.WEST;
+ c.gridx = x;
+ c.gridy = y;
+ c.gridwidth = 4;
+ c.gridheight = 1;
+ c.weightx = 0;
+ c.weighty = 0;
+ message = new JTextField(64);
+ pane.add(message, c);
+
+ y++; x = 0;
+
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.WEST;
+ c.gridx = x;
+ c.gridy = y;
+ c.gridwidth = 1;
+ c.gridheight = 1;
+ c.weightx = 0;
+ c.weighty = 0;
+ antenna_up = new JButton("Antenna Up");
+ antenna_up.setActionCommand("up");
+ antenna_up.setEnabled(false);
+ antenna_up.addActionListener(this);
+ pane.add(antenna_up, c);
+
+ x++;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.WEST;
+ c.gridx = x;
+ c.gridy = y;
+ c.gridwidth = 1;
+ c.gridheight = 1;
+ c.weightx = 0;
+ c.weighty = 0;
+ antenna_down = new JButton("Antenna Down");
+ antenna_down.setActionCommand("down");
+ antenna_down.setEnabled(false);
+ antenna_down.addActionListener(this);
+ pane.add(antenna_down, c);
+
+ x++;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.WEST;
+ c.gridx = x;
+ c.gridy = y;
+ c.gridwidth = 1;
+ c.gridheight = 1;
+ c.weightx = 0;
+ c.weighty = 0;
+ ok = new JButton("OK");
+ ok.setActionCommand("ok");
+ ok.setEnabled(false);
+ ok.addActionListener(this);
+ pane.add(ok, c);
+
+ x++;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.WEST;
+ c.gridx = x;
+ c.gridy = y;
+ c.gridwidth = 1;
+ c.gridheight = 1;
+ c.weightx = 0;
+ c.weighty = 0;
+ cancel = new JButton("Cancel");
+ cancel.setActionCommand("cancel");
+ cancel.setEnabled(true);
+ cancel.addActionListener(this);
+ pane.add(cancel, c);
+
+ cal = new AltosAccelCal(this.link, this);
+ }
+}
diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am
index 4b5eb524..ce86d21e 100644
--- a/altosuilib/Makefile.am
+++ b/altosuilib/Makefile.am
@@ -13,6 +13,7 @@ altosuilib_JAVA = \
AltosDevice.java \
AltosDeviceDialog.java \
AltosPositionListener.java \
+ AltosUIAccelCal.java \
AltosUIConfigure.java \
AltosUIAxis.java \
AltosUIDataMissing.java \