altoslib/altosui: Further AltosState transition work
authorKeith Packard <keithp@keithp.com>
Sun, 1 Sep 2013 04:11:39 +0000 (23:11 -0500)
committerKeith Packard <keithp@keithp.com>
Sun, 1 Sep 2013 04:11:39 +0000 (23:11 -0500)
Parses most eeprom and telem records now; altosui updated to show from
AltosState info.

Signed-off-by: Keith Packard <keithp@keithp.com>
40 files changed:
altoslib/AltosConvert.java
altoslib/AltosEeprom.java
altoslib/AltosEepromChunk.java
altoslib/AltosEepromFile.java
altoslib/AltosEepromGPS.java [new file with mode: 0644]
altoslib/AltosEepromHeader.java
altoslib/AltosEepromMega.java
altoslib/AltosEepromMetrum.java
altoslib/AltosEepromMetrum2.java [new file with mode: 0644]
altoslib/AltosEepromMini.java
altoslib/AltosEepromTM.java
altoslib/AltosEepromTeleScience.java
altoslib/AltosGPS.java
altoslib/AltosLib.java
altoslib/AltosState.java
altoslib/AltosTelemetry.java
altoslib/AltosTelemetryConfiguration.java [new file with mode: 0644]
altoslib/AltosTelemetryLegacy.java
altoslib/AltosTelemetryLocation.java [new file with mode: 0644]
altoslib/AltosTelemetryMegaData.java [new file with mode: 0644]
altoslib/AltosTelemetryMegaSensor.java [new file with mode: 0644]
altoslib/AltosTelemetryMetrumData.java [new file with mode: 0644]
altoslib/AltosTelemetryMetrumSensor.java [new file with mode: 0644]
altoslib/AltosTelemetryRaw.java [new file with mode: 0644]
altoslib/AltosTelemetrySatellite.java [new file with mode: 0644]
altoslib/AltosTelemetrySensor.java [new file with mode: 0644]
altoslib/AltosTelemetryStandard.java [new file with mode: 0644]
altoslib/Makefile.am
altosui/AltosAscent.java
altosui/AltosDescent.java
altosui/AltosDisplayThread.java
altosui/AltosEepromDownload.java
altosui/AltosFlightStatus.java
altosui/AltosFlightUI.java
altosui/AltosIdleMonitorUI.java
altosui/AltosInfoTable.java
altosui/AltosLanded.java
altosui/AltosPad.java
altosui/AltosUI.java
src/core/ao_log.h

index a1e2cdc..cf2bc59 100644 (file)
@@ -196,6 +196,28 @@ public class AltosConvert {
                return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0;
        }
 
+       static double
+       thermometer_to_temperature(double thermo)
+       {
+               return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247;
+       }
+
+       static double mega_adc(int raw) {
+               return raw / 4095.0;
+       }
+
+       static public double mega_battery_voltage(int v_batt) {
+               if (v_batt != AltosRecord.MISSING)
+                       return 3.3 * mega_adc(v_batt) * (15.0 + 27.0) / 27.0;
+               return AltosRecord.MISSING;
+       }
+
+       static double mega_pyro_voltage(int raw) {
+               if (raw != AltosRecord.MISSING)
+                       return 3.3 * mega_adc(raw) * (100.0 + 27.0) / 27.0;
+               return AltosRecord.MISSING;
+       }
+
        public static double radio_to_frequency(int freq, int setting, int cal, int channel) {
                double  f;
 
index 31646c7..081b3be 100644 (file)
@@ -27,8 +27,26 @@ public abstract class AltosEeprom implements AltosStateUpdate {
        public int      data8[];
        public boolean  valid;
 
+       public int data8(int i) {
+               return data8[i];
+       }
+
+       public int data16(int i) {
+               return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16;
+       }
+
+       public int data24(int i) {
+               return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16);
+       }
+
+       public int data32(int i) {
+               return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24);
+       }
+
        public final static int header_length = 4;
 
+       public abstract int record_length();
+
        public abstract void update_state(AltosState state);
 
        public void write(PrintStream out) {
@@ -40,14 +58,28 @@ public abstract class AltosEeprom implements AltosStateUpdate {
                out.printf ("\n");
        }
 
-       void parse_chunk(AltosEepromChunk chunk, int start, int record_length) throws ParseException {
+       public String string() {
+               String  s;
+
+               s = String.format("%c %04x", cmd, tick);
+               if (data8 != null) {
+                       for (int i = 0; i < data8.length; i++) {
+                               String  d = String.format(" %02x", data8[i]);
+                               s = s.concat(d);
+                       }
+               }
+               s = s.concat("\n");
+               return s;
+       }
+
+       void parse_chunk(AltosEepromChunk chunk, int start) throws ParseException {
                cmd = chunk.data(start);
 
-               int data_length = record_length - header_length;
+               int data_length = record_length() - header_length;
 
-               valid = !chunk.erased(start, record_length);
+               valid = !chunk.erased(start, record_length());
                if (valid) {
-                       if (AltosConvert.checksum(chunk.data, start, record_length) != 0)
+                       if (AltosConvert.checksum(chunk.data, start, record_length()) != 0)
                                throw new ParseException(String.format("invalid checksum at 0x%x",
                                                                       chunk.address + start), 0);
                } else {
@@ -61,12 +93,12 @@ public abstract class AltosEeprom implements AltosStateUpdate {
                        data8[i] = chunk.data(start + header_length + i);
        }
 
-       void parse_string(String line, int record_length) {
+       void parse_string(String line) {
                valid = false;
                tick = 0;
                cmd = AltosLib.AO_LOG_INVALID;
 
-               int data_length = record_length - header_length;
+               int data_length = record_length() - header_length;
 
                if (line == null)
                        return;
@@ -79,6 +111,7 @@ public abstract class AltosEeprom implements AltosStateUpdate {
                                        tick = Integer.parseInt(tokens[1],16);
                                        valid = true;
                                        data8 = new int[data_length];
+
                                        for (int i = 0; i < data_length; i++)
                                                data8[i] = Integer.parseInt(tokens[2 + i],16);
                                }
index b1bba3b..1709352 100644 (file)
@@ -62,6 +62,32 @@ public class AltosEepromChunk {
                return true;
        }
 
+       public AltosEeprom eeprom(int offset, int log_format) {
+               AltosEeprom     eeprom = null;
+               try {
+                       switch (log_format) {
+                       case AltosLib.AO_LOG_FORMAT_FULL:
+                               eeprom = new AltosEepromTM(this, offset);
+                               break;
+                       case AltosLib.AO_LOG_FORMAT_TINY:
+                       case AltosLib.AO_LOG_FORMAT_TELEMETRY:
+                       case AltosLib.AO_LOG_FORMAT_TELESCIENCE:
+                       case AltosLib.AO_LOG_FORMAT_TELEMEGA:
+                               eeprom = new AltosEepromMega(this, offset);
+                               break;
+                       case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
+                               eeprom = new AltosEepromMetrum2(this, offset);
+                               break;
+                       case AltosLib.AO_LOG_FORMAT_TELEMINI:
+                       case AltosLib.AO_LOG_FORMAT_EASYMINI:
+                               eeprom = new AltosEepromMini(this, offset);
+                               break;
+                       }
+               } catch (ParseException e) {
+               }
+               return eeprom;
+       }
+
        public AltosEepromChunk(AltosLink link, int block, boolean flush)
                throws TimeoutException, InterruptedException {
 
index 2f4c54d..367b679 100644 (file)
@@ -72,6 +72,7 @@ public class AltosEepromFile extends AltosStateIterable {
                headers = new AltosEepromIterable(AltosEepromHeader.read(input));
 
                start = headers.state();
+               start.set_state(AltosLib.ao_flight_pad);
 
                switch (start.log_format) {
                case AltosLib.AO_LOG_FORMAT_FULL:
@@ -81,6 +82,10 @@ public class AltosEepromFile extends AltosStateIterable {
                case AltosLib.AO_LOG_FORMAT_TELEMETRY:
                case AltosLib.AO_LOG_FORMAT_TELESCIENCE:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA:
+                       body = new AltosEepromIterable(AltosEepromMega.read(input));
+                       break;
+               case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
+                       body = new AltosEepromIterable(AltosEepromMetrum2.read(input));
                        break;
                case AltosLib.AO_LOG_FORMAT_TELEMINI:
                case AltosLib.AO_LOG_FORMAT_EASYMINI:
diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java
new file mode 100644 (file)
index 0000000..d8e47a6
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+public class AltosEepromGPS extends AltosEeprom {
+       public static final int record_length = 16;
+
+       public int record_length() { return record_length; }
+
+       /* AO_LOG_FLIGHT elements */
+       public int flight() { return data16(0); }
+       public int ground_accel() { return data16(2); }
+       public int ground_pres() { return data32(4); }
+       public int ground_temp() { return data32(8); }
+
+       /* AO_LOG_STATE elements */
+       public int state() { return data16(0); }
+       public int reason() { return data16(2); }
+
+       /* AO_LOG_SENSOR elements */
+       public int pres() { return data32(0); }
+       public int temp() { return data32(4); }
+       public int accel() { return data16(8); }
+
+       /* AO_LOG_TEMP_VOLT elements */
+       public int v_batt() { return data16(0); }
+       public int sense_a() { return data16(2); }
+       public int sense_m() { return data16(4); }
+
+       /* AO_LOG_GPS_POS elements */
+       public int latitude() { return data32(0); }
+       public int longitude() { return data32(4); }
+       public int altitude() { return data16(8); }
+
+       /* AO_LOG_GPS_TIME elements */
+       public int hour() { return data8(0); }
+       public int minute() { return data8(1); }
+       public int second() { return data8(2); }
+       public int flags() { return data8(3); }
+       public int year() { return data8(4); }
+       public int month() { return data8(5); }
+       public int day() { return data8(6); }
+       
+       /* AO_LOG_GPS_SAT elements */
+       public int nsat() { return data8(0); }
+       public int more() { return data8(1); }
+       public int svid(int n) { return data8(2 + n * 2); }
+       public int c_n(int n) { return data8(2 + n * 2 + 1); }
+
+       public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException {
+               parse_chunk(chunk, start);
+       }
+
+       public void update_state(AltosState state) {
+               AltosGPS        gps;
+
+               /* Flush any pending GPS changes */
+               if (state.gps_pending) {
+                       switch (cmd) {
+                       case AltosLib.AO_LOG_GPS_POS:
+                       case AltosLib.AO_LOG_GPS_LAT:
+                       case AltosLib.AO_LOG_GPS_LON:
+                       case AltosLib.AO_LOG_GPS_ALT:
+                       case AltosLib.AO_LOG_GPS_SAT:
+                       case AltosLib.AO_LOG_GPS_DATE:
+                               break;
+                       default:
+                               state.set_temp_gps();
+                               break;
+                       }
+               }
+
+               if (cmd != AltosLib.AO_LOG_FLIGHT)
+                       state.set_tick(tick);
+               switch (cmd) {
+               case AltosLib.AO_LOG_FLIGHT:
+                       state.set_boost_tick(tick);
+                       state.set_flight(flight());
+                       state.set_ground_accel(ground_accel());
+                       state.set_ground_pressure(ground_pres());
+//                     state.set_temperature(ground_temp() / 100.0);
+                       break;
+               case AltosLib.AO_LOG_STATE:
+                       state.set_state(state());
+                       break;
+               case AltosLib.AO_LOG_SENSOR:
+                       state.set_ms5607(pres(), temp());
+                       state.set_accel(accel());
+
+                       break;
+               case AltosLib.AO_LOG_TEMP_VOLT:
+                       state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+
+                       state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
+                       state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
+
+                       break;
+               case AltosLib.AO_LOG_GPS_POS:
+                       gps = state.make_temp_gps();
+                       gps.lat = latitude() / 1e7;
+                       gps.lon = longitude() / 1e7;
+                       gps.alt = altitude();
+                       break;
+               case AltosLib.AO_LOG_GPS_TIME:
+                       gps = state.make_temp_gps();
+
+                       gps.hour = hour();
+                       gps.minute = minute();
+                       gps.second = second();
+
+                       int flags = flags();
+
+                       gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0;
+                       gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0;
+                       gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >>
+                               AltosLib.AO_GPS_NUM_SAT_SHIFT;
+
+                       gps.year = year();
+                       gps.month = month();
+                       gps.day = day();
+                       break;
+               case AltosLib.AO_LOG_GPS_SAT:
+                       state.set_tick(tick);
+                       gps = state.make_temp_gps();
+
+                       int n = nsat();
+                       for (int i = 0; i < n; i++)
+                               gps.add_sat(svid(i), c_n(i));
+                       break;
+               }
+       }
+
+       public AltosEepromMetrum2 (String line) {
+               parse_string(line);
+       }
+
+       static public LinkedList<AltosEeprom> read(FileInputStream input) {
+               LinkedList<AltosEeprom> megas = new LinkedList<AltosEeprom>();
+
+               for (;;) {
+                       try {
+                               String line = AltosLib.gets(input);
+                               if (line == null)
+                                       break;
+                               try {
+                                       AltosEepromMetrum2 mega = new AltosEepromMetrum2(line);
+                                       if (mega.cmd != AltosLib.AO_LOG_INVALID)
+                                               megas.add(mega);
+                               } catch (Exception e) {
+                                       System.out.printf ("exception\n");
+                               }
+                       } catch (IOException ie) {
+                               break;
+                       }
+               }
+
+               return megas;
+       }
+}
index a06f05e..35a03a1 100644 (file)
@@ -29,6 +29,9 @@ public class AltosEepromHeader extends AltosEeprom {
        public boolean  last;
        public boolean  valid;
 
+       public int record_length () { return 0; }
+
+       /* XXX pull rest of config data to state */
        public void update_state(AltosState state) {
                switch (cmd) {
                case AltosLib.AO_LOG_CONFIG_VERSION:
@@ -40,7 +43,7 @@ public class AltosEepromHeader extends AltosEeprom {
                case AltosLib.AO_LOG_RADIO_CHANNEL:
                        break;
                case AltosLib.AO_LOG_CALLSIGN:
-                       state.callsign = data;
+                       state.set_callsign(data);
                        break;
                case AltosLib.AO_LOG_ACCEL_CAL:
                        state.set_accel_g(config_a, config_b);
@@ -90,6 +93,7 @@ public class AltosEepromHeader extends AltosEeprom {
                        state.baro.crc = config_a;
                        break;
                case AltosLib.AO_LOG_SOFTWARE_VERSION:
+                       state.set_firmware_version(data);
                        break;
                }
        }
index 0804c39..e8f9b1f 100644 (file)
 
 package org.altusmetrum.altoslib_1;
 
+import java.io.*;
+import java.util.*;
 import java.text.*;
 
-public class AltosEepromMega {
-       public int      cmd;
-       public int      tick;
-       public boolean  valid;
-       public String   data;
-       public int      config_a, config_b;
-
-       public int      data8[];
-
+public class AltosEepromMega extends AltosEeprom {
        public static final int record_length = 32;
-       static final int        header_length = 4;
-       static final int        data_length = record_length - header_length;
-
-       public int data8(int i) {
-               return data8[i];
-       }
 
-       public int data16(int i) {
-               return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16;
-       }
-
-       public int data32(int i) {
-               return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24);
-       }
+       public int record_length() { return record_length; }
 
        /* AO_LOG_FLIGHT elements */
        public int flight() { return data16(0); }
@@ -68,7 +50,7 @@ public class AltosEepromMega {
        public int mag_z() { return data16(24); }
        public int accel() { return data16(26); }
 
-       /* AO_LOG_VOLT elements */
+       /* AO_LOG_TEMP_VOLT elements */
        public int v_batt() { return data16(0); }
        public int v_pbatt() { return data16(2); }
        public int nsense() { return data16(4); }
@@ -91,131 +73,137 @@ public class AltosEepromMega {
        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);
-
-               valid = !chunk.erased(start, record_length);
-               if (valid) {
-                       if (AltosConvert.checksum(chunk.data, start, record_length) != 0)
-                               throw new ParseException(String.format("invalid checksum at 0x%x",
-                                                                      chunk.address + start), 0);
-               } else {
-                       cmd = AltosLib.AO_LOG_INVALID;
-               }
+               parse_chunk(chunk, start);
+       }
 
-               tick = chunk.data16(start+2);
+       public void update_state(AltosState state) {
+               AltosGPS        gps;
+
+               /* Flush any pending GPS changes */
+               if (state.gps_pending) {
+                       switch (cmd) {
+                       case AltosLib.AO_LOG_GPS_LAT:
+                       case AltosLib.AO_LOG_GPS_LON:
+                       case AltosLib.AO_LOG_GPS_ALT:
+                       case AltosLib.AO_LOG_GPS_SAT:
+                       case AltosLib.AO_LOG_GPS_DATE:
+                               break;
+                       default:
+                               state.set_temp_gps();
+                               break;
+                       }
+               }
 
-               data8 = new int[data_length];
-               for (int i = 0; i < data_length; i++)
-                       data8[i] = chunk.data(start + header_length + i);
+               switch (cmd) {
+               case AltosLib.AO_LOG_FLIGHT:
+                       state.set_boost_tick(tick);
+                       state.set_flight(flight());
+                       state.set_ground_accel(ground_accel());
+                       state.set_ground_pressure(ground_pres());
+                       state.set_temperature(ground_temp() / 100.0);
+                       break;
+               case AltosLib.AO_LOG_STATE:
+                       state.set_tick(tick);
+                       state.set_state(state());
+                       break;
+               case AltosLib.AO_LOG_SENSOR:
+                       state.set_tick(tick);
+                       state.set_ms5607(pres(), temp());
+
+                       AltosIMU imu = new AltosIMU();
+                       imu.accel_x = accel_x();
+                       imu.accel_y = accel_y();
+                       imu.accel_z = accel_z();
+
+                       imu.gyro_x = gyro_x();
+                       imu.gyro_y = gyro_y();
+                       imu.gyro_z = gyro_z();
+                       state.imu = imu;
+
+                       AltosMag mag = new AltosMag();
+                       mag.x = mag_x();
+                       mag.y = mag_y();
+                       mag.z = mag_z();
+
+                       state.mag = mag;
+
+                       state.set_accel(accel());
+
+                       break;
+               case AltosLib.AO_LOG_TEMP_VOLT:
+                       state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+                       state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt()));
+
+                       int nsense = nsense();
+
+                       state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2)));
+                       state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1)));
+
+                       double voltages[] = new double[nsense-2];
+                       for (int i = 0; i < nsense-2; i++)
+                               voltages[i] = AltosConvert.mega_pyro_voltage(sense(i));
+
+                       state.set_ignitor_voltage(voltages);
+                       break;
+               case AltosLib.AO_LOG_GPS_TIME:
+                       state.set_tick(tick);
+                       gps = state.make_temp_gps();
+                       gps.lat = latitude() / 1e7;
+                       gps.lon = longitude() / 1e7;
+                       gps.alt = altitude();
+
+                       gps.hour = hour();
+                       gps.minute = minute();
+                       gps.second = second();
+
+                       int flags = flags();
+
+                       gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0;
+                       gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0;
+                       gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >>
+                               AltosLib.AO_GPS_NUM_SAT_SHIFT;
+
+                       gps.year = year();
+                       gps.month = month();
+                       gps.day = day();
+                       break;
+               case AltosLib.AO_LOG_GPS_SAT:
+                       state.set_tick(tick);
+                       gps = state.make_temp_gps();
+
+                       int n = nsat();
+                       for (int i = 0; i < n; i++)
+                               gps.add_sat(svid(i), c_n(i));
+                       break;
+               }
        }
 
        public AltosEepromMega (String line) {
-               valid = false;
-               tick = 0;
+               parse_string(line);
+       }
 
-               if (line == null) {
-                       cmd = AltosLib.AO_LOG_INVALID;
-                       line = "";
-               } else {
+       static public LinkedList<AltosEeprom> read(FileInputStream input) {
+               LinkedList<AltosEeprom> megas = new LinkedList<AltosEeprom>();
+
+               for (;;) {
                        try {
-                               String[] tokens = line.split("\\s+");
-
-                               if (tokens[0].length() == 1) {
-                                       if (tokens.length != 2 + data_length) {
-                                               cmd = AltosLib.AO_LOG_INVALID;
-                                               data = line;
-                                       } else {
-                                               cmd = tokens[0].codePointAt(0);
-                                               tick = Integer.parseInt(tokens[1],16);
-                                               valid = true;
-                                               data8 = new int[data_length];
-                                               for (int i = 0; i < data_length; i++)
-                                                       data8[i] = Integer.parseInt(tokens[2 + i],16);
-                                       }
-                               } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) {
-                                       cmd = AltosLib.AO_LOG_CONFIG_VERSION;
-                                       data = tokens[2];
-                               } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) {
-                                       cmd = AltosLib.AO_LOG_MAIN_DEPLOY;
-                                       config_a = Integer.parseInt(tokens[2]);
-                               } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) {
-                                       cmd = AltosLib.AO_LOG_APOGEE_DELAY;
-                                       config_a = Integer.parseInt(tokens[2]);
-                               } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) {
-                                       cmd = AltosLib.AO_LOG_RADIO_CHANNEL;
-                                       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;
-                                       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;
-                                       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;
-                                       config_a = Integer.parseInt(tokens[3]);
-                               } else if (tokens[0].equals("manufacturer")) {
-                                       cmd = AltosLib.AO_LOG_MANUFACTURER;
-                                       data = tokens[1];
-                               } else if (tokens[0].equals("product")) {
-                                       cmd = AltosLib.AO_LOG_PRODUCT;
-                                       data = tokens[1];
-                               } else if (tokens[0].equals("serial-number")) {
-                                       cmd = AltosLib.AO_LOG_SERIAL_NUMBER;
-                                       config_a = Integer.parseInt(tokens[1]);
-                               } else if (tokens[0].equals("log-format")) {
-                                       cmd = AltosLib.AO_LOG_LOG_FORMAT;
-                                       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;
-                                               config_a = Integer.parseInt(tokens[2]);
-                                       } else if (tokens[1].equals("sens:")) {
-                                               cmd = AltosLib.AO_LOG_BARO_SENS;
-                                               config_a = Integer.parseInt(tokens[2]);
-                                       } else if (tokens[1].equals("off:")) {
-                                               cmd = AltosLib.AO_LOG_BARO_OFF;
-                                               config_a = Integer.parseInt(tokens[2]);
-                                       } else if (tokens[1].equals("tcs:")) {
-                                               cmd = AltosLib.AO_LOG_BARO_TCS;
-                                               config_a = Integer.parseInt(tokens[2]);
-                                       } else if (tokens[1].equals("tco:")) {
-                                               cmd = AltosLib.AO_LOG_BARO_TCO;
-                                               config_a = Integer.parseInt(tokens[2]);
-                                       } else if (tokens[1].equals("tref:")) {
-                                               cmd = AltosLib.AO_LOG_BARO_TREF;
-                                               config_a = Integer.parseInt(tokens[2]);
-                                       } else if (tokens[1].equals("tempsens:")) {
-                                               cmd = AltosLib.AO_LOG_BARO_TEMPSENS;
-                                               config_a = Integer.parseInt(tokens[2]);
-                                       } else if (tokens[1].equals("crc:")) {
-                                               cmd = AltosLib.AO_LOG_BARO_CRC;
-                                               config_a = Integer.parseInt(tokens[2]);
-                                       } else {
-                                               cmd = AltosLib.AO_LOG_INVALID;
-                                               data = line;
-                                       }
-                               } else {
-                                       cmd = AltosLib.AO_LOG_INVALID;
-                                       data = line;
+                               String line = AltosLib.gets(input);
+                               if (line == null)
+                                       break;
+                               try {
+                                       AltosEepromMega mega = new AltosEepromMega(line);
+                                       if (mega.cmd != AltosLib.AO_LOG_INVALID)
+                                               megas.add(mega);
+                               } catch (Exception e) {
+                                       System.out.printf ("exception\n");
                                }
-                       } catch (NumberFormatException ne) {
-                               cmd = AltosLib.AO_LOG_INVALID;
-                               data = line;
+                       } catch (IOException ie) {
+                               break;
                        }
                }
-       }
 
-       public AltosEepromMega(int in_cmd, int in_tick) {
-               cmd = in_cmd;
-               tick = in_tick;
-               valid = true;
+               return megas;
        }
 }
index 7288703..e035e5f 100644 (file)
@@ -32,6 +32,8 @@ public class AltosEepromMetrum {
        static final int        header_length = 4;
        static final int        data_length = record_length - header_length;
 
+       public int record_length() { return record_length; }
+
        public int data8(int i) {
                return data8[i];
        }
diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java
new file mode 100644 (file)
index 0000000..5a616e6
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+public class AltosEepromMetrum2 extends AltosEeprom {
+       public static final int record_length = 16;
+
+       public int record_length() { return record_length; }
+
+       /* AO_LOG_FLIGHT elements */
+       public int flight() { return data16(0); }
+       public int ground_accel() { return data16(2); }
+       public int ground_pres() { return data32(4); }
+       public int ground_temp() { return data32(8); }
+
+       /* AO_LOG_STATE elements */
+       public int state() { return data16(0); }
+       public int reason() { return data16(2); }
+
+       /* AO_LOG_SENSOR elements */
+       public int pres() { return data32(0); }
+       public int temp() { return data32(4); }
+       public int accel() { return data16(8); }
+
+       /* AO_LOG_TEMP_VOLT elements */
+       public int v_batt() { return data16(0); }
+       public int sense_a() { return data16(2); }
+       public int sense_m() { return data16(4); }
+
+       /* AO_LOG_GPS_POS elements */
+       public int latitude() { return data32(0); }
+       public int longitude() { return data32(4); }
+       public int altitude() { return data16(8); }
+
+       /* AO_LOG_GPS_TIME elements */
+       public int hour() { return data8(0); }
+       public int minute() { return data8(1); }
+       public int second() { return data8(2); }
+       public int flags() { return data8(3); }
+       public int year() { return data8(4); }
+       public int month() { return data8(5); }
+       public int day() { return data8(6); }
+       
+       /* AO_LOG_GPS_SAT elements */
+       public int nsat() { return data8(0); }
+       public int more() { return data8(1); }
+       public int svid(int n) { return data8(2 + n * 2); }
+       public int c_n(int n) { return data8(2 + n * 2 + 1); }
+
+       public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException {
+               parse_chunk(chunk, start);
+       }
+
+       public void update_state(AltosState state) {
+               AltosGPS        gps;
+
+               /* Flush any pending GPS changes */
+               if (state.gps_pending) {
+                       switch (cmd) {
+                       case AltosLib.AO_LOG_GPS_POS:
+                       case AltosLib.AO_LOG_GPS_LAT:
+                       case AltosLib.AO_LOG_GPS_LON:
+                       case AltosLib.AO_LOG_GPS_ALT:
+                       case AltosLib.AO_LOG_GPS_SAT:
+                       case AltosLib.AO_LOG_GPS_DATE:
+                               break;
+                       default:
+                               state.set_temp_gps();
+                               break;
+                       }
+               }
+
+               if (cmd != AltosLib.AO_LOG_FLIGHT)
+                       state.set_tick(tick);
+               switch (cmd) {
+               case AltosLib.AO_LOG_FLIGHT:
+                       state.set_boost_tick(tick);
+                       state.set_flight(flight());
+                       state.set_ground_accel(ground_accel());
+                       state.set_ground_pressure(ground_pres());
+//                     state.set_temperature(ground_temp() / 100.0);
+                       break;
+               case AltosLib.AO_LOG_STATE:
+                       state.set_state(state());
+                       break;
+               case AltosLib.AO_LOG_SENSOR:
+                       state.set_ms5607(pres(), temp());
+                       state.set_accel(accel());
+
+                       break;
+               case AltosLib.AO_LOG_TEMP_VOLT:
+                       state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt()));
+
+                       state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a()));
+                       state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m()));
+
+                       break;
+               case AltosLib.AO_LOG_GPS_POS:
+                       gps = state.make_temp_gps();
+                       gps.lat = latitude() / 1e7;
+                       gps.lon = longitude() / 1e7;
+                       gps.alt = altitude();
+                       break;
+               case AltosLib.AO_LOG_GPS_TIME:
+                       gps = state.make_temp_gps();
+
+                       gps.hour = hour();
+                       gps.minute = minute();
+                       gps.second = second();
+
+                       int flags = flags();
+
+                       gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0;
+                       gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0;
+                       gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >>
+                               AltosLib.AO_GPS_NUM_SAT_SHIFT;
+
+                       gps.year = year();
+                       gps.month = month();
+                       gps.day = day();
+                       break;
+               case AltosLib.AO_LOG_GPS_SAT:
+                       state.set_tick(tick);
+                       gps = state.make_temp_gps();
+
+                       int n = nsat();
+                       for (int i = 0; i < n; i++)
+                               gps.add_sat(svid(i), c_n(i));
+                       break;
+               }
+       }
+
+       public AltosEepromMetrum2 (String line) {
+               parse_string(line);
+       }
+
+       static public LinkedList<AltosEeprom> read(FileInputStream input) {
+               LinkedList<AltosEeprom> megas = new LinkedList<AltosEeprom>();
+
+               for (;;) {
+                       try {
+                               String line = AltosLib.gets(input);
+                               if (line == null)
+                                       break;
+                               try {
+                                       AltosEepromMetrum2 mega = new AltosEepromMetrum2(line);
+                                       if (mega.cmd != AltosLib.AO_LOG_INVALID)
+                                               megas.add(mega);
+                               } catch (Exception e) {
+                                       System.out.printf ("exception\n");
+                               }
+                       } catch (IOException ie) {
+                               break;
+                       }
+               }
+
+               return megas;
+       }
+}
index 1e0ff1b..15ec192 100644 (file)
@@ -24,21 +24,7 @@ import java.text.*;
 public class AltosEepromMini extends AltosEeprom {
        public static final int record_length = 16;
 
-       public int data8(int i) {
-               return data8[i];
-       }
-
-       public int data16(int i) {
-               return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16;
-       }
-
-       public int data24(int i) {
-               return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16);
-       }
-
-       public int data32(int i) {
-               return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24);
-       }
+       public int record_length() { return record_length; }
 
        /* AO_LOG_FLIGHT elements */
        public int flight() { return data16(0); }
@@ -84,11 +70,11 @@ public class AltosEepromMini extends AltosEeprom {
        }
 
        public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException {
-               parse_chunk(chunk, start, record_length);
+               parse_chunk(chunk, start);
        }
 
        public AltosEepromMini (String line) {
-               parse_string(line, record_length);
+               parse_string(line);
        }
 
        public AltosEepromMini(int in_cmd, int in_tick) {
index 6945468..461a7a9 100644 (file)
@@ -30,16 +30,16 @@ public class AltosEepromTM extends AltosEeprom {
 
        public static final int record_length = 8;
 
-       static double
-       thermometer_to_temperature(double thermo)
-       {
-               return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247;
-       }
-
        public void write(PrintStream out) {
                out.printf("%c %4x %4x %4x\n", cmd, tick, a, b);
        }
 
+       public int record_length() { return record_length; }
+
+       public String string() {
+               return String.format("%c %4x %4x %4x\n", cmd, tick, a, b);
+       }
+
        public void update_state(AltosState state) {
                AltosGPS        gps;
 
@@ -77,7 +77,7 @@ public class AltosEepromTM extends AltosEeprom {
                        break;
                case AltosLib.AO_LOG_TEMP_VOLT:
                        state.set_tick(tick);
-                       state.set_temperature(thermometer_to_temperature(a));
+                       state.set_temperature(AltosConvert.thermometer_to_temperature(a));
                        state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(b));
                        break;
                case AltosLib.AO_LOG_DEPLOY:
index 2a828cf..bacd66b 100644 (file)
@@ -33,6 +33,8 @@ public class AltosEepromTeleScience {
        static final int        max_data = 12;
        public static final int record_length = 32;
 
+       public int record_length() { return record_length; }
+
        public AltosEepromTeleScience (AltosEepromChunk chunk, int start) throws ParseException {
                type = chunk.data(start);
 
index 399e95b..a8c19e4 100644 (file)
@@ -65,8 +65,8 @@ public class AltosGPS implements Cloneable {
        }
 
        public void ClearGPSTime() {
-               year = month = day = 0;
-               hour = minute = second = 0;
+               year = month = day = AltosRecord.MISSING;
+               hour = minute = second = AltosRecord.MISSING;
        }
 
        public AltosGPS(AltosTelemetryMap map) throws ParseException {
@@ -212,6 +212,9 @@ public class AltosGPS implements Cloneable {
        }
 
        public AltosGPS() {
+               lat = AltosRecord.MISSING;
+               lon = AltosRecord.MISSING;
+               alt = AltosRecord.MISSING;
                ClearGPSTime();
                cc_gps_sat = null;
        }
@@ -280,6 +283,9 @@ public class AltosGPS implements Cloneable {
                                }
                        }
                } else {
+                       lat = AltosRecord.MISSING;
+                       lon = AltosRecord.MISSING;
+                       alt = AltosRecord.MISSING;
                        ClearGPSTime();
                        cc_gps_sat = null;
                }
index 4ca8ad9..d6d78ca 100644 (file)
@@ -28,6 +28,7 @@ public class AltosLib {
        public static final int AO_LOG_TEMP_VOLT = 'T';
        public static final int AO_LOG_DEPLOY = 'D';
        public static final int AO_LOG_STATE = 'S';
+       public static final int AO_LOG_GPS_POS = 'P';
        public static final int AO_LOG_GPS_TIME = 'G';
        public static final int AO_LOG_GPS_LAT = 'N';
        public static final int AO_LOG_GPS_LON = 'W';
index aa3de43..b80d7b2 100644 (file)
@@ -32,7 +32,7 @@ public class AltosState implements Cloneable {
 
        /* derived data */
 
-       public long     report_time;
+       public long     received_time;
 
        public double   time;
        public double   prev_time;
@@ -48,6 +48,12 @@ public class AltosState implements Cloneable {
        public boolean  boost;  /* under power */
        public int      rssi;
        public int      status;
+       public int      device_type;
+       public int      config_major;
+       public int      config_minor;
+       public int      apogee_delay;
+       public int      main_deploy;
+       public int      flight_log_max;
 
        public double   ground_altitude;
        public double   ground_pressure;
@@ -61,11 +67,16 @@ public class AltosState implements Cloneable {
        public double   apogee_voltage;
        public double   main_voltage;
        public double   speed;
+       public double   ignitor_voltage[];
 
        public double   prev_height;
        public double   prev_speed;
        public double   prev_acceleration;
 
+       public double   prev_max_height;
+       public double   prev_max_acceleration;
+       public double   prev_max_speed;
+
        public double   max_height;
        public double   max_acceleration;
        public double   max_speed;
@@ -100,6 +111,8 @@ public class AltosState implements Cloneable {
        public double   speak_altitude;
 
        public String   callsign;
+       public String   firmware_version;
+
        public double   accel_plus_g;
        public double   accel_minus_g;
        public double   accel;
@@ -133,7 +146,7 @@ public class AltosState implements Cloneable {
 
                set = 0;
 
-               report_time = System.currentTimeMillis();
+               received_time = System.currentTimeMillis();
                time = AltosRecord.MISSING;
                time_change = AltosRecord.MISSING;
                prev_time = AltosRecord.MISSING;
@@ -145,6 +158,12 @@ public class AltosState implements Cloneable {
                boost = false;
                rssi = AltosRecord.MISSING;
                status = 0;
+               device_type = AltosRecord.MISSING;
+               config_major = AltosRecord.MISSING;
+               config_minor = AltosRecord.MISSING;
+               apogee_delay = AltosRecord.MISSING;
+               main_deploy = AltosRecord.MISSING;
+               flight_log_max = AltosRecord.MISSING;
 
                ground_altitude = AltosRecord.MISSING;
                ground_pressure = AltosRecord.MISSING;
@@ -158,10 +177,15 @@ public class AltosState implements Cloneable {
                prev_speed = AltosRecord.MISSING;
                prev_acceleration = AltosRecord.MISSING;
 
+               prev_max_height = 0;
+               prev_max_speed = 0;
+               prev_max_acceleration = 0;
+
                battery_voltage = AltosRecord.MISSING;
                pyro_voltage = AltosRecord.MISSING;
                apogee_voltage = AltosRecord.MISSING;
                main_voltage = AltosRecord.MISSING;
+               ignitor_voltage = null;
 
                speed = AltosRecord.MISSING;
 
@@ -219,7 +243,7 @@ public class AltosState implements Cloneable {
                        return;
                }
 
-               report_time = old.report_time;
+               received_time = old.received_time;
                time = old.time;
                time_change = 0;
                tick = old.tick;
@@ -232,6 +256,12 @@ public class AltosState implements Cloneable {
                boost = old.boost;
                rssi = old.rssi;
                status = old.status;
+               device_type = old.device_type;
+               config_major = old.config_major;
+               config_minor = old.config_minor;
+               apogee_delay = old.apogee_delay;
+               main_deploy = old.main_deploy;
+               flight_log_max = old.flight_log_max;
                
                set = 0;
 
@@ -245,11 +275,16 @@ public class AltosState implements Cloneable {
                temperature = old.temperature;
                apogee_voltage = old.apogee_voltage;
                main_voltage = old.main_voltage;
+               ignitor_voltage = old.ignitor_voltage;
                speed = old.speed;
 
                prev_height = old.height;
                prev_speed = old.speed;
                prev_acceleration = old.acceleration;
+
+               prev_max_height = old.max_height;
+               prev_max_speed = old.max_speed;
+               prev_max_acceleration = old.max_acceleration;
                prev_time = old.time;
 
                max_height = old.max_height;
@@ -343,7 +378,7 @@ public class AltosState implements Cloneable {
                else
                        height = AltosRecord.MISSING;
 
-               if (height != AltosRecord.MISSING && height > max_height)
+               if (height != AltosRecord.MISSING && height > prev_max_height)
                        max_height = height;
 
                update_speed();
@@ -394,31 +429,34 @@ public class AltosState implements Cloneable {
                                }
                        }
                }
-               if (boost && speed != AltosRecord.MISSING && speed > max_speed)
+               if (boost && speed != AltosRecord.MISSING && speed > prev_max_speed)
                        max_speed = speed;
        }
        
        void update_accel() {
-               double  ground = ground_accel;
-
-               if (ground == AltosRecord.MISSING)
-                       ground = ground_accel_avg;
-               if (accel == AltosRecord.MISSING)
-                       return;
-               if (ground == AltosRecord.MISSING)
-                       return;
-               if (accel_plus_g == AltosRecord.MISSING)
-                       return;
-               if (accel_minus_g == AltosRecord.MISSING)
-                       return;
-
-               double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0;
-               double counts_per_mss = counts_per_g / 9.80665;
-
-               acceleration = (ground - accel) / counts_per_mss;
+               if (kalman_acceleration != AltosRecord.MISSING) {
+                       acceleration = kalman_acceleration;
+               } else {
+                       double  ground = ground_accel;
+
+                       if (ground == AltosRecord.MISSING)
+                               ground = ground_accel_avg;
+                       if (accel == AltosRecord.MISSING)
+                               return;
+                       if (ground == AltosRecord.MISSING)
+                               return;
+                       if (accel_plus_g == AltosRecord.MISSING)
+                               return;
+                       if (accel_minus_g == AltosRecord.MISSING)
+                               return;
+
+                       double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0;
+                       double counts_per_mss = counts_per_g / 9.80665;
+                       acceleration = (ground - accel) / counts_per_mss;
+               }
 
                /* Only look at accelerometer data under boost */
-               if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration))
+               if (boost && acceleration != AltosRecord.MISSING && acceleration > prev_max_acceleration)
                        max_acceleration = acceleration;
                update_speed();
        }
@@ -502,6 +540,26 @@ public class AltosState implements Cloneable {
 
        }
 
+       public void set_device_type(int device_type) {
+               this.device_type = device_type;
+       }
+
+       public void set_config(int major, int minor, int apogee_delay, int main_deploy, int flight_log_max) {
+               config_major = major;
+               config_minor = minor;
+               this.apogee_delay = apogee_delay;
+               this.main_deploy = main_deploy;
+               this.flight_log_max = flight_log_max;
+       }
+
+       public void set_callsign(String callsign) {
+               this.callsign = callsign;
+       }
+
+       public void set_firmware_version(String version) {
+               firmware_version = version;
+       }
+
        public void set_flight(int flight) {
 
                /* When the flight changes, reset the state */
@@ -538,6 +596,10 @@ public class AltosState implements Cloneable {
                }
        }
 
+       public void set_received_time(long ms) {
+               received_time = ms;
+       }
+
        public void set_altitude(double altitude) {
                if (altitude != AltosRecord.MISSING) {
                        this.altitude = altitude;
@@ -577,6 +639,8 @@ public class AltosState implements Cloneable {
                        kalman_speed = speed;
                        kalman_acceleration = acceleration;
                        update_vertical_pos();
+                       update_speed();
+                       update_accel();
                }
        }
 
@@ -672,6 +736,9 @@ public class AltosState implements Cloneable {
                }
        }
 
+       public void set_ignitor_voltage(double[] voltage) {
+               this.ignitor_voltage = voltage;
+       }
 
        public double time_since_boost() {
                if (tick == AltosRecord.MISSING)
@@ -702,6 +769,13 @@ public class AltosState implements Cloneable {
                temp_gps = null;
        }
 
+       public AltosState clone() {
+               AltosState s = new AltosState();
+               s.copy(this);
+               return s;
+       }
+
+
        public void init (AltosRecord cur, AltosState prev_state) {
 
                System.out.printf ("init\n");
@@ -721,7 +795,7 @@ public class AltosState implements Cloneable {
 
                set_kalman(cur.kalman_height, cur.kalman_speed, cur.kalman_acceleration);
 
-               report_time = System.currentTimeMillis();
+               received_time = System.currentTimeMillis();
 
                set_temperature(cur.temperature());
                set_apogee_voltage(cur.drogue_voltage());
@@ -742,12 +816,6 @@ public class AltosState implements Cloneable {
 
        }
 
-       public AltosState clone() {
-               AltosState s = new AltosState();
-               s.copy(this);
-               return s;
-       }
-
        public AltosState(AltosRecord cur) {
                init(cur, null);
        }
@@ -756,6 +824,7 @@ public class AltosState implements Cloneable {
                init(cur, prev);
        }
 
+
        public AltosState () {
                init();
        }
index b84455d..82e5400 100644 (file)
@@ -43,6 +43,10 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
        }
 
        public void update_state(AltosState state) {
+               state.set_serial(serial);
+               state.set_tick(tick);
+               state.set_rssi(rssi, status);
+               state.set_received_time(received_time);
        }
 
        final static int PKT_APPEND_STATUS_1_CRC_OK             = (1 << 7);
@@ -56,9 +60,11 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
        final static int packet_type_location = 0x05;
        final static int packet_type_satellite = 0x06;
        final static int packet_type_companion = 0x07;
-       final static int packet_type_MM_sensor = 0x08;
-       final static int packet_type_MM_data = 0x09;
-       final static int packet_type_Mini = 0x10;
+       final static int packet_type_mega_sensor = 0x08;
+       final static int packet_type_mega_data = 0x09;
+       final static int packet_type_metrum_sensor = 0x0a;
+       final static int packet_type_metrum_data = 0x0b;
+       final static int packet_type_mini = 0x10;
        
        static AltosTelemetry parse_hex(String hex)  throws ParseException, AltosCRCException {
                AltosTelemetry  telem = null;
@@ -87,37 +93,7 @@ public abstract class AltosTelemetry implements AltosStateUpdate {
                /* length, data ..., rssi, status, checksum -- 4 bytes extra */
                switch (bytes.length) {
                case AltosLib.ao_telemetry_standard_len + 4:
-                       int     type = AltosLib.uint8(bytes, 4 + 1);
-/*
-                       switch (type) {
-                       case packet_type_TM_sensor:
-                       case packet_type_Tm_sensor:
-                       case packet_type_Tn_sensor:
-                               telem = new AltosTelemetrySensor(bytes);
-                               break;
-                       case packet_type_configuration:
-                               telem = new AltosTelemetryConfiguration(bytes);
-                               break;
-                       case packet_type_location:
-                               telem = new AltosTelemetryLocation(bytes);
-                               break;
-                       case packet_type_satellite:
-                               telem = new AltosTelemetrySatellite(bytes);
-                               break;
-                       case packet_type_companion:
-                               telem = new AltosTelemetryCompanion(bytes);
-                               break;
-                       case packet_type_MM_sensor:
-                               telem = new AltosTelemetryMegaSensor(bytes);
-                               break;
-                       case packet_type_MM_data:
-                               telem = new AltosTelemetryMegaData(bytes);
-                               break;
-                       default:
-                               telem = new AltosTelemetryRaw(bytes);
-                               break;
-                       }
-*/
+                       telem = AltosTelemetryStandard.parse_hex(bytes);
                        break;
                case AltosLib.ao_telemetry_0_9_len + 4:
                        telem = new AltosTelemetryLegacy(bytes);
diff --git a/altoslib/AltosTelemetryConfiguration.java b/altoslib/AltosTelemetryConfiguration.java
new file mode 100644 (file)
index 0000000..4c9bdd1
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+
+public class AltosTelemetryConfiguration extends AltosTelemetryStandard {
+       int     device_type;
+       int     flight;
+       int     config_major;
+       int     config_minor;
+       int     apogee_delay;
+       int     main_deploy;
+       int     flight_log_max;
+       String  callsign;
+       String  version;
+
+       public AltosTelemetryConfiguration(int[] bytes) {
+               super(bytes);
+
+               device_type    = uint8(5);
+               flight         = uint16(6);
+               config_major   = uint8(8);
+               config_minor   = uint8(9);
+               apogee_delay   = uint16(10);
+               main_deploy    = uint16(12);
+               flight_log_max = uint16(14);
+               callsign       = string(16, 8);
+               version        = string(24, 8);
+       }
+
+       public void update_state(AltosState state) {
+               super.update_state(state);
+               state.set_device_type(device_type);
+               state.set_flight(flight);
+               state.set_config(config_major, config_minor, apogee_delay, main_deploy, flight_log_max);
+
+               state.set_callsign(callsign);
+               state.set_firmware_version(version);
+       }
+}
index 45e5c31..95cbbee 100644 (file)
@@ -546,7 +546,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry {
                state.set_accel(accel);
                if (kalman_height != AltosRecord.MISSING)
                        state.set_kalman(kalman_height, kalman_speed, kalman_acceleration);
-               state.set_temperature(AltosEepromTM.thermometer_to_temperature(temp));
+               state.set_temperature(AltosConvert.thermometer_to_temperature(temp));
                state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt));
                state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(apogee));
                state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main));
diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java
new file mode 100644 (file)
index 0000000..fa3c24d
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+
+public class AltosTelemetryLocation extends AltosTelemetryStandard {
+       int     flags;
+       int     altitude;
+       int     latitude;
+       int     longitude;
+       int     year;
+       int     month;
+       int     day;
+       int     hour;
+       int     minute;
+       int     second;
+       int     pdop;
+       int     hdop;
+       int     vdop;
+       int     mode;
+       int     ground_speed;
+       int     climb_rate;
+       int     course;
+
+       public AltosTelemetryLocation(int[] bytes) {
+               super(bytes);
+
+               flags          = uint8(5);
+               altitude       = int16(6);
+               latitude       = uint32(8);
+               longitude      = uint32(12);
+               year           = uint8(16);
+               month          = uint8(17);
+               day            = uint8(18);
+               hour           = uint8(19);
+               minute         = uint8(20);
+               second         = uint8(21);
+               pdop           = uint8(22);
+               hdop           = uint8(23);
+               vdop           = uint8(24);
+               mode           = uint8(25);
+               ground_speed   = uint16(26);
+               climb_rate     = int16(28);
+               course         = uint8(30);
+       }
+
+       public void update_state(AltosState state) {
+               super.update_state(state);
+               AltosGPS        gps = state.make_temp_gps();
+
+               gps.nsat = flags & 0xf;
+               gps.locked = (flags & (1 << 4)) != 0;
+               gps.connected = (flags & (1 << 5)) != 0;
+
+               if (gps.locked) {
+                       gps.lat = latitude * 1.0e-7;
+                       gps.lon = longitude * 1.0e-7;
+                       gps.alt = altitude;
+                       gps.year = 2000 + year;
+                       gps.month = month;
+                       gps.day = day;
+                       gps.hour = hour;
+                       gps.minute = minute;
+                       gps.second = second;
+                       gps.ground_speed = ground_speed * 1.0e-2;
+                       gps.course = course * 2;
+                       gps.climb_rate = climb_rate * 1.0e-2;
+                       gps.hdop = hdop;
+                       gps.vdop = vdop;
+               }
+               state.set_temp_gps();
+       }
+}
diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java
new file mode 100644 (file)
index 0000000..5e6cd58
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+public class AltosTelemetryMegaData extends AltosTelemetryStandard {
+       int     state;
+       
+       int     v_batt;
+       int     v_pyro;
+       int     sense[];
+
+       int     ground_pres;
+       int     ground_accel;
+       int     accel_plus_g;
+       int     accel_minus_g;
+
+       int     acceleration;
+       int     speed;
+       int     height;
+
+       public AltosTelemetryMegaData(int[] bytes) {
+               super(bytes);
+
+               state = int8(5);
+
+               v_batt = int16(6);
+               v_pyro = int16(8);
+
+               sense = new int[6];     
+
+               for (int i = 0; i < 6; i++) {
+                       sense[i] = int8(10 + i) << 4;
+                       sense[i] |= sense[i] >> 8;
+               }
+
+               ground_pres = int32(16);
+               ground_accel = int16(20);
+               accel_plus_g = int16(22);
+               accel_minus_g = int16(24);
+
+               acceleration = int16(26);
+               speed = int16(28);
+               height = int16(30);
+       }
+
+       public void update_state(AltosState state) {
+               super.update_state(state);
+
+               state.set_state(this.state);
+                       
+               state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt));
+               state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro));
+
+               state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense[4]));
+               state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense[5]));
+
+               double voltages[] = new double[4];
+               for (int i = 0; i < 4; i++)
+                       voltages[i] = AltosConvert.mega_pyro_voltage(sense[i]);
+
+               state.set_ignitor_voltage(voltages);
+
+               state.set_ground_accel(ground_accel);
+               state.set_ground_pressure(ground_pres);
+               state.set_accel_g(accel_plus_g, accel_minus_g);
+
+               state.set_kalman(height, speed/16.0, acceleration / 16.0);
+       }
+}
+
diff --git a/altoslib/AltosTelemetryMegaSensor.java b/altoslib/AltosTelemetryMegaSensor.java
new file mode 100644 (file)
index 0000000..7c385cf
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+public class AltosTelemetryMegaSensor extends AltosTelemetryStandard {
+       int     accel;
+       int     pres;
+       int     temp;
+
+       int     accel_x;
+       int     accel_y;
+       int     accel_z;
+
+       int     gyro_x;
+       int     gyro_y;
+       int     gyro_z;
+
+       int     mag_x;
+       int     mag_y;
+       int     mag_z;
+
+       public AltosTelemetryMegaSensor(int[] bytes) {
+               super(bytes);
+
+               accel         = int16(6);
+               pres          = int32(8);
+               temp          = int16(12);
+
+               accel_x       = int16(14);
+               accel_y       = int16(16);
+               accel_z       = int16(18);
+
+               gyro_x        = int16(20);
+               gyro_y        = int16(22);
+               gyro_z        = int16(24);
+
+               mag_x         = int16(26);
+               mag_y         = int16(28);
+               mag_z         = int16(30);
+       }
+
+       public void update_state(AltosState state) {
+               super.update_state(state);
+
+               state.set_accel(accel);
+               state.set_pressure(pres);
+               state.set_temperature(temp / 100.0);
+
+               AltosIMU imu = new AltosIMU();
+               
+               imu.accel_x = accel_x;
+               imu.accel_y = accel_y;
+               imu.accel_z = accel_z;
+
+               imu.gyro_x = gyro_x;
+               imu.gyro_y = gyro_y;
+               imu.gyro_z = gyro_z;
+
+               state.imu = imu;
+
+               AltosMag mag = new AltosMag();
+
+               mag.x = mag_x;
+               mag.y = mag_y;
+               mag.z = mag_z;
+
+               state.mag = mag;
+       }
+}
diff --git a/altoslib/AltosTelemetryMetrumData.java b/altoslib/AltosTelemetryMetrumData.java
new file mode 100644 (file)
index 0000000..d419ab8
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+
+public class AltosTelemetryMetrumData extends AltosTelemetryStandard {
+
+       int     ground_pres;
+       int     ground_accel;
+       int     accel_plus_g;
+       int     accel_minus_g;
+
+       public AltosTelemetryMetrumData(int[] bytes) {
+               super(bytes);
+
+               ground_pres = int32(8);
+               ground_accel = int16(12);
+               accel_plus_g = int16(14);
+               accel_minus_g = int16(16);
+       }
+
+       public void update_state(AltosState state) {
+               state.set_ground_accel(ground_accel);
+               state.set_accel_g(accel_plus_g, accel_minus_g);
+               state.set_ground_pressure(ground_pres);
+       }
+}
diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java
new file mode 100644 (file)
index 0000000..59d34db
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+
+public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
+       int     state;
+
+       int     accel;
+       int     pres;
+       int     temp;
+
+       int     acceleration;
+       int     speed;
+       int     height;
+
+       int     v_batt;
+       int     sense_a;
+       int     sense_m;
+
+       public AltosTelemetryMetrumSensor(int[] bytes) {
+               super(bytes);
+
+               state         = int8(5);
+               accel         = int16(6);
+               pres          = int32(8);
+               temp          = int16(12);
+
+               acceleration  = int16(14);
+               speed         = int16(16);
+               height        = int16(18);
+
+               v_batt        = int16(20);
+               sense_a       = int16(22);
+               sense_m       = int16(24);
+       }
+
+       public void update_state(AltosState state) {
+               super.update_state(state);
+
+               state.set_state(this.state);
+
+               state.set_accel(accel);
+               state.set_ms5607(pres, temp);
+
+               state.set_kalman(height, speed/16.0, acceleration/16.0);
+
+               state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt));
+
+               state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a));
+               state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m));
+               System.out.printf ("sense_a %d apogee voltage %g\n", sense_a, state.apogee_voltage);
+       }
+}
diff --git a/altoslib/AltosTelemetryRaw.java b/altoslib/AltosTelemetryRaw.java
new file mode 100644 (file)
index 0000000..9ef7787
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+public class AltosTelemetryRaw extends AltosTelemetryStandard {
+       public AltosTelemetryRaw(int[] bytes) {
+               super(bytes);
+       }
+
+       public void update_state(AltosState state) {
+               super.update_state(state);
+       }
+}
diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java
new file mode 100644 (file)
index 0000000..3f70f21
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+public class AltosTelemetrySatellite extends AltosTelemetryStandard {
+       int             channels;
+       AltosGPSSat[]   sats;
+
+       public AltosTelemetrySatellite(int[] bytes) {
+               super(bytes);
+
+               channels = uint8(5);
+               if (channels > 12)
+                       channels = 12;
+               if (channels == 0)
+                       sats = null;
+               else {
+                       sats = new AltosGPSSat[channels];
+                       for (int i = 0; i < channels; i++) {
+                               int     svid =  uint8(6 + i * 2 + 0);
+                               int     c_n_1 = uint8(6 + i * 2 + 1);
+                               sats[i] = new AltosGPSSat(svid, c_n_1);
+                       }
+               }
+       }
+
+       public void update_state(AltosState state) {
+               super.update_state(state);
+
+               AltosGPS        gps = state.make_temp_gps();
+               
+               gps.cc_gps_sat = sats;
+               state.set_temp_gps();
+       }
+}
diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java
new file mode 100644 (file)
index 0000000..f89e56c
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+
+public class AltosTelemetrySensor extends AltosTelemetryStandard {
+       int     state;
+       int     accel;
+       int     pres;
+       int     temp;
+       int     v_batt;
+       int     sense_d;
+       int     sense_m;
+
+       int     acceleration;
+       int     speed;
+       int     height;
+
+       int     ground_accel;
+       int     ground_pres;
+       int     accel_plus_g;
+       int     accel_minus_g;
+
+       public AltosTelemetrySensor(int[] bytes) {
+               super(bytes);
+               state         = uint8(5);
+
+               accel         = int16(6);
+               pres          = int16(8);
+               temp          = int16(10);
+               v_batt        = int16(12);
+               sense_d       = int16(14);
+               sense_m       = int16(16);
+
+               acceleration  = int16(18);
+               speed         = int16(20);
+               height        = int16(22);
+
+               ground_pres   = int16(24);
+               ground_accel  = int16(26);
+               accel_plus_g  = int16(28);
+               accel_minus_g = int16(30);
+       }
+
+       public void update_state(AltosState state) {
+               super.update_state(state);
+
+               state.set_state(this.state);
+               if (type == packet_type_TM_sensor) {
+                       state.set_ground_accel(ground_accel);
+                       state.set_accel_g(accel_plus_g, accel_minus_g);
+                       state.set_accel(accel);
+               }
+               state.set_ground_pressure(AltosConvert.barometer_to_pressure(ground_pres));
+               state.set_pressure(AltosConvert.barometer_to_pressure(pres));
+               state.set_temperature(AltosConvert.thermometer_to_temperature(temp));
+               state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt));
+               if (type == packet_type_TM_sensor || type == packet_type_Tm_sensor) {
+                       state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d));
+                       state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m));
+               }
+
+               state.set_kalman(height, speed/16.0, acceleration / 16.0);
+       }
+}
diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java
new file mode 100644 (file)
index 0000000..fa86bf8
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_1;
+
+public abstract class AltosTelemetryStandard extends AltosTelemetry {
+       int[]   bytes;
+       int     type;
+
+       public int int8(int off) {
+               return AltosLib.int8(bytes, off + 1);
+       }
+
+       public int uint8(int off) {
+               return AltosLib.uint8(bytes, off + 1);
+       }
+
+       public int int16(int off) {
+               return AltosLib.int16(bytes, off + 1);
+       }
+
+       public int uint16(int off) {
+               return AltosLib.uint16(bytes, off + 1);
+       }
+
+       public int uint32(int off) {
+               return AltosLib.uint32(bytes, off + 1);
+       }
+
+       public int int32(int off) {
+               return AltosLib.int32(bytes, off + 1);
+       }
+
+       public String string(int off, int l) {
+               return AltosLib.string(bytes, off + 1, l);
+       }
+
+       public static AltosTelemetry parse_hex(int[] bytes) {
+               int     type = AltosLib.uint8(bytes, 4 + 1);
+
+               AltosTelemetry  telem;
+               switch (type) {
+               case packet_type_TM_sensor:
+               case packet_type_Tm_sensor:
+               case packet_type_Tn_sensor:
+                       telem = new AltosTelemetrySensor(bytes);
+                       break;
+               case packet_type_configuration:
+                       telem = new AltosTelemetryConfiguration(bytes);
+                       break;
+               case packet_type_location:
+                       telem = new AltosTelemetryLocation(bytes);
+                       break;
+               case packet_type_satellite:
+                       telem = new AltosTelemetrySatellite(bytes);
+                       break;
+/*
+               case packet_type_companion:
+                       telem = new AltosTelemetryCompanion(bytes);
+                       break;
+*/
+               case packet_type_mega_sensor:
+                       telem = new AltosTelemetryMegaSensor(bytes);
+                       break;
+               case packet_type_mega_data:
+                       telem = new AltosTelemetryMegaData(bytes);
+                       break;
+               case packet_type_metrum_sensor:
+                       telem = new AltosTelemetryMetrumSensor(bytes);
+                       break;
+               case packet_type_metrum_data:
+                       telem = new AltosTelemetryMetrumData(bytes);
+                       break;
+               default:
+                       telem = new AltosTelemetryRaw(bytes);
+                       break;
+               }
+               return telem;
+       }
+
+       public AltosTelemetryStandard(int[] bytes) {
+               this.bytes = bytes;
+
+               serial = uint16(0);
+               tick   = uint16(2);
+               type   = uint8(4);
+       }
+
+       public void update_state(AltosState state) {
+               super.update_state(state);
+       }
+}
index 59e0ec1..87d4d89 100644 (file)
@@ -10,7 +10,19 @@ SRC=.
 
 altoslibdir = $(datadir)/java
 
+record_files = \
+       AltosEepromRecord.java \
+       AltosEepromTeleScience.java \
+       AltosRecordCompanion.java \
+       AltosRecordIterable.java \
+       AltosRecord.java \
+       AltosRecordNone.java \
+       AltosRecordTM.java \
+       AltosRecordMM.java \
+       AltosRecordMini.java
+
 altoslib_JAVA = \
+       $(record_files) \
        AltosLib.java \
        AltosConfigData.java \
        AltosConfigValues.java \
@@ -25,11 +37,8 @@ altoslib_JAVA = \
        AltosEepromIterable.java \
        AltosEepromLog.java \
        AltosEepromMega.java \
-       AltosEepromMegaIterable.java \
-       AltosEepromRecord.java \
-       AltosEepromTeleScience.java \
+       AltosEepromMetrum2.java \
        AltosEepromMini.java \
-       AltosEepromOldIterable.java \
        AltosFile.java \
        AltosFlash.java \
        AltosFlashListener.java \
@@ -57,13 +66,6 @@ altoslib_JAVA = \
        AltosParse.java \
        AltosPreferences.java \
        AltosPreferencesBackend.java \
-       AltosRecordCompanion.java \
-       AltosRecordIterable.java \
-       AltosRecord.java \
-       AltosRecordNone.java \
-       AltosRecordTM.java \
-       AltosRecordMM.java \
-       AltosRecordMini.java \
        AltosReplayReader.java \
        AltosRomconfig.java \
        AltosSensorMM.java \
@@ -72,11 +74,21 @@ altoslib_JAVA = \
        AltosStateIterable.java \
        AltosStateUpdate.java \
        AltosTelemetry.java \
+       AltosTelemetryConfiguration.java \
        AltosTelemetryFile.java \
        AltosTelemetryIterable.java \
        AltosTelemetryLegacy.java \
+       AltosTelemetryLocation.java \
        AltosTelemetryMap.java \
+       AltosTelemetryMegaSensor.java \
+       AltosTelemetryMegaData.java \
+       AltosTelemetryMetrumSensor.java \
+       AltosTelemetryMetrumData.java \
        AltosTelemetryReader.java \
+       AltosTelemetryRaw.java \
+       AltosTelemetrySensor.java \
+       AltosTelemetrySatellite.java \
+       AltosTelemetryStandard.java \
        AltosUnitsListener.java \
        AltosMs5607.java \
        AltosIMU.java \
index f843503..ceba2d1 100644 (file)
@@ -308,7 +308,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
 
        class Lat extends AscentValue {
                void show (AltosState state, AltosListenerState listener_state) {
-                       if (state.gps != null)
+                       if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING)
                                show(pos(state.gps.lat,"N", "S"));
                        else
                                show("???");
@@ -322,7 +322,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
 
        class Lon extends AscentValue {
                void show (AltosState state, AltosListenerState listener_state) {
-                       if (state.gps != null)
+                       if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING)
                                show(pos(state.gps.lon,"E", "W"));
                        else
                                show("???");
index 2b6575c..35efce1 100644 (file)
@@ -278,7 +278,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
 
        class Lat extends DescentValue {
                void show (AltosState state, AltosListenerState listener_state) {
-                       if (state.gps != null && state.gps.connected)
+                       if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING)
                                show(pos(state.gps.lat,"N", "S"));
                        else
                                show("???");
@@ -292,7 +292,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
 
        class Lon extends DescentValue {
                void show (AltosState state, AltosListenerState listener_state) {
-                       if (state.gps != null && state.gps.connected)
+                       if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING)
                                show(pos(state.gps.lon,"W", "E"));
                        else
                                show("???");
index 70144fb..7a750c8 100644 (file)
@@ -110,7 +110,7 @@ public class AltosDisplayThread extends Thread {
                         */
                        if (state.state >= Altos.ao_flight_drogue &&
                            (last ||
-                            System.currentTimeMillis() - state.report_time >= 15000 ||
+                            System.currentTimeMillis() - state.received_time >= 15000 ||
                             state.state == Altos.ao_flight_landed))
                        {
                                if (Math.abs(state.speed) < 20 && state.height < 100)
index 95b17e2..931b55f 100644 (file)
@@ -33,9 +33,6 @@ public class AltosEepromDownload implements Runnable {
        Thread                  eeprom_thread;
        AltosEepromMonitor      monitor;
 
-       int                     flight;
-       int                     serial;
-       int                     year, month, day;
        boolean                 want_file;
        FileWriter              eeprom_file;
        LinkedList<String>      eeprom_pending;
@@ -44,7 +41,7 @@ public class AltosEepromDownload implements Runnable {
        ActionListener          listener;
        boolean                 success;
        ParseException          parse_exception;
-       String                  extension;
+       AltosState              state;
 
        private void FlushPending() throws IOException {
                for (String s : flights.config_data) {
@@ -59,15 +56,19 @@ public class AltosEepromDownload implements Runnable {
        private void CheckFile(boolean force) throws IOException {
                if (eeprom_file != null)
                        return;
-               if (force || (flight != 0 && want_file)) {
+               if (force || (state.flight != 0 && want_file)) {
                        AltosFile               eeprom_name;
-
-                       if (extension == null)
-                               extension = "data";
-                       if (year != 0 && month != 0 && day != 0)
-                               eeprom_name = new AltosFile(year, month, day, serial, flight, extension);
-                       else
-                               eeprom_name = new AltosFile(serial, flight, extension);
+                       AltosGPS                gps = state.gps;
+
+                       if (gps != null &&
+                           gps.year != AltosRecord.MISSING &&
+                           gps.month != AltosRecord.MISSING &&
+                           gps.day != AltosRecord.MISSING)
+                       {
+                               eeprom_name = new AltosFile(gps.year, gps.month, gps.day,
+                                                           state.serial, state.flight, "eeprom");
+                       } else
+                               eeprom_name = new AltosFile(state.serial, state.flight, "eeprom");
 
                        eeprom_file = new FileWriter(eeprom_name);
                        if (eeprom_file != null) {
@@ -78,270 +79,49 @@ public class AltosEepromDownload implements Runnable {
                }
        }
 
-       void Log(AltosEepromRecord r) throws IOException {
+       boolean                 done;
+       boolean                 start;
+
+       void LogEeprom(AltosEeprom r) throws IOException {
                if (r.cmd != Altos.AO_LOG_INVALID) {
-                       String log_line = String.format("%c %4x %4x %4x\n",
-                                                       r.cmd, r.tick, r.a, r.b);
+                       String line = r.string();
                        if (eeprom_file != null)
-                               eeprom_file.write(log_line);
+                               eeprom_file.write(line);
                        else
-                               eeprom_pending.add(log_line);
+                               eeprom_pending.add(line);
                }
        }
 
-       void set_serial(int in_serial) {
-               serial = in_serial;
-               monitor.set_serial(serial);
-       }
-
-       void set_flight(int in_flight) {
-               flight = in_flight;
-               monitor.set_flight(flight);
-       }
-               
-       boolean                 done;
-       int                     state;
-
-       void CaptureFull(AltosEepromChunk eechunk) throws IOException {
-               boolean any_valid = false;
-
-               extension = "eeprom";
-               set_serial(flights.config_data.serial);
-               for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromRecord.record_length) {
-                       try {
-                               AltosEepromRecord r = new AltosEepromRecord(eechunk, i);
-                               if (r.cmd == Altos.AO_LOG_FLIGHT)
-                                       set_flight(r.b);
-
-                               /* Monitor state transitions to update display */
-                               if (r.cmd == Altos.AO_LOG_STATE && r.a <= Altos.ao_flight_landed) {
-                                       state = r.a;
-                                       if (state > Altos.ao_flight_pad)
-                                               want_file = true;
-                               }
-
-                               if (r.cmd == Altos.AO_LOG_GPS_DATE) {
-                                       year = 2000 + (r.a & 0xff);
-                                       month = (r.a >> 8) & 0xff;
-                                       day = (r.b & 0xff);
-                                       want_file = true;
-                               }
-                               if (r.cmd == Altos.AO_LOG_STATE && r.a == Altos.ao_flight_landed)
-                                       done = true;
-                               if (r.cmd != AltosLib.AO_LOG_INVALID)
-                                       any_valid = true;
-                               Log(r);
-                       } catch (ParseException pe) {
-                               if (parse_exception == null)
-                                       parse_exception = pe;
-                       }
-               }
-
-               if (!any_valid)
-                       done = true;
-
-               CheckFile(false);
-       }
-
-       boolean start;
-       int     tiny_tick;
-
-       void CaptureTiny (AltosEepromChunk eechunk) throws IOException {
+       void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException {
                boolean any_valid = false;
 
-               extension = "eeprom";
-               set_serial(flights.config_data.serial);
-               for (int i = 0; i < eechunk.data.length && !done; i += 2) {
-                       int                     v = eechunk.data16(i);
-                       AltosEepromRecord       r;
-
-                       if (i == 0 && start) {
-                               tiny_tick = 0;
-                               start = false;
-                               set_flight(v);
-                               r = new AltosEepromRecord(Altos.AO_LOG_FLIGHT, tiny_tick, 0, v);
-                               any_valid = true;
-                       } else {
-                               int     s = v ^ 0x8000;
-
-                               if (Altos.ao_flight_startup <= s && s <= Altos.ao_flight_invalid) {
-                                       state = s;
-                                       r = new AltosEepromRecord(Altos.AO_LOG_STATE, tiny_tick, state, 0);
-                                       if (state == Altos.ao_flight_landed)
-                                               done = true;
-                                       state = s;
-                                       any_valid = true;
-                               } else {
-                                       if (v != 0xffff)
-                                               any_valid = true;
-
-                                       r = new AltosEepromRecord(Altos.AO_LOG_PRESSURE, tiny_tick, 0, v);
-
-                                       /*
-                                        * The flight software records ascent data every 100ms, and descent
-                                        * data every 1s.
-                                        */
-                                       if (state < Altos.ao_flight_drogue)
-                                               tiny_tick += 10;
-                                       else
-                                               tiny_tick += 100;
-                               }
-                       }
-                       Log(r);
-               }
-               CheckFile(false);
-               if (!any_valid)
-                       done = true;
-       }
-
-       void LogTeleScience(AltosEepromTeleScience r) throws IOException {
-               if (r.type != Altos.AO_LOG_INVALID) {
-                       String log_line = String.format("%c %4x %4x %d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n",
-                                                       r.type, r.tick, r.tm_tick, r.tm_state,
-                                                       r.data[0], r.data[1], r.data[2], r.data[3], 
-                                                       r.data[4], r.data[5], r.data[6], r.data[7], 
-                                                       r.data[8], r.data[9], r.data[10], r.data[11]);
-                       if (eeprom_file != null)
-                               eeprom_file.write(log_line);
-                       else
-                               eeprom_pending.add(log_line);
-               }
-       }
-       
-       boolean telescience_start;
-
-       void CaptureTeleScience (AltosEepromChunk eechunk) throws IOException {
-               boolean any_valid = false;
-
-               extension = "science";
-               for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromTeleScience.record_length) {
-                       try {
-                               AltosEepromTeleScience r = new AltosEepromTeleScience(eechunk, i);
-                               if (r.type == AltosEepromTeleScience.AO_LOG_TELESCIENCE_START) {
-                                       if (telescience_start) {
-                                               done = true;
-                                               break;
-                                       }
-                                       set_serial(r.data[0]);
-                                       set_flight(r.data[1]);
-                                       telescience_start = true;
-                               } else {
-                                       if (!telescience_start)
-                                               break;
-                               }
-                               state = r.tm_state;
-                               want_file =true;
-                               any_valid = true;
-                               LogTeleScience(r);
-                       } catch (ParseException pe) {
-                               if (parse_exception == null)
-                                       parse_exception = pe;
-                       }
-               }
+               int record_length = 8;
 
-               CheckFile(false);
-               if (!any_valid)
-                       done = true;
-       }
+               state.set_serial(flights.config_data.serial);
 
-       void LogMega(AltosEepromMega r) throws IOException {
-               if (r.cmd != Altos.AO_LOG_INVALID) {
-                       String log_line = String.format("%c %4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n",
-                                                       r.cmd, r.tick,
-                                                       r.data8[0], r.data8[1], r.data8[2], r.data8[3],
-                                                       r.data8[4], r.data8[5], r.data8[6], r.data8[7],
-                                                       r.data8[8], r.data8[9], r.data8[10], r.data8[11],
-                                                       r.data8[12], r.data8[13], r.data8[14], r.data8[15],
-                                                       r.data8[16], r.data8[17], r.data8[18], r.data8[19],
-                                                       r.data8[20], r.data8[21], r.data8[22], r.data8[23],
-                                                       r.data8[24], r.data8[25], r.data8[26], r.data8[27]);
-                       if (eeprom_file != null)
-                               eeprom_file.write(log_line);
-                       else
-                               eeprom_pending.add(log_line);
-               }
-       }
+               for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) {
+                       AltosEeprom r = eechunk.eeprom(i, log_format);
 
-       void CaptureMega(AltosEepromChunk eechunk) throws IOException {
-               boolean any_valid = false;
+                       record_length = r.record_length();
 
-               extension = "mega";
-               set_serial(flights.config_data.serial);
-               for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromMega.record_length) {
-                       try {
-                               AltosEepromMega r = new AltosEepromMega(eechunk, i);
-                               if (r.cmd == Altos.AO_LOG_FLIGHT)
-                                       set_flight(r.data16(0));
-
-                               /* Monitor state transitions to update display */
-                               if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) <= Altos.ao_flight_landed) {
-                                       state = r.data16(0);
-                                       if (state > Altos.ao_flight_pad)
-                                               want_file = true;
-                               }
+                       r.update_state(state);
 
-                               if (r.cmd == Altos.AO_LOG_GPS_TIME) {
-                                       year = 2000 + r.data8(14);
-                                       month = r.data8(15);
-                                       day = r.data8(16);
+                       /* Monitor state transitions to update display */
+                       if (state.state != AltosLib.ao_flight_invalid &&
+                           state.state <= AltosLib.ao_flight_landed)
+                       {
+                               if (state.state > Altos.ao_flight_pad)
                                        want_file = true;
-                               }
-
-                               if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed)
+                               if (state.state == AltosLib.ao_flight_landed)
                                        done = true;
-                               if (r.cmd != AltosLib.AO_LOG_INVALID)
-                                       any_valid = true;
-                               LogMega(r);
-                       } catch (ParseException pe) {
-                               if (parse_exception == null)
-                                       parse_exception = pe;
                        }
-               }
-               if (!any_valid)
-                       done = true;
 
-               CheckFile(false);
-       }
-       
-       void LogMini(AltosEepromMini r) throws IOException {
-               if (r.cmd != Altos.AO_LOG_INVALID) {
-                       String log_line = String.format("%c %4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n",
-                                                       r.cmd, r.tick,
-                                                       r.data8[0], r.data8[1], r.data8[2], r.data8[3],
-                                                       r.data8[4], r.data8[5], r.data8[6], r.data8[7],
-                                                       r.data8[8], r.data8[9], r.data8[10], r.data8[11]);
-                       if (eeprom_file != null)
-                               eeprom_file.write(log_line);
-                       else
-                               eeprom_pending.add(log_line);
-               }
-       }
+                       if (state.gps != null)
+                               want_file = true;
 
-       void CaptureMini(AltosEepromChunk eechunk) throws IOException {
-               boolean any_valid = false;
-
-               extension = "mini";
-               set_serial(flights.config_data.serial);
-               for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromMini.record_length) {
-                       try {
-                               AltosEepromMini r = new AltosEepromMini(eechunk, i);
-                               if (r.cmd == Altos.AO_LOG_FLIGHT)
-                                       set_flight(r.data16(0));
-
-                               /* Monitor state transitions to update display */
-                               if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) <= Altos.ao_flight_landed) {
-                                       state = r.data16(0);
-                                       if (state > Altos.ao_flight_pad)
-                                               want_file = true;
-                               }
-
-                               if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed)
-                                       done = true;
+                       if (r.valid) {
                                any_valid = true;
-                               LogMini(r);
-                       } catch (ParseException pe) {
-                               if (parse_exception == null)
-                                       parse_exception = pe;
+                               LogEeprom(r);
                        }
                }
                if (!any_valid)
@@ -350,15 +130,12 @@ public class AltosEepromDownload implements Runnable {
                CheckFile(false);
        }
        
-       void CaptureTelemetry(AltosEepromChunk eechunk) throws IOException {
-               
-       }
-
        void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException {
                int                     block, state_block = 0;
                int                     log_format = flights.config_data.log_format;
 
-               state = 0;
+               state = new AltosState();
+
                done = false;
                start = true;
 
@@ -366,10 +143,6 @@ public class AltosEepromDownload implements Runnable {
                        throw new IOException("no serial number found");
 
                /* Reset per-capture variables */
-               flight = 0;
-               year = 0;
-               month = 0;
-               day = 0;
                want_file = false;
                eeprom_file = null;
                eeprom_pending = new LinkedList<String>();
@@ -377,9 +150,12 @@ public class AltosEepromDownload implements Runnable {
                /* Set serial number in the monitor dialog window */
                /* Now scan the eeprom, reading blocks of data and converting to .eeprom file form */
 
-               state = 0; state_block = log.start_block;
+               state_block = log.start_block;
                for (block = log.start_block; !done && block < log.end_block; block++) {
-                       monitor.set_value(AltosLib.state_name(state), state, block - state_block, block - log.start_block);
+                       monitor.set_value(state.state_name(),
+                                         state.state,
+                                         block - state_block,
+                                         block - log.start_block);
 
                        AltosEepromChunk        eechunk = new AltosEepromChunk(serial_line, block, block == log.start_block);
 
@@ -397,33 +173,7 @@ public class AltosEepromDownload implements Runnable {
                                }
                        }
 
-                       switch (log_format) {
-                       case AltosLib.AO_LOG_FORMAT_FULL:
-                               extension = "eeprom";
-                               CaptureFull(eechunk);
-                               break;
-                       case AltosLib.AO_LOG_FORMAT_TINY:
-                               extension = "eeprom";
-                               CaptureTiny(eechunk);
-                               break;
-                       case AltosLib.AO_LOG_FORMAT_TELEMETRY:
-                               extension = "telem";
-                               CaptureTelemetry(eechunk);
-                               break;
-                       case AltosLib.AO_LOG_FORMAT_TELESCIENCE:
-                               extension = "science";
-                               CaptureTeleScience(eechunk);
-                               break;
-                       case AltosLib.AO_LOG_FORMAT_TELEMEGA:
-                               extension = "mega";
-                               CaptureMega(eechunk);
-                               break;
-                       case AltosLib.AO_LOG_FORMAT_EASYMINI:
-                       case AltosLib.AO_LOG_FORMAT_TELEMINI:
-                               extension = "eeprom";
-                               CaptureMini(eechunk);
-                               break;
-                       }
+                       CaptureEeprom (eechunk, log_format);
                }
                CheckFile(true);
                if (eeprom_file != null) {
index 0be7bb5..6383e5b 100644 (file)
@@ -126,7 +126,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
 
        class LastPacket extends FlightValue {
                void show(AltosState state, AltosListenerState listener_state) {
-                       long secs = (System.currentTimeMillis() - state.report_time + 500) / 1000;
+                       long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000;
                        value.setText(String.format("%d", secs));
                }
                public LastPacket(GridBagLayout layout, int x) {
index 423cf10..1c450ce 100644 (file)
@@ -102,7 +102,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A
                status_update.saved_state = state;
 
                if (state == null)
-                       state = new AltosState(new AltosRecord());
+                       state = new AltosState();
 
                pad.show(state, listener_state);
 
index bbab017..f6a91de 100644 (file)
@@ -65,13 +65,13 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl
 
        public void show(AltosState state, AltosListenerState listener_state) {
                status_update.saved_state = state;
-               try {
+//             try {
                        pad.show(state, listener_state);
                        flightStatus.show(state, listener_state);
                        flightInfo.show(state, listener_state);
-               } catch (Exception e) {
-                       System.out.print("Show exception" + e);
-               }
+//             } catch (Exception e) {
+//                     System.out.print("Show exception " + e);
+//             }
        }
 
        public void update(final AltosState state, final AltosListenerState listener_state) {
index 8601d76..8906920 100644 (file)
@@ -155,10 +155,14 @@ public class AltosInfoTable extends JTable {
                                else
                                        info_add_row(1, "GPS", "  missing");
                                info_add_row(1, "Satellites", "%6d", state.gps.nsat);
-                               info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S');
-                               info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W');
-                               info_add_row(1, "GPS altitude", "%6d", state.gps.alt);
-                               info_add_row(1, "GPS height", "%6.0f", state.gps_height);
+                               if (state.gps.lat != AltosRecord.MISSING)
+                                       info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S');
+                               if (state.gps.lon != AltosRecord.MISSING)
+                                       info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W');
+                               if (state.gps.alt != AltosRecord.MISSING)
+                                       info_add_row(1, "GPS altitude", "%8.1f", state.gps.alt);
+                               if (state.gps_height != AltosRecord.MISSING)
+                                       info_add_row(1, "GPS height", "%8.1f", state.gps_height);
 
                                /* The SkyTraq GPS doesn't report these values */
                                /*
@@ -195,14 +199,16 @@ public class AltosInfoTable extends JTable {
                                        info_add_deg(1, "Pad longitude", state.pad_lon, 'E', 'W');
                                        info_add_row(1, "Pad GPS alt", "%6.0f m", state.pad_alt);
                                }
-                               info_add_row(1, "GPS date", "%04d-%02d-%02d",
-                                            state.gps.year,
-                                            state.gps.month,
-                                            state.gps.day);
-                               info_add_row(1, "GPS time", "  %02d:%02d:%02d",
-                                            state.gps.hour,
-                                            state.gps.minute,
-                                            state.gps.second);
+                               if (state.gps.year != AltosRecord.MISSING) 
+                                       info_add_row(1, "GPS date", "%04d-%02d-%02d",
+                                                    state.gps.year,
+                                                    state.gps.month,
+                                                    state.gps.day);
+                               if (state.gps.hour != AltosRecord.MISSING)
+                                       info_add_row(1, "GPS time", "  %02d:%02d:%02d",
+                                                    state.gps.hour,
+                                                    state.gps.minute,
+                                                    state.gps.second);
                                //int   nsat_vis = 0;
                                int     c;
 
index 38f273c..4cdaa3d 100644 (file)
@@ -103,7 +103,8 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio
 
        class Lat extends LandedValue {
                void show (AltosState state, AltosListenerState listener_state) {
-                       if (state.gps != null && state.gps.connected)
+                       show();
+                       if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING)
                                show(pos(state.gps.lat,"N", "S"));
                        else
                                show("???");
@@ -118,7 +119,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio
        class Lon extends LandedValue {
                void show (AltosState state, AltosListenerState listener_state) {
                        show();
-                       if (state.gps != null && state.gps.connected)
+                       if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING)
                                show(pos(state.gps.lon,"E", "W"));
                        else
                                show("???");
index fed009c..e9c973d 100644 (file)
@@ -310,17 +310,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
 
        class PadLat extends LaunchValue {
                void show (AltosState state, AltosListenerState listener_state) {
-                       if (state == null || state.gps == null) {
-                               hide();
-                       } else {
-                               if (state.state < AltosLib.ao_flight_pad) {
-                                       show(pos(state.gps.lat,"N", "S"));
-                                       set_label("Latitude");
-                               } else { 
-                                       show(pos(state.pad_lat,"N", "S"));
-                                       set_label("Pad Latitude");
+                       double lat = AltosRecord.MISSING;
+                       String label = null;
+
+                       if (state != null) {
+                               if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lat != AltosRecord.MISSING) {
+                                       lat = state.gps.lat;
+                                       label = "Latitude";
+                               } else {
+                                       lat = state.pad_lat;
+                                       label = "Pad Latitude";
                                }
                        }
+                       if (lat != AltosRecord.MISSING) {
+                               show(pos(lat,"E", "W"));
+                               set_label(label);
+                       } else
+                               hide();
                }
                public PadLat (GridBagLayout layout, int y) {
                        super (layout, y, "Pad Latitude");
@@ -331,17 +337,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
 
        class PadLon extends LaunchValue {
                void show (AltosState state, AltosListenerState listener_state) {
-                       if (state == null || state.gps == null) {
-                               hide();
-                       } else {
-                               if (state.state < AltosLib.ao_flight_pad) {
-                                       show(pos(state.gps.lon,"E", "W"));
-                                       set_label("Longitude");
-                               } else { 
-                                       show(pos(state.pad_lon,"E", "W"));
-                                       set_label("Pad Longitude");
+                       double lon = AltosRecord.MISSING;
+                       String label = null;
+
+                       if (state != null) {
+                               if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lon != AltosRecord.MISSING) {
+                                       lon = state.gps.lon;
+                                       label = "Longitude";
+                               } else {
+                                       lon = state.pad_lon;
+                                       label = "Pad Longitude";
                                }
                        }
+                       if (lon != AltosRecord.MISSING) {
+                               show(pos(lon,"E", "W"));
+                               set_label(label);
+                       } else
+                               hide();
                }
                public PadLon (GridBagLayout layout, int y) {
                        super (layout, y, "Pad Longitude");
@@ -352,21 +364,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
 
        class PadAlt extends LaunchValue {
                void show (AltosState state, AltosListenerState listener_state) {
-                       if (state == null)
-                               hide();
-                       else {
-                               if (state.state < AltosLib.ao_flight_pad && state.gps != null) {
-                                       show("%4.0f m", state.gps.alt);
-                                       set_label("Altitude");
+                       double alt = AltosRecord.MISSING;
+                       String label = null;
+
+                       if (state != null) {
+                               if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.alt != AltosRecord.MISSING) {
+                                       alt = state.gps.alt;
+                                       label = "Altitude";
                                } else {
-                                       if (state.pad_alt == AltosRecord.MISSING)
-                                               hide();
-                                       else {
-                                               show("%4.0f m", state.pad_alt);
-                                               set_label("Pad Altitude");
-                                       }
+                                       alt = state.pad_alt;
+                                       label = "Pad Altitude";
                                }
                        }
+                       if (alt != AltosRecord.MISSING) {
+                               show("%4.0f m", state.gps.alt);
+                               set_label(label);
+                       } else
+                               hide();
                }
                public PadAlt (GridBagLayout layout, int y) {
                        super (layout, y, "Pad Altitude");
index b47df0d..151f68f 100644 (file)
@@ -350,10 +350,10 @@ public class AltosUI extends AltosUIFrame {
                        FileInputStream in;
 
                        in = new FileInputStream(file);
-                       if (file.getName().endsWith("eeprom"))
-                               return new AltosEepromFile(in);
-                       else
+                       if (file.getName().endsWith("telem"))
                                return new AltosTelemetryFile(in);
+                       else
+                               return new AltosEepromFile(in);
                } catch (FileNotFoundException fe) {
                        System.out.printf("%s\n", fe.getMessage());
                        return null;
@@ -434,11 +434,10 @@ public class AltosUI extends AltosUIFrame {
                        System.out.printf("Failed to open file '%s'\n", file);
                        return null;
                }
-               if (file.getName().endsWith("eeprom")) {
-                       return new AltosEepromFile(in);
-               } else {
+               if (file.getName().endsWith("telem"))
                        return new AltosTelemetryFile(in);
-               }
+               else
+                       return new AltosEepromFile(in);
        }
 
        static AltosReplayReader replay_file(File file) {
@@ -521,6 +520,8 @@ public class AltosUI extends AltosUIFrame {
 
                        System.out.printf ("process cat\n");
                        for (AltosState state : eef) {
+                               System.out.printf ("tick %d state %d height %g\n",
+                                                  state.tick, state.state, state.height);
                                if ((state.set & AltosState.set_gps) != 0)
                                        System.out.printf ("time %g lat %g lon %g alt %g\n",
                                                           state.time_since_boost(),
index a2f342d..4b09fae 100644 (file)
@@ -276,7 +276,8 @@ struct ao_log_metrum {
                        uint16_t        flight;         /* 4 */
                        int16_t         ground_accel;   /* 6 */
                        uint32_t        ground_pres;    /* 8 */
-               } flight;       /* 12 */
+                       uint32_t        ground_temp;    /* 12 */
+               } flight;       /* 16 */
                /* AO_LOG_STATE */
                struct {
                        uint16_t        state;          /* 4 */