231 lines
6.7 KiB
Java
231 lines
6.7 KiB
Java
/*
|
|
* 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_14;
|
|
|
|
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 {
|
|
int plus = config_data.accel_cal_plus(config_data.pad_orientation);
|
|
int minus = config_data.accel_cal_minus(config_data.pad_orientation);
|
|
System.out.printf("Restore orientation %d +g %d -g %d\n",
|
|
config_data.pad_orientation,
|
|
plus, minus);
|
|
if (config_data.pad_orientation != AltosLib.MISSING)
|
|
link.printf("c o %d\n", config_data.pad_orientation);
|
|
if (plus != AltosLib.MISSING && minus != AltosLib.MISSING && plus != 0) {
|
|
if (plus < 0)
|
|
plus = 65536 + plus;
|
|
if (minus < 0)
|
|
minus = 65536 + minus;
|
|
if (config_data.accel_zero_along != AltosLib.MISSING)
|
|
link.printf("c a %d %d %d %d %d\n",
|
|
plus, minus,
|
|
config_data.accel_zero_along,
|
|
config_data.accel_zero_across,
|
|
config_data.accel_zero_through);
|
|
else
|
|
link.printf("c a %d %d\n", plus, minus);
|
|
}
|
|
link.flush_output();
|
|
stop_link();
|
|
}
|
|
if (new_config != null) {
|
|
int plus = new_config.accel_cal_plus(AltosLib.AO_PAD_ORIENTATION_ANTENNA_UP);
|
|
int minus = new_config.accel_cal_minus(AltosLib.AO_PAD_ORIENTATION_ANTENNA_UP);
|
|
System.out.printf("*** +1g %d -1g %d\n", plus, minus);
|
|
listener.cal_done(this, plus, 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);
|
|
}
|
|
}
|