summaryrefslogtreecommitdiff
path: root/altoslib
diff options
context:
space:
mode:
authorBdale Garbee <bdale@gag.com>2013-05-16 00:36:23 -0600
committerBdale Garbee <bdale@gag.com>2013-05-16 00:36:23 -0600
commit02d111b1b53ef01fc6e9ab6c4bc60b8af1be0067 (patch)
tree8356f4a019969ee99a45e264c87d38555cf316cc /altoslib
parent7a2e1f05adad990a6b161865267abf07ffec7a7e (diff)
parent7699a55aed3a9a7daeb4c6a5a9a280f43edf455f (diff)
Merge branch 'branch-1.2' into debian
Diffstat (limited to 'altoslib')
-rw-r--r--altoslib/.gitignore4
-rw-r--r--altoslib/AltosAccel.java4
-rw-r--r--altoslib/AltosCRCException.java2
-rw-r--r--altoslib/AltosConfigData.java435
-rw-r--r--altoslib/AltosConfigValues.java79
-rw-r--r--altoslib/AltosConvert.java8
-rw-r--r--altoslib/AltosDebug.java280
-rw-r--r--altoslib/AltosDistance.java6
-rw-r--r--altoslib/AltosEepromChunk.java2
-rw-r--r--altoslib/AltosEepromIterable.java14
-rw-r--r--altoslib/AltosEepromLog.java2
-rw-r--r--altoslib/AltosEepromMega.java61
-rw-r--r--altoslib/AltosEepromMegaIterable.java199
-rw-r--r--altoslib/AltosEepromRecord.java2
-rw-r--r--altoslib/AltosEepromTeleScience.java2
-rw-r--r--altoslib/AltosFile.java2
-rw-r--r--altoslib/AltosFlash.java353
-rw-r--r--altoslib/AltosFlashListener.java22
-rw-r--r--altoslib/AltosFlightReader.java6
-rw-r--r--altoslib/AltosFrequency.java2
-rw-r--r--altoslib/AltosGPS.java59
-rw-r--r--altoslib/AltosGPSQuery.java2
-rw-r--r--altoslib/AltosGPSSat.java2
-rw-r--r--altoslib/AltosGreatCircle.java22
-rw-r--r--altoslib/AltosHeight.java4
-rw-r--r--altoslib/AltosHexfile.java300
-rw-r--r--altoslib/AltosIMU.java2
-rw-r--r--altoslib/AltosIMUQuery.java2
-rw-r--r--altoslib/AltosIdleMonitor.java39
-rw-r--r--altoslib/AltosIdleMonitorListener.java4
-rw-r--r--altoslib/AltosIgnite.java2
-rw-r--r--altoslib/AltosLib.java17
-rw-r--r--altoslib/AltosLine.java2
-rw-r--r--altoslib/AltosLink.java70
-rw-r--r--altoslib/AltosListenerState.java28
-rw-r--r--altoslib/AltosLog.java10
-rw-r--r--altoslib/AltosMag.java2
-rw-r--r--altoslib/AltosMs5607.java59
-rw-r--r--altoslib/AltosMs5607Query.java35
-rw-r--r--altoslib/AltosOrderedMegaRecord.java14
-rw-r--r--altoslib/AltosOrderedRecord.java2
-rw-r--r--altoslib/AltosParse.java2
-rw-r--r--altoslib/AltosPreferences.java182
-rw-r--r--altoslib/AltosPreferencesBackend.java45
-rw-r--r--altoslib/AltosPyro.java293
-rw-r--r--altoslib/AltosRecord.java123
-rw-r--r--altoslib/AltosRecordCompanion.java2
-rw-r--r--altoslib/AltosRecordIterable.java2
-rw-r--r--altoslib/AltosRecordMM.java26
-rw-r--r--altoslib/AltosRecordNone.java38
-rw-r--r--altoslib/AltosRecordTM.java31
-rw-r--r--altoslib/AltosReplayReader.java2
-rw-r--r--altoslib/AltosRomconfig.java148
-rw-r--r--altoslib/AltosSensorMM.java124
-rw-r--r--altoslib/AltosSensorTM.java82
-rw-r--r--altoslib/AltosSpeed.java10
-rw-r--r--altoslib/AltosState.java145
-rw-r--r--altoslib/AltosTelemetry.java2
-rw-r--r--altoslib/AltosTelemetryIterable.java2
-rw-r--r--altoslib/AltosTelemetryMap.java2
-rw-r--r--altoslib/AltosTelemetryReader.java10
-rw-r--r--altoslib/AltosTelemetryRecord.java14
-rw-r--r--altoslib/AltosTelemetryRecordCompanion.java6
-rw-r--r--altoslib/AltosTelemetryRecordConfiguration.java6
-rw-r--r--altoslib/AltosTelemetryRecordGeneral.java2
-rw-r--r--altoslib/AltosTelemetryRecordLegacy.java32
-rw-r--r--altoslib/AltosTelemetryRecordLocation.java8
-rw-r--r--altoslib/AltosTelemetryRecordMegaData.java14
-rw-r--r--altoslib/AltosTelemetryRecordMegaSensor.java12
-rw-r--r--altoslib/AltosTelemetryRecordRaw.java12
-rw-r--r--altoslib/AltosTelemetryRecordSatellite.java6
-rw-r--r--altoslib/AltosTelemetryRecordSensor.java18
-rw-r--r--altoslib/AltosTemperature.java43
-rw-r--r--altoslib/AltosUnits.java8
-rw-r--r--altoslib/AltosUnitsListener.java22
-rw-r--r--altoslib/Makefile.am159
76 files changed, 2919 insertions, 876 deletions
diff --git a/altoslib/.gitignore b/altoslib/.gitignore
index a71d076c..ff0fd710 100644
--- a/altoslib/.gitignore
+++ b/altoslib/.gitignore
@@ -1,3 +1,3 @@
bin
-classAltosLib.stamp
-AltosLib.jar
+classaltoslib.stamp
+altoslib*.jar
diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java
index d14764a2..d02b3238 100644
--- a/altoslib/AltosAccel.java
+++ b/altoslib/AltosAccel.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosAccel extends AltosUnits {
@@ -37,7 +37,7 @@ public class AltosAccel extends AltosUnits {
return "meters per second squared";
}
- int show_fraction(int width) {
+ public int show_fraction(int width) {
return width / 9;
}
} \ No newline at end of file
diff --git a/altoslib/AltosCRCException.java b/altoslib/AltosCRCException.java
index 101c5363..76e79add 100644
--- a/altoslib/AltosCRCException.java
+++ b/altoslib/AltosCRCException.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosCRCException extends Exception {
public int rssi;
diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java
index 6f343639..2ca5a7a5 100644
--- a/altoslib/AltosConfigData.java
+++ b/altoslib/AltosConfigData.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.*;
import java.text.*;
@@ -26,30 +26,57 @@ public class AltosConfigData implements Iterable<String> {
/* Version information */
public String manufacturer;
public String product;
- public String version;
- public int log_format;
public int serial;
+ public int flight;
+ public int log_format;
+ public String version;
/* Strings returned */
public LinkedList<String> lines;
/* Config information */
- public int config_major;
- public int config_minor;
+ /* HAS_FLIGHT*/
public int main_deploy;
public int apogee_delay;
- public int radio_channel;
- public int radio_setting;
+ public int apogee_lockout;
+
+ /* HAS_RADIO */
public int radio_frequency;
public String callsign;
- public int accel_cal_plus, accel_cal_minus;
+ public int radio_enable;
public int radio_calibration;
+ /* Old HAS_RADIO values */
+ public int radio_channel;
+ public int radio_setting;
+
+ /* HAS_ACCEL */
+ public int accel_cal_plus, accel_cal_minus;
+ public int pad_orientation;
+
+ /* HAS_LOG */
public int flight_log_max;
+
+ /* HAS_IGNITE */
public int ignite_mode;
- public int stored_flight;
+
+ /* HAS_AES */
+ public String aes_key;
+
+ /* AO_PYRO_NUM */
+ public AltosPyro[] pyros;
+ public int npyro;
+ public int pyro;
+
+ /* HAS_APRS */
+ public int aprs_interval;
+
+ /* Storage info replies */
public int storage_size;
public int storage_erase_unit;
+ /* Log listing replies */
+ public int stored_flight;
+
public static String get_string(String line, String label) throws ParseException {
if (line.startsWith(label)) {
String quoted = line.substring(label.length()).trim();
@@ -83,18 +110,37 @@ public class AltosConfigData implements Iterable<String> {
if (stored_flight == 0)
return 1;
return 0;
+ case AltosLib.AO_LOG_FORMAT_TELEMETRY:
+ case AltosLib.AO_LOG_FORMAT_TELESCIENCE:
+ return 1;
default:
if (flight_log_max <= 0)
return 1;
+ int log_max = flight_log_max * 1024;
int log_space = storage_size - storage_erase_unit;
- int log_used = stored_flight * flight_log_max;
+ int log_used;
+
+ if (stored_flight <= 0)
+ log_used = 0;
+ else
+ log_used = stored_flight * log_max;
+ int log_avail;
if (log_used >= log_space)
- return 0;
- return (log_space - log_used) / flight_log_max;
+ log_avail = 0;
+ else
+ log_avail = (log_space - log_used) / log_max;
+
+ return log_avail;
}
}
+ public boolean has_monitor_battery() {
+ if (product.startsWith("TeleBT"))
+ return true;
+ return false;
+ }
+
int[] parse_version(String v) {
String[] parts = v.split("\\.");
int r[] = new int[parts.length];
@@ -109,7 +155,7 @@ public class AltosConfigData implements Iterable<String> {
return r;
}
-
+
public int compare_version(String other) {
int[] me = parse_version(version);
int[] them = parse_version(other);
@@ -128,55 +174,342 @@ public class AltosConfigData implements Iterable<String> {
return 0;
}
- public AltosConfigData(AltosLink link) throws InterruptedException, TimeoutException {
- link.printf("c s\nf\nl\nv\n");
+ public void reset() {
lines = new LinkedList<String>();
- radio_setting = 0;
- radio_frequency = 0;
+
+ manufacturer = "unknown";
+ product = "unknown";
+ serial = 0;
+ flight = 0;
+ log_format = AltosLib.AO_LOG_FORMAT_UNKNOWN;
+ version = "unknown";
+
+ main_deploy = -1;
+ apogee_delay = -1;
+ apogee_lockout = -1;
+
+ radio_frequency = -1;
+ callsign = null;
+ radio_enable = -1;
+ radio_calibration = -1;
+ radio_channel = -1;
+ radio_setting = -1;
+
+ accel_cal_plus = -1;
+ accel_cal_minus = -1;
+ pad_orientation = -1;
+
+ flight_log_max = -1;
+ ignite_mode = -1;
+
+ aes_key = "";
+
+ pyro = 0;
+ npyro = 0;
+ pyros = null;
+
+ aprs_interval = -1;
+
+ storage_size = -1;
+ storage_erase_unit = -1;
stored_flight = 0;
+ }
+
+ public void parse_line(String line) {
+ lines.add(line);
+ /* Version replies */
+ try { manufacturer = get_string(line, "manufacturer"); } catch (Exception e) {}
+ try { product = get_string(line, "product"); } catch (Exception e) {}
+ try { serial = get_int(line, "serial-number"); } catch (Exception e) {}
+ try { flight = get_int(line, "current-flight"); } catch (Exception e) {}
+ try { log_format = get_int(line, "log-format"); } catch (Exception e) {}
+ try { version = get_string(line, "software-version"); } catch (Exception e) {}
+
+ /* Version also contains MS5607 info, which we ignore here */
+
+ /* Config show replies */
+
+ /* HAS_FLIGHT */
+ try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {}
+ try { apogee_delay = get_int(line, "Apogee delay:"); } catch (Exception e) {}
+ try { apogee_lockout = get_int(line, "Apogee lockout:"); } catch (Exception e) {}
+
+ /* HAS_RADIO */
+ try {
+ radio_frequency = get_int(line, "Frequency:");
+ if (radio_frequency < 0)
+ radio_frequency = 434550;
+ } catch (Exception e) {}
+ try { callsign = get_string(line, "Callsign:"); } catch (Exception e) {}
+ try { radio_enable = get_int(line, "Radio enable:"); } catch (Exception e) {}
+ try { radio_calibration = get_int(line, "Radio cal:"); } catch (Exception e) {}
+
+ /* Old HAS_RADIO values */
+ try { radio_channel = get_int(line, "Radio channel:"); } catch (Exception e) {}
+ try { radio_setting = get_int(line, "Radio setting:"); } catch (Exception e) {}
+
+ /* HAS_ACCEL */
+ try {
+ if (line.startsWith("Accel cal")) {
+ String[] bits = line.split("\\s+");
+ if (bits.length >= 6) {
+ accel_cal_plus = Integer.parseInt(bits[3]);
+ accel_cal_minus = Integer.parseInt(bits[5]);
+ }
+ }
+ } catch (Exception e) {}
+ try { pad_orientation = get_int(line, "Pad orientation:"); } catch (Exception e) {}
+
+ /* HAS_LOG */
+ try { flight_log_max = get_int(line, "Max flight log:"); } catch (Exception e) {}
+
+ /* HAS_IGNITE */
+ try { ignite_mode = get_int(line, "Ignite mode:"); } catch (Exception e) {}
+
+ /* HAS_AES */
+ try { aes_key = get_string(line, "AES key:"); } catch (Exception e) {}
+
+ /* AO_PYRO_NUM */
+ try {
+ npyro = get_int(line, "Pyro-count:");
+ pyros = new AltosPyro[npyro];
+ pyro = 0;
+ } catch (Exception e) {}
+ if (npyro > 0) {
+ try {
+ AltosPyro p = new AltosPyro(pyro, line);
+ if (pyro < npyro)
+ pyros[pyro++] = p;
+ } catch (Exception e) {}
+ }
+
+ /* HAS_APRS */
+ try { aprs_interval = get_int(line, "APRS interval:"); } catch (Exception e) {}
+
+ /* Storage info replies */
+ try { storage_size = get_int(line, "Storage size:"); } catch (Exception e) {}
+ try { storage_erase_unit = get_int(line, "Storage erase unit:"); } catch (Exception e) {}
+
+ /* Log listing replies */
+ try { get_int(line, "flight"); stored_flight++; } catch (Exception e) {}
+ }
+
+ public AltosConfigData() {
+ reset();
+ }
+
+ private void read_link(AltosLink link, String finished) throws InterruptedException, TimeoutException {
for (;;) {
String line = link.get_reply();
if (line == null)
throw new TimeoutException();
if (line.contains("Syntax error"))
continue;
- lines.add(line);
- try { serial = get_int(line, "serial-number"); } catch (Exception e) {}
- try { log_format = get_int(line, "log-format"); } catch (Exception e) {}
- try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {}
- try { apogee_delay = get_int(line, "Apogee delay:"); } catch (Exception e) {}
- try { radio_channel = get_int(line, "Radio channel:"); } catch (Exception e) {}
- try { radio_setting = get_int(line, "Radio setting:"); } catch (Exception e) {}
- try {
- radio_frequency = get_int(line, "Frequency:");
- if (radio_frequency < 0)
- radio_frequency = 434550;
- } catch (Exception e) {}
- try {
- if (line.startsWith("Accel cal")) {
- String[] bits = line.split("\\s+");
- if (bits.length >= 6) {
- accel_cal_plus = Integer.parseInt(bits[3]);
- accel_cal_minus = Integer.parseInt(bits[5]);
- }
- }
- } catch (Exception e) {}
- try { radio_calibration = get_int(line, "Radio cal:"); } catch (Exception e) {}
- try { flight_log_max = get_int(line, "Max flight log:"); } catch (Exception e) {}
- try { ignite_mode = get_int(line, "Ignite mode:"); } catch (Exception e) {}
- try { callsign = get_string(line, "Callsign:"); } catch (Exception e) {}
- try { version = get_string(line,"software-version"); } catch (Exception e) {}
- try { product = get_string(line,"product"); } catch (Exception e) {}
- try { manufacturer = get_string(line,"manufacturer"); } catch (Exception e) {}
-
- try { get_int(line, "flight"); stored_flight++; } catch (Exception e) {}
- try { storage_size = get_int(line, "Storage size:"); } catch (Exception e) {}
- try { storage_erase_unit = get_int(line, "Storage erase unit"); } catch (Exception e) {}
+ this.parse_line(line);
/* signals the end of the version info */
- if (line.startsWith("software-version"))
+ if (line.startsWith(finished))
break;
}
}
-} \ No newline at end of file
+ public boolean has_frequency() {
+ return radio_frequency >= 0 || radio_setting >= 0 || radio_channel >= 0;
+ }
+
+ public void set_frequency(double freq) {
+ int frequency = radio_frequency;
+ int setting = radio_setting;
+
+ if (frequency > 0) {
+ radio_frequency = (int) Math.floor (freq * 1000 + 0.5);
+ radio_channel = -1;
+ } else if (setting > 0) {
+ radio_setting =AltosConvert.radio_frequency_to_setting(freq,
+ radio_calibration);
+ radio_channel = -1;
+ } else {
+ radio_channel = AltosConvert.radio_frequency_to_channel(freq);
+ }
+ }
+
+ public double frequency() {
+ int channel = radio_channel;
+ int setting = radio_setting;
+ if (channel < 0)
+ channel = 0;
+ if (setting < 0)
+ setting = 0;
+
+ return AltosConvert.radio_to_frequency(radio_frequency,
+ setting,
+ radio_calibration,
+ channel);
+ }
+
+ public int log_limit() {
+ if (storage_size > 0 && storage_erase_unit > 0) {
+ int log_limit = storage_size - storage_erase_unit;
+ if (log_limit > 0)
+ return log_limit / 1024;
+ }
+ return 1024;
+ }
+
+ public void get_values(AltosConfigValues source) {
+
+ /* HAS_FLIGHT */
+ if (main_deploy >= 0)
+ main_deploy = source.main_deploy();
+ if (apogee_delay >= 0)
+ apogee_delay = source.apogee_delay();
+ if (apogee_lockout >= 0)
+ apogee_lockout = source.apogee_lockout();
+
+ /* HAS_RADIO */
+ if (has_frequency())
+ set_frequency(source.radio_frequency());
+ if (radio_enable >= 0)
+ radio_enable = source.radio_enable();
+ if (callsign != null)
+ callsign = source.callsign();
+ if (radio_calibration >= 0)
+ radio_calibration = source.radio_calibration();
+
+ /* HAS_ACCEL */
+ if (pad_orientation >= 0)
+ pad_orientation = source.pad_orientation();
+
+ /* HAS_LOG */
+ if (flight_log_max >= 0)
+ flight_log_max = source.flight_log_max();
+
+ /* HAS_IGNITE */
+ if (ignite_mode >= 0)
+ ignite_mode = source.ignite_mode();
+
+ /* AO_PYRO_NUM */
+ if (npyro > 0)
+ pyros = source.pyros();
+
+ if (aprs_interval >= 0)
+ aprs_interval = source.aprs_interval();
+ }
+
+ public void set_values(AltosConfigValues dest) {
+ dest.set_serial(serial);
+ dest.set_product(product);
+ dest.set_version(version);
+ dest.set_main_deploy(main_deploy);
+ dest.set_apogee_delay(apogee_delay);
+ dest.set_apogee_lockout(apogee_lockout);
+ dest.set_radio_calibration(radio_calibration);
+ dest.set_radio_frequency(frequency());
+ boolean max_enabled = true;
+ switch (log_format) {
+ case AltosLib.AO_LOG_FORMAT_TINY:
+ max_enabled = false;
+ break;
+ default:
+ if (stored_flight >= 0)
+ max_enabled = false;
+ break;
+ }
+ dest.set_flight_log_max_enabled(max_enabled);
+ dest.set_radio_enable(radio_enable);
+ dest.set_flight_log_max_limit(log_limit());
+ dest.set_flight_log_max(flight_log_max);
+ dest.set_ignite_mode(ignite_mode);
+ dest.set_pad_orientation(pad_orientation);
+ dest.set_callsign(callsign);
+ if (npyro > 0)
+ dest.set_pyros(pyros);
+ else
+ dest.set_pyros(null);
+ dest.set_aprs_interval(aprs_interval);
+ }
+
+ public void save(AltosLink link, boolean remote) throws InterruptedException, TimeoutException {
+
+ /* HAS_FLIGHT */
+ if (main_deploy >= 0)
+ link.printf("c m %d\n", main_deploy);
+ if (apogee_delay >= 0)
+ link.printf("c d %d\n", apogee_delay);
+ if (apogee_lockout >= 0)
+ link.printf("c L %d\n", apogee_lockout);
+
+ /* Don't mess with radio calibration when remote */
+ if (radio_calibration > 0 && !remote)
+ link.printf("c f %d\n", radio_calibration);
+
+ /* HAS_RADIO */
+ if (has_frequency()) {
+ boolean has_frequency = radio_frequency >= 0;
+ boolean has_setting = radio_setting > 0;
+ double frequency = frequency();
+ link.set_radio_frequency(frequency,
+ has_frequency,
+ has_setting,
+ radio_calibration);
+ /* When remote, reset the dongle frequency at the same time */
+ if (remote) {
+ link.stop_remote();
+ link.set_radio_frequency(frequency);
+ link.start_remote();
+ }
+ }
+
+ if (callsign != null)
+ link.printf("c c %s\n", callsign);
+ if (radio_enable >= 0)
+ link.printf("c e %d\n", radio_enable);
+
+ /* HAS_ACCEL */
+ /* UI doesn't support accel cal */
+ if (pad_orientation >= 0)
+ link.printf("c o %d\n", pad_orientation);
+
+ /* HAS_LOG */
+ if (flight_log_max != 0)
+ link.printf("c l %d\n", flight_log_max);
+
+ /* HAS_IGNITE */
+ if (ignite_mode >= 0)
+ link.printf("c i %d\n", ignite_mode);
+
+ /* HAS_AES */
+ /* UI doesn't support AES key config */
+
+ /* AO_PYRO_NUM */
+ if (npyro > 0) {
+ for (int p = 0; p < pyros.length; p++) {
+ link.printf("c P %s\n",
+ pyros[p].toString());
+ }
+ }
+
+ /* HAS_APRS */
+ if (aprs_interval >= 0)
+ link.printf("c A %d\n", aprs_interval);
+
+ link.printf("c w\n");
+ link.flush_output();
+ }
+
+ public AltosConfigData(AltosLink link) throws InterruptedException, TimeoutException {
+ reset();
+ link.printf("c s\nf\nv\n");
+ read_link(link, "software-version");
+ switch (log_format) {
+ case AltosLib.AO_LOG_FORMAT_FULL:
+ case AltosLib.AO_LOG_FORMAT_TINY:
+ case AltosLib.AO_LOG_FORMAT_TELEMEGA:
+ link.printf("l\n");
+ read_link(link, "done");
+ default:
+ break;
+ }
+ }
+
+}
diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java
new file mode 100644
index 00000000..027d10f4
--- /dev/null
+++ b/altoslib/AltosConfigValues.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2012 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 interface AltosConfigValues {
+ /* set and get all of the dialog values */
+ public abstract void set_product(String product);
+
+ public abstract void set_version(String version);
+
+ public abstract void set_serial(int serial);
+
+ public abstract void set_main_deploy(int new_main_deploy);
+
+ public abstract int main_deploy();
+
+ public abstract void set_apogee_delay(int new_apogee_delay);
+
+ public abstract int apogee_delay();
+
+ public abstract void set_apogee_lockout(int new_apogee_lockout);
+
+ public abstract int apogee_lockout();
+
+ public abstract void set_radio_frequency(double new_radio_frequency);
+
+ public abstract double radio_frequency();
+
+ public abstract void set_radio_calibration(int new_radio_calibration);
+
+ public abstract int radio_calibration();
+
+ public abstract void set_radio_enable(int new_radio_enable);
+
+ public abstract int radio_enable();
+
+ public abstract void set_callsign(String new_callsign);
+
+ public abstract String callsign();
+
+ public abstract void set_flight_log_max(int new_flight_log_max);
+
+ public abstract void set_flight_log_max_enabled(boolean enable);
+
+ public abstract int flight_log_max();
+
+ public abstract void set_flight_log_max_limit(int flight_log_max_limit);
+
+ public abstract void set_ignite_mode(int new_ignite_mode);
+
+ public abstract int ignite_mode();
+
+ public abstract void set_pad_orientation(int new_pad_orientation);
+
+ public abstract int pad_orientation();
+
+ public abstract void set_pyros(AltosPyro[] new_pyros);
+
+ public abstract AltosPyro[] pyros();
+
+ public abstract int aprs_interval();
+
+ public abstract void set_aprs_interval(int new_aprs_interval);
+}
diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java
index acd6c5f4..a42b36c4 100644
--- a/altoslib/AltosConvert.java
+++ b/altoslib/AltosConvert.java
@@ -18,7 +18,7 @@
/*
* Sensor data conversion functions
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosConvert {
/*
@@ -258,6 +258,10 @@ public class AltosConvert {
return meters / 9.80665;
}
+ public static double c_to_f(double c) {
+ return c * 9/5 + 32;
+ }
+
public static boolean imperial_units = false;
public static AltosDistance distance = new AltosDistance();
@@ -268,6 +272,8 @@ public class AltosConvert {
public static AltosAccel accel = new AltosAccel();
+ public static AltosTemperature temperature = new AltosTemperature();
+
public static String show_gs(String format, double a) {
a = meters_to_g(a);
format = format.concat(" g");
diff --git a/altoslib/AltosDebug.java b/altoslib/AltosDebug.java
new file mode 100644
index 00000000..4d8e3ae7
--- /dev/null
+++ b/altoslib/AltosDebug.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright © 2010 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.*;
+
+public class AltosDebug {
+
+ public static final byte WR_CONFIG = 0x1d;
+ public static final byte RD_CONFIG = 0x24;
+ public static final byte CONFIG_TIMERS_OFF = (1 << 3);
+ public static final byte CONFIG_DMA_PAUSE = (1 << 2);
+ public static final byte CONFIG_TIMER_SUSPEND = (1 << 1);
+ public static final byte SET_FLASH_INFO_PAGE = (1 << 0);
+
+ public static final byte GET_PC = 0x28;
+ public static final byte READ_STATUS = 0x34;
+ public static final byte STATUS_CHIP_ERASE_DONE = (byte) (1 << 7);
+ public static final byte STATUS_PCON_IDLE = (1 << 6);
+ public static final byte STATUS_CPU_HALTED = (1 << 5);
+ public static final byte STATUS_POWER_MODE_0 = (1 << 4);
+ public static final byte STATUS_HALT_STATUS = (1 << 3);
+ public static final byte STATUS_DEBUG_LOCKED = (1 << 2);
+ public static final byte STATUS_OSCILLATOR_STABLE = (1 << 1);
+ public static final byte STATUS_STACK_OVERFLOW = (1 << 0);
+
+ public static final byte SET_HW_BRKPNT = 0x3b;
+ public static byte HW_BRKPNT_N(byte n) { return (byte) ((n) << 3); }
+ public static final byte HW_BRKPNT_N_MASK = (0x3 << 3);
+ public static final byte HW_BRKPNT_ENABLE = (1 << 2);
+
+ public static final byte HALT = 0x44;
+ public static final byte RESUME = 0x4c;
+ public static byte DEBUG_INSTR(byte n) { return (byte) (0x54|(n)); }
+ public static final byte STEP_INSTR = 0x5c;
+ public static byte STEP_REPLACE(byte n) { return (byte) (0x64|(n)); }
+ public static final byte GET_CHIP_ID = 0x68;
+
+
+ AltosLink link;
+
+ boolean debug_mode;
+
+ void ensure_debug_mode() {
+ if (!debug_mode) {
+ link.printf("D\n");
+ try {
+ link.flush_input();
+ } catch (InterruptedException ie) {
+ }
+ debug_mode = true;
+ }
+ }
+
+ void dump_memory(String header, int address, byte[] bytes, int start, int len) {
+ System.out.printf("%s\n", header);
+ for (int j = 0; j < len; j++) {
+ if ((j & 15) == 0) {
+ if (j != 0)
+ System.out.printf("\n");
+ System.out.printf ("%04x:", address + j);
+ }
+ System.out.printf(" %02x", bytes[start + j]);
+ }
+ System.out.printf("\n");
+ }
+
+ public void close() {
+ link.close();
+ }
+
+ /*
+ * Write target memory
+ */
+ public void write_memory(int address, byte[] bytes, int start, int len) {
+ ensure_debug_mode();
+// dump_memory("write_memory", address, bytes, start, len);
+ link.printf("O %x %x\n", len, address);
+ for (int i = 0; i < len; i++)
+ link.printf("%02x", bytes[start + i]);
+ }
+
+ public void write_memory(int address, byte[] bytes) {
+ write_memory(address, bytes, 0, bytes.length);
+ }
+
+ /*
+ * Read target memory
+ */
+ public byte[] read_memory(int address, int length)
+ throws IOException, InterruptedException {
+ byte[] data = new byte[length];
+
+ link.flush_input();
+ ensure_debug_mode();
+ link.printf("I %x %x\n", length, address);
+ int i = 0;
+ int start = 0;
+ while (i < length) {
+ String line = link.get_reply().trim();
+ if (!AltosLib.ishex(line) || line.length() % 2 != 0)
+ throw new IOException(
+ String.format
+ ("Invalid reply \"%s\"", line));
+ int this_time = line.length() / 2;
+ for (int j = 0; j < this_time; j++)
+ data[start + j] = (byte) ((AltosLib.fromhex(line.charAt(j*2)) << 4) +
+ AltosLib.fromhex(line.charAt(j*2+1)));
+ start += this_time;
+ i += this_time;
+ }
+// dump_memory("read_memory", address, data, 0, length);
+
+ return data;
+ }
+
+ /*
+ * Write raw bytes to the debug link using the 'P' command
+ */
+ public void write_bytes(byte[] bytes) throws IOException {
+ int i = 0;
+ ensure_debug_mode();
+ while (i < bytes.length) {
+ int this_time = bytes.length - i;
+ if (this_time > 8)
+ this_time = 0;
+ link.printf("P");
+ for (int j = 0; j < this_time; j++)
+ link.printf(" %02x", bytes[i+j]);
+ link.printf("\n");
+ i += this_time;
+ }
+ }
+
+ public void write_byte(byte b) throws IOException {
+ byte[] bytes = { b };
+ write_bytes(bytes);
+ }
+
+ /*
+ * Read raw bytes from the debug link using the 'G' command
+ */
+ public byte[] read_bytes(int length)
+ throws IOException, InterruptedException {
+
+ link.flush_input();
+ ensure_debug_mode();
+ link.printf("G %x\n", length);
+ int i = 0;
+ byte[] data = new byte[length];
+ while (i < length) {
+ String line = link.get_reply();
+
+ if (line == null)
+ throw new IOException("Timeout in read_bytes");
+ line = line.trim();
+ String tokens[] = line.split("\\s+");
+ for (int j = 0; j < tokens.length; j++) {
+ if (!AltosLib.ishex(tokens[j]) ||
+ tokens[j].length() != 2)
+ throw new IOException(
+ String.format
+ ("Invalid read_bytes reply \"%s\"", line));
+ try {
+ if (i + j >= length)
+ throw new IOException(
+ String.format
+ ("Invalid read_bytes reply \"%s\"", line));
+ else
+ data[i + j] = (byte) Integer.parseInt(tokens[j], 16);
+ } catch (NumberFormatException ne) {
+ throw new IOException(
+ String.format
+ ("Invalid read_bytes reply \"%s\"", line));
+ }
+ }
+ i += tokens.length;
+ }
+ return data;
+ }
+
+ public byte read_byte() throws IOException, InterruptedException {
+ return read_bytes(1)[0];
+ }
+
+ public byte debug_instr(byte[] instruction) throws IOException, InterruptedException {
+ byte[] command = new byte[1 + instruction.length];
+ command[0] = DEBUG_INSTR((byte) instruction.length);
+ for (int i = 0; i < instruction.length; i++)
+ command[i+1] = instruction[i];
+ write_bytes(command);
+ return read_byte();
+ }
+
+ public byte resume() throws IOException, InterruptedException {
+ write_byte(RESUME);
+ return read_byte();
+ }
+
+ public int read_uint16() throws IOException, InterruptedException {
+ byte[] d = read_bytes(2);
+ return ((int) (d[0] & 0xff) << 8) | (d[1] & 0xff);
+ }
+
+ public int read_uint8() throws IOException, InterruptedException {
+ byte[] d = read_bytes(1);
+ return (int) (d[0] & 0xff);
+ }
+
+ public int get_chip_id() throws IOException, InterruptedException {
+ write_byte(GET_CHIP_ID);
+ return read_uint16();
+ }
+
+ public int get_pc() throws IOException, InterruptedException {
+ write_byte(GET_PC);
+ return read_uint16();
+ }
+
+ public byte read_status() throws IOException, InterruptedException {
+ write_byte(READ_STATUS);
+ return read_byte();
+ }
+
+ static final byte LJMP = 0x02;
+
+ public void set_pc(int pc) throws IOException, InterruptedException {
+ byte high = (byte) (pc >> 8);
+ byte low = (byte) pc;
+ byte[] jump_mem = { LJMP, high, low };
+ debug_instr(jump_mem);
+ }
+
+ public boolean check_connection() throws IOException, InterruptedException {
+ byte reply = read_status();
+ if ((reply & STATUS_CHIP_ERASE_DONE) == 0)
+ return false;
+ if ((reply & STATUS_PCON_IDLE) != 0)
+ return false;
+ if ((reply & STATUS_POWER_MODE_0) == 0)
+ return false;
+ return true;
+ }
+
+ public AltosRomconfig romconfig() {
+ try {
+ byte[] bytes = read_memory(0xa0, 10);
+ return new AltosRomconfig(bytes, 0);
+ } catch (IOException ie) {
+ } catch (InterruptedException ie) {
+ }
+ return new AltosRomconfig();
+ }
+
+ /*
+ * Reset target
+ */
+ public void reset() {
+ link.printf ("R\n");
+ }
+
+ public AltosDebug (AltosLink link) {
+ this.link = link;
+ }
+} \ No newline at end of file
diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java
index a6026d4a..25028ac7 100644
--- a/altoslib/AltosDistance.java
+++ b/altoslib/AltosDistance.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosDistance extends AltosUnits {
@@ -37,13 +37,13 @@ public class AltosDistance extends AltosUnits {
return "meters";
}
- int show_fraction(int width) {
+ public int show_fraction(int width) {
if (AltosConvert.imperial_units)
return width / 3;
return width / 9;
}
- int say_fraction() {
+ public int say_fraction() {
if (AltosConvert.imperial_units)
return 1;
return 0;
diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java
index 77b22fe2..b1bba3bb 100644
--- a/altoslib/AltosEepromChunk.java
+++ b/altoslib/AltosEepromChunk.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
import java.util.concurrent.*;
diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java
index 986b7a2c..b84574ef 100644
--- a/altoslib/AltosEepromIterable.java
+++ b/altoslib/AltosEepromIterable.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.util.*;
@@ -125,30 +125,40 @@ public class AltosEepromIterable extends AltosRecordIterable {
state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0;
state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >>
AltosLib.AO_GPS_NUM_SAT_SHIFT;
- state.new_gps = true;
+ state.gps_sequence++;
has_gps = true;
break;
case AltosLib.AO_LOG_GPS_LAT:
eeprom.seen |= AltosRecord.seen_gps_lat;
int lat32 = record.a | (record.b << 16);
+ if (state.gps == null)
+ state.gps = new AltosGPS();
state.gps.lat = (double) lat32 / 1e7;
break;
case AltosLib.AO_LOG_GPS_LON:
eeprom.seen |= AltosRecord.seen_gps_lon;
int lon32 = record.a | (record.b << 16);
+ if (state.gps == null)
+ state.gps = new AltosGPS();
state.gps.lon = (double) lon32 / 1e7;
break;
case AltosLib.AO_LOG_GPS_ALT:
+ if (state.gps == null)
+ state.gps = new AltosGPS();
state.gps.alt = record.a;
break;
case AltosLib.AO_LOG_GPS_SAT:
if (state.tick == eeprom.gps_tick) {
int svid = record.a;
int c_n0 = record.b >> 8;
+ if (state.gps == null)
+ state.gps = new AltosGPS();
state.gps.add_sat(svid, c_n0);
}
break;
case AltosLib.AO_LOG_GPS_DATE:
+ if (state.gps == null)
+ state.gps = new AltosGPS();
state.gps.year = (record.a & 0xff) + 2000;
state.gps.month = record.a >> 8;
state.gps.day = record.b & 0xff;
diff --git a/altoslib/AltosEepromLog.java b/altoslib/AltosEepromLog.java
index 211fd706..20026c6d 100644
--- a/altoslib/AltosEepromLog.java
+++ b/altoslib/AltosEepromLog.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
import java.util.concurrent.*;
diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java
index 26bacf8d..b077e26c 100644
--- a/altoslib/AltosEepromMega.java
+++ b/altoslib/AltosEepromMega.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
@@ -24,7 +24,7 @@ public class AltosEepromMega {
public int tick;
public boolean valid;
public String data;
- public int a, b;
+ public int config_a, config_b;
public int data8[];
@@ -66,12 +66,7 @@ public class AltosEepromMega {
public int mag_x() { return data16(20); }
public int mag_y() { return data16(22); }
public int mag_z() { return data16(24); }
- public int accel() {
- int a = data16(26);
- if (a != 0xffff)
- return a;
- return accel_y();
- }
+ public int accel() { return data16(26); }
/* AO_LOG_VOLT elements */
public int v_batt() { return data16(0); }
@@ -79,6 +74,22 @@ public class AltosEepromMega {
public int nsense() { return data16(4); }
public int sense(int i) { return data16(6 + i * 2); }
+ /* AO_LOG_GPS_TIME elements */
+ public int latitude() { return data32(0); }
+ public int longitude() { return data32(4); }
+ public int altitude() { return data16(8); }
+ public int hour() { return data8(10); }
+ public int minute() { return data8(11); }
+ public int second() { return data8(12); }
+ public int flags() { return data8(13); }
+ public int year() { return data8(14); }
+ public int month() { return data8(15); }
+ public int day() { return data8(16); }
+
+ /* AO_LOG_GPS_SAT elements */
+ public int nsat() { return data16(0); }
+ public int svid(int n) { return data8(2 + n * 2); }
+ public int c_n(int n) { return data8(2 + n * 2 + 1); }
public AltosEepromMega (AltosEepromChunk chunk, int start) throws ParseException {
cmd = chunk.data(start);
@@ -126,26 +137,26 @@ public class AltosEepromMega {
data = tokens[2];
} else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) {
cmd = AltosLib.AO_LOG_MAIN_DEPLOY;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) {
cmd = AltosLib.AO_LOG_APOGEE_DELAY;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) {
cmd = AltosLib.AO_LOG_RADIO_CHANNEL;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[0].equals("Callsign:")) {
cmd = AltosLib.AO_LOG_CALLSIGN;
data = tokens[1].replaceAll("\"","");
} else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) {
cmd = AltosLib.AO_LOG_ACCEL_CAL;
- a = Integer.parseInt(tokens[3]);
- b = Integer.parseInt(tokens[5]);
+ config_a = Integer.parseInt(tokens[3]);
+ config_b = Integer.parseInt(tokens[5]);
} else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) {
cmd = AltosLib.AO_LOG_RADIO_CAL;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) {
cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG;
- a = Integer.parseInt(tokens[3]);
+ config_a = Integer.parseInt(tokens[3]);
} else if (tokens[0].equals("manufacturer")) {
cmd = AltosLib.AO_LOG_MANUFACTURER;
data = tokens[1];
@@ -154,38 +165,38 @@ public class AltosEepromMega {
data = tokens[1];
} else if (tokens[0].equals("serial-number")) {
cmd = AltosLib.AO_LOG_SERIAL_NUMBER;
- a = Integer.parseInt(tokens[1]);
+ config_a = Integer.parseInt(tokens[1]);
} else if (tokens[0].equals("log-format")) {
cmd = AltosLib.AO_LOG_LOG_FORMAT;
- a = Integer.parseInt(tokens[1]);
+ config_a = Integer.parseInt(tokens[1]);
} else if (tokens[0].equals("software-version")) {
cmd = AltosLib.AO_LOG_SOFTWARE_VERSION;
data = tokens[1];
} else if (tokens[0].equals("ms5607")) {
if (tokens[1].equals("reserved:")) {
cmd = AltosLib.AO_LOG_BARO_RESERVED;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[1].equals("sens:")) {
cmd = AltosLib.AO_LOG_BARO_SENS;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[1].equals("off:")) {
cmd = AltosLib.AO_LOG_BARO_OFF;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[1].equals("tcs:")) {
cmd = AltosLib.AO_LOG_BARO_TCS;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[1].equals("tco:")) {
cmd = AltosLib.AO_LOG_BARO_TCO;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[1].equals("tref:")) {
cmd = AltosLib.AO_LOG_BARO_TREF;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[1].equals("tempsens:")) {
cmd = AltosLib.AO_LOG_BARO_TEMPSENS;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else if (tokens[1].equals("crc:")) {
cmd = AltosLib.AO_LOG_BARO_CRC;
- a = Integer.parseInt(tokens[2]);
+ config_a = Integer.parseInt(tokens[2]);
} else {
cmd = AltosLib.AO_LOG_INVALID;
data = line;
diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java
index 1ab2fcc8..5736f937 100644
--- a/altoslib/AltosEepromMegaIterable.java
+++ b/altoslib/AltosEepromMegaIterable.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.util.*;
@@ -106,80 +106,47 @@ public class AltosEepromMegaIterable extends AltosRecordIterable {
eeprom.sensor_tick = record.tick;
has_accel = true;
break;
- case AltosLib.AO_LOG_PRESSURE:
- state.pres = record.b;
- state.flight_pres = state.pres;
- if (eeprom.n_pad_samples == 0) {
- eeprom.n_pad_samples++;
- state.ground_pres = state.pres;
- }
- eeprom.seen |= seen_sensor;
- break;
case AltosLib.AO_LOG_TEMP_VOLT:
state.v_batt = record.v_batt();
state.v_pyro = record.v_pbatt();
- for (int i = 0; i < AltosRecordMM.num_sense; i++)
+ for (int i = 0; i < record.nsense(); i++)
state.sense[i] = record.sense(i);
eeprom.seen |= seen_temp_volt;
break;
-//
-// case AltosLib.AO_LOG_DEPLOY:
-// state.drogue = record.a;
-// state.main = record.b;
-// eeprom.seen |= seen_deploy;
-// has_ignite = true;
-// break;
-
case AltosLib.AO_LOG_STATE:
state.state = record.state();
break;
case AltosLib.AO_LOG_GPS_TIME:
eeprom.gps_tick = state.tick;
- AltosGPS old = state.gps;
state.gps = new AltosGPS();
- /* GPS date doesn't get repeated through the file */
- if (old != null) {
- state.gps.year = old.year;
- state.gps.month = old.month;
- state.gps.day = old.day;
- }
- state.gps.hour = (record.a & 0xff);
- state.gps.minute = (record.a >> 8);
- state.gps.second = (record.b & 0xff);
+ state.gps.lat = record.latitude() / 1e7;
+ state.gps.lon = record.longitude() / 1e7;
+ state.gps.alt = record.altitude();
+ state.gps.year = record.year() + 2000;
+ state.gps.month = record.month();
+ state.gps.day = record.day();
+
+ state.gps.hour = record.hour();
+ state.gps.minute = record.minute();
+ state.gps.second = record.second();
- int flags = (record.b >> 8);
+ int flags = record.flags();
state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0;
state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0;
state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >>
AltosLib.AO_GPS_NUM_SAT_SHIFT;
- state.new_gps = true;
+ state.gps_sequence++;
has_gps = true;
- break;
- case AltosLib.AO_LOG_GPS_LAT:
- int lat32 = record.a | (record.b << 16);
- state.gps.lat = (double) lat32 / 1e7;
- break;
- case AltosLib.AO_LOG_GPS_LON:
- int lon32 = record.a | (record.b << 16);
- state.gps.lon = (double) lon32 / 1e7;
- break;
- case AltosLib.AO_LOG_GPS_ALT:
- state.gps.alt = record.a;
+ eeprom.seen |= seen_gps_time | seen_gps_lat | seen_gps_lon;
break;
case AltosLib.AO_LOG_GPS_SAT:
if (state.tick == eeprom.gps_tick) {
- int svid = record.a;
- int c_n0 = record.b >> 8;
- state.gps.add_sat(svid, c_n0);
+ int nsat = record.nsat();
+ for (int i = 0; i < nsat; i++)
+ state.gps.add_sat(record.svid(i), record.c_n(i));
}
break;
- case AltosLib.AO_LOG_GPS_DATE:
- state.gps.year = (record.a & 0xff) + 2000;
- state.gps.month = record.a >> 8;
- state.gps.day = record.b & 0xff;
- break;
-
case AltosLib.AO_LOG_CONFIG_VERSION:
break;
case AltosLib.AO_LOG_MAIN_DEPLOY:
@@ -192,8 +159,8 @@ public class AltosEepromMegaIterable extends AltosRecordIterable {
state.callsign = record.data;
break;
case AltosLib.AO_LOG_ACCEL_CAL:
- state.accel_plus_g = record.a;
- state.accel_minus_g = record.b;
+ state.accel_plus_g = record.config_a;
+ state.accel_minus_g = record.config_b;
break;
case AltosLib.AO_LOG_RADIO_CAL:
break;
@@ -202,33 +169,33 @@ public class AltosEepromMegaIterable extends AltosRecordIterable {
case AltosLib.AO_LOG_PRODUCT:
break;
case AltosLib.AO_LOG_SERIAL_NUMBER:
- state.serial = record.a;
+ state.serial = record.config_a;
break;
case AltosLib.AO_LOG_SOFTWARE_VERSION:
break;
case AltosLib.AO_LOG_BARO_RESERVED:
- baro.reserved = record.a;
+ baro.reserved = record.config_a;
break;
case AltosLib.AO_LOG_BARO_SENS:
- baro.sens =record.a;
+ baro.sens =record.config_a;
break;
case AltosLib.AO_LOG_BARO_OFF:
- baro.off =record.a;
+ baro.off =record.config_a;
break;
case AltosLib.AO_LOG_BARO_TCS:
- baro.tcs =record.a;
+ baro.tcs =record.config_a;
break;
case AltosLib.AO_LOG_BARO_TCO:
- baro.tco =record.a;
+ baro.tco =record.config_a;
break;
case AltosLib.AO_LOG_BARO_TREF:
- baro.tref =record.a;
+ baro.tref =record.config_a;
break;
case AltosLib.AO_LOG_BARO_TEMPSENS:
- baro.tempsens =record.a;
+ baro.tempsens =record.config_a;
break;
case AltosLib.AO_LOG_BARO_CRC:
- baro.crc =record.a;
+ baro.crc =record.config_a;
break;
}
state.seen |= eeprom.seen;
@@ -287,25 +254,25 @@ public class AltosEepromMegaIterable extends AltosRecordIterable {
out.printf("# Config version: %s\n", record.data);
break;
case AltosLib.AO_LOG_MAIN_DEPLOY:
- out.printf("# Main deploy: %s\n", record.a);
+ out.printf("# Main deploy: %s\n", record.config_a);
break;
case AltosLib.AO_LOG_APOGEE_DELAY:
- out.printf("# Apogee delay: %s\n", record.a);
+ out.printf("# Apogee delay: %s\n", record.config_a);
break;
case AltosLib.AO_LOG_RADIO_CHANNEL:
- out.printf("# Radio channel: %s\n", record.a);
+ out.printf("# Radio channel: %s\n", record.config_a);
break;
case AltosLib.AO_LOG_CALLSIGN:
out.printf("# Callsign: %s\n", record.data);
break;
case AltosLib.AO_LOG_ACCEL_CAL:
- out.printf ("# Accel cal: %d %d\n", record.a, record.b);
+ out.printf ("# Accel cal: %d %d\n", record.config_a, record.config_b);
break;
case AltosLib.AO_LOG_RADIO_CAL:
- out.printf ("# Radio cal: %d\n", record.a);
+ out.printf ("# Radio cal: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_MAX_FLIGHT_LOG:
- out.printf ("# Max flight log: %d\n", record.a);
+ out.printf ("# Max flight log: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_MANUFACTURER:
out.printf ("# Manufacturer: %s\n", record.data);
@@ -314,74 +281,40 @@ public class AltosEepromMegaIterable extends AltosRecordIterable {
out.printf ("# Product: %s\n", record.data);
break;
case AltosLib.AO_LOG_SERIAL_NUMBER:
- out.printf ("# Serial number: %d\n", record.a);
+ out.printf ("# Serial number: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_SOFTWARE_VERSION:
out.printf ("# Software version: %s\n", record.data);
break;
case AltosLib.AO_LOG_BARO_RESERVED:
- out.printf ("# Baro reserved: %d\n", record.a);
+ out.printf ("# Baro reserved: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_BARO_SENS:
- out.printf ("# Baro sens: %d\n", record.a);
+ out.printf ("# Baro sens: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_BARO_OFF:
- out.printf ("# Baro off: %d\n", record.a);
+ out.printf ("# Baro off: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_BARO_TCS:
- out.printf ("# Baro tcs: %d\n", record.a);
+ out.printf ("# Baro tcs: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_BARO_TCO:
- out.printf ("# Baro tco: %d\n", record.a);
+ out.printf ("# Baro tco: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_BARO_TREF:
- out.printf ("# Baro tref: %d\n", record.a);
+ out.printf ("# Baro tref: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_BARO_TEMPSENS:
- out.printf ("# Baro tempsens: %d\n", record.a);
+ out.printf ("# Baro tempsens: %d\n", record.config_a);
break;
case AltosLib.AO_LOG_BARO_CRC:
- out.printf ("# Baro crc: %d\n", record.a);
+ out.printf ("# Baro crc: %d\n", record.config_a);
break;
}
}
}
/*
- * Given an AO_LOG_GPS_TIME record with correct time, and one
- * missing time, rewrite the missing time values with the good
- * ones, assuming that the difference between them is 'diff' seconds
- */
- void update_time(AltosOrderedMegaRecord good, AltosOrderedMegaRecord bad) {
-
- int diff = (bad.tick - good.tick + 50) / 100;
-
- int hour = (good.a & 0xff);
- int minute = (good.a >> 8);
- int second = (good.b & 0xff);
- int flags = (good.b >> 8);
- int seconds = hour * 3600 + minute * 60 + second;
-
- /* Make sure this looks like a good GPS value */
- if ((flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT < 4)
- flags = (flags & ~AltosLib.AO_GPS_NUM_SAT_MASK) | (4 << AltosLib.AO_GPS_NUM_SAT_SHIFT);
- flags |= AltosLib.AO_GPS_RUNNING;
- flags |= AltosLib.AO_GPS_VALID;
-
- int new_seconds = seconds + diff;
- if (new_seconds < 0)
- new_seconds += 24 * 3600;
- int new_second = (new_seconds % 60);
- int new_minutes = (new_seconds / 60);
- int new_minute = (new_minutes % 60);
- int new_hours = (new_minutes / 60);
- int new_hour = (new_hours % 24);
-
- bad.a = new_hour + (new_minute << 8);
- bad.b = new_second + (flags << 8);
- }
-
- /*
* Read the whole file, dumping records into a RB tree so
* we can enumerate them in time order -- the eeprom data
* are sometimes out of order with GPS data getting timestamps
@@ -416,53 +349,11 @@ public class AltosEepromMegaIterable extends AltosRecordIterable {
continue;
}
- /* Two firmware bugs caused the loss of some GPS data.
- * The flight date would never be recorded, and often
- * the flight time would get overwritten by another
- * record. Detect the loss of the GPS date and fix up the
- * missing time records
- */
- if (record.cmd == AltosLib.AO_LOG_GPS_DATE) {
- gps_date_record = record;
- continue;
- }
-
- /* go back and fix up any missing time values */
- if (record.cmd == AltosLib.AO_LOG_GPS_TIME) {
- last_gps_time = record;
- if (missing_time) {
- Iterator<AltosOrderedMegaRecord> iterator = records.iterator();
- while (iterator.hasNext()) {
- AltosOrderedMegaRecord old = iterator.next();
- if (old.cmd == AltosLib.AO_LOG_GPS_TIME &&
- old.a == -1 && old.b == -1)
- {
- update_time(record, old);
- }
- }
- missing_time = false;
- }
- }
-
- if (record.cmd == AltosLib.AO_LOG_GPS_LAT) {
- if (last_gps_time == null || last_gps_time.tick != record.tick) {
- AltosOrderedMegaRecord add_gps_time = new AltosOrderedMegaRecord(AltosLib.AO_LOG_GPS_TIME,
- record.tick,
- -1, -1, index-1);
- if (last_gps_time != null)
- update_time(last_gps_time, add_gps_time);
- else
- missing_time = true;
-
- records.add(add_gps_time);
- record.index = index++;
- }
- }
records.add(record);
/* Bail after reading the 'landed' record; we're all done */
if (record.cmd == AltosLib.AO_LOG_STATE &&
- record.a == AltosLib.ao_flight_landed)
+ record.state() == AltosLib.ao_flight_landed)
break;
}
} catch (IOException io) {
diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java
index c7ced6a3..70ac1113 100644
--- a/altoslib/AltosEepromRecord.java
+++ b/altoslib/AltosEepromRecord.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
diff --git a/altoslib/AltosEepromTeleScience.java b/altoslib/AltosEepromTeleScience.java
index 02ce4553..2a828cf3 100644
--- a/altoslib/AltosEepromTeleScience.java
+++ b/altoslib/AltosEepromTeleScience.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java
index 1ab00b38..90dbc6db 100644
--- a/altoslib/AltosFile.java
+++ b/altoslib/AltosFile.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.File;
import java.util.*;
diff --git a/altoslib/AltosFlash.java b/altoslib/AltosFlash.java
new file mode 100644
index 00000000..010274b9
--- /dev/null
+++ b/altoslib/AltosFlash.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright © 2010 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.*;
+
+public class AltosFlash {
+ File file;
+ FileInputStream input;
+ AltosHexfile image;
+ AltosLink link;
+ AltosDebug debug;
+ AltosRomconfig rom_config;
+ boolean aborted;
+ AltosFlashListener listener;
+
+ static final byte MOV_direct_data = (byte) 0x75;
+ static final byte MOV_DPTR_data16 = (byte) 0x90;
+ static final byte MOV_A_data = (byte) 0x74;
+ static final byte MOVX_atDPTR_A = (byte) 0xf0;
+ static final byte MOVX_A_atDPTR = (byte) 0xe0;
+ static final byte INC_DPTR = (byte) 0xa3;
+ static final byte TRAP = (byte) 0xa5;
+
+ static final byte JB = (byte) 0x20;
+
+ static final byte MOV_A_direct = (byte) 0xe5;
+ static final byte MOV_direct1_direct2 = (byte) 0x85;
+ static final byte MOV_direct_A = (byte) 0xf5;
+ static final byte MOV_R0_data = (byte) (0x78 | 0);
+ static final byte MOV_R1_data = (byte) (0x78 | 1);
+ static final byte MOV_R2_data = (byte) (0x78 | 2);
+ static final byte MOV_R3_data = (byte) (0x78 | 3);
+ static final byte MOV_R4_data = (byte) (0x78 | 4);
+ static final byte MOV_R5_data = (byte) (0x78 | 5);
+ static final byte MOV_R6_data = (byte) (0x78 | 6);
+ static final byte MOV_R7_data = (byte) (0x78 | 7);
+ static final byte DJNZ_R0_rel = (byte) (0xd8 | 0);
+ static final byte DJNZ_R1_rel = (byte) (0xd8 | 1);
+ static final byte DJNZ_R2_rel = (byte) (0xd8 | 2);
+ static final byte DJNZ_R3_rel = (byte) (0xd8 | 3);
+ static final byte DJNZ_R4_rel = (byte) (0xd8 | 4);
+ static final byte DJNZ_R5_rel = (byte) (0xd8 | 5);
+ static final byte DJNZ_R6_rel = (byte) (0xd8 | 6);
+ static final byte DJNZ_R7_rel = (byte) (0xd8 | 7);
+
+ static final byte P1DIR = (byte) 0xFE;
+ static final byte P1 = (byte) 0x90;
+
+ /* flash controller */
+ static final byte FWT = (byte) 0xAB;
+ static final byte FADDRL = (byte) 0xAC;
+ static final byte FADDRH = (byte) 0xAD;
+ static final byte FCTL = (byte) 0xAE;
+ static final byte FCTL_BUSY = (byte) 0x80;
+ static final byte FCTL_BUSY_BIT = (byte) 7;
+ static final byte FCTL_SWBSY = (byte) 0x40;
+ static final byte FCTL_SWBSY_BIT = (byte) 6;
+ static final byte FCTL_CONTRD = (byte) 0x10;
+ static final byte FCTL_WRITE = (byte) 0x02;
+ static final byte FCTL_ERASE = (byte) 0x01;
+ static final byte FWDATA = (byte) 0xAF;
+
+ static final byte ACC = (byte) 0xE0;
+
+ /* offsets within the flash_page program */
+ static final int FLASH_ADDR_HIGH = 8;
+ static final int FLASH_ADDR_LOW = 11;
+ static final int RAM_ADDR_HIGH = 13;
+ static final int RAM_ADDR_LOW = 14;
+ static final int FLASH_WORDS_HIGH = 16;
+ static final int FLASH_WORDS_LOW = 18;
+ static final int FLASH_TIMING = 21;
+
+ /* sleep mode control */
+ static final int SLEEP = (byte) 0xbe;
+ static final int SLEEP_USB_EN = (byte) 0x80;
+ static final int SLEEP_XOSC_STB = (byte) 0x40;
+ static final int SLEEP_HFRC_STB = (byte) 0x20;
+ static final int SLEEP_RST_MASK = (byte) 0x18;
+ static final int SLEEP_RST_POWERON = (byte) 0x00;
+ static final int SLEEP_RST_EXTERNAL = (byte) 0x10;
+ static final int SLEEP_RST_WATCHDOG = (byte) 0x08;
+ static final int SLEEP_OSC_PD = (byte) 0x04;
+ static final int SLEEP_MODE_MASK = (byte) 0x03;
+ static final int SLEEP_MODE_PM0 = (byte) 0x00;
+ static final int SLEEP_MODE_PM1 = (byte) 0x01;
+ static final int SLEEP_MODE_PM2 = (byte) 0x02;
+ static final int SLEEP_MODE_PM3 = (byte) 0x03;
+
+ /* clock controller */
+ static final byte CLKCON = (byte) 0xC6;
+ static final byte CLKCON_OSC32K = (byte) 0x80;
+ static final byte CLKCON_OSC = (byte) 0x40;
+ static final byte CLKCON_TICKSPD = (byte) 0x38;
+ static final byte CLKCON_CLKSPD = (byte) 0x07;
+
+ static final byte[] flash_page_proto = {
+
+ MOV_direct_data, P1DIR, (byte) 0x02,
+ MOV_direct_data, P1, (byte) 0xFF,
+
+ MOV_direct_data, FADDRH, 0, /* FLASH_ADDR_HIGH */
+
+ MOV_direct_data, FADDRL, 0, /* FLASH_ADDR_LOW */
+
+ MOV_DPTR_data16, 0, 0, /* RAM_ADDR_HIGH, RAM_ADDR_LOW */
+
+ MOV_R7_data, 0, /* FLASH_WORDS_HIGH */
+
+ MOV_R6_data, 0, /* FLASH_WORDS_LOW */
+
+
+ MOV_direct_data, FWT, 0x20, /* FLASH_TIMING */
+
+ MOV_direct_data, FCTL, FCTL_ERASE,
+/* eraseWaitLoop: */
+ MOV_A_direct, FCTL,
+ JB, ACC|FCTL_BUSY_BIT, (byte) 0xfb,
+
+ MOV_direct_data, P1, (byte) 0xfd,
+
+ MOV_direct_data, FCTL, FCTL_WRITE,
+/* writeLoop: */
+ MOV_R5_data, 2,
+/* writeWordLoop: */
+ MOVX_A_atDPTR,
+ INC_DPTR,
+ MOV_direct_A, FWDATA,
+ DJNZ_R5_rel, (byte) 0xfa, /* writeWordLoop */
+/* writeWaitLoop: */
+ MOV_A_direct, FCTL,
+ JB, ACC|FCTL_SWBSY_BIT, (byte) 0xfb, /* writeWaitLoop */
+ DJNZ_R6_rel, (byte) 0xf1, /* writeLoop */
+ DJNZ_R7_rel, (byte) 0xef, /* writeLoop */
+
+ MOV_direct_data, P1DIR, (byte) 0x00,
+ MOV_direct_data, P1, (byte) 0xFF,
+ TRAP,
+ };
+
+ public byte[] make_flash_page(int flash_addr, int ram_addr, int byte_count) {
+ int flash_word_addr = flash_addr >> 1;
+ int flash_word_count = ((byte_count + 1) >> 1);
+
+ byte[] flash_page = new byte[flash_page_proto.length];
+ for (int i = 0; i < flash_page.length; i++)
+ flash_page[i] = flash_page_proto[i];
+
+ flash_page[FLASH_ADDR_HIGH] = (byte) (flash_word_addr >> 8);
+ flash_page[FLASH_ADDR_LOW] = (byte) (flash_word_addr);
+ flash_page[RAM_ADDR_HIGH] = (byte) (ram_addr >> 8);
+ flash_page[RAM_ADDR_LOW] = (byte) (ram_addr);
+
+ byte flash_words_low = (byte) (flash_word_count);
+ byte flash_words_high = (byte) (flash_word_count >> 8);
+ /* the flashing code has a minor 'bug' */
+ if (flash_words_low != 0)
+ flash_words_high++;
+
+ flash_page[FLASH_WORDS_HIGH] = (byte) flash_words_high;
+ flash_page[FLASH_WORDS_LOW] = (byte) flash_words_low;
+ return flash_page;
+ }
+
+ static byte[] set_clkcon_fast = {
+ MOV_direct_data, CLKCON, 0x00
+ };
+
+ static byte[] get_sleep = {
+ MOV_A_direct, SLEEP
+ };
+
+ public void clock_init() throws IOException, InterruptedException {
+ if (debug != null) {
+ debug.debug_instr(set_clkcon_fast);
+
+ byte status;
+ for (int times = 0; times < 20; times++) {
+ Thread.sleep(1);
+ status = debug.debug_instr(get_sleep);
+ if ((status & SLEEP_XOSC_STB) != 0)
+ return;
+ }
+ throw new IOException("Failed to initialize target clock");
+ }
+ }
+
+ void action(String s, int percent) {
+ if (listener != null && !aborted)
+ listener.position(s, percent);
+ }
+
+ void action(int part, int total) {
+ int percent = 100 * part / total;
+ action(String.format("%d/%d (%d%%)",
+ part, total, percent),
+ percent);
+ }
+
+ void altos_run(int pc) throws IOException, InterruptedException {
+ debug.set_pc(pc);
+ int set_pc = debug.get_pc();
+ if (pc != set_pc)
+ throw new IOException("Failed to set target program counter");
+ debug.resume();
+
+ for (int times = 0; times < 20; times++) {
+ byte status = debug.read_status();
+ if ((status & AltosDebug.STATUS_CPU_HALTED) != 0)
+ return;
+ }
+
+ throw new IOException("Failed to execute program on target");
+ }
+
+ public void flash() {
+ try {
+ if (!check_rom_config())
+ throw new IOException("Invalid rom config settings");
+ if (image.address + image.data.length > 0x8000)
+ throw new IOException(String.format("Flash image too long %d",
+ image.address +
+ image.data.length));
+ if ((image.address & 0x3ff) != 0)
+ throw new IOException(String.format("Flash image must start on page boundary (is 0x%x)",
+ image.address));
+ int ram_address = 0xf000;
+ int flash_prog = 0xf400;
+
+ /*
+ * Store desired config values into image
+ */
+ rom_config.write(image);
+ /*
+ * Bring up the clock
+ */
+ clock_init();
+
+ int remain = image.data.length;
+ int flash_addr = image.address;
+ int image_start = 0;
+
+ action("start", 0);
+ action(0, image.data.length);
+ while (remain > 0 && !aborted) {
+ int this_time = remain;
+ if (this_time > 0x400)
+ this_time = 0x400;
+
+ if (debug != null) {
+ /* write the data */
+ debug.write_memory(ram_address, image.data,
+ image_start, this_time);
+
+ /* write the flash program */
+ byte[] flash_page = make_flash_page(flash_addr,
+ ram_address,
+ this_time);
+ debug.write_memory(flash_prog, flash_page);
+
+ altos_run(flash_prog);
+ byte[] check = debug.read_memory(flash_addr, this_time);
+ for (int i = 0; i < this_time; i++)
+ if (check[i] != image.data[image_start + i])
+ throw new IOException(String.format("Flash write failed at 0x%x (%02x != %02x)",
+ image.address + image_start + i,
+ check[i], image.data[image_start + i]));
+ } else {
+ Thread.sleep(100);
+ }
+
+ remain -= this_time;
+ flash_addr += this_time;
+ image_start += this_time;
+
+ action(image.data.length - remain, image.data.length);
+ }
+ if (!aborted) {
+ action("done", 100);
+ if (debug != null) {
+ debug.set_pc(image.address);
+ debug.resume();
+ }
+ }
+ if (debug != null)
+ debug.close();
+ } catch (IOException ie) {
+ action(ie.getMessage(), -1);
+ abort();
+ } catch (InterruptedException ie) {
+ abort();
+ }
+ }
+
+ public void close() {
+ if (debug != null)
+ debug.close();
+ }
+
+ synchronized public void abort() {
+ aborted = true;
+ close();
+ }
+
+ public boolean check_rom_config() {
+ if (debug == null)
+ return true;
+ if (rom_config == null)
+ rom_config = debug.romconfig();
+ return rom_config != null && rom_config.valid();
+ }
+
+ public void set_romconfig (AltosRomconfig romconfig) {
+ rom_config = romconfig;
+ }
+
+ public AltosRomconfig romconfig() {
+ if (!check_rom_config())
+ return null;
+ return rom_config;
+ }
+
+ public AltosFlash(File file, AltosLink link, AltosFlashListener listener)
+ throws IOException, FileNotFoundException, InterruptedException {
+ this.file = file;
+ this.link = link;
+ this.listener = listener;
+ if (link != null)
+ debug = new AltosDebug(link);
+ input = new FileInputStream(file);
+ image = new AltosHexfile(input);
+ if (debug != null && !debug.check_connection()) {
+ debug.close();
+ throw new IOException("Debug port not connected");
+ }
+ }
+} \ No newline at end of file
diff --git a/altoslib/AltosFlashListener.java b/altoslib/AltosFlashListener.java
new file mode 100644
index 00000000..ab50b74a
--- /dev/null
+++ b/altoslib/AltosFlashListener.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright © 2013 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 interface AltosFlashListener {
+ public void position(String label, int percent);
+}
diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java
index cbd64153..34526658 100644
--- a/altoslib/AltosFlightReader.java
+++ b/altoslib/AltosFlightReader.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
import java.io.*;
@@ -45,4 +45,8 @@ public class AltosFlightReader {
public boolean supports_telemetry(int telemetry) { return false; }
public File backing_file() { return null; }
+
+ public boolean has_monitor_battery() { return false; }
+
+ public double monitor_battery() { return AltosRecord.MISSING; }
}
diff --git a/altoslib/AltosFrequency.java b/altoslib/AltosFrequency.java
index e20f03b7..484a2fd9 100644
--- a/altoslib/AltosFrequency.java
+++ b/altoslib/AltosFrequency.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosFrequency {
public double frequency;
diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java
index ea0949ec..f23842f3 100644
--- a/altoslib/AltosGPS.java
+++ b/altoslib/AltosGPS.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
@@ -217,33 +217,38 @@ public class AltosGPS {
}
public AltosGPS(AltosGPS old) {
- nsat = old.nsat;
- locked = old.locked;
- connected = old.connected;
- lat = old.lat; /* degrees (+N -S) */
- lon = old.lon; /* degrees (+E -W) */
- alt = old.alt; /* m */
- year = old.year;
- month = old.month;
- day = old.day;
- hour = old.hour;
- minute = old.minute;
- second = old.second;
-
- ground_speed = old.ground_speed; /* m/s */
- course = old.course; /* degrees */
- climb_rate = old.climb_rate; /* m/s */
- hdop = old.hdop; /* unitless? */
- h_error = old.h_error; /* m */
- v_error = old.v_error; /* m */
-
- if (old.cc_gps_sat != null) {
- cc_gps_sat = new AltosGPSSat[old.cc_gps_sat.length];
- for (int i = 0; i < old.cc_gps_sat.length; i++) {
- cc_gps_sat[i] = new AltosGPSSat();
- cc_gps_sat[i].svid = old.cc_gps_sat[i].svid;
- cc_gps_sat[i].c_n0 = old.cc_gps_sat[i].c_n0;
+ if (old != null) {
+ nsat = old.nsat;
+ locked = old.locked;
+ connected = old.connected;
+ lat = old.lat; /* degrees (+N -S) */
+ lon = old.lon; /* degrees (+E -W) */
+ alt = old.alt; /* m */
+ year = old.year;
+ month = old.month;
+ day = old.day;
+ hour = old.hour;
+ minute = old.minute;
+ second = old.second;
+
+ ground_speed = old.ground_speed; /* m/s */
+ course = old.course; /* degrees */
+ climb_rate = old.climb_rate; /* m/s */
+ hdop = old.hdop; /* unitless? */
+ h_error = old.h_error; /* m */
+ v_error = old.v_error; /* m */
+
+ if (old.cc_gps_sat != null) {
+ cc_gps_sat = new AltosGPSSat[old.cc_gps_sat.length];
+ for (int i = 0; i < old.cc_gps_sat.length; i++) {
+ cc_gps_sat[i] = new AltosGPSSat();
+ cc_gps_sat[i].svid = old.cc_gps_sat[i].svid;
+ cc_gps_sat[i].c_n0 = old.cc_gps_sat[i].c_n0;
+ }
}
+ } else {
+ ClearGPSTime();
+ cc_gps_sat = null;
}
}
}
diff --git a/altoslib/AltosGPSQuery.java b/altoslib/AltosGPSQuery.java
index e93af259..deb9d201 100644
--- a/altoslib/AltosGPSQuery.java
+++ b/altoslib/AltosGPSQuery.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.*;
diff --git a/altoslib/AltosGPSSat.java b/altoslib/AltosGPSSat.java
index faa1ec8d..8714dd8a 100644
--- a/altoslib/AltosGPSSat.java
+++ b/altoslib/AltosGPSSat.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosGPSSat {
public int svid;
diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java
index 76b71859..f1cf0ae9 100644
--- a/altoslib/AltosGreatCircle.java
+++ b/altoslib/AltosGreatCircle.java
@@ -15,13 +15,15 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.lang.Math;
public class AltosGreatCircle {
public double distance;
public double bearing;
+ public double range;
+ public double elevation;
double sqr(double a) { return a * a; }
@@ -54,9 +56,8 @@ public class AltosGreatCircle {
return bearing_string[length][(int)((bearing / 90 * 8 + 1) / 2)%16];
}
- public AltosGreatCircle (double start_lat, double start_lon,
- double end_lat, double end_lon)
- {
+ public AltosGreatCircle (double start_lat, double start_lon, double start_alt,
+ double end_lat, double end_lon, double end_alt) {
double lat1 = rad * start_lat;
double lon1 = rad * -start_lon;
double lat2 = rad * end_lat;
@@ -88,14 +89,25 @@ public class AltosGreatCircle {
}
distance = d * earth_radius;
bearing = course * 180/Math.PI;
+
+ double height_diff = end_alt - start_alt;
+ range = Math.sqrt(distance * distance + height_diff * height_diff);
+ elevation = Math.atan2(height_diff, distance) * 180 / Math.PI;
+ }
+
+ public AltosGreatCircle (double start_lat, double start_lon,
+ double end_lat, double end_lon) {
+ this(start_lat, start_lon, 0, end_lat, end_lon, 0);
}
public AltosGreatCircle(AltosGPS start, AltosGPS end) {
- this(start.lat, start.lon, end.lat, end.lon);
+ this(start.lat, start.lon, start.alt, end.lat, end.lon, end.alt);
}
public AltosGreatCircle() {
distance = 0;
bearing = 0;
+ range = 0;
+ elevation = 0;
}
}
diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java
index da7ffdae..ed590812 100644
--- a/altoslib/AltosHeight.java
+++ b/altoslib/AltosHeight.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosHeight extends AltosUnits {
@@ -37,7 +37,7 @@ public class AltosHeight extends AltosUnits {
return "meters";
}
- int show_fraction(int width) {
+ public int show_fraction(int width) {
return width / 9;
}
} \ No newline at end of file
diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java
new file mode 100644
index 00000000..2140228a
--- /dev/null
+++ b/altoslib/AltosHexfile.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright © 2010 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.LinkedList;
+import java.util.Arrays;
+
+class HexFileInputStream extends PushbackInputStream {
+ public int line;
+
+ public HexFileInputStream(FileInputStream o) {
+ super(new BufferedInputStream(o));
+ line = 1;
+ }
+
+ public int read() throws IOException {
+ int c = super.read();
+ if (c == '\n')
+ line++;
+ return c;
+ }
+
+ public void unread(int c) throws IOException {
+ if (c == '\n')
+ line--;
+ if (c != -1)
+ super.unread(c);
+ }
+}
+
+class HexRecord implements Comparable<Object> {
+ public int address;
+ public int type;
+ public byte checksum;
+ public byte[] data;
+
+ static final int NORMAL = 0;
+ static final int EOF = 1;
+ static final int EXTENDED_ADDRESS = 2;
+
+ enum read_state {
+ marker,
+ length,
+ address,
+ type,
+ data,
+ checksum,
+ newline,
+ white,
+ done,
+ }
+
+ boolean ishex(int c) {
+ if ('0' <= c && c <= '9')
+ return true;
+ if ('a' <= c && c <= 'f')
+ return true;
+ if ('A' <= c && c <= 'F')
+ return true;
+ return false;
+ }
+
+ boolean isspace(int c) {
+ switch (c) {
+ case ' ':
+ case '\t':
+ return true;
+ }
+ return false;
+ }
+
+ int fromhex(int c) {
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ return -1;
+ }
+
+ public byte checksum() {
+ byte got = 0;
+
+ got += data.length;
+ got += (address >> 8) & 0xff;
+ got += (address ) & 0xff;
+ got += type;
+ for (int i = 0; i < data.length; i++)
+ got += data[i];
+ return (byte) (-got);
+ }
+
+ public int compareTo(Object other) {
+ HexRecord o = (HexRecord) other;
+ return address - o.address;
+ }
+
+ public String toString() {
+ return String.format("%04x: %02x (%d)", address, type, data.length);
+ }
+
+ public HexRecord(HexFileInputStream input) throws IOException {
+ read_state state = read_state.marker;
+ int nhexbytes = 0;
+ int hex = 0;
+ int ndata = 0;
+ byte got_checksum;
+
+ while (state != read_state.done) {
+ int c = input.read();
+ if (c < 0 && state != read_state.white)
+ throw new IOException(String.format("%d: Unexpected EOF", input.line));
+ if (c == ' ')
+ continue;
+ switch (state) {
+ case marker:
+ if (c != ':')
+ throw new IOException("Missing ':'");
+ state = read_state.length;
+ nhexbytes = 2;
+ hex = 0;
+ break;
+ case length:
+ case address:
+ case type:
+ case data:
+ case checksum:
+ if(!ishex(c))
+ throw new IOException(String.format("Non-hex char '%c'", c));
+ hex = hex << 4 | fromhex(c);
+ --nhexbytes;
+ if (nhexbytes != 0)
+ break;
+
+ switch (state) {
+ case length:
+ data = new byte[hex];
+ state = read_state.address;
+ nhexbytes = 4;
+ break;
+ case address:
+ address = hex;
+ state = read_state.type;
+ nhexbytes = 2;
+ break;
+ case type:
+ type = hex;
+ if (data.length > 0)
+ state = read_state.data;
+ else
+ state = read_state.checksum;
+ nhexbytes = 2;
+ ndata = 0;
+ break;
+ case data:
+ data[ndata] = (byte) hex;
+ ndata++;
+ nhexbytes = 2;
+ if (ndata == data.length)
+ state = read_state.checksum;
+ break;
+ case checksum:
+ checksum = (byte) hex;
+ state = read_state.newline;
+ break;
+ default:
+ break;
+ }
+ hex = 0;
+ break;
+ case newline:
+ if (c != '\n' && c != '\r')
+ throw new IOException("Missing newline");
+ state = read_state.white;
+ break;
+ case white:
+ if (!isspace(c)) {
+ input.unread(c);
+ state = read_state.done;
+ }
+ break;
+ case done:
+ break;
+ }
+ }
+ got_checksum = checksum();
+ if (got_checksum != checksum)
+ throw new IOException(String.format("Invalid checksum (read 0x%02x computed 0x%02x)\n",
+ checksum, got_checksum));
+ }
+}
+
+public class AltosHexfile {
+ public int address;
+ public byte[] data;
+
+ public byte get_byte(int a) {
+ return data[a - address];
+ }
+
+ public AltosHexfile(FileInputStream file) throws IOException {
+ HexFileInputStream input = new HexFileInputStream(file);
+ LinkedList<HexRecord> record_list = new LinkedList<HexRecord>();
+ boolean done = false;
+
+ while (!done) {
+ HexRecord record = new HexRecord(input);
+
+ if (record.type == HexRecord.EOF)
+ done = true;
+ else
+ record_list.add(record);
+ }
+
+ long extended_addr = 0;
+ long base = 0;
+ long bound = 0;
+ boolean set = false;
+ for (HexRecord record : record_list) {
+ switch (record.type) {
+ case 0:
+ long addr = extended_addr + record.address;
+ long r_bound = addr + record.data.length;
+ if (!set || addr < base)
+ base = addr;
+ if (!set || r_bound > bound)
+ bound = r_bound;
+ set = true;
+ break;
+ case 1:
+ break;
+ case 2:
+ if (record.data.length != 2)
+ throw new IOException("invalid extended segment address record");
+ extended_addr = ((record.data[0] << 8) + (record.data[1])) << 4;
+ break;
+ case 4:
+ if (record.data.length != 2)
+ throw new IOException("invalid extended segment address record");
+ extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16;
+ break;
+ default:
+ throw new IOException ("invalid hex record type");
+ }
+ }
+
+ if (!set || base >= bound)
+ throw new IOException("invalid hex file");
+
+ if (bound - base > 4 * 1024 * 1024)
+ throw new IOException("hex file too large");
+
+ data = new byte[(int) (bound - base)];
+ address = (int) base;
+ Arrays.fill(data, (byte) 0xff);
+
+ /* Paint the records into the new array */
+ for (HexRecord record : record_list) {
+ switch (record.type) {
+ case 0:
+ long addr = extended_addr + record.address;
+ long r_bound = addr + record.data.length;
+ for (int j = 0; j < record.data.length; j++)
+ data[(int) (addr - base) + j] = record.data[j];
+ break;
+ case 1:
+ break;
+ case 2:
+ if (record.data.length != 2)
+ throw new IOException("invalid extended segment address record");
+ extended_addr = ((record.data[0] << 8) + (record.data[1])) << 4;
+ break;
+ case 4:
+ if (record.data.length != 2)
+ throw new IOException("invalid extended segment address record");
+ extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16;
+ break;
+ default:
+ throw new IOException ("invalid hex record type");
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java
index c0eaf139..8f6731fa 100644
--- a/altoslib/AltosIMU.java
+++ b/altoslib/AltosIMU.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosIMU {
public int accel_x;
diff --git a/altoslib/AltosIMUQuery.java b/altoslib/AltosIMUQuery.java
index 0965fa39..4ea5d963 100644
--- a/altoslib/AltosIMUQuery.java
+++ b/altoslib/AltosIMUQuery.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.TimeoutException;
diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java
index 2c4965ff..b3ce5b20 100644
--- a/altoslib/AltosIdleMonitor.java
+++ b/altoslib/AltosIdleMonitor.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.util.concurrent.*;
@@ -27,7 +27,9 @@ public class AltosIdleMonitor extends Thread {
AltosState state;
boolean remote;
double frequency;
+ String callsign;
AltosState previous_state;
+ AltosListenerState listener_state;
AltosConfigData config_data;
AltosGPS gps;
@@ -50,11 +52,11 @@ public class AltosIdleMonitor extends Thread {
}
boolean has_sensor_mm(AltosConfigData config_data) {
- return config_data.product.startsWith("MegaMetrum");
+ return config_data.product.startsWith("TeleMega");
}
boolean has_gps(AltosConfigData config_data) {
- return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("MegaMetrum");
+ return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("TeleMega");
}
AltosRecord sensor_mm(AltosConfigData config_data) throws InterruptedException, TimeoutException {
@@ -87,6 +89,7 @@ public class AltosIdleMonitor extends Thread {
try {
if (remote) {
link.set_radio_frequency(frequency);
+ link.set_callsign(callsign);
link.start_remote();
} else
link.flush_input();
@@ -97,7 +100,7 @@ public class AltosIdleMonitor extends Thread {
else if (has_sensor_mm(config_data))
record = sensor_mm(config_data);
else
- record = new AltosRecord();
+ record = new AltosRecordNone();
if (has_gps(config_data))
gps = new AltosGPSQuery(link, config_data);
@@ -109,13 +112,15 @@ public class AltosIdleMonitor extends Thread {
record.status = 0;
record.state = AltosLib.ao_flight_idle;
record.gps = gps;
- record.new_gps = true;
+ record.gps_sequence++;
state = new AltosState (record, state);
} finally {
if (remote) {
link.stop_remote();
- if (record != null)
- record.rssi = AltosRSSI();
+ if (record != null) {
+ record.rssi = link.rssi();
+ listener_state.battery = link.monitor_battery();
+ }
} else {
if (record != null)
record.rssi = 0;
@@ -126,10 +131,27 @@ public class AltosIdleMonitor extends Thread {
public void set_frequency(double in_frequency) {
frequency = in_frequency;
+ link.abort_reply();
+ }
+
+ public void set_callsign(String in_callsign) {
+ callsign = in_callsign;
+ link.abort_reply();
}
public void post_state() {
- listener.update(state);
+ listener.update(state, listener_state);
+ }
+
+ public void abort() {
+ if (isAlive()) {
+ interrupt();
+ link.abort_reply();
+ try {
+ join();
+ } catch (InterruptedException ie) {
+ }
+ }
}
public void run() {
@@ -153,5 +175,6 @@ public class AltosIdleMonitor extends Thread {
link = in_link;
remote = in_remote;
state = null;
+ listener_state = new AltosListenerState();
}
}
diff --git a/altoslib/AltosIdleMonitorListener.java b/altoslib/AltosIdleMonitorListener.java
index 9f9ababf..27e36dea 100644
--- a/altoslib/AltosIdleMonitorListener.java
+++ b/altoslib/AltosIdleMonitorListener.java
@@ -15,8 +15,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public interface AltosIdleMonitorListener {
- public void update(AltosState state);
+ public void update(AltosState state, AltosListenerState listener_state);
} \ No newline at end of file
diff --git a/altoslib/AltosIgnite.java b/altoslib/AltosIgnite.java
index a48d0b69..85905900 100644
--- a/altoslib/AltosIgnite.java
+++ b/altoslib/AltosIgnite.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.util.concurrent.*;
diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java
index 192c445e..25d17e72 100644
--- a/altoslib/AltosLib.java
+++ b/altoslib/AltosLib.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.*;
import java.io.*;
@@ -50,7 +50,7 @@ public class AltosLib {
public static final int AO_LOG_SERIAL_NUMBER = 2002;
public static final int AO_LOG_LOG_FORMAT = 2003;
- /* Added for header fields in megametrum files */
+ /* Added for header fields in telemega files */
public static final int AO_LOG_BARO_RESERVED = 3000;
public static final int AO_LOG_BARO_SENS = 3001;
public static final int AO_LOG_BARO_OFF = 3002;
@@ -89,10 +89,11 @@ public class AltosLib {
public final static int product_telelco = 0x0010;
public final static int product_telescience = 0x0011;
public final static int product_telepyro =0x0012;
- public final static int product_megametrum = 0x0023;
+ public final static int product_telemega = 0x0023;
public final static int product_megadongle = 0x0024;
+ public final static int product_telegps = 0x0025;
public final static int product_altusmetrum_min = 0x000a;
- public final static int product_altusmetrum_max = 0x0024;
+ public final static int product_altusmetrum_max = 0x0025;
public final static int product_any = 0x10000;
public final static int product_basestation = 0x10000 + 1;
@@ -199,7 +200,7 @@ public class AltosLib {
public static String state_name_capital(int state) {
if (state < 0 || state_to_string.length <= state)
- return "invalid";
+ return "Invalid";
return state_to_string_capital[state];
}
@@ -214,7 +215,7 @@ public class AltosLib {
public static final int AO_LOG_FORMAT_TINY = 2;
public static final int AO_LOG_FORMAT_TELEMETRY = 3;
public static final int AO_LOG_FORMAT_TELESCIENCE = 4;
- public static final int AO_LOG_FORMAT_MEGAMETRUM = 5;
+ public static final int AO_LOG_FORMAT_TELEMEGA = 5;
public static final int AO_LOG_FORMAT_NONE = 127;
public static boolean isspace(int c) {
@@ -405,4 +406,8 @@ public class AltosLib {
input = input.substring(0,dot);
return input.concat(extension);
}
+
+ public static File replace_extension(File input, String extension) {
+ return new File(replace_extension(input.getPath(), extension));
+ }
}
diff --git a/altoslib/AltosLine.java b/altoslib/AltosLine.java
index 5627795a..b3bd20f9 100644
--- a/altoslib/AltosLine.java
+++ b/altoslib/AltosLine.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosLine {
public String line;
diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java
index 6d510563..159ebfe1 100644
--- a/altoslib/AltosLink.java
+++ b/altoslib/AltosLink.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.util.concurrent.*;
@@ -249,6 +249,7 @@ public abstract class AltosLink implements Runnable {
public boolean monitor_mode = false;
public int telemetry = AltosLib.ao_telemetry_standard;
public double frequency;
+ public String callsign;
AltosConfigData config_data;
private int telemetry_len() {
@@ -284,8 +285,8 @@ public abstract class AltosLink implements Runnable {
frequency = in_frequency;
config_data();
set_radio_frequency(frequency,
- config_data.radio_frequency != 0,
- config_data.radio_setting != 0,
+ config_data.radio_frequency > 0,
+ config_data.radio_setting > 0,
config_data.radio_calibration);
}
@@ -330,6 +331,7 @@ public abstract class AltosLink implements Runnable {
}
public void set_callsign(String callsign) {
+ this.callsign = callsign;
printf ("c c %s\n", callsign);
flush_output();
}
@@ -339,10 +341,10 @@ public abstract class AltosLink implements Runnable {
public String name;
public void start_remote() throws TimeoutException, InterruptedException {
- if (debug)
- System.out.printf("start remote %7.3f\n", frequency);
if (frequency == 0.0)
frequency = AltosPreferences.frequency(serial);
+ if (debug)
+ System.out.printf("start remote %7.3f\n", frequency);
set_radio_frequency(frequency);
set_callsign(AltosPreferences.callsign());
printf("p\nE 0\n");
@@ -362,6 +364,64 @@ public abstract class AltosLink implements Runnable {
remote = false;
}
+ public int rssi() throws TimeoutException, InterruptedException {
+ if (remote)
+ return 0;
+ printf("s\n");
+ String line = get_reply_no_dialog(5000);
+ if (line == null)
+ throw new TimeoutException();
+ String[] items = line.split("\\s+");
+ if (items.length < 2)
+ return 0;
+ if (!items[0].equals("RSSI:"))
+ return 0;
+ int rssi = Integer.parseInt(items[1]);
+ return rssi;
+ }
+
+ public String[] adc() throws TimeoutException, InterruptedException {
+ printf("a\n");
+ for (;;) {
+ String line = get_reply_no_dialog(5000);
+ if (line == null) {
+ throw new TimeoutException();
+ }
+ if (!line.startsWith("tick:"))
+ continue;
+ String[] items = line.split("\\s+");
+ return items;
+ }
+ }
+
+ public boolean has_monitor_battery() {
+ return config_data.has_monitor_battery();
+ }
+
+ public double monitor_battery() {
+ int monitor_batt = AltosRecord.MISSING;
+
+ if (config_data.has_monitor_battery()) {
+ try {
+ String[] items = adc();
+ for (int i = 0; i < items.length;) {
+ if (items[i].equals("batt")) {
+ monitor_batt = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ i++;
+ }
+ } catch (InterruptedException ie) {
+ } catch (TimeoutException te) {
+ }
+ }
+ if (monitor_batt == AltosRecord.MISSING)
+ return AltosRecord.MISSING;
+ return AltosConvert.cc_battery_to_voltage(monitor_batt);
+ }
+
public AltosLink() {
+ callsign = "";
}
}
diff --git a/altoslib/AltosListenerState.java b/altoslib/AltosListenerState.java
new file mode 100644
index 00000000..2fb4673e
--- /dev/null
+++ b/altoslib/AltosListenerState.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2013 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 AltosListenerState {
+ public int crc_errors;
+ public double battery;
+
+ public AltosListenerState() {
+ crc_errors = 0;
+ battery = AltosRecord.MISSING;
+ }
+}
diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java
index 3c124700..974c9f0f 100644
--- a/altoslib/AltosLog.java
+++ b/altoslib/AltosLog.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.text.ParseException;
@@ -25,7 +25,7 @@ import java.util.concurrent.LinkedBlockingQueue;
* This creates a thread to capture telemetry data and write it to
* a log file
*/
-class AltosLog implements Runnable {
+public class AltosLog implements Runnable {
LinkedBlockingQueue<AltosLine> input_queue;
LinkedBlockingQueue<String> pending_queue;
@@ -45,7 +45,7 @@ class AltosLog implements Runnable {
}
}
- void close() {
+ public void close() {
close_log_file();
if (log_thread != null) {
log_thread.interrupt();
@@ -53,7 +53,7 @@ class AltosLog implements Runnable {
}
}
- File file() {
+ public File file() {
return file;
}
@@ -85,7 +85,7 @@ class AltosLog implements Runnable {
continue;
try {
AltosRecord telem = AltosTelemetry.parse(line.line, previous);
- if (telem.serial != 0 && telem.flight != 0 &&
+ if ((telem.seen & AltosRecord.seen_flight) != 0 &&
(telem.serial != serial || telem.flight != flight || log_file == null))
{
close_log_file();
diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java
index 0f8399ab..b3bbd92f 100644
--- a/altoslib/AltosMag.java
+++ b/altoslib/AltosMag.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosMag {
public int x;
diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java
index 268e89f6..606916b7 100644
--- a/altoslib/AltosMs5607.java
+++ b/altoslib/AltosMs5607.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosMs5607 {
public int reserved;
@@ -32,6 +32,8 @@ public class AltosMs5607 {
public int pa;
public int cc;
+ static final boolean ms5611 = false;
+
void convert() {
int dT;
int TEMP;
@@ -41,20 +43,26 @@ public class AltosMs5607 {
dT = raw_temp - ((int) tref << 8);
- TEMP = (int) (2000 + (((long) dT * tempsens) >> 23));
+ TEMP = (int) (2000 + (((long) dT * (long) tempsens) >> 23));
+
+ if (ms5611) {
+ OFF = ((long) off << 16) + (((long) tco * (long) dT) >> 7);
- OFF = ((long) off << 17) + (((long) tco * dT) >> 6);
+ SENS = ((long) sens << 15) + (((long) tcs * (long) dT) >> 8);
+ } else {
+ OFF = ((long) off << 17) + (((long) tco * (long) dT) >> 6);
- SENS = ((long) sens << 16) + (((long) tcs * dT) >> 7);
+ SENS = ((long) sens << 16) + (((long) tcs * (long) dT) >> 7);
+ }
if (TEMP < 2000) {
int T2 = (int) (((long) dT * (long) dT) >> 31);
int TEMPM = TEMP - 2000;
- long OFF2 = (61 * (long) TEMPM * (long) TEMPM) >> 4;
- long SENS2 = 2 * (long) TEMPM * (long) TEMPM;
+ long OFF2 = ((long) 61 * (long) TEMPM * (long) TEMPM) >> 4;
+ long SENS2 = (long) 2 * (long) TEMPM * (long) TEMPM;
if (TEMP < 1500) {
int TEMPP = TEMP + 1500;
- long TEMPP2 = TEMPP * TEMPP;
+ long TEMPP2 = (long) TEMPP * (long) TEMPP;
OFF2 = OFF2 + 15 * TEMPP2;
SENS2 = SENS2 + 8 * TEMPP2;
}
@@ -74,6 +82,43 @@ public class AltosMs5607 {
return pa;
}
+ public boolean parse_line(String line) {
+ String[] items = line.split("\\s+");
+ if (line.startsWith("Pressure:")) {
+ if (items.length >= 2)
+ raw_pres = Integer.parseInt(items[1]);
+ } else if (line.startsWith("Temperature:")) {
+ if (items.length >= 2)
+ raw_temp = Integer.parseInt(items[1]);
+ } else if (line.startsWith("ms5607 reserved:")) {
+ if (items.length >= 3)
+ reserved = Integer.parseInt(items[2]);
+ } else if (line.startsWith("ms5607 sens:")) {
+ if (items.length >= 3)
+ sens = Integer.parseInt(items[2]);
+ } else if (line.startsWith("ms5607 off:")) {
+ if (items.length >= 3)
+ off = Integer.parseInt(items[2]);
+ } else if (line.startsWith("ms5607 tcs:")) {
+ if (items.length >= 3)
+ tcs = Integer.parseInt(items[2]);
+ } else if (line.startsWith("ms5607 tco:")) {
+ if (items.length >= 3)
+ tco = Integer.parseInt(items[2]);
+ } else if (line.startsWith("ms5607 tref:")) {
+ if (items.length >= 3)
+ tref = Integer.parseInt(items[2]);
+ } else if (line.startsWith("ms5607 tempsens:")) {
+ if (items.length >= 3)
+ tempsens = Integer.parseInt(items[2]);
+ } else if (line.startsWith("ms5607 crc:")) {
+ if (items.length >= 3)
+ crc = Integer.parseInt(items[2]);
+ } else if (line.startsWith("Altitude"))
+ return false;
+ return true;
+ }
+
public AltosMs5607() {
raw_pres = AltosRecord.MISSING;
raw_temp = AltosRecord.MISSING;
diff --git a/altoslib/AltosMs5607Query.java b/altoslib/AltosMs5607Query.java
index 3c746795..d39dbf26 100644
--- a/altoslib/AltosMs5607Query.java
+++ b/altoslib/AltosMs5607Query.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.TimeoutException;
@@ -27,38 +27,7 @@ class AltosMs5607Query extends AltosMs5607 {
if (line == null) {
throw new TimeoutException();
}
- String[] items = line.split("\\s+");
- if (line.startsWith("Pressure:")) {
- if (items.length >= 2)
- raw_pres = Integer.parseInt(items[1]);
- } else if (line.startsWith("Temperature:")) {
- if (items.length >= 2)
- raw_temp = Integer.parseInt(items[1]);
- } else if (line.startsWith("ms5607 reserved:")) {
- if (items.length >= 3)
- reserved = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 sens:")) {
- if (items.length >= 3)
- sens = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 off:")) {
- if (items.length >= 3)
- off = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tcs:")) {
- if (items.length >= 3)
- tcs = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tco:")) {
- if (items.length >= 3)
- tco = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tref:")) {
- if (items.length >= 3)
- tref = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 tempsens:")) {
- if (items.length >= 3)
- tempsens = Integer.parseInt(items[2]);
- } else if (line.startsWith("ms5607 crc:")) {
- if (items.length >= 3)
- crc = Integer.parseInt(items[2]);
- } else if (line.startsWith("Altitude"))
+ if (!parse_line(line))
break;
}
convert();
diff --git a/altoslib/AltosOrderedMegaRecord.java b/altoslib/AltosOrderedMegaRecord.java
index 05423dd9..b20a5bbd 100644
--- a/altoslib/AltosOrderedMegaRecord.java
+++ b/altoslib/AltosOrderedMegaRecord.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.ParseException;
@@ -43,18 +43,6 @@ class AltosOrderedMegaRecord extends AltosEepromMega implements Comparable<Altos
index = in_index;
}
- public AltosOrderedMegaRecord(int in_cmd, int in_tick, int in_a, int in_b, int in_index) {
- super(in_cmd, in_tick);
- a = in_a;
- b = in_b;
- index = in_index;
- }
-
- public String toString() {
- return String.format("%d.%d %04x %04x %04x",
- cmd, index, tick, a, b);
- }
-
public int compareTo(AltosOrderedMegaRecord o) {
int tick_diff = tick - o.tick;
if (tick_diff != 0)
diff --git a/altoslib/AltosOrderedRecord.java b/altoslib/AltosOrderedRecord.java
index b4cfd8f2..63507d39 100644
--- a/altoslib/AltosOrderedRecord.java
+++ b/altoslib/AltosOrderedRecord.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.ParseException;
diff --git a/altoslib/AltosParse.java b/altoslib/AltosParse.java
index e938a177..66bbeed5 100644
--- a/altoslib/AltosParse.java
+++ b/altoslib/AltosParse.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java
index 0e7b2bd3..088ca3d7 100644
--- a/altoslib/AltosPreferences.java
+++ b/altoslib/AltosPreferences.java
@@ -15,15 +15,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.util.*;
-import java.util.prefs.*;
-import javax.swing.filechooser.FileSystemView;
public class AltosPreferences {
- public static Preferences preferences;
+ public static AltosPreferencesBackend backend = null;
/* logdir preference name */
public final static String logdirPreference = "LOGDIR";
@@ -64,6 +62,9 @@ public class AltosPreferences {
/* Log directory */
public static File logdir;
+ /* Last log directory - use this next time we open or save something */
+ public static File last_logdir;
+
/* Map directory -- hangs of logdir */
public static File mapdir;
@@ -100,13 +101,10 @@ public class AltosPreferences {
public static AltosFrequency[] load_common_frequencies() {
AltosFrequency[] frequencies = null;
boolean existing = false;
- try {
- existing = preferences.nodeExists(common_frequencies_node_name);
- } catch (BackingStoreException be) {
- existing = false;
- }
+ existing = backend.nodeExists(common_frequencies_node_name);
+
if (existing) {
- Preferences node = preferences.node(common_frequencies_node_name);
+ AltosPreferencesBackend node = backend.node(common_frequencies_node_name);
int count = node.getInt(frequency_count, 0);
frequencies = new AltosFrequency[count];
@@ -115,7 +113,7 @@ public class AltosPreferences {
String description;
frequency = node.getDouble(String.format(frequency_format, i), 0.0);
- description = node.get(String.format(description_format, i), null);
+ description = node.getString(String.format(description_format, i), null);
frequencies[i] = new AltosFrequency(frequency, description);
}
} else {
@@ -129,28 +127,27 @@ public class AltosPreferences {
}
public static void save_common_frequencies(AltosFrequency[] frequencies) {
- Preferences node = preferences.node(common_frequencies_node_name);
+ AltosPreferencesBackend node = backend.node(common_frequencies_node_name);
node.putInt(frequency_count, frequencies.length);
for (int i = 0; i < frequencies.length; i++) {
node.putDouble(String.format(frequency_format, i), frequencies[i].frequency);
- node.put(String.format(description_format, i), frequencies[i].description);
+ node.putString(String.format(description_format, i), frequencies[i].description);
}
}
public static int launcher_serial;
public static int launcher_channel;
- public static void init() {
- preferences = Preferences.userRoot().node("/org/altusmetrum/altosui");
+ public static void init(AltosPreferencesBackend in_backend) {
+ backend = in_backend;
/* Initialize logdir from preferences */
- String logdir_string = preferences.get(logdirPreference, null);
+ String logdir_string = backend.getString(logdirPreference, null);
if (logdir_string != null)
logdir = new File(logdir_string);
else {
- /* Use the file system view default directory */
- logdir = new File(FileSystemView.getFileSystemView().getDefaultDirectory(), logdirName);
+ logdir = new File(backend.homeDirectory(), logdirName);
if (!logdir.exists())
logdir.mkdirs();
}
@@ -162,17 +159,17 @@ public class AltosPreferences {
telemetries = new Hashtable<Integer,Integer>();
- voice = preferences.getBoolean(voicePreference, true);
+ voice = backend.getBoolean(voicePreference, true);
- callsign = preferences.get(callsignPreference,"N0CALL");
+ callsign = backend.getString(callsignPreference,"N0CALL");
- scanning_telemetry = preferences.getInt(scanningTelemetryPreference,(1 << AltosLib.ao_telemetry_standard));
+ scanning_telemetry = backend.getInt(scanningTelemetryPreference,(1 << AltosLib.ao_telemetry_standard));
- launcher_serial = preferences.getInt(launcherSerialPreference, 0);
+ launcher_serial = backend.getInt(launcherSerialPreference, 0);
- launcher_channel = preferences.getInt(launcherChannelPreference, 0);
+ launcher_channel = backend.getInt(launcherChannelPreference, 0);
- String firmwaredir_string = preferences.get(firmwaredirPreference, null);
+ String firmwaredir_string = backend.getString(firmwaredirPreference, null);
if (firmwaredir_string != null)
firmwaredir = new File(firmwaredir_string);
else
@@ -180,65 +177,69 @@ public class AltosPreferences {
common_frequencies = load_common_frequencies();
- AltosConvert.imperial_units = preferences.getBoolean(unitsPreference, false);
+ AltosConvert.imperial_units = backend.getBoolean(unitsPreference, false);
}
- static { init(); }
-
public static void flush_preferences() {
- try {
- preferences.flush();
- } catch (BackingStoreException ee) {
-/*
- if (component != null)
- JOptionPane.showMessageDialog(component,
- preferences.absolutePath(),
- "Cannot save prefernces",
- JOptionPane.ERROR_MESSAGE);
- else
-*/
- System.err.printf("Cannot save preferences\n");
- }
+ backend.flush();
}
public static void set_logdir(File new_logdir) {
- synchronized (preferences) {
+ synchronized (backend) {
logdir = new_logdir;
mapdir = new File(logdir, "maps");
if (!mapdir.exists())
mapdir.mkdirs();
- preferences.put(logdirPreference, logdir.getPath());
+ backend.putString(logdirPreference, logdir.getPath());
flush_preferences();
}
}
public static File logdir() {
- synchronized (preferences) {
+ synchronized (backend) {
return logdir;
}
}
+ public static File last_logdir() {
+ synchronized (backend) {
+ if (last_logdir == null)
+ last_logdir = logdir;
+ return last_logdir;
+ }
+ }
+
+ public static void set_last_logdir(File file) {
+ synchronized(backend) {
+ if (file != null && !file.isDirectory())
+ file = file.getParentFile();
+ if (file == null)
+ file = new File(".");
+ last_logdir = file;
+ }
+ }
+
public static File mapdir() {
- synchronized (preferences) {
+ synchronized (backend) {
return mapdir;
}
}
public static void set_frequency(int serial, double new_frequency) {
- synchronized (preferences) {
+ synchronized (backend) {
frequencies.put(serial, new_frequency);
- preferences.putDouble(String.format(frequencyPreferenceFormat, serial), new_frequency);
+ backend.putDouble(String.format(frequencyPreferenceFormat, serial), new_frequency);
flush_preferences();
}
}
public static double frequency(int serial) {
- synchronized (preferences) {
+ synchronized (backend) {
if (frequencies.containsKey(serial))
return frequencies.get(serial);
- double frequency = preferences.getDouble(String.format(frequencyPreferenceFormat, serial), 0);
+ double frequency = backend.getDouble(String.format(frequencyPreferenceFormat, serial), 0);
if (frequency == 0.0) {
- int channel = preferences.getInt(String.format(channelPreferenceFormat, serial), 0);
+ int channel = backend.getInt(String.format(channelPreferenceFormat, serial), 0);
frequency = AltosConvert.radio_channel_to_frequency(channel);
}
frequencies.put(serial, frequency);
@@ -247,122 +248,122 @@ public class AltosPreferences {
}
public static void set_telemetry(int serial, int new_telemetry) {
- synchronized (preferences) {
+ synchronized (backend) {
telemetries.put(serial, new_telemetry);
- preferences.putInt(String.format(telemetryPreferenceFormat, serial), new_telemetry);
+ backend.putInt(String.format(telemetryPreferenceFormat, serial), new_telemetry);
flush_preferences();
}
}
public static int telemetry(int serial) {
- synchronized (preferences) {
+ synchronized (backend) {
if (telemetries.containsKey(serial))
return telemetries.get(serial);
- int telemetry = preferences.getInt(String.format(telemetryPreferenceFormat, serial),
- AltosLib.ao_telemetry_standard);
+ int telemetry = backend.getInt(String.format(telemetryPreferenceFormat, serial),
+ AltosLib.ao_telemetry_standard);
telemetries.put(serial, telemetry);
return telemetry;
}
}
public static void set_scanning_telemetry(int new_scanning_telemetry) {
- synchronized (preferences) {
+ synchronized (backend) {
scanning_telemetry = new_scanning_telemetry;
- preferences.putInt(scanningTelemetryPreference, scanning_telemetry);
+ backend.putInt(scanningTelemetryPreference, scanning_telemetry);
flush_preferences();
}
}
public static int scanning_telemetry() {
- synchronized (preferences) {
+ synchronized (backend) {
return scanning_telemetry;
}
}
public static void set_voice(boolean new_voice) {
- synchronized (preferences) {
+ synchronized (backend) {
voice = new_voice;
- preferences.putBoolean(voicePreference, voice);
+ backend.putBoolean(voicePreference, voice);
flush_preferences();
}
}
public static boolean voice() {
- synchronized (preferences) {
+ synchronized (backend) {
return voice;
}
}
public static void set_callsign(String new_callsign) {
- synchronized(preferences) {
+ synchronized(backend) {
callsign = new_callsign;
- preferences.put(callsignPreference, callsign);
+ backend.putString(callsignPreference, callsign);
flush_preferences();
}
}
public static String callsign() {
- synchronized(preferences) {
+ synchronized(backend) {
return callsign;
}
}
public static void set_firmwaredir(File new_firmwaredir) {
- synchronized (preferences) {
+ synchronized (backend) {
firmwaredir = new_firmwaredir;
- preferences.put(firmwaredirPreference, firmwaredir.getPath());
+ backend.putString(firmwaredirPreference, firmwaredir.getPath());
flush_preferences();
}
}
public static File firmwaredir() {
- synchronized (preferences) {
+ synchronized (backend) {
return firmwaredir;
}
}
public static void set_launcher_serial(int new_launcher_serial) {
- synchronized (preferences) {
+ synchronized (backend) {
launcher_serial = new_launcher_serial;
- preferences.putInt(launcherSerialPreference, launcher_serial);
+ backend.putInt(launcherSerialPreference, launcher_serial);
flush_preferences();
}
}
public static int launcher_serial() {
- synchronized (preferences) {
+ synchronized (backend) {
return launcher_serial;
}
}
public static void set_launcher_channel(int new_launcher_channel) {
- synchronized (preferences) {
+ synchronized (backend) {
launcher_channel = new_launcher_channel;
- preferences.putInt(launcherChannelPreference, launcher_channel);
+ backend.putInt(launcherChannelPreference, launcher_channel);
flush_preferences();
}
}
public static int launcher_channel() {
- synchronized (preferences) {
+ synchronized (backend) {
return launcher_channel;
}
}
- public static Preferences bt_devices() {
- synchronized (preferences) {
- return preferences.node("bt_devices");
+ public static AltosPreferencesBackend bt_devices() {
+ synchronized (backend) {
+ return backend.node("bt_devices");
}
}
public static AltosFrequency[] common_frequencies() {
- synchronized (preferences) {
+ synchronized (backend) {
return common_frequencies;
}
}
public static void set_common_frequencies(AltosFrequency[] frequencies) {
- synchronized(preferences) {
+ synchronized(backend) {
common_frequencies = frequencies;
save_common_frequencies(frequencies);
flush_preferences();
@@ -387,17 +388,38 @@ public class AltosPreferences {
set_common_frequencies(new_frequencies);
}
+ static LinkedList<AltosUnitsListener> units_listeners;
+
public static boolean imperial_units() {
- synchronized(preferences) {
+ synchronized(backend) {
return AltosConvert.imperial_units;
}
}
public static void set_imperial_units(boolean imperial_units) {
- synchronized (preferences) {
+ synchronized (backend) {
AltosConvert.imperial_units = imperial_units;
- preferences.putBoolean(unitsPreference, imperial_units);
+ backend.putBoolean(unitsPreference, imperial_units);
flush_preferences();
}
+ if (units_listeners != null) {
+ for (AltosUnitsListener l : units_listeners) {
+ l.units_changed(imperial_units);
+ }
+ }
+ }
+
+ public static void register_units_listener(AltosUnitsListener l) {
+ synchronized(backend) {
+ if (units_listeners == null)
+ units_listeners = new LinkedList<AltosUnitsListener>();
+ units_listeners.add(l);
+ }
+ }
+
+ public static void unregister_units_listener(AltosUnitsListener l) {
+ synchronized(backend) {
+ units_listeners.remove(l);
+ }
}
}
diff --git a/altoslib/AltosPreferencesBackend.java b/altoslib/AltosPreferencesBackend.java
new file mode 100644
index 00000000..fb8a235a
--- /dev/null
+++ b/altoslib/AltosPreferencesBackend.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2010 Mike Beattie <mike@ethernal.org>
+ *
+ * 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.File;
+
+public interface AltosPreferencesBackend {
+
+ public String getString(String key, String def);
+ public void putString(String key, String value);
+
+ public int getInt(String key, int def);
+ public void putInt(String key, int value);
+
+ public double getDouble(String key, double def);
+ public void putDouble(String key, double value);
+
+ public boolean getBoolean(String key, boolean def);
+ public void putBoolean(String key, boolean value);
+
+ public boolean nodeExists(String key);
+ public AltosPreferencesBackend node(String key);
+
+ public String[] keys();
+ public void remove(String key);
+
+ public void flush();
+
+ public File homeDirectory();
+}
diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java
new file mode 100644
index 00000000..4dbb4223
--- /dev/null
+++ b/altoslib/AltosPyro.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright © 2012 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.util.*;
+import java.text.*;
+import java.util.concurrent.*;
+
+public class AltosPyro {
+ public static final int pyro_none = 0x00000000;
+
+ public static final int pyro_accel_less = 0x00000001;
+ public static final int pyro_accel_greater = 0x00000002;
+ public static final String pyro_accel_less_string = "a<";
+ public static final String pyro_accel_greater_string = "a>";
+ public static final String pyro_accel_less_name = "Acceleration less than (m/s²)";
+ public static final String pyro_accel_greater_name = "Acceleration greater than (m/s²)";
+ public static final double pyro_accel_scale = 16.0;
+
+ public static final int pyro_speed_less = 0x00000004;
+ public static final int pyro_speed_greater = 0x00000008;
+ public static final String pyro_speed_less_string = "s<";
+ public static final String pyro_speed_greater_string = "s>";
+ public static final String pyro_speed_less_name = "Speed less than (m/s)";
+ public static final String pyro_speed_greater_name = "Speed greater than (m/s)";
+ public static final double pyro_speed_scale = 16.0;
+
+ public static final int pyro_height_less = 0x00000010;
+ public static final int pyro_height_greater = 0x00000020;
+ public static final String pyro_height_less_string = "h<";
+ public static final String pyro_height_greater_string = "h>";
+ public static final String pyro_height_less_name = "Height less than (m)";
+ public static final String pyro_height_greater_name = "Height greater than (m)";
+ public static final double pyro_height_scale = 1.0;
+
+ public static final int pyro_orient_less = 0x00000040;
+ public static final int pyro_orient_greater = 0x00000080;
+ public static final String pyro_orient_less_string = "o<";
+ public static final String pyro_orient_greater_string = "o>";
+ public static final String pyro_orient_less_name = "Angle from vertical less than (degrees)";
+ public static final String pyro_orient_greater_name = "Angle from vertical greater than (degrees)";
+ public static final double pyro_orient_scale = 1.0;
+
+ public static final int pyro_time_less = 0x00000100;
+ public static final int pyro_time_greater = 0x00000200;
+ public static final String pyro_time_less_string = "t<";
+ public static final String pyro_time_greater_string = "t>";
+ public static final String pyro_time_less_name = "Time since boost less than (s)";
+ public static final String pyro_time_greater_name = "Time since boost greater than (s)";
+ public static final double pyro_time_scale = 100.0;
+
+ public static final int pyro_ascending = 0x00000400;
+ public static final int pyro_descending = 0x00000800;
+ public static final String pyro_ascending_string = "A";
+ public static final String pyro_descending_string = "D";
+ public static final String pyro_ascending_name = "Ascending";
+ public static final String pyro_descending_name = "Descending";
+
+ public static final int pyro_after_motor = 0x00001000;
+ public static final String pyro_after_motor_string = "m";
+ public static final String pyro_after_motor_name = "After motor number";
+ public static final double pyro_after_motor_scale = 1.0;
+
+ public static final int pyro_delay = 0x00002000;
+ public static final String pyro_delay_string = "d";
+ public static final String pyro_delay_name = "Delay after other conditions (s)";
+ public static final double pyro_delay_scale = 100.0;
+
+ public static final int pyro_state_less = 0x00004000;
+ public static final int pyro_state_greater_or_equal = 0x00008000;
+ public static final String pyro_state_less_string = "f<";
+ public static final String pyro_state_greater_or_equal_string = "f>=";
+ public static final String pyro_state_less_name = "Flight state before";
+ public static final String pyro_state_greater_or_equal_name = "Flight state after";
+ public static final double pyro_state_scale = 1.0;
+
+ public static final int pyro_all = 0x0000ffff;
+
+ public static final int pyro_no_value = (pyro_ascending |
+ pyro_descending);
+
+ public static final int pyro_state_value = pyro_state_less | pyro_state_greater_or_equal;
+
+ private static HashMap<String,Integer> string_to_pyro = new HashMap<String,Integer>();
+
+ private static HashMap<Integer,String> pyro_to_string = new HashMap<Integer,String>();
+
+ private static HashMap<Integer,String> pyro_to_name = new HashMap<Integer,String>();
+
+ private static HashMap<Integer,Double> pyro_to_scale = new HashMap<Integer,Double>();
+
+ private static void insert_map(int flag, String string, String name, double scale) {
+ string_to_pyro.put(string, flag);
+ pyro_to_string.put(flag, string);
+ pyro_to_name.put(flag, name);
+ pyro_to_scale.put(flag, scale);
+ }
+
+ public static int string_to_pyro(String name) {
+ if (string_to_pyro.containsKey(name))
+ return string_to_pyro.get(name);
+ return pyro_none;
+ }
+
+ public static String pyro_to_string(int flag) {
+ if (pyro_to_string.containsKey(flag))
+ return pyro_to_string.get(flag);
+ return null;
+ }
+
+ public static String pyro_to_name(int flag) {
+ if (pyro_to_name.containsKey(flag))
+ return pyro_to_name.get(flag);
+ return null;
+ }
+
+ public static double pyro_to_scale(int flag) {
+ if (pyro_to_scale.containsKey(flag))
+ return pyro_to_scale.get(flag);
+ return 1.0;
+ }
+
+ private static void initialize_maps() {
+ insert_map(pyro_accel_less, pyro_accel_less_string, pyro_accel_less_name, pyro_accel_scale);
+ insert_map(pyro_accel_greater, pyro_accel_greater_string, pyro_accel_greater_name, pyro_accel_scale);
+
+ insert_map(pyro_speed_less, pyro_speed_less_string, pyro_speed_less_name, pyro_speed_scale);
+ insert_map(pyro_speed_greater, pyro_speed_greater_string, pyro_speed_greater_name, pyro_speed_scale);
+
+ insert_map(pyro_height_less, pyro_height_less_string, pyro_height_less_name, pyro_height_scale);
+ insert_map(pyro_height_greater, pyro_height_greater_string, pyro_height_greater_name, pyro_height_scale);
+
+ insert_map(pyro_orient_less, pyro_orient_less_string, pyro_orient_less_name, pyro_orient_scale);
+ insert_map(pyro_orient_greater, pyro_orient_greater_string, pyro_orient_greater_name, pyro_orient_scale);
+
+ insert_map(pyro_time_less, pyro_time_less_string, pyro_time_less_name, pyro_time_scale);
+ insert_map(pyro_time_greater, pyro_time_greater_string, pyro_time_greater_name, pyro_time_scale);
+
+ insert_map(pyro_ascending, pyro_ascending_string, pyro_ascending_name, 1.0);
+ insert_map(pyro_descending, pyro_descending_string, pyro_descending_name, 1.0);
+
+ insert_map(pyro_after_motor, pyro_after_motor_string, pyro_after_motor_name, 1.0);
+ insert_map(pyro_delay, pyro_delay_string, pyro_delay_name, pyro_delay_scale);
+
+ insert_map(pyro_state_less, pyro_state_less_string, pyro_state_less_name, 1.0);
+ insert_map(pyro_state_greater_or_equal, pyro_state_greater_or_equal_string, pyro_state_greater_or_equal_name, 1.0);
+ }
+
+ {
+ initialize_maps();
+ }
+
+ public int channel;
+ public int flags;
+ public int accel_less, accel_greater;
+ public int speed_less, speed_greater;
+ public int height_less, height_greater;
+ public int orient_less, orient_greater;
+ public int time_less, time_greater;
+ public int delay;
+ public int state_less, state_greater_or_equal;
+ public int motor;
+
+ public AltosPyro(int in_channel) {
+ channel = in_channel;
+ flags = 0;
+ }
+
+ private boolean set_ivalue(int flag, int value) {
+ switch (flag) {
+ case pyro_accel_less: accel_less = value; break;
+ case pyro_accel_greater: accel_greater = value; break;
+ case pyro_speed_less: speed_less = value; break;
+ case pyro_speed_greater: speed_greater = value; break;
+ case pyro_height_less: height_less = value; break;
+ case pyro_height_greater: height_greater = value; break;
+ case pyro_orient_less: orient_less = value; break;
+ case pyro_orient_greater: orient_greater = value; break;
+ case pyro_time_less: time_less = value; break;
+ case pyro_time_greater: time_greater = value; break;
+ case pyro_after_motor: motor = value; break;
+ case pyro_delay: delay = value; break;
+ case pyro_state_less: state_less = value; break;
+ case pyro_state_greater_or_equal: state_greater_or_equal = value; break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ public boolean set_value(int flag, double dvalue) {
+ return set_ivalue(flag, (int) (dvalue * pyro_to_scale(flag)));
+ }
+
+ private int get_ivalue (int flag) {
+ int value;
+
+ switch (flag) {
+ case pyro_accel_less: value = accel_less; break;
+ case pyro_accel_greater: value = accel_greater; break;
+ case pyro_speed_less: value = speed_less; break;
+ case pyro_speed_greater: value = speed_greater; break;
+ case pyro_height_less: value = height_less; break;
+ case pyro_height_greater: value = height_greater; break;
+ case pyro_orient_less: value = orient_less; break;
+ case pyro_orient_greater: value = orient_greater; break;
+ case pyro_time_less: value = time_less; break;
+ case pyro_time_greater: value = time_greater; break;
+ case pyro_after_motor: value = motor; break;
+ case pyro_delay: value = delay; break;
+ case pyro_state_less: value = state_less; break;
+ case pyro_state_greater_or_equal: value = state_greater_or_equal; break;
+ default: value = 0; break;
+ }
+ return value;
+ }
+
+ public double get_value(int flag) {
+ return get_ivalue(flag) / pyro_to_scale(flag);
+ }
+
+ public AltosPyro(int in_channel, String line) throws ParseException {
+ String[] tokens = line.split("\\s+");
+
+ channel = in_channel;
+ flags = 0;
+
+ int i = 0;
+ if (tokens[i].equals("Pyro"))
+ i += 2;
+
+ for (; i < tokens.length; i++) {
+
+ if (tokens[i].equals("<disabled>"))
+ break;
+
+ int flag = string_to_pyro(tokens[i]);
+ if (flag == pyro_none)
+ throw new ParseException(String.format("Invalid pyro token \"%s\"",
+ tokens[i]), i);
+ flags |= flag;
+
+ if ((flag & pyro_no_value) == 0) {
+ int value = 0;
+ ++i;
+ try {
+ value = AltosLib.fromdec(tokens[i]);
+ } catch (NumberFormatException n) {
+ throw new ParseException(String.format("Invalid pyro value \"%s\"",
+ tokens[i]), i);
+ }
+ if (!set_ivalue(flag, value))
+ throw new ParseException(String.format("Internal parser error \"%s\" \"%s\"",
+ tokens[i-1], tokens[i]), i-1);
+ }
+ }
+ }
+
+ public String toString() {
+ String ret = String.format("%d", channel);
+
+ for (int flag = 1; flag <= flags; flag <<= 1) {
+ if ((flags & flag) != 0) {
+ String add;
+ if ((flag & pyro_no_value) == 0) {
+ add = String.format(" %s %d",
+ pyro_to_string.get(flag),
+ get_ivalue(flag));
+ } else {
+ add = String.format(" %s",
+ pyro_to_string.get(flag));
+ }
+ ret = ret.concat(add);
+ }
+ }
+ return ret;
+ }
+}
diff --git a/altoslib/AltosRecord.java b/altoslib/AltosRecord.java
index 8bab1d0c..5e4ed927 100644
--- a/altoslib/AltosRecord.java
+++ b/altoslib/AltosRecord.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosRecord implements Comparable <AltosRecord>, Cloneable {
@@ -43,13 +43,8 @@ public class AltosRecord implements Comparable <AltosRecord>, Cloneable {
public int state;
public int tick;
- /* Current flight dynamic state */
- public double acceleration; /* m/s² */
- public double speed; /* m/s */
- public double height; /* m */
-
public AltosGPS gps;
- public boolean new_gps;
+ public int gps_sequence;
public double time; /* seconds since boost */
@@ -63,6 +58,11 @@ public class AltosRecord implements Comparable <AltosRecord>, Cloneable {
public AltosRecordCompanion companion;
+ /* Telemetry sources have these values recorded from the flight computer */
+ public double kalman_height;
+ public double kalman_speed;
+ public double kalman_acceleration;
+
/*
* Abstract methods that convert record data
* to standard units:
@@ -75,76 +75,48 @@ public class AltosRecord implements Comparable <AltosRecord>, Cloneable {
* temperature: °C
*/
- public double raw_pressure() { return MISSING; }
-
- public double filtered_pressure() { return MISSING; }
-
+ public double pressure() { return MISSING; }
public double ground_pressure() { return MISSING; }
-
- public double battery_voltage() { return MISSING; }
-
- public double main_voltage() { return MISSING; }
-
- public double drogue_voltage() { return MISSING; }
-
- public double temperature() { return MISSING; }
-
public double acceleration() { return MISSING; }
- public double accel_speed() { return MISSING; }
-
- public AltosIMU imu() { return null; }
-
- public AltosMag mag() { return null; }
+ public double altitude() {
+ double p = pressure();
- /*
- * Convert various pressure values to altitude
- */
-
- public double raw_altitude() {
- double p = raw_pressure();
if (p == MISSING)
return MISSING;
return AltosConvert.pressure_to_altitude(p);
}
public double ground_altitude() {
- double p = ground_pressure();
+ double p = ground_pressure();
+
if (p == MISSING)
return MISSING;
return AltosConvert.pressure_to_altitude(p);
}
- public double filtered_altitude() {
- double ga = ground_altitude();
- if (height != MISSING && ga != MISSING)
- return height + ga;
+ public double height() {
+ double g = ground_altitude();
+ double a = altitude();
- double p = filtered_pressure();
- if (p == MISSING)
- return raw_altitude();
- return AltosConvert.pressure_to_altitude(p);
+ if (g == MISSING)
+ return MISSING;
+ if (a == MISSING)
+ return MISSING;
+ return a - g;
}
- public double filtered_height() {
- if (height != MISSING)
- return height;
+ public double battery_voltage() { return MISSING; }
- double f = filtered_altitude();
- double g = ground_altitude();
- if (f == MISSING || g == MISSING)
- return MISSING;
- return f - g;
- }
+ public double main_voltage() { return MISSING; }
- public double raw_height() {
- double r = raw_altitude();
- double g = ground_altitude();
+ public double drogue_voltage() { return MISSING; }
- if (r == MISSING || g == MISSING)
- return height;
- return r - g;
- }
+ public double temperature() { return MISSING; }
+
+ public AltosIMU imu() { return null; }
+
+ public AltosMag mag() { return null; }
public String state() {
return AltosLib.state_name(state);
@@ -154,6 +126,12 @@ public class AltosRecord implements Comparable <AltosRecord>, Cloneable {
return tick - o.tick;
}
+ public AltosRecord clone() {
+ AltosRecord n = new AltosRecord();
+ n.copy(this);
+ return n;
+ }
+
public void copy(AltosRecord old) {
seen = old.seen;
version = old.version;
@@ -164,39 +142,30 @@ public class AltosRecord implements Comparable <AltosRecord>, Cloneable {
status = old.status;
state = old.state;
tick = old.tick;
- acceleration = old.acceleration;
- speed = old.speed;
- height = old.height;
gps = new AltosGPS(old.gps);
- new_gps = old.new_gps;
+ gps_sequence = old.gps_sequence;
companion = old.companion;
- }
-
- public AltosRecord clone() {
- try {
- AltosRecord n = (AltosRecord) super.clone();
- n.copy(this);
- return n;
- } catch (CloneNotSupportedException e) {
- return null;
- }
+ kalman_acceleration = old.kalman_acceleration;
+ kalman_speed = old.kalman_speed;
+ kalman_height = old.kalman_height;
}
public AltosRecord() {
seen = 0;
version = 0;
callsign = "N0CALL";
- serial = 0;
- flight = 0;
+ serial = MISSING;
+ flight = MISSING;
rssi = 0;
status = 0;
state = AltosLib.ao_flight_startup;
tick = 0;
- acceleration = MISSING;
- speed = MISSING;
- height = MISSING;
- gps = new AltosGPS();
- new_gps = false;
+ gps = null;
+ gps_sequence = 0;
companion = null;
+
+ kalman_acceleration = MISSING;
+ kalman_speed = MISSING;
+ kalman_height = MISSING;
}
}
diff --git a/altoslib/AltosRecordCompanion.java b/altoslib/AltosRecordCompanion.java
index c8cc6cac..b153fb5b 100644
--- a/altoslib/AltosRecordCompanion.java
+++ b/altoslib/AltosRecordCompanion.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosRecordCompanion {
public final static int board_id_telescience = 0x0a;
diff --git a/altoslib/AltosRecordIterable.java b/altoslib/AltosRecordIterable.java
index ed1787ed..62dbdfe3 100644
--- a/altoslib/AltosRecordIterable.java
+++ b/altoslib/AltosRecordIterable.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.util.*;
diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java
index 5f952f7a..bf64192c 100644
--- a/altoslib/AltosRecordMM.java
+++ b/altoslib/AltosRecordMM.java
@@ -15,10 +15,11 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosRecordMM extends AltosRecord {
+ /* Sensor values */
public int accel;
public int pres;
public int temp;
@@ -45,16 +46,12 @@ public class AltosRecordMM extends AltosRecord {
return raw / 4095.0;
}
- public double raw_pressure() {
+ public double pressure() {
if (pres != MISSING)
return pres;
return MISSING;
}
- public double filtered_pressure() {
- return raw_pressure();
- }
-
public double ground_pressure() {
if (ground_pres != MISSING)
return ground_pres;
@@ -98,9 +95,6 @@ public class AltosRecordMM extends AltosRecord {
}
public double acceleration() {
- if (acceleration != MISSING)
- return acceleration;
-
if (ground_accel == MISSING || accel == MISSING)
return MISSING;
@@ -110,10 +104,6 @@ public class AltosRecordMM extends AltosRecord {
return (ground_accel - accel) / accel_counts_per_mss();
}
- public double accel_speed() {
- return speed;
- }
-
public void copy (AltosRecordMM old) {
super.copy(old);
@@ -141,10 +131,10 @@ public class AltosRecordMM extends AltosRecord {
mag = old.mag;
}
+
+
public AltosRecordMM clone() {
- AltosRecordMM n = (AltosRecordMM) super.clone();
- n.copy(this);
- return n;
+ return new AltosRecordMM(this);
}
void make_missing() {
@@ -177,6 +167,10 @@ public class AltosRecordMM extends AltosRecord {
make_missing();
}
+ public AltosRecordMM(AltosRecordMM old) {
+ copy(old);
+ }
+
public AltosRecordMM() {
super();
make_missing();
diff --git a/altoslib/AltosRecordNone.java b/altoslib/AltosRecordNone.java
new file mode 100644
index 00000000..a95b6a9c
--- /dev/null
+++ b/altoslib/AltosRecordNone.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2012 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 AltosRecordNone extends AltosRecord {
+
+ public double pressure() { return MISSING; }
+ public double ground_pressure() { return MISSING; }
+ public double temperature() { return MISSING; }
+ public double acceleration() { return MISSING; }
+
+ public AltosRecordNone(AltosRecord old) {
+ super.copy(old);
+ }
+
+ public AltosRecordNone clone() {
+ return new AltosRecordNone(this);
+ }
+
+ public AltosRecordNone() {
+ super();
+ }
+}
diff --git a/altoslib/AltosRecordTM.java b/altoslib/AltosRecordTM.java
index 37accef6..c6cf3646 100644
--- a/altoslib/AltosRecordTM.java
+++ b/altoslib/AltosRecordTM.java
@@ -15,9 +15,11 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosRecordTM extends AltosRecord {
+
+ /* Sensor values */
public int accel;
public int pres;
public int temp;
@@ -57,18 +59,12 @@ public class AltosRecordTM extends AltosRecord {
return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0;
}
- public double raw_pressure() {
+ public double pressure() {
if (pres == MISSING)
return MISSING;
return barometer_to_pressure(pres);
}
- public double filtered_pressure() {
- if (flight_pres == MISSING)
- return MISSING;
- return barometer_to_pressure(flight_pres);
- }
-
public double ground_pressure() {
if (ground_pres == MISSING)
return MISSING;
@@ -121,22 +117,11 @@ public class AltosRecordTM extends AltosRecord {
}
public double acceleration() {
- if (acceleration != MISSING)
- return acceleration;
-
if (ground_accel == MISSING || accel == MISSING)
return MISSING;
return (ground_accel - accel) / accel_counts_per_mss();
}
- public double accel_speed() {
- if (speed != MISSING)
- return speed;
- if (flight_vel == MISSING)
- return MISSING;
- return flight_vel / (accel_counts_per_mss() * 100.0);
- }
-
public void copy(AltosRecordTM old) {
super.copy(old);
@@ -164,9 +149,7 @@ public class AltosRecordTM extends AltosRecord {
}
public AltosRecordTM clone() {
- AltosRecordTM n = (AltosRecordTM) super.clone();
- n.copy(this);
- return n;
+ return new AltosRecordTM(this);
}
void make_missing() {
@@ -192,6 +175,10 @@ public class AltosRecordTM extends AltosRecord {
make_missing();
}
+ public AltosRecordTM(AltosRecordTM old) {
+ copy(old);
+ }
+
public AltosRecordTM() {
super();
make_missing();
diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java
index 50bef07a..a7e30370 100644
--- a/altoslib/AltosReplayReader.java
+++ b/altoslib/AltosReplayReader.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.util.*;
diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java
new file mode 100644
index 00000000..0800a2c4
--- /dev/null
+++ b/altoslib/AltosRomconfig.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 2010 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.*;
+
+public class AltosRomconfig {
+ public boolean valid;
+ public int version;
+ public int check;
+ public int serial_number;
+ public int radio_calibration;
+
+ static int get_int(byte[] bytes, int start, int len) {
+ int v = 0;
+ int o = 0;
+ while (len > 0) {
+ v = v | ((((int) bytes[start]) & 0xff) << o);
+ start++;
+ len--;
+ o += 8;
+ }
+ return v;
+ }
+
+ static void put_int(int value, byte[] bytes, int start, int len) {
+ while (len > 0) {
+ bytes[start] = (byte) (value & 0xff);
+ start++;
+ len--;
+ value >>= 8;
+ }
+ }
+
+ static void put_string(String value, byte[] bytes, int start) {
+ for (int i = 0; i < value.length(); i++)
+ bytes[start + i] = (byte) value.charAt(i);
+ }
+
+ static final int AO_USB_DESC_STRING = 3;
+
+ static void put_usb_serial(int value, byte[] bytes, int start) {
+ int offset = start + 0xa;
+ int string_num = 0;
+
+ while (offset < bytes.length && bytes[offset] != 0) {
+ if (bytes[offset + 1] == AO_USB_DESC_STRING) {
+ ++string_num;
+ if (string_num == 4)
+ break;
+ }
+ offset += ((int) bytes[offset]) & 0xff;
+ }
+ if (offset >= bytes.length || bytes[offset] == 0)
+ return;
+ int len = ((((int) bytes[offset]) & 0xff) - 2) / 2;
+ String fmt = String.format("%%0%dd", len);
+
+ String s = String.format(fmt, value);
+ if (s.length() != len) {
+ System.out.printf("weird usb length issue %s isn't %d\n",
+ s, len);
+ return;
+ }
+ for (int i = 0; i < len; i++) {
+ bytes[offset + 2 + i*2] = (byte) s.charAt(i);
+ bytes[offset + 2 + i*2+1] = 0;
+ }
+ }
+
+ public AltosRomconfig(byte[] bytes, int offset) {
+ version = get_int(bytes, offset + 0, 2);
+ check = get_int(bytes, offset + 2, 2);
+ if (check == (~version & 0xffff)) {
+ switch (version) {
+ case 2:
+ case 1:
+ serial_number = get_int(bytes, offset + 4, 2);
+ radio_calibration = get_int(bytes, offset + 6, 4);
+ valid = true;
+ break;
+ }
+ }
+ }
+
+ public AltosRomconfig(AltosHexfile hexfile) {
+ this(hexfile.data, 0xa0 - hexfile.address);
+ }
+
+ public void write(byte[] bytes, int offset) throws IOException {
+ if (!valid)
+ throw new IOException("rom configuration invalid");
+
+ if (offset < 0 || bytes.length < offset + 10)
+ throw new IOException("image cannot contain rom config");
+
+ AltosRomconfig existing = new AltosRomconfig(bytes, offset);
+ if (!existing.valid)
+ throw new IOException("image does not contain existing rom config");
+
+ switch (existing.version) {
+ case 2:
+ put_usb_serial(serial_number, bytes, offset);
+ case 1:
+ put_int(serial_number, bytes, offset + 4, 2);
+ put_int(radio_calibration, bytes, offset + 6, 4);
+ break;
+ }
+ }
+
+ public void write (AltosHexfile hexfile) throws IOException {
+ write(hexfile.data, 0xa0 - hexfile.address);
+ AltosRomconfig check = new AltosRomconfig(hexfile);
+ if (!check.valid())
+ throw new IOException("writing new rom config failed\n");
+ }
+
+ public AltosRomconfig(int in_serial_number, int in_radio_calibration) {
+ valid = true;
+ version = 1;
+ check = (~version & 0xffff);
+ serial_number = in_serial_number;
+ radio_calibration = in_radio_calibration;
+ }
+
+ public boolean valid() {
+ return valid && serial_number != 0;
+ }
+
+ public AltosRomconfig() {
+ valid = false;
+ }
+}
diff --git a/altoslib/AltosSensorMM.java b/altoslib/AltosSensorMM.java
index b6f21ef0..6d1b61c0 100644
--- a/altoslib/AltosSensorMM.java
+++ b/altoslib/AltosSensorMM.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.TimeoutException;
@@ -28,75 +28,65 @@ class AltosSensorMM {
int accel_ref;
public AltosSensorMM(AltosLink link) throws InterruptedException, TimeoutException {
- link.printf("a\n");
- for (;;) {
- String line = link.get_reply_no_dialog(5000);
- if (line == null) {
- throw new TimeoutException();
+ String[] items = link.adc();
+ sense = new int[6];
+ for (int i = 0; i < items.length;) {
+ if (items[i].equals("tick:")) {
+ tick = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("0:")) {
+ sense[0] = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("1:")) {
+ sense[1] = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("2:")) {
+ sense[2] = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("3:")) {
+ sense[3] = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("4:")) {
+ sense[4] = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("5:")) {
+ sense[5] = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("6:")) {
+ v_batt = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("7:")) {
+ v_pyro = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("8:")) {
+ accel = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
}
- if (!line.startsWith("tick:"))
+ if (items[i].equals("9:")) {
+ accel_ref = Integer.parseInt(items[i+1]);
+ i += 2;
continue;
- String[] items = line.split("\\s+");
- sense = new int[6];
- for (int i = 0; i < items.length;) {
- if (items[i].equals("tick:")) {
- tick = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("0:")) {
- sense[0] = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("1:")) {
- sense[1] = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("2:")) {
- sense[2] = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("3:")) {
- sense[3] = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("4:")) {
- sense[4] = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("5:")) {
- sense[5] = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("6:")) {
- v_batt = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("7:")) {
- v_pyro = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("8:")) {
- accel = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("9:")) {
- accel_ref = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- i++;
}
- break;
+ i++;
}
}
}
diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java
index 75158cbf..754dc5bb 100644
--- a/altoslib/AltosSensorTM.java
+++ b/altoslib/AltosSensorTM.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.util.concurrent.TimeoutException;
@@ -23,54 +23,44 @@ class AltosSensorTM extends AltosRecordTM {
public AltosSensorTM(AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException {
super();
- link.printf("a\n");
- for (;;) {
- String line = link.get_reply_no_dialog(5000);
- if (line == null) {
- throw new TimeoutException();
+ String[] items = link.adc();
+ for (int i = 0; i < items.length;) {
+ if (items[i].equals("tick:")) {
+ tick = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("accel:")) {
+ accel = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("pres:")) {
+ pres = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("temp:")) {
+ temp = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("batt:")) {
+ batt = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
+ }
+ if (items[i].equals("drogue:")) {
+ drogue = Integer.parseInt(items[i+1]);
+ i += 2;
+ continue;
}
- if (!line.startsWith("tick:"))
+ if (items[i].equals("main:")) {
+ main = Integer.parseInt(items[i+1]);
+ i += 2;
continue;
- String[] items = line.split("\\s+");
- for (int i = 0; i < items.length;) {
- if (items[i].equals("tick:")) {
- tick = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("accel:")) {
- accel = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("pres:")) {
- pres = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("temp:")) {
- temp = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("batt:")) {
- batt = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("drogue:")) {
- drogue = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- if (items[i].equals("main:")) {
- main = Integer.parseInt(items[i+1]);
- i += 2;
- continue;
- }
- i++;
}
- break;
+ i++;
}
ground_accel = config_data.accel_cal_plus;
ground_pres = pres;
diff --git a/altoslib/AltosSpeed.java b/altoslib/AltosSpeed.java
index af63ed17..6fb624fb 100644
--- a/altoslib/AltosSpeed.java
+++ b/altoslib/AltosSpeed.java
@@ -15,29 +15,29 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosSpeed extends AltosUnits {
public double value(double v) {
if (AltosConvert.imperial_units)
- return AltosConvert.meters_to_feet(v);
+ return AltosConvert.meters_to_mph(v);
return v;
}
public String show_units() {
if (AltosConvert.imperial_units)
- return "ft/s";
+ return "mph";
return "m/s";
}
public String say_units() {
if (AltosConvert.imperial_units)
- return "feet per second";
+ return "miles per hour";
return "meters per second";
}
- int show_fraction(int width) {
+ public int show_fraction(int width) {
return width / 9;
}
} \ No newline at end of file
diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java
index 2e4d8870..825306be 100644
--- a/altoslib/AltosState.java
+++ b/altoslib/AltosState.java
@@ -19,7 +19,7 @@
* Track flight state from telemetry or eeprom data stream
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosState {
public AltosRecord data;
@@ -40,20 +40,21 @@ public class AltosState {
public double ground_altitude;
public double altitude;
public double height;
- public double speed;
public double acceleration;
public double battery;
public double temperature;
public double main_sense;
public double drogue_sense;
+ public double accel_speed;
public double baro_speed;
public double max_height;
public double max_acceleration;
- public double max_speed;
+ public double max_accel_speed;
public double max_baro_speed;
public AltosGPS gps;
+ public int gps_sequence;
public AltosIMU imu;
public AltosMag mag;
@@ -76,20 +77,50 @@ public class AltosState {
public int speak_tick;
public double speak_altitude;
- public void init (AltosRecord cur, AltosState prev_state) {
- //int i;
- //AltosRecord prev;
+ public double speed() {
+ if (ascent)
+ return accel_speed;
+ else
+ return baro_speed;
+ }
+
+ public double max_speed() {
+ if (max_accel_speed != 0)
+ return max_accel_speed;
+ return max_baro_speed;
+ }
+ public void init (AltosRecord cur, AltosState prev_state) {
data = cur;
+ /* Discard previous state if it was for a different board */
+ if (prev_state != null && prev_state.data.serial != data.serial)
+ prev_state = null;
ground_altitude = data.ground_altitude();
- altitude = data.raw_altitude();
- height = data.filtered_height();
+
+ altitude = data.altitude();
+ if (altitude == AltosRecord.MISSING && data.gps != null)
+ altitude = data.gps.alt;
+
+ height = AltosRecord.MISSING;
+ if (data.kalman_height != AltosRecord.MISSING)
+ height = data.kalman_height;
+ else {
+ if (altitude != AltosRecord.MISSING && ground_altitude != AltosRecord.MISSING) {
+ double cur_height = altitude - ground_altitude;
+ if (prev_state == null || prev_state.height == AltosRecord.MISSING)
+ height = cur_height;
+ else
+ height = (prev_state.height * 15 + cur_height) / 16.0;
+ }
+ }
report_time = System.currentTimeMillis();
- acceleration = data.acceleration();
- speed = data.accel_speed();
+ if (data.kalman_acceleration != AltosRecord.MISSING)
+ acceleration = data.kalman_acceleration;
+ else
+ acceleration = data.acceleration();
temperature = data.temperature();
drogue_sense = data.drogue_voltage();
main_sense = data.main_voltage();
@@ -103,12 +134,13 @@ public class AltosState {
npad = prev_state.npad;
ngps = prev_state.ngps;
gps = prev_state.gps;
+ gps_sequence = prev_state.gps_sequence;
pad_lat = prev_state.pad_lat;
pad_lon = prev_state.pad_lon;
pad_alt = prev_state.pad_alt;
max_height = prev_state.max_height;
max_acceleration = prev_state.max_acceleration;
- max_speed = prev_state.max_speed;
+ max_accel_speed = prev_state.max_accel_speed;
max_baro_speed = prev_state.max_baro_speed;
imu = prev_state.imu;
mag = prev_state.mag;
@@ -119,28 +151,58 @@ public class AltosState {
time_change = (tick - prev_state.tick) / 100.0;
- /* compute barometric speed */
+ if (data.kalman_speed != AltosRecord.MISSING) {
+ baro_speed = accel_speed = data.kalman_speed;
+ } else {
+ /* compute barometric speed */
+
+ double height_change = height - prev_state.height;
+
+ double prev_baro_speed = prev_state.baro_speed;
+ if (prev_baro_speed == AltosRecord.MISSING)
+ prev_baro_speed = 0;
- double height_change = height - prev_state.height;
- if (data.speed != AltosRecord.MISSING)
- baro_speed = data.speed;
- else {
if (time_change > 0)
- baro_speed = (prev_state.baro_speed * 3 + (height_change / time_change)) / 4.0;
+ baro_speed = (prev_baro_speed * 3 + (height_change / time_change)) / 4.0;
else
baro_speed = prev_state.baro_speed;
+
+ double prev_accel_speed = prev_state.accel_speed;
+
+ if (prev_accel_speed == AltosRecord.MISSING)
+ prev_accel_speed = 0;
+
+ if (acceleration == AltosRecord.MISSING) {
+ /* Fill in mising acceleration value */
+ accel_speed = baro_speed;
+
+ if (time_change > 0 && accel_speed != AltosRecord.MISSING)
+ acceleration = (accel_speed - prev_accel_speed) / time_change;
+ else
+ acceleration = prev_state.acceleration;
+ } else {
+ /* compute accelerometer speed */
+ accel_speed = prev_accel_speed + acceleration * time_change;
+ }
}
} else {
npad = 0;
ngps = 0;
gps = null;
- baro_speed = 0;
+ gps_sequence = 0;
+ baro_speed = AltosRecord.MISSING;
+ accel_speed = AltosRecord.MISSING;
+ pad_alt = AltosRecord.MISSING;
+ max_baro_speed = 0;
+ max_accel_speed = 0;
+ max_height = 0;
+ max_acceleration = 0;
time_change = 0;
}
time = tick / 100.0;
- if (cur.new_gps && (state == AltosLib.ao_flight_pad || state == AltosLib.ao_flight_idle)) {
+ if (data.gps != null && data.gps_sequence != gps_sequence && (state < AltosLib.ao_flight_boost)) {
/* Track consecutive 'good' gps reports, waiting for 10 of them */
if (data.gps != null && data.gps.locked && data.gps.nsat >= 4)
@@ -150,7 +212,7 @@ public class AltosState {
/* Average GPS data while on the pad */
if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) {
- if (ngps > 1) {
+ if (ngps > 1 && state == AltosLib.ao_flight_pad) {
/* filter pad position */
pad_lat = (pad_lat * 31.0 + data.gps.lat) / 32.0;
pad_lon = (pad_lon * 31.0 + data.gps.lon) / 32.0;
@@ -162,10 +224,12 @@ public class AltosState {
}
ngps++;
}
- } else
- pad_alt = ground_altitude;
+ } else {
+ if (ngps == 0 && ground_altitude != AltosRecord.MISSING)
+ pad_alt = ground_altitude;
+ }
- data.new_gps = false;
+ gps_sequence = data.gps_sequence;
gps_waiting = MIN_PAD_SAMPLES - npad;
if (gps_waiting < 0)
@@ -178,32 +242,29 @@ public class AltosState {
boost = (AltosLib.ao_flight_boost == state);
/* Only look at accelerometer data under boost */
- if (boost && acceleration > max_acceleration && acceleration != AltosRecord.MISSING)
+ if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration))
max_acceleration = acceleration;
- if (boost && speed > max_speed && speed != AltosRecord.MISSING)
- max_speed = speed;
- if (boost && baro_speed > max_baro_speed && baro_speed != AltosRecord.MISSING)
+ if (boost && accel_speed != AltosRecord.MISSING && accel_speed > max_accel_speed)
+ max_accel_speed = accel_speed;
+ if (boost && baro_speed != AltosRecord.MISSING && baro_speed > max_baro_speed)
max_baro_speed = baro_speed;
- if (height > max_height && height != AltosRecord.MISSING)
+ if (height != AltosRecord.MISSING && height > max_height)
max_height = height;
- if (data.gps != null) {
- if (gps == null || !gps.locked || data.gps.locked)
- gps = data.gps;
- if (ngps > 0 && gps.locked) {
- from_pad = new AltosGreatCircle(pad_lat, pad_lon, gps.lat, gps.lon);
- }
- }
elevation = 0;
range = -1;
- if (ngps > 0) {
- gps_height = gps.alt - pad_alt;
- if (from_pad != null) {
- elevation = Math.atan2(height, from_pad.distance) * 180 / Math.PI;
- range = Math.sqrt(height * height + from_pad.distance * from_pad.distance);
+ gps_height = 0;
+ if (data.gps != null) {
+ gps = data.gps;
+ if (ngps > 0 && gps.locked) {
+ double h = height;
+
+ if (h == AltosRecord.MISSING) h = 0;
+ from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h);
+ elevation = from_pad.elevation;
+ range = from_pad.range;
+ gps_height = gps.alt - pad_alt;
}
- } else {
- gps_height = 0;
}
}
diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java
index 15534158..e7322349 100644
--- a/altoslib/AltosTelemetry.java
+++ b/altoslib/AltosTelemetry.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java
index e95c15e0..57033638 100644
--- a/altoslib/AltosTelemetryIterable.java
+++ b/altoslib/AltosTelemetryIterable.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.io.*;
import java.util.*;
diff --git a/altoslib/AltosTelemetryMap.java b/altoslib/AltosTelemetryMap.java
index bc1486d8..7cca98b0 100644
--- a/altoslib/AltosTelemetryMap.java
+++ b/altoslib/AltosTelemetryMap.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
import java.util.HashMap;
diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java
index 94fa560b..b4293c73 100644
--- a/altoslib/AltosTelemetryReader.java
+++ b/altoslib/AltosTelemetryReader.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
import java.io.*;
@@ -107,6 +107,14 @@ public class AltosTelemetryReader extends AltosFlightReader {
return log.file();
}
+ public boolean has_monitor_battery() {
+ return link.has_monitor_battery();
+ }
+
+ public double monitor_battery() {
+ return link.monitor_battery();
+ }
+
public AltosTelemetryReader (AltosLink in_link)
throws IOException, InterruptedException, TimeoutException {
link = in_link;
diff --git a/altoslib/AltosTelemetryRecord.java b/altoslib/AltosTelemetryRecord.java
index 6a8cfd35..fdc3c88e 100644
--- a/altoslib/AltosTelemetryRecord.java
+++ b/altoslib/AltosTelemetryRecord.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
public abstract class AltosTelemetryRecord {
@@ -80,25 +80,25 @@ public abstract class AltosTelemetryRecord {
r = new AltosTelemetryRecordSensor(bytes, rssi);
break;
case packet_type_configuration:
- r = new AltosTelemetryRecordConfiguration(bytes);
+ r = new AltosTelemetryRecordConfiguration(bytes, rssi);
break;
case packet_type_location:
- r = new AltosTelemetryRecordLocation(bytes);
+ r = new AltosTelemetryRecordLocation(bytes, rssi);
break;
case packet_type_satellite:
- r = new AltosTelemetryRecordSatellite(bytes);
+ r = new AltosTelemetryRecordSatellite(bytes, rssi);
break;
case packet_type_companion:
- r = new AltosTelemetryRecordCompanion(bytes);
+ r = new AltosTelemetryRecordCompanion(bytes, rssi);
break;
case packet_type_MM_sensor:
r = new AltosTelemetryRecordMegaSensor(bytes, rssi);
break;
case packet_type_MM_data:
- r = new AltosTelemetryRecordMegaData(bytes);
+ r = new AltosTelemetryRecordMegaData(bytes, rssi);
break;
default:
- r = new AltosTelemetryRecordRaw(bytes);
+ r = new AltosTelemetryRecordRaw(bytes, rssi);
break;
}
break;
diff --git a/altoslib/AltosTelemetryRecordCompanion.java b/altoslib/AltosTelemetryRecordCompanion.java
index 6ad17244..2231df13 100644
--- a/altoslib/AltosTelemetryRecordCompanion.java
+++ b/altoslib/AltosTelemetryRecordCompanion.java
@@ -15,14 +15,14 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordCompanion extends AltosTelemetryRecordRaw {
AltosRecordCompanion companion;
- public AltosTelemetryRecordCompanion(int[] in_bytes) {
- super(in_bytes);
+ public AltosTelemetryRecordCompanion(int[] in_bytes, int rssi) {
+ super(in_bytes, rssi);
int off = 0;
if (uint8(6) == 0)
diff --git a/altoslib/AltosTelemetryRecordConfiguration.java b/altoslib/AltosTelemetryRecordConfiguration.java
index 25242edc..47fc3488 100644
--- a/altoslib/AltosTelemetryRecordConfiguration.java
+++ b/altoslib/AltosTelemetryRecordConfiguration.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordConfiguration extends AltosTelemetryRecordRaw {
@@ -29,8 +29,8 @@ public class AltosTelemetryRecordConfiguration extends AltosTelemetryRecordRaw {
String callsign;
String version;
- public AltosTelemetryRecordConfiguration(int[] in_bytes) {
- super(in_bytes);
+ public AltosTelemetryRecordConfiguration(int[] in_bytes, int rssi) {
+ super(in_bytes, rssi);
device_type = uint8(5);
flight = uint16(6);
diff --git a/altoslib/AltosTelemetryRecordGeneral.java b/altoslib/AltosTelemetryRecordGeneral.java
index a53280cf..08cd6065 100644
--- a/altoslib/AltosTelemetryRecordGeneral.java
+++ b/altoslib/AltosTelemetryRecordGeneral.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
diff --git a/altoslib/AltosTelemetryRecordLegacy.java b/altoslib/AltosTelemetryRecordLegacy.java
index 21176069..f2d3f868 100644
--- a/altoslib/AltosTelemetryRecordLegacy.java
+++ b/altoslib/AltosTelemetryRecordLegacy.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
import java.text.*;
@@ -257,9 +257,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord {
record.accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosRecord.MISSING);
/* flight computer values */
- record.acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0);
- record.speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0);
- record.height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING);
+ record.kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0);
+ record.kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0);
+ record.kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING);
record.flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosRecord.MISSING);
record.flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosRecord.MISSING);
@@ -267,7 +267,7 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord {
if (map.has(AO_TELEM_GPS_STATE)) {
record.gps = new AltosGPS(map);
- record.new_gps = true;
+ record.gps_sequence++;
}
else
record.gps = null;
@@ -334,9 +334,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord {
/* Old TeleDongle code with kalman-reporting TeleMetrum code */
if ((record.flight_vel & 0xffff0000) == 0x80000000) {
- record.speed = ((short) record.flight_vel) / 16.0;
- record.acceleration = record.flight_accel / 16.0;
- record.height = record.flight_pres;
+ record.kalman_speed = ((short) record.flight_vel) / 16.0;
+ record.kalman_acceleration = record.flight_accel / 16.0;
+ record.kalman_height = record.flight_pres;
record.flight_vel = AltosRecord.MISSING;
record.flight_pres = AltosRecord.MISSING;
record.flight_accel = AltosRecord.MISSING;
@@ -357,7 +357,7 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord {
}
record.gps = new AltosGPS(words, i, record.version);
- record.new_gps = true;
+ record.gps_sequence++;
}
public AltosTelemetryRecordLegacy(String line) throws ParseException, AltosCRCException {
@@ -455,9 +455,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord {
record.accel_minus_g = int16(19);
if (uint16(11) == 0x8000) {
- record.acceleration = int16(5);
- record.speed = int16(9);
- record.height = int16(13);
+ record.kalman_acceleration = int16(5);
+ record.kalman_speed = int16(9);
+ record.kalman_height = int16(13);
record.flight_accel = AltosRecord.MISSING;
record.flight_vel = AltosRecord.MISSING;
record.flight_pres = AltosRecord.MISSING;
@@ -465,9 +465,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord {
record.flight_accel = int16(5);
record.flight_vel = uint32(9);
record.flight_pres = int16(13);
- record.acceleration = AltosRecord.MISSING;
- record.speed = AltosRecord.MISSING;
- record.height = AltosRecord.MISSING;
+ record.kalman_acceleration = AltosRecord.MISSING;
+ record.kalman_speed = AltosRecord.MISSING;
+ record.kalman_height = AltosRecord.MISSING;
}
record.gps = null;
@@ -476,7 +476,7 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord {
if ((gps_flags & (AO_GPS_VALID|AO_GPS_RUNNING)) != 0) {
record.gps = new AltosGPS();
- record.new_gps = true;
+ record.gps_sequence++;
record.seen |= AltosRecord.seen_gps_time | AltosRecord.seen_gps_lat | AltosRecord.seen_gps_lon;
record.gps.nsat = (gps_flags & AO_GPS_NUM_SAT_MASK);
diff --git a/altoslib/AltosTelemetryRecordLocation.java b/altoslib/AltosTelemetryRecordLocation.java
index cddb773d..0236d291 100644
--- a/altoslib/AltosTelemetryRecordLocation.java
+++ b/altoslib/AltosTelemetryRecordLocation.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordLocation extends AltosTelemetryRecordRaw {
@@ -37,8 +37,8 @@ public class AltosTelemetryRecordLocation extends AltosTelemetryRecordRaw {
int climb_rate;
int course;
- public AltosTelemetryRecordLocation(int[] in_bytes) {
- super(in_bytes);
+ public AltosTelemetryRecordLocation(int[] in_bytes, int rssi) {
+ super(in_bytes, rssi);
flags = uint8(5);
altitude = int16(6);
@@ -85,7 +85,7 @@ public class AltosTelemetryRecordLocation extends AltosTelemetryRecordRaw {
next.gps.hdop = hdop;
next.gps.vdop = vdop;
next.seen |= AltosRecord.seen_gps_time | AltosRecord.seen_gps_lat | AltosRecord.seen_gps_lon;
- next.new_gps = true;
+ next.gps_sequence++;
}
return next;
diff --git a/altoslib/AltosTelemetryRecordMegaData.java b/altoslib/AltosTelemetryRecordMegaData.java
index 8f55d238..a484ef4e 100644
--- a/altoslib/AltosTelemetryRecordMegaData.java
+++ b/altoslib/AltosTelemetryRecordMegaData.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw {
@@ -35,8 +35,8 @@ public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw {
int speed;
int height;
- public AltosTelemetryRecordMegaData(int[] in_bytes) {
- super(in_bytes);
+ public AltosTelemetryRecordMegaData(int[] in_bytes, int rssi) {
+ super(in_bytes, rssi);
state = int8(5);
@@ -83,11 +83,11 @@ public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw {
next.accel_plus_g = accel_plus_g;
next.accel_minus_g = accel_minus_g;
- next.acceleration = acceleration / 16.0;
- next.speed = speed / 16.0;
- next.height = height;
+ next.kalman_acceleration = acceleration / 16.0;
+ next.kalman_speed = speed / 16.0;
+ next.kalman_height = height;
- next.seen |= AltosRecord.seen_flight | AltosRecord.seen_temp_volt;
+ next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt;
return next;
}
diff --git a/altoslib/AltosTelemetryRecordMegaSensor.java b/altoslib/AltosTelemetryRecordMegaSensor.java
index 93c001de..2a4b17a4 100644
--- a/altoslib/AltosTelemetryRecordMegaSensor.java
+++ b/altoslib/AltosTelemetryRecordMegaSensor.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordMegaSensor extends AltosTelemetryRecordRaw {
@@ -35,10 +35,8 @@ public class AltosTelemetryRecordMegaSensor extends AltosTelemetryRecordRaw {
int mag_y;
int mag_z;
- int rssi;
-
- public AltosTelemetryRecordMegaSensor(int[] in_bytes, int in_rssi) {
- super(in_bytes);
+ public AltosTelemetryRecordMegaSensor(int[] in_bytes, int rssi) {
+ super(in_bytes, rssi);
accel = int16(6);
pres = int32(8);
@@ -55,8 +53,6 @@ public class AltosTelemetryRecordMegaSensor extends AltosTelemetryRecordRaw {
mag_x = int16(26);
mag_y = int16(28);
mag_z = int16(30);
-
- rssi = in_rssi;
}
public AltosRecord update_state(AltosRecord previous) {
@@ -85,8 +81,6 @@ public class AltosTelemetryRecordMegaSensor extends AltosTelemetryRecordRaw {
next.mag.y = mag_y;
next.mag.z = mag_z;
- next.rssi = rssi;
-
next.seen |= AltosRecord.seen_sensor;
return next;
diff --git a/altoslib/AltosTelemetryRecordRaw.java b/altoslib/AltosTelemetryRecordRaw.java
index fbb373d5..f94789bb 100644
--- a/altoslib/AltosTelemetryRecordRaw.java
+++ b/altoslib/AltosTelemetryRecordRaw.java
@@ -15,13 +15,14 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordRaw extends AltosTelemetryRecord {
int[] bytes;
int serial;
int tick;
int type;
+ int rssi;
long received_time;
@@ -53,21 +54,24 @@ public class AltosTelemetryRecordRaw extends AltosTelemetryRecord {
return AltosLib.string(bytes, off + 1, l);
}
- public AltosTelemetryRecordRaw(int[] in_bytes) {
+ public AltosTelemetryRecordRaw(int[] in_bytes, int in_rssi) {
bytes = in_bytes;
serial = uint16(0);
tick = uint16(2);
type = uint8(4);
+ rssi = in_rssi;
}
public AltosRecord update_state(AltosRecord previous) {
AltosRecord next;
- if (previous != null)
+
+ if (previous != null && previous.serial == serial)
next = previous.clone();
else
- next = new AltosRecord();
+ next = new AltosRecordNone();
next.serial = serial;
next.tick = tick;
+ next.rssi = rssi;
return next;
}
diff --git a/altoslib/AltosTelemetryRecordSatellite.java b/altoslib/AltosTelemetryRecordSatellite.java
index 2526afb6..9835389b 100644
--- a/altoslib/AltosTelemetryRecordSatellite.java
+++ b/altoslib/AltosTelemetryRecordSatellite.java
@@ -15,14 +15,14 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordSatellite extends AltosTelemetryRecordRaw {
int channels;
AltosGPSSat[] sats;
- public AltosTelemetryRecordSatellite(int[] in_bytes) {
- super(in_bytes);
+ public AltosTelemetryRecordSatellite(int[] in_bytes, int rssi) {
+ super(in_bytes, rssi);
channels = uint8(5);
if (channels > 12)
diff --git a/altoslib/AltosTelemetryRecordSensor.java b/altoslib/AltosTelemetryRecordSensor.java
index 319a91b3..e0e92c13 100644
--- a/altoslib/AltosTelemetryRecordSensor.java
+++ b/altoslib/AltosTelemetryRecordSensor.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw {
@@ -36,10 +36,8 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw {
int accel_plus_g;
int accel_minus_g;
- int rssi;
-
- public AltosTelemetryRecordSensor(int[] in_bytes, int in_rssi) {
- super(in_bytes);
+ public AltosTelemetryRecordSensor(int[] in_bytes, int rssi) {
+ super(in_bytes, rssi);
state = uint8(5);
accel = int16(6);
@@ -57,8 +55,6 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw {
ground_accel = int16(26);
accel_plus_g = int16(28);
accel_minus_g = int16(30);
-
- rssi = in_rssi;
}
public AltosRecord update_state(AltosRecord prev) {
@@ -86,9 +82,9 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw {
next.main = AltosRecord.MISSING;
}
- next.acceleration = acceleration / 16.0;
- next.speed = speed / 16.0;
- next.height = height;
+ next.kalman_acceleration = acceleration / 16.0;
+ next.kalman_speed = speed / 16.0;
+ next.kalman_height = height;
next.ground_pres = ground_pres;
if (type == packet_type_TM_sensor) {
@@ -101,8 +97,6 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw {
next.accel_minus_g = AltosRecord.MISSING;
}
- next.rssi = rssi;
-
next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt;
return next;
diff --git a/altoslib/AltosTemperature.java b/altoslib/AltosTemperature.java
new file mode 100644
index 00000000..2749eac0
--- /dev/null
+++ b/altoslib/AltosTemperature.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2012 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 AltosTemperature extends AltosUnits {
+
+ public double value(double v) {
+ if (AltosConvert.imperial_units)
+ return AltosConvert.c_to_f(v);
+ return v;
+ }
+
+ public String show_units() {
+ if (AltosConvert.imperial_units)
+ return "°F";
+ return "°C";
+ }
+
+ public String say_units() {
+ if (AltosConvert.imperial_units)
+ return "degrees farenheit";
+ return "degrees celsius";
+ }
+
+ public int show_fraction(int width) {
+ return width / 3;
+ }
+}
diff --git a/altoslib/AltosUnits.java b/altoslib/AltosUnits.java
index 47540c61..b8b3254c 100644
--- a/altoslib/AltosUnits.java
+++ b/altoslib/AltosUnits.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.AltosLib;
+package org.altusmetrum.altoslib_1;
public abstract class AltosUnits {
@@ -25,7 +25,7 @@ public abstract class AltosUnits {
public abstract String say_units();
- abstract int show_fraction(int width);
+ public abstract int show_fraction(int width);
int say_fraction() {
return 0;
@@ -43,6 +43,10 @@ public abstract class AltosUnits {
return String.format("%%1.%df %s", say_fraction(), say_units());
}
+ public String graph_format(int width) {
+ return String.format(String.format("%%%d.%df", width, show_fraction(width)), 0.0);
+ }
+
public String show(int width, double v) {
return String.format(show_format(width), value(v));
}
diff --git a/altoslib/AltosUnitsListener.java b/altoslib/AltosUnitsListener.java
new file mode 100644
index 00000000..61a181a4
--- /dev/null
+++ b/altoslib/AltosUnitsListener.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright © 2012 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 interface AltosUnitsListener {
+ public void units_changed(boolean imperial_units);
+}
diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am
index a9f810f9..18b028d6 100644
--- a/altoslib/Makefile.am
+++ b/altoslib/Makefile.am
@@ -2,94 +2,107 @@ AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation
JAVAROOT=bin
+VERSION=1
+
CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH="bin:$(FREETTS)/*:/usr/share/java/*"
SRC=.
-BIN=bin/org/altusmetrum/AltosLib
-AltosLibdir = $(datadir)/java
+altoslibdir = $(datadir)/java
-AltosLib_JAVA = \
- $(SRC)/AltosLib.java \
- $(SRC)/AltosConfigData.java \
- $(SRC)/AltosConvert.java \
- $(SRC)/AltosCRCException.java \
- $(SRC)/AltosEepromChunk.java \
- $(SRC)/AltosEepromIterable.java \
- $(SRC)/AltosEepromLog.java \
- $(SRC)/AltosEepromMega.java \
- $(SRC)/AltosEepromMegaIterable.java \
- $(SRC)/AltosEepromRecord.java \
- $(SRC)/AltosEepromTeleScience.java \
- $(SRC)/AltosFile.java \
- $(SRC)/AltosFlightReader.java \
- $(SRC)/AltosFrequency.java \
- $(SRC)/AltosGPS.java \
- $(SRC)/AltosGPSQuery.java \
- $(SRC)/AltosGPSSat.java \
- $(SRC)/AltosGreatCircle.java \
- $(SRC)/AltosIdleMonitor.java \
- $(SRC)/AltosIdleMonitorListener.java \
- $(SRC)/AltosIgnite.java \
- $(SRC)/AltosIMU.java \
- $(SRC)/AltosIMUQuery.java \
- $(SRC)/AltosLine.java \
- $(SRC)/AltosLink.java \
- $(SRC)/AltosLog.java \
- $(SRC)/AltosMs5607.java \
- $(SRC)/AltosMs5607Query.java \
- $(SRC)/AltosOrderedRecord.java \
- $(SRC)/AltosOrderedMegaRecord.java \
- $(SRC)/AltosParse.java \
- $(SRC)/AltosPreferences.java \
- $(SRC)/AltosRecordCompanion.java \
- $(SRC)/AltosRecordIterable.java \
- $(SRC)/AltosRecord.java \
- $(SRC)/AltosRecordTM.java \
- $(SRC)/AltosRecordMM.java \
- $(SRC)/AltosReplayReader.java \
- $(SRC)/AltosSensorMM.java \
- $(SRC)/AltosSensorTM.java \
- $(SRC)/AltosState.java \
- $(SRC)/AltosTelemetry.java \
- $(SRC)/AltosTelemetryIterable.java \
- $(SRC)/AltosTelemetryMap.java \
- $(SRC)/AltosTelemetryReader.java \
- $(SRC)/AltosTelemetryRecordCompanion.java \
- $(SRC)/AltosTelemetryRecordConfiguration.java \
- $(SRC)/AltosTelemetryRecordGeneral.java \
- $(SRC)/AltosTelemetryRecord.java \
- $(SRC)/AltosTelemetryRecordLegacy.java \
- $(SRC)/AltosTelemetryRecordLocation.java \
- $(SRC)/AltosTelemetryRecordRaw.java \
- $(SRC)/AltosTelemetryRecordSatellite.java \
- $(SRC)/AltosTelemetryRecordSensor.java \
- $(SRC)/AltosTelemetryRecordMegaSensor.java \
- $(SRC)/AltosTelemetryRecordMegaData.java \
- $(SRC)/AltosMs5607.java \
- $(SRC)/AltosIMU.java \
- $(SRC)/AltosMag.java \
- $(SRC)/AltosUnits.java \
- $(SRC)/AltosDistance.java \
- $(SRC)/AltosHeight.java \
- $(SRC)/AltosSpeed.java \
- $(SRC)/AltosAccel.java
+altoslib_JAVA = \
+ AltosLib.java \
+ AltosConfigData.java \
+ AltosConfigValues.java \
+ AltosConvert.java \
+ AltosCRCException.java \
+ AltosDebug.java \
+ AltosEepromChunk.java \
+ AltosEepromIterable.java \
+ AltosEepromLog.java \
+ AltosEepromMega.java \
+ AltosEepromMegaIterable.java \
+ AltosEepromRecord.java \
+ AltosEepromTeleScience.java \
+ AltosFile.java \
+ AltosFlash.java \
+ AltosFlashListener.java \
+ AltosFlightReader.java \
+ AltosFrequency.java \
+ AltosGPS.java \
+ AltosGPSQuery.java \
+ AltosGPSSat.java \
+ AltosGreatCircle.java \
+ AltosHexfile.java \
+ AltosIdleMonitor.java \
+ AltosIdleMonitorListener.java \
+ AltosIgnite.java \
+ AltosIMU.java \
+ AltosIMUQuery.java \
+ AltosLine.java \
+ AltosLink.java \
+ AltosListenerState.java \
+ AltosLog.java \
+ AltosMs5607.java \
+ AltosMs5607Query.java \
+ AltosOrderedRecord.java \
+ AltosOrderedMegaRecord.java \
+ AltosParse.java \
+ AltosPreferences.java \
+ AltosPreferencesBackend.java \
+ AltosRecordCompanion.java \
+ AltosRecordIterable.java \
+ AltosRecord.java \
+ AltosRecordNone.java \
+ AltosRecordTM.java \
+ AltosRecordMM.java \
+ AltosReplayReader.java \
+ AltosRomconfig.java \
+ AltosSensorMM.java \
+ AltosSensorTM.java \
+ AltosState.java \
+ AltosTelemetry.java \
+ AltosTelemetryIterable.java \
+ AltosTelemetryMap.java \
+ AltosTelemetryReader.java \
+ AltosTelemetryRecordCompanion.java \
+ AltosTelemetryRecordConfiguration.java \
+ AltosTelemetryRecordGeneral.java \
+ AltosTelemetryRecord.java \
+ AltosTelemetryRecordLegacy.java \
+ AltosTelemetryRecordLocation.java \
+ AltosTelemetryRecordRaw.java \
+ AltosTelemetryRecordSatellite.java \
+ AltosTelemetryRecordSensor.java \
+ AltosTelemetryRecordMegaSensor.java \
+ AltosTelemetryRecordMegaData.java \
+ AltosUnitsListener.java \
+ AltosMs5607.java \
+ AltosIMU.java \
+ AltosMag.java \
+ AltosUnits.java \
+ AltosDistance.java \
+ AltosHeight.java \
+ AltosSpeed.java \
+ AltosTemperature.java \
+ AltosAccel.java \
+ AltosPyro.java
-JAR=AltosLib.jar
+JAR=altoslib_$(ALTOSLIB_VERSION).jar
all-local: $(JAR)
clean-local:
-rm -rf bin $(JAR)
-install-AltosLibJAVA: $(JAR)
+install-altoslibJAVA: $(JAR)
@$(NORMAL_INSTALL)
- test -z "$(AltosLibdir)" || $(MKDIR_P) "$(DESTDIR)$(AltosLibdir)"
- echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(AltosLibdir)/$(JAR)"; \
- $(INSTALL_DATA) "$<" "$(DESTDIR)$(AltosLibdir)"
+ test -z "$(altoslibdir)" || $(MKDIR_P) "$(DESTDIR)$(altoslibdir)"
+ echo " $(INSTALL_DATA)" "$<" "'$(DESTDIR)$(altoslibdir)/$(JAR)"; \
+ $(INSTALL_DATA) "$<" "$(DESTDIR)$(altoslibdir)"
bin:
mkdir -p bin
-$(JAR): classAltosLib.stamp
+$(JAR): classaltoslib.stamp
jar cf $@ -C bin org