altoslib: Store saved state in version-independent format
authorKeith Packard <keithp@keithp.com>
Fri, 13 May 2016 06:33:53 +0000 (23:33 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 13 May 2016 06:41:55 +0000 (23:41 -0700)
Use AltosHashSet for AltosState so that AltosDroid doesn't lose
tracker information when the application is upgraded.

Signed-off-by: Keith Packard <keithp@keithp.com>
26 files changed:
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java
altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java
altoslib/AltosAccel.java
altoslib/AltosCompanion.java
altoslib/AltosConfigData.java
altoslib/AltosFrequency.java
altoslib/AltosGPS.java
altoslib/AltosGPSSat.java
altoslib/AltosGreatCircle.java
altoslib/AltosHashSet.java
altoslib/AltosHashable.java [new file with mode: 0644]
altoslib/AltosIMU.java
altoslib/AltosLib.java
altoslib/AltosListenerState.java
altoslib/AltosMag.java
altoslib/AltosMs5607.java
altoslib/AltosParse.java
altoslib/AltosPreferences.java
altoslib/AltosPreferencesBackend.java
altoslib/AltosPyro.java
altoslib/AltosQuaternion.java
altoslib/AltosRotation.java
altoslib/AltosSavedState.java
altoslib/AltosState.java
altoslib/Makefile.am
altosui/AltosLaunch.java

index 385348e..a62bf7f 100644 (file)
@@ -825,9 +825,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                }
        }
 
-       private void disconnectDevice() {
+       private void disconnectDevice(boolean remember) {
                try {
-                       mService.send(Message.obtain(null, TelemetryService.MSG_DISCONNECT, null));
+                       mService.send(Message.obtain(null, TelemetryService.MSG_DISCONNECT, (Boolean) remember));
                } catch (RemoteException e) {
                }
        }
@@ -978,11 +978,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                case R.id.disconnect:
                        /* Disconnect the device
                         */
-                       disconnectDevice();
+                       disconnectDevice(false);
                        return true;
                case R.id.quit:
                        AltosDebug.debug("R.id.quit");
-                       disconnectDevice();
+                       disconnectDevice(true);
                        finish();
                        return true;
                case R.id.setup:
index 6519a11..dc39c89 100644 (file)
@@ -129,7 +129,8 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
                        case MSG_DISCONNECT:
                                AltosDebug.debug("Disconnect command received");
                                s.address = null;
-                               AltosDroidPreferences.set_active_device(null);
+                               if (!(Boolean) msg.obj)
+                                       AltosDroidPreferences.set_active_device(null);
                                s.disconnect(true);
                                break;
                        case MSG_DELETE_SERIAL:
@@ -613,6 +614,8 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
 
                telemetry_state.latest_serial = AltosPreferences.latest_state();
 
+               AltosDebug.debug("latest serial %d\n", telemetry_state.latest_serial);
+
                for (int serial : serials) {
                        AltosState saved_state = AltosPreferences.state(serial);
                        if (saved_state != null) {
@@ -629,6 +632,7 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
                                telemetry_state.states.put(serial, saved_state);
                        } else {
                                AltosDebug.debug("Failed to recover state for %d", serial);
+                               AltosPreferences.remove_state(serial);
                        }
                }
        }
index 00f3aef..c6a2da1 100644 (file)
@@ -19,7 +19,7 @@ package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosAccel extends AltosUnits implements Serializable {
+public class AltosAccel extends AltosUnits {
 
        public double value(double v, boolean imperial_units) {
                if (imperial_units)
index 381b0a2..6f18d93 100644 (file)
@@ -19,7 +19,7 @@ package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosCompanion implements Serializable {
+public class AltosCompanion implements AltosHashable {
        public final static int board_id_telescience = 0x0a;
        public final static int MAX_CHANNELS = 12;
 
@@ -37,4 +37,30 @@ public class AltosCompanion implements Serializable {
                        channels = MAX_CHANNELS;
                companion_data = new int[channels];
        }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet h = new AltosHashSet();
+
+               h.putInt("tick", tick);
+               h.putInt("board_id", board_id);
+               h.putInt("update_period", update_period);
+               h.putInt("channels", channels);
+               h.putIntArray("companion_data", companion_data);
+               return h;
+       }
+
+       public AltosCompanion(AltosHashSet h) {
+               tick = h.getInt("tick", tick);
+               board_id = h.getInt("board_id", board_id);
+               update_period = h.getInt("update_period", update_period);
+               channels = h.getInt("channels", channels);
+               companion_data = h.getIntArray("companion_data", new int[channels]);
+       }
+
+       public static AltosCompanion fromHashSet(AltosHashSet h, AltosCompanion def) {
+               if (h == null)
+                       return def;
+
+               return new AltosCompanion(h);
+       }
 }
index aa46f11..ce430d7 100644 (file)
@@ -204,7 +204,7 @@ public class AltosConfigData implements Iterable<String> {
 
                for (int i = 0; i < parts.length; i++) {
                        try {
-                               r[i] = AltosLib.fromdec(parts[i]);
+                               r[i] = (int) AltosLib.fromdec(parts[i]);
                        } catch (NumberFormatException n) {
                                r[i] = 0;
                        }
index 8899715..f9aa6de 100644 (file)
@@ -21,7 +21,7 @@ import java.io.*;
 import java.util.*;
 import java.text.*;
 
-public class AltosFrequency implements Serializable {
+public class AltosFrequency {
        public double   frequency;
        public String   description;
 
@@ -71,8 +71,14 @@ public class AltosFrequency implements Serializable {
                description = d;
        }
 
-       public AltosFrequency(AltosHashSet h) {
+       private AltosFrequency(AltosHashSet h) {
                frequency = h.getDouble("frequency", 0.0);
                description = h.getString("description", "");
        }
+
+       public static AltosFrequency fromHashSet(AltosHashSet h, AltosFrequency def) {
+               if (h == null)
+                       return def;
+               return new AltosFrequency(h);
+       }
 }
index 6f7c40b..371fd7b 100644 (file)
@@ -21,7 +21,7 @@ import java.text.*;
 import java.util.concurrent.*;
 import java.io.*;
 
-public class AltosGPS implements Cloneable, Serializable {
+public class AltosGPS implements Cloneable, AltosHashable {
 
        public final static int MISSING = AltosLib.MISSING;
 
@@ -388,4 +388,65 @@ public class AltosGPS implements Cloneable, Serializable {
                                break;
                }
        }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet    h = new AltosHashSet();
+
+               h.putInt("nsat", nsat);
+               h.putBoolean("locked", locked);
+               h.putBoolean("connected", connected);
+               h.putDouble("lat", lat);
+               h.putDouble("lon", lon);
+               h.putDouble("alt", alt);
+               h.putInt("year", year);
+               h.putInt("month", month);
+               h.putInt("day", day);
+               h.putInt("hour", hour);
+               h.putInt("minute", minute);
+               h.putInt("second", second);
+
+               h.putDouble("ground_speed", ground_speed);
+               h.putInt("course", course);
+               h.putDouble("climb_rate", climb_rate);
+               h.putDouble("pdop", pdop);
+               h.putDouble("hdop", hdop);
+               h.putDouble("vdop", vdop);
+               h.putDouble("h_error", h_error);
+               h.putDouble("v_error", v_error);
+               h.putString("cc_gps_sat", AltosGPSSat.toString(cc_gps_sat));
+               return h;
+       }
+
+       public AltosGPS(AltosHashSet h) {
+               init();
+               nsat = h.getInt("nsat", nsat);
+               locked = h.getBoolean("locked", locked);
+               connected = h.getBoolean("connected", connected);
+               lat = h.getDouble("lat", lat);
+               lon = h.getDouble("lon", lon);
+               alt = h.getDouble("alt", alt);
+               year = h.getInt("year", year);
+               month = h.getInt("month", month);
+               day = h.getInt("day", day);
+               hour = h.getInt("hour", hour);
+               minute = h.getInt("minute", minute);
+               second = h.getInt("second", second);
+
+               ground_speed = h.getDouble("ground_speed", ground_speed);
+               course = h.getInt("course", course);
+               climb_rate = h.getDouble("climb_rate", climb_rate);
+               pdop = h.getDouble("pdop", pdop);
+               hdop = h.getDouble("hdop", hdop);
+               vdop = h.getDouble("vdop", vdop);
+               h_error = h.getDouble("h_error", h_error);
+               v_error = h.getDouble("v_error", v_error);
+               cc_gps_sat = AltosGPSSat.array(h.getString("cc_gps_sat", null));
+       }
+
+       public static AltosGPS fromHashSet(AltosHashSet h, AltosGPS def) {
+               if (h == null)
+                       return def;
+
+               return new AltosGPS(h);
+       }
 }
index abde1c0..ad7a864 100644 (file)
  */
 
 package org.altusmetrum.altoslib_11;
+
+import java.io.*;
 import java.text.*;
+import java.util.*;
 import java.util.concurrent.*;
-import java.io.*;
 
-public class AltosGPSSat implements Serializable {
+public class AltosGPSSat {
        public int      svid;
        public int      c_n0;
 
@@ -31,5 +33,61 @@ public class AltosGPSSat implements Serializable {
 
        public AltosGPSSat() {
        }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet h = new AltosHashSet();
+               h.putInt("svid", svid);
+               h.putInt("c_n0", c_n0);
+               return h;
+       }
+
+       private AltosGPSSat(AltosHashSet h) {
+               svid = h.getInt("svid", 0);
+               c_n0 = h.getInt("c_n0", 0);
+       }
+
+       static public AltosGPSSat fromHashSet(AltosHashSet h, AltosGPSSat def) {
+               if (h == null)
+                       return def;
+               return new AltosGPSSat(h);
+       }
+
+       static public AltosGPSSat[] array(String string) {
+
+               if (string == null)
+                       return null;
+
+               try {
+                       StringReader            reader = new StringReader(string);
+                       ArrayList<AltosGPSSat>  array = new ArrayList<AltosGPSSat>();
+                       String                  element;
+
+                       while ((element = AltosHashSet.get_token(reader)) != null) {
+                               AltosGPSSat sat = AltosGPSSat.fromHashSet(AltosHashSet.fromString(element), null);
+                               if (sat != null)
+                                       array.add(sat);
+                       }
+                       return array.toArray(new AltosGPSSat[0]);
+               } catch (IOException ie) {
+                       return null;
+               }
+       }
+
+       public static String toString(AltosGPSSat[] sats) {
+               if (sats == null)
+                       return null;
+
+               try {
+                       StringWriter            writer = new StringWriter();
+
+                       for (AltosGPSSat g : sats) {
+                               String          element = g.hashSet().toString();
+                               AltosHashSet.put_token(writer, element);
+                       }
+                       return writer.toString();
+               } catch (IOException ie) {
+                       return null;
+               }
+       }
 }
 
index 03e0567..9ec808a 100644 (file)
@@ -20,7 +20,7 @@ package org.altusmetrum.altoslib_11;
 import java.lang.Math;
 import java.io.*;
 
-public class AltosGreatCircle implements Cloneable, Serializable {
+public class AltosGreatCircle implements Cloneable, AltosHashable {
        public double   distance;
        public double   bearing;
        public double   range;
@@ -103,4 +103,31 @@ public class AltosGreatCircle implements Cloneable, Serializable {
                range = 0;
                elevation = 0;
        }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet h = new AltosHashSet();
+
+               h.putDouble("distance", distance);
+               h.putDouble("bearing", bearing);
+               h.putDouble("range", range);
+               h.putDouble("elevation", elevation);
+
+               return h;
+       }
+
+       public AltosGreatCircle(AltosHashSet h) {
+               this();
+
+               distance = h.getDouble("distance", distance);
+               bearing = h.getDouble("bearing", bearing);
+               range = h.getDouble("range", range);
+               elevation = h.getDouble("elevation", elevation);
+       }
+
+       public static AltosGreatCircle fromHashSet(AltosHashSet h, AltosGreatCircle def) {
+               if (h == null)
+                       return def;
+
+               return new AltosGreatCircle(h);
+       }
 }
index 488d52e..4b89f8c 100644 (file)
@@ -22,13 +22,11 @@ import java.util.*;
 import java.text.*;
 
 public class AltosHashSet extends Hashtable<String,String> {
-       private StringWriter    writer;
-
        static private int get(StringReader reader) throws IOException {
                return reader.read();
        }
 
-       static private String get_token(StringReader reader) throws IOException {
+       static public String get_token(StringReader reader) throws IOException {
                int     c = get(reader);
 
                if (c == -1)
@@ -54,7 +52,7 @@ public class AltosHashSet extends Hashtable<String,String> {
                writer.write(c);
        }
 
-       static private void put_token(StringWriter writer, String token) throws IOException {
+       static public void put_token(StringWriter writer, String token) throws IOException {
                for (int i = 0; i < token.length(); i++) {
                        int c = token.codePointAt(i);
 
@@ -83,6 +81,22 @@ public class AltosHashSet extends Hashtable<String,String> {
                }
        }
 
+       public void putBoolean(String key, boolean value) {
+               put(key, value ? "t" : "f");
+       }
+
+       public boolean getBoolean(String key, boolean def) {
+               String  value = get(key);
+
+               if (value == null)
+                       return def;
+               if (value.equals("t"))
+                       return true;
+               if (value.equals("f"))
+                       return false;
+               return def;
+       }
+
        public void putInt(String key, int value) {
                put(key, Integer.toString(value));
        }
@@ -99,6 +113,59 @@ public class AltosHashSet extends Hashtable<String,String> {
                }
        }
 
+       public void putIntArray(String key, int value[]) {
+               if (value == null)
+                       return;
+
+               StringWriter    writer = new StringWriter();
+
+               try {
+                       for (int i = 0; i < value.length; i++)
+                               put_token(writer, Integer.toString(value[i]));
+                       put(key, writer.toString());
+               } catch (IOException ie) {
+               }
+       }
+
+       public int[] getIntArray(String key, int[] def) {
+               String          value = get(key);
+
+               if (value == null)
+                       return def;
+               try {
+                       StringReader            reader = new StringReader(value);
+                       ArrayList<Integer>      array = new ArrayList<Integer>();
+                       String                  elt;
+
+                       while ((elt = get_token(reader)) != null)
+                               array.add(AltosParse.parse_int(elt));
+                       int[] ret = new int[array.size()];
+                       for (int i = 0; i < ret.length; i++)
+                               ret[i] = array.get(i);
+                       return ret;
+               } catch (ParseException pe) {
+                       return def;
+               } catch (IOException ie) {
+                       return def;
+               }
+       }
+
+       public void putLong(String key, long value) {
+               put(key, Long.toString(value));
+       }
+
+       public long getLong(String key, long def) {
+               String  value = get(key);
+
+               if (value == null)
+                       return def;
+               try {
+                       return AltosParse.parse_long(value);
+               } catch (ParseException pe) {
+                       return def;
+               }
+       }
+
        public void putDouble(String key, double value) {
                put(key, AltosParse.format_double_net(value));
        }
@@ -115,6 +182,43 @@ public class AltosHashSet extends Hashtable<String,String> {
                }
        }
 
+       public void putDoubleArray(String key, double value[]) {
+               if (value == null)
+                       return;
+
+               StringWriter    writer = new StringWriter();
+
+               try {
+                       for (int i = 0; i < value.length; i++)
+                               put_token(writer, AltosParse.format_double_net(value[i]));
+                       put(key, writer.toString());
+               } catch (IOException ie) {
+               }
+       }
+
+       public double[] getDoubleArray(String key, double[] def) {
+               String          value = get(key);
+
+               if (value == null)
+                       return def;
+               try {
+                       StringReader            reader = new StringReader(value);
+                       ArrayList<Double>       array = new ArrayList<Double>();
+                       String                  elt;
+
+                       while ((elt = get_token(reader)) != null)
+                               array.add(AltosParse.parse_double_net(elt));
+                       double[] ret = new double[array.size()];
+                       for (int i = 0; i < ret.length; i++)
+                               ret[i] = array.get(i);
+                       return ret;
+               } catch (ParseException pe) {
+                       return def;
+               } catch (IOException ie) {
+                       return def;
+               }
+       }
+
        public String getString(String key, String def) {
                String  value = get(key);
 
@@ -124,10 +228,34 @@ public class AltosHashSet extends Hashtable<String,String> {
        }
 
        public void putString(String key, String value) {
-               put(key, value);
+               if (value != null)
+                   put(key, value);
        }
 
-       public AltosHashSet (String string) throws IOException {
+       public AltosHashSet getHash(String key) {
+               String  value = get(key);
+
+               if (value == null)
+                       return null;
+               try {
+                       return new AltosHashSet(value);
+               } catch (IOException ie) {
+                       return null;
+               }
+       }
+
+       public void putHash(String key, AltosHashSet h) {
+               put(key, h.toString());
+       }
+
+       public void putHashable(String key, AltosHashable h) {
+               if (h == null)
+                       return;
+
+               put(key, h.hashSet().toString());
+       }
+
+       private AltosHashSet (String string) throws IOException {
                StringReader reader = new StringReader(string);
                String  key, value;
 
@@ -143,31 +271,46 @@ public class AltosHashSet extends Hashtable<String,String> {
        public AltosHashSet() {
        }
 
-       static public AltosHashSet[] array(String string) throws IOException {
+       static public AltosHashSet fromString(String string) {
+               try {
+                       return new AltosHashSet(string);
+               } catch (IOException ie) {
+                       return null;
+               }
+       }
+
+       static public AltosHashSet[] array(String string) {
 
                if (string == null)
                        return null;
 
-               StringReader            reader = new StringReader(string);
-               ArrayList<AltosHashSet> array = new ArrayList<AltosHashSet>();
-               String                  element;
+               try {
+                       StringReader            reader = new StringReader(string);
+                       ArrayList<AltosHashSet> array = new ArrayList<AltosHashSet>();
+                       String                  element;
 
-               while ((element = get_token(reader)) != null)
-                       array.add(new AltosHashSet(element));
-               return array.toArray(new AltosHashSet[0]);
+                       while ((element = get_token(reader)) != null)
+                               array.add(new AltosHashSet(element));
+                       return array.toArray(new AltosHashSet[0]);
+               } catch (IOException ie) {
+                       return null;
+               }
        }
 
-       static public String toString(AltosHashSet[] sets) throws IOException {
-
+       static public String toString(AltosHashSet[] sets) {
                if (sets == null)
                        return null;
 
-               StringWriter            writer = new StringWriter();
+               try {
+                       StringWriter            writer = new StringWriter();
 
-               for (AltosHashSet h : sets) {
-                       String          element = h.toString();
-                       put_token(writer, element);
+                       for (AltosHashSet h : sets) {
+                               String          element = h.toString();
+                               put_token(writer, element);
+                       }
+                       return writer.toString();
+               } catch (IOException ie) {
+                       return null;
                }
-               return writer.toString();
        }
 }
diff --git a/altoslib/AltosHashable.java b/altoslib/AltosHashable.java
new file mode 100644 (file)
index 0000000..e228543
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright © 2016 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_11;
+
+import java.io.*;
+
+public interface AltosHashable {
+
+       public AltosHashSet hashSet();
+}
index 26d1159..df6c4ed 100644 (file)
@@ -20,7 +20,7 @@ package org.altusmetrum.altoslib_11;
 import java.util.concurrent.*;
 import java.io.*;
 
-public class AltosIMU implements Cloneable, Serializable {
+public class AltosIMU implements Cloneable, AltosHashable {
        public int              accel_along;
        public int              accel_across;
        public int              accel_through;
@@ -29,13 +29,13 @@ public class AltosIMU implements Cloneable, Serializable {
        public int              gyro_pitch;
        public int              gyro_yaw;
 
-       public static double    counts_per_g = 2048.0;
+       public static final double      counts_per_g = 2048.0;
 
        public static double convert_accel(double counts) {
                return counts / counts_per_g * (-AltosConvert.GRAVITATIONAL_ACCELERATION);
        }
 
-       public static double    counts_per_degsec = 16.4;
+       public static final double      counts_per_degsec = 16.4;
 
        public static double convert_gyro(double counts) {
                return counts / counts_per_degsec;
@@ -115,4 +115,35 @@ public class AltosIMU implements Cloneable, Serializable {
                                break;
                }
        }
+
+       public AltosIMU (AltosHashSet h) {
+               this();
+
+               accel_along = h.getInt("accel_along", accel_along);
+               accel_across = h.getInt("accel_across", accel_across);
+               accel_through = h.getInt("accel_through", accel_through);
+
+               gyro_roll = h.getInt("gyro_roll", gyro_roll);
+               gyro_pitch = h.getInt("gyro_pitch", gyro_pitch);
+               gyro_yaw = h.getInt("gyro_yaw", gyro_yaw);
+       }
+
+       static public AltosIMU fromHashSet(AltosHashSet h, AltosIMU def) {
+               if (h == null)
+                       return def;
+               return new AltosIMU(h);
+       }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet    h = new AltosHashSet();
+
+               h.putInt("accel_along", accel_along);
+               h.putInt("accel_across", accel_across);
+               h.putInt("accel_through", accel_through);
+
+               h.putInt("gyro_roll", gyro_roll);
+               h.putInt("gyro_pitch", gyro_pitch);
+               h.putInt("gyro_yaw", gyro_yaw);
+               return h;
+       }
 }
index 103052c..044caf8 100644 (file)
@@ -493,9 +493,10 @@ public class AltosLib {
                return r;
        }
 
-       public static int fromdec(String s) throws NumberFormatException {
-               int c, v = 0;
-               int sign = 1;
+       public static long fromdec(String s) throws NumberFormatException {
+               int c;
+               long v = 0;
+               long sign = 1;
                for (int i = 0; i < s.length(); i++) {
                        c = s.charAt(i);
                        if (i == 0 && c == '-') {
index f5d1c0c..7d9ec2a 100644 (file)
@@ -19,7 +19,7 @@ package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosListenerState implements Serializable {
+public class AltosListenerState {
        public int      crc_errors;
        public double   battery;
        public boolean  running;
index 3e82f49..c350ae4 100644 (file)
@@ -20,12 +20,12 @@ package org.altusmetrum.altoslib_11;
 import java.util.concurrent.*;
 import java.io.*;
 
-public class AltosMag implements Cloneable, Serializable {
+public class AltosMag implements Cloneable, AltosHashable {
        public int              along;
        public int              across;
        public int              through;
 
-       public static double counts_per_gauss = 1090;
+       public static final double counts_per_gauss = 1090;
 
        public static double convert_gauss(double counts) {
                return counts / counts_per_gauss;
@@ -93,4 +93,28 @@ public class AltosMag implements Cloneable, Serializable {
                                break;
                }
        }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet    h = new AltosHashSet();
+
+               h.putInt("along", along);
+               h.putInt("across", across);
+               h.putInt("through", through);
+               return h;
+       }
+
+       public AltosMag(AltosHashSet h) {
+               this();
+
+               along = h.getInt("along", along);
+               across = h.getInt("across", across);
+               through = h.getInt("through", through);
+       }
+
+       public static AltosMag fromHashSet(AltosHashSet h, AltosMag def) {
+               if (h == null)
+                       return def;
+
+               return new AltosMag(h);
+       }
 }
index 4f5549a..88a9782 100644 (file)
@@ -20,7 +20,7 @@ package org.altusmetrum.altoslib_11;
 import java.util.concurrent.*;
 import java.io.*;
 
-public class AltosMs5607 implements Serializable {
+public class AltosMs5607 implements AltosHashable {
        public int      reserved;
        public int      sens;
        public int      off;
@@ -166,4 +166,46 @@ public class AltosMs5607 implements Serializable {
                }
                convert();
        }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet h = new AltosHashSet();
+
+               h.putInt("reserved", reserved);
+               h.putInt("sens", sens);
+               h.putInt("off", off);
+               h.putInt("tcs", tcs);
+               h.putInt("tco", tco);
+               h.putInt("tref", tref);
+               h.putInt("tempsens", tempsens);
+               h.putInt("crc", crc);
+               h.putInt("raw_pres", raw_pres);
+               h.putInt("raw_temp", raw_temp);
+               h.putInt("pa", pa);
+               h.putInt("cc", cc);
+               return h;
+       }
+
+       public AltosMs5607(AltosHashSet h) {
+               this();
+
+               reserved = h.getInt("reserved", reserved);
+               sens = h.getInt("sens", sens);
+               off = h.getInt("off", off);
+               tcs = h.getInt("tcs", tcs);
+               tco = h.getInt("tco", tco);
+               tref = h.getInt("tref", tref);
+               tempsens = h.getInt("tempsens", tempsens);
+               crc = h.getInt("crc", crc);
+               raw_pres = h.getInt("raw_pres", raw_pres);
+               raw_temp = h.getInt("raw_temp", raw_temp);
+               pa = h.getInt("pa", pa);
+               cc = h.getInt("cc", cc);
+       }
+
+       public static AltosMs5607 fromHashSet(AltosHashSet h, AltosMs5607 def) {
+               if (h == null)
+                       return def;
+
+               return new AltosMs5607(h);
+       }
 }
index 12499b7..fbd049a 100644 (file)
@@ -26,6 +26,14 @@ public class AltosParse {
        }
 
        public static int parse_int(String v) throws ParseException {
+               try {
+                       return (int) AltosLib.fromdec(v);
+               } catch (NumberFormatException e) {
+                       throw new ParseException("error parsing int " + v, 0);
+               }
+       }
+
+       public static long parse_long(String v) throws ParseException {
                try {
                        return AltosLib.fromdec(v);
                } catch (NumberFormatException e) {
index f8101ce..3f8e7a0 100644 (file)
@@ -136,16 +136,16 @@ public class AltosPreferences {
 
                AltosFrequency[] frequencies = null;
 
-               try {
-                       AltosHashSet[]  sets = AltosHashSet.array(backend.getString(frequenciesPreference,null));
-                       if (sets != null) {
-                               frequencies = new AltosFrequency[sets.length];
-                               for (int i = 0; i < frequencies.length; i++)
-                                       frequencies[i] = new AltosFrequency(sets[i]);
+               AltosHashSet[]  sets = AltosHashSet.array(backend.getString(frequenciesPreference,null));
+               if (sets != null) {
+                       ArrayList<AltosFrequency>       freqs = new ArrayList<AltosFrequency>();
+
+                       for (int i = 0; i < sets.length; i++) {
+                               AltosFrequency f = AltosFrequency.fromHashSet(sets[i], null);
+                               if (f != null)
+                                       freqs.add(f);
                        }
-
-               } catch (IOException ie) {
-                       frequencies = null;
+                       frequencies = freqs.toArray(new AltosFrequency[0]);
                }
 
                if (frequencies == null) {
@@ -153,14 +153,16 @@ public class AltosPreferences {
                                AltosPreferencesBackend node = backend.node(common_frequencies_node_name);
                                int             count = node.getInt(frequency_count, 0);
 
-                               frequencies = new AltosFrequency[count];
-                               for (int i = 0; i < count; i++) {
-                                       double  frequency;
-                                       String  description;
+                               if (count > 0) {
+                                       frequencies = new AltosFrequency[count];
+                                       for (int i = 0; i < count; i++) {
+                                               double  frequency;
+                                               String  description;
 
-                                       frequency = node.getDouble(String.format(frequency_format, i), 0.0);
-                                       description = node.getString(String.format(description_format, i), null);
-                                       frequencies[i] = new AltosFrequency(frequency, description);
+                                               frequency = node.getDouble(String.format(frequency_format, i), 0.0);
+                                               description = node.getString(String.format(description_format, i), null);
+                                               frequencies[i] = new AltosFrequency(frequency, description);
+                                       }
                                }
                        }
                }
@@ -176,13 +178,10 @@ public class AltosPreferences {
        }
 
        public static void save_common_frequencies() {
-               try {
-                       AltosHashSet[]  sets = new AltosHashSet[common_frequencies.length];
-                       for (int i = 0; i < sets.length; i++)
-                               sets[i] = common_frequencies[i].hashSet();
-                       backend.putString(frequenciesPreference, AltosHashSet.toString(sets));
-               } catch (IOException ie) {
-               }
+               AltosHashSet[]  sets = new AltosHashSet[common_frequencies.length];
+               for (int i = 0; i < sets.length; i++)
+                       sets[i] = common_frequencies[i].hashSet();
+               backend.putString(frequenciesPreference, AltosHashSet.toString(sets));
                flush_preferences();
        }
 
@@ -374,7 +373,7 @@ public class AltosPreferences {
        public static void set_state(AltosState state) {
 
                synchronized(backend) {
-                       backend.putSerializable(String.format(statePreferenceFormat, state.serial), state);
+                       backend.putHashSet(String.format(statePreferenceFormat, state.serial), state.hashSet());
                        backend.putInt(statePreferenceLatest, state.serial);
                        flush_preferences();
                }
@@ -399,6 +398,7 @@ public class AltosPreferences {
        public static void remove_state(int serial) {
                synchronized(backend) {
                        backend.remove(String.format(statePreferenceFormat, serial));
+                       flush_preferences();
                }
        }
 
@@ -413,7 +413,7 @@ public class AltosPreferences {
        public static AltosState state(int serial) {
                synchronized(backend) {
                        try {
-                               return (AltosState) backend.getSerializable(String.format(statePreferenceFormat, serial), null);
+                               return AltosState.fromHashSet(backend.getHashSet(String.format(statePreferenceFormat, serial)));
                        } catch (Exception e) {
                                return null;
                        }
index 1f92591..9131ad3 100644 (file)
@@ -38,40 +38,16 @@ public abstract class AltosPreferencesBackend {
        public abstract byte[]  getBytes(String key, byte[] def);
        public abstract void    putBytes(String key, byte[] value);
 
-       public Serializable getSerializable(String key, Serializable def) {
-               byte[] bytes = null;
-
-               bytes = getBytes(key, null);
-               if (bytes == null)
-                       return def;
-
-               ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
-               try {
-                       ObjectInputStream ois = new ObjectInputStream(bais);
-                       Serializable object = (Serializable) ois.readObject();
-                       return object;
-               } catch (IOException ie) {
-                       debug("IO exception %s\n", ie.toString());
-               } catch (ClassNotFoundException ce) {
-                       debug("ClassNotFoundException %s\n", ce.toString());
-               }
-               return def;
-       }
-
-       public void putSerializable(String key, Serializable object) {
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+       public AltosHashSet     getHashSet(String key) {
+               String  value = getString(key, null);
 
-               try {
-                       ObjectOutputStream oos = new ObjectOutputStream(baos);
-
-                       oos.writeObject(object);
-                       byte[] bytes = baos.toByteArray();
+               if (value == null)
+                       return null;
+               return AltosHashSet.fromString(value);
+       }
 
-                       putBytes(key, bytes);
-               } catch (IOException ie) {
-                       debug("set_state failed %s\n", ie.toString());
-               }
+       public void             putHashSet(String key, AltosHashSet h) {
+               putString(key, h.toString());
        }
 
        public abstract boolean nodeExists(String key);
index a1a903f..c948ce2 100644 (file)
@@ -277,7 +277,7 @@ public class AltosPyro {
                                int     value = 0;
                                ++i;
                                try {
-                                       value = AltosLib.fromdec(tokens[i]);
+                                       value = (int) AltosLib.fromdec(tokens[i]);
                                } catch (NumberFormatException n) {
                                        throw new ParseException(String.format("Invalid pyro value \"%s\"",
                                                                               tokens[i]), i);
index 351685f..af9eb47 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.altusmetrum.altoslib_11;
 
-public class AltosQuaternion {
+public class AltosQuaternion implements AltosHashable {
        double  r;              /* real bit */
        double  x, y, z;        /* imaginary bits */
 
@@ -147,4 +147,24 @@ public class AltosQuaternion {
                                           c_x * s_y * c_z + s_x * c_y * s_z,
                                           c_x * c_y * s_z - s_x * s_y * c_z);
        }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet h = new AltosHashSet();
+
+               h.putDouble("r", r);
+               h.putDouble("x", x);
+               h.putDouble("y", y);
+               h.putDouble("z", z);
+               return h;
+       }
+
+       public AltosQuaternion(AltosHashSet h) {
+               if (h == null)
+                       return;
+
+               r = h.getDouble("r", 1);
+               x = h.getDouble("x", 0);
+               y = h.getDouble("y", 0);
+               z = h.getDouble("z", 0);
+       }
 }
index 411ecbd..e9c447a 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.altusmetrum.altoslib_11;
 
-public class AltosRotation {
+public class AltosRotation implements AltosHashable {
        private AltosQuaternion         rotation;
 
        public double tilt() {
@@ -47,4 +47,22 @@ public class AltosRotation {
                AltosQuaternion up = new AltosQuaternion(0, 0, 0, sky);
                rotation = up.vectors_to_rotation(orient);
        }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet h = new AltosHashSet();
+
+               h.putHashable("rotation", rotation);
+               return h;
+       }
+
+       public AltosRotation(AltosHashSet h) {
+               rotation = new AltosQuaternion(h.getHash("rotation"));
+       }
+
+       public static AltosRotation fromHashSet(AltosHashSet h, AltosRotation def) {
+               if (h == null)
+                       return def;
+
+               return new AltosRotation(h);
+       }
 }
index a795404..f1d3e99 100644 (file)
@@ -19,7 +19,7 @@ package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosSavedState implements Serializable {
+public class AltosSavedState {
        public AltosState               state;
        public AltosListenerState       listener_state;
 
index ca28a16..0970a88 100644 (file)
@@ -23,7 +23,7 @@ package org.altusmetrum.altoslib_11;
 
 import java.io.*;
 
-public class AltosState implements Cloneable, Serializable {
+public class AltosState implements Cloneable, AltosHashable {
 
        public static final int set_position = 1;
        public static final int set_gps = 2;
@@ -46,7 +46,7 @@ public class AltosState implements Cloneable, Serializable {
        private int     prev_tick;
        public int      boost_tick;
 
-       class AltosValue implements Serializable{
+       class AltosValue implements AltosHashable {
                double  value;
                double  prev_value;
                private double  max_value;
@@ -177,19 +177,56 @@ public class AltosState implements Cloneable, Serializable {
                        prev_set_time = set_time;
                }
 
+               public AltosHashSet hashSet() {
+                       AltosHashSet h = new AltosHashSet();
+
+                       h.putDouble("value", value);
+                       h.putDouble("prev_value", prev_value);
+                       h.putDouble("max_value", max_value);
+                       h.putDouble("set_time", set_time);
+                       h.putDouble("prev_set_time", prev_set_time);
+                       return h;
+               }
+
+               AltosValue(AltosHashSet h) {
+                       this();
+                       if (h != null) {
+                               value = h.getDouble("value", value);
+                               prev_value = h.getDouble("prev_value", prev_value);
+                               max_value = h.getDouble("max_value", max_value);
+                               set_time = h.getDouble("set_time", 0);
+                               prev_set_time = h.getDouble("prev_set_time", 0);
+                       }
+               }
+
                AltosValue() {
                        value = AltosLib.MISSING;
                        prev_value = AltosLib.MISSING;
                        max_value = AltosLib.MISSING;
                }
+
+       }
+
+       AltosValue AltosValue_fromHashSet(AltosHashSet h, AltosValue def) {
+               if (h == null)
+                       return def;
+               return new AltosValue(h);
        }
 
-       class AltosCValue implements Serializable {
+       class AltosCValue implements AltosHashable {
 
-               class AltosIValue extends AltosValue implements Serializable {
+               class AltosIValue extends AltosValue implements AltosHashable {
                        boolean can_max() {
                                return c_can_max();
                        }
+
+                       AltosIValue() {
+                               super();
+                       }
+
+                       AltosIValue(AltosHashSet h) {
+                               super(h);
+                       }
                };
 
                public AltosIValue      measured;
@@ -282,6 +319,26 @@ public class AltosState implements Cloneable, Serializable {
                        measured = new AltosIValue();
                        computed = new AltosIValue();
                }
+
+
+               public AltosHashSet hashSet() {
+                       AltosHashSet h = new AltosHashSet();
+
+                       h.putHashable("measured", measured);
+                       h.putHashable("computed", computed);
+                       return h;
+               }
+
+               AltosCValue(AltosHashSet h) {
+                       measured = new AltosIValue(h.getHash("measured"));
+                       computed = new AltosIValue(h.getHash("computed"));
+               }
+       }
+
+       AltosCValue AltosCValue_fromHashSet(AltosHashSet h, AltosCValue def) {
+               if (h == null)
+                       return def;
+               return new AltosCValue(h);
        }
 
        private int     state;
@@ -317,7 +374,7 @@ public class AltosState implements Cloneable, Serializable {
                ground_altitude.set_measured(a, time);
        }
 
-       class AltosGpsGroundAltitude extends AltosValue implements Serializable {
+       class AltosGpsGroundAltitude extends AltosValue {
                void set(double a, double t) {
                        super.set(a, t);
                        pad_alt = value();
@@ -329,6 +386,19 @@ public class AltosState implements Cloneable, Serializable {
                        pad_alt = value();
                        gps_altitude.set_gps_height();
                }
+
+               AltosGpsGroundAltitude() {
+                       super();
+               }
+
+               AltosGpsGroundAltitude (AltosHashSet h) {
+                       super(h);
+               }
+       }
+
+       AltosGpsGroundAltitude AltosGpsGroundAltitude_fromHashSet(AltosHashSet h, AltosGpsGroundAltitude def) {
+               if (h == null) return def;
+               return new AltosGpsGroundAltitude(h);
        }
 
        private AltosGpsGroundAltitude gps_ground_altitude;
@@ -341,7 +411,7 @@ public class AltosState implements Cloneable, Serializable {
                gps_ground_altitude.set(a, time);
        }
 
-       class AltosGroundPressure extends AltosCValue implements Serializable {
+       class AltosGroundPressure extends AltosCValue {
                void set_filtered(double p, double time) {
                        computed.set_filtered(p, time);
                        if (!is_measured())
@@ -352,6 +422,19 @@ public class AltosState implements Cloneable, Serializable {
                        super.set_measured(p, time);
                        ground_altitude.set_computed(pressure_to_altitude(p), time);
                }
+
+               AltosGroundPressure () {
+                       super();
+               }
+
+               AltosGroundPressure (AltosHashSet h) {
+                       super(h);
+               }
+       }
+
+       AltosGroundPressure AltosGroundPressure_fromHashSet(AltosHashSet h, AltosGroundPressure def) {
+               if (h == null) return def;
+               return new AltosGroundPressure(h);
        }
 
        private AltosGroundPressure ground_pressure;
@@ -364,7 +447,7 @@ public class AltosState implements Cloneable, Serializable {
                ground_pressure.set_measured(pressure, time);
        }
 
-       class AltosAltitude extends AltosCValue implements Serializable {
+       class AltosAltitude extends AltosCValue implements AltosHashable {
 
                private void set_speed(AltosValue v) {
                        if (!acceleration.is_measured() || !ascent)
@@ -382,11 +465,24 @@ public class AltosState implements Cloneable, Serializable {
                        set_speed(measured);
                        set |= set_position;
                }
+
+               AltosAltitude() {
+                       super();
+               }
+
+               AltosAltitude (AltosHashSet h) {
+                       super(h);
+               }
+       }
+
+       AltosAltitude AltosAltitude_fromHashSet(AltosHashSet h, AltosAltitude def) {
+               if (h == null) return def;
+               return new AltosAltitude(h);
        }
 
        private AltosAltitude   altitude;
 
-       class AltosGpsAltitude extends AltosValue implements Serializable {
+       class AltosGpsAltitude extends AltosValue implements AltosHashable {
 
                private void set_gps_height() {
                        double  a = value();
@@ -402,6 +498,19 @@ public class AltosState implements Cloneable, Serializable {
                        super.set(a, t);
                        set_gps_height();
                }
+
+               AltosGpsAltitude() {
+                       super();
+               }
+
+               AltosGpsAltitude (AltosHashSet h) {
+                       super(h);
+               }
+       }
+
+       AltosGpsAltitude AltosGpsAltitude_fromHashSet(AltosHashSet h, AltosGpsAltitude def) {
+               if (h == null) return def;
+               return new AltosGpsAltitude(h);
        }
 
        private AltosGpsAltitude        gps_altitude;
@@ -469,7 +578,7 @@ public class AltosState implements Cloneable, Serializable {
                return gps_speed.max();
        }
 
-       class AltosPressure extends AltosValue implements Serializable {
+       class AltosPressure extends AltosValue {
                void set(double p, double time) {
                        super.set(p, time);
                        if (state == AltosLib.ao_flight_pad)
@@ -477,6 +586,19 @@ public class AltosState implements Cloneable, Serializable {
                        double a = pressure_to_altitude(p);
                        altitude.set_computed(a, time);
                }
+
+               AltosPressure() {
+                       super();
+               }
+
+               AltosPressure (AltosHashSet h) {
+                       super(h);
+               }
+       }
+
+       AltosPressure AltosPressure_fromHashSet(AltosHashSet h, AltosPressure def) {
+               if (h == null) return def;
+               return new AltosPressure(h);
        }
 
        private AltosPressure   pressure;
@@ -539,7 +661,7 @@ public class AltosState implements Cloneable, Serializable {
                return AltosLib.MISSING;
        }
 
-       class AltosSpeed extends AltosCValue implements Serializable {
+       class AltosSpeed extends AltosCValue implements AltosHashable {
 
                boolean can_max() {
                        return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless;
@@ -563,6 +685,19 @@ public class AltosState implements Cloneable, Serializable {
                        super.set_measured(new_value, time);
                        set_accel();
                }
+
+               AltosSpeed() {
+                       super();
+               }
+
+               AltosSpeed (AltosHashSet h) {
+                       super(h);
+               }
+       }
+
+       AltosSpeed AltosSpeed_fromHashSet(AltosHashSet h, AltosSpeed def) {
+               if (h == null) return def;
+               return new AltosSpeed(h);
        }
 
        private AltosSpeed speed;
@@ -593,7 +728,7 @@ public class AltosState implements Cloneable, Serializable {
                return AltosLib.MISSING;
        }
 
-       class AltosAccel extends AltosCValue implements Serializable {
+       class AltosAccel extends AltosCValue implements AltosHashable {
 
                boolean can_max() {
                        return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless;
@@ -604,6 +739,19 @@ public class AltosState implements Cloneable, Serializable {
                        if (ascent)
                                speed.set_integral(this.measured);
                }
+
+               AltosAccel() {
+                       super();
+               }
+
+               AltosAccel (AltosHashSet h) {
+                       super(h);
+               }
+       }
+
+       AltosAccel AltosAccel_fromHashSet(AltosHashSet h, AltosAccel def) {
+               if (h == null) return def;
+               return new AltosAccel(h);
        }
 
        AltosAccel acceleration;
@@ -1483,10 +1631,238 @@ public class AltosState implements Cloneable, Serializable {
        public AltosState clone() {
                AltosState s = new AltosState();
                s.copy(this);
+
+               AltosHashSet    hash = hashSet();
+               String          onetrip = hash.toString();
+               AltosHashSet    back = AltosHashSet.fromString(onetrip);
+               AltosState      tripstate = AltosState.fromHashSet(back);
+               AltosHashSet    triphash = tripstate.hashSet();
+               String          twotrip = triphash.toString();
+
+               if (!onetrip.equals(twotrip)) {
+                       System.out.printf("%s\n%s\n", onetrip, twotrip);
+                       System.exit(1);
+               }
                return s;
        }
 
        public AltosState () {
                init();
        }
+
+       public AltosHashSet hashSet() {
+               AltosHashSet    h = new AltosHashSet();
+
+               h.putBoolean("valid", true);
+               h.putInt("set", set);
+               h.putLong("received_time", received_time);
+               h.putDouble("time", time);
+               h.putDouble("prev_time", prev_time);
+               h.putDouble("time_change", time_change);
+               h.putInt("tick", tick);
+               h.putInt("prev_tick", prev_tick);
+               h.putInt("boost_tick", boost_tick);
+               h.putInt("state", state);
+               h.putInt("flight", flight);
+               h.putInt("serial", serial);
+               h.putInt("altitude_32", altitude_32);
+               h.putInt("receiver_serial", receiver_serial);
+               h.putBoolean("landed", landed);
+               h.putBoolean("ascent", ascent);
+               h.putBoolean("boost", boost);
+               h.putInt("rssi", rssi);
+               h.putInt("status", status);
+               h.putInt("device_type", device_type);
+               h.putInt("config_major", config_major);
+               h.putInt("config_minor", config_minor);
+               h.putInt("apogee_delay", apogee_delay);
+               h.putInt("main_deploy", main_deploy);
+               h.putInt("flight_log_max", flight_log_max);
+               h.putHashable("ground_altitude", ground_altitude);
+               h.putHashable("gps_ground_altitude", gps_ground_altitude);
+               h.putHashable("ground_pressure", ground_pressure);
+               h.putHashable("altitude", altitude);
+               h.putHashable("gps_altitude", gps_altitude);
+               h.putHashable("gps_ground_speed", gps_ground_speed);
+               h.putHashable("gps_ascent_rate", gps_ascent_rate);
+               h.putHashable("gps_course", gps_course);
+               h.putHashable("gps_speed", gps_speed);
+               h.putHashable("pressure", pressure);
+               h.putHashable("speed", speed);
+               h.putHashable("acceleration", acceleration);
+               h.putHashable("orient", orient);
+               h.putHashable("kalman_height", kalman_height);
+               h.putHashable("kalman_speed", kalman_speed);
+               h.putHashable("kalman_acceleration", kalman_acceleration);
+
+               h.putDouble("battery_voltage",battery_voltage);
+               h.putDouble("pyro_voltage",pyro_voltage);
+               h.putDouble("temperature",temperature);
+               h.putDouble("apogee_voltage",apogee_voltage);
+               h.putDouble("main_voltage",main_voltage);
+               h.putDoubleArray("ignitor_voltage",ignitor_voltage);
+               h.putHashable("gps", gps);
+               h.putHashable("temp_gps", temp_gps);
+               h.putInt("temp_gps_sat_tick", temp_gps_sat_tick);
+               h.putBoolean("gps_pending", gps_pending);
+               h.putInt("gps_sequence", gps_sequence);
+               h.putHashable("imu", imu);
+               h.putHashable("mag", mag);
+
+               h.putInt("npad", npad);
+               h.putInt("gps_waiting", gps_waiting);
+               h.putBoolean("gps_ready", gps_ready);
+               h.putInt("ngps", ngps);
+               h.putHashable("from_pad", from_pad);
+               h.putDouble("elevation", elevation);
+               h.putDouble("range", range);
+               h.putDouble("gps_height", gps_height);
+               h.putDouble("pad_lat", pad_lat);
+               h.putDouble("pad_lon", pad_lon);
+               h.putDouble("pad_alt", pad_alt);
+               h.putInt("speak_tick", speak_tick);
+               h.putDouble("speak_altitude", speak_altitude);
+               h.putString("callsign", callsign);
+               h.putString("firmware_version", firmware_version);
+               h.putDouble("accel_plus_g", accel_plus_g);
+               h.putDouble("accel_minus_g", accel_minus_g);
+               h.putDouble("accel", accel);
+               h.putDouble("ground_accel", ground_accel);
+               h.putDouble("ground_accel_avg", ground_accel_avg);
+               h.putInt("log_format", log_format);
+               h.putString("product", product);
+               h.putHashable("baro", baro);
+               h.putHashable("companion", companion);
+               h.putInt("pyro_fired", pyro_fired);
+               h.putDouble("accel_zero_along", accel_zero_along);
+               h.putDouble("accel_zero_across", accel_zero_across);
+               h.putDouble("accel_zero_through", accel_zero_through);
+
+               h.putHashable("rotation", rotation);
+               h.putHashable("ground_rotation", ground_rotation);
+
+               h.putInt("pad_orientation", pad_orientation);
+
+               h.putDouble("accel_ground_along", accel_ground_along);
+               h.putDouble("accel_ground_across", accel_ground_across);
+               h.putDouble("accel_ground_through", accel_ground_through);
+
+               h.putDouble("gyro_zero_roll", gyro_zero_roll);
+               h.putDouble("gyro_zero_pitch", gyro_zero_pitch);
+               h.putDouble("gyro_zero_yaw", gyro_zero_yaw);
+
+               h.putDouble("last_imu_time", last_imu_time);
+               return h;
+       }
+
+       public AltosState(AltosHashSet h) {
+               this();
+
+               set = h.getInt("set", set);
+               received_time = h.getLong("received_time", received_time);
+               time = h.getDouble("time", time);
+               prev_time = h.getDouble("prev_time", prev_time);
+               time_change = h.getDouble("time_change", time_change);
+               tick = h.getInt("tick", tick);
+               prev_tick = h.getInt("prev_tick", prev_tick);
+               boost_tick = h.getInt("boost_tick", boost_tick);
+               state = h.getInt("state", state);
+               flight = h.getInt("flight", flight);
+               serial = h.getInt("serial", serial);
+               altitude_32 = h.getInt("altitude_32", altitude_32);
+               receiver_serial = h.getInt("receiver_serial", receiver_serial);
+               landed = h.getBoolean("landed", landed);
+               ascent = h.getBoolean("ascent", ascent);
+               boost = h.getBoolean("boost", boost);
+               rssi = h.getInt("rssi", rssi);
+               status = h.getInt("status", status);
+               device_type = h.getInt("device_type", device_type);
+               config_major = h.getInt("config_major", config_major);
+               config_minor = h.getInt("config_minor", config_minor);
+               apogee_delay = h.getInt("apogee_delay", apogee_delay);
+               main_deploy = h.getInt("main_deploy", main_deploy);
+               flight_log_max = h.getInt("flight_log_max", flight_log_max);
+               ground_altitude = AltosCValue_fromHashSet(h.getHash("ground_altitude"), ground_altitude);
+               gps_ground_altitude = AltosGpsGroundAltitude_fromHashSet(h.getHash("gps_ground_altitude"), gps_ground_altitude);
+               ground_pressure = AltosGroundPressure_fromHashSet(h.getHash("ground_pressure"), ground_pressure);
+               altitude = AltosAltitude_fromHashSet(h.getHash("altitude"), altitude);
+               gps_altitude = AltosGpsAltitude_fromHashSet(h.getHash("gps_altitude"), gps_altitude);
+               gps_ground_speed = AltosValue_fromHashSet(h.getHash("gps_ground_speed"), gps_ground_speed);
+               gps_ascent_rate = AltosValue_fromHashSet(h.getHash("gps_ascent_rate"), gps_ascent_rate);
+               gps_course = AltosValue_fromHashSet(h.getHash("gps_course"), gps_course);
+               gps_speed = AltosValue_fromHashSet(h.getHash("gps_speed"), gps_speed);
+               pressure = AltosPressure_fromHashSet(h.getHash("pressure"), pressure);
+               speed = AltosSpeed_fromHashSet(h.getHash("speed"), speed);
+               acceleration = AltosAccel_fromHashSet(h.getHash("acceleration"), acceleration);
+               orient = AltosCValue_fromHashSet(h.getHash("orient"), orient);
+               kalman_height = AltosValue_fromHashSet(h.getHash("kalman_height"), kalman_height);
+               kalman_speed = AltosValue_fromHashSet(h.getHash("kalman_speed"), kalman_speed);
+               kalman_acceleration = AltosValue_fromHashSet(h.getHash("kalman_acceleration"), kalman_acceleration);
+
+               battery_voltage = h.getDouble("battery_voltage", battery_voltage);
+               pyro_voltage = h.getDouble("pyro_voltage", pyro_voltage);
+               temperature = h.getDouble("temperature", temperature);
+               apogee_voltage = h.getDouble("apogee_voltage", apogee_voltage);
+               main_voltage=  h.getDouble("main_voltage", main_voltage);
+               ignitor_voltage = h.getDoubleArray("ignitor_voltage", ignitor_voltage);
+               gps = AltosGPS.fromHashSet(h.getHash("gps"), gps);
+               temp_gps = AltosGPS.fromHashSet(h.getHash("temp_gps"), temp_gps);
+               temp_gps_sat_tick = h.getInt("temp_gps_sat_tick", temp_gps_sat_tick);
+               gps_pending = h.getBoolean("gps_pending", gps_pending);
+               gps_sequence = h.getInt("gps_sequence", gps_sequence);
+               imu = AltosIMU.fromHashSet(h.getHash("imu"), imu);
+               mag = AltosMag.fromHashSet(h.getHash("mag"), mag);
+
+               npad = h.getInt("npad", npad);
+               gps_waiting = h.getInt("gps_waiting", gps_waiting);
+               gps_ready = h.getBoolean("gps_ready", gps_ready);
+               ngps = h.getInt("ngps", ngps);
+               from_pad = AltosGreatCircle.fromHashSet(h.getHash("from_pad"), from_pad);
+               elevation = h.getDouble("elevation", elevation);
+               range = h.getDouble("range", range);
+               gps_height = h.getDouble("gps_height", gps_height);
+               pad_lat = h.getDouble("pad_lat", pad_lat);
+               pad_lon = h.getDouble("pad_lon", pad_lon);
+               pad_alt = h.getDouble("pad_alt", pad_alt);
+               speak_tick = h.getInt("speak_tick", speak_tick);
+               speak_altitude = h.getDouble("speak_altitude", speak_altitude);
+               callsign = h.getString("callsign", callsign);
+               firmware_version = h.getString("firmware_version", firmware_version);
+               accel_plus_g = h.getDouble("accel_plus_g", accel_plus_g);
+               accel_minus_g = h.getDouble("accel_minus_g", accel_minus_g);
+               accel = h.getDouble("accel", accel);
+               ground_accel = h.getDouble("ground_accel", ground_accel);
+               ground_accel_avg = h.getDouble("ground_accel_avg", ground_accel_avg);
+               log_format = h.getInt("log_format", log_format);
+               product = h.getString("product", product);
+               baro = AltosMs5607.fromHashSet(h.getHash("baro"), baro);
+               companion = AltosCompanion.fromHashSet(h.getHash("companion"), companion);
+               pyro_fired = h.getInt("pyro_fired", pyro_fired);
+               accel_zero_along = h.getDouble("accel_zero_along", accel_zero_along);
+               accel_zero_across = h.getDouble("accel_zero_across", accel_zero_across);
+               accel_zero_through = h.getDouble("accel_zero_through", accel_zero_through);
+
+               rotation = AltosRotation.fromHashSet(h.getHash("rotation"), rotation);
+               ground_rotation = AltosRotation.fromHashSet(h.getHash("ground_rotation"), ground_rotation);
+
+               pad_orientation = h.getInt("pad_orientation", pad_orientation);
+
+               accel_ground_along = h.getDouble("accel_ground_along", accel_ground_along);
+               accel_ground_across = h.getDouble("accel_ground_across", accel_ground_across);
+               accel_ground_through = h.getDouble("accel_ground_through", accel_ground_through);
+
+               gyro_zero_roll = h.getDouble("gyro_zero_roll", gyro_zero_roll);
+               gyro_zero_pitch = h.getDouble("gyro_zero_pitch", gyro_zero_pitch);
+               gyro_zero_yaw = h.getDouble("gyro_zero_yaw", gyro_zero_yaw);
+
+               last_imu_time = h.getDouble("last_imu_time", last_imu_time);
+       }
+
+       public static AltosState fromHashSet(AltosHashSet h) {
+               if (h == null)
+                       return null;
+               if (!h.getBoolean("valid", false))
+                       return null;
+               return new AltosState(h);
+       }
 }
index 512e1cc..edc443b 100644 (file)
@@ -161,6 +161,7 @@ altoslib_JAVA = \
        AltosMapLoader.java \
        AltosMapTypeListener.java \
        AltosHashSet.java \
+       AltosHashable.java \
        AltosVersion.java
 
 JAR=altoslib_$(ALTOSLIB_VERSION).jar
index 46a29d4..fb2cd88 100644 (file)
@@ -91,7 +91,7 @@ public class AltosLaunch {
                                throw new TimeoutException();
                        if (get_string(line, "Rssi: ", status_name)) {
                                try {
-                                       rssi = Altos.fromdec(status_name.get());
+                                       rssi = (int) Altos.fromdec(status_name.get());
                                } catch (NumberFormatException ne) {
                                }
                                break;
@@ -194,4 +194,4 @@ public class AltosLaunch {
                device = in_device;
                serial = new AltosSerial(device);
        }
-}
\ No newline at end of file
+}