diff options
Diffstat (limited to 'altoslib')
98 files changed, 1620 insertions, 215 deletions
diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java index 43dc20bd..3d340e5d 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_3; +package org.altusmetrum.altoslib_4; public class AltosAccel extends AltosUnits { diff --git a/altoslib/AltosCRCException.java b/altoslib/AltosCRCException.java index 94962731..253ca435 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_3; +package org.altusmetrum.altoslib_4; public class AltosCRCException extends Exception { public int rssi; diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java new file mode 100644 index 00000000..27e1fade --- /dev/null +++ b/altoslib/AltosCSV.java @@ -0,0 +1,334 @@ +/* + * 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_4; + +import java.io.*; +import java.util.*; + +public class AltosCSV implements AltosWriter { + File name; + PrintStream out; + boolean header_written; + boolean seen_boost; + int boost_tick; + LinkedList<AltosState> pad_states; + AltosState state; + + static final int ALTOS_CSV_VERSION = 5; + + /* Version 4 format: + * + * General info + * version number + * serial number + * flight number + * callsign + * time (seconds since boost) + * clock (tick count / 100) + * rssi + * link quality + * + * Flight status + * state + * state name + * + * Basic sensors + * acceleration (m/s²) + * pressure (mBar) + * altitude (m) + * height (m) + * accelerometer speed (m/s) + * barometer speed (m/s) + * temp (°C) + * battery (V) + * drogue (V) + * main (V) + * + * Advanced sensors (if available) + * accel_x (m/s²) + * accel_y (m/s²) + * accel_z (m/s²) + * gyro_x (d/s) + * gyro_y (d/s) + * gyro_z (d/s) + * mag_x (g) + * mag_y (g) + * mag_z (g) + * + * GPS data (if available) + * connected (1/0) + * locked (1/0) + * nsat (used for solution) + * latitude (°) + * longitude (°) + * altitude (m) + * year (e.g. 2010) + * month (1-12) + * day (1-31) + * hour (0-23) + * minute (0-59) + * second (0-59) + * from_pad_dist (m) + * from_pad_azimuth (deg true) + * from_pad_range (m) + * from_pad_elevation (deg from horizon) + * hdop + * + * GPS Sat data + * C/N0 data for all 32 valid SDIDs + * + * Companion data + * companion_id (1-255. 10 is TeleScience) + * time of last companion data (seconds since boost) + * update_period (0.1-2.55 minimum telemetry interval) + * channels (0-12) + * channel data for all 12 possible channels + */ + + void write_general_header() { + out.printf("version,serial,flight,call,time,clock,rssi,lqi"); + } + + void write_general(AltosState state) { + out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d", + ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign, + (double) state.time, (double) state.tick / 100.0, + state.rssi, + state.status & 0x7f); + } + + void write_flight_header() { + out.printf("state,state_name"); + } + + void write_flight(AltosState state) { + out.printf("%d,%8s", state.state, state.state_name()); + } + + void write_basic_header() { + out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,battery_voltage,drogue_voltage,main_voltage"); + } + + void write_basic(AltosState state) { + out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f,%5.2f", + state.acceleration(), + state.pressure(), + state.altitude(), + state.height(), + state.speed(), + state.speed(), + state.temperature, + state.battery_voltage, + state.apogee_voltage, + state.main_voltage); + } + + void write_advanced_header() { + out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z"); + } + + void write_advanced(AltosState state) { + AltosIMU imu = state.imu; + AltosMag mag = state.mag; + + if (imu == null) + imu = new AltosIMU(); + if (mag == null) + mag = new AltosMag(); + out.printf("%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d", + imu.accel_x, imu.accel_y, imu.accel_z, + imu.gyro_x, imu.gyro_y, imu.gyro_z, + mag.x, mag.y, mag.z); + } + + void write_gps_header() { + out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,hdop"); + } + + void write_gps(AltosState state) { + AltosGPS gps = state.gps; + if (gps == null) + gps = new AltosGPS(); + + AltosGreatCircle from_pad = state.from_pad; + if (from_pad == null) + from_pad = new AltosGreatCircle(); + + out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f", + gps.connected?1:0, + gps.locked?1:0, + gps.nsat, + gps.lat, + gps.lon, + gps.alt, + gps.year, + gps.month, + gps.day, + gps.hour, + gps.minute, + gps.second, + from_pad.distance, + state.range, + from_pad.bearing, + state.elevation, + gps.hdop); + } + + void write_gps_sat_header() { + for(int i = 1; i <= 32; i++) { + out.printf("sat%02d", i); + if (i != 32) + out.printf(","); + } + } + + void write_gps_sat(AltosState state) { + AltosGPS gps = state.gps; + for(int i = 1; i <= 32; i++) { + int c_n0 = 0; + if (gps != null && gps.cc_gps_sat != null) { + for(int j = 0; j < gps.cc_gps_sat.length; j++) + if (gps.cc_gps_sat[j].svid == i) { + c_n0 = gps.cc_gps_sat[j].c_n0; + break; + } + } + out.printf ("%3d", c_n0); + if (i != 32) + out.printf(","); + } + } + + void write_companion_header() { + out.printf("companion_id,companion_time,companion_update,companion_channels"); + for (int i = 0; i < 12; i++) + out.printf(",companion_%02d", i); + } + + void write_companion(AltosState state) { + AltosCompanion companion = state.companion; + + int channels_written = 0; + if (companion == null) { + out.printf("0,0,0,0"); + } else { + out.printf("%3d,%5.2f,%5.2f,%2d", + companion.board_id, + (companion.tick - boost_tick) / 100.0, + companion.update_period / 100.0, + companion.channels); + for (; channels_written < companion.channels; channels_written++) + out.printf(",%5d", companion.companion_data[channels_written]); + } + for (; channels_written < 12; channels_written++) + out.printf(",0"); + } + + void write_header(boolean advanced, boolean gps, boolean companion) { + out.printf("#"); write_general_header(); + out.printf(","); write_flight_header(); + out.printf(","); write_basic_header(); + if (advanced) + out.printf(","); write_advanced_header(); + if (gps) { + out.printf(","); write_gps_header(); + out.printf(","); write_gps_sat_header(); + } + if (companion) { + out.printf(","); write_companion_header(); + } + out.printf ("\n"); + } + + void write_one(AltosState state) { + write_general(state); out.printf(","); + write_flight(state); out.printf(","); + write_basic(state); out.printf(","); + if (state.imu != null || state.mag != null) + write_advanced(state); + if (state.gps != null) { + out.printf(","); + write_gps(state); out.printf(","); + write_gps_sat(state); + } + if (state.companion != null) { + out.printf(","); + write_companion(state); + } + out.printf ("\n"); + } + + void flush_pad() { + while (!pad_states.isEmpty()) { + write_one (pad_states.remove()); + } + } + + public void write(AltosState state) { + if (state.state == AltosLib.ao_flight_startup) + return; + if (!header_written) { + write_header(state.imu != null || state.mag != null, + state.gps != null, state.companion != null); + header_written = true; + } + if (!seen_boost) { + if (state.state >= AltosLib.ao_flight_boost) { + seen_boost = true; + boost_tick = state.tick; + flush_pad(); + } + } + if (seen_boost) + write_one(state); + else + pad_states.add(state); + } + + public PrintStream out() { + return out; + } + + public void close() { + if (!pad_states.isEmpty()) { + boost_tick = pad_states.element().tick; + flush_pad(); + } + out.close(); + } + + public void write(AltosStateIterable states) { + states.write_comments(out()); + for (AltosState state : states) + write(state); + } + + public AltosCSV(PrintStream in_out, File in_name) { + name = in_name; + out = in_out; + pad_states = new LinkedList<AltosState>(); + } + + public AltosCSV(File in_name) throws FileNotFoundException { + this(new PrintStream(in_name), in_name); + } + + public AltosCSV(String in_string) throws FileNotFoundException { + this(new File(in_string)); + } +} diff --git a/altoslib/AltosCompanion.java b/altoslib/AltosCompanion.java index 47ca328e..09bfe9f3 100644 --- a/altoslib/AltosCompanion.java +++ b/altoslib/AltosCompanion.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosCompanion { public final static int board_id_telescience = 0x0a; diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index c4e108f8..e1043958 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_3; +package org.altusmetrum.altoslib_4; import java.util.*; import java.text.*; @@ -29,6 +29,7 @@ public class AltosConfigData implements Iterable<String> { public int serial; public int flight; public int log_format; + public int log_space; public String version; /* Strings returned */ @@ -66,10 +67,14 @@ public class AltosConfigData implements Iterable<String> { public AltosPyro[] pyros; public int npyro; public int pyro; + public double pyro_firing_time; /* HAS_APRS */ public int aprs_interval; + /* HAS_BEEP */ + public int beep; + /* Storage info replies */ public int storage_size; public int storage_erase_unit; @@ -77,6 +82,10 @@ public class AltosConfigData implements Iterable<String> { /* Log listing replies */ public int stored_flight; + /* HAS_TRACKER */ + public int tracker_motion; + public int tracker_interval; + public static String get_string(String line, String label) throws ParseException { if (line.startsWith(label)) { String quoted = line.substring(label.length()).trim(); @@ -100,10 +109,40 @@ public class AltosConfigData implements Iterable<String> { throw new ParseException("mismatch", 0); } + public static int[] get_values(String line, String label) throws NumberFormatException, ParseException { + if (line.startsWith(label)) { + String tail = line.substring(label.length()).trim(); + String[] tokens = tail.split("\\s+"); + if (tokens.length > 1) { + int[] values = new int[2]; + values[0] = Integer.parseInt(tokens[0]); + values[1] = Integer.parseInt(tokens[1]); + return values; + } + } + throw new ParseException("mismatch", 0); + } + public Iterator<String> iterator() { return lines.iterator(); } + public int log_space() { + if (log_space > 0) + return log_space; + + if (storage_size > 0) { + int space = storage_size; + + if (storage_erase_unit > 0 && use_flash_for_config()) + space -= storage_erase_unit; + + if (space > 0) + return space; + } + return 0; + } + public int log_available() { switch (log_format) { case AltosLib.AO_LOG_FORMAT_TINY: @@ -117,7 +156,7 @@ public class AltosConfigData implements Iterable<String> { if (flight_log_max <= 0) return 1; int log_max = flight_log_max * 1024; - int log_space = storage_size - storage_erase_unit; + int log_space = log_space(); int log_used; if (stored_flight <= 0) @@ -182,6 +221,7 @@ public class AltosConfigData implements Iterable<String> { serial = 0; flight = 0; log_format = AltosLib.AO_LOG_FORMAT_UNKNOWN; + log_space = -1; version = "unknown"; main_deploy = -1; @@ -207,9 +247,15 @@ public class AltosConfigData implements Iterable<String> { pyro = 0; npyro = 0; pyros = null; + pyro_firing_time = -1; aprs_interval = -1; + beep = -1; + + tracker_motion = -1; + tracker_interval = -1; + storage_size = -1; storage_erase_unit = -1; stored_flight = 0; @@ -223,6 +269,7 @@ public class AltosConfigData implements Iterable<String> { 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 { log_space = get_int(line, "log-space"); } catch (Exception e) {} try { version = get_string(line, "software-version"); } catch (Exception e) {} /* Version also contains MS5607 info, which we ignore here */ @@ -282,10 +329,21 @@ public class AltosConfigData implements Iterable<String> { pyros[pyro++] = p; } catch (Exception e) {} } + try { pyro_firing_time = get_int(line, "Pyro time:") / 100.0; } catch (Exception e) {} /* HAS_APRS */ try { aprs_interval = get_int(line, "APRS interval:"); } catch (Exception e) {} + /* HAS_BEEP */ + try { beep = get_int(line, "Beeper setting:"); } catch (Exception e) {} + + /* HAS_TRACKER */ + try { + int[] values = get_values(line, "Tracker setting:"); + tracker_motion = values[0]; + tracker_interval = values[1]; + } 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) {} @@ -351,16 +409,16 @@ public class AltosConfigData implements Iterable<String> { 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; + boolean use_flash_for_config() { + if (product.startsWith("TeleMega")) + return false; + if (product.startsWith("TeleMetrum-v2")) + return false; + return true; } - public void get_values(AltosConfigValues source) { + + public void get_values(AltosConfigValues source) throws AltosConfigDataException { /* HAS_FLIGHT */ if (main_deploy >= 0) @@ -395,9 +453,21 @@ public class AltosConfigData implements Iterable<String> { /* AO_PYRO_NUM */ if (npyro > 0) pyros = source.pyros(); + if (pyro_firing_time >= 0) + pyro_firing_time = source.pyro_firing_time(); + /* HAS_APRS */ if (aprs_interval >= 0) aprs_interval = source.aprs_interval(); + + /* HAS_BEEP */ + if (beep >= 0) + beep = source.beep(); + /* HAS_TRACKER */ + if (tracker_motion >= 0) + tracker_motion = source.tracker_motion(); + if (tracker_interval >= 0) + tracker_interval = source.tracker_interval(); } public void set_values(AltosConfigValues dest) { @@ -410,18 +480,23 @@ public class AltosConfigData implements Iterable<String> { dest.set_radio_calibration(radio_calibration); dest.set_radio_frequency(frequency()); boolean max_enabled = true; + + if (log_space() == 0) + max_enabled = false; + switch (log_format) { case AltosLib.AO_LOG_FORMAT_TINY: max_enabled = false; break; default: - if (stored_flight >= 0) + 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_limit(log_space() / 1024); dest.set_flight_log_max(flight_log_max); dest.set_ignite_mode(ignite_mode); dest.set_pad_orientation(pad_orientation); @@ -430,7 +505,11 @@ public class AltosConfigData implements Iterable<String> { dest.set_pyros(pyros); else dest.set_pyros(null); + dest.set_pyro_firing_time(pyro_firing_time); dest.set_aprs_interval(aprs_interval); + dest.set_beep(beep); + dest.set_tracker_motion(tracker_motion); + dest.set_tracker_interval(tracker_interval); } public void save(AltosLink link, boolean remote) throws InterruptedException, TimeoutException { @@ -492,11 +571,21 @@ public class AltosConfigData implements Iterable<String> { pyros[p].toString()); } } + if (pyro_firing_time >= 0) + link.printf("c I %d\n", (int) (pyro_firing_time * 100.0 + 0.5)); /* HAS_APRS */ if (aprs_interval >= 0) link.printf("c A %d\n", aprs_interval); + /* HAS_BEEP */ + if (beep >= 0) + link.printf("c b %d\n", beep); + + /* HAS_TRACKER */ + if (tracker_motion >= 0 && tracker_interval >= 0) + link.printf("c t %d %d\n", tracker_motion, tracker_interval); + link.printf("c w\n"); link.flush_output(); } @@ -506,12 +595,12 @@ public class AltosConfigData implements Iterable<String> { 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: + case AltosLib.AO_LOG_FORMAT_UNKNOWN: + case AltosLib.AO_LOG_FORMAT_NONE: + break; + default: link.printf("l\n"); read_link(link, "done"); - default: break; } } diff --git a/altoslib/AltosConfigDataException.java b/altoslib/AltosConfigDataException.java new file mode 100644 index 00000000..ae5621cc --- /dev/null +++ b/altoslib/AltosConfigDataException.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2014 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_4; + +public class AltosConfigDataException extends Exception { + + public AltosConfigDataException(String format, Object... args) { + super(String.format(format, args)); + } + +} diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java index 4aa55d6a..724ba7dc 100644 --- a/altoslib/AltosConfigValues.java +++ b/altoslib/AltosConfigValues.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public interface AltosConfigValues { /* set and get all of the dialog values */ @@ -27,23 +27,23 @@ public interface AltosConfigValues { public abstract void set_main_deploy(int new_main_deploy); - public abstract int main_deploy(); + public abstract int main_deploy() throws AltosConfigDataException; public abstract void set_apogee_delay(int new_apogee_delay); - public abstract int apogee_delay(); + public abstract int apogee_delay() throws AltosConfigDataException; public abstract void set_apogee_lockout(int new_apogee_lockout); - public abstract int apogee_lockout(); + public abstract int apogee_lockout() throws AltosConfigDataException; public abstract void set_radio_frequency(double new_radio_frequency); - public abstract double radio_frequency(); + public abstract double radio_frequency() throws AltosConfigDataException; public abstract void set_radio_calibration(int new_radio_calibration); - public abstract int radio_calibration(); + public abstract int radio_calibration() throws AltosConfigDataException; public abstract void set_radio_enable(int new_radio_enable); @@ -57,7 +57,7 @@ public interface AltosConfigValues { public abstract void set_flight_log_max_enabled(boolean enable); - public abstract int flight_log_max(); + public abstract int flight_log_max() throws AltosConfigDataException; public abstract void set_flight_log_max_limit(int flight_log_max_limit); @@ -71,9 +71,25 @@ public interface AltosConfigValues { public abstract void set_pyros(AltosPyro[] new_pyros); - public abstract AltosPyro[] pyros(); + public abstract AltosPyro[] pyros() throws AltosConfigDataException; - public abstract int aprs_interval(); + public abstract void set_pyro_firing_time(double new_pyro_firing_time); + + public abstract double pyro_firing_time() throws AltosConfigDataException; + + public abstract int aprs_interval() throws AltosConfigDataException; public abstract void set_aprs_interval(int new_aprs_interval); + + public abstract int beep() throws AltosConfigDataException; + + public abstract void set_beep(int new_beep); + + public abstract int tracker_motion() throws AltosConfigDataException; + + public abstract void set_tracker_motion(int tracker_motion); + + public abstract int tracker_interval() throws AltosConfigDataException; + + public abstract void set_tracker_interval(int tracker_motion); } diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index 8f214c8b..dc0fbb62 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -18,7 +18,7 @@ /* * Sensor data conversion functions */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosConvert { /* @@ -208,7 +208,7 @@ public class AltosConvert { static public double mega_battery_voltage(int v_batt) { if (v_batt != AltosLib.MISSING) - return 3.3 * mega_adc(v_batt) * (15.0 + 27.0) / 27.0; + return 3.3 * mega_adc(v_batt) * (5.6 + 10.0) / 10.0; return AltosLib.MISSING; } @@ -224,10 +224,27 @@ public class AltosConvert { return sensor / 32767.0 * supply * 127/27; } - static double easy_mini_voltage(int sensor) { - double supply = 3.0; + static double tele_gps_voltage(int sensor) { + double supply = 3.3; - return sensor / 32767.0 * supply * 127/27; + return sensor / 32767.0 * supply * (5.6 + 10.0) / 10.0; + } + + static double easy_mini_voltage(int sensor, int serial) { + double supply = 3.3; + double diode_offset = 0.0; + + /* early prototypes had a 3.0V regulator */ + if (serial < 1000) + supply = 3.0; + + /* Purple v1.0 boards had the sensor after the + * blocking diode, which drops about 150mV + */ + if (serial < 1665) + diode_offset = 0.150; + + return sensor / 32767.0 * supply * 127/27 + diode_offset; } public static double radio_to_frequency(int freq, int setting, int cal, int channel) { @@ -332,6 +349,12 @@ public class AltosConvert { public static AltosOrient orient = new AltosOrient(); + public static AltosVoltage voltage = new AltosVoltage(); + + public static AltosLatitude latitude = new AltosLatitude(); + + public static AltosLongitude longitude = new AltosLongitude(); + public static String show_gs(String format, double a) { a = meters_to_g(a); format = format.concat(" g"); @@ -348,4 +371,42 @@ public class AltosConvert { csum += data[i + start]; return csum & 0xff; } + + public static double beep_value_to_freq(int value) { + if (value == 0) + return 4000; + return 1.0/2.0 * (24.0e6/32.0) / (double) value; + } + + public static int beep_freq_to_value(double freq) { + if (freq == 0) + return 94; + return (int) Math.floor (1.0/2.0 * (24.0e6/32.0) / freq + 0.5); + } + + public static final int BEARING_LONG = 0; + public static final int BEARING_SHORT = 1; + public static final int BEARING_VOICE = 2; + + public static String bearing_to_words(int length, double bearing) { + String [][] bearing_string = { + { + "North", "North North East", "North East", "East North East", + "East", "East South East", "South East", "South South East", + "South", "South South West", "South West", "West South West", + "West", "West North West", "North West", "North North West" + }, { + "N", "NNE", "NE", "ENE", + "E", "ESE", "SE", "SSE", + "S", "SSW", "SW", "WSW", + "W", "WNW", "NW", "NNW" + }, { + "north", "nor nor east", "north east", "east nor east", + "east", "east sow east", "south east", "sow sow east", + "south", "sow sow west", "south west", "west sow west", + "west", "west nor west", "north west", "nor nor west " + } + }; + return bearing_string[length][(int)((bearing / 90 * 8 + 1) / 2)%16]; + } } diff --git a/altoslib/AltosDebug.java b/altoslib/AltosDebug.java index 4dfb31e5..b0e52fc1 100644 --- a/altoslib/AltosDebug.java +++ b/altoslib/AltosDebug.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java index 71ee81d7..76ca20c0 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_3; +package org.altusmetrum.altoslib_4; public class AltosDistance extends AltosUnits { diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index 57ee73ad..020590eb 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -43,6 +43,10 @@ public abstract class AltosEeprom implements AltosStateUpdate { return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); } + public boolean has_seconds() { return false; } + + public int seconds() { return 0; } + public final static int header_length = 4; public abstract int record_length(); diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index c884b659..91eebc5a 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_3; +package org.altusmetrum.altoslib_4; import java.text.*; import java.util.concurrent.*; @@ -84,6 +84,9 @@ public class AltosEepromChunk { case AltosLib.AO_LOG_FORMAT_EASYMINI: eeprom = new AltosEepromMini(this, offset); break; + case AltosLib.AO_LOG_FORMAT_TELEGPS: + eeprom = new AltosEepromGPS(this, offset); + break; default: throw new ParseException("unknown eeprom format " + log_format, 0); } @@ -125,4 +128,4 @@ public class AltosEepromChunk { } } } -}
\ No newline at end of file +} diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java index 04101079..a2dfc438 100644 --- a/altoslib/AltosEepromDownload.java +++ b/altoslib/AltosEepromDownload.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -132,7 +132,7 @@ public class AltosEepromDownload implements Runnable { CheckFile(false); } - + void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException, ParseException { int block, state_block = 0; int log_format = flights.config_data.log_format; diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 91ffc223..b7e446ce 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -72,7 +72,17 @@ public class AltosEepromFile extends AltosStateIterable { headers = new AltosEepromIterable(AltosEepromHeader.read(input)); start = headers.state(); - start.set_state(AltosLib.ao_flight_pad); + if (start.state != AltosLib.ao_flight_stateless) + start.set_state(AltosLib.ao_flight_pad); + + if (start.log_format == AltosLib.MISSING) { + if (start.product != null) { + if (start.product.startsWith("TeleMetrum")) + start.log_format = AltosLib.AO_LOG_FORMAT_FULL; + else if (start.product.startsWith("TeleMini")) + start.log_format = AltosLib.AO_LOG_FORMAT_TINY; + } + } switch (start.log_format) { case AltosLib.AO_LOG_FORMAT_FULL: @@ -93,6 +103,9 @@ public class AltosEepromFile extends AltosStateIterable { case AltosLib.AO_LOG_FORMAT_EASYMINI: body = new AltosEepromIterable(AltosEepromMini.read(input)); break; + case AltosLib.AO_LOG_FORMAT_TELEGPS: + body = new AltosEepromIterable(AltosEepromGPS.read(input)); + break; default: body = new AltosEepromIterable(new LinkedList<AltosEeprom>()); break; @@ -120,4 +133,4 @@ public class AltosEepromFile extends AltosStateIterable { } return new AltosEepromIterator(state, i); } -}
\ No newline at end of file +} diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java new file mode 100644 index 00000000..3c1852c0 --- /dev/null +++ b/altoslib/AltosEepromGPS.java @@ -0,0 +1,153 @@ +/* + * Copyright © 2014 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_4; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromGPS extends AltosEeprom { + public static final int record_length = 32; + + public static final int max_sat = 12; + + public int record_length() { return record_length; } + + /* AO_LOG_FLIGHT elements */ + public int flight() { return data16(0); } + public int start_altitude() { return data16(2); } + public int start_latitude() { return data32(4); } + public int start_longitude() { return data32(8); } + + /* 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); } + public int course() { return data8(17); } + public int ground_speed() { return data16(18); } + public int climb_rate() { return data16(20); } + public int pdop() { return data8(22); } + public int hdop() { return data8(23); } + public int vdop() { return data8(24); } + public int mode() { return data8(25); } + + public boolean has_seconds() { return cmd == AltosLib.AO_LOG_GPS_TIME; } + + public int seconds() { + switch (cmd) { + case AltosLib.AO_LOG_GPS_TIME: + return second() + 60 * (minute() + 60 * (hour() + 24 * (day() + 31 * month()))); + default: + return 0; + } + } + + public AltosEepromGPS (AltosEepromChunk chunk, int start) throws ParseException { + parse_chunk(chunk, start); + } + + public void update_state(AltosState state) { + super.update_state(state); + + AltosGPS gps; + + /* Flush any pending GPS changes */ + if (state.gps_pending) { + switch (cmd) { + case AltosLib.AO_LOG_GPS_LAT: + case AltosLib.AO_LOG_GPS_LON: + case AltosLib.AO_LOG_GPS_ALT: + case AltosLib.AO_LOG_GPS_SAT: + case AltosLib.AO_LOG_GPS_DATE: + break; + default: + state.set_temp_gps(); + break; + } + } + + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.set_boost_tick(tick); + state.set_flight(flight()); + /* no place to log start lat/lon yet */ + break; + case AltosLib.AO_LOG_GPS_TIME: + state.set_tick(tick); + gps = state.make_temp_gps(false); + gps.lat = latitude() / 1e7; + gps.lon = longitude() / 1e7; + gps.alt = altitude(); + + gps.hour = hour(); + gps.minute = minute(); + gps.second = second(); + + int flags = flags(); + + gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + + gps.year = 2000 + year(); + gps.month = month(); + gps.day = day(); + gps.ground_speed = ground_speed() * 1.0e-2; + gps.course = course() * 2; + gps.climb_rate = climb_rate() * 1.0e-2; + gps.hdop = hdop(); + gps.vdop = vdop(); + break; + } + } + + public AltosEepromGPS (String line) { + parse_string(line); + } + + static public LinkedList<AltosEeprom> read(FileInputStream input) { + LinkedList<AltosEeprom> tgpss = new LinkedList<AltosEeprom>(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + try { + AltosEepromGPS tgps = new AltosEepromGPS(line); + if (tgps.cmd != AltosLib.AO_LOG_INVALID) + tgpss.add(tgps); + } catch (Exception e) { + System.out.printf ("exception\n"); + } + } catch (IOException ie) { + break; + } + } + + return tgpss; + } +} diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index 6ce7ddd3..839aa06e 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -53,9 +53,10 @@ public class AltosEepromHeader extends AltosEeprom { case AltosLib.AO_LOG_MANUFACTURER: break; case AltosLib.AO_LOG_PRODUCT: + state.product = data; break; case AltosLib.AO_LOG_LOG_FORMAT: - state.log_format = config_a; + state.set_log_format(config_a); break; case AltosLib.AO_LOG_SERIAL_NUMBER: state.set_serial(config_a); @@ -162,7 +163,7 @@ public class AltosEepromHeader extends AltosEeprom { break; } } - + public AltosEepromHeader (String[] tokens) { last = false; valid = true; @@ -269,7 +270,7 @@ public class AltosEepromHeader extends AltosEeprom { for (AltosEepromHeader header : headers) { header.write(out); } - + } public AltosEepromHeader (String line) { diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 081721b3..d6832c1b 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_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -38,6 +38,13 @@ class AltosEepromOrdered implements Comparable<AltosEepromOrdered> { if (cmd_diff != 0) return cmd_diff; + if (eeprom.has_seconds() && o.eeprom.has_seconds()) { + int seconds_diff = eeprom.seconds() - o.eeprom.seconds(); + + if (seconds_diff != 0) + return seconds_diff; + } + int tick_diff = tick - o.tick; if (tick_diff != 0) @@ -116,4 +123,4 @@ public class AltosEepromIterable implements Iterable<AltosEeprom> { eeproms = new LinkedList<AltosEeprom>(); return new AltosEepromOrderedIterator(eeproms); } -}
\ No newline at end of file +} diff --git a/altoslib/AltosEepromList.java b/altoslib/AltosEepromList.java index a9dac13a..ab853a88 100644 --- a/altoslib/AltosEepromList.java +++ b/altoslib/AltosEepromList.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromLog.java b/altoslib/AltosEepromLog.java index cc298207..1a430c03 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_3; +package org.altusmetrum.altoslib_4; import java.text.*; import java.util.concurrent.*; diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index b8a1b9e8..71719a26 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_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -32,7 +32,12 @@ public class AltosEepromMega extends AltosEeprom { public int flight() { return data16(0); } public int ground_accel() { return data16(2); } public int ground_pres() { return data32(4); } - public int ground_temp() { return data32(8); } + public int ground_accel_along() { return data16(8); } + public int ground_accel_across() { return data16(10); } + public int ground_accel_through() { return data16(12); } + public int ground_roll() { return data16(14); } + public int ground_pitch() { return data16(16); } + public int ground_yaw() { return data16(18); } /* AO_LOG_STATE elements */ public int state() { return data16(0); } @@ -70,7 +75,14 @@ public class AltosEepromMega extends AltosEeprom { public int year() { return data8(14); } public int month() { return data8(15); } public int day() { return data8(16); } - + public int course() { return data8(17); } + public int ground_speed() { return data16(18); } + public int climb_rate() { return data16(20); } + public int pdop() { return data8(22); } + public int hdop() { return data8(23); } + public int vdop() { return data8(24); } + public int mode() { return data8(25); } + /* AO_LOG_GPS_SAT elements */ public int nsat() { return data16(0); } public int svid(int n) { return data8(2 + n * 2); } @@ -106,7 +118,6 @@ public class AltosEepromMega extends AltosEeprom { state.set_flight(flight()); state.set_ground_accel(ground_accel()); state.set_ground_pressure(ground_pres()); - state.set_temperature(ground_temp() / 100.0); break; case AltosLib.AO_LOG_STATE: state.set_tick(tick); @@ -150,6 +161,7 @@ public class AltosEepromMega extends AltosEeprom { voltages[i] = AltosConvert.mega_pyro_voltage(sense(i)); state.set_ignitor_voltage(voltages); + state.set_pyro_fired(pyro()); break; case AltosLib.AO_LOG_GPS_TIME: state.set_tick(tick); @@ -172,6 +184,11 @@ public class AltosEepromMega extends AltosEeprom { gps.year = 2000 + year(); gps.month = month(); gps.day = day(); + gps.ground_speed = ground_speed() * 1.0e-2; + gps.course = course() * 2; + gps.climb_rate = climb_rate() * 1.0e-2; + gps.hdop = hdop(); + gps.vdop = vdop(); break; case AltosLib.AO_LOG_GPS_SAT: state.set_tick(tick); diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index f1bca6dc..d137614a 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -59,7 +59,7 @@ public class AltosEepromMetrum2 extends AltosEeprom { public int year() { return data8(4); } public int month() { return data8(5); } public int day() { return data8(6); } - + /* AO_LOG_GPS_SAT elements */ public int nsat() { return data8(0); } public int more() { return data8(1); } @@ -161,7 +161,7 @@ public class AltosEepromMetrum2 extends AltosEeprom { break; try { AltosEepromMetrum2 metrum = new AltosEepromMetrum2(line); - + if (metrum.cmd != AltosLib.AO_LOG_INVALID) metrums.add(metrum); } catch (Exception e) { diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index fb3b4d23..32985639 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -43,7 +43,7 @@ public class AltosEepromMini extends AltosEeprom { double voltage(AltosState state, int sensor) { if (state.log_format == AltosLib.AO_LOG_FORMAT_EASYMINI) - return AltosConvert.easy_mini_voltage(sensor); + return AltosConvert.easy_mini_voltage(sensor, state.serial); else return AltosConvert.tele_mini_voltage(sensor); } diff --git a/altoslib/AltosEepromMonitor.java b/altoslib/AltosEepromMonitor.java index 9ab1a5ab..b97287c3 100644 --- a/altoslib/AltosEepromMonitor.java +++ b/altoslib/AltosEepromMonitor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public interface AltosEepromMonitor { diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index c8b1e60c..77fe20c5 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromTm.java b/altoslib/AltosEepromTm.java index 049dd340..6cbb7253 100644 --- a/altoslib/AltosEepromTm.java +++ b/altoslib/AltosEepromTm.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index 37bf7075..2a738996 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_3; +package org.altusmetrum.altoslib_4; import java.io.File; import java.util.*; diff --git a/altoslib/AltosFlash.java b/altoslib/AltosFlash.java index 25c76863..8e8722c2 100644 --- a/altoslib/AltosFlash.java +++ b/altoslib/AltosFlash.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; diff --git a/altoslib/AltosFlashListener.java b/altoslib/AltosFlashListener.java index b7fcd73b..8bb86bba 100644 --- a/altoslib/AltosFlashListener.java +++ b/altoslib/AltosFlashListener.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public interface AltosFlashListener { public void position(String label, int percent); diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java index 86757e82..2fcd556e 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_3; +package org.altusmetrum.altoslib_4; import java.text.*; import java.io.*; diff --git a/altoslib/AltosFlightStats.java b/altoslib/AltosFlightStats.java new file mode 100644 index 00000000..56feb848 --- /dev/null +++ b/altoslib/AltosFlightStats.java @@ -0,0 +1,201 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_4; + +import java.io.*; + +public class AltosFlightStats { + public double max_height; + public double max_gps_height; + public double max_speed; + public double max_acceleration; + public double[] state_speed = new double[AltosLib.ao_flight_invalid + 1]; + public double[] state_accel = new double[AltosLib.ao_flight_invalid + 1]; + public int[] state_count = new int[AltosLib.ao_flight_invalid + 1]; + public double[] state_start = new double[AltosLib.ao_flight_invalid + 1]; + public double[] state_end = new double[AltosLib.ao_flight_invalid + 1]; + public int serial; + public int flight; + public int year, month, day; + public int hour, minute, second; + public double lat, lon; + public double pad_lat, pad_lon; + public boolean has_flight_data; + public boolean has_gps; + public boolean has_flight_adc; + public boolean has_battery; + public boolean has_rssi; + public boolean has_imu; + public boolean has_mag; + public boolean has_orient; + public int num_ignitor; + + double landed_time(AltosStateIterable states) { + AltosState state = null; + + for (AltosState s : states) { + state = s; + if (state.state == AltosLib.ao_flight_landed) + break; + } + + if (state == null) + return 0; + + double landed_height = state.height(); + + state = null; + + boolean above = true; + + double landed_time = -1000; + + for (AltosState s : states) { + state = s; + + if (state.height() > landed_height + 10) { + above = true; + } else { + if (above && state.height() < landed_height + 2) { + above = false; + landed_time = state.time; + } + } + } + if (landed_time == -1000) + landed_time = state.time; + return landed_time; + } + + double boost_time(AltosStateIterable states) { + double boost_time = AltosLib.MISSING; + AltosState state = null; + + for (AltosState s : states) { + state = s; + if (state.acceleration() < 1) + boost_time = state.time; + if (state.state >= AltosLib.ao_flight_boost && state.state <= AltosLib.ao_flight_landed) + break; + } + if (state == null) + return 0; + + if (boost_time == AltosLib.MISSING) + boost_time = state.time; + return boost_time; + } + + + public AltosFlightStats(AltosStateIterable states) throws InterruptedException, IOException { + double boost_time = boost_time(states); + double end_time = 0; + double landed_time = landed_time(states); + + year = month = day = AltosLib.MISSING; + hour = minute = second = AltosLib.MISSING; + serial = flight = AltosLib.MISSING; + lat = lon = AltosLib.MISSING; + has_flight_data = false; + has_gps = false; + has_flight_adc = false; + has_battery = false; + has_rssi = false; + has_imu = false; + has_mag = false; + has_orient = false; + for (AltosState state : states) { + if (serial == AltosLib.MISSING && state.serial != AltosLib.MISSING) + serial = state.serial; + if (flight == AltosLib.MISSING && state.flight != AltosLib.MISSING) + flight = state.flight; + if (state.battery_voltage != AltosLib.MISSING) + has_battery = true; + if (state.main_voltage != AltosLib.MISSING) + has_flight_adc = true; + if (state.rssi != AltosLib.MISSING) + has_rssi = true; + end_time = state.time; + + if (state.pressure() != AltosLib.MISSING) + has_flight_data = true; + + int state_id = state.state; + if (state.time >= boost_time && state_id < AltosLib.ao_flight_boost) + state_id = AltosLib.ao_flight_boost; + if (state.time >= landed_time && state_id < AltosLib.ao_flight_landed) + state_id = AltosLib.ao_flight_landed; + if (state.gps != null && state.gps.locked) { + year = state.gps.year; + month = state.gps.month; + day = state.gps.day; + hour = state.gps.hour; + minute = state.gps.minute; + second = state.gps.second; + } + max_height = state.max_height(); + max_speed = state.max_speed(); + max_acceleration = state.max_acceleration(); + max_gps_height = state.max_gps_height(); + + if (0 <= state_id && state_id < AltosLib.ao_flight_invalid) { + double acceleration = state.acceleration(); + double speed = state.speed(); + if (acceleration != AltosLib.MISSING && speed != AltosLib.MISSING) { + state_accel[state_id] += acceleration; + state_speed[state_id] += speed; + state_count[state_id]++; + } + if (state_start[state_id] == 0.0) + state_start[state_id] = state.time; + if (state_end[state_id] < state.time) + state_end[state_id] = state.time; + } + if (state.pad_lat != AltosLib.MISSING) { + pad_lat = state.pad_lat; + pad_lon = state.pad_lon; + } + if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { + lat = state.gps.lat; + lon = state.gps.lon; + has_gps = true; + } + if (state.imu != null) + has_imu = true; + if (state.mag != null) + has_mag = true; + if (state.orient() != AltosLib.MISSING) + has_orient = true; + if (state.ignitor_voltage != null && state.ignitor_voltage.length > num_ignitor) + num_ignitor = state.ignitor_voltage.length; + } + for (int s = AltosLib.ao_flight_startup; s <= AltosLib.ao_flight_landed; s++) { + if (state_count[s] > 0) { + state_speed[s] /= state_count[s]; + state_accel[s] /= state_count[s]; + } else { + state_speed[s] = AltosLib.MISSING; + state_accel[s] = AltosLib.MISSING; + } + if (state_start[s] == 0) + state_start[s] = end_time; + if (state_end[s] == 0) + state_end[s] = end_time; + } + } +} diff --git a/altoslib/AltosFrequency.java b/altoslib/AltosFrequency.java index 5770b646..7c291ea9 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_3; +package org.altusmetrum.altoslib_4; public class AltosFrequency { public double frequency; diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index 01e6fdbc..2708d026 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_3; +package org.altusmetrum.altoslib_4; import java.text.*; import java.util.concurrent.*; diff --git a/altoslib/AltosGPSSat.java b/altoslib/AltosGPSSat.java index 76fa3a56..ef24d497 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_3; +package org.altusmetrum.altoslib_4; public class AltosGPSSat { public int svid; diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java index b884a3bc..4782c34d 100644 --- a/altoslib/AltosGreatCircle.java +++ b/altoslib/AltosGreatCircle.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.lang.Math; @@ -30,30 +30,12 @@ public class AltosGreatCircle implements Cloneable { static final double rad = Math.PI / 180; static final double earth_radius = 6371.2 * 1000; /* in meters */ - public static final int BEARING_LONG = 0; - public static final int BEARING_SHORT = 1; - public static final int BEARING_VOICE = 2; + public static final int BEARING_LONG = AltosConvert.BEARING_LONG; + public static final int BEARING_SHORT = AltosConvert.BEARING_SHORT; + public static final int BEARING_VOICE = AltosConvert.BEARING_VOICE; public String bearing_words(int length) { - String [][] bearing_string = { - { - "North", "North North East", "North East", "East North East", - "East", "East South East", "South East", "South South East", - "South", "South South West", "South West", "West South West", - "West", "West North West", "North West", "North North West" - }, { - "N", "NNE", "NE", "ENE", - "E", "ESE", "SE", "SSE", - "S", "SSW", "SW", "WSW", - "W", "WNW", "NW", "NNW" - }, { - "north", "nor nor east", "north east", "east nor east", - "east", "east sow east", "south east", "sow sow east", - "south", "sow sow west", "south west", "west sow west", - "west", "west nor west", "north west", "nor nor west " - } - }; - return bearing_string[length][(int)((bearing / 90 * 8 + 1) / 2)%16]; + return AltosConvert.bearing_to_words(length, bearing); } public AltosGreatCircle (double start_lat, double start_lon, double start_alt, diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java index a81897e7..84981032 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_3; +package org.altusmetrum.altoslib_4; public class AltosHeight extends AltosUnits { diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java index 60f4ecdc..d5fa8f5f 100644 --- a/altoslib/AltosHexfile.java +++ b/altoslib/AltosHexfile.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.LinkedList; diff --git a/altoslib/AltosHexsym.java b/altoslib/AltosHexsym.java index a98ef0fc..403b5644 100644 --- a/altoslib/AltosHexsym.java +++ b/altoslib/AltosHexsym.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosHexsym { String name; diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index 260f3587..a22b3fed 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_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.*; @@ -28,6 +28,18 @@ public class AltosIMU implements Cloneable { public double gyro_y; public double gyro_z; +/* + * XXX use ground measurements to adjust values + + public double ground_accel_x; + public double ground_accel_y; + public double ground_accel_z; + + public double ground_gyro_x; + public double ground_gyro_y; + public double ground_gyro_z; +*/ + public static int counts_per_g = 2048; public static double convert_accel(int counts) { diff --git a/altoslib/AltosIdle.java b/altoslib/AltosIdle.java index c7b546b6..55f6f5c9 100644 --- a/altoslib/AltosIdle.java +++ b/altoslib/AltosIdle.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; diff --git a/altoslib/AltosIdleFetch.java b/altoslib/AltosIdleFetch.java index 02cb7a94..5cd8bf36 100644 --- a/altoslib/AltosIdleFetch.java +++ b/altoslib/AltosIdleFetch.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -142,7 +142,7 @@ public class AltosIdleFetch implements AltosStateUpdate { state.set_received_time(System.currentTimeMillis()); } catch (TimeoutException te) { } - + } public AltosIdleFetch(AltosLink link) { diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index 8342f8a5..f81abdff 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_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.concurrent.*; diff --git a/altoslib/AltosIdleMonitorListener.java b/altoslib/AltosIdleMonitorListener.java index dcaa77a6..6a9abea2 100644 --- a/altoslib/AltosIdleMonitorListener.java +++ b/altoslib/AltosIdleMonitorListener.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public interface AltosIdleMonitorListener { public void update(AltosState state, AltosListenerState listener_state); diff --git a/altoslib/AltosIgnite.java b/altoslib/AltosIgnite.java index 8ab47d1d..c21f17ac 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_3; +package org.altusmetrum.altoslib_4; import java.util.*; import java.io.*; diff --git a/altoslib/AltosKML.java b/altoslib/AltosKML.java new file mode 100644 index 00000000..d55da9ef --- /dev/null +++ b/altoslib/AltosKML.java @@ -0,0 +1,178 @@ +/* + * 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_4; + +import java.io.*; + +public class AltosKML implements AltosWriter { + + File name; + PrintStream out; + int flight_state = -1; + AltosState prev = null; + double gps_start_altitude; + + static final String[] kml_state_colors = { + "FF000000", + "FF000000", + "FF000000", + "FF0000FF", + "FF4080FF", + "FF00FFFF", + "FFFF0000", + "FF00FF00", + "FF000000", + "FFFFFFFF" + }; + + static final String kml_header_start = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" + + "<Document>\n" + + " <name>AO Flight#%d S/N: %03d</name>\n" + + " <description>\n"; + static final String kml_header_end = + " </description>\n" + + " <open>0</open>\n"; + + static final String kml_style_start = + " <Style id=\"ao-flightstate-%s\">\n" + + " <LineStyle><color>%s</color><width>4</width></LineStyle>\n" + + " <BalloonStyle>\n" + + " <text>\n"; + + static final String kml_style_end = + " </text>\n" + + " </BalloonStyle>\n" + + " </Style>\n"; + + static final String kml_placemark_start = + " <Placemark>\n" + + " <name>%s</name>\n" + + " <styleUrl>#ao-flightstate-%s</styleUrl>\n" + + " <LineString>\n" + + " <tessellate>1</tessellate>\n" + + " <altitudeMode>absolute</altitudeMode>\n" + + " <coordinates>\n"; + + static final String kml_coord_fmt = + " %.7f,%.7f,%.7f <!-- alt %12.7f time %12.7f sats %d -->\n"; + + static final String kml_placemark_end = + " </coordinates>\n" + + " </LineString>\n" + + " </Placemark>\n"; + + static final String kml_footer = + "</Document>\n" + + "</kml>\n"; + + void start (AltosState record) { + out.printf(kml_header_start, record.flight, record.serial); + out.printf("Date: %04d-%02d-%02d\n", + record.gps.year, record.gps.month, record.gps.day); + out.printf("Time: %2d:%02d:%02d\n", + record.gps.hour, record.gps.minute, record.gps.second); + out.printf("%s", kml_header_end); + } + + boolean started = false; + + void state_start(AltosState state) { + String state_name = AltosLib.state_name(state.state); + out.printf(kml_style_start, state_name, kml_state_colors[state.state]); + out.printf("\tState: %s\n", state_name); + out.printf("%s", kml_style_end); + out.printf(kml_placemark_start, state_name, state_name); + } + + void state_end(AltosState state) { + out.printf("%s", kml_placemark_end); + } + + void coord(AltosState state) { + AltosGPS gps = state.gps; + double altitude; + + if (state.height() != AltosLib.MISSING) + altitude = state.height() + gps_start_altitude; + else + altitude = gps.alt; + out.printf(kml_coord_fmt, + gps.lon, gps.lat, + altitude, (double) gps.alt, + state.time, gps.nsat); + } + + void end() { + out.printf("%s", kml_footer); + } + + public void close() { + if (prev != null) { + state_end(prev); + end(); + prev = null; + } + } + + public void write(AltosState state) { + AltosGPS gps = state.gps; + + if (gps == null) + return; + + if (gps.lat == AltosLib.MISSING) + return; + if (gps.lon == AltosLib.MISSING) + return; + if (!started) { + start(state); + started = true; + gps_start_altitude = gps.alt; + } + if (prev != null && prev.gps_sequence == state.gps_sequence) + return; + if (state.state != flight_state) { + flight_state = state.state; + if (prev != null) { + coord(state); + state_end(prev); + } + state_start(state); + } + coord(state); + prev = state; + } + + public void write(AltosStateIterable states) { + for (AltosState state : states) { + if ((state.set & AltosState.set_gps) != 0) + write(state); + } + } + + public AltosKML(File in_name) throws FileNotFoundException { + name = in_name; + out = new PrintStream(name); + } + + public AltosKML(String in_string) throws FileNotFoundException { + this(new File(in_string)); + } +} diff --git a/altoslib/AltosLatitude.java b/altoslib/AltosLatitude.java new file mode 100644 index 00000000..6156d6dc --- /dev/null +++ b/altoslib/AltosLatitude.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2014 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_4; + +public class AltosLatitude extends AltosLocation { + public String pos() { return "N"; } + public String neg() { return "S"; } +} diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 05f0af8d..69c6d604 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_3; +package org.altusmetrum.altoslib_4; import java.util.*; import java.io.*; @@ -79,6 +79,7 @@ public class AltosLib { public static final int ao_flight_main = 7; public static final int ao_flight_landed = 8; public static final int ao_flight_invalid = 9; + public static final int ao_flight_stateless = 10; /* USB product IDs */ public final static int vendor_altusmetrum = 0xfffe; @@ -187,6 +188,7 @@ public class AltosLib { string_to_state.put("main", ao_flight_main); string_to_state.put("landed", ao_flight_landed); string_to_state.put("invalid", ao_flight_invalid); + string_to_state.put("stateless", ao_flight_stateless); map_initialized = true; } @@ -203,7 +205,7 @@ public class AltosLib { throw new IllegalArgumentException(String.format("Invalid telemetry %d", telemetry)); } - + private static String[] state_to_string = { "startup", "idle", @@ -215,6 +217,7 @@ public class AltosLib { "main", "landed", "invalid", + "stateless", }; private static String[] state_to_string_capital = { @@ -228,6 +231,7 @@ public class AltosLib { "Main", "Landed", "Invalid", + "Stateless", }; public static int state(String state) { @@ -265,6 +269,7 @@ public class AltosLib { public static final int AO_LOG_FORMAT_EASYMINI = 6; public static final int AO_LOG_FORMAT_TELEMETRUM = 7; public static final int AO_LOG_FORMAT_TELEMINI = 8; + public static final int AO_LOG_FORMAT_TELEGPS = 9; public static final int AO_LOG_FORMAT_NONE = 127; public static boolean isspace(int c) { @@ -479,4 +484,8 @@ public class AltosLib { default: return "unknown"; } } + + public static String ignitor_name(int i) { + return String.format("Ignitor %c", 'A' + i); + } } diff --git a/altoslib/AltosLine.java b/altoslib/AltosLine.java index 9d796a89..f9c712a3 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_3; +package org.altusmetrum.altoslib_4; public class AltosLine { public String line; diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index 97fa7062..7f434a06 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_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.concurrent.*; @@ -76,7 +76,7 @@ public abstract class AltosLink implements Runnable { return get_reply(5000); } - + public abstract boolean can_cancel_reply(); public abstract boolean show_reply_timeout(); public abstract void hide_reply_timeout(); @@ -215,7 +215,7 @@ public abstract class AltosLink implements Runnable { break; } } - + } finally { --in_reply; } diff --git a/altoslib/AltosListenerState.java b/altoslib/AltosListenerState.java index 53ed33f9..5bf761b0 100644 --- a/altoslib/AltosListenerState.java +++ b/altoslib/AltosListenerState.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosListenerState { public int crc_errors; diff --git a/altoslib/AltosLocation.java b/altoslib/AltosLocation.java new file mode 100644 index 00000000..725a02ba --- /dev/null +++ b/altoslib/AltosLocation.java @@ -0,0 +1,66 @@ +/* + * Copyright © 2014 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_4; + +public abstract class AltosLocation extends AltosUnits { + + public abstract String pos(); + public abstract String neg(); + + public double value(double v, boolean imperial_units) { + return v; + } + + public double inverse(double v, boolean imperial_units) { + return v; + } + + public String show_units(boolean imperial_units) { + return "°"; + } + + public String say_units(boolean imperial_units) { + return "degrees"; + } + + public int show_fraction(int width, boolean imperial_units) { + return 2; + } + + public String show(int width, double v, boolean imperial_units) { + String h = pos(); + if (v < 0) { + h = neg(); + v = -v; + } + int deg = (int) Math.floor(v); + double min = (v - Math.floor(v)) * 60.0; + return String.format("%s %4d° %9.6f", h, deg, min); + } + + public String say(double v, boolean imperial_units) { + String h = pos(); + if (v < 0) { + h = neg(); + v = -v; + } + int deg = (int) Math.floor(v); + double min = (v - Math.floor(v)) * 60.0; + return String.format("%s %d degrees %d", h, deg, (int) Math.floor(min + 0.5)); + } +} diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index 70c017b7..c4e9e425 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_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.text.*; @@ -48,6 +48,7 @@ public class AltosLog implements Runnable { } public void close() { + link.remove_monitor(input_queue); close_log_file(); if (log_thread != null) { log_thread.interrupt(); diff --git a/altoslib/AltosLongitude.java b/altoslib/AltosLongitude.java new file mode 100644 index 00000000..29a5dcd4 --- /dev/null +++ b/altoslib/AltosLongitude.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2014 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_4; + +public class AltosLongitude extends AltosLocation { + public String pos() { return "E"; } + public String neg() { return "W"; } +} diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java index d2bb9da6..9262de2d 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_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.*; @@ -87,4 +87,3 @@ public class AltosMag implements Cloneable { } } } -
\ No newline at end of file diff --git a/altoslib/AltosMma655x.java b/altoslib/AltosMma655x.java index 0d90c351..cb2e63d4 100644 --- a/altoslib/AltosMma655x.java +++ b/altoslib/AltosMma655x.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.*; diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java index 97d08c3e..5aa3a7ec 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_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.*; @@ -44,7 +44,7 @@ public class AltosMs5607 { //int P; dT = raw_temp - ((int) tref << 8); - + TEMP = (int) (2000 + (((long) dT * (long) tempsens) >> 23)); if (ms5611) { @@ -55,7 +55,7 @@ public class AltosMs5607 { OFF = ((long) off << 17) + (((long) tco * (long) dT) >> 6); SENS = ((long) sens << 16) + (((long) tcs * (long) dT) >> 7); - } + } if (TEMP < 2000) { int T2 = (int) (((long) dT * (long) dT) >> 31); diff --git a/altoslib/AltosNoSymbol.java b/altoslib/AltosNoSymbol.java index 791899c0..f5e53b8c 100644 --- a/altoslib/AltosNoSymbol.java +++ b/altoslib/AltosNoSymbol.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosNoSymbol extends Exception { public AltosNoSymbol(String name) { diff --git a/altoslib/AltosOrient.java b/altoslib/AltosOrient.java index d916a0fb..5fcbe28d 100644 --- a/altoslib/AltosOrient.java +++ b/altoslib/AltosOrient.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosOrient extends AltosUnits { diff --git a/altoslib/AltosParse.java b/altoslib/AltosParse.java index 5137fef8..1bff7682 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_3; +package org.altusmetrum.altoslib_4; import java.text.*; diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java index b8920d26..d299f27b 100644 --- a/altoslib/AltosPreferences.java +++ b/altoslib/AltosPreferences.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -55,7 +55,7 @@ public class AltosPreferences { /* Launcher channel preference name */ public final static String launcherChannelPreference = "LAUNCHER-CHANNEL"; - + /* Default logdir is ~/TeleMetrum */ public final static String logdirName = "TeleMetrum"; @@ -349,7 +349,7 @@ public class AltosPreferences { return launcher_channel; } } - + public static AltosPreferencesBackend bt_devices() { synchronized (backend) { return backend.node("bt_devices"); diff --git a/altoslib/AltosPreferencesBackend.java b/altoslib/AltosPreferencesBackend.java index 2eb29702..461b5c80 100644 --- a/altoslib/AltosPreferencesBackend.java +++ b/altoslib/AltosPreferencesBackend.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.File; diff --git a/altoslib/AltosProgrammer.java b/altoslib/AltosProgrammer.java index 750e1f02..c96f04ca 100644 --- a/altoslib/AltosProgrammer.java +++ b/altoslib/AltosProgrammer.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java index aefc6fbd..9e47bc80 100644 --- a/altoslib/AltosPyro.java +++ b/altoslib/AltosPyro.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.util.*; import java.text.*; @@ -105,7 +105,7 @@ public class AltosPyro { private static HashMap<Integer,AltosUnits> pyro_to_units = new HashMap<Integer,AltosUnits>(); private static HashMap<Integer,Double> pyro_to_scale = new HashMap<Integer,Double>(); - + private static void insert_map(int flag, String string, String name, AltosUnits units, double scale) { string_to_pyro.put(string, flag); pyro_to_string.put(flag, string); @@ -114,7 +114,7 @@ public class AltosPyro { pyro_to_units.put(flag, units); 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); @@ -174,7 +174,7 @@ public class AltosPyro { insert_map(pyro_after_motor, pyro_after_motor_string, pyro_after_motor_name, null, 1.0); insert_map(pyro_delay, pyro_delay_string, pyro_delay_name, null, pyro_delay_scale); - + insert_map(pyro_state_less, pyro_state_less_string, pyro_state_less_name, null, 1.0); insert_map(pyro_state_greater_or_equal, pyro_state_greater_or_equal_string, pyro_state_greater_or_equal_name, null, 1.0); } diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index 4cf642ca..bf7e0e5b 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_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -39,7 +39,7 @@ public class AltosReplayReader extends AltosFlightReader { public void update(AltosState state) throws InterruptedException { /* Make it run in realtime after the rocket leaves the pad */ - if (state.state > AltosLib.ao_flight_pad) + if (state.state > AltosLib.ao_flight_pad && state.time_change > 0) Thread.sleep((int) (Math.min(state.time_change,10) * 1000)); state.set_received_time(System.currentTimeMillis()); } diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java index 1273fbc6..10df11af 100644 --- a/altoslib/AltosRomconfig.java +++ b/altoslib/AltosRomconfig.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; @@ -144,7 +144,7 @@ public class AltosRomconfig { ao_romconfig_check, ao_serial_number }; - + private static boolean name_required(String name) { for (String required : required_names) if (name.equals(required)) diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java index aae993eb..502c6d65 100644 --- a/altoslib/AltosSelfFlash.java +++ b/altoslib/AltosSelfFlash.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; @@ -47,7 +47,7 @@ public class AltosSelfFlash extends AltosProgrammer { for (int offset = 0; offset < len; offset += 0x100) { link.printf("R %x\n", addr + offset); byte[] reply = link.get_binary_reply(5000, 0x100); - + if (reply == null) throw new IOException("Read device memory timeout"); for (b = 0; b < len; b++) @@ -55,7 +55,7 @@ public class AltosSelfFlash extends AltosProgrammer { } return data; } - + void write_memory(long addr, byte[] data, int start, int len) { int b; link.printf("W %x\n", addr); diff --git a/altoslib/AltosSensorEMini.java b/altoslib/AltosSensorEMini.java index f888754c..ee0238f9 100644 --- a/altoslib/AltosSensorEMini.java +++ b/altoslib/AltosSensorEMini.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.TimeoutException; @@ -31,10 +31,10 @@ public class AltosSensorEMini { if (sensor_emini == null) return; - state.set_battery_voltage(AltosConvert.easy_mini_voltage(sensor_emini.batt)); - state.set_apogee_voltage(AltosConvert.easy_mini_voltage(sensor_emini.apogee)); - state.set_main_voltage(AltosConvert.easy_mini_voltage(sensor_emini.main)); - + state.set_battery_voltage(AltosConvert.easy_mini_voltage(sensor_emini.batt, config_data.serial)); + state.set_apogee_voltage(AltosConvert.easy_mini_voltage(sensor_emini.apogee, config_data.serial)); + state.set_main_voltage(AltosConvert.easy_mini_voltage(sensor_emini.main, config_data.serial)); + } catch (TimeoutException te) { } } diff --git a/altoslib/AltosSensorMM.java b/altoslib/AltosSensorMM.java index 0c23d671..e34e71b7 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_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorMega.java b/altoslib/AltosSensorMega.java index c52f688d..02f3a256 100644 --- a/altoslib/AltosSensorMega.java +++ b/altoslib/AltosSensorMega.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorMetrum.java b/altoslib/AltosSensorMetrum.java index bb794a1e..e5421ef5 100644 --- a/altoslib/AltosSensorMetrum.java +++ b/altoslib/AltosSensorMetrum.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java index b8f54bcb..2d60d8cf 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_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.TimeoutException; @@ -40,7 +40,7 @@ public class AltosSensorTM { state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(sensor_tm.batt)); state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.drogue)); state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.main)); - + } catch (TimeoutException te) { } } diff --git a/altoslib/AltosSensorTMini.java b/altoslib/AltosSensorTMini.java index 35857e35..b9eeca0c 100644 --- a/altoslib/AltosSensorTMini.java +++ b/altoslib/AltosSensorTMini.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.util.concurrent.TimeoutException; @@ -31,10 +31,10 @@ public class AltosSensorTMini { if (sensor_tmini == null) return; - state.set_battery_voltage(AltosConvert.easy_mini_voltage(sensor_tmini.batt)); - state.set_apogee_voltage(AltosConvert.easy_mini_voltage(sensor_tmini.apogee)); - state.set_main_voltage(AltosConvert.easy_mini_voltage(sensor_tmini.main)); - + state.set_battery_voltage(AltosConvert.tele_mini_voltage(sensor_tmini.batt)); + state.set_apogee_voltage(AltosConvert.tele_mini_voltage(sensor_tmini.apogee)); + state.set_main_voltage(AltosConvert.tele_mini_voltage(sensor_tmini.main)); + } catch (TimeoutException te) { } } diff --git a/altoslib/AltosSpeed.java b/altoslib/AltosSpeed.java index d93229dd..9134f5f4 100644 --- a/altoslib/AltosSpeed.java +++ b/altoslib/AltosSpeed.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosSpeed extends AltosUnits { diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 758fd636..b05cd358 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_3; +package org.altusmetrum.altoslib_4; public class AltosState implements Cloneable { @@ -50,12 +50,13 @@ public class AltosState implements Cloneable { private double set_time; private double prev_set_time; + boolean can_max() { return true; } + void set(double new_value, double time) { if (new_value != AltosLib.MISSING) { value = new_value; - if (max_value == AltosLib.MISSING || value > max_value) { + if (can_max() && (max_value == AltosLib.MISSING || value > max_value)) max_value = value; - } set_time = time; } } @@ -108,7 +109,7 @@ public class AltosState implements Cloneable { void set_derivative(AltosValue in) { double n = in.rate(); - + if (n == AltosLib.MISSING) return; @@ -123,7 +124,7 @@ public class AltosState implements Cloneable { /* Clip changes to reduce noise */ double ddt = in.time() - pt; double ddv = (n - p) / ddt; - + final double max = 100000; /* 100gs */ @@ -246,11 +247,11 @@ public class AltosState implements Cloneable { void set_integral(AltosValue in) { computed.set_integral(in); } - + void set_integral(AltosCValue in) { set_integral(in.altos_value()); } - + void copy(AltosCValue old) { measured.copy(old.measured); computed.copy(old.computed); @@ -337,7 +338,7 @@ public class AltosState implements Cloneable { } private AltosGroundPressure ground_pressure; - + public double ground_pressure() { return ground_pressure.value(); } @@ -388,6 +389,11 @@ public class AltosState implements Cloneable { private AltosGpsAltitude gps_altitude; + private AltosValue gps_ground_speed; + private AltosValue gps_ascent_rate; + private AltosValue gps_course; + private AltosValue gps_speed; + public double altitude() { double a = altitude.value(); if (a != AltosLib.MISSING) @@ -418,6 +424,34 @@ public class AltosState implements Cloneable { gps_altitude.set(new_gps_altitude, time); } + public double gps_ground_speed() { + return gps_ground_speed.value(); + } + + public double max_gps_ground_speed() { + return gps_ground_speed.max(); + } + + public double gps_ascent_rate() { + return gps_ascent_rate.value(); + } + + public double max_gps_ascent_rate() { + return gps_ascent_rate.max(); + } + + public double gps_course() { + return gps_course.value(); + } + + public double gps_speed() { + return gps_speed.value(); + } + + public double max_gps_speed() { + return gps_speed.max(); + } + class AltosPressure extends AltosValue { void set(double p, double time) { super.set(p, time); @@ -447,7 +481,7 @@ public class AltosState implements Cloneable { double g = ground_altitude(); if (a != AltosLib.MISSING && g != AltosLib.MISSING) return a - g; - return AltosLib.MISSING; + return gps_height(); } public double max_height() { @@ -459,7 +493,7 @@ public class AltosState implements Cloneable { double g = ground_altitude(); if (a != AltosLib.MISSING && g != AltosLib.MISSING) return a - g; - return AltosLib.MISSING; + return max_gps_height(); } public double gps_height() { @@ -481,7 +515,11 @@ public class AltosState implements Cloneable { } class AltosSpeed extends AltosCValue { - + + boolean can_max() { + return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless; + } + void set_accel() { acceleration.set_derivative(this); } @@ -508,17 +546,34 @@ public class AltosState implements Cloneable { double v = kalman_speed.value(); if (v != AltosLib.MISSING) return v; - return speed.value(); + v = speed.value(); + if (v != AltosLib.MISSING) + return v; + v = gps_speed(); + if (v != AltosLib.MISSING) + return v; + return AltosLib.MISSING; } public double max_speed() { double v = kalman_speed.max(); if (v != AltosLib.MISSING) return v; - return speed.max(); + v = speed.max(); + if (v != AltosLib.MISSING) + return v; + v = max_gps_speed(); + if (v != AltosLib.MISSING) + return v; + return AltosLib.MISSING; } class AltosAccel extends AltosCValue { + + boolean can_max() { + return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless; + } + void set_measured(double a, double time) { super.set_measured(a, time); if (ascent) @@ -604,11 +659,14 @@ public class AltosState implements Cloneable { public double ground_accel_avg; public int log_format; + public String product; public AltosMs5607 baro; public AltosCompanion companion; + public int pyro_fired; + public void set_npad(int npad) { this.npad = npad; gps_waiting = MIN_PAD_SAMPLES - npad; @@ -682,11 +740,16 @@ public class AltosState implements Cloneable { gps_altitude = new AltosGpsAltitude(); gps_ground_altitude = new AltosGpsGroundAltitude(); + gps_ground_speed = new AltosValue(); + gps_speed = new AltosValue(); + gps_ascent_rate = new AltosValue(); + gps_course = new AltosValue(); speak_tick = AltosLib.MISSING; speak_altitude = AltosLib.MISSING; callsign = null; + firmware_version = null; accel_plus_g = AltosLib.MISSING; accel_minus_g = AltosLib.MISSING; @@ -696,11 +759,14 @@ public class AltosState implements Cloneable { ground_accel_avg = AltosLib.MISSING; log_format = AltosLib.MISSING; + product = null; serial = AltosLib.MISSING; receiver_serial = AltosLib.MISSING; baro = null; companion = null; + + pyro_fired = 0; } void finish_update() { @@ -729,7 +795,7 @@ public class AltosState implements Cloneable { time = old.time; time_change = old.time_change; prev_time = old.time; - + tick = old.tick; prev_tick = old.tick; boost_tick = old.boost_tick; @@ -747,7 +813,7 @@ public class AltosState implements Cloneable { apogee_delay = old.apogee_delay; main_deploy = old.main_deploy; flight_log_max = old.flight_log_max; - + set = 0; ground_pressure.copy(old.ground_pressure); @@ -808,6 +874,10 @@ public class AltosState implements Cloneable { gps_altitude.copy(old.gps_altitude); gps_ground_altitude.copy(old.gps_ground_altitude); + gps_ground_speed.copy(old.gps_ground_speed); + gps_ascent_rate.copy(old.gps_ascent_rate); + gps_course.copy(old.gps_course); + gps_speed.copy(old.gps_speed); pad_lat = old.pad_lat; pad_lon = old.pad_lon; @@ -817,6 +887,7 @@ public class AltosState implements Cloneable { speak_altitude = old.speak_altitude; callsign = old.callsign; + firmware_version = old.firmware_version; accel_plus_g = old.accel_plus_g; accel_minus_g = old.accel_minus_g; @@ -825,28 +896,31 @@ public class AltosState implements Cloneable { ground_accel_avg = old.ground_accel_avg; log_format = old.log_format; + product = old.product; serial = old.serial; receiver_serial = old.receiver_serial; baro = old.baro; companion = old.companion; + + pyro_fired = old.pyro_fired; } - + void update_time() { } void update_gps() { - elevation = 0; - range = -1; + elevation = AltosLib.MISSING; + range = AltosLib.MISSING; if (gps == null) return; if (gps.locked && gps.nsat >= 4) { /* Track consecutive 'good' gps reports, waiting for 10 of them */ - if (state == AltosLib.ao_flight_pad) { + if (state == AltosLib.ao_flight_pad || state == AltosLib.ao_flight_stateless) { set_npad(npad+1); - if (pad_lat != AltosLib.MISSING) { + if (pad_lat != AltosLib.MISSING && (npad < 10 || state == AltosLib.ao_flight_pad)) { pad_lat = (pad_lat * 31 + gps.lat) / 32; pad_lon = (pad_lon * 31 + gps.lon) / 32; gps_ground_altitude.set_filtered(gps.alt, time); @@ -858,6 +932,15 @@ public class AltosState implements Cloneable { gps_ground_altitude.set(gps.alt, time); } gps_altitude.set(gps.alt, time); + if (gps.climb_rate != AltosLib.MISSING) + gps_ascent_rate.set(gps.climb_rate, time); + if (gps.ground_speed != AltosLib.MISSING) + gps_ground_speed.set(gps.ground_speed, time); + if (gps.climb_rate != AltosLib.MISSING && gps.ground_speed != AltosLib.MISSING) + gps_speed.set(Math.sqrt(gps.ground_speed * gps.ground_speed + + gps.climb_rate * gps.climb_rate), time); + if (gps.course != AltosLib.MISSING) + gps_course.set(gps.course, time); } if (gps.lat != 0 && gps.lon != 0 && pad_lat != AltosLib.MISSING && @@ -902,18 +985,34 @@ public class AltosState implements Cloneable { state <= AltosLib.ao_flight_coast); boost = (AltosLib.ao_flight_boost == state); } - } public void set_device_type(int device_type) { this.device_type = device_type; + switch (device_type) { + case AltosLib.product_telegps: + this.state = AltosLib.ao_flight_stateless; + break; + } } - public void set_config(int major, int minor, int apogee_delay, int main_deploy, int flight_log_max) { - config_major = major; - config_minor = minor; + public void set_log_format(int log_format) { + this.log_format = log_format; + switch (log_format) { + case AltosLib.AO_LOG_FORMAT_TELEGPS: + this.state = AltosLib.ao_flight_stateless; + break; + } + } + + public void set_flight_params(int apogee_delay, int main_deploy) { this.apogee_delay = apogee_delay; this.main_deploy = main_deploy; + } + + public void set_config(int major, int minor, int flight_log_max) { + config_major = major; + config_minor = minor; this.flight_log_max = flight_log_max; } @@ -1104,6 +1203,10 @@ public class AltosState implements Cloneable { this.ignitor_voltage = voltage; } + public void set_pyro_fired(int fired) { + this.pyro_fired = fired; + } + public double time_since_boost() { if (tick == AltosLib.MISSING) return 0.0; diff --git a/altoslib/AltosStateIterable.java b/altoslib/AltosStateIterable.java index 5a919b66..be812095 100644 --- a/altoslib/AltosStateIterable.java +++ b/altoslib/AltosStateIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -24,6 +24,6 @@ public abstract class AltosStateIterable implements Iterable<AltosState> { public void write_comments (PrintStream out) { } - + public abstract void write(PrintStream out); } diff --git a/altoslib/AltosStateUpdate.java b/altoslib/AltosStateUpdate.java index 4614c67a..ac4e963e 100644 --- a/altoslib/AltosStateUpdate.java +++ b/altoslib/AltosStateUpdate.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public interface AltosStateUpdate { public void update_state(AltosState state) throws InterruptedException; diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index 01bedd5e..8182ec6b 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_3; +package org.altusmetrum.altoslib_4; import java.text.*; @@ -43,9 +43,9 @@ public abstract class AltosTelemetry implements AltosStateUpdate { } public void update_state(AltosState state) { + state.set_serial(serial); if (state.state == AltosLib.ao_flight_invalid) state.set_state(AltosLib.ao_flight_startup); - state.set_serial(serial); state.set_tick(tick); state.set_rssi(rssi, status); state.set_received_time(received_time); @@ -67,7 +67,7 @@ public abstract class AltosTelemetry implements AltosStateUpdate { final static int packet_type_metrum_sensor = 0x0a; final static int packet_type_metrum_data = 0x0b; final static int packet_type_mini = 0x10; - + static AltosTelemetry parse_hex(String hex) throws ParseException, AltosCRCException { AltosTelemetry telem = null; diff --git a/altoslib/AltosTelemetryConfiguration.java b/altoslib/AltosTelemetryConfiguration.java index 67a43748..e3884051 100644 --- a/altoslib/AltosTelemetryConfiguration.java +++ b/altoslib/AltosTelemetryConfiguration.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetryConfiguration extends AltosTelemetryStandard { @@ -25,6 +25,7 @@ public class AltosTelemetryConfiguration extends AltosTelemetryStandard { int config_minor; int apogee_delay; int main_deploy; + int v_batt; int flight_log_max; String callsign; String version; @@ -36,6 +37,7 @@ public class AltosTelemetryConfiguration extends AltosTelemetryStandard { flight = uint16(6); config_major = uint8(8); config_minor = uint8(9); + v_batt = uint16(10); apogee_delay = uint16(10); main_deploy = uint16(12); flight_log_max = uint16(14); @@ -47,7 +49,11 @@ public class AltosTelemetryConfiguration extends AltosTelemetryStandard { super.update_state(state); state.set_device_type(device_type); state.set_flight(flight); - state.set_config(config_major, config_minor, apogee_delay, main_deploy, flight_log_max); + state.set_config(config_major, config_minor, flight_log_max); + if (device_type == AltosLib.product_telegps) + state.set_battery_voltage(AltosConvert.tele_gps_voltage(v_batt)); + else + state.set_flight_params(apogee_delay, main_deploy); state.set_callsign(callsign); state.set_firmware_version(version); diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java index 09d7d3f8..3d3fa407 100644 --- a/altoslib/AltosTelemetryFile.java +++ b/altoslib/AltosTelemetryFile.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; @@ -62,7 +62,7 @@ public class AltosTelemetryFile extends AltosStateIterable { } public void write(PrintStream out) { - + } public AltosTelemetryFile(FileInputStream input) { diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index 002f53b4..cba97ddc 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_3; +package org.altusmetrum.altoslib_4; import java.io.*; import java.util.*; diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index d302addd..3367ece7 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; import java.text.*; @@ -470,7 +470,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry { batt = int16(29); apogee = int16(31); main = int16(33); - + ground_accel = int16(7); ground_pres = int16(15); accel_plus_g = int16(17); diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index 8dcda9e1..8368188f 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetryLocation extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMap.java b/altoslib/AltosTelemetryMap.java index 37b2527b..8d0de355 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_3; +package org.altusmetrum.altoslib_4; import java.text.*; import java.util.HashMap; diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java index a4df70be..fac5695f 100644 --- a/altoslib/AltosTelemetryMegaData.java +++ b/altoslib/AltosTelemetryMegaData.java @@ -15,11 +15,11 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetryMegaData extends AltosTelemetryStandard { int state; - + int v_batt; int v_pyro; int sense[]; @@ -41,7 +41,7 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard { v_batt = int16(6); v_pyro = int16(8); - sense = new int[6]; + sense = new int[6]; for (int i = 0; i < 6; i++) { sense[i] = int8(10 + i) << 4; @@ -62,7 +62,7 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard { super.update_state(state); state.set_state(this.state); - + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt)); state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro)); diff --git a/altoslib/AltosTelemetryMegaSensor.java b/altoslib/AltosTelemetryMegaSensor.java index d1a463c0..9e73bc4e 100644 --- a/altoslib/AltosTelemetryMegaSensor.java +++ b/altoslib/AltosTelemetryMegaSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetryMegaSensor extends AltosTelemetryStandard { int accel; @@ -67,7 +67,7 @@ public class AltosTelemetryMegaSensor extends AltosTelemetryStandard { state.set_orient(orient); AltosIMU imu = new AltosIMU(); - + imu.accel_x = AltosIMU.convert_accel(accel_x); imu.accel_y = AltosIMU.convert_accel(accel_y); imu.accel_z = AltosIMU.convert_accel(accel_z); diff --git a/altoslib/AltosTelemetryMetrumData.java b/altoslib/AltosTelemetryMetrumData.java index b8f7e9ea..96617306 100644 --- a/altoslib/AltosTelemetryMetrumData.java +++ b/altoslib/AltosTelemetryMetrumData.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetryMetrumData extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java index 232468bb..e7055404 100644 --- a/altoslib/AltosTelemetryMetrumSensor.java +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMini.java b/altoslib/AltosTelemetryMini.java index e0a493dc..fbfaff8e 100644 --- a/altoslib/AltosTelemetryMini.java +++ b/altoslib/AltosTelemetryMini.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetryMini extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryRaw.java b/altoslib/AltosTelemetryRaw.java index 91cfbb18..0dca62aa 100644 --- a/altoslib/AltosTelemetryRaw.java +++ b/altoslib/AltosTelemetryRaw.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetryRaw extends AltosTelemetryStandard { public AltosTelemetryRaw(int[] bytes) { diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index 5e283587..3dff661a 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_3; +package org.altusmetrum.altoslib_4; import java.text.*; import java.io.*; diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java index 01252bde..d611e88c 100644 --- a/altoslib/AltosTelemetrySatellite.java +++ b/altoslib/AltosTelemetrySatellite.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetrySatellite extends AltosTelemetryStandard { int channels; @@ -43,7 +43,7 @@ public class AltosTelemetrySatellite extends AltosTelemetryStandard { super.update_state(state); AltosGPS gps = state.make_temp_gps(true); - + gps.cc_gps_sat = sats; state.set_temp_gps(); } diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java index d6389865..ad4d9283 100644 --- a/altoslib/AltosTelemetrySensor.java +++ b/altoslib/AltosTelemetrySensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTelemetrySensor extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java index c9531fcb..23ae9d21 100644 --- a/altoslib/AltosTelemetryStandard.java +++ b/altoslib/AltosTelemetryStandard.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public abstract class AltosTelemetryStandard extends AltosTelemetry { int[] bytes; diff --git a/altoslib/AltosTemperature.java b/altoslib/AltosTemperature.java index 36e26564..5fa71b86 100644 --- a/altoslib/AltosTemperature.java +++ b/altoslib/AltosTemperature.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public class AltosTemperature extends AltosUnits { diff --git a/altoslib/AltosUnits.java b/altoslib/AltosUnits.java index e573a43b..d29cfae7 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_3; +package org.altusmetrum.altoslib_4; public abstract class AltosUnits { @@ -41,7 +41,7 @@ public abstract class AltosUnits { public double value(double v) { return value(v, AltosConvert.imperial_units); } - + public double inverse(double v) { return inverse(v, AltosConvert.imperial_units); } @@ -49,15 +49,15 @@ public abstract class AltosUnits { public String show_units() { return show_units(AltosConvert.imperial_units); } - + public String say_units() { return say_units(AltosConvert.imperial_units); } - + public int show_fraction(int width) { return show_fraction(width, AltosConvert.imperial_units); } - + int say_fraction(boolean imperial_units) { return 0; } diff --git a/altoslib/AltosUnitsListener.java b/altoslib/AltosUnitsListener.java index e9b29f9a..ca6faafd 100644 --- a/altoslib/AltosUnitsListener.java +++ b/altoslib/AltosUnitsListener.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_3; +package org.altusmetrum.altoslib_4; public interface AltosUnitsListener { public void units_changed(boolean imperial_units); diff --git a/altoslib/AltosVoltage.java b/altoslib/AltosVoltage.java new file mode 100644 index 00000000..351bf115 --- /dev/null +++ b/altoslib/AltosVoltage.java @@ -0,0 +1,41 @@ +/* + * 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_4; + +public class AltosVoltage extends AltosUnits { + + public double value(double v, boolean imperial_units) { + return v; + } + + public double inverse(double v, boolean imperial_units) { + return v; + } + + public String show_units(boolean imperial_units) { + return "V"; + } + + public String say_units(boolean imperial_units) { + return "volts"; + } + + public int show_fraction(int width, boolean imperial_units) { + return 2; + } +} diff --git a/altoslib/AltosWriter.java b/altoslib/AltosWriter.java new file mode 100644 index 00000000..c3479a93 --- /dev/null +++ b/altoslib/AltosWriter.java @@ -0,0 +1,27 @@ +/* + * 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_4; + +public interface AltosWriter { + + public void write(AltosState state); + + public void write(AltosStateIterable states); + + public void close(); +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 2ee4d89f..e81418bb 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -1,4 +1,4 @@ -AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6 +AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked -source 6 JAVAROOT=bin @@ -28,9 +28,11 @@ altoslib_JAVA = \ AltosLib.java \ AltosCompanion.java \ AltosConfigData.java \ + AltosConfigDataException.java \ AltosConfigValues.java \ AltosConvert.java \ AltosCRCException.java \ + AltosCSV.java \ AltosDebug.java \ AltosEeprom.java \ AltosEepromChunk.java \ @@ -45,11 +47,13 @@ altoslib_JAVA = \ AltosEepromMega.java \ AltosEepromMetrum2.java \ AltosEepromMini.java \ + AltosEepromGPS.java \ AltosEepromMonitor.java \ AltosFile.java \ AltosFlash.java \ AltosFlashListener.java \ AltosFlightReader.java \ + AltosFlightStats.java \ AltosFrequency.java \ AltosGPS.java \ AltosGPSSat.java \ @@ -62,6 +66,7 @@ altoslib_JAVA = \ AltosIdleMonitorListener.java \ AltosIgnite.java \ AltosIMU.java \ + AltosKML.java \ AltosLine.java \ AltosLink.java \ AltosListenerState.java \ @@ -114,7 +119,12 @@ altoslib_JAVA = \ AltosSpeed.java \ AltosTemperature.java \ AltosAccel.java \ - AltosPyro.java + AltosVoltage.java \ + AltosLocation.java \ + AltosLatitude.java \ + AltosLongitude.java \ + AltosPyro.java \ + AltosWriter.java JAR=altoslib_$(ALTOSLIB_VERSION).jar |