From 1f5a453cb4650fc97cc990a9e42242278c29cc04 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 13:42:00 -0700 Subject: altoslib: MegaMetrum eeprom never loses GPS date TeleMetrum had a firmware bug that would fail to record the GPS date and time correctly, that was hacked around in altosui, but isn't needed for MegaMetrum. Remove those hacks from the MM path. Signed-off-by: Keith Packard --- altoslib/AltosEepromMega.java | 7 +--- altoslib/AltosEepromMegaIterable.java | 76 ----------------------------------- altoslib/AltosOrderedMegaRecord.java | 12 ------ 3 files changed, 1 insertion(+), 94 deletions(-) (limited to 'altoslib') diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 26bacf8d..25a29fb2 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -66,12 +66,7 @@ public class AltosEepromMega { public int mag_x() { return data16(20); } public int mag_y() { return data16(22); } public int mag_z() { return data16(24); } - public int accel() { - int a = data16(26); - if (a != 0xffff) - return a; - return accel_y(); - } + public int accel() { return data16(26); } /* AO_LOG_VOLT elements */ public int v_batt() { return data16(0); } diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java index 1ab2fcc8..003bff44 100644 --- a/altoslib/AltosEepromMegaIterable.java +++ b/altoslib/AltosEepromMegaIterable.java @@ -347,40 +347,6 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { } } - /* - * Given an AO_LOG_GPS_TIME record with correct time, and one - * missing time, rewrite the missing time values with the good - * ones, assuming that the difference between them is 'diff' seconds - */ - void update_time(AltosOrderedMegaRecord good, AltosOrderedMegaRecord bad) { - - int diff = (bad.tick - good.tick + 50) / 100; - - int hour = (good.a & 0xff); - int minute = (good.a >> 8); - int second = (good.b & 0xff); - int flags = (good.b >> 8); - int seconds = hour * 3600 + minute * 60 + second; - - /* Make sure this looks like a good GPS value */ - if ((flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT < 4) - flags = (flags & ~AltosLib.AO_GPS_NUM_SAT_MASK) | (4 << AltosLib.AO_GPS_NUM_SAT_SHIFT); - flags |= AltosLib.AO_GPS_RUNNING; - flags |= AltosLib.AO_GPS_VALID; - - int new_seconds = seconds + diff; - if (new_seconds < 0) - new_seconds += 24 * 3600; - int new_second = (new_seconds % 60); - int new_minutes = (new_seconds / 60); - int new_minute = (new_minutes % 60); - int new_hours = (new_minutes / 60); - int new_hour = (new_hours % 24); - - bad.a = new_hour + (new_minute << 8); - bad.b = new_second + (flags << 8); - } - /* * Read the whole file, dumping records into a RB tree so * we can enumerate them in time order -- the eeprom data @@ -416,48 +382,6 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { continue; } - /* Two firmware bugs caused the loss of some GPS data. - * The flight date would never be recorded, and often - * the flight time would get overwritten by another - * record. Detect the loss of the GPS date and fix up the - * missing time records - */ - if (record.cmd == AltosLib.AO_LOG_GPS_DATE) { - gps_date_record = record; - continue; - } - - /* go back and fix up any missing time values */ - if (record.cmd == AltosLib.AO_LOG_GPS_TIME) { - last_gps_time = record; - if (missing_time) { - Iterator iterator = records.iterator(); - while (iterator.hasNext()) { - AltosOrderedMegaRecord old = iterator.next(); - if (old.cmd == AltosLib.AO_LOG_GPS_TIME && - old.a == -1 && old.b == -1) - { - update_time(record, old); - } - } - missing_time = false; - } - } - - if (record.cmd == AltosLib.AO_LOG_GPS_LAT) { - if (last_gps_time == null || last_gps_time.tick != record.tick) { - AltosOrderedMegaRecord add_gps_time = new AltosOrderedMegaRecord(AltosLib.AO_LOG_GPS_TIME, - record.tick, - -1, -1, index-1); - if (last_gps_time != null) - update_time(last_gps_time, add_gps_time); - else - missing_time = true; - - records.add(add_gps_time); - record.index = index++; - } - } records.add(record); /* Bail after reading the 'landed' record; we're all done */ diff --git a/altoslib/AltosOrderedMegaRecord.java b/altoslib/AltosOrderedMegaRecord.java index 05423dd9..3aaf7b5b 100644 --- a/altoslib/AltosOrderedMegaRecord.java +++ b/altoslib/AltosOrderedMegaRecord.java @@ -43,18 +43,6 @@ class AltosOrderedMegaRecord extends AltosEepromMega implements Comparable Date: Sun, 21 Oct 2012 14:10:32 -0700 Subject: altoslib: remove a couple of TM log record types from MM log parsing PRESSURE and DEPLOY log records don't occurin MM eeprom files. Signed-off-by: Keith Packard --- altoslib/AltosEepromMegaIterable.java | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'altoslib') diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java index 003bff44..50f9d33d 100644 --- a/altoslib/AltosEepromMegaIterable.java +++ b/altoslib/AltosEepromMegaIterable.java @@ -106,15 +106,6 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { eeprom.sensor_tick = record.tick; has_accel = true; break; - case AltosLib.AO_LOG_PRESSURE: - state.pres = record.b; - state.flight_pres = state.pres; - if (eeprom.n_pad_samples == 0) { - eeprom.n_pad_samples++; - state.ground_pres = state.pres; - } - eeprom.seen |= seen_sensor; - break; case AltosLib.AO_LOG_TEMP_VOLT: state.v_batt = record.v_batt(); state.v_pyro = record.v_pbatt(); @@ -122,14 +113,6 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { state.sense[i] = record.sense(i); eeprom.seen |= seen_temp_volt; break; -// -// case AltosLib.AO_LOG_DEPLOY: -// state.drogue = record.a; -// state.main = record.b; -// eeprom.seen |= seen_deploy; -// has_ignite = true; -// break; - case AltosLib.AO_LOG_STATE: state.state = record.state(); break; -- cgit v1.2.3 From dec2e455935a71dec13b84bb886252b7f4a1a641 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 14:11:07 -0700 Subject: altoslib: Compute accelerometer speed from megametrum eeprom data Duplicates code from the TM eeprom state tracking code. Signed-off-by: Keith Packard --- altoslib/AltosRecordMM.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'altoslib') diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java index 5f952f7a..63b37f82 100644 --- a/altoslib/AltosRecordMM.java +++ b/altoslib/AltosRecordMM.java @@ -111,7 +111,11 @@ public class AltosRecordMM extends AltosRecord { } public double accel_speed() { - return speed; + if (speed != MISSING) + return speed; + if (flight_vel == MISSING) + return MISSING; + return flight_vel / (accel_counts_per_mss() * 100.0); } public void copy (AltosRecordMM old) { -- cgit v1.2.3 From 7894c27b2b2c3c46a7c107c8acd5977830f006cf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 16:13:14 -0700 Subject: altoslib: Move computed state from AltosRecord to AltosState Make AltosRecord simply track the raw data and have AltosState hold all computed values, including cross-packet averages and computed speeds. Signed-off-by: Keith Packard --- altoslib/AltosIdleMonitor.java | 2 +- altoslib/AltosRecord.java | 99 +++++++++++------------------- altoslib/AltosRecordMM.java | 18 +----- altoslib/AltosRecordTM.java | 21 +------ altoslib/AltosState.java | 69 ++++++++++++++++----- altoslib/AltosTelemetryRecordLegacy.java | 24 ++++---- altoslib/AltosTelemetryRecordMegaData.java | 6 +- altoslib/AltosTelemetryRecordRaw.java | 2 +- altoslib/AltosTelemetryRecordSensor.java | 6 +- altoslib/Makefile.am | 1 + altosui/AltosAscent.java | 2 +- altosui/AltosCSV.java | 8 +-- altosui/AltosDataPoint.java | 5 +- altosui/AltosDataPointReader.java | 47 +++++++------- altosui/AltosDescent.java | 2 +- altosui/AltosDisplayThread.java | 2 +- altosui/AltosFlightStats.java | 10 +-- altosui/AltosGraphUI.java | 7 +-- altosui/AltosInfoTable.java | 4 +- altosui/AltosKML.java | 2 +- altosui/AltosLanded.java | 2 +- 21 files changed, 153 insertions(+), 186 deletions(-) (limited to 'altoslib') diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index 2c4965ff..07d8930d 100644 --- a/altoslib/AltosIdleMonitor.java +++ b/altoslib/AltosIdleMonitor.java @@ -97,7 +97,7 @@ public class AltosIdleMonitor extends Thread { else if (has_sensor_mm(config_data)) record = sensor_mm(config_data); else - record = new AltosRecord(); + record = new AltosRecordNone(); if (has_gps(config_data)) gps = new AltosGPSQuery(link, config_data); diff --git a/altoslib/AltosRecord.java b/altoslib/AltosRecord.java index 8bab1d0c..09169515 100644 --- a/altoslib/AltosRecord.java +++ b/altoslib/AltosRecord.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosLib; -public class AltosRecord implements Comparable , Cloneable { +public abstract class AltosRecord implements Comparable , Cloneable { public static final int seen_flight = 1; public static final int seen_sensor = 2; @@ -43,11 +43,6 @@ public class AltosRecord implements Comparable , Cloneable { public int state; public int tick; - /* Current flight dynamic state */ - public double acceleration; /* m/s² */ - public double speed; /* m/s */ - public double height; /* m */ - public AltosGPS gps; public boolean new_gps; @@ -63,6 +58,11 @@ public class AltosRecord implements Comparable , Cloneable { public AltosRecordCompanion companion; + /* Telemetry sources have these values recorded from the flight computer */ + public double kalman_height; + public double kalman_speed; + public double kalman_acceleration; + /* * Abstract methods that convert record data * to standard units: @@ -75,76 +75,48 @@ public class AltosRecord implements Comparable , Cloneable { * temperature: °C */ - public double raw_pressure() { return MISSING; } - - public double filtered_pressure() { return MISSING; } - - public double ground_pressure() { return MISSING; } - - public double battery_voltage() { return MISSING; } + abstract public double pressure(); + abstract public double ground_pressure(); + abstract public double acceleration(); - public double main_voltage() { return MISSING; } + public double altitude() { + double p = pressure(); - public double drogue_voltage() { return MISSING; } - - public double temperature() { return MISSING; } - - public double acceleration() { return MISSING; } - - public double accel_speed() { return MISSING; } - - public AltosIMU imu() { return null; } - - public AltosMag mag() { return null; } - - /* - * Convert various pressure values to altitude - */ - - public double raw_altitude() { - double p = raw_pressure(); if (p == MISSING) return MISSING; return AltosConvert.pressure_to_altitude(p); } public double ground_altitude() { - double p = ground_pressure(); + double p = ground_pressure(); + if (p == MISSING) return MISSING; return AltosConvert.pressure_to_altitude(p); } - public double filtered_altitude() { - double ga = ground_altitude(); - if (height != MISSING && ga != MISSING) - return height + ga; + public double height() { + double g = ground_altitude(); + double a = altitude(); - double p = filtered_pressure(); - if (p == MISSING) - return raw_altitude(); - return AltosConvert.pressure_to_altitude(p); + if (g == MISSING) + return MISSING; + if (a == MISSING) + return MISSING; + return a - g; } - public double filtered_height() { - if (height != MISSING) - return height; + public double battery_voltage() { return MISSING; } - double f = filtered_altitude(); - double g = ground_altitude(); - if (f == MISSING || g == MISSING) - return MISSING; - return f - g; - } + public double main_voltage() { return MISSING; } - public double raw_height() { - double r = raw_altitude(); - double g = ground_altitude(); + public double drogue_voltage() { return MISSING; } - if (r == MISSING || g == MISSING) - return height; - return r - g; - } + public double temperature() { return MISSING; } + + public AltosIMU imu() { return null; } + + public AltosMag mag() { return null; } public String state() { return AltosLib.state_name(state); @@ -164,12 +136,12 @@ public class AltosRecord implements Comparable , Cloneable { status = old.status; state = old.state; tick = old.tick; - acceleration = old.acceleration; - speed = old.speed; - height = old.height; gps = new AltosGPS(old.gps); new_gps = old.new_gps; companion = old.companion; + kalman_acceleration = old.kalman_acceleration; + kalman_speed = old.kalman_speed; + kalman_height = old.kalman_height; } public AltosRecord clone() { @@ -192,11 +164,12 @@ public class AltosRecord implements Comparable , Cloneable { status = 0; state = AltosLib.ao_flight_startup; tick = 0; - acceleration = MISSING; - speed = MISSING; - height = MISSING; gps = new AltosGPS(); new_gps = false; companion = null; + + kalman_acceleration = MISSING; + kalman_speed = MISSING; + kalman_height = MISSING; } } diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java index 63b37f82..9f529234 100644 --- a/altoslib/AltosRecordMM.java +++ b/altoslib/AltosRecordMM.java @@ -19,6 +19,7 @@ package org.altusmetrum.AltosLib; public class AltosRecordMM extends AltosRecord { + /* Sensor values */ public int accel; public int pres; public int temp; @@ -45,16 +46,12 @@ public class AltosRecordMM extends AltosRecord { return raw / 4095.0; } - public double raw_pressure() { + public double pressure() { if (pres != MISSING) return pres; return MISSING; } - public double filtered_pressure() { - return raw_pressure(); - } - public double ground_pressure() { if (ground_pres != MISSING) return ground_pres; @@ -98,9 +95,6 @@ public class AltosRecordMM extends AltosRecord { } public double acceleration() { - if (acceleration != MISSING) - return acceleration; - if (ground_accel == MISSING || accel == MISSING) return MISSING; @@ -110,14 +104,6 @@ public class AltosRecordMM extends AltosRecord { return (ground_accel - accel) / accel_counts_per_mss(); } - public double accel_speed() { - if (speed != MISSING) - return speed; - if (flight_vel == MISSING) - return MISSING; - return flight_vel / (accel_counts_per_mss() * 100.0); - } - public void copy (AltosRecordMM old) { super.copy(old); diff --git a/altoslib/AltosRecordTM.java b/altoslib/AltosRecordTM.java index 37accef6..9530be31 100644 --- a/altoslib/AltosRecordTM.java +++ b/altoslib/AltosRecordTM.java @@ -18,6 +18,8 @@ package org.altusmetrum.AltosLib; public class AltosRecordTM extends AltosRecord { + + /* Sensor values */ public int accel; public int pres; public int temp; @@ -57,18 +59,12 @@ public class AltosRecordTM extends AltosRecord { return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0; } - public double raw_pressure() { + public double pressure() { if (pres == MISSING) return MISSING; return barometer_to_pressure(pres); } - public double filtered_pressure() { - if (flight_pres == MISSING) - return MISSING; - return barometer_to_pressure(flight_pres); - } - public double ground_pressure() { if (ground_pres == MISSING) return MISSING; @@ -121,22 +117,11 @@ public class AltosRecordTM extends AltosRecord { } public double acceleration() { - if (acceleration != MISSING) - return acceleration; - if (ground_accel == MISSING || accel == MISSING) return MISSING; return (ground_accel - accel) / accel_counts_per_mss(); } - public double accel_speed() { - if (speed != MISSING) - return speed; - if (flight_vel == MISSING) - return MISSING; - return flight_vel / (accel_counts_per_mss() * 100.0); - } - public void copy(AltosRecordTM old) { super.copy(old); diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 2e4d8870..f28dd1c6 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -40,17 +40,17 @@ public class AltosState { public double ground_altitude; public double altitude; public double height; - public double speed; public double acceleration; public double battery; public double temperature; public double main_sense; public double drogue_sense; + public double accel_speed; public double baro_speed; public double max_height; public double max_acceleration; - public double max_speed; + public double max_accel_speed; public double max_baro_speed; public AltosGPS gps; @@ -76,20 +76,39 @@ public class AltosState { public int speak_tick; public double speak_altitude; - public void init (AltosRecord cur, AltosState prev_state) { - //int i; - //AltosRecord prev; + public double speed() { + if (ascent) + return accel_speed; + else + return baro_speed; + } + + public double max_speed() { + if (max_accel_speed != 0) + return max_accel_speed; + return max_baro_speed; + } + public void init (AltosRecord cur, AltosState prev_state) { data = cur; ground_altitude = data.ground_altitude(); - altitude = data.raw_altitude(); - height = data.filtered_height(); + + altitude = data.altitude(); + + if (data.kalman_height != AltosRecord.MISSING) + height = data.kalman_height; + else { + if (prev_state != null) + height = (prev_state.height * 15 + altitude - ground_altitude) / 16.0; + } report_time = System.currentTimeMillis(); - acceleration = data.acceleration(); - speed = data.accel_speed(); + if (data.kalman_acceleration != AltosRecord.MISSING) + acceleration = data.kalman_acceleration; + else + acceleration = data.acceleration(); temperature = data.temperature(); drogue_sense = data.drogue_voltage(); main_sense = data.main_voltage(); @@ -108,7 +127,7 @@ public class AltosState { pad_alt = prev_state.pad_alt; max_height = prev_state.max_height; max_acceleration = prev_state.max_acceleration; - max_speed = prev_state.max_speed; + max_accel_speed = prev_state.max_accel_speed; max_baro_speed = prev_state.max_baro_speed; imu = prev_state.imu; mag = prev_state.mag; @@ -119,23 +138,39 @@ public class AltosState { time_change = (tick - prev_state.tick) / 100.0; - /* compute barometric speed */ + if (data.kalman_speed != AltosRecord.MISSING) { + baro_speed = accel_speed = data.kalman_speed; + } else { + /* compute barometric speed */ - double height_change = height - prev_state.height; - if (data.speed != AltosRecord.MISSING) - baro_speed = data.speed; - else { + double height_change = height - prev_state.height; if (time_change > 0) baro_speed = (prev_state.baro_speed * 3 + (height_change / time_change)) / 4.0; else baro_speed = prev_state.baro_speed; + + if (acceleration == AltosRecord.MISSING) { + /* Fill in mising acceleration value */ + accel_speed = baro_speed; + if (time_change > 0) + acceleration = (accel_speed - prev_state.accel_speed) / time_change; + else + acceleration = prev_state.acceleration; + } else { + /* compute accelerometer speed */ + accel_speed = prev_state.accel_speed + acceleration * time_change; + } } + } else { npad = 0; ngps = 0; gps = null; baro_speed = 0; + accel_speed = 0; time_change = 0; + if (acceleration == AltosRecord.MISSING) + acceleration = 0; } time = tick / 100.0; @@ -180,8 +215,8 @@ public class AltosState { /* Only look at accelerometer data under boost */ if (boost && acceleration > max_acceleration && acceleration != AltosRecord.MISSING) max_acceleration = acceleration; - if (boost && speed > max_speed && speed != AltosRecord.MISSING) - max_speed = speed; + if (boost && accel_speed > max_accel_speed && accel_speed != AltosRecord.MISSING) + max_accel_speed = accel_speed; if (boost && baro_speed > max_baro_speed && baro_speed != AltosRecord.MISSING) max_baro_speed = baro_speed; diff --git a/altoslib/AltosTelemetryRecordLegacy.java b/altoslib/AltosTelemetryRecordLegacy.java index 21176069..43189794 100644 --- a/altoslib/AltosTelemetryRecordLegacy.java +++ b/altoslib/AltosTelemetryRecordLegacy.java @@ -257,9 +257,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosRecord.MISSING); /* flight computer values */ - record.acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); - record.speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); - record.height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); + record.kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); + record.kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); + record.kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); record.flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosRecord.MISSING); record.flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosRecord.MISSING); @@ -334,9 +334,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { /* Old TeleDongle code with kalman-reporting TeleMetrum code */ if ((record.flight_vel & 0xffff0000) == 0x80000000) { - record.speed = ((short) record.flight_vel) / 16.0; - record.acceleration = record.flight_accel / 16.0; - record.height = record.flight_pres; + record.kalman_speed = ((short) record.flight_vel) / 16.0; + record.kalman_acceleration = record.flight_accel / 16.0; + record.kalman_height = record.flight_pres; record.flight_vel = AltosRecord.MISSING; record.flight_pres = AltosRecord.MISSING; record.flight_accel = AltosRecord.MISSING; @@ -455,9 +455,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.accel_minus_g = int16(19); if (uint16(11) == 0x8000) { - record.acceleration = int16(5); - record.speed = int16(9); - record.height = int16(13); + record.kalman_acceleration = int16(5); + record.kalman_speed = int16(9); + record.kalman_height = int16(13); record.flight_accel = AltosRecord.MISSING; record.flight_vel = AltosRecord.MISSING; record.flight_pres = AltosRecord.MISSING; @@ -465,9 +465,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.flight_accel = int16(5); record.flight_vel = uint32(9); record.flight_pres = int16(13); - record.acceleration = AltosRecord.MISSING; - record.speed = AltosRecord.MISSING; - record.height = AltosRecord.MISSING; + record.kalman_acceleration = AltosRecord.MISSING; + record.kalman_speed = AltosRecord.MISSING; + record.kalman_height = AltosRecord.MISSING; } record.gps = null; diff --git a/altoslib/AltosTelemetryRecordMegaData.java b/altoslib/AltosTelemetryRecordMegaData.java index 8f55d238..16a7b80c 100644 --- a/altoslib/AltosTelemetryRecordMegaData.java +++ b/altoslib/AltosTelemetryRecordMegaData.java @@ -83,9 +83,9 @@ public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw { next.accel_plus_g = accel_plus_g; next.accel_minus_g = accel_minus_g; - next.acceleration = acceleration / 16.0; - next.speed = speed / 16.0; - next.height = height; + next.kalman_acceleration = acceleration / 16.0; + next.kalman_speed = speed / 16.0; + next.kalman_height = height; next.seen |= AltosRecord.seen_flight | AltosRecord.seen_temp_volt; diff --git a/altoslib/AltosTelemetryRecordRaw.java b/altoslib/AltosTelemetryRecordRaw.java index fbb373d5..c21da6fc 100644 --- a/altoslib/AltosTelemetryRecordRaw.java +++ b/altoslib/AltosTelemetryRecordRaw.java @@ -65,7 +65,7 @@ public class AltosTelemetryRecordRaw extends AltosTelemetryRecord { if (previous != null) next = previous.clone(); else - next = new AltosRecord(); + next = new AltosRecordNone(); next.serial = serial; next.tick = tick; return next; diff --git a/altoslib/AltosTelemetryRecordSensor.java b/altoslib/AltosTelemetryRecordSensor.java index 319a91b3..f1fc156c 100644 --- a/altoslib/AltosTelemetryRecordSensor.java +++ b/altoslib/AltosTelemetryRecordSensor.java @@ -86,9 +86,9 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { next.main = AltosRecord.MISSING; } - next.acceleration = acceleration / 16.0; - next.speed = speed / 16.0; - next.height = height; + next.kalman_acceleration = acceleration / 16.0; + next.kalman_speed = speed / 16.0; + next.kalman_height = height; next.ground_pres = ground_pres; if (type == packet_type_TM_sensor) { diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index b56d8af1..f04c10c6 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -46,6 +46,7 @@ AltosLib_JAVA = \ $(SRC)/AltosRecordCompanion.java \ $(SRC)/AltosRecordIterable.java \ $(SRC)/AltosRecord.java \ + $(SRC)/AltosRecordNone.java \ $(SRC)/AltosRecordTM.java \ $(SRC)/AltosRecordMM.java \ $(SRC)/AltosReplayReader.java \ diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index 007c74ec..a05c4404 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -251,7 +251,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Speed extends AscentValueHold { void show (AltosState state, int crc_errors) { - double speed = state.speed; + double speed = state.accel_speed; if (!state.ascent) speed = state.baro_speed; show(AltosConvert.speed, speed); diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index f8cc1ed6..1c929a7c 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -128,10 +128,10 @@ public class AltosCSV implements AltosWriter { void write_basic(AltosRecord record) { out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", record.acceleration(), - record.raw_pressure(), - record.raw_altitude(), - record.raw_height(), - record.accel_speed(), + record.pressure(), + record.altitude(), + record.height(), + state.accel_speed, state.baro_speed, record.temperature(), record.battery_voltage(), diff --git a/altosui/AltosDataPoint.java b/altosui/AltosDataPoint.java index 5e077320..4956e9f3 100644 --- a/altosui/AltosDataPoint.java +++ b/altosui/AltosDataPoint.java @@ -16,11 +16,8 @@ interface AltosDataPoint { String state_name(); double acceleration(); - double pressure(); - double altitude(); double height(); - double accel_speed(); - double baro_speed(); + double speed(); double temperature(); double battery_voltage(); double drogue_voltage(); diff --git a/altosui/AltosDataPointReader.java b/altosui/AltosDataPointReader.java index 2316cf97..88df081f 100644 --- a/altosui/AltosDataPointReader.java +++ b/altosui/AltosDataPointReader.java @@ -12,7 +12,6 @@ import org.altusmetrum.AltosLib.*; class AltosDataPointReader implements Iterable { Iterator iter; AltosState state; - AltosRecord record; boolean has_gps; boolean has_accel; boolean has_ignite; @@ -22,7 +21,7 @@ class AltosDataPointReader implements Iterable { public AltosDataPointReader(AltosRecordIterable reader) { this.iter = reader.iterator(); this.state = null; - has_accel = reader.has_accel(); + has_accel = true; has_gps = reader.has_gps(); has_ignite = reader.has_ignite(); } @@ -30,35 +29,31 @@ class AltosDataPointReader implements Iterable { private void read_next_record() throws NoSuchElementException { - record = iter.next(); - state = new AltosState(record, state); + state = new AltosState(iter.next(), state); } private AltosDataPoint current_dp() { - assert this.record != null; + assert this.state != null; return new AltosDataPoint() { - public int version() { return record.version; } - public int serial() { return record.serial; } - public int flight() { return record.flight; } - public String callsign() { return record.callsign; } - public double time() { return record.time; } - public double rssi() { return record.rssi; } + public int version() { return state.data.version; } + public int serial() { return state.data.serial; } + public int flight() { return state.data.flight; } + public String callsign() { return state.data.callsign; } + public double time() { return state.data.time; } + public double rssi() { return state.data.rssi; } - public int state() { return record.state; } - public String state_name() { return record.state(); } + public int state() { return state.state; } + public String state_name() { return state.data.state(); } - public double acceleration() { return record.acceleration(); } - public double pressure() { return record.raw_pressure(); } - public double altitude() { return record.raw_altitude(); } - public double height() { return record.raw_height(); } - public double accel_speed() { return record.accel_speed(); } - public double baro_speed() { return state.baro_speed; } - public double temperature() { return record.temperature(); } - public double battery_voltage() { return record.battery_voltage(); } - public double drogue_voltage() { return record.drogue_voltage(); } - public double main_voltage() { return record.main_voltage(); } - public boolean has_accel() { return has_accel; } + public double acceleration() { return state.acceleration; } + public double height() { return state.height; } + public double speed() { return state.speed(); } + public double temperature() { return state.temperature; } + public double battery_voltage() { return state.battery; } + public double drogue_voltage() { return state.drogue_sense; } + public double main_voltage() { return state.main_sense; } + public boolean has_accel() { return true; } // return state.acceleration != AltosRecord.MISSING; } }; } @@ -68,14 +63,14 @@ class AltosDataPointReader implements Iterable { throw new UnsupportedOperationException(); } public boolean hasNext() { - if (record != null && record.state == Altos.ao_flight_landed) + if (state != null && state.state == Altos.ao_flight_landed) return false; return iter.hasNext(); } public AltosDataPoint next() { do { read_next_record(); - } while (record.time < -1.0 && hasNext()); + } while (state.data.time < -1.0 && hasNext()); return current_dp(); } }; diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index a71cdc10..2ea7cbfa 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -256,7 +256,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Speed extends DescentValue { void show (AltosState state, int crc_errors) { - double speed = state.speed; + double speed = state.accel_speed; if (!state.ascent) speed = state.baro_speed; show(AltosConvert.speed, speed); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index f7a1d03e..1ba70c7e 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -197,7 +197,7 @@ public class AltosDisplayThread extends Thread { if ((old_state == null || old_state.state <= Altos.ao_flight_boost) && state.state > Altos.ao_flight_boost) { voice.speak("max speed: %s.", - AltosConvert.speed.say_units(state.max_speed + 0.5)); + AltosConvert.speed.say_units(state.max_accel_speed + 0.5)); ret = true; } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) && state.state >= Altos.ao_flight_drogue) { diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index e48cb608..1653ca57 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -24,7 +24,7 @@ public class AltosFlightStats { double max_height; double max_speed; double max_acceleration; - double[] state_speed = new double[Altos.ao_flight_invalid + 1]; + double[] state_accel_speed = new double[Altos.ao_flight_invalid + 1]; double[] state_baro_speed = new double[Altos.ao_flight_invalid + 1]; double[] state_accel = new double[Altos.ao_flight_invalid + 1]; int[] state_count = new int[Altos.ao_flight_invalid + 1]; @@ -123,7 +123,7 @@ public class AltosFlightStats { } } state_accel[state.state] += state.acceleration; - state_speed[state.state] += state.speed; + state_accel_speed[state.state] += state.accel_speed; state_baro_speed[state.state] += state.baro_speed; state_count[state.state]++; if (state_start[state.state] == 0.0) @@ -131,8 +131,8 @@ public class AltosFlightStats { if (state_end[state.state] < state.time) state_end[state.state] = state.time; max_height = state.max_height; - if (state.max_speed != 0) - max_speed = state.max_speed; + if (state.max_accel_speed != 0) + max_speed = state.max_accel_speed; else max_speed = state.max_baro_speed; max_acceleration = state.max_acceleration; @@ -140,7 +140,7 @@ public class AltosFlightStats { } for (int s = Altos.ao_flight_startup; s <= Altos.ao_flight_landed; s++) { if (state_count[s] > 0) { - state_speed[s] /= state_count[s]; + state_accel_speed[s] /= state_count[s]; state_baro_speed[s] /= state_count[s]; state_accel[s] /= state_count[s]; } diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index cb8e3d20..f59f70ba 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -40,12 +40,7 @@ public class AltosGraphUI extends AltosFrame AltosGraphTime.Element speed = new AltosGraphTime.TimeSeries(String.format("Speed (%s)", AltosConvert.speed.show_units()), "Vertical Speed", green) { public void gotTimeData(double time, AltosDataPoint d) { - double speed; - if (d.state() < Altos.ao_flight_drogue && d.has_accel()) { - speed = d.accel_speed(); - } else { - speed = d.baro_speed(); - } + double speed = d.speed(); if (speed != AltosRecord.MISSING) series.add(time, AltosConvert.speed.value(speed)); } diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 86e02ab1..11d1b0c1 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -114,8 +114,8 @@ public class AltosInfoTable extends JTable { info_add_row(0, "Max height", "%6.0f m", state.max_height); info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration); info_add_row(0, "Max acceleration", "%8.1f m/s²", state.max_acceleration); - info_add_row(0, "Speed", "%8.1f m/s", state.ascent ? state.speed : state.baro_speed); - info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed); + info_add_row(0, "Speed", "%8.1f m/s", state.speed()); + info_add_row(0, "Max Speed", "%8.1f m/s", state.max_accel_speed); info_add_row(0, "Temperature", "%9.2f °C", state.temperature); info_add_row(0, "Battery", "%9.2f V", state.battery); if (state.drogue_sense != AltosRecord.MISSING) diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index 57339b19..281638bf 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -109,7 +109,7 @@ public class AltosKML implements AltosWriter { AltosGPS gps = record.gps; out.printf(kml_coord_fmt, gps.lon, gps.lat, - record.filtered_altitude(), (double) gps.alt, + record.altitude(), (double) gps.alt, record.time, gps.nsat); } diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 57c2d476..0111a08a 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -173,7 +173,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Speed extends LandedValue { void show (AltosState state, int crc_errors) { - show(AltosConvert.speed, state.max_speed); + show(AltosConvert.speed, state.max_speed()); } public Speed (GridBagLayout layout, int y) { super (layout, y, "Maximum Speed"); -- cgit v1.2.3 From 89c621be35e1a6d3394b0e143391fcf2d94d7b41 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 16:53:23 -0700 Subject: altoslib: Parse GPS .mega file entries for reply/graphing The .mega file parsing had a pile of leftovers from when it was cloned from the .eeprom file parsing code. Replace all of that with the right parsing bits so that GPS data will be presented correctly. Signed-off-by: Keith Packard --- altoslib/AltosEepromMega.java | 52 +++++++++++------ altoslib/AltosEepromMegaIterable.java | 102 ++++++++++++++-------------------- 2 files changed, 77 insertions(+), 77 deletions(-) (limited to 'altoslib') diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 25a29fb2..af4f8aca 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -24,7 +24,7 @@ public class AltosEepromMega { public int tick; public boolean valid; public String data; - public int a, b; + public int config_a, config_b; public int data8[]; @@ -74,6 +74,22 @@ public class AltosEepromMega { public int nsense() { return data16(4); } public int sense(int i) { return data16(6 + i * 2); } + /* AO_LOG_GPS_TIME elements */ + public int latitude() { return data32(0); } + public int longitude() { return data32(4); } + public int altitude() { return data16(8); } + public int hour() { return data8(10); } + public int minute() { return data8(11); } + public int second() { return data8(12); } + public int flags() { return data8(13); } + public int year() { return data8(14); } + public int month() { return data8(15); } + public int day() { return data8(16); } + + /* AO_LOG_GPS_SAT elements */ + public int nsat() { return data16(0); } + public int svid(int n) { return data8(2 + n * 2); } + public int c_n(int n) { return data8(2 + n * 2 + 1); } public AltosEepromMega (AltosEepromChunk chunk, int start) throws ParseException { cmd = chunk.data(start); @@ -121,26 +137,26 @@ public class AltosEepromMega { data = tokens[2]; } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { cmd = AltosLib.AO_LOG_APOGEE_DELAY; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[0].equals("Callsign:")) { cmd = AltosLib.AO_LOG_CALLSIGN; data = tokens[1].replaceAll("\"",""); } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { cmd = AltosLib.AO_LOG_ACCEL_CAL; - a = Integer.parseInt(tokens[3]); - b = Integer.parseInt(tokens[5]); + config_a = Integer.parseInt(tokens[3]); + config_b = Integer.parseInt(tokens[5]); } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { cmd = AltosLib.AO_LOG_RADIO_CAL; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - a = Integer.parseInt(tokens[3]); + config_a = Integer.parseInt(tokens[3]); } else if (tokens[0].equals("manufacturer")) { cmd = AltosLib.AO_LOG_MANUFACTURER; data = tokens[1]; @@ -149,38 +165,38 @@ public class AltosEepromMega { data = tokens[1]; } else if (tokens[0].equals("serial-number")) { cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - a = Integer.parseInt(tokens[1]); + config_a = Integer.parseInt(tokens[1]); } else if (tokens[0].equals("log-format")) { cmd = AltosLib.AO_LOG_LOG_FORMAT; - a = Integer.parseInt(tokens[1]); + config_a = Integer.parseInt(tokens[1]); } else if (tokens[0].equals("software-version")) { cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; data = tokens[1]; } else if (tokens[0].equals("ms5607")) { if (tokens[1].equals("reserved:")) { cmd = AltosLib.AO_LOG_BARO_RESERVED; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("sens:")) { cmd = AltosLib.AO_LOG_BARO_SENS; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("off:")) { cmd = AltosLib.AO_LOG_BARO_OFF; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("tcs:")) { cmd = AltosLib.AO_LOG_BARO_TCS; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("tco:")) { cmd = AltosLib.AO_LOG_BARO_TCO; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("tref:")) { cmd = AltosLib.AO_LOG_BARO_TREF; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("tempsens:")) { cmd = AltosLib.AO_LOG_BARO_TEMPSENS; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else if (tokens[1].equals("crc:")) { cmd = AltosLib.AO_LOG_BARO_CRC; - a = Integer.parseInt(tokens[2]); + config_a = Integer.parseInt(tokens[2]); } else { cmd = AltosLib.AO_LOG_INVALID; data = line; diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java index 50f9d33d..16809089 100644 --- a/altoslib/AltosEepromMegaIterable.java +++ b/altoslib/AltosEepromMegaIterable.java @@ -109,7 +109,7 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { case AltosLib.AO_LOG_TEMP_VOLT: state.v_batt = record.v_batt(); state.v_pyro = record.v_pbatt(); - for (int i = 0; i < AltosRecordMM.num_sense; i++) + for (int i = 0; i < record.nsense(); i++) state.sense[i] = record.sense(i); eeprom.seen |= seen_temp_volt; break; @@ -118,51 +118,35 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { break; case AltosLib.AO_LOG_GPS_TIME: eeprom.gps_tick = state.tick; - AltosGPS old = state.gps; state.gps = new AltosGPS(); - /* GPS date doesn't get repeated through the file */ - if (old != null) { - state.gps.year = old.year; - state.gps.month = old.month; - state.gps.day = old.day; - } - state.gps.hour = (record.a & 0xff); - state.gps.minute = (record.a >> 8); - state.gps.second = (record.b & 0xff); + state.gps.lat = record.latitude() / 1e7; + state.gps.lon = record.longitude() / 1e7; + state.gps.alt = record.altitude(); + state.gps.year = record.year() + 2000; + state.gps.month = record.month(); + state.gps.day = record.day(); + + state.gps.hour = record.hour(); + state.gps.minute = record.minute(); + state.gps.second = record.second(); - int flags = (record.b >> 8); + int flags = record.flags(); state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT; state.new_gps = true; has_gps = true; - break; - case AltosLib.AO_LOG_GPS_LAT: - int lat32 = record.a | (record.b << 16); - state.gps.lat = (double) lat32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_LON: - int lon32 = record.a | (record.b << 16); - state.gps.lon = (double) lon32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_ALT: - state.gps.alt = record.a; + eeprom.seen |= seen_gps_time | seen_gps_lat | seen_gps_lon; break; case AltosLib.AO_LOG_GPS_SAT: if (state.tick == eeprom.gps_tick) { - int svid = record.a; - int c_n0 = record.b >> 8; - state.gps.add_sat(svid, c_n0); + int nsat = record.nsat(); + for (int i = 0; i < nsat; i++) + state.gps.add_sat(record.svid(i), record.c_n(i)); } break; - case AltosLib.AO_LOG_GPS_DATE: - state.gps.year = (record.a & 0xff) + 2000; - state.gps.month = record.a >> 8; - state.gps.day = record.b & 0xff; - break; - case AltosLib.AO_LOG_CONFIG_VERSION: break; case AltosLib.AO_LOG_MAIN_DEPLOY: @@ -175,8 +159,8 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { state.callsign = record.data; break; case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = record.a; - state.accel_minus_g = record.b; + state.accel_plus_g = record.config_a; + state.accel_minus_g = record.config_b; break; case AltosLib.AO_LOG_RADIO_CAL: break; @@ -185,33 +169,33 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { case AltosLib.AO_LOG_PRODUCT: break; case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = record.a; + state.serial = record.config_a; break; case AltosLib.AO_LOG_SOFTWARE_VERSION: break; case AltosLib.AO_LOG_BARO_RESERVED: - baro.reserved = record.a; + baro.reserved = record.config_a; break; case AltosLib.AO_LOG_BARO_SENS: - baro.sens =record.a; + baro.sens =record.config_a; break; case AltosLib.AO_LOG_BARO_OFF: - baro.off =record.a; + baro.off =record.config_a; break; case AltosLib.AO_LOG_BARO_TCS: - baro.tcs =record.a; + baro.tcs =record.config_a; break; case AltosLib.AO_LOG_BARO_TCO: - baro.tco =record.a; + baro.tco =record.config_a; break; case AltosLib.AO_LOG_BARO_TREF: - baro.tref =record.a; + baro.tref =record.config_a; break; case AltosLib.AO_LOG_BARO_TEMPSENS: - baro.tempsens =record.a; + baro.tempsens =record.config_a; break; case AltosLib.AO_LOG_BARO_CRC: - baro.crc =record.a; + baro.crc =record.config_a; break; } state.seen |= eeprom.seen; @@ -270,25 +254,25 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { out.printf("# Config version: %s\n", record.data); break; case AltosLib.AO_LOG_MAIN_DEPLOY: - out.printf("# Main deploy: %s\n", record.a); + out.printf("# Main deploy: %s\n", record.config_a); break; case AltosLib.AO_LOG_APOGEE_DELAY: - out.printf("# Apogee delay: %s\n", record.a); + out.printf("# Apogee delay: %s\n", record.config_a); break; case AltosLib.AO_LOG_RADIO_CHANNEL: - out.printf("# Radio channel: %s\n", record.a); + out.printf("# Radio channel: %s\n", record.config_a); break; case AltosLib.AO_LOG_CALLSIGN: out.printf("# Callsign: %s\n", record.data); break; case AltosLib.AO_LOG_ACCEL_CAL: - out.printf ("# Accel cal: %d %d\n", record.a, record.b); + out.printf ("# Accel cal: %d %d\n", record.config_a, record.config_b); break; case AltosLib.AO_LOG_RADIO_CAL: - out.printf ("# Radio cal: %d\n", record.a); + out.printf ("# Radio cal: %d\n", record.config_a); break; case AltosLib.AO_LOG_MAX_FLIGHT_LOG: - out.printf ("# Max flight log: %d\n", record.a); + out.printf ("# Max flight log: %d\n", record.config_a); break; case AltosLib.AO_LOG_MANUFACTURER: out.printf ("# Manufacturer: %s\n", record.data); @@ -297,34 +281,34 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { out.printf ("# Product: %s\n", record.data); break; case AltosLib.AO_LOG_SERIAL_NUMBER: - out.printf ("# Serial number: %d\n", record.a); + out.printf ("# Serial number: %d\n", record.config_a); break; case AltosLib.AO_LOG_SOFTWARE_VERSION: out.printf ("# Software version: %s\n", record.data); break; case AltosLib.AO_LOG_BARO_RESERVED: - out.printf ("# Baro reserved: %d\n", record.a); + out.printf ("# Baro reserved: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_SENS: - out.printf ("# Baro sens: %d\n", record.a); + out.printf ("# Baro sens: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_OFF: - out.printf ("# Baro off: %d\n", record.a); + out.printf ("# Baro off: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_TCS: - out.printf ("# Baro tcs: %d\n", record.a); + out.printf ("# Baro tcs: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_TCO: - out.printf ("# Baro tco: %d\n", record.a); + out.printf ("# Baro tco: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_TREF: - out.printf ("# Baro tref: %d\n", record.a); + out.printf ("# Baro tref: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_TEMPSENS: - out.printf ("# Baro tempsens: %d\n", record.a); + out.printf ("# Baro tempsens: %d\n", record.config_a); break; case AltosLib.AO_LOG_BARO_CRC: - out.printf ("# Baro crc: %d\n", record.a); + out.printf ("# Baro crc: %d\n", record.config_a); break; } } @@ -369,7 +353,7 @@ public class AltosEepromMegaIterable extends AltosRecordIterable { /* Bail after reading the 'landed' record; we're all done */ if (record.cmd == AltosLib.AO_LOG_STATE && - record.a == AltosLib.ao_flight_landed) + record.state() == AltosLib.ao_flight_landed) break; } } catch (IOException io) { -- cgit v1.2.3 From e4ee3a35dbb1586f65adada0eaf34b7b4e5432eb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Oct 2012 19:51:02 -0700 Subject: altoslib: Add AltosRecordNone.java oops. forgot a file. Signed-off-by: Keith Packard --- altoslib/AltosRecordNone.java | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 altoslib/AltosRecordNone.java (limited to 'altoslib') diff --git a/altoslib/AltosRecordNone.java b/altoslib/AltosRecordNone.java new file mode 100644 index 00000000..ca0a5fe3 --- /dev/null +++ b/altoslib/AltosRecordNone.java @@ -0,0 +1,34 @@ +/* + * 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; + +public class AltosRecordNone extends AltosRecord { + + public double pressure() { return MISSING; } + public double ground_pressure() { return MISSING; } + public double temperature() { return MISSING; } + public double acceleration() { return MISSING; } + + public AltosRecordNone(AltosRecord old) { + super.copy(old); + } + + public AltosRecordNone() { + super(); + } +} -- cgit v1.2.3 From fe00d1169c65cb289f77093cf281efbd0a5d4e64 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2012 21:35:06 -0700 Subject: 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 --- altoslib/AltosConfigData.java | 17 +++ altoslib/AltosPyro.java | 293 +++++++++++++++++++++++++++++++++++++++++ altoslib/Makefile.am | 3 +- altosui/AltosConfig.java | 32 +++++ altosui/AltosConfigPyroUI.java | 288 ++++++++++++++++++++++++++++++++++++++++ altosui/AltosConfigUI.java | 68 ++++++++-- altosui/AltosDialog.java | 6 + altosui/Makefile.am | 1 + 8 files changed, 697 insertions(+), 11 deletions(-) create mode 100644 altoslib/AltosPyro.java create mode 100644 altosui/AltosConfigPyroUI.java (limited to 'altoslib') diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index a962b105..45a88783 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -50,6 +50,8 @@ public class AltosConfigData implements Iterable { public int storage_size; public int storage_erase_unit; + public AltosPyro[] pyros; + public static String get_string(String line, String label) throws ParseException { if (line.startsWith(label)) { String quoted = line.substring(label.length()).trim(); @@ -135,6 +137,10 @@ public class AltosConfigData implements Iterable { radio_frequency = 0; stored_flight = 0; serial = -1; + pyros = null; + + int npyro = 0; + int pyro = 0; for (;;) { String line = link.get_reply(); if (line == null) @@ -142,6 +148,16 @@ public class AltosConfigData implements Iterable { if (line.contains("Syntax error")) continue; lines.add(line); + if (pyro < npyro - 1) { + if (pyros == null) + pyros = new AltosPyro[npyro]; + try { + pyros[pyro] = new AltosPyro(pyro, line); + } catch (ParseException e) { + } + ++pyro; + continue; + } try { serial = get_int(line, "serial-number"); } catch (Exception e) {} try { log_format = get_int(line, "log-format"); } catch (Exception e) {} try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {} @@ -173,6 +189,7 @@ public class AltosConfigData implements Iterable { try { get_int(line, "flight"); stored_flight++; } catch (Exception e) {} try { storage_size = get_int(line, "Storage size:"); } catch (Exception e) {} try { storage_erase_unit = get_int(line, "Storage erase unit"); } catch (Exception e) {} + try { npyro = get_int(line, "Pyro-count:"); pyro = 0; } catch (Exception e) {} /* signals the end of the version info */ if (line.startsWith("software-version")) diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java new file mode 100644 index 00000000..14051169 --- /dev/null +++ b/altoslib/AltosPyro.java @@ -0,0 +1,293 @@ +/* + * 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.util.*; +import java.text.*; +import java.util.concurrent.*; + +public class AltosPyro { + public static final int pyro_none = 0x00000000; + + public static final int pyro_accel_less = 0x00000001; + public static final int pyro_accel_greater = 0x00000002; + public static final String pyro_accel_less_string = "a<"; + public static final String pyro_accel_greater_string = "a>"; + public static final String pyro_accel_less_name = "Acceleration less than (m/s²)"; + public static final String pyro_accel_greater_name = "Acceleration greater than (m/s²)"; + public static final double pyro_accel_scale = 16.0; + + public static final int pyro_speed_less = 0x00000004; + public static final int pyro_speed_greater = 0x00000008; + public static final String pyro_speed_less_string = "s<"; + public static final String pyro_speed_greater_string = "s>"; + public static final String pyro_speed_less_name = "Speed less than (m/s)"; + public static final String pyro_speed_greater_name = "Speed greater than (m/s)"; + public static final double pyro_speed_scale = 16.0; + + public static final int pyro_height_less = 0x00000010; + public static final int pyro_height_greater = 0x00000020; + public static final String pyro_height_less_string = "h<"; + public static final String pyro_height_greater_string = "h>"; + public static final String pyro_height_less_name = "Height less than (m)"; + public static final String pyro_height_greater_name = "Height greater than (m)"; + public static final double pyro_height_scale = 1.0; + + public static final int pyro_orient_less = 0x00000040; + public static final int pyro_orient_greater = 0x00000080; + public static final String pyro_orient_less_string = "o<"; + public static final String pyro_orient_greater_string = "o>"; + public static final String pyro_orient_less_name = "Angle from vertical less than (degrees)"; + public static final String pyro_orient_greater_name = "Angle from vertical greater than (degrees)"; + public static final double pyro_orient_scale = 1.0; + + public static final int pyro_time_less = 0x00000100; + public static final int pyro_time_greater = 0x00000200; + public static final String pyro_time_less_string = "t<"; + public static final String pyro_time_greater_string = "t>"; + public static final String pyro_time_less_name = "Time since boost less than (s)"; + public static final String pyro_time_greater_name = "Time since boost greater than (s)"; + public static final double pyro_time_scale = 100.0; + + public static final int pyro_ascending = 0x00000400; + public static final int pyro_descending = 0x00000800; + public static final String pyro_ascending_string = "A"; + public static final String pyro_descending_string = "D"; + public static final String pyro_ascending_name = "Ascending"; + public static final String pyro_descending_name = "Descending"; + + public static final int pyro_after_motor = 0x00001000; + public static final String pyro_after_motor_string = "m"; + public static final String pyro_after_motor_name = "After motor number"; + public static final double pyro_after_motor_scale = 1.0; + + public static final int pyro_delay = 0x00002000; + public static final String pyro_delay_string = "d"; + public static final String pyro_delay_name = "Delay after other conditions (s)"; + public static final double pyro_delay_scale = 100.0; + + public static final int pyro_state_less = 0x00004000; + public static final int pyro_state_greater_or_equal = 0x00008000; + public static final String pyro_state_less_string = "f<"; + public static final String pyro_state_greater_or_equal_string = "f>="; + public static final String pyro_state_less_name = "Flight state before"; + public static final String pyro_state_greater_or_equal_name = "Flight state after"; + public static final double pyro_state_scale = 1.0; + + public static final int pyro_all = 0x0000ffff; + + public static final int pyro_no_value = (pyro_ascending | + pyro_descending); + + public static final int pyro_state_value = pyro_state_less | pyro_state_greater_or_equal; + + private static HashMap string_to_pyro = new HashMap(); + + private static HashMap pyro_to_string = new HashMap(); + + private static HashMap pyro_to_name = new HashMap(); + + private static HashMap pyro_to_scale = new HashMap(); + + private static void insert_map(int flag, String string, String name, double scale) { + string_to_pyro.put(string, flag); + pyro_to_string.put(flag, string); + pyro_to_name.put(flag, name); + pyro_to_scale.put(flag, scale); + } + + public static int string_to_pyro(String name) { + if (string_to_pyro.containsKey(name)) + return string_to_pyro.get(name); + return pyro_none; + } + + public static String pyro_to_string(int flag) { + if (pyro_to_string.containsKey(flag)) + return pyro_to_string.get(flag); + return null; + } + + public static String pyro_to_name(int flag) { + if (pyro_to_name.containsKey(flag)) + return pyro_to_name.get(flag); + return null; + } + + public static double pyro_to_scale(int flag) { + if (pyro_to_scale.containsKey(flag)) + return pyro_to_scale.get(flag); + return 1.0; + } + + private static void initialize_maps() { + insert_map(pyro_accel_less, pyro_accel_less_string, pyro_accel_less_name, pyro_accel_scale); + insert_map(pyro_accel_greater, pyro_accel_greater_string, pyro_accel_greater_name, pyro_accel_scale); + + insert_map(pyro_speed_less, pyro_speed_less_string, pyro_speed_less_name, pyro_speed_scale); + insert_map(pyro_speed_greater, pyro_speed_greater_string, pyro_speed_greater_name, pyro_speed_scale); + + insert_map(pyro_height_less, pyro_height_less_string, pyro_height_less_name, pyro_height_scale); + insert_map(pyro_height_greater, pyro_height_greater_string, pyro_height_greater_name, pyro_height_scale); + + insert_map(pyro_orient_less, pyro_orient_less_string, pyro_orient_less_name, pyro_orient_scale); + insert_map(pyro_orient_greater, pyro_orient_greater_string, pyro_orient_greater_name, pyro_orient_scale); + + insert_map(pyro_time_less, pyro_time_less_string, pyro_time_less_name, pyro_time_scale); + insert_map(pyro_time_greater, pyro_time_greater_string, pyro_time_greater_name, pyro_time_scale); + + insert_map(pyro_ascending, pyro_ascending_string, pyro_ascending_name, 1.0); + insert_map(pyro_descending, pyro_descending_string, pyro_descending_name, 1.0); + + insert_map(pyro_after_motor, pyro_after_motor_string, pyro_after_motor_name, 1.0); + insert_map(pyro_delay, pyro_delay_string, pyro_delay_name, pyro_delay_scale); + + insert_map(pyro_state_less, pyro_state_less_string, pyro_state_less_name, 1.0); + insert_map(pyro_state_greater_or_equal, pyro_state_greater_or_equal_string, pyro_state_greater_or_equal_name, 1.0); + } + + { + initialize_maps(); + } + + public int channel; + public int flags; + public int accel_less, accel_greater; + public int speed_less, speed_greater; + public int height_less, height_greater; + public int orient_less, orient_greater; + public int time_less, time_greater; + public int delay; + public int state_less, state_greater_or_equal; + public int motor; + + public AltosPyro(int in_channel) { + channel = in_channel; + flags = 0; + } + + private boolean set_ivalue(int flag, int value) { + switch (flag) { + case pyro_accel_less: accel_less = value; break; + case pyro_accel_greater: accel_greater = value; break; + case pyro_speed_less: speed_less = value; break; + case pyro_speed_greater: speed_greater = value; break; + case pyro_height_less: height_less = value; break; + case pyro_height_greater: height_greater = value; break; + case pyro_orient_less: orient_less = value; break; + case pyro_orient_greater: orient_greater = value; break; + case pyro_time_less: time_less = value; break; + case pyro_time_greater: time_greater = value; break; + case pyro_after_motor: motor = value; break; + case pyro_delay: delay = value; break; + case pyro_state_less: state_less = value; break; + case pyro_state_greater_or_equal: state_greater_or_equal = value; break; + default: + return false; + } + return true; + } + + public boolean set_value(int flag, double dvalue) { + return set_ivalue(flag, (int) (dvalue * pyro_to_scale(flag))); + } + + private int get_ivalue (int flag) { + int value; + + switch (flag) { + case pyro_accel_less: value = accel_less; break; + case pyro_accel_greater: value = accel_greater; break; + case pyro_speed_less: value = speed_less; break; + case pyro_speed_greater: value = speed_greater; break; + case pyro_height_less: value = height_less; break; + case pyro_height_greater: value = height_greater; break; + case pyro_orient_less: value = orient_less; break; + case pyro_orient_greater: value = orient_greater; break; + case pyro_time_less: value = time_less; break; + case pyro_time_greater: value = time_greater; break; + case pyro_after_motor: value = motor; break; + case pyro_delay: value = delay; break; + case pyro_state_less: value = state_less; break; + case pyro_state_greater_or_equal: value = state_greater_or_equal; break; + default: value = 0; break; + } + return value; + } + + public double get_value(int flag) { + return get_ivalue(flag) / pyro_to_scale(flag); + } + + public AltosPyro(int in_channel, String line) throws ParseException { + String[] tokens = line.split("\\s+"); + + channel = in_channel; + flags = 0; + + int i = 0; + if (tokens[i].equals("Pyro")) + i += 2; + + for (; i < tokens.length; i++) { + + if (tokens[i].equals("")) + break; + + int flag = string_to_pyro(tokens[i]); + if (flag == pyro_none) + throw new ParseException(String.format("Invalid pyro token \"%s\"", + tokens[i]), i); + flags |= flag; + + if ((flag & pyro_no_value) == 0) { + int value = 0; + ++i; + try { + value = AltosLib.fromdec(tokens[i]); + } catch (NumberFormatException n) { + throw new ParseException(String.format("Invalid pyro value \"%s\"", + tokens[i]), i); + } + if (!set_ivalue(flag, value)) + throw new ParseException(String.format("Internal parser error \"%s\" \"%s\"", + tokens[i-1], tokens[i]), i-1); + } + } + } + + public String toString() { + String ret = String.format("%d", channel); + + for (int flag = 1; flag <= flags; flag <<= 1) { + if ((flags & flag) != 0) { + String add; + if ((flag & pyro_no_value) == 0) { + add = String.format(" %s %d", + pyro_to_string.get(flag), + get_ivalue(flag)); + } else { + add = String.format(" %s", + pyro_to_string.get(flag)); + } + ret = ret.concat(add); + } + } + return ret; + } +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index f04c10c6..2579a650 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -75,7 +75,8 @@ AltosLib_JAVA = \ $(SRC)/AltosDistance.java \ $(SRC)/AltosHeight.java \ $(SRC)/AltosSpeed.java \ - $(SRC)/AltosAccel.java + $(SRC)/AltosAccel.java \ + $(SRC)/AltosPyro.java JAR=AltosLib.jar 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 + * + * 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 \ -- cgit v1.2.3 From 20496608ca287e65302193ee1afe9f0cad3a36e1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2012 21:36:12 -0700 Subject: altoslib: capitalize 'Invalid' state name appropriately It shouldn't ever appear, but it seemed wrong to have it not match the rest of the strings. Signed-off-by: Keith Packard --- altoslib/AltosLib.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'altoslib') diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 192c445e..07516aeb 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -199,7 +199,7 @@ public class AltosLib { public static String state_name_capital(int state) { if (state < 0 || state_to_string.length <= state) - return "invalid"; + return "Invalid"; return state_to_string_capital[state]; } -- cgit v1.2.3