From 99b7eaf8d1b312443b842d078fb8464032b3a39b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Jul 2012 20:42:42 -0700 Subject: altoslib: Fix MM conversion functions Pressure is already reported in Pa, no need to convert that. Voltage divider computations were backwards. Signed-off-by: Keith Packard --- altoslib/AltosRecordMM.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'altoslib') diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java index 055cf85f..5f952f7a 100644 --- a/altoslib/AltosRecordMM.java +++ b/altoslib/AltosRecordMM.java @@ -47,7 +47,7 @@ public class AltosRecordMM extends AltosRecord { public double raw_pressure() { if (pres != MISSING) - return pres / 100.0; + return pres; return MISSING; } @@ -57,19 +57,19 @@ public class AltosRecordMM extends AltosRecord { public double ground_pressure() { if (ground_pres != MISSING) - return ground_pres / 100.0; + return ground_pres; return MISSING; } public double battery_voltage() { if (v_batt != MISSING) - return 3.3 * adc(v_batt) * 27.0 / (15.0 + 27.0); + return 3.3 * adc(v_batt) * (15.0 + 27.0) / 27.0; return MISSING; } static double pyro(int raw) { if (raw != MISSING) - return 3.3 * adc(raw) * 27.0 / (100.0 + 27.0); + return 3.3 * adc(raw) * (100.0 + 27.0) / 27.0; return MISSING; } -- cgit v1.2.3 From 97c1cfee929a35dd1596dc02ce519b80132f3c5c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Jul 2012 20:43:31 -0700 Subject: altoslib: Don't use MISSING values in max computations Early telemetry state may be missing critical data, don't use MISSING values in computing max ranges. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'altoslib') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 68c7611f..e20ec9a7 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -160,7 +160,8 @@ public class AltosState { } ngps++; } - } + } else + pad_alt = ground_altitude; gps_waiting = MIN_PAD_SAMPLES - npad; if (gps_waiting < 0) @@ -173,14 +174,14 @@ public class AltosState { boost = (AltosLib.ao_flight_boost == state); /* Only look at accelerometer data under boost */ - if (boost && acceleration > max_acceleration) + if (boost && acceleration > max_acceleration && acceleration != AltosRecord.MISSING) max_acceleration = acceleration; - if (boost && speed > max_speed) + if (boost && speed > max_speed && speed != AltosRecord.MISSING) max_speed = speed; - if (boost && baro_speed > max_baro_speed) + if (boost && baro_speed > max_baro_speed && baro_speed != AltosRecord.MISSING) max_baro_speed = baro_speed; - if (height > max_height) + if (height > max_height && height != AltosRecord.MISSING) max_height = height; if (data.gps != null) { if (gps == null || !gps.locked || data.gps.locked) -- cgit v1.2.3 From f6921c9040b1f1fc4408d163532b0695a3611195 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Jul 2012 21:04:23 -0700 Subject: altoslib: Move idle monitor managing code to altoslib More stuff to be shared (potentially) Signed-off-by: Keith Packard --- altoslib/AltosIdleMonitor.java | 445 +++++++++++++++++++++++++++++++++ altoslib/AltosIdleMonitorListener.java | 28 +++ altoslib/AltosIdleRecordTM.java | 268 ++++++++++++++++++++ altoslib/Makefile.am | 2 + altosui/AltosIdleMonitorUI.java | 266 +------------------- 5 files changed, 752 insertions(+), 257 deletions(-) create mode 100644 altoslib/AltosIdleMonitor.java create mode 100644 altoslib/AltosIdleMonitorListener.java create mode 100644 altoslib/AltosIdleRecordTM.java (limited to 'altoslib') diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java new file mode 100644 index 00000000..cd518c28 --- /dev/null +++ b/altoslib/AltosIdleMonitor.java @@ -0,0 +1,445 @@ +/* + * Copyright © 2010 Keith Packard + * + * 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 org.altusmetrum.AltosLib; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.*; + +class AltosSensorTM { + int tick; + int accel; + int pres; + int temp; + int batt; + int drogue; + int main; + + public AltosSensorTM(AltosLink link) throws InterruptedException, TimeoutException { + link.printf("a\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (!line.startsWith("tick:")) + continue; + String[] items = line.split("\\s+"); + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("accel:")) { + accel = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("pres:")) { + pres = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("temp:")) { + temp = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("batt:")) { + batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("drogue:")) { + drogue = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("main:")) { + main = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + break; + } + } +} + +class AltosSensorMM { + int tick; + int sense[]; + int v_batt; + int v_pyro; + int accel; + int accel_ref; + + public AltosSensorMM(AltosLink link) throws InterruptedException, TimeoutException { + link.printf("a\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (!line.startsWith("tick:")) + continue; + String[] items = line.split("\\s+"); + sense = new int[6]; + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("0:")) { + sense[0] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("1:")) { + sense[1] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("2:")) { + sense[2] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("3:")) { + sense[3] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("4:")) { + sense[4] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("5:")) { + sense[5] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("6:")) { + v_batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("7:")) { + v_pyro = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("8:")) { + accel = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("9:")) { + accel_ref = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + for (int i = 0; i < sense.length; i++) + System.out.printf("sense[%d]: %d\n", i, sense[i]); + break; + } + } +} + +class AltosIMUQuery extends AltosIMU { + + public AltosIMUQuery (AltosLink link) throws InterruptedException, TimeoutException { + link.printf("I\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (!line.startsWith("Accel:")) + continue; + String[] items = line.split("\\s+"); + if (items.length >= 8) { + accel_x = Integer.parseInt(items[1]); + accel_y = Integer.parseInt(items[2]); + accel_z = Integer.parseInt(items[3]); + gyro_x = Integer.parseInt(items[5]); + gyro_y = Integer.parseInt(items[6]); + gyro_z = Integer.parseInt(items[7]); + } + break; + } + } +} + +class AltosMs5607Query extends AltosMs5607 { + public AltosMs5607Query (AltosLink link) throws InterruptedException, TimeoutException { + link.printf("v\nB\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + String[] items = line.split("\\s+"); + if (line.startsWith("Pressure:")) { + if (items.length >= 2) + raw_pres = Integer.parseInt(items[1]); + } else if (line.startsWith("Temperature:")) { + if (items.length >= 2) + raw_temp = Integer.parseInt(items[1]); + } else if (line.startsWith("ms5607 reserved:")) { + if (items.length >= 3) + reserved = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 sens:")) { + if (items.length >= 3) + sens = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 off:")) { + if (items.length >= 3) + off = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 tcs:")) { + if (items.length >= 3) + tcs = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 tco:")) { + if (items.length >= 3) + tco = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 tref:")) { + if (items.length >= 3) + tref = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 tempsens:")) { + if (items.length >= 3) + tempsens = Integer.parseInt(items[2]); + } else if (line.startsWith("ms5607 crc:")) { + if (items.length >= 3) + crc = Integer.parseInt(items[2]); + } else if (line.startsWith("Altitude")) + break; + } + convert(); + } +} + +class AltosGPSQuery extends AltosGPS { + public AltosGPSQuery (AltosLink link, AltosConfigData config_data) + throws TimeoutException, InterruptedException { + boolean says_done = config_data.compare_version("1.0") >= 0; + link.printf("g\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) + throw new TimeoutException(); + String[] bits = line.split("\\s+"); + if (bits.length == 0) + continue; + if (line.startsWith("Date:")) { + if (bits.length < 2) + continue; + String[] d = bits[1].split(":"); + if (d.length < 3) + continue; + year = Integer.parseInt(d[0]) + 2000; + month = Integer.parseInt(d[1]); + day = Integer.parseInt(d[2]); + continue; + } + if (line.startsWith("Time:")) { + if (bits.length < 2) + continue; + String[] d = bits[1].split("/"); + if (d.length < 3) + continue; + hour = Integer.parseInt(d[0]); + minute = Integer.parseInt(d[1]); + second = Integer.parseInt(d[2]); + continue; + } + if (line.startsWith("Lat/Lon:")) { + if (bits.length < 3) + continue; + lat = Integer.parseInt(bits[1]) * 1.0e-7; + lon = Integer.parseInt(bits[2]) * 1.0e-7; + continue; + } + if (line.startsWith("Alt:")) { + if (bits.length < 2) + continue; + alt = Integer.parseInt(bits[1]); + continue; + } + if (line.startsWith("Flags:")) { + if (bits.length < 2) + continue; + int status = Integer.decode(bits[1]); + connected = (status & AltosLib.AO_GPS_RUNNING) != 0; + locked = (status & AltosLib.AO_GPS_VALID) != 0; + if (!says_done) + break; + continue; + } + if (line.startsWith("Sats:")) { + if (bits.length < 2) + continue; + nsat = Integer.parseInt(bits[1]); + cc_gps_sat = new AltosGPSSat[nsat]; + for (int i = 0; i < nsat; i++) { + int svid = Integer.parseInt(bits[2+i*2]); + int cc_n0 = Integer.parseInt(bits[3+i*2]); + cc_gps_sat[i] = new AltosGPSSat(svid, cc_n0); + } + } + if (line.startsWith("done")) + break; + if (line.startsWith("Syntax error")) + break; + } + } +} + +public class AltosIdleMonitor extends Thread { + AltosLink link; + AltosIdleMonitorListener listener; + AltosState state; + boolean remote; + double frequency; + AltosState previous_state; + AltosConfigData config_data; + AltosGPS gps; + + int AltosRSSI() throws TimeoutException, InterruptedException { + link.printf("s\n"); + String line = link.get_reply_no_dialog(5000); + if (line == null) + throw new TimeoutException(); + String[] items = line.split("\\s+"); + if (items.length < 2) + return 0; + if (!items[0].equals("RSSI:")) + return 0; + int rssi = Integer.parseInt(items[1]); + return rssi; + } + + void update_state() throws InterruptedException, TimeoutException { + AltosRecord record; + int rssi; + + try { + if (remote) { + link.set_radio_frequency(frequency); + link.start_remote(); + } else + link.flush_input(); + config_data = new AltosConfigData(link); + if (config_data.product.startsWith("TeleMetrum")) { + AltosRecordTM record_tm = new AltosRecordTM(); + AltosSensorTM sensor = new AltosSensorTM(link); + record_tm.accel = sensor.accel; + record_tm.pres = sensor.pres; + record_tm.batt = sensor.batt; + record_tm.temp = sensor.temp; + record_tm.drogue = sensor.drogue; + record_tm.main = sensor.main; + record_tm.ground_accel = record_tm.accel; + record_tm.ground_pres = record_tm.pres; + record_tm.accel_plus_g = config_data.accel_cal_plus; + record_tm.accel_minus_g = config_data.accel_cal_minus; + record_tm.tick = sensor.tick; + record = record_tm; + } else if (config_data.product.startsWith("MegaMetrum")) { + AltosRecordMM record_mm = new AltosRecordMM(); + AltosSensorMM sensor = new AltosSensorMM(link); + AltosMs5607 ms5607 = new AltosMs5607Query(link); + AltosIMU imu = new AltosIMUQuery(link); + + record_mm.accel_plus_g = config_data.accel_cal_plus; + record_mm.accel_minus_g = config_data.accel_cal_minus; + + record_mm.ground_accel = sensor.accel; + record_mm.accel = sensor.accel; + record_mm.ground_pres = ms5607.pa; + record_mm.pres = ms5607.pa; + record_mm.temp = ms5607.cc; + + record_mm.v_batt = sensor.v_batt; + record_mm.v_pyro = sensor.v_pyro; + record_mm.sense = sensor.sense; + + record_mm.imu = imu; + + record = record_mm; + } else + record = new AltosRecord(); + + gps = new AltosGPSQuery(link, config_data); + } finally { + if (remote) { + link.stop_remote(); + rssi = AltosRSSI(); + } else + rssi = 0; + } + + record.version = 0; + record.callsign = config_data.callsign; + record.serial = config_data.serial; + record.flight = config_data.log_available() > 0 ? 255 : 0; + record.rssi = rssi; + record.status = 0; + record.state = AltosLib.ao_flight_idle; + + record.gps = gps; + state = new AltosState (record, state); + } + + public void set_frequency(double in_frequency) { + frequency = in_frequency; + } + + public void post_state() { + listener.update(state); + } + + public void run() { + try { + for (;;) { + try { + update_state(); + post_state(); + } catch (TimeoutException te) { + } + Thread.sleep(1000); + } + } catch (InterruptedException ie) { + link.close(); + } + } + + public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote) + throws FileNotFoundException, InterruptedException, TimeoutException { + listener = in_listener; + link = in_link; + remote = in_remote; + state = null; + } +} diff --git a/altoslib/AltosIdleMonitorListener.java b/altoslib/AltosIdleMonitorListener.java new file mode 100644 index 00000000..3c18bfaa --- /dev/null +++ b/altoslib/AltosIdleMonitorListener.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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 org.altusmetrum.AltosLib; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.*; + +public interface AltosIdleMonitorListener { + public void update(AltosState state); +} \ No newline at end of file diff --git a/altoslib/AltosIdleRecordTM.java b/altoslib/AltosIdleRecordTM.java new file mode 100644 index 00000000..112b847e --- /dev/null +++ b/altoslib/AltosIdleRecordTM.java @@ -0,0 +1,268 @@ +/* + * Copyright © 2012 Keith Packard + * + * 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 org.altusmetrum.AltosLib; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.*; + +class AltosADCTM { + int tick; + int accel; + int pres; + int temp; + int batt; + int drogue; + int main; + + public AltosADCTM(AltosLink link) throws InterruptedException, TimeoutException { + link.printf("a\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (!line.startsWith("tick:")) + continue; + String[] items = line.split("\\s+"); + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("accel:")) { + accel = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("pres:")) { + pres = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("temp:")) { + temp = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("batt:")) { + batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("drogue:")) { + drogue = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("main:")) { + main = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + break; + } + } +} + +class AltosGPSQuery extends AltosGPS { + public AltosGPSQuery (AltosLink link, AltosConfigData config_data) + throws TimeoutException, InterruptedException { + boolean says_done = config_data.compare_version("1.0") >= 0; + link.printf("g\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) + throw new TimeoutException(); + String[] bits = line.split("\\s+"); + if (bits.length == 0) + continue; + if (line.startsWith("Date:")) { + if (bits.length < 2) + continue; + String[] d = bits[1].split(":"); + if (d.length < 3) + continue; + year = Integer.parseInt(d[0]) + 2000; + month = Integer.parseInt(d[1]); + day = Integer.parseInt(d[2]); + continue; + } + if (line.startsWith("Time:")) { + if (bits.length < 2) + continue; + String[] d = bits[1].split("/"); + if (d.length < 3) + continue; + hour = Integer.parseInt(d[0]); + minute = Integer.parseInt(d[1]); + second = Integer.parseInt(d[2]); + continue; + } + if (line.startsWith("Lat/Lon:")) { + if (bits.length < 3) + continue; + lat = Integer.parseInt(bits[1]) * 1.0e-7; + lon = Integer.parseInt(bits[2]) * 1.0e-7; + continue; + } + if (line.startsWith("Alt:")) { + if (bits.length < 2) + continue; + alt = Integer.parseInt(bits[1]); + continue; + } + if (line.startsWith("Flags:")) { + if (bits.length < 2) + continue; + int status = Integer.decode(bits[1]); + connected = (status & AltosLib.AO_GPS_RUNNING) != 0; + locked = (status & AltosLib.AO_GPS_VALID) != 0; + if (!says_done) + break; + continue; + } + if (line.startsWith("Sats:")) { + if (bits.length < 2) + continue; + nsat = Integer.parseInt(bits[1]); + cc_gps_sat = new AltosGPSSat[nsat]; + for (int i = 0; i < nsat; i++) { + int svid = Integer.parseInt(bits[2+i*2]); + int cc_n0 = Integer.parseInt(bits[3+i*2]); + cc_gps_sat[i] = new AltosGPSSat(svid, cc_n0); + } + } + if (line.startsWith("done")) + break; + if (line.startsWith("Syntax error")) + break; + } + } +} + +public class AltosIdleMonitor extends Thread { + AltosLink link; + AltosIdleMonitorListener listener; + AltosState state; + boolean remote; + double frequency; + AltosState previous_state; + AltosConfigData config_data; + AltosADC adc; + AltosGPS gps; + + int AltosRSSI() throws TimeoutException, InterruptedException { + link.printf("s\n"); + String line = link.get_reply_no_dialog(5000); + if (line == null) + throw new TimeoutException(); + String[] items = line.split("\\s+"); + if (items.length < 2) + return 0; + if (!items[0].equals("RSSI:")) + return 0; + int rssi = Integer.parseInt(items[1]); + return rssi; + } + + void update_state() throws InterruptedException, TimeoutException { + AltosRecordTM record = new AltosRecordTM(); + int rssi; + + try { + if (remote) { + link.set_radio_frequency(frequency); + link.start_remote(); + } else + link.flush_input(); + config_data = new AltosConfigData(link); + adc = new AltosADC(link); + gps = new AltosGPSQuery(link, config_data); + } finally { + if (remote) { + link.stop_remote(); + rssi = AltosRSSI(); + } else + rssi = 0; + } + + record.version = 0; + record.callsign = config_data.callsign; + record.serial = config_data.serial; + record.flight = config_data.log_available() > 0 ? 255 : 0; + record.rssi = rssi; + record.status = 0; + record.state = AltosLib.ao_flight_idle; + + record.tick = adc.tick; + + record.accel = adc.accel; + record.pres = adc.pres; + record.batt = adc.batt; + record.temp = adc.temp; + record.drogue = adc.drogue; + record.main = adc.main; + + record.ground_accel = record.accel; + record.ground_pres = record.pres; + record.accel_plus_g = config_data.accel_cal_plus; + record.accel_minus_g = config_data.accel_cal_minus; + record.acceleration = 0; + record.speed = 0; + record.height = 0; + record.gps = gps; + state = new AltosState (record, state); + } + + public void set_frequency(double in_frequency) { + frequency = in_frequency; + } + + public void post_state() { + listener.update(state); + } + + public void run() { + try { + for (;;) { + try { + update_state(); + post_state(); + } catch (TimeoutException te) { + } + Thread.sleep(1000); + } + } catch (InterruptedException ie) { + link.close(); + } + } + + public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote) + throws FileNotFoundException, InterruptedException, TimeoutException { + listener = in_listener; + link = in_link; + remote = in_remote; + state = null; + } +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index ac97c9cb..a39623ee 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -27,6 +27,8 @@ AltosLib_JAVA = \ $(SRC)/AltosGPS.java \ $(SRC)/AltosGPSSat.java \ $(SRC)/AltosGreatCircle.java \ + $(SRC)/AltosIdleMonitor.java \ + $(SRC)/AltosIdleMonitorListener.java \ $(SRC)/AltosLine.java \ $(SRC)/AltosLink.java \ $(SRC)/AltosLog.java \ diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index ce608d2b..46ca3e5d 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -29,260 +29,7 @@ import java.util.prefs.*; import java.util.concurrent.*; import org.altusmetrum.AltosLib.*; -class AltosADC { - int tick; - int accel; - int pres; - int temp; - int batt; - int drogue; - int main; - - public AltosADC(AltosSerial serial) throws InterruptedException, TimeoutException { - serial.printf("a\n"); - for (;;) { - String line = serial.get_reply_no_dialog(5000); - if (line == null) { - throw new TimeoutException(); - } - if (!line.startsWith("tick:")) - continue; - String[] items = line.split("\\s+"); - for (int i = 0; i < items.length;) { - if (items[i].equals("tick:")) { - tick = Integer.parseInt(items[i+1]); - i += 2; - continue; - } - if (items[i].equals("accel:")) { - accel = Integer.parseInt(items[i+1]); - i += 2; - continue; - } - if (items[i].equals("pres:")) { - pres = Integer.parseInt(items[i+1]); - i += 2; - continue; - } - if (items[i].equals("temp:")) { - temp = Integer.parseInt(items[i+1]); - i += 2; - continue; - } - if (items[i].equals("batt:")) { - batt = Integer.parseInt(items[i+1]); - i += 2; - continue; - } - if (items[i].equals("drogue:")) { - drogue = Integer.parseInt(items[i+1]); - i += 2; - continue; - } - if (items[i].equals("main:")) { - main = Integer.parseInt(items[i+1]); - i += 2; - continue; - } - i++; - } - break; - } - } -} - -class AltosGPSQuery extends AltosGPS { - public AltosGPSQuery (AltosSerial serial, AltosConfigData config_data) - throws TimeoutException, InterruptedException { - boolean says_done = config_data.compare_version("1.0") >= 0; - serial.printf("g\n"); - for (;;) { - String line = serial.get_reply_no_dialog(5000); - if (line == null) - throw new TimeoutException(); - String[] bits = line.split("\\s+"); - if (bits.length == 0) - continue; - if (line.startsWith("Date:")) { - if (bits.length < 2) - continue; - String[] d = bits[1].split(":"); - if (d.length < 3) - continue; - year = Integer.parseInt(d[0]) + 2000; - month = Integer.parseInt(d[1]); - day = Integer.parseInt(d[2]); - continue; - } - if (line.startsWith("Time:")) { - if (bits.length < 2) - continue; - String[] d = bits[1].split("/"); - if (d.length < 3) - continue; - hour = Integer.parseInt(d[0]); - minute = Integer.parseInt(d[1]); - second = Integer.parseInt(d[2]); - continue; - } - if (line.startsWith("Lat/Lon:")) { - if (bits.length < 3) - continue; - lat = Integer.parseInt(bits[1]) * 1.0e-7; - lon = Integer.parseInt(bits[2]) * 1.0e-7; - continue; - } - if (line.startsWith("Alt:")) { - if (bits.length < 2) - continue; - alt = Integer.parseInt(bits[1]); - continue; - } - if (line.startsWith("Flags:")) { - if (bits.length < 2) - continue; - int status = Integer.decode(bits[1]); - connected = (status & Altos.AO_GPS_RUNNING) != 0; - locked = (status & Altos.AO_GPS_VALID) != 0; - if (!says_done) - break; - continue; - } - if (line.startsWith("Sats:")) { - if (bits.length < 2) - continue; - nsat = Integer.parseInt(bits[1]); - cc_gps_sat = new AltosGPSSat[nsat]; - for (int i = 0; i < nsat; i++) { - int svid = Integer.parseInt(bits[2+i*2]); - int cc_n0 = Integer.parseInt(bits[3+i*2]); - cc_gps_sat[i] = new AltosGPSSat(svid, cc_n0); - } - } - if (line.startsWith("done")) - break; - if (line.startsWith("Syntax error")) - break; - } - } -} - -class AltosIdleMonitor extends Thread { - AltosDevice device; - AltosSerial serial; - AltosIdleMonitorUI ui; - AltosState state; - boolean remote; - double frequency; - AltosState previous_state; - AltosConfigData config_data; - AltosADC adc; - AltosGPS gps; - - int AltosRSSI() throws TimeoutException, InterruptedException { - serial.printf("s\n"); - String line = serial.get_reply_no_dialog(5000); - if (line == null) - throw new TimeoutException(); - String[] items = line.split("\\s+"); - if (items.length < 2) - return 0; - if (!items[0].equals("RSSI:")) - return 0; - int rssi = Integer.parseInt(items[1]); - return rssi; - } - - void update_state() throws InterruptedException, TimeoutException { - AltosRecordTM record = new AltosRecordTM(); - int rssi; - - try { - if (remote) { - serial.set_radio_frequency(frequency); - serial.start_remote(); - } else - serial.flush_input(); - config_data = new AltosConfigData(serial); - adc = new AltosADC(serial); - gps = new AltosGPSQuery(serial, config_data); - } finally { - if (remote) { - serial.stop_remote(); - rssi = AltosRSSI(); - } else - rssi = 0; - } - - record.version = 0; - record.callsign = config_data.callsign; - record.serial = config_data.serial; - record.flight = config_data.log_available() > 0 ? 255 : 0; - record.rssi = rssi; - record.status = 0; - record.state = Altos.ao_flight_idle; - - record.tick = adc.tick; - - record.accel = adc.accel; - record.pres = adc.pres; - record.batt = adc.batt; - record.temp = adc.temp; - record.drogue = adc.drogue; - record.main = adc.main; - - record.ground_accel = record.accel; - record.ground_pres = record.pres; - record.accel_plus_g = config_data.accel_cal_plus; - record.accel_minus_g = config_data.accel_cal_minus; - record.acceleration = 0; - record.speed = 0; - record.height = 0; - record.gps = gps; - state = new AltosState (record, state); - } - - void set_frequency(double in_frequency) { - frequency = in_frequency; - } - - public void post_state() { - Runnable r = new Runnable() { - public void run() { - ui.update(state); - } - }; - SwingUtilities.invokeLater(r); - } - - public void run() { - try { - for (;;) { - try { - update_state(); - post_state(); - } catch (TimeoutException te) { - if (AltosSerial.debug) - System.out.printf ("monitor idle data timeout\n"); - } - Thread.sleep(1000); - } - } catch (InterruptedException ie) { - serial.close(); - } - } - - public AltosIdleMonitor(AltosIdleMonitorUI in_ui, AltosDevice in_device, boolean in_remote) - throws FileNotFoundException, AltosSerialInUseException, InterruptedException, TimeoutException { - device = in_device; - ui = in_ui; - serial = new AltosSerial(device); - remote = in_remote; - state = null; - } -} - -public class AltosIdleMonitorUI extends AltosFrame implements AltosFlightDisplay, AltosFontListener { +public class AltosIdleMonitorUI extends AltosFrame implements AltosFlightDisplay, AltosFontListener, AltosIdleMonitorListener { AltosDevice device; JTabbedPane pane; AltosPad pad; @@ -333,8 +80,13 @@ public class AltosIdleMonitorUI extends AltosFrame implements AltosFlightDisplay } } - public void update(AltosState state) { - show (state, 0); + public void update(final AltosState state) { + Runnable r = new Runnable() { + public void run() { + show(state, 0); + } + }; + SwingUtilities.invokeLater(r); } Container bag; @@ -427,7 +179,7 @@ public class AltosIdleMonitorUI extends AltosFrame implements AltosFlightDisplay pack(); setVisible(true); - thread = new AltosIdleMonitor(this, device, remote); + thread = new AltosIdleMonitor((AltosIdleMonitorListener) this, (AltosLink) new AltosSerial (device), (boolean) remote); status_update = new AltosFlightStatusUpdate(flightStatus); -- cgit v1.2.3 From f164e48cbeff521d45737794e2046a08322951d6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Jul 2012 00:01:51 -0700 Subject: altosui: Make scan UI handle incremental telem data The new telem format doesn't send everything in each telem packet, so we need to handle updating information incrementally in the scan results. This involved clearing old scan data when switching frequencies and then updating existing entries with new data as it arrives. Signed-off-by: Keith Packard --- altoslib/AltosIdleMonitor.java | 2 -- altoslib/AltosTelemetryReader.java | 5 +++++ altosui/AltosScanUI.java | 42 +++++++++++++++++++++++++++++--------- 3 files changed, 37 insertions(+), 12 deletions(-) (limited to 'altoslib') diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index cd518c28..57c4da71 100644 --- a/altoslib/AltosIdleMonitor.java +++ b/altoslib/AltosIdleMonitor.java @@ -162,8 +162,6 @@ class AltosSensorMM { } i++; } - for (int i = 0; i < sense.length; i++) - System.out.printf("sense[%d]: %d\n", i, sense[i]); break; } } diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index 911a099a..bdb44eef 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -44,6 +44,11 @@ public class AltosTelemetryReader extends AltosFlightReader { telem.clear(); } + public void reset() { + previous = null; + flush(); + } + public void close(boolean interrupted) { link.remove_monitor(telem); log.close(); diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 44eeda6d..ef6389b6 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -59,29 +59,50 @@ class AltosScanResult { } public boolean equals(AltosScanResult other) { - return (callsign.equals(other.callsign) && - serial == other.serial && - flight == other.flight && + return (serial == other.serial && frequency.frequency == other.frequency.frequency && telemetry == other.telemetry); } + + public boolean up_to_date(AltosScanResult other) { + if (flight == 0 && other.flight != 0) { + flight = other.flight; + return false; + } + if (callsign.equals("N0CALL") && !other.callsign.equals("N0CALL")) { + callsign = other.callsign; + return false; + } + return true; + } } class AltosScanResults extends LinkedList implements ListModel { LinkedList listeners = new LinkedList(); + void changed(ListDataEvent de) { + for (ListDataListener l : listeners) + l.contentsChanged(de); + } + public boolean add(AltosScanResult r) { - for (AltosScanResult old : this) - if (old.equals(r)) + int i = 0; + for (AltosScanResult old : this) { + if (old.equals(r)) { + if (!old.up_to_date(r)) + changed (new ListDataEvent(this, + ListDataEvent.CONTENTS_CHANGED, + i, i)); return true; + } + i++; + } super.add(r); - ListDataEvent de = new ListDataEvent(this, - ListDataEvent.INTERVAL_ADDED, - this.size() - 2, this.size() - 1); - for (ListDataListener l : listeners) - l.contentsChanged(de); + changed(new ListDataEvent(this, + ListDataEvent.INTERVAL_ADDED, + this.size() - 2, this.size() - 1)); return true; } @@ -205,6 +226,7 @@ public class AltosScanUI void set_frequency() throws InterruptedException, TimeoutException { reader.set_frequency(frequencies[frequency_index].frequency); + reader.reset(); } void next() throws InterruptedException, TimeoutException { -- cgit v1.2.3