From 10f3d0084ff1c0b3dbf28c5d44727b514caeee20 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 17 Jun 2013 14:00:43 -0700 Subject: altosui: Add raw pressure to the AltosUI graph A nice addition, and useful when diagnosing baro sensor issues Signed-off-by: Keith Packard --- altoslib/AltosState.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 825306be..e0d9bb1f 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -40,6 +40,7 @@ public class AltosState { public double ground_altitude; public double altitude; public double height; + public double pressure; public double acceleration; public double battery; public double temperature; @@ -125,6 +126,7 @@ public class AltosState { drogue_sense = data.drogue_voltage(); main_sense = data.main_voltage(); battery = data.battery_voltage(); + pressure = data.pressure(); tick = data.tick; state = data.state; -- cgit v1.2.3 From 04d7d0f829ba953ffeca8ad9887a4b6b2b5d5087 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 27 Aug 2013 21:28:07 -0600 Subject: altoslib: Start restructuring AltosState harder Make per-packet code update state itself rather than having all state updates done centrally. Will make adding new packet types easier. Signed-off-by: Keith Packard --- altoslib/AltosCompanion.java | 38 ++ altoslib/AltosEeprom.java | 89 +++++ altoslib/AltosEepromBody.java | 31 ++ altoslib/AltosEepromBodyIterable.java | 28 ++ altoslib/AltosEepromFile.java | 51 +++ altoslib/AltosEepromHeader.java | 267 +++++++++++++ altoslib/AltosEepromHeaderIterable.java | 48 +++ altoslib/AltosEepromIterable.java | 422 +------------------- altoslib/AltosEepromMetrum.java | 214 ++++++++++ altoslib/AltosEepromMetrumIterable.java | 358 +++++++++++++++++ altoslib/AltosEepromMini.java | 159 ++------ altoslib/AltosEepromOldIterable.java | 435 +++++++++++++++++++++ altoslib/AltosEepromTM.java | 255 ++++++++++++ altoslib/AltosGPS.java | 35 +- altoslib/AltosGreatCircle.java | 12 +- altoslib/AltosIMU.java | 14 +- altoslib/AltosMag.java | 11 +- altoslib/AltosOrderedMetrumRecord.java | 52 +++ altoslib/AltosRecordMini.java | 4 + altoslib/AltosRecordTM2.java | 156 ++++++++ altoslib/AltosSelfFlash.java | 149 +++++++ altoslib/AltosSensorMetrum.java | 55 +++ altoslib/AltosState.java | 517 +++++++++++++++++++++---- altoslib/AltosStateUpdate.java | 22 ++ altoslib/AltosTelemetryRecord.java | 1 + altoslib/AltosTelemetryRecordMetrumData.java | 54 +++ altoslib/AltosTelemetryRecordMetrumSensor.java | 81 ++++ altoslib/AltosTelemetryRecordMini.java | 82 ++++ altoslib/Makefile.am | 6 + 29 files changed, 3034 insertions(+), 612 deletions(-) create mode 100644 altoslib/AltosCompanion.java create mode 100644 altoslib/AltosEeprom.java create mode 100644 altoslib/AltosEepromBody.java create mode 100644 altoslib/AltosEepromBodyIterable.java create mode 100644 altoslib/AltosEepromFile.java create mode 100644 altoslib/AltosEepromHeader.java create mode 100644 altoslib/AltosEepromHeaderIterable.java create mode 100644 altoslib/AltosEepromMetrum.java create mode 100644 altoslib/AltosEepromMetrumIterable.java create mode 100644 altoslib/AltosEepromOldIterable.java create mode 100644 altoslib/AltosEepromTM.java create mode 100644 altoslib/AltosOrderedMetrumRecord.java create mode 100644 altoslib/AltosRecordTM2.java create mode 100644 altoslib/AltosSelfFlash.java create mode 100644 altoslib/AltosSensorMetrum.java create mode 100644 altoslib/AltosStateUpdate.java create mode 100644 altoslib/AltosTelemetryRecordMetrumData.java create mode 100644 altoslib/AltosTelemetryRecordMetrumSensor.java create mode 100644 altoslib/AltosTelemetryRecordMini.java (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosCompanion.java b/altoslib/AltosCompanion.java new file mode 100644 index 00000000..1572fdae --- /dev/null +++ b/altoslib/AltosCompanion.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosCompanion { + public final static int board_id_telescience = 0x0a; + public final static int MAX_CHANNELS = 12; + + public int tick; + public int board_id; + public int update_period; + public int channels; + public int[] companion_data; + + public AltosCompanion(int in_channels) { + channels = in_channels; + if (channels < 0) + channels = 0; + if (channels > MAX_CHANNELS) + channels = MAX_CHANNELS; + companion_data = new int[channels]; + } +} diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java new file mode 100644 index 00000000..31646c7e --- /dev/null +++ b/altoslib/AltosEeprom.java @@ -0,0 +1,89 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public abstract class AltosEeprom implements AltosStateUpdate { + public int cmd; + public int tick; + public int data8[]; + public boolean valid; + + public final static int header_length = 4; + + public abstract void update_state(AltosState state); + + public void write(PrintStream out) { + out.printf("%c %04x", cmd, tick); + if (data8 != null) { + for (int i = 0; i < data8.length; i++) + out.printf (" %02x", data8[i]); + } + out.printf ("\n"); + } + + void parse_chunk(AltosEepromChunk chunk, int start, int record_length) throws ParseException { + cmd = chunk.data(start); + + int data_length = record_length - header_length; + + valid = !chunk.erased(start, record_length); + if (valid) { + if (AltosConvert.checksum(chunk.data, start, record_length) != 0) + throw new ParseException(String.format("invalid checksum at 0x%x", + chunk.address + start), 0); + } else { + cmd = AltosLib.AO_LOG_INVALID; + } + + tick = chunk.data16(start+2); + + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = chunk.data(start + header_length + i); + } + + void parse_string(String line, int record_length) { + valid = false; + tick = 0; + cmd = AltosLib.AO_LOG_INVALID; + + int data_length = record_length - header_length; + + if (line == null) + return; + try { + String[] tokens = line.split("\\s+"); + + if (tokens[0].length() == 1) { + if (tokens.length == 2 + data_length) { + cmd = tokens[0].codePointAt(0); + tick = Integer.parseInt(tokens[1],16); + valid = true; + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = Integer.parseInt(tokens[2 + i],16); + } + } + } catch (NumberFormatException ne) { + } + } +} diff --git a/altoslib/AltosEepromBody.java b/altoslib/AltosEepromBody.java new file mode 100644 index 00000000..60aa8881 --- /dev/null +++ b/altoslib/AltosEepromBody.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromBody implements AltosEeprom, AltosStateUpdate { + + public void update_state(AltosState state) { + } + + public void write(PrintStream out) { + } +} \ No newline at end of file diff --git a/altoslib/AltosEepromBodyIterable.java b/altoslib/AltosEepromBodyIterable.java new file mode 100644 index 00000000..33dc0ac8 --- /dev/null +++ b/altoslib/AltosEepromBodyIterable.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromBodyIterable { + LinkedList bodies; + + +} \ No newline at end of file diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java new file mode 100644 index 00000000..48d2543c --- /dev/null +++ b/altoslib/AltosEepromFile.java @@ -0,0 +1,51 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromFile { + + AltosEepromIterable headers; + AltosEepromIterable body; + + public void write(PrintStream out) { + headers.write(out); + body.write(out); + } + + public AltosEepromFile(FileInputStream input) { + headers = new AltosEepromIterable(AltosEepromHeader.read(input)); + + AltosState state = headers.state(); + + switch (state.log_format) { + case AltosLib.AO_LOG_FORMAT_FULL: + case AltosLib.AO_LOG_FORMAT_TINY: + case AltosLib.AO_LOG_FORMAT_TELEMETRY: + case AltosLib.AO_LOG_FORMAT_TELESCIENCE: + case AltosLib.AO_LOG_FORMAT_TELEMEGA: + break; + case AltosLib.AO_LOG_FORMAT_MINI: + body = new AltosEepromIterable(AltosEepromMini.read(input)); + break; + } + } +} \ No newline at end of file diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java new file mode 100644 index 00000000..b2343dc6 --- /dev/null +++ b/altoslib/AltosEepromHeader.java @@ -0,0 +1,267 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromHeader extends AltosEeprom { + + public int cmd; + public String data; + public int config_a, config_b; + public boolean last; + public boolean valid; + + public void update_state(AltosState state) { + switch (cmd) { + case AltosLib.AO_LOG_CONFIG_VERSION: + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + break; + case AltosLib.AO_LOG_CALLSIGN: + state.callsign = data; + break; + case AltosLib.AO_LOG_ACCEL_CAL: + state.accel_plus_g = config_a; + state.accel_minus_g = config_b; + break; + case AltosLib.AO_LOG_RADIO_CAL: + break; + case AltosLib.AO_LOG_MANUFACTURER: + break; + case AltosLib.AO_LOG_PRODUCT: + break; + case AltosLib.AO_LOG_LOG_FORMAT: + state.log_format = config_a; + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + state.serial = config_a; + break; + case AltosLib.AO_LOG_BARO_RESERVED: + state.baro.reserved = config_a; + break; + case AltosLib.AO_LOG_BARO_SENS: + state.baro.sens = config_a; + break; + case AltosLib.AO_LOG_BARO_OFF: + state.baro.off = config_a; + break; + case AltosLib.AO_LOG_BARO_TCS: + state.baro.tcs = config_a; + break; + case AltosLib.AO_LOG_BARO_TCO: + state.baro.tco = config_a; + break; + case AltosLib.AO_LOG_BARO_TREF: + state.baro.tref = config_a; + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + state.baro.tempsens = config_a; + break; + case AltosLib.AO_LOG_BARO_CRC: + state.baro.crc = config_a; + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + break; + } + } + + public void write(PrintStream out) { + switch (cmd) { + case AltosLib.AO_LOG_CONFIG_VERSION: + out.printf("# Config version: %s\n", data); + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + out.printf("# Main deploy: %s\n", config_a); + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + out.printf("# Apogee delay: %s\n", config_a); + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + out.printf("# Radio channel: %s\n", config_a); + break; + case AltosLib.AO_LOG_CALLSIGN: + out.printf("# Callsign: %s\n", data); + break; + case AltosLib.AO_LOG_ACCEL_CAL: + out.printf ("# Accel cal: %d %d\n", config_a, config_b); + break; + case AltosLib.AO_LOG_RADIO_CAL: + out.printf ("# Radio cal: %d\n", config_a); + break; + case AltosLib.AO_LOG_MAX_FLIGHT_LOG: + out.printf ("# Max flight log: %d\n", config_a); + break; + case AltosLib.AO_LOG_MANUFACTURER: + out.printf ("# Manufacturer: %s\n", data); + break; + case AltosLib.AO_LOG_PRODUCT: + out.printf ("# Product: %s\n", data); + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + out.printf ("# Serial number: %d\n", config_a); + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + out.printf ("# Software version: %s\n", data); + break; + case AltosLib.AO_LOG_BARO_RESERVED: + out.printf ("# Baro reserved: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_SENS: + out.printf ("# Baro sens: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_OFF: + out.printf ("# Baro off: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_TCS: + out.printf ("# Baro tcs: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_TCO: + out.printf ("# Baro tco: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_TREF: + out.printf ("# Baro tref: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + out.printf ("# Baro tempsens: %d\n", config_a); + break; + case AltosLib.AO_LOG_BARO_CRC: + out.printf ("# Baro crc: %d\n", config_a); + break; + } + } + + public AltosEepromHeader (String[] tokens) { + last = false; + valid = true; + try { + if (tokens[0].equals("Config") && tokens[1].equals("version:")) { + cmd = AltosLib.AO_LOG_CONFIG_VERSION; + data = tokens[2]; + } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { + cmd = AltosLib.AO_LOG_MAIN_DEPLOY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { + cmd = AltosLib.AO_LOG_APOGEE_DELAY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { + cmd = AltosLib.AO_LOG_RADIO_CHANNEL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Callsign:")) { + cmd = AltosLib.AO_LOG_CALLSIGN; + data = tokens[1].replaceAll("\"",""); + } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { + cmd = AltosLib.AO_LOG_ACCEL_CAL; + config_a = Integer.parseInt(tokens[3]); + config_b = Integer.parseInt(tokens[5]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { + cmd = AltosLib.AO_LOG_RADIO_CAL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { + cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; + config_a = Integer.parseInt(tokens[3]); + } else if (tokens[0].equals("manufacturer")) { + cmd = AltosLib.AO_LOG_MANUFACTURER; + data = tokens[1]; + } else if (tokens[0].equals("product")) { + cmd = AltosLib.AO_LOG_PRODUCT; + data = tokens[1]; + } else if (tokens[0].equals("serial-number")) { + cmd = AltosLib.AO_LOG_SERIAL_NUMBER; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("log-format")) { + cmd = AltosLib.AO_LOG_LOG_FORMAT; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("software-version")) { + cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; + data = tokens[1]; + last = true; + } else if (tokens[0].equals("ms5607")) { + if (tokens[1].equals("reserved:")) { + cmd = AltosLib.AO_LOG_BARO_RESERVED; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("sens:")) { + cmd = AltosLib.AO_LOG_BARO_SENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("off:")) { + cmd = AltosLib.AO_LOG_BARO_OFF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tcs:")) { + cmd = AltosLib.AO_LOG_BARO_TCS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tco:")) { + cmd = AltosLib.AO_LOG_BARO_TCO; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tref:")) { + cmd = AltosLib.AO_LOG_BARO_TREF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tempsens:")) { + cmd = AltosLib.AO_LOG_BARO_TEMPSENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("crc:")) { + cmd = AltosLib.AO_LOG_BARO_CRC; + config_a = Integer.parseInt(tokens[2]); + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = tokens[2]; + } + } else + valid = false; + } catch (Exception e) { + valid = false; + } + } + + static public LinkedList read(FileInputStream input) { + LinkedList headers = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosEepromHeader header = new AltosEepromHeader(line); + headers.add(header); + if (header.last) + break; + } catch (IOException ie) { + break; + } + } + + return headers; + } + + static public void write (PrintStream out, LinkedList headers) { + out.printf("# Comments\n"); + for (AltosEepromHeader header : headers) { + header.write(out); + } + + } + + public AltosEepromHeader (String line) { + this(line.split("\\s+")); + } +} diff --git a/altoslib/AltosEepromHeaderIterable.java b/altoslib/AltosEepromHeaderIterable.java new file mode 100644 index 00000000..fe9e05d9 --- /dev/null +++ b/altoslib/AltosEepromHeaderIterable.java @@ -0,0 +1,48 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromHeaderIterable implements Iterable { + public LinkedList headers; + + public void write(PrintStream out) { + AltosEepromHeader.write(out, headers); + } + + public AltosState state() { + AltosState state = new AltosState(null); + + for (AltosEepromHeader header : headers) + header.update_state(state); + return state; + } + + public AltosEepromHeaderIterable(FileInputStream input) { + headers = AltosEepromHeader.read(input); + } + + public Iterator iterator() { + if (headers == null) + headers = new LinkedList(); + return headers.iterator(); + } +} \ No newline at end of file diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index b84574ef..470a7a8a 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -1,5 +1,5 @@ /* - * Copyright © 2010 Keith Packard + * Copyright © 2013 Keith Packard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,415 +21,29 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosEepromIterable extends AltosRecordIterable { +public class AltosEepromIterable implements Iterable { + public LinkedList eeproms; - static final int seen_basic = AltosRecord.seen_flight|AltosRecord.seen_sensor; - - boolean has_accel; - boolean has_gps; - boolean has_ignite; - - AltosEepromRecord flight_record; - AltosEepromRecord gps_date_record; - - TreeSet records; - - LinkedList list; - - class EepromState { - int seen; - int n_pad_samples; - double ground_pres; - int gps_tick; - int boost_tick; - int sensor_tick; - - EepromState() { - seen = 0; - n_pad_samples = 0; - ground_pres = 0.0; - gps_tick = 0; - } - } - - void update_state(AltosRecordTM state, AltosEepromRecord record, EepromState eeprom) { - state.tick = record.tick; - switch (record.cmd) { - case AltosLib.AO_LOG_FLIGHT: - eeprom.seen |= AltosRecord.seen_flight; - state.ground_accel = record.a; - state.flight_accel = record.a; - state.flight = record.b; - eeprom.boost_tick = record.tick; - break; - case AltosLib.AO_LOG_SENSOR: - state.accel = record.a; - state.pres = record.b; - if (state.state < AltosLib.ao_flight_boost) { - eeprom.n_pad_samples++; - eeprom.ground_pres += state.pres; - state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); - state.flight_pres = state.ground_pres; - } else { - state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; - } - state.flight_accel = (state.flight_accel * 15 + state.accel) / 16; - if ((eeprom.seen & AltosRecord.seen_sensor) == 0) - eeprom.sensor_tick = record.tick - 1; - state.flight_vel += (state.accel_plus_g - state.accel) * (record.tick - eeprom.sensor_tick); - eeprom.seen |= AltosRecord.seen_sensor; - eeprom.sensor_tick = record.tick; - has_accel = true; - break; - case AltosLib.AO_LOG_PRESSURE: - state.pres = record.b; - state.flight_pres = state.pres; - if (eeprom.n_pad_samples == 0) { - eeprom.n_pad_samples++; - state.ground_pres = state.pres; - } - eeprom.seen |= AltosRecord.seen_sensor; - break; - case AltosLib.AO_LOG_TEMP_VOLT: - state.temp = record.a; - state.batt = record.b; - eeprom.seen |= AltosRecord.seen_temp_volt; - break; - case AltosLib.AO_LOG_DEPLOY: - state.drogue = record.a; - state.main = record.b; - eeprom.seen |= AltosRecord.seen_deploy; - has_ignite = true; - break; - case AltosLib.AO_LOG_STATE: - state.state = record.a; - break; - case AltosLib.AO_LOG_GPS_TIME: - eeprom.gps_tick = state.tick; - eeprom.seen |= AltosRecord.seen_gps_time; - AltosGPS old = state.gps; - state.gps = new AltosGPS(); - - /* GPS date doesn't get repeated through the file */ - if (old != null) { - state.gps.year = old.year; - state.gps.month = old.month; - state.gps.day = old.day; - } - state.gps.hour = (record.a & 0xff); - state.gps.minute = (record.a >> 8); - state.gps.second = (record.b & 0xff); - - int flags = (record.b >> 8); - state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; - state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; - state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> - AltosLib.AO_GPS_NUM_SAT_SHIFT; - state.gps_sequence++; - has_gps = true; - break; - case AltosLib.AO_LOG_GPS_LAT: - eeprom.seen |= AltosRecord.seen_gps_lat; - int lat32 = record.a | (record.b << 16); - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.lat = (double) lat32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_LON: - eeprom.seen |= AltosRecord.seen_gps_lon; - int lon32 = record.a | (record.b << 16); - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.lon = (double) lon32 / 1e7; - break; - case AltosLib.AO_LOG_GPS_ALT: - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.alt = record.a; - break; - case AltosLib.AO_LOG_GPS_SAT: - if (state.tick == eeprom.gps_tick) { - int svid = record.a; - int c_n0 = record.b >> 8; - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.add_sat(svid, c_n0); - } - break; - case AltosLib.AO_LOG_GPS_DATE: - if (state.gps == null) - state.gps = new AltosGPS(); - state.gps.year = (record.a & 0xff) + 2000; - state.gps.month = record.a >> 8; - state.gps.day = record.b & 0xff; - break; - - case AltosLib.AO_LOG_CONFIG_VERSION: - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - break; - case AltosLib.AO_LOG_CALLSIGN: - state.callsign = record.data; - break; - case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = record.a; - state.accel_minus_g = record.b; - break; - case AltosLib.AO_LOG_RADIO_CAL: - break; - case AltosLib.AO_LOG_MANUFACTURER: - break; - case AltosLib.AO_LOG_PRODUCT: - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = record.a; - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - break; - } - state.seen |= eeprom.seen; + public void write(PrintStream out) { + for (AltosEeprom eeprom : eeproms) + eeprom.write(out); } - LinkedList make_list() { - LinkedList list = new LinkedList(); - Iterator iterator = records.iterator(); - AltosOrderedRecord record = null; - AltosRecordTM state = new AltosRecordTM(); - //boolean last_reported = false; - EepromState eeprom = new EepromState(); - - state.state = AltosLib.ao_flight_pad; - state.accel_plus_g = 15758; - state.accel_minus_g = 16294; - state.flight_vel = 0; + public AltosState state() { + AltosState state = new AltosState(null); - /* Pull in static data from the flight and gps_date records */ - if (flight_record != null) - update_state(state, flight_record, eeprom); - if (gps_date_record != null) - update_state(state, gps_date_record, eeprom); - - while (iterator.hasNext()) { - record = iterator.next(); - if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { - AltosRecordTM r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - } - update_state(state, record, eeprom); - } - AltosRecordTM r = state.clone(); - r.time = (r.tick - eeprom.boost_tick) / 100.0; - list.add(r); - return list; - } - - public Iterator iterator() { - if (list == null) - list = make_list(); - return list.iterator(); + for (AltosEeprom header : eeproms) + header.update_state(state); + return state; } - public boolean has_gps() { return has_gps; } - public boolean has_accel() { return has_accel; } - public boolean has_ignite() { return has_ignite; } - - public void write_comments(PrintStream out) { - Iterator iterator = records.iterator(); - out.printf("# Comments\n"); - while (iterator.hasNext()) { - AltosOrderedRecord record = iterator.next(); - switch (record.cmd) { - case AltosLib.AO_LOG_CONFIG_VERSION: - out.printf("# Config version: %s\n", record.data); - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - out.printf("# Main deploy: %s\n", record.a); - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - out.printf("# Apogee delay: %s\n", record.a); - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - out.printf("# Radio channel: %s\n", record.a); - break; - case AltosLib.AO_LOG_CALLSIGN: - out.printf("# Callsign: %s\n", record.data); - break; - case AltosLib.AO_LOG_ACCEL_CAL: - out.printf ("# Accel cal: %d %d\n", record.a, record.b); - break; - case AltosLib.AO_LOG_RADIO_CAL: - out.printf ("# Radio cal: %d\n", record.a); - break; - case AltosLib.AO_LOG_MAX_FLIGHT_LOG: - out.printf ("# Max flight log: %d\n", record.a); - break; - case AltosLib.AO_LOG_MANUFACTURER: - out.printf ("# Manufacturer: %s\n", record.data); - break; - case AltosLib.AO_LOG_PRODUCT: - out.printf ("# Product: %s\n", record.data); - break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - out.printf ("# Serial number: %d\n", record.a); - break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: - out.printf ("# Software version: %s\n", record.data); - break; - case AltosLib.AO_LOG_BARO_RESERVED: - out.printf ("# Baro reserved: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_SENS: - out.printf ("# Baro sens: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_OFF: - out.printf ("# Baro off: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TCS: - out.printf ("# Baro tcs: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TCO: - out.printf ("# Baro tco: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TREF: - out.printf ("# Baro tref: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_TEMPSENS: - out.printf ("# Baro tempsens: %d\n", record.a); - break; - case AltosLib.AO_LOG_BARO_CRC: - out.printf ("# Baro crc: %d\n", record.a); - break; - } - } + public AltosEepromIterable(LinkedList eeproms) { + this.eeproms = eeproms; } - /* - * Given an AO_LOG_GPS_TIME record with correct time, and one - * missing time, rewrite the missing time values with the good - * ones, assuming that the difference between them is 'diff' seconds - */ - void update_time(AltosOrderedRecord good, AltosOrderedRecord bad) { - - int diff = (bad.tick - good.tick + 50) / 100; - - int hour = (good.a & 0xff); - int minute = (good.a >> 8); - int second = (good.b & 0xff); - int flags = (good.b >> 8); - int seconds = hour * 3600 + minute * 60 + second; - - /* Make sure this looks like a good GPS value */ - if ((flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT < 4) - flags = (flags & ~AltosLib.AO_GPS_NUM_SAT_MASK) | (4 << AltosLib.AO_GPS_NUM_SAT_SHIFT); - flags |= AltosLib.AO_GPS_RUNNING; - flags |= AltosLib.AO_GPS_VALID; - - int new_seconds = seconds + diff; - if (new_seconds < 0) - new_seconds += 24 * 3600; - int new_second = (new_seconds % 60); - int new_minutes = (new_seconds / 60); - int new_minute = (new_minutes % 60); - int new_hours = (new_minutes / 60); - int new_hour = (new_hours % 24); - - bad.a = new_hour + (new_minute << 8); - bad.b = new_second + (flags << 8); - } - - /* - * Read the whole file, dumping records into a RB tree so - * we can enumerate them in time order -- the eeprom data - * are sometimes out of order with GPS data getting timestamps - * matching the first packet out of the GPS unit but not - * written until the final GPS packet has been received. - */ - public AltosEepromIterable (FileInputStream input) { - records = new TreeSet(); - - AltosOrderedRecord last_gps_time = null; - - int index = 0; - int prev_tick = 0; - boolean prev_tick_valid = false; - boolean missing_time = false; - - try { - for (;;) { - String line = AltosLib.gets(input); - if (line == null) - break; - AltosOrderedRecord record = new AltosOrderedRecord(line, index++, prev_tick, prev_tick_valid); - if (record.cmd == AltosLib.AO_LOG_INVALID) - continue; - prev_tick = record.tick; - if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) - prev_tick_valid = true; - if (record.cmd == AltosLib.AO_LOG_FLIGHT) { - flight_record = record; - continue; - } - - /* Two firmware bugs caused the loss of some GPS data. - * The flight date would never be recorded, and often - * the flight time would get overwritten by another - * record. Detect the loss of the GPS date and fix up the - * missing time records - */ - if (record.cmd == AltosLib.AO_LOG_GPS_DATE) { - gps_date_record = record; - continue; - } - - /* go back and fix up any missing time values */ - if (record.cmd == AltosLib.AO_LOG_GPS_TIME) { - last_gps_time = record; - if (missing_time) { - Iterator iterator = records.iterator(); - while (iterator.hasNext()) { - AltosOrderedRecord old = iterator.next(); - if (old.cmd == AltosLib.AO_LOG_GPS_TIME && - old.a == -1 && old.b == -1) - { - update_time(record, old); - } - } - missing_time = false; - } - } - - if (record.cmd == AltosLib.AO_LOG_GPS_LAT) { - if (last_gps_time == null || last_gps_time.tick != record.tick) { - AltosOrderedRecord add_gps_time = new AltosOrderedRecord(AltosLib.AO_LOG_GPS_TIME, - record.tick, - -1, -1, index-1); - if (last_gps_time != null) - update_time(last_gps_time, add_gps_time); - else - missing_time = true; - - records.add(add_gps_time); - record.index = index++; - } - } - records.add(record); - - /* Bail after reading the 'landed' record; we're all done */ - if (record.cmd == AltosLib.AO_LOG_STATE && - record.a == AltosLib.ao_flight_landed) - break; - } - } catch (IOException io) { - } catch (ParseException pe) { - } - try { - input.close(); - } catch (IOException ie) { - } + public Iterator iterator() { + if (eeproms == null) + eeproms = new LinkedList(); + return eeproms.iterator(); } -} +} \ No newline at end of file diff --git a/altoslib/AltosEepromMetrum.java b/altoslib/AltosEepromMetrum.java new file mode 100644 index 00000000..72887032 --- /dev/null +++ b/altoslib/AltosEepromMetrum.java @@ -0,0 +1,214 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.*; + +public class AltosEepromMetrum { + public int cmd; + public int tick; + public boolean valid; + public String data; + public int config_a, config_b; + + public int data8[]; + + public static final int record_length = 16; + static final int header_length = 4; + static final int data_length = record_length - header_length; + + public int data8(int i) { + return data8[i]; + } + + public int data16(int i) { + return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; + } + + public int data32(int i) { + return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); + } + + /* AO_LOG_FLIGHT elements */ + public int flight() { return data16(0); } + public int ground_accel() { return data16(2); } + public int ground_pres() { return data32(4); } + public int ground_temp() { return data32(8); } + + /* AO_LOG_STATE elements */ + public int state() { return data16(0); } + public int reason() { return data16(2); } + + /* AO_LOG_SENSOR elements */ + public int pres() { return data32(0); } + public int temp() { return data32(4); } + public int accel() { return data16(8); } + + /* AO_LOG_TEMP_VOLT elements */ + public int v_batt() { return data16(0); } + public int sense_a() { return data16(2); } + public int sense_m() { return data16(4); } + + /* AO_LOG_GPS_POS elements */ + public int latitude() { return data32(0); } + public int longitude() { return data32(4); } + public int altitude() { return data16(8); } + + /* AO_LOG_GPS_TIME elements */ + public int hour() { return data8(0); } + public int minute() { return data8(1); } + public int second() { return data8(2); } + public int flags() { return data8(3); } + public int year() { return data8(4); } + public int month() { return data8(5); } + public int day() { return data8(6); } + + /* AO_LOG_GPS_SAT elements */ + public int channels() { return data8(0); } + public int more() { return data8(1); } + public int svid(int n) { return data8(2 + n * 2); } + public int c_n(int n) { return data8(2 + n * 2 + 1); } + + public AltosEepromMetrum (AltosEepromChunk chunk, int start) throws ParseException { + cmd = chunk.data(start); + + valid = !chunk.erased(start, record_length); + if (valid) { + if (AltosConvert.checksum(chunk.data, start, record_length) != 0) + throw new ParseException(String.format("invalid checksum at 0x%x", + chunk.address + start), 0); + } else { + cmd = AltosLib.AO_LOG_INVALID; + } + + tick = chunk.data16(start+2); + + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = chunk.data(start + header_length + i); + } + + public AltosEepromMetrum (String line) { + valid = false; + tick = 0; + + if (line == null) { + cmd = AltosLib.AO_LOG_INVALID; + line = ""; + } else { + try { + String[] tokens = line.split("\\s+"); + + if (tokens[0].length() == 1) { + if (tokens.length != 2 + data_length) { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } else { + cmd = tokens[0].codePointAt(0); + tick = Integer.parseInt(tokens[1],16); + valid = true; + data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) + data8[i] = Integer.parseInt(tokens[2 + i],16); + } + } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { + cmd = AltosLib.AO_LOG_CONFIG_VERSION; + data = tokens[2]; + } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { + cmd = AltosLib.AO_LOG_MAIN_DEPLOY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { + cmd = AltosLib.AO_LOG_APOGEE_DELAY; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { + cmd = AltosLib.AO_LOG_RADIO_CHANNEL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Callsign:")) { + cmd = AltosLib.AO_LOG_CALLSIGN; + data = tokens[1].replaceAll("\"",""); + } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { + cmd = AltosLib.AO_LOG_ACCEL_CAL; + config_a = Integer.parseInt(tokens[3]); + config_b = Integer.parseInt(tokens[5]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { + cmd = AltosLib.AO_LOG_RADIO_CAL; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { + cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; + config_a = Integer.parseInt(tokens[3]); + } else if (tokens[0].equals("manufacturer")) { + cmd = AltosLib.AO_LOG_MANUFACTURER; + data = tokens[1]; + } else if (tokens[0].equals("product")) { + cmd = AltosLib.AO_LOG_PRODUCT; + data = tokens[1]; + } else if (tokens[0].equals("serial-number")) { + cmd = AltosLib.AO_LOG_SERIAL_NUMBER; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("log-format")) { + cmd = AltosLib.AO_LOG_LOG_FORMAT; + config_a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("software-version")) { + cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; + data = tokens[1]; + } else if (tokens[0].equals("ms5607")) { + if (tokens[1].equals("reserved:")) { + cmd = AltosLib.AO_LOG_BARO_RESERVED; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("sens:")) { + cmd = AltosLib.AO_LOG_BARO_SENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("off:")) { + cmd = AltosLib.AO_LOG_BARO_OFF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tcs:")) { + cmd = AltosLib.AO_LOG_BARO_TCS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tco:")) { + cmd = AltosLib.AO_LOG_BARO_TCO; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tref:")) { + cmd = AltosLib.AO_LOG_BARO_TREF; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("tempsens:")) { + cmd = AltosLib.AO_LOG_BARO_TEMPSENS; + config_a = Integer.parseInt(tokens[2]); + } else if (tokens[1].equals("crc:")) { + cmd = AltosLib.AO_LOG_BARO_CRC; + config_a = Integer.parseInt(tokens[2]); + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } catch (NumberFormatException ne) { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } + } + + public AltosEepromMetrum(int in_cmd, int in_tick) { + cmd = in_cmd; + tick = in_tick; + valid = true; + } +} diff --git a/altoslib/AltosEepromMetrumIterable.java b/altoslib/AltosEepromMetrumIterable.java new file mode 100644 index 00000000..0387319e --- /dev/null +++ b/altoslib/AltosEepromMetrumIterable.java @@ -0,0 +1,358 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromMetrumIterable extends AltosRecordIterable { + + static final int seen_flight = 1; + static final int seen_sensor = 2; + static final int seen_temp_volt = 4; + static final int seen_deploy = 8; + static final int seen_gps_time = 16; + static final int seen_gps_lat = 32; + static final int seen_gps_lon = 64; + + static final int seen_basic = seen_flight|seen_sensor; + + boolean has_accel; + boolean has_gps; + boolean has_ignite; + + AltosEepromMetrum flight_record; + AltosEepromMetrum gps_date_record; + + TreeSet records; + + AltosMs5607 baro; + + LinkedList list; + + class EepromState { + int seen; + int n_pad_samples; + double ground_pres; + int gps_tick; + int boost_tick; + int sensor_tick; + + EepromState() { + seen = 0; + n_pad_samples = 0; + ground_pres = 0.0; + gps_tick = 0; + } + } + + void update_state(AltosRecordTM2 state, AltosEepromMetrum record, EepromState eeprom) { + state.tick = record.tick; + switch (record.cmd) { + case AltosLib.AO_LOG_FLIGHT: + eeprom.seen |= seen_flight; + state.ground_accel = record.ground_accel(); + state.flight_accel = record.ground_accel(); + state.ground_pres = baro.set(record.ground_pres(), record.ground_temp()); + state.flight_pres = state.ground_pres; + state.flight = record.data16(0); + eeprom.boost_tick = record.tick; + break; + case AltosLib.AO_LOG_STATE: + state.state = record.state(); + break; + case AltosLib.AO_LOG_SENSOR: + state.accel = record.accel(); + baro.set(record.pres(), record.temp()); + state.pres = baro.pa; + state.temp = baro.cc; + if (state.state < AltosLib.ao_flight_boost) { + eeprom.n_pad_samples++; + eeprom.ground_pres += state.pres; + state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); + state.flight_pres = state.ground_pres; + } else { + state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; + } + state.flight_accel = (state.flight_accel * 15 + state.accel) / 16; + if ((eeprom.seen & seen_sensor) == 0) + eeprom.sensor_tick = record.tick - 1; + state.flight_vel += (state.accel_plus_g - state.accel) * (record.tick - eeprom.sensor_tick); + eeprom.seen |= seen_sensor; + eeprom.sensor_tick = record.tick; + has_accel = true; + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.v_batt = record.v_batt(); + state.sense_a = record.sense_a(); + state.sense_m = record.sense_m(); + eeprom.seen |= seen_temp_volt; + break; + case AltosLib.AO_LOG_GPS_POS: + eeprom.gps_tick = state.tick; + state.gps = new AltosGPS(); + + state.gps.lat = record.latitude() / 1e7; + state.gps.lon = record.longitude() / 1e7; + state.gps.alt = record.altitude(); + break; + + case AltosLib.AO_LOG_GPS_TIME: + state.gps.year = record.year() + 2000; + state.gps.month = record.month(); + state.gps.day = record.day(); + + state.gps.hour = record.hour(); + state.gps.minute = record.minute(); + state.gps.second = record.second(); + + int flags = record.flags(); + state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + state.gps_sequence++; + has_gps = true; + eeprom.seen |= seen_gps_time | seen_gps_lat | seen_gps_lon; + break; + case AltosLib.AO_LOG_GPS_SAT: + if (state.tick == eeprom.gps_tick) { + int nsat = record.channels(); + for (int i = 0; i < nsat; i++) + state.gps.add_sat(record.svid(i), record.c_n(i)); + } + break; + case AltosLib.AO_LOG_CONFIG_VERSION: + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + break; + case AltosLib.AO_LOG_CALLSIGN: + state.callsign = record.data; + break; + case AltosLib.AO_LOG_ACCEL_CAL: + state.accel_plus_g = record.config_a; + state.accel_minus_g = record.config_b; + break; + case AltosLib.AO_LOG_RADIO_CAL: + break; + case AltosLib.AO_LOG_MANUFACTURER: + break; + case AltosLib.AO_LOG_PRODUCT: + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + state.serial = record.config_a; + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + break; + case AltosLib.AO_LOG_BARO_RESERVED: + baro.reserved = record.config_a; + break; + case AltosLib.AO_LOG_BARO_SENS: + baro.sens =record.config_a; + break; + case AltosLib.AO_LOG_BARO_OFF: + baro.off =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TCS: + baro.tcs =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TCO: + baro.tco =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TREF: + baro.tref =record.config_a; + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + baro.tempsens =record.config_a; + break; + case AltosLib.AO_LOG_BARO_CRC: + baro.crc =record.config_a; + break; + } + state.seen |= eeprom.seen; + } + + LinkedList make_list() { + LinkedList list = new LinkedList(); + Iterator iterator = records.iterator(); + AltosOrderedMetrumRecord record = null; + AltosRecordTM2 state = new AltosRecordTM2(); + //boolean last_reported = false; + EepromState eeprom = new EepromState(); + + state.state = AltosLib.ao_flight_pad; + state.accel_plus_g = 15758; + state.accel_minus_g = 16294; + + /* Pull in static data from the flight and gps_date records */ + if (flight_record != null) + update_state(state, flight_record, eeprom); + if (gps_date_record != null) + update_state(state, gps_date_record, eeprom); + + while (iterator.hasNext()) { + record = iterator.next(); + if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { + AltosRecordTM2 r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + } + update_state(state, record, eeprom); + } + AltosRecordTM2 r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + return list; + } + + public Iterator iterator() { + if (list == null) + list = make_list(); + return list.iterator(); + } + + public boolean has_gps() { return has_gps; } + public boolean has_accel() { return has_accel; } + public boolean has_ignite() { return has_ignite; } + + public void write_comments(PrintStream out) { + Iterator iterator = records.iterator(); + out.printf("# Comments\n"); + while (iterator.hasNext()) { + AltosOrderedMetrumRecord record = iterator.next(); + switch (record.cmd) { + case AltosLib.AO_LOG_CONFIG_VERSION: + out.printf("# Config version: %s\n", record.data); + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + out.printf("# Main deploy: %s\n", record.config_a); + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + out.printf("# Apogee delay: %s\n", record.config_a); + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + out.printf("# Radio channel: %s\n", record.config_a); + break; + case AltosLib.AO_LOG_CALLSIGN: + out.printf("# Callsign: %s\n", record.data); + break; + case AltosLib.AO_LOG_ACCEL_CAL: + out.printf ("# Accel cal: %d %d\n", record.config_a, record.config_b); + break; + case AltosLib.AO_LOG_RADIO_CAL: + out.printf ("# Radio cal: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_MAX_FLIGHT_LOG: + out.printf ("# Max flight log: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_MANUFACTURER: + out.printf ("# Manufacturer: %s\n", record.data); + break; + case AltosLib.AO_LOG_PRODUCT: + out.printf ("# Product: %s\n", record.data); + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + out.printf ("# Serial number: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + out.printf ("# Software version: %s\n", record.data); + break; + case AltosLib.AO_LOG_BARO_RESERVED: + out.printf ("# Baro reserved: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_SENS: + out.printf ("# Baro sens: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_OFF: + out.printf ("# Baro off: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TCS: + out.printf ("# Baro tcs: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TCO: + out.printf ("# Baro tco: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TREF: + out.printf ("# Baro tref: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + out.printf ("# Baro tempsens: %d\n", record.config_a); + break; + case AltosLib.AO_LOG_BARO_CRC: + out.printf ("# Baro crc: %d\n", record.config_a); + break; + } + } + } + + /* + * Read the whole file, dumping records into a RB tree so + * we can enumerate them in time order -- the eeprom data + * are sometimes out of order with GPS data getting timestamps + * matching the first packet out of the GPS unit but not + * written until the final GPS packet has been received. + */ + public AltosEepromMetrumIterable (FileInputStream input) { + records = new TreeSet(); + + AltosOrderedMetrumRecord last_gps_time = null; + + baro = new AltosMs5607(); + + int index = 0; + int prev_tick = 0; + boolean prev_tick_valid = false; + boolean missing_time = false; + + try { + for (;;) { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosOrderedMetrumRecord record = new AltosOrderedMetrumRecord(line, index++, prev_tick, prev_tick_valid); + if (record.cmd == AltosLib.AO_LOG_INVALID) + continue; + prev_tick = record.tick; + if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) + prev_tick_valid = true; + if (record.cmd == AltosLib.AO_LOG_FLIGHT) { + flight_record = record; + continue; + } + + records.add(record); + + /* Bail after reading the 'landed' record; we're all done */ + if (record.cmd == AltosLib.AO_LOG_STATE && + record.state() == AltosLib.ao_flight_landed) + break; + } + } catch (IOException io) { + } catch (ParseException pe) { + } + try { + input.close(); + } catch (IOException ie) { + } + } +} diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index 215cd3d9..ced87680 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -17,20 +17,12 @@ package org.altusmetrum.altoslib_1; +import java.io.*; +import java.util.*; import java.text.*; -public class AltosEepromMini { - public int cmd; - public int tick; - public boolean valid; - public String data; - public int config_a, config_b; - - public int data8[]; - +public class AltosEepromMini extends AltosEeprom { public static final int record_length = 16; - static final int header_length = 4; - static final int data_length = record_length - header_length; public int data8(int i) { return data8[i]; @@ -63,126 +55,23 @@ public class AltosEepromMini { public int sense_m() { return data16(8); } public int v_batt() { return data16(10); } - public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException { - cmd = chunk.data(start); - - valid = !chunk.erased(start, record_length); - if (valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x", - chunk.address + start), 0); - } else { - cmd = AltosLib.AO_LOG_INVALID; + public void update_state(AltosState state) { + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + break; + case AltosLib.AO_LOG_STATE: + break; + case AltosLib.AO_LOG_SENSOR: + break; } + } - tick = chunk.data16(start+2); - - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = chunk.data(start + header_length + i); + public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException { + parse_chunk(chunk, start, record_length); } public AltosEepromMini (String line) { - valid = false; - tick = 0; - - if (line == null) { - cmd = AltosLib.AO_LOG_INVALID; - line = ""; - } else { - try { - String[] tokens = line.split("\\s+"); - - if (tokens[0].length() == 1) { - if (tokens.length != 2 + data_length) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } else { - cmd = tokens[0].codePointAt(0); - tick = Integer.parseInt(tokens[1],16); - valid = true; - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = Integer.parseInt(tokens[2 + i],16); - } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - config_a = Integer.parseInt(tokens[3]); - config_b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - config_a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; - } else if (tokens[0].equals("ms5607")) { - if (tokens[1].equals("reserved:")) { - cmd = AltosLib.AO_LOG_BARO_RESERVED; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("sens:")) { - cmd = AltosLib.AO_LOG_BARO_SENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("off:")) { - cmd = AltosLib.AO_LOG_BARO_OFF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tcs:")) { - cmd = AltosLib.AO_LOG_BARO_TCS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tco:")) { - cmd = AltosLib.AO_LOG_BARO_TCO; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tref:")) { - cmd = AltosLib.AO_LOG_BARO_TREF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tempsens:")) { - cmd = AltosLib.AO_LOG_BARO_TEMPSENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("crc:")) { - cmd = AltosLib.AO_LOG_BARO_CRC; - config_a = Integer.parseInt(tokens[2]); - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } catch (NumberFormatException ne) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } + parse_string(line, record_length); } public AltosEepromMini(int in_cmd, int in_tick) { @@ -190,4 +79,22 @@ public class AltosEepromMini { tick = in_tick; valid = true; } + + static public LinkedList read(FileInputStream input) { + LinkedList minis = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosEepromMini mini = new AltosEepromMini(line); + minis.add(mini); + } catch (IOException ie) { + break; + } + } + + return minis; + } } diff --git a/altoslib/AltosEepromOldIterable.java b/altoslib/AltosEepromOldIterable.java new file mode 100644 index 00000000..ef82828b --- /dev/null +++ b/altoslib/AltosEepromOldIterable.java @@ -0,0 +1,435 @@ +/* + * Copyright © 2010 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromOldIterable extends AltosRecordIterable { + + static final int seen_basic = AltosRecord.seen_flight|AltosRecord.seen_sensor; + + boolean has_accel; + boolean has_gps; + boolean has_ignite; + + AltosEepromRecord flight_record; + AltosEepromRecord gps_date_record; + + TreeSet records; + + LinkedList list; + + class EepromState { + int seen; + int n_pad_samples; + double ground_pres; + int gps_tick; + int boost_tick; + int sensor_tick; + + EepromState() { + seen = 0; + n_pad_samples = 0; + ground_pres = 0.0; + gps_tick = 0; + } + } + + void update_state(AltosRecordTM state, AltosEepromRecord record, EepromState eeprom) { + state.tick = record.tick; + switch (record.cmd) { + case AltosLib.AO_LOG_FLIGHT: + eeprom.seen |= AltosRecord.seen_flight; + state.ground_accel = record.a; + state.flight_accel = record.a; + state.flight = record.b; + eeprom.boost_tick = record.tick; + break; + case AltosLib.AO_LOG_SENSOR: + state.accel = record.a; + state.pres = record.b; + if (state.state < AltosLib.ao_flight_boost) { + eeprom.n_pad_samples++; + eeprom.ground_pres += state.pres; + state.ground_pres = (int) (eeprom.ground_pres / eeprom.n_pad_samples); + state.flight_pres = state.ground_pres; + } else { + state.flight_pres = (state.flight_pres * 15 + state.pres) / 16; + } + state.flight_accel = (state.flight_accel * 15 + state.accel) / 16; + if ((eeprom.seen & AltosRecord.seen_sensor) == 0) + eeprom.sensor_tick = record.tick - 1; + state.flight_vel += (state.accel_plus_g - state.accel) * (record.tick - eeprom.sensor_tick); + eeprom.seen |= AltosRecord.seen_sensor; + eeprom.sensor_tick = record.tick; + has_accel = true; + break; + case AltosLib.AO_LOG_PRESSURE: + state.pres = record.b; + state.flight_pres = state.pres; + if (eeprom.n_pad_samples == 0) { + eeprom.n_pad_samples++; + state.ground_pres = state.pres; + } + eeprom.seen |= AltosRecord.seen_sensor; + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.temp = record.a; + state.batt = record.b; + eeprom.seen |= AltosRecord.seen_temp_volt; + break; + case AltosLib.AO_LOG_DEPLOY: + state.drogue = record.a; + state.main = record.b; + eeprom.seen |= AltosRecord.seen_deploy; + has_ignite = true; + break; + case AltosLib.AO_LOG_STATE: + state.state = record.a; + break; + case AltosLib.AO_LOG_GPS_TIME: + eeprom.gps_tick = state.tick; + eeprom.seen |= AltosRecord.seen_gps_time; + AltosGPS old = state.gps; + state.gps = new AltosGPS(); + + /* GPS date doesn't get repeated through the file */ + if (old != null) { + state.gps.year = old.year; + state.gps.month = old.month; + state.gps.day = old.day; + } + state.gps.hour = (record.a & 0xff); + state.gps.minute = (record.a >> 8); + state.gps.second = (record.b & 0xff); + + int flags = (record.b >> 8); + state.gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + state.gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + state.gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + state.gps_sequence++; + has_gps = true; + break; + case AltosLib.AO_LOG_GPS_LAT: + eeprom.seen |= AltosRecord.seen_gps_lat; + int lat32 = record.a | (record.b << 16); + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.lat = (double) lat32 / 1e7; + break; + case AltosLib.AO_LOG_GPS_LON: + eeprom.seen |= AltosRecord.seen_gps_lon; + int lon32 = record.a | (record.b << 16); + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.lon = (double) lon32 / 1e7; + break; + case AltosLib.AO_LOG_GPS_ALT: + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.alt = record.a; + break; + case AltosLib.AO_LOG_GPS_SAT: + if (state.tick == eeprom.gps_tick) { + int svid = record.a; + int c_n0 = record.b >> 8; + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.add_sat(svid, c_n0); + } + break; + case AltosLib.AO_LOG_GPS_DATE: + if (state.gps == null) + state.gps = new AltosGPS(); + state.gps.year = (record.a & 0xff) + 2000; + state.gps.month = record.a >> 8; + state.gps.day = record.b & 0xff; + break; + + case AltosLib.AO_LOG_CONFIG_VERSION: + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + break; + case AltosLib.AO_LOG_CALLSIGN: + state.callsign = record.data; + break; + case AltosLib.AO_LOG_ACCEL_CAL: + state.accel_plus_g = record.a; + state.accel_minus_g = record.b; + break; + case AltosLib.AO_LOG_RADIO_CAL: + break; + case AltosLib.AO_LOG_MANUFACTURER: + break; + case AltosLib.AO_LOG_PRODUCT: + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + state.serial = record.a; + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + break; + } + state.seen |= eeprom.seen; + } + + LinkedList make_list() { + LinkedList list = new LinkedList(); + Iterator iterator = records.iterator(); + AltosOrderedRecord record = null; + AltosRecordTM state = new AltosRecordTM(); + //boolean last_reported = false; + EepromState eeprom = new EepromState(); + + state.state = AltosLib.ao_flight_pad; + state.accel_plus_g = 15758; + state.accel_minus_g = 16294; + state.flight_vel = 0; + + /* Pull in static data from the flight and gps_date records */ + if (flight_record != null) + update_state(state, flight_record, eeprom); + if (gps_date_record != null) + update_state(state, gps_date_record, eeprom); + + while (iterator.hasNext()) { + record = iterator.next(); + if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { + AltosRecordTM r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + } + update_state(state, record, eeprom); + } + AltosRecordTM r = state.clone(); + r.time = (r.tick - eeprom.boost_tick) / 100.0; + list.add(r); + return list; + } + + public Iterator iterator() { + if (list == null) + list = make_list(); + return list.iterator(); + } + + public boolean has_gps() { return has_gps; } + public boolean has_accel() { return has_accel; } + public boolean has_ignite() { return has_ignite; } + + public void write_comments(PrintStream out) { + Iterator iterator = records.iterator(); + out.printf("# Comments\n"); + while (iterator.hasNext()) { + AltosOrderedRecord record = iterator.next(); + switch (record.cmd) { + case AltosLib.AO_LOG_CONFIG_VERSION: + out.printf("# Config version: %s\n", record.data); + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + out.printf("# Main deploy: %s\n", record.a); + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + out.printf("# Apogee delay: %s\n", record.a); + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + out.printf("# Radio channel: %s\n", record.a); + break; + case AltosLib.AO_LOG_CALLSIGN: + out.printf("# Callsign: %s\n", record.data); + break; + case AltosLib.AO_LOG_ACCEL_CAL: + out.printf ("# Accel cal: %d %d\n", record.a, record.b); + break; + case AltosLib.AO_LOG_RADIO_CAL: + out.printf ("# Radio cal: %d\n", record.a); + break; + case AltosLib.AO_LOG_MAX_FLIGHT_LOG: + out.printf ("# Max flight log: %d\n", record.a); + break; + case AltosLib.AO_LOG_MANUFACTURER: + out.printf ("# Manufacturer: %s\n", record.data); + break; + case AltosLib.AO_LOG_PRODUCT: + out.printf ("# Product: %s\n", record.data); + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + out.printf ("# Serial number: %d\n", record.a); + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + out.printf ("# Software version: %s\n", record.data); + break; + case AltosLib.AO_LOG_BARO_RESERVED: + out.printf ("# Baro reserved: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_SENS: + out.printf ("# Baro sens: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_OFF: + out.printf ("# Baro off: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_TCS: + out.printf ("# Baro tcs: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_TCO: + out.printf ("# Baro tco: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_TREF: + out.printf ("# Baro tref: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_TEMPSENS: + out.printf ("# Baro tempsens: %d\n", record.a); + break; + case AltosLib.AO_LOG_BARO_CRC: + out.printf ("# Baro crc: %d\n", record.a); + break; + } + } + } + + /* + * Given an AO_LOG_GPS_TIME record with correct time, and one + * missing time, rewrite the missing time values with the good + * ones, assuming that the difference between them is 'diff' seconds + */ + void update_time(AltosOrderedRecord good, AltosOrderedRecord bad) { + + int diff = (bad.tick - good.tick + 50) / 100; + + int hour = (good.a & 0xff); + int minute = (good.a >> 8); + int second = (good.b & 0xff); + int flags = (good.b >> 8); + int seconds = hour * 3600 + minute * 60 + second; + + /* Make sure this looks like a good GPS value */ + if ((flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> AltosLib.AO_GPS_NUM_SAT_SHIFT < 4) + flags = (flags & ~AltosLib.AO_GPS_NUM_SAT_MASK) | (4 << AltosLib.AO_GPS_NUM_SAT_SHIFT); + flags |= AltosLib.AO_GPS_RUNNING; + flags |= AltosLib.AO_GPS_VALID; + + int new_seconds = seconds + diff; + if (new_seconds < 0) + new_seconds += 24 * 3600; + int new_second = (new_seconds % 60); + int new_minutes = (new_seconds / 60); + int new_minute = (new_minutes % 60); + int new_hours = (new_minutes / 60); + int new_hour = (new_hours % 24); + + bad.a = new_hour + (new_minute << 8); + bad.b = new_second + (flags << 8); + } + + /* + * Read the whole file, dumping records into a RB tree so + * we can enumerate them in time order -- the eeprom data + * are sometimes out of order with GPS data getting timestamps + * matching the first packet out of the GPS unit but not + * written until the final GPS packet has been received. + */ + public AltosEepromOldIterable (FileInputStream input) { + records = new TreeSet(); + + AltosOrderedRecord last_gps_time = null; + + int index = 0; + int prev_tick = 0; + boolean prev_tick_valid = false; + boolean missing_time = false; + + try { + for (;;) { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosOrderedRecord record = new AltosOrderedRecord(line, index++, prev_tick, prev_tick_valid); + if (record.cmd == AltosLib.AO_LOG_INVALID) + continue; + prev_tick = record.tick; + if (record.cmd < AltosLib.AO_LOG_CONFIG_VERSION) + prev_tick_valid = true; + if (record.cmd == AltosLib.AO_LOG_FLIGHT) { + flight_record = record; + continue; + } + + /* Two firmware bugs caused the loss of some GPS data. + * The flight date would never be recorded, and often + * the flight time would get overwritten by another + * record. Detect the loss of the GPS date and fix up the + * missing time records + */ + if (record.cmd == AltosLib.AO_LOG_GPS_DATE) { + gps_date_record = record; + continue; + } + + /* go back and fix up any missing time values */ + if (record.cmd == AltosLib.AO_LOG_GPS_TIME) { + last_gps_time = record; + if (missing_time) { + Iterator iterator = records.iterator(); + while (iterator.hasNext()) { + AltosOrderedRecord old = iterator.next(); + if (old.cmd == AltosLib.AO_LOG_GPS_TIME && + old.a == -1 && old.b == -1) + { + update_time(record, old); + } + } + missing_time = false; + } + } + + if (record.cmd == AltosLib.AO_LOG_GPS_LAT) { + if (last_gps_time == null || last_gps_time.tick != record.tick) { + AltosOrderedRecord add_gps_time = new AltosOrderedRecord(AltosLib.AO_LOG_GPS_TIME, + record.tick, + -1, -1, index-1); + if (last_gps_time != null) + update_time(last_gps_time, add_gps_time); + else + missing_time = true; + + records.add(add_gps_time); + record.index = index++; + } + } + records.add(record); + + /* Bail after reading the 'landed' record; we're all done */ + if (record.cmd == AltosLib.AO_LOG_STATE && + record.a == AltosLib.ao_flight_landed) + break; + } + } catch (IOException io) { + } catch (ParseException pe) { + } + try { + input.close(); + } catch (IOException ie) { + } + } +} diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java new file mode 100644 index 00000000..fc7ec321 --- /dev/null +++ b/altoslib/AltosEepromTM.java @@ -0,0 +1,255 @@ +/* + * Copyright © 2010 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.*; + +public class AltosEepromTM implements AltosStateUpdate { + public int cmd; + public int tick; + public int a; + public int b; + public String data; + public boolean tick_valid; + + public static final int record_length = 8; + + public void update_state(AltosState state) { + state.set_tick(tick); + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.ground_accel = a; + state.flight = b; + state.set_boost_tick(tick); + state.time = 0; + break; + case AltosLib.AO_LOG_SENSOR: + state.set_telemetrum(a, b); + break; + case AltosLib.AO_LOG_PRESSURE: + state.set_telemetrum(AltosState.MISSING, b); + break; + case AltosLib.AO_LOG_TEMP_VOLT: +/* + + record.temp = a; + record.batt = b; + eeprom_state.seen |= AltosRecord.seen_temp_volt; +*/ + break; + case AltosLib.AO_LOG_DEPLOY: +/* + record.drogue = a; + record.main = b; + eeprom_state.seen |= AltosRecord.seen_deploy; + has_ignite = true; +*/ + break; + case AltosLib.AO_LOG_STATE: + state.state = a; + break; +// case AltosLib.AO_LOG_GPS_TIME: +// eeprom_state.gps_tick = record.tick; +// eeprom_state.seen |= AltosRecord.seen_gps_time; +// AltosGPS old = state.gps; +// AltosGPS gps = new AltosGPS(); +// +// /* GPS date doesn't get repeated through the file */ +// if (old != null) { +// gps.year = old.year; +// gps.month = old.month; +// gps.day = old.day; +// } +// gps.hour = (a & 0xff); +// gps.minute = (a >> 8); +// gps.second = (b & 0xff); +// +// int flags = (b >> 8); +// 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; +// state.temp_gps = gps; +// break; +// case AltosLib.AO_LOG_GPS_LAT: +// int lat32 = a | (b << 16); +// if (state.temp_gps == null) +// state.temp_gps = new AltosGPS(); +// state.temp_gps.lat = (double) lat32 / 1e7; +// break; +// case AltosLib.AO_LOG_GPS_LON: +// int lon32 = a | (b << 16); +// if (state.temp_gps == null) +// state.temp_gps = new AltosGPS(); +// state.temp_gps.lon = (double) lon32 / 1e7; +// break; +// case AltosLib.AO_LOG_GPS_ALT: +// if (state.temp_gps == null) +// state.temp_gps = new AltosGPS(); +// state.temp_gps.alt = a; +// break; +// case AltosLib.AO_LOG_GPS_SAT: +// if (record.tick == eeprom_state.gps_tick) { +// int svid = a; +// int c_n0 = b >> 8; +// if (record.gps == null) +// record.gps = new AltosGPS(); +// record.gps.add_sat(svid, c_n0); +// } +// break; +// case AltosLib.AO_LOG_GPS_DATE: +// if (record.gps == null) +// record.gps = new AltosGPS(); +// record.gps.year = (a & 0xff) + 2000; +// record.gps.month = a >> 8; +// record.gps.day = b & 0xff; +// break; + + case AltosLib.AO_LOG_CONFIG_VERSION: + break; + case AltosLib.AO_LOG_MAIN_DEPLOY: + break; + case AltosLib.AO_LOG_APOGEE_DELAY: + break; + case AltosLib.AO_LOG_RADIO_CHANNEL: + break; + case AltosLib.AO_LOG_CALLSIGN: + state.callsign = data; + break; + case AltosLib.AO_LOG_ACCEL_CAL: + state.accel_plus_g = a; + state.accel_minus_g = b; + break; + case AltosLib.AO_LOG_RADIO_CAL: + break; + case AltosLib.AO_LOG_MANUFACTURER: + break; + case AltosLib.AO_LOG_PRODUCT: + break; + case AltosLib.AO_LOG_SERIAL_NUMBER: + state.serial = a; + break; + case AltosLib.AO_LOG_SOFTWARE_VERSION: + break; + } + } + + public AltosEepromTM (AltosEepromChunk chunk, int start) throws ParseException { + + cmd = chunk.data(start); + tick_valid = true; + + tick_valid = !chunk.erased(start, record_length); + if (tick_valid) { + if (AltosConvert.checksum(chunk.data, start, record_length) != 0) + throw new ParseException(String.format("invalid checksum at 0x%x", + chunk.address + start), 0); + } else { + cmd = AltosLib.AO_LOG_INVALID; + } + + tick = chunk.data16(start + 2); + a = chunk.data16(start + 4); + b = chunk.data16(start + 6); + + data = null; + } + + public AltosEepromTM (String line) { + tick_valid = false; + tick = 0; + a = 0; + b = 0; + data = null; + if (line == null) { + cmd = AltosLib.AO_LOG_INVALID; + data = ""; + } else { + try { + String[] tokens = line.split("\\s+"); + + if (tokens[0].length() == 1) { + if (tokens.length != 4) { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } else { + cmd = tokens[0].codePointAt(0); + tick = Integer.parseInt(tokens[1],16); + tick_valid = true; + a = Integer.parseInt(tokens[2],16); + b = Integer.parseInt(tokens[3],16); + } + } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { + cmd = AltosLib.AO_LOG_CONFIG_VERSION; + data = tokens[2]; + } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { + cmd = AltosLib.AO_LOG_MAIN_DEPLOY; + a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { + cmd = AltosLib.AO_LOG_APOGEE_DELAY; + a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { + cmd = AltosLib.AO_LOG_RADIO_CHANNEL; + a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Callsign:")) { + cmd = AltosLib.AO_LOG_CALLSIGN; + data = tokens[1].replaceAll("\"",""); + } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { + cmd = AltosLib.AO_LOG_ACCEL_CAL; + a = Integer.parseInt(tokens[3]); + b = Integer.parseInt(tokens[5]); + } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { + cmd = AltosLib.AO_LOG_RADIO_CAL; + a = Integer.parseInt(tokens[2]); + } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { + cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; + a = Integer.parseInt(tokens[3]); + } else if (tokens[0].equals("manufacturer")) { + cmd = AltosLib.AO_LOG_MANUFACTURER; + data = tokens[1]; + } else if (tokens[0].equals("product")) { + cmd = AltosLib.AO_LOG_PRODUCT; + data = tokens[1]; + } else if (tokens[0].equals("serial-number")) { + cmd = AltosLib.AO_LOG_SERIAL_NUMBER; + a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("log-format")) { + cmd = AltosLib.AO_LOG_LOG_FORMAT; + a = Integer.parseInt(tokens[1]); + } else if (tokens[0].equals("software-version")) { + cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; + data = tokens[1]; + } else { + cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } catch (NumberFormatException ne) { +v cmd = AltosLib.AO_LOG_INVALID; + data = line; + } + } + } + + public AltosEepromTM(int in_cmd, int in_tick, int in_a, int in_b) { + tick_valid = true; + cmd = in_cmd; + tick = in_tick; + a = in_a; + b = in_b; + } +} diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index f23842f3..f7929a4c 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -19,7 +19,7 @@ package org.altusmetrum.altoslib_1; import java.text.*; -public class AltosGPS { +public class AltosGPS implements Cloneable { public final static int MISSING = AltosRecord.MISSING; @@ -216,6 +216,39 @@ public class AltosGPS { cc_gps_sat = null; } + public AltosGPS clone() { + AltosGPS g = new AltosGPS(); + + g.nsat = nsat; + g.locked = locked; + g.connected = connected; + g.lat = lat; g./* degrees (+N -S) */ + g.lon = lon; /* degrees (+E -W) */ + g.alt = alt; /* m */ + g.year = year; + g.month = month; + g.day = day; + g.hour = hour; + g.minute = minute; + g.second = second; + + g.ground_speed = ground_speed; /* m/s */ + g.course = course; /* degrees */ + g.climb_rate = climb_rate; /* m/s */ + g.hdop = hdop; /* unitless? */ + g.h_error = h_error; /* m */ + g.v_error = v_error; /* m */ + + if (cc_gps_sat != null) { + g.cc_gps_sat = new AltosGPSSat[cc_gps_sat.length]; + for (int i = 0; i < cc_gps_sat.length; i++) { + g.cc_gps_sat[i] = new AltosGPSSat(); + g.cc_gps_sat[i].svid = cc_gps_sat[i].svid; + g.cc_gps_sat[i].c_n0 = cc_gps_sat[i].c_n0; + } + } + } + public AltosGPS(AltosGPS old) { if (old != null) { nsat = old.nsat; diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java index f1cf0ae9..770c3c6c 100644 --- a/altoslib/AltosGreatCircle.java +++ b/altoslib/AltosGreatCircle.java @@ -19,7 +19,7 @@ package org.altusmetrum.altoslib_1; import java.lang.Math; -public class AltosGreatCircle { +public class AltosGreatCircle implements Cloneable { public double distance; public double bearing; public double range; @@ -95,6 +95,16 @@ public class AltosGreatCircle { elevation = Math.atan2(height_diff, distance) * 180 / Math.PI; } + public AltosGreatCircle clone() { + AltosGreatCircle n = new AltosGreatCircle(); + + n.distance = distance; + n.bearing = bearing; + n.range = range; + n.elevation = elevation; + return n; + } + public AltosGreatCircle (double start_lat, double start_lon, double end_lat, double end_lon) { this(start_lat, start_lon, 0, end_lat, end_lon, 0); diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index 8f6731fa..46df35bf 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -17,7 +17,7 @@ package org.altusmetrum.altoslib_1; -public class AltosIMU { +public class AltosIMU implements Cloneable { public int accel_x; public int accel_y; public int accel_z; @@ -25,5 +25,17 @@ public class AltosIMU { public int gyro_x; public int gyro_y; public int gyro_z; + + public AltosIMU clone() { + AltosIMU n = new AltosIMU(); + + n.accel_x = accel_x; + n.accel_y = accel_y; + n.accel_z = accel_z; + + n.gyro_x = gyro_x; + n.gyro_y = gyro_y; + n.gyro_z = gyro_z; + return n; } \ No newline at end of file diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java index b3bbd92f..cb6826f3 100644 --- a/altoslib/AltosMag.java +++ b/altoslib/AltosMag.java @@ -17,9 +17,18 @@ package org.altusmetrum.altoslib_1; -public class AltosMag { +public class AltosMag implements Cloneable { public int x; public int y; public int z; + + public AltosMag clone() { + AltosMag n = new AltosMag(); + + n.x = x; + n.y = y; + n.z = z; + return n; + } } \ No newline at end of file diff --git a/altoslib/AltosOrderedMetrumRecord.java b/altoslib/AltosOrderedMetrumRecord.java new file mode 100644 index 00000000..02cdf1fe --- /dev/null +++ b/altoslib/AltosOrderedMetrumRecord.java @@ -0,0 +1,52 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.ParseException; + +/* + * AltosRecords with an index field so they can be sorted by tick while preserving + * the original ordering for elements with matching ticks + */ +class AltosOrderedMetrumRecord extends AltosEepromMetrum implements Comparable { + + public int index; + + public AltosOrderedMetrumRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) + throws ParseException { + super(line); + if (prev_tick_valid) { + tick |= (prev_tick & ~0xffff); + if (tick < prev_tick) { + if (prev_tick - tick > 0x8000) + tick += 0x10000; + } else { + if (tick - prev_tick > 0x8000) + tick -= 0x10000; + } + } + index = in_index; + } + + public int compareTo(AltosOrderedMetrumRecord o) { + int tick_diff = tick - o.tick; + if (tick_diff != 0) + return tick_diff; + return index - o.index; + } +} diff --git a/altoslib/AltosRecordMini.java b/altoslib/AltosRecordMini.java index 253f3804..dacd89b8 100644 --- a/altoslib/AltosRecordMini.java +++ b/altoslib/AltosRecordMini.java @@ -31,6 +31,8 @@ public class AltosRecordMini extends AltosRecord { public int flight_accel; public int flight_vel; + public int flight_height; + public int flight_pres; static double adc(int raw) { @@ -89,6 +91,7 @@ public class AltosRecordMini extends AltosRecord { flight_accel = old.flight_accel; flight_vel = old.flight_vel; + flight_height = old.flight_height; flight_pres = old.flight_pres; } @@ -110,6 +113,7 @@ public class AltosRecordMini extends AltosRecord { flight_accel = 0; flight_vel = 0; + flight_height = 0; flight_pres = 0; } diff --git a/altoslib/AltosRecordTM2.java b/altoslib/AltosRecordTM2.java new file mode 100644 index 00000000..0cd54f2c --- /dev/null +++ b/altoslib/AltosRecordTM2.java @@ -0,0 +1,156 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosRecordTM2 extends AltosRecord { + + /* Sensor values */ + public int accel; + public int pres; + public int temp; + + public int v_batt; + public int sense_a; + public int sense_m; + + public int ground_accel; + public int ground_pres; + public int accel_plus_g; + public int accel_minus_g; + + public int flight_accel; + public int flight_vel; + public int flight_pres; + + static double adc(int raw) { + return raw / 4095.0; + } + + public double pressure() { + if (pres != MISSING) + return pres; + return MISSING; + } + + public double ground_pressure() { + if (ground_pres != MISSING) + return ground_pres; + return MISSING; + } + + public double battery_voltage() { + if (v_batt != MISSING) + return 3.3 * adc(v_batt) * (15.0 + 27.0) / 27.0; + return MISSING; + } + + static double pyro(int raw) { + if (raw != MISSING) + return 3.3 * adc(raw) * (100.0 + 27.0) / 27.0; + return MISSING; + } + + public double main_voltage() { + return pyro(sense_m); + } + + public double drogue_voltage() { + return pyro(sense_a); + } + + public double temperature() { + if (temp != MISSING) + return temp / 100.0; + return MISSING; + } + + double accel_counts_per_mss() { + double counts_per_g = Math.abs(accel_minus_g - accel_plus_g) / 2; + + return counts_per_g / 9.80665; + } + + public double acceleration() { + if (ground_accel == MISSING || accel == MISSING) + return MISSING; + + if (accel_minus_g == MISSING || accel_plus_g == MISSING) + return MISSING; + + return (ground_accel - accel) / accel_counts_per_mss(); + } + + public void copy (AltosRecordTM2 old) { + super.copy(old); + + accel = old.accel; + pres = old.pres; + temp = old.temp; + + v_batt = old.v_batt; + sense_a = old.sense_a; + sense_m = old.sense_m; + + ground_accel = old.ground_accel; + ground_pres = old.ground_pres; + accel_plus_g = old.accel_plus_g; + accel_minus_g = old.accel_minus_g; + + flight_accel = old.flight_accel; + flight_vel = old.flight_vel; + flight_pres = old.flight_pres; + } + + public AltosRecordTM2 clone() { + return new AltosRecordTM2(this); + } + + void make_missing() { + + accel = MISSING; + pres = MISSING; + temp = MISSING; + + v_batt = MISSING; + sense_a = MISSING; + sense_m = MISSING; + + ground_accel = MISSING; + ground_pres = MISSING; + accel_plus_g = MISSING; + accel_minus_g = MISSING; + + flight_accel = 0; + flight_vel = 0; + flight_pres = 0; + } + + public AltosRecordTM2(AltosRecord old) { + super.copy(old); + make_missing(); + } + + public AltosRecordTM2(AltosRecordTM2 old) { + copy(old); + } + + public AltosRecordTM2() { + super(); + make_missing(); + } +} diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java new file mode 100644 index 00000000..07917d5d --- /dev/null +++ b/altoslib/AltosSelfFlash.java @@ -0,0 +1,149 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; + +public class AltosSelfFlash { + File file; + FileInputStream input; + AltosHexfile image; + AltosLink link; + boolean aborted; + AltosFlashListener listener; + byte[] read_block, write_block; + + void action(String s, int percent) { + if (listener != null && !aborted) + listener.position(s, percent); + } + + void action(int part, int total) { + int percent = 100 * part / total; + action(String.format("%d/%d (%d%%)", + part, total, percent), + percent); + } + + void read_block(long addr) { + link.printf("R %x\n", addr); + + } + + void read_memory(long addr, int len) { + } + + void write_memory(long addr, byte[] data, int start, int len) { + + } + + void reboot() { + } + + public void flash() { + try { + int remain = image.data.length; + long flash_addr = image.address; + int image_start = 0; + + action("start", 0); + action(0, image.data.length); + while (remain > 0 && !aborted) { + int this_time = remain; + if (this_time > 0x100) + this_time = 0x100; + + if (link != null) { + /* write the data */ + write_memory(flash_addr, image.data, image_start, this_time); + + byte[] check = read_memory(flash_addr, this_time); + for (int i = 0; i < this_time; i++) + if (check[i] != image.data[image_start + i]) + throw new IOException(String.format("Flash write failed at 0x%x (%02x != %02x)", + image.address + image_start + i, + check[i], image.data[image_start + i])); + } else { + Thread.sleep(100); + } + + remain -= this_time; + flash_addr += this_time; + image_start += this_time; + + action(image.data.length - remain, image.data.length); + } + if (!aborted) { + action("done", 100); + if (link != null) { + reboot(); + } + } + if (link != null) + link.close(); + } catch (IOException ie) { + action(ie.getMessage(), -1); + abort(); + } catch (InterruptedException ie) { + abort(); + } + } + + public void close() { + if (link != null) + link.close(); + } + + synchronized public void abort() { + aborted = true; + close(); + } + + public boolean check_rom_config() { + if (link == null) + return true; + if (rom_config == null) + rom_config = debug.romconfig(); + return rom_config != null && rom_config.valid(); + } + + public void set_romconfig (AltosRomconfig romconfig) { + rom_config = romconfig; + } + + public AltosRomconfig romconfig() { + if (!check_rom_config()) + return null; + return rom_config; + } + + public AltosFlash(File file, AltosLink link, AltosFlashListener listener) + throws IOException, FileNotFoundException, InterruptedException { + this.file = file; + this.link = link; + this.listener = listener; + this.read_block = new byte[256]; + this.write_block = new byte[256]; + input = new FileInputStream(file); + image = new AltosHexfile(input); + if (link != null) { + debug.close(); + throw new IOException("Debug port not connected"); + } + } +} \ No newline at end of file diff --git a/altoslib/AltosSensorMetrum.java b/altoslib/AltosSensorMetrum.java new file mode 100644 index 00000000..686c78a8 --- /dev/null +++ b/altoslib/AltosSensorMetrum.java @@ -0,0 +1,55 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.util.concurrent.TimeoutException; + +class AltosSensorMetrum { + int tick; + int sense_a; + int sense_m; + int v_batt; + + public AltosSensorMetrum(AltosLink link) throws InterruptedException, TimeoutException { + String[] items = link.adc(); + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("drogue:")) { + sense_a = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("main:")) { + sense_m = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("batt:")) { + v_batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + } +} + diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index e0d9bb1f..b40b744f 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -21,7 +21,7 @@ package org.altusmetrum.altoslib_1; -public class AltosState { +public class AltosState implements Cloneable { public AltosRecord data; /* derived data */ @@ -35,24 +35,29 @@ public class AltosState { public int state; public boolean landed; public boolean ascent; /* going up? */ - public boolean boost; /* under power */ + public boolean boost; /* under power */ public double ground_altitude; public double altitude; public double height; public double pressure; public double acceleration; - public double battery; + public double battery_voltage; + public double pyro_voltage; public double temperature; - public double main_sense; - public double drogue_sense; - public double accel_speed; - public double baro_speed; + public double apogee_voltage; + public double main_voltage; + public double speed; + + public double prev_height; + public double prev_speed; + public double prev_acceleration; public double max_height; public double max_acceleration; - public double max_accel_speed; - public double max_baro_speed; + public double max_speed; + + public double kalman_height, kalman_speed, kalman_acceleration; public AltosGPS gps; public int gps_sequence; @@ -63,10 +68,11 @@ public class AltosState { public static final int MIN_PAD_SAMPLES = 10; public int npad; - public int ngps; public int gps_waiting; public boolean gps_ready; + public int ngps; + public AltosGreatCircle from_pad; public double elevation; /* from pad */ public double range; /* total distance */ @@ -78,80 +84,434 @@ public class AltosState { public int speak_tick; public double speak_altitude; + public String callsign; + public double accel_plus_g; + public double accel_minus_g; + public double accel; + public double ground_accel; + + public int log_format; + public int serial; + + public AltosMs5607 baro; + public double speed() { - if (ascent) - return accel_speed; - else - return baro_speed; + return speed; } public double max_speed() { - if (max_accel_speed != 0) - return max_accel_speed; - return max_baro_speed; + return max_speed; + } + + public void set_npad(int npad) { + this.npad = npad; + gps_waiting = MIN_PAD_SAMPLES - npad; + if (this.gps_waiting < 0) + gps_waiting = 0; + gps_ready = gps_waiting == 0; + } + + public void init() { + data = new AltosRecord(); + + report_time = System.currentTimeMillis(); + time = AltosRecord.MISSING; + time_change = AltosRecord.MISSING; + tick = AltosRecord.MISSING; + state = AltosLib.ao_flight_invalid; + landed = false; + boost = false; + + ground_altitude = AltosRecord.MISSING; + altitude = AltosRecord.MISSING; + height = AltosRecord.MISSING; + pressure = AltosRecord.MISSING; + acceleration = AltosRecord.MISSING; + temperature = AltosRecord.MISSING; + + prev_height = AltosRecord.MISSING; + prev_speed = AltosRecord.MISSING; + prev_acceleration = AltosRecord.MISSING; + + battery_voltage = AltosRecord.MISSING; + pyro_voltage = AltosRecord.MISSING; + apogee_voltage = AltosRecord.MISSING; + main_voltage = AltosRecord.MISSING; + + + accel_speed = AltosRecord.MISSING; + baro_speed = AltosRecord.MISSING; + + kalman_height = AltosRecord.MISSING; + kalman_speed = AltosRecord.MISSING; + kalman_acceleration = AltosRecord.MISSING; + + max_baro_speed = 0; + max_accel_speed = 0; + max_height = 0; + max_acceleration = 0; + + gps = null; + gps_sequence = 0; + + imu = null; + mag = null; + + set_npad(0); + ngps = 0; + + from_pad = null; + elevation = AltosRecord.MISSING; + range = AltosRecord.MISSING; + gps_height = AltosRecord.MISSING; + + pat_lat = AltosRecord.MISSING; + pad_lon = AltosRecord.MISSING; + pad_alt = AltosRecord.MISSING; + + speak_tick = AltosRecord.MISSING; + speak_altitude = AltosRecord.MISSING; + + callsign = null; + + accel_plus_g = AltosRecord.MISSING; + accel_minus_g = AltosRecord.MISSING; + log_format = AltosRecord.MISSING; + serial = AltosRecord.MISSING; + + baro = null; + } + + void copy(AltosState old) { + + data = null; + + if (old == null) { + init(); + return; + } + + report_time = old.report_time; + time = old.time; + time_change = old.time_change; + tick = old.tick; + + state = old.state; + landed = old.landed; + ascent = old.ascent; + boost = old.boost; + + ground_altitude = old.ground_altitude; + altitude = old.altitude; + height = old.height; + pressure = old.pressure; + acceleration = old.acceleration; + battery_voltage = old.battery_voltage; + pyro_voltage = old.pyro_voltage; + temperature = old.temperature; + apogee_voltage = old.apogee_voltage; + main_voltage = old.main_voltage; + accel_speed = old.accel_speed; + baro_speed = old.baro_speed; + + prev_height = old.height; + prev_speed = old.speed; + prev_acceleration = old.acceleration; + + max_height = old.max_height; + max_acceleration = old.max_acceleration; + max_accel_speed = old.max_accel_speed; + max_baro_speed = old.max_baro_speed; + + kalman_height = old.kalman_height; + kalman_speed = old.kalman_speed; + kalman_acceleration = old.kalman_acceleration; + + if (old.gps != null) + gps = old.gps.clone(); + else + gps = null; + gps_sequence = old.gps_sequence; + + if (old.imu != null) + imu = old.imu.clone(); + else + imu = null; + + if (old.mag != null) + mag = old.mag.clone(); + else + mag = null; + + npad = old.npad; + gps_waiting = old.gps_waiting; + gps_ready = old.gps_ready; + ngps = old.ngps; + + if (old.from_pad != null) + from_pad = old.from_pad.clone(); + else + from_pad = null; + + elevation = old.elevation; + range = old.range; + + gps_height = old.gps_height; + pad_lat = old.pad_lat; + pad_lon = old.pad_lon; + pad_alt = old.pad_alt; + + speak_tick = old.speak_tick; + speak_altitude = old.speak_altitude; + + callsign = old.callsign; + + accel_plus_g = old.accel_plus_g; + accel_minus_g = old.accel_minus_g; + log_format = old.log_format; + serial = old.serial; + + baro = old.baro; + } + + double ground_altitude() { + + } + + double altitude() { + if (altitude != AltosRecord.MISSING) + return altitude; + if (gps != null) + return gps.alt; + return AltosRecord.MISSING; + } + + void update_vertical_pos() { + + double alt = altitude(); + if (state == AltosLib.ao_flight_pad) { + + } + + if (kalman_height != AltosRecord.MISSING) + height = kalman_height; + else if (altitude != AltosRecord.MISSING && ground_altitude != AltosRecord.MISSING) + height = altitude - ground_altitude; + else + height = AltosRecord.MISSING; + + update_speed(); + } + + double motion_filter_value() { + return 1/ Math.exp(time_change/10.0); + } + + void update_speed() { + if (kalman_speed != AltosRecord.MISSING) + speed = kalman_speed; + else if (state != AltosLib.ao_flight_invalid && + time_change != AltosRecord.MISSING) + { + if (ascent && acceleration != AltosRecord.MISSING) + { + if (prev_speed == AltosRecord.MISSING) + speed = acceleration * time_change; + else + speed = prev_speed + acceleration * time_change; + } + else if (height != AltosRecord.MISSING && + prev_height != AltosRecord.MISSING && + time_change != 0) + { + double new_speed = (height - prev_height) / time_change; + + if (prev_speed == AltosRecord.MISSING) + speed = new_speed; + else { + double filter = motion_filter_value(); + + speed = prev_speed * filter + new_speed * (1-filter); + } + } + } + if (acceleration == AltosRecord.MISSING) { + if (prev_speed != AltosRecord.MISSING && time_change != 0) { + double new_acceleration = (speed - prev_speed) / time_change; + + if (prev_acceleration == AltosRecord.MISSING) + acceleration = new_acceleration; + else { + double filter = motion_filter_value(); + + acceleration = prev_acceleration * filter + new_acceleration * (1-filter); + } + } + } + } + + void update_accel() { + if (accel == AltosRecord.MISSING) + return; + if (ground_Accel == AltosRecord.MISSING) + return; + if (accel_plus_g == AltosRecord.MISSING) + return; + if (accel_minus_g == AltosRecord.MISSING) + return; + + double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; + double counts_per_mss = counts_per_g / 9.80665; + + acceleration = (ground_accel - accel) / counts_per_mss; + update_speed(); + } + + public void set_tick(int tick) { + if (tick != AltosRecord.MISSING) { + if (this.tick != AltosRecord.MISSING) { + while (tick < this.tick) + tick += 65536; + time_change = (tick - this.tick) / 100.0; + } else + time_change = 0; + this.tick = tick; + update_time(); + } + } + + public void set_state(int state) { + if (state != AltosLib.ao_flight_invalid) { + this.state = state; + ascent = (AltosLib.ao_flight_boost <= state && + state <= AltosLib.ao_flight_coast); + boost = (AltosLib.ao_flight_boost == state); + } + + } + + public void set_altitude(double altitude) { + if (altitude != AltosRecord.MISSING) { + this.altitude = altitude; + update_vertical_pos(); + } + } + + public void set_ground_altitude(double ground_altitude) { + if (ground_altitude != AltosRecord.MISSING) { + this.ground_altitude = ground_altitude; + update_vertical_pos(); + } + } + + public void set_gps(AltosGPS gps, int sequence) { + if (gps != null) { + this.gps = gps.clone(); + gps_sequence = sequence; + update_vertical_pos(); + } + } + + public void set_kalman(double height, double speed, double acceleration) { + if (height != AltosRecord.MISSING) { + kalman_height = height; + kalman_speed = speed; + kalman_acceleration = acceleration; + baro_speed = accel_speed = speed; + update_vertical_pos(); + } + } + + public void set_pressure(double pressure) { + if (pressure != AltosRecord.MISSING) { + this.pressure = pressure; + set_altitude(AltosConvert.pressure_to_altitude(pressure)); + } + } + + public void set_accel_g(double accel_plus_g, double accel_minus_g) { + if (accel_plus_g != AltosRecord.MISSING) { + this.accel_plus_g = accel_plus_g; + this.accel_minus_g = accel_minus_g; + update_accel(); + } + } + public void set_ground_accel(double ground_accel) { + if (ground_accel != AltosRecord.MISSING) { + this.ground_accel = ground_accel; + update_accel(); + } + } + + public void set_accel(double accel) { + if (accel != AltosRecord.MISSING) { + this.accel = accel; + } + update_accel(); + } + + public void set_temperature(double temperature) { + if (temperature != AltosRecord.MISSING) + this.temperature = temperature; + } + + public void set_battery_voltage(double battery_voltage) { + if (battery_voltage != AltosRecord.MISSING) + this.battery_voltage = battery_voltage; + } + + public void set_pyro_voltage(double pyro_voltage) { + if (pyro_voltage != AltosRecord.MISSING) + this.pyro_voltage = pyro_voltage; + } + + public void set_apogee_voltage(double apogee_voltage) { + if (apogee_voltage != AltosRecord.MISSING) + this.apogee_voltage = apogee_voltage; + } + + public void set_main_voltage(double main_voltage) { + if (main_voltage != AltosRecord.MISSING) + this.main_voltage = main_voltage; } public void init (AltosRecord cur, AltosState prev_state) { + + if (cur == null) + cur = new AltosRecord(); + data = cur; /* Discard previous state if it was for a different board */ - if (prev_state != null && prev_state.data.serial != data.serial) + if (prev_state != null && prev_state.serial != cur.serial) prev_state = null; - ground_altitude = data.ground_altitude(); - altitude = data.altitude(); - if (altitude == AltosRecord.MISSING && data.gps != null) - altitude = data.gps.alt; + copy(prev_state); - height = AltosRecord.MISSING; - if (data.kalman_height != AltosRecord.MISSING) - height = data.kalman_height; - else { - if (altitude != AltosRecord.MISSING && ground_altitude != AltosRecord.MISSING) { - double cur_height = altitude - ground_altitude; - if (prev_state == null || prev_state.height == AltosRecord.MISSING) - height = cur_height; - else - height = (prev_state.height * 15 + cur_height) / 16.0; - } - } + set_ground_altitude(data.ground_altitude()); + set_altitude(data.altitude()); + + set_kalman(data.kalman_height, data.kalman_speed, data.kalman_acceleration); report_time = System.currentTimeMillis(); - if (data.kalman_acceleration != AltosRecord.MISSING) - acceleration = data.kalman_acceleration; - else - acceleration = data.acceleration(); - temperature = data.temperature(); - drogue_sense = data.drogue_voltage(); - main_sense = data.main_voltage(); - battery = data.battery_voltage(); - pressure = data.pressure(); - tick = data.tick; - state = data.state; + set_temperature(data.temperature()); + set_apogee_voltage(data.drogue_voltage()); + set_main_voltage(data.main_voltage()); + set_battery_voltage(data.battery_voltage()); - if (prev_state != null) { + set_pressure(data.pressure()); - /* Preserve any existing gps data */ - npad = prev_state.npad; - ngps = prev_state.ngps; - gps = prev_state.gps; - gps_sequence = prev_state.gps_sequence; - pad_lat = prev_state.pad_lat; - pad_lon = prev_state.pad_lon; - pad_alt = prev_state.pad_alt; - max_height = prev_state.max_height; - max_acceleration = prev_state.max_acceleration; - max_accel_speed = prev_state.max_accel_speed; - max_baro_speed = prev_state.max_baro_speed; - imu = prev_state.imu; - mag = prev_state.mag; - - /* make sure the clock is monotonic */ - while (tick < prev_state.tick) - tick += 65536; - - time_change = (tick - prev_state.tick) / 100.0; + set_tick(data.tick); + set_state(data.state); + + set_accel_g (data.accel_minus_g, data.accel_plus_g); + set_ground_accel(data.ground_accel); + set_accel (data.accel); + + set_gps(data.gps, data.gps_sequence); + + if (prev_state != null) { if (data.kalman_speed != AltosRecord.MISSING) { baro_speed = accel_speed = data.kalman_speed; @@ -200,6 +560,12 @@ public class AltosState { max_height = 0; max_acceleration = 0; time_change = 0; + baro = new AltosMs5607(); + callsign = ""; + accel_plus_g = AltosRecord.MISSING; + accel_minus_g = AltosRecord.MISSING; + log_format = AltosRecord.MISSING; + serial = AltosRecord.MISSING; } time = tick / 100.0; @@ -208,9 +574,9 @@ public class AltosState { /* Track consecutive 'good' gps reports, waiting for 10 of them */ if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) - npad++; + set_npad(npad+1); else - npad = 0; + set_npad(0); /* Average GPS data while on the pad */ if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) { @@ -233,16 +599,6 @@ public class AltosState { gps_sequence = data.gps_sequence; - gps_waiting = MIN_PAD_SAMPLES - npad; - if (gps_waiting < 0) - gps_waiting = 0; - - gps_ready = gps_waiting == 0; - - ascent = (AltosLib.ao_flight_boost <= state && - state <= AltosLib.ao_flight_coast); - boost = (AltosLib.ao_flight_boost == state); - /* Only look at accelerometer data under boost */ if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) max_acceleration = acceleration; @@ -270,6 +626,11 @@ public class AltosState { } } + public AltosState clone() { + AltosState s = new AltosState(data, this); + return s; + } + public AltosState(AltosRecord cur) { init(cur, null); } diff --git a/altoslib/AltosStateUpdate.java b/altoslib/AltosStateUpdate.java new file mode 100644 index 00000000..50460e21 --- /dev/null +++ b/altoslib/AltosStateUpdate.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +public interface AltosStateUpdate { + public void update_state(AltosState state); +} \ No newline at end of file diff --git a/altoslib/AltosTelemetryRecord.java b/altoslib/AltosTelemetryRecord.java index fdc3c88e..a744e61a 100644 --- a/altoslib/AltosTelemetryRecord.java +++ b/altoslib/AltosTelemetryRecord.java @@ -44,6 +44,7 @@ public abstract class AltosTelemetryRecord { final static int packet_type_companion = 0x07; final static int packet_type_MM_sensor = 0x08; final static int packet_type_MM_data = 0x09; + final static int packet_type_Mini = 0x10; static AltosTelemetryRecord parse_hex(String hex) throws ParseException, AltosCRCException { AltosTelemetryRecord r; diff --git a/altoslib/AltosTelemetryRecordMetrumData.java b/altoslib/AltosTelemetryRecordMetrumData.java new file mode 100644 index 00000000..70179b28 --- /dev/null +++ b/altoslib/AltosTelemetryRecordMetrumData.java @@ -0,0 +1,54 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryRecordMetrumData extends AltosTelemetryRecordRaw { + + int ground_pres; + int ground_accel; + int accel_plus_g; + int accel_minus_g; + + public AltosTelemetryRecordMetrumData(int[] in_bytes, int rssi) { + super(in_bytes, rssi); + + ground_pres = int32(8); + ground_accel = int16(12); + accel_plus_g = int16(14); + accel_minus_g = int16(16); + } + + public AltosRecord update_state(AltosRecord previous) { + AltosRecord n = super.update_state(previous); + + AltosRecordTM2 next; + if (!(n instanceof AltosRecordTM2)) { + next = new AltosRecordTM2(n); + } else { + next = (AltosRecordTM2) n; + } + + next.ground_accel = ground_accel; + next.ground_pres = ground_pres; + next.accel_plus_g = accel_plus_g; + next.accel_minus_g = accel_minus_g; + + return next; + } +} diff --git a/altoslib/AltosTelemetryRecordMetrumSensor.java b/altoslib/AltosTelemetryRecordMetrumSensor.java new file mode 100644 index 00000000..e41242c5 --- /dev/null +++ b/altoslib/AltosTelemetryRecordMetrumSensor.java @@ -0,0 +1,81 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryRecordMetrumSensor extends AltosTelemetryRecordRaw { + int state; + + int accel; + int pres; + int temp; + + int acceleration; + int speed; + int height; + + int v_batt; + int sense_a; + int sense_m; + + public AltosTelemetryRecordMetrumSensor(int[] in_bytes, int rssi) { + super(in_bytes, rssi); + + state = int8(5); + accel = int16(6); + pres = int32(8); + temp = int16(12); + + acceleration = int16(14); + speed = int16(16); + height = int16(18); + + v_batt = int16(20); + sense_a = int16(22); + sense_m = int16(24); + } + + public AltosRecord update_state(AltosRecord previous) { + AltosRecord n = super.update_state(previous); + + AltosRecordTM2 next; + if (!(n instanceof AltosRecordTM2)) { + next = new AltosRecordTM2(n); + } else { + next = (AltosRecordTM2) n; + } + + next.state = state; + + next.accel = accel; + next.pres = pres; + next.temp = temp; + + next.kalman_acceleration = acceleration / 16.0; + next.kalman_speed = speed / 16.0; + next.kalman_height = height; + + next.v_batt = v_batt; + next.sense_a = sense_a; + next.sense_m = sense_m; + + next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt;; + + return next; + } +} diff --git a/altoslib/AltosTelemetryRecordMini.java b/altoslib/AltosTelemetryRecordMini.java new file mode 100644 index 00000000..75a66c16 --- /dev/null +++ b/altoslib/AltosTelemetryRecordMini.java @@ -0,0 +1,82 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryRecordMini extends AltosTelemetryRecordRaw { + int state; + + int accel; + int pres; + int temp; + + int v_batt; + int sense_a; + int sense_m; + + int acceleration; + int speed; + int height; + + int ground_pres; + + public AltosTelemetryRecordMini(int[] in_bytes, int rssi) { + super(in_bytes, rssi); + + state = int8(5); + v_batt = int16(6); + sense_a = int16(8); + sense_m = int16(10); + + pres = int32(12); + temp = int16(16); + + acceleration = int16(18); + speed = int16(20); + height = int16(22); + + ground_pres = int32(24); + } + + public AltosRecord update_state(AltosRecord previous) { + AltosRecord n = super.update_state(previous); + + AltosRecordMini next; + if (!(n instanceof AltosRecordMini)) { + next = new AltosRecordMini(n); + } else { + next = (AltosRecordMini) n; + } + + next.pres = pres; + next.temp = temp; + + next.sense_a = sense_a; + next.sense_m = sense_m; + + next.ground_pres = ground_pres; + next.flight_accel = acceleration; + next.flight_vel = speed; + next.flight_height = height; + next.flight_pres = pres; + + next.seen |= AltosRecord.seen_sensor; + + return next; + } +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 8c1cf2ad..8a41b90c 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -17,7 +17,10 @@ altoslib_JAVA = \ AltosConvert.java \ AltosCRCException.java \ AltosDebug.java \ + AltosEeprom.java \ AltosEepromChunk.java \ + AltosEepromFile.java \ + AltosEepromHeader.java \ AltosEepromIterable.java \ AltosEepromLog.java \ AltosEepromMega.java \ @@ -26,6 +29,7 @@ altoslib_JAVA = \ AltosEepromTeleScience.java \ AltosEepromMini.java \ AltosEepromMiniIterable.java \ + AltosEepromOldIterable.java \ AltosFile.java \ AltosFlash.java \ AltosFlashListener.java \ @@ -65,6 +69,7 @@ altoslib_JAVA = \ AltosSensorMM.java \ AltosSensorTM.java \ AltosState.java \ + AltosStateUpdate.java \ AltosTelemetry.java \ AltosTelemetryIterable.java \ AltosTelemetryMap.java \ @@ -80,6 +85,7 @@ altoslib_JAVA = \ AltosTelemetryRecordSensor.java \ AltosTelemetryRecordMegaSensor.java \ AltosTelemetryRecordMegaData.java \ + AltosTelemetryRecordMini.java \ AltosUnitsListener.java \ AltosMs5607.java \ AltosIMU.java \ -- cgit v1.2.3 From de8d9c5630ae46378c50faf97f7d2e97fe139e30 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 29 Aug 2013 19:24:51 -0500 Subject: altoslib, altosui: Restructured state management now does TM eeprom files Removed uses of AltosRecord from AltosState, now just need to rewrite the other AltosState changing code to match Signed-off-by: Keith Packard --- altoslib/AltosConvert.java | 6 + altoslib/AltosEepromFile.java | 64 ++++- altoslib/AltosEepromHeader.java | 13 +- altoslib/AltosEepromHeaderIterable.java | 2 +- altoslib/AltosEepromIterable.java | 72 +++++- altoslib/AltosEepromMini.java | 17 ++ altoslib/AltosEepromMiniIterable.java | 2 +- altoslib/AltosEepromTM.java | 249 ++++++++----------- altoslib/AltosFlightReader.java | 2 +- altoslib/AltosGPS.java | 10 +- altoslib/AltosIMU.java | 1 + altoslib/AltosLib.java | 4 +- altoslib/AltosRecord.java | 8 + altoslib/AltosReplayReader.java | 6 +- altoslib/AltosState.java | 425 ++++++++++++++++++++------------ altoslib/AltosStateIterable.java | 29 +++ altoslib/AltosTelemetryReader.java | 6 +- altoslib/Makefile.am | 3 +- altosui/AltosAscent.java | 17 +- altosui/AltosCSV.java | 113 +++++---- altosui/AltosCSVUI.java | 8 +- altosui/AltosCompanionInfo.java | 4 +- altosui/AltosDataChooser.java | 12 +- altosui/AltosDescent.java | 17 +- altosui/AltosDisplayThread.java | 12 +- altosui/AltosEepromDownload.java | 5 +- altosui/AltosFlightStats.java | 99 ++++---- altosui/AltosFlightStatsTable.java | 8 +- altosui/AltosFlightStatus.java | 14 +- altosui/AltosFlightUI.java | 2 +- altosui/AltosGraphDataPoint.java | 17 +- altosui/AltosGraphDataSet.java | 31 ++- altosui/AltosGraphUI.java | 13 +- altosui/AltosInfoTable.java | 20 +- altosui/AltosKML.java | 56 +++-- altosui/AltosLanded.java | 14 +- altosui/AltosPad.java | 28 +-- altosui/AltosScanUI.java | 12 +- altosui/AltosSiteMap.java | 21 +- altosui/AltosUI.java | 106 ++++---- altosui/AltosWriter.java | 4 +- 41 files changed, 907 insertions(+), 645 deletions(-) create mode 100644 altoslib/AltosStateIterable.java (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index 8cd478e2..a1e2cdca 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -190,6 +190,12 @@ public class AltosConvert { return ignite / 32767 * 15.0; } + public static double + barometer_to_pressure(double count) + { + return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0; + } + public static double radio_to_frequency(int freq, int setting, int cal, int channel) { double f; diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 48d2543c..bcc7171e 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -21,11 +21,47 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosEepromFile { +class AltosEepromIterator implements Iterator { + AltosState state; + Iterator body; + AltosEeprom next; + boolean seen; + + public boolean hasNext() { + return !seen || body.hasNext(); + } + + public AltosState next() { + if (seen) { + AltosState n = state.clone(); + AltosEeprom e = body.next(); + + e.update_state(n); + state = n; + } + seen = true; + return state; + } + + public void remove () { + } + + public AltosEepromIterator(AltosState start, Iterator body) { + this.state = start; + this.body = body; + this.seen = false; + } +} + +public class AltosEepromFile extends AltosStateIterable { AltosEepromIterable headers; AltosEepromIterable body; + public void write_comments(PrintStream out) { + headers.write(out); + } + public void write(PrintStream out) { headers.write(out); body.write(out); @@ -38,14 +74,38 @@ public class AltosEepromFile { switch (state.log_format) { case AltosLib.AO_LOG_FORMAT_FULL: + body = new AltosEepromIterable(AltosEepromTM.read(input)); + break; case AltosLib.AO_LOG_FORMAT_TINY: case AltosLib.AO_LOG_FORMAT_TELEMETRY: case AltosLib.AO_LOG_FORMAT_TELESCIENCE: case AltosLib.AO_LOG_FORMAT_TELEMEGA: break; - case AltosLib.AO_LOG_FORMAT_MINI: + case AltosLib.AO_LOG_FORMAT_TELEMINI: + case AltosLib.AO_LOG_FORMAT_EASYMINI: body = new AltosEepromIterable(AltosEepromMini.read(input)); break; } } + + int boost_tick (AltosState start) { + AltosState state = start.clone(); + for (AltosEeprom eeprom : body) { + eeprom.update_state(state); + if (state.state >= AltosLib.ao_flight_boost) + return state.tick; + } + return 0; + } + + public Iterator iterator() { + + AltosState state = headers.state(); + Iterator i = body.iterator(); + + while (i.hasNext() && !state.valid()) + i.next().update_state(state); + state.set_boost_tick(boost_tick(state)); + return new AltosEepromIterator(state, i); + } } \ No newline at end of file diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index b2343dc6..a06f05ed 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -43,8 +43,7 @@ public class AltosEepromHeader extends AltosEeprom { state.callsign = data; break; case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = config_a; - state.accel_minus_g = config_b; + state.set_accel_g(config_a, config_b); break; case AltosLib.AO_LOG_RADIO_CAL: break; @@ -56,30 +55,38 @@ public class AltosEepromHeader extends AltosEeprom { state.log_format = config_a; break; case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = config_a; + state.set_serial(config_a); break; case AltosLib.AO_LOG_BARO_RESERVED: + state.make_baro(); state.baro.reserved = config_a; break; case AltosLib.AO_LOG_BARO_SENS: + state.make_baro(); state.baro.sens = config_a; break; case AltosLib.AO_LOG_BARO_OFF: + state.make_baro(); state.baro.off = config_a; break; case AltosLib.AO_LOG_BARO_TCS: + state.make_baro(); state.baro.tcs = config_a; break; case AltosLib.AO_LOG_BARO_TCO: + state.make_baro(); state.baro.tco = config_a; break; case AltosLib.AO_LOG_BARO_TREF: + state.make_baro(); state.baro.tref = config_a; break; case AltosLib.AO_LOG_BARO_TEMPSENS: + state.make_baro(); state.baro.tempsens = config_a; break; case AltosLib.AO_LOG_BARO_CRC: + state.make_baro(); state.baro.crc = config_a; break; case AltosLib.AO_LOG_SOFTWARE_VERSION: diff --git a/altoslib/AltosEepromHeaderIterable.java b/altoslib/AltosEepromHeaderIterable.java index fe9e05d9..01953f0e 100644 --- a/altoslib/AltosEepromHeaderIterable.java +++ b/altoslib/AltosEepromHeaderIterable.java @@ -29,7 +29,7 @@ public class AltosEepromHeaderIterable implements Iterable { } public AltosState state() { - AltosState state = new AltosState(null); + AltosState state = new AltosState(); for (AltosEepromHeader header : headers) header.update_state(state); diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 470a7a8a..8e6a2313 100644 --- a/altoslib/AltosEepromIterable.java +++ b/altoslib/AltosEepromIterable.java @@ -21,6 +21,74 @@ import java.io.*; import java.util.*; import java.text.*; +class AltosEepromOrdered implements Comparable { + AltosEeprom eeprom; + int index; + int tick; + + int cmdi() { + if (eeprom.cmd == AltosLib.AO_LOG_FLIGHT) + return 0; + return 1; + } + + public int compareTo(AltosEepromOrdered o) { + int cmd_diff = cmdi() - o.cmdi(); + + if (cmd_diff != 0) + return cmd_diff; + + int tick_diff = tick - o.tick; + + if (tick_diff != 0) + return tick_diff; + return index - o.index; + } + + AltosEepromOrdered (AltosEeprom eeprom, int index, int tick) { + this.eeprom = eeprom; + this.index = index; + this.tick = tick; + } +} + +class AltosEepromOrderedIterator implements Iterator { + TreeSet olist; + Iterator oiterator; + + public AltosEepromOrderedIterator(Iterable eeproms) { + olist = new TreeSet(); + + int tick = 0; + int index = 0; + boolean first = true; + + for (AltosEeprom e : eeproms) { + int t = e.tick; + if (first) + tick = t; + else { + while (t < tick - 32767) + t += 65536; + tick = t; + } + olist.add(new AltosEepromOrdered(e, index++, tick)); + } + oiterator = olist.iterator(); + } + + public boolean hasNext() { + return oiterator.hasNext(); + } + + public AltosEeprom next() { + return oiterator.next().eeprom; + } + + public void remove () { + } +} + public class AltosEepromIterable implements Iterable { public LinkedList eeproms; @@ -30,7 +98,7 @@ public class AltosEepromIterable implements Iterable { } public AltosState state() { - AltosState state = new AltosState(null); + AltosState state = new AltosState(); for (AltosEeprom header : eeproms) header.update_state(state); @@ -44,6 +112,6 @@ public class AltosEepromIterable implements Iterable { public Iterator iterator() { if (eeproms == null) eeproms = new LinkedList(); - return eeproms.iterator(); + return new AltosEepromOrderedIterator(eeproms); } } \ No newline at end of file diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index ced87680..1e0ff1b9 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -55,13 +55,30 @@ public class AltosEepromMini extends AltosEeprom { public int sense_m() { return data16(8); } public int v_batt() { return data16(10); } + double voltage(AltosState state, int sensor) { + double supply; + + if (state.log_format == AltosLib.AO_LOG_FORMAT_EASYMINI) + supply = 3.0; + else + supply = 3.3; + return sensor / 32767.0 * supply * 127/27; + } + public void update_state(AltosState state) { switch (cmd) { case AltosLib.AO_LOG_FLIGHT: + state.set_flight(flight()); + state.set_ground_pressure(ground_pres()); break; case AltosLib.AO_LOG_STATE: + state.set_state(state()); break; case AltosLib.AO_LOG_SENSOR: + state.set_ms5607(pres(), temp()); + state.set_apogee_voltage(voltage(state, sense_a())); + state.set_main_voltage(voltage(state, sense_m())); + state.set_battery_voltage(voltage(state, v_batt())); break; } } diff --git a/altoslib/AltosEepromMiniIterable.java b/altoslib/AltosEepromMiniIterable.java index 1f221187..495495eb 100644 --- a/altoslib/AltosEepromMiniIterable.java +++ b/altoslib/AltosEepromMiniIterable.java @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosEepromMiniIterable extends AltosRecordIterable { +public class AltosEepromMiniIterable implements Iterable { static final int seen_flight = 1; static final int seen_sensor = 2; diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index fc7ec321..6945468b 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -17,134 +17,119 @@ package org.altusmetrum.altoslib_1; +import java.io.*; +import java.util.*; import java.text.*; -public class AltosEepromTM implements AltosStateUpdate { +public class AltosEepromTM extends AltosEeprom { public int cmd; public int tick; public int a; public int b; - public String data; public boolean tick_valid; public static final int record_length = 8; + static double + thermometer_to_temperature(double thermo) + { + return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; + } + + public void write(PrintStream out) { + out.printf("%c %4x %4x %4x\n", cmd, tick, a, b); + } + public void update_state(AltosState state) { - state.set_tick(tick); + 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.ground_accel = a; - state.flight = b; + state.set_state(AltosLib.ao_flight_pad); + state.set_ground_accel(a); + state.set_flight(b); state.set_boost_tick(tick); - state.time = 0; break; case AltosLib.AO_LOG_SENSOR: - state.set_telemetrum(a, b); + state.set_tick(tick); + state.set_accel(a); + double pressure = AltosConvert.barometer_to_pressure(b); + state.set_pressure(pressure); break; case AltosLib.AO_LOG_PRESSURE: - state.set_telemetrum(AltosState.MISSING, b); + state.set_tick(tick); + state.set_pressure(AltosConvert.barometer_to_pressure(b)); break; case AltosLib.AO_LOG_TEMP_VOLT: -/* - - record.temp = a; - record.batt = b; - eeprom_state.seen |= AltosRecord.seen_temp_volt; -*/ + state.set_tick(tick); + state.set_temperature(thermometer_to_temperature(a)); + state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(b)); break; case AltosLib.AO_LOG_DEPLOY: -/* - record.drogue = a; - record.main = b; - eeprom_state.seen |= AltosRecord.seen_deploy; - has_ignite = true; -*/ + state.set_tick(tick); + state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(a)); + state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(b)); break; case AltosLib.AO_LOG_STATE: - state.state = a; - break; -// case AltosLib.AO_LOG_GPS_TIME: -// eeprom_state.gps_tick = record.tick; -// eeprom_state.seen |= AltosRecord.seen_gps_time; -// AltosGPS old = state.gps; -// AltosGPS gps = new AltosGPS(); -// -// /* GPS date doesn't get repeated through the file */ -// if (old != null) { -// gps.year = old.year; -// gps.month = old.month; -// gps.day = old.day; -// } -// gps.hour = (a & 0xff); -// gps.minute = (a >> 8); -// gps.second = (b & 0xff); -// -// int flags = (b >> 8); -// 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; -// state.temp_gps = gps; -// break; -// case AltosLib.AO_LOG_GPS_LAT: -// int lat32 = a | (b << 16); -// if (state.temp_gps == null) -// state.temp_gps = new AltosGPS(); -// state.temp_gps.lat = (double) lat32 / 1e7; -// break; -// case AltosLib.AO_LOG_GPS_LON: -// int lon32 = a | (b << 16); -// if (state.temp_gps == null) -// state.temp_gps = new AltosGPS(); -// state.temp_gps.lon = (double) lon32 / 1e7; -// break; -// case AltosLib.AO_LOG_GPS_ALT: -// if (state.temp_gps == null) -// state.temp_gps = new AltosGPS(); -// state.temp_gps.alt = a; -// break; -// case AltosLib.AO_LOG_GPS_SAT: -// if (record.tick == eeprom_state.gps_tick) { -// int svid = a; -// int c_n0 = b >> 8; -// if (record.gps == null) -// record.gps = new AltosGPS(); -// record.gps.add_sat(svid, c_n0); -// } -// break; -// case AltosLib.AO_LOG_GPS_DATE: -// if (record.gps == null) -// record.gps = new AltosGPS(); -// record.gps.year = (a & 0xff) + 2000; -// record.gps.month = a >> 8; -// record.gps.day = b & 0xff; -// break; - - case AltosLib.AO_LOG_CONFIG_VERSION: - break; - case AltosLib.AO_LOG_MAIN_DEPLOY: - break; - case AltosLib.AO_LOG_APOGEE_DELAY: - break; - case AltosLib.AO_LOG_RADIO_CHANNEL: - break; - case AltosLib.AO_LOG_CALLSIGN: - state.callsign = data; + state.set_tick(tick); + state.set_state(a); break; - case AltosLib.AO_LOG_ACCEL_CAL: - state.accel_plus_g = a; - state.accel_minus_g = b; + case AltosLib.AO_LOG_GPS_TIME: + gps = state.make_temp_gps(); + + gps.hour = (a & 0xff); + gps.minute = (a >> 8); + gps.second = (b & 0xff); + + int flags = (b >> 8); + + 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; break; - case AltosLib.AO_LOG_RADIO_CAL: + case AltosLib.AO_LOG_GPS_LAT: + gps = state.make_temp_gps(); + + int lat32 = a | (b << 16); + gps.lat = (double) lat32 / 1e7; break; - case AltosLib.AO_LOG_MANUFACTURER: + case AltosLib.AO_LOG_GPS_LON: + gps = state.make_temp_gps(); + + int lon32 = a | (b << 16); + gps.lon = (double) lon32 / 1e7; break; - case AltosLib.AO_LOG_PRODUCT: + case AltosLib.AO_LOG_GPS_ALT: + gps = state.make_temp_gps(); + gps.alt = a; break; - case AltosLib.AO_LOG_SERIAL_NUMBER: - state.serial = a; + case AltosLib.AO_LOG_GPS_SAT: + gps = state.make_temp_gps(); + int svid = a; + int c_n0 = b >> 8; + gps.add_sat(svid, c_n0); break; - case AltosLib.AO_LOG_SOFTWARE_VERSION: + case AltosLib.AO_LOG_GPS_DATE: + gps = state.make_temp_gps(); + gps.year = (a & 0xff) + 2000; + gps.month = a >> 8; + gps.day = b & 0xff; break; } } @@ -166,8 +151,6 @@ public class AltosEepromTM implements AltosStateUpdate { tick = chunk.data16(start + 2); a = chunk.data16(start + 4); b = chunk.data16(start + 6); - - data = null; } public AltosEepromTM (String line) { @@ -175,10 +158,8 @@ public class AltosEepromTM implements AltosStateUpdate { tick = 0; a = 0; b = 0; - data = null; if (line == null) { cmd = AltosLib.AO_LOG_INVALID; - data = ""; } else { try { String[] tokens = line.split("\\s+"); @@ -186,7 +167,6 @@ public class AltosEepromTM implements AltosStateUpdate { if (tokens[0].length() == 1) { if (tokens.length != 4) { cmd = AltosLib.AO_LOG_INVALID; - data = line; } else { cmd = tokens[0].codePointAt(0); tick = Integer.parseInt(tokens[1],16); @@ -194,53 +174,11 @@ public class AltosEepromTM implements AltosStateUpdate { a = Integer.parseInt(tokens[2],16); b = Integer.parseInt(tokens[3],16); } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - a = Integer.parseInt(tokens[3]); - b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; } else { cmd = AltosLib.AO_LOG_INVALID; - data = line; } } catch (NumberFormatException ne) { -v cmd = AltosLib.AO_LOG_INVALID; - data = line; + cmd = AltosLib.AO_LOG_INVALID; } } } @@ -252,4 +190,23 @@ v cmd = AltosLib.AO_LOG_INVALID; a = in_a; b = in_b; } + + static public LinkedList read(FileInputStream input) { + LinkedList tms = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + AltosEepromTM tm = new AltosEepromTM(line); + tms.add(tm); + } catch (IOException ie) { + break; + } + } + + return tms; + } + } diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java index 34526658..5a415274 100644 --- a/altoslib/AltosFlightReader.java +++ b/altoslib/AltosFlightReader.java @@ -28,7 +28,7 @@ public class AltosFlightReader { public void init() { } - public AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { return null; } + public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException { return null; } public void close(boolean interrupted) { } diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index f7929a4c..eb384e4d 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -28,7 +28,7 @@ public class AltosGPS implements Cloneable { public boolean connected; public double lat; /* degrees (+N -S) */ public double lon; /* degrees (+E -W) */ - public int alt; /* m */ + public double alt; /* m */ public int year; public int month; public int day; @@ -222,7 +222,7 @@ public class AltosGPS implements Cloneable { g.nsat = nsat; g.locked = locked; g.connected = connected; - g.lat = lat; g./* degrees (+N -S) */ + g.lat = lat; /* degrees (+N -S) */ g.lon = lon; /* degrees (+E -W) */ g.alt = alt; /* m */ g.year = year; @@ -242,11 +242,11 @@ public class AltosGPS implements Cloneable { if (cc_gps_sat != null) { g.cc_gps_sat = new AltosGPSSat[cc_gps_sat.length]; for (int i = 0; i < cc_gps_sat.length; i++) { - g.cc_gps_sat[i] = new AltosGPSSat(); - g.cc_gps_sat[i].svid = cc_gps_sat[i].svid; - g.cc_gps_sat[i].c_n0 = cc_gps_sat[i].c_n0; + g.cc_gps_sat[i] = new AltosGPSSat(cc_gps_sat[i].svid, + cc_gps_sat[i].c_n0); } } + return g; } public AltosGPS(AltosGPS old) { diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index 46df35bf..c5ebbb16 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -37,5 +37,6 @@ public class AltosIMU implements Cloneable { n.gyro_y = gyro_y; n.gyro_z = gyro_z; return n; + } } \ No newline at end of file diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index d60ef492..4ca8ad9d 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -218,7 +218,9 @@ public class AltosLib { public static final int AO_LOG_FORMAT_TELEMETRY = 3; public static final int AO_LOG_FORMAT_TELESCIENCE = 4; public static final int AO_LOG_FORMAT_TELEMEGA = 5; - public static final int AO_LOG_FORMAT_MINI = 6; + 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_NONE = 127; public static boolean isspace(int c) { diff --git a/altoslib/AltosRecord.java b/altoslib/AltosRecord.java index 5e4ed927..0c8e1db9 100644 --- a/altoslib/AltosRecord.java +++ b/altoslib/AltosRecord.java @@ -56,6 +56,10 @@ public class AltosRecord implements Comparable , Cloneable { public int flight_log_max; public String firmware_version; + public double accel_plus_g, accel_minus_g; + public double ground_accel; + public double accel; + public AltosRecordCompanion companion; /* Telemetry sources have these values recorded from the flight computer */ @@ -167,5 +171,9 @@ public class AltosRecord implements Comparable , Cloneable { kalman_acceleration = MISSING; kalman_speed = MISSING; kalman_height = MISSING; + + accel_plus_g = MISSING; + accel_minus_g = MISSING; + } } diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index a7e30370..0c14dee4 100644 --- a/altoslib/AltosReplayReader.java +++ b/altoslib/AltosReplayReader.java @@ -25,10 +25,10 @@ import java.util.*; */ public class AltosReplayReader extends AltosFlightReader { - Iterator iterator; + Iterator iterator; File file; - public AltosRecord read() { + public AltosState read() { if (iterator.hasNext()) return iterator.next(); return null; @@ -45,7 +45,7 @@ public class AltosReplayReader extends AltosFlightReader { public File backing_file() { return file; } - public AltosReplayReader(Iterator in_iterator, File in_file) { + public AltosReplayReader(Iterator in_iterator, File in_file) { iterator = in_iterator; file = in_file; name = file.getName(); diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index b40b744f..daf06c19 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -22,22 +22,35 @@ package org.altusmetrum.altoslib_1; public class AltosState implements Cloneable { - public AltosRecord data; + public AltosRecord record; + + public static final int set_position = 1; + public static final int set_gps = 2; + public static final int set_data = 4; + + public int set; /* derived data */ public long report_time; public double time; + public double prev_time; public double time_change; public int tick; + public int boost_tick; public int state; + public int flight; + public int serial; public boolean landed; public boolean ascent; /* going up? */ public boolean boost; /* under power */ + public int rssi; + public int status; public double ground_altitude; + public double ground_pressure; public double altitude; public double height; public double pressure; @@ -60,6 +73,8 @@ public class AltosState implements Cloneable { public double kalman_height, kalman_speed, kalman_acceleration; public AltosGPS gps; + public AltosGPS temp_gps; + public boolean gps_pending; public int gps_sequence; public AltosIMU imu; @@ -91,10 +106,11 @@ public class AltosState implements Cloneable { public double ground_accel; public int log_format; - public int serial; public AltosMs5607 baro; + public AltosRecordCompanion companion; + public double speed() { return speed; } @@ -112,17 +128,25 @@ public class AltosState implements Cloneable { } public void init() { - data = new AltosRecord(); + record = null; + + set = 0; report_time = System.currentTimeMillis(); time = AltosRecord.MISSING; time_change = AltosRecord.MISSING; + prev_time = AltosRecord.MISSING; tick = AltosRecord.MISSING; + boost_tick = AltosRecord.MISSING; state = AltosLib.ao_flight_invalid; + flight = AltosRecord.MISSING; landed = false; boost = false; + rssi = AltosRecord.MISSING; + status = 0; ground_altitude = AltosRecord.MISSING; + ground_pressure = AltosRecord.MISSING; altitude = AltosRecord.MISSING; height = AltosRecord.MISSING; pressure = AltosRecord.MISSING; @@ -138,21 +162,20 @@ public class AltosState implements Cloneable { apogee_voltage = AltosRecord.MISSING; main_voltage = AltosRecord.MISSING; - - accel_speed = AltosRecord.MISSING; - baro_speed = AltosRecord.MISSING; + speed = AltosRecord.MISSING; kalman_height = AltosRecord.MISSING; kalman_speed = AltosRecord.MISSING; kalman_acceleration = AltosRecord.MISSING; - max_baro_speed = 0; - max_accel_speed = 0; + max_speed = 0; max_height = 0; max_acceleration = 0; gps = null; + temp_gps = null; gps_sequence = 0; + gps_pending = false; imu = null; mag = null; @@ -165,7 +188,7 @@ public class AltosState implements Cloneable { range = AltosRecord.MISSING; gps_height = AltosRecord.MISSING; - pat_lat = AltosRecord.MISSING; + pad_lat = AltosRecord.MISSING; pad_lon = AltosRecord.MISSING; pad_alt = AltosRecord.MISSING; @@ -176,15 +199,18 @@ public class AltosState implements Cloneable { accel_plus_g = AltosRecord.MISSING; accel_minus_g = AltosRecord.MISSING; + accel = AltosRecord.MISSING; + ground_accel = AltosRecord.MISSING; log_format = AltosRecord.MISSING; serial = AltosRecord.MISSING; baro = null; + companion = null; } void copy(AltosState old) { - data = null; + record = null; if (old == null) { init(); @@ -193,13 +219,19 @@ public class AltosState implements Cloneable { report_time = old.report_time; time = old.time; - time_change = old.time_change; + time_change = 0; tick = old.tick; + boost_tick = old.boost_tick; state = old.state; + flight = old.flight; landed = old.landed; ascent = old.ascent; boost = old.boost; + rssi = old.rssi; + status = old.status; + + set = 0; ground_altitude = old.ground_altitude; altitude = old.altitude; @@ -211,17 +243,16 @@ public class AltosState implements Cloneable { temperature = old.temperature; apogee_voltage = old.apogee_voltage; main_voltage = old.main_voltage; - accel_speed = old.accel_speed; - baro_speed = old.baro_speed; + speed = old.speed; prev_height = old.height; prev_speed = old.speed; prev_acceleration = old.acceleration; + prev_time = old.time; max_height = old.max_height; max_acceleration = old.max_acceleration; - max_accel_speed = old.max_accel_speed; - max_baro_speed = old.max_baro_speed; + max_speed = old.max_speed; kalman_height = old.kalman_height; kalman_speed = old.kalman_speed; @@ -231,7 +262,12 @@ public class AltosState implements Cloneable { gps = old.gps.clone(); else gps = null; + if (old.temp_gps != null) + temp_gps = old.temp_gps.clone(); + else + temp_gps = null; gps_sequence = old.gps_sequence; + gps_pending = old.gps_pending; if (old.imu != null) imu = old.imu.clone(); @@ -268,14 +304,14 @@ public class AltosState implements Cloneable { accel_plus_g = old.accel_plus_g; accel_minus_g = old.accel_minus_g; + accel = old.accel; + ground_accel = old.ground_accel; + log_format = old.log_format; serial = old.serial; baro = old.baro; - } - - double ground_altitude() { - + companion = old.companion; } double altitude() { @@ -289,8 +325,12 @@ public class AltosState implements Cloneable { void update_vertical_pos() { double alt = altitude(); - if (state == AltosLib.ao_flight_pad) { - + + if (state == AltosLib.ao_flight_pad && alt != AltosRecord.MISSING && ground_pressure == AltosRecord.MISSING) { + if (ground_altitude == AltosRecord.MISSING) + ground_altitude = alt; + else + ground_altitude = (ground_altitude * 7 + alt) / 8; } if (kalman_height != AltosRecord.MISSING) @@ -300,6 +340,9 @@ public class AltosState implements Cloneable { else height = AltosRecord.MISSING; + if (height != AltosRecord.MISSING && height > max_height) + max_height = height; + update_speed(); } @@ -348,12 +391,14 @@ public class AltosState implements Cloneable { } } } + if (boost && speed != AltosRecord.MISSING && speed > max_speed) + max_speed = speed; } void update_accel() { if (accel == AltosRecord.MISSING) return; - if (ground_Accel == AltosRecord.MISSING) + if (ground_accel == AltosRecord.MISSING) return; if (accel_plus_g == AltosRecord.MISSING) return; @@ -364,9 +409,60 @@ public class AltosState implements Cloneable { double counts_per_mss = counts_per_g / 9.80665; acceleration = (ground_accel - accel) / counts_per_mss; + + /* Only look at accelerometer data under boost */ + if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) + max_acceleration = acceleration; update_speed(); } + void update_time() { + if (tick != AltosRecord.MISSING) { + time = tick / 100.0; + if (prev_time != AltosRecord.MISSING) + time_change = time - prev_time; + } + } + + void update_gps() { + elevation = 0; + range = -1; + gps_height = 0; + + 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) { + set_npad(npad+1); + if (pad_lat != AltosRecord.MISSING) { + pad_lat = (pad_lat * 31 + gps.lat) / 32; + pad_lon = (pad_lon * 31 + gps.lon) / 32; + pad_alt = (pad_alt * 31 + gps.alt) / 32; + } + } + if (pad_lat == AltosRecord.MISSING) { + pad_lat = gps.lat; + pad_lon = gps.lon; + pad_alt = gps.alt; + } + } + if (gps.lat != 0 && gps.lon != 0 && + pad_lat != AltosRecord.MISSING && + pad_lon != AltosRecord.MISSING) + { + double h = height; + + if (h == AltosRecord.MISSING) + h = 0; + from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h); + elevation = from_pad.elevation; + range = from_pad.range; + gps_height = gps.alt - pad_alt; + } + } + public void set_tick(int tick) { if (tick != AltosRecord.MISSING) { if (this.tick != AltosRecord.MISSING) { @@ -380,6 +476,15 @@ public class AltosState implements Cloneable { } } + public void set_boost_tick(int boost_tick) { + if (boost_tick != AltosRecord.MISSING) + this.boost_tick = boost_tick; + } + + public String state_name() { + return AltosLib.state_name(state); + } + public void set_state(int state) { if (state != AltosLib.ao_flight_invalid) { this.state = state; @@ -390,10 +495,47 @@ public class AltosState implements Cloneable { } + public void set_flight(int flight) { + + /* When the flight changes, reset the state */ + if (flight != AltosRecord.MISSING) { + if (this.flight != AltosRecord.MISSING && + this.flight != flight) { + init(); + } + this.flight = flight; + } + } + + public void set_serial(int serial) { + /* When the serial changes, reset the state */ + if (serial != AltosRecord.MISSING) { + if (this.serial != AltosRecord.MISSING && + this.serial != serial) { + init(); + } + this.serial = serial; + } + } + + public int rssi() { + if (rssi == AltosRecord.MISSING) + return 0; + return rssi; + } + + public void set_rssi(int rssi, int status) { + if (rssi != AltosRecord.MISSING) { + this.rssi = rssi; + this.status = status; + } + } + public void set_altitude(double altitude) { if (altitude != AltosRecord.MISSING) { this.altitude = altitude; update_vertical_pos(); + set |= set_position; } } @@ -404,11 +546,24 @@ public class AltosState implements Cloneable { } } + public void set_ground_pressure (double pressure) { + if (pressure != AltosRecord.MISSING) { + this.ground_pressure = pressure; + set_ground_altitude(AltosConvert.pressure_to_altitude(pressure)); + update_vertical_pos(); + } + } + public void set_gps(AltosGPS gps, int sequence) { if (gps != null) { + System.out.printf ("gps date: %d-%d-%d time %d:%d:%d\n", + gps.year, gps.month, gps.day, + gps.hour, gps.minute, gps.second); this.gps = gps.clone(); gps_sequence = sequence; + update_gps(); update_vertical_pos(); + set |= set_gps; } } @@ -417,7 +572,6 @@ public class AltosState implements Cloneable { kalman_height = height; kalman_speed = speed; kalman_acceleration = acceleration; - baro_speed = accel_speed = speed; update_vertical_pos(); } } @@ -429,6 +583,29 @@ public class AltosState implements Cloneable { } } + public void make_baro() { + if (baro == null) + baro = new AltosMs5607(); + } + + public void set_ms5607(int pres, int temp) { + if (baro != null) { + baro.set(pres, temp); + + set_pressure(baro.pa); + set_temperature(baro.cc / 100.0); + } + } + + public void make_companion (int nchannels) { + if (companion == null) + companion = new AltosRecordCompanion(nchannels); + } + + public void set_companion(AltosRecordCompanion companion) { + this.companion = companion; + } + public void set_accel_g(double accel_plus_g, double accel_minus_g) { if (accel_plus_g != AltosRecord.MISSING) { this.accel_plus_g = accel_plus_g; @@ -451,36 +628,77 @@ public class AltosState implements Cloneable { } public void set_temperature(double temperature) { - if (temperature != AltosRecord.MISSING) + if (temperature != AltosRecord.MISSING) { this.temperature = temperature; + set |= set_data; + } } public void set_battery_voltage(double battery_voltage) { - if (battery_voltage != AltosRecord.MISSING) + if (battery_voltage != AltosRecord.MISSING) { this.battery_voltage = battery_voltage; + set |= set_data; + } } public void set_pyro_voltage(double pyro_voltage) { - if (pyro_voltage != AltosRecord.MISSING) + if (pyro_voltage != AltosRecord.MISSING) { this.pyro_voltage = pyro_voltage; + set |= set_data; + } } public void set_apogee_voltage(double apogee_voltage) { - if (apogee_voltage != AltosRecord.MISSING) + if (apogee_voltage != AltosRecord.MISSING) { this.apogee_voltage = apogee_voltage; + set |= set_data; + } } public void set_main_voltage(double main_voltage) { - if (main_voltage != AltosRecord.MISSING) + if (main_voltage != AltosRecord.MISSING) { this.main_voltage = main_voltage; + set |= set_data; + } + } + + + public double time_since_boost() { + if (tick == AltosRecord.MISSING) + return 0.0; + + if (boost_tick != AltosRecord.MISSING) { + return (tick - boost_tick) / 100.0; + } + return tick / 100.0; + } + + public boolean valid() { + return tick != AltosRecord.MISSING && serial != AltosRecord.MISSING; + } + + public AltosGPS make_temp_gps() { + if (temp_gps == null) { + temp_gps = new AltosGPS(gps); + temp_gps.cc_gps_sat = null; + } + gps_pending = true; + return temp_gps; + } + + public void set_temp_gps() { + set_gps(temp_gps, gps_sequence + 1); + gps_pending = false; + temp_gps = null; } public void init (AltosRecord cur, AltosState prev_state) { + System.out.printf ("init\n"); if (cur == null) cur = new AltosRecord(); - data = cur; + record = cur; /* Discard previous state if it was for a different board */ if (prev_state != null && prev_state.serial != cur.serial) @@ -488,146 +706,35 @@ public class AltosState implements Cloneable { copy(prev_state); - set_ground_altitude(data.ground_altitude()); - set_altitude(data.altitude()); + set_ground_altitude(cur.ground_altitude()); + set_altitude(cur.altitude()); - set_kalman(data.kalman_height, data.kalman_speed, data.kalman_acceleration); + set_kalman(cur.kalman_height, cur.kalman_speed, cur.kalman_acceleration); report_time = System.currentTimeMillis(); - set_temperature(data.temperature()); - set_apogee_voltage(data.drogue_voltage()); - set_main_voltage(data.main_voltage()); - set_battery_voltage(data.battery_voltage()); - - set_pressure(data.pressure()); - - set_tick(data.tick); - set_state(data.state); + set_temperature(cur.temperature()); + set_apogee_voltage(cur.drogue_voltage()); + set_main_voltage(cur.main_voltage()); + set_battery_voltage(cur.battery_voltage()); - set_accel_g (data.accel_minus_g, data.accel_plus_g); - set_ground_accel(data.ground_accel); - set_accel (data.accel); + set_pressure(cur.pressure()); - set_gps(data.gps, data.gps_sequence); + set_tick(cur.tick); + set_state(cur.state); - if (prev_state != null) { + set_accel_g (cur.accel_minus_g, cur.accel_plus_g); + set_ground_accel(cur.ground_accel); + set_accel (cur.accel); - if (data.kalman_speed != AltosRecord.MISSING) { - baro_speed = accel_speed = data.kalman_speed; - } else { - /* compute barometric speed */ - - double height_change = height - prev_state.height; - - double prev_baro_speed = prev_state.baro_speed; - if (prev_baro_speed == AltosRecord.MISSING) - prev_baro_speed = 0; - - if (time_change > 0) - baro_speed = (prev_baro_speed * 3 + (height_change / time_change)) / 4.0; - else - baro_speed = prev_state.baro_speed; + if (cur.gps_sequence != gps_sequence) + set_gps(cur.gps, cur.gps_sequence); - double prev_accel_speed = prev_state.accel_speed; - - if (prev_accel_speed == AltosRecord.MISSING) - prev_accel_speed = 0; - - if (acceleration == AltosRecord.MISSING) { - /* Fill in mising acceleration value */ - accel_speed = baro_speed; - - if (time_change > 0 && accel_speed != AltosRecord.MISSING) - acceleration = (accel_speed - prev_accel_speed) / time_change; - else - acceleration = prev_state.acceleration; - } else { - /* compute accelerometer speed */ - accel_speed = prev_accel_speed + acceleration * time_change; - } - } - } else { - npad = 0; - ngps = 0; - gps = null; - gps_sequence = 0; - baro_speed = AltosRecord.MISSING; - accel_speed = AltosRecord.MISSING; - pad_alt = AltosRecord.MISSING; - max_baro_speed = 0; - max_accel_speed = 0; - max_height = 0; - max_acceleration = 0; - time_change = 0; - baro = new AltosMs5607(); - callsign = ""; - accel_plus_g = AltosRecord.MISSING; - accel_minus_g = AltosRecord.MISSING; - log_format = AltosRecord.MISSING; - serial = AltosRecord.MISSING; - } - - time = tick / 100.0; - - if (data.gps != null && data.gps_sequence != gps_sequence && (state < AltosLib.ao_flight_boost)) { - - /* Track consecutive 'good' gps reports, waiting for 10 of them */ - if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) - set_npad(npad+1); - else - set_npad(0); - - /* Average GPS data while on the pad */ - if (data.gps != null && data.gps.locked && data.gps.nsat >= 4) { - if (ngps > 1 && state == AltosLib.ao_flight_pad) { - /* filter pad position */ - pad_lat = (pad_lat * 31.0 + data.gps.lat) / 32.0; - pad_lon = (pad_lon * 31.0 + data.gps.lon) / 32.0; - pad_alt = (pad_alt * 31.0 + data.gps.alt) / 32.0; - } else { - pad_lat = data.gps.lat; - pad_lon = data.gps.lon; - pad_alt = data.gps.alt; - } - ngps++; - } - } else { - if (ngps == 0 && ground_altitude != AltosRecord.MISSING) - pad_alt = ground_altitude; - } - - gps_sequence = data.gps_sequence; - - /* Only look at accelerometer data under boost */ - if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) - max_acceleration = acceleration; - if (boost && accel_speed != AltosRecord.MISSING && accel_speed > max_accel_speed) - max_accel_speed = accel_speed; - if (boost && baro_speed != AltosRecord.MISSING && baro_speed > max_baro_speed) - max_baro_speed = baro_speed; - - if (height != AltosRecord.MISSING && height > max_height) - max_height = height; - elevation = 0; - range = -1; - gps_height = 0; - if (data.gps != null) { - gps = data.gps; - if (ngps > 0 && gps.locked) { - double h = height; - - if (h == AltosRecord.MISSING) h = 0; - from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h); - elevation = from_pad.elevation; - range = from_pad.range; - gps_height = gps.alt - pad_alt; - } - } } public AltosState clone() { - AltosState s = new AltosState(data, this); + AltosState s = new AltosState(); + s.copy(this); return s; } @@ -638,4 +745,8 @@ public class AltosState implements Cloneable { public AltosState (AltosRecord cur, AltosState prev) { init(cur, prev); } + + public AltosState () { + init(); + } } diff --git a/altoslib/AltosStateIterable.java b/altoslib/AltosStateIterable.java new file mode 100644 index 00000000..db4a2568 --- /dev/null +++ b/altoslib/AltosStateIterable.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; + +public abstract class AltosStateIterable implements Iterable { + + public void write_comments (PrintStream out) { + } + + public abstract void write(PrintStream out); +} diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index b4293c73..3915927c 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -27,16 +27,18 @@ public class AltosTelemetryReader extends AltosFlightReader { AltosRecord previous; double frequency; int telemetry; + AltosState state = null; LinkedBlockingQueue telem; - public AltosRecord read() throws InterruptedException, ParseException, AltosCRCException, IOException { + public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException { AltosLine l = telem.take(); if (l.line == null) throw new IOException("IO error"); AltosRecord next = AltosTelemetry.parse(l.line, previous); previous = next; - return next; + state = new AltosState (next, state); + return state; } public void flush() { diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 8a41b90c..bbcca906 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -20,6 +20,7 @@ altoslib_JAVA = \ AltosEeprom.java \ AltosEepromChunk.java \ AltosEepromFile.java \ + AltosEepromTM.java \ AltosEepromHeader.java \ AltosEepromIterable.java \ AltosEepromLog.java \ @@ -28,7 +29,6 @@ altoslib_JAVA = \ AltosEepromRecord.java \ AltosEepromTeleScience.java \ AltosEepromMini.java \ - AltosEepromMiniIterable.java \ AltosEepromOldIterable.java \ AltosFile.java \ AltosFlash.java \ @@ -69,6 +69,7 @@ altoslib_JAVA = \ AltosSensorMM.java \ AltosSensorTM.java \ AltosState.java \ + AltosStateIterable.java \ AltosStateUpdate.java \ AltosTelemetry.java \ AltosTelemetryIterable.java \ diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index 4da4d591..f8435037 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -251,10 +251,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Speed extends AscentValueHold { void show (AltosState state, AltosListenerState listener_state) { - double speed = state.accel_speed; - if (!state.ascent) - speed = state.baro_speed; - show(AltosConvert.speed, speed); + show(AltosConvert.speed, state.speed); } public Speed (GridBagLayout layout, int y) { super (layout, y, "Speed"); @@ -287,8 +284,8 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Apogee extends AscentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.drogue_sense); - lights.set(state.drogue_sense > 3.2); + show("%4.2f V", state.apogee_voltage); + lights.set(state.apogee_voltage > 3.7); } public Apogee (GridBagLayout layout, int y) { super(layout, y, "Apogee Igniter Voltage"); @@ -299,8 +296,8 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Main extends AscentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.main_sense); - lights.set(state.main_sense > 3.2); + show("%4.2f V", state.main_voltage); + lights.set(state.main_voltage > 3.7); } public Main (GridBagLayout layout, int y) { super(layout, y, "Main Igniter Voltage"); @@ -368,11 +365,11 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { lon.hide(); } height.show(state, listener_state); - if (state.main_sense != AltosRecord.MISSING) + if (state.main_voltage != AltosRecord.MISSING) main.show(state, listener_state); else main.hide(); - if (state.drogue_sense != AltosRecord.MISSING) + if (state.apogee_voltage != AltosRecord.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index 0676f99d..0b5a74e9 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -27,7 +27,7 @@ public class AltosCSV implements AltosWriter { boolean header_written; boolean seen_boost; int boost_tick; - LinkedList pad_records; + LinkedList pad_states; AltosState state; static final int ALTOS_CSV_VERSION = 5; @@ -105,47 +105,47 @@ public class AltosCSV implements AltosWriter { out.printf("version,serial,flight,call,time,clock,rssi,lqi"); } - void write_general(AltosRecord record) { + void write_general(AltosState state) { out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d", - ALTOS_CSV_VERSION, record.serial, record.flight, record.callsign, - (double) record.time, (double) record.tick / 100.0, - record.rssi, - record.status & 0x7f); + 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(AltosRecord record) { - out.printf("%d,%8s", record.state, record.state()); + 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(AltosRecord record) { + 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", - record.acceleration(), - record.pressure(), - record.altitude(), - record.height(), - state.accel_speed, - state.baro_speed, - record.temperature(), - record.battery_voltage(), - record.drogue_voltage(), - record.main_voltage()); + 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(AltosRecord record) { - AltosIMU imu = record.imu(); - AltosMag mag = record.mag(); + void write_advanced(AltosState state) { + AltosIMU imu = state.imu; + AltosMag mag = state.mag; if (imu == null) imu = new AltosIMU(); @@ -161,8 +161,8 @@ public class AltosCSV implements AltosWriter { 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(AltosRecord record) { - AltosGPS gps = record.gps; + void write_gps(AltosState state) { + AltosGPS gps = state.gps; if (gps == null) gps = new AltosGPS(); @@ -198,8 +198,8 @@ public class AltosCSV implements AltosWriter { } } - void write_gps_sat(AltosRecord record) { - AltosGPS gps = record.gps; + 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) { @@ -221,8 +221,8 @@ public class AltosCSV implements AltosWriter { out.printf(",companion_%02d", i); } - void write_companion(AltosRecord record) { - AltosRecordCompanion companion = record.companion; + void write_companion(AltosState state) { + AltosRecordCompanion companion = state.companion; int channels_written = 0; if (companion == null) { @@ -256,50 +256,49 @@ public class AltosCSV implements AltosWriter { out.printf ("\n"); } - void write_one(AltosRecord record) { - state = new AltosState(record, state); - write_general(record); out.printf(","); - write_flight(record); out.printf(","); - write_basic(record); out.printf(","); - if (record.imu() != null || record.mag() != null) - write_advanced(record); - if (record.gps != null) { + 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(record); out.printf(","); - write_gps_sat(record); + write_gps(state); out.printf(","); + write_gps_sat(state); } - if (record.companion != null) { + if (state.companion != null) { out.printf(","); - write_companion(record); + write_companion(state); } out.printf ("\n"); } void flush_pad() { - while (!pad_records.isEmpty()) { - write_one (pad_records.remove()); + while (!pad_states.isEmpty()) { + write_one (pad_states.remove()); } } - public void write(AltosRecord record) { - if (record.state == Altos.ao_flight_startup) + public void write(AltosState state) { + if (state.state == Altos.ao_flight_startup) return; if (!header_written) { - write_header(record.imu() != null || record.mag() != null, - record.gps != null, record.companion != null); + write_header(state.imu != null || state.mag != null, + state.gps != null, state.companion != null); header_written = true; } if (!seen_boost) { - if (record.state >= Altos.ao_flight_boost) { + if (state.state >= Altos.ao_flight_boost) { seen_boost = true; - boost_tick = record.tick; + boost_tick = state.tick; flush_pad(); } } if (seen_boost) - write_one(record); + write_one(state); else - pad_records.add(record); + pad_states.add(state); } public PrintStream out() { @@ -307,23 +306,23 @@ public class AltosCSV implements AltosWriter { } public void close() { - if (!pad_records.isEmpty()) { - boost_tick = pad_records.element().tick; + if (!pad_states.isEmpty()) { + boost_tick = pad_states.element().tick; flush_pad(); } out.close(); } - public void write(AltosRecordIterable iterable) { - iterable.write_comments(out()); - for (AltosRecord r : iterable) - write(r); + 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_records = new LinkedList(); + pad_states = new LinkedList(); } public AltosCSV(File in_name) throws FileNotFoundException { diff --git a/altosui/AltosCSVUI.java b/altosui/AltosCSVUI.java index 42508346..4b48bdf6 100644 --- a/altosui/AltosCSVUI.java +++ b/altosui/AltosCSVUI.java @@ -31,7 +31,7 @@ public class AltosCSVUI JFileChooser csv_chooser; JPanel accessory; JComboBox combo_box; - AltosRecordIterable iterable; + Iterable states; AltosWriter writer; static String[] combo_box_items = { "Comma Separated Values (.CSV)", "Googleearth Data (.KML)" }; @@ -55,8 +55,8 @@ public class AltosCSVUI set_default_file(); } - public AltosCSVUI(JFrame frame, AltosRecordIterable in_iterable, File source_file) { - iterable = in_iterable; + public AltosCSVUI(JFrame frame, AltosStateIterable states, File source_file) { + this.states = states; csv_chooser = new JFileChooser(source_file); accessory = new JPanel(); @@ -91,7 +91,7 @@ public class AltosCSVUI writer = new AltosCSV(file); else writer = new AltosKML(file); - writer.write(iterable); + writer.write(states); writer.close(); } catch (FileNotFoundException ee) { JOptionPane.showMessageDialog(frame, diff --git a/altosui/AltosCompanionInfo.java b/altosui/AltosCompanionInfo.java index ebe1d1f9..1ed2c425 100644 --- a/altosui/AltosCompanionInfo.java +++ b/altosui/AltosCompanionInfo.java @@ -86,8 +86,8 @@ public class AltosCompanionInfo extends JTable { public void show(AltosState state, AltosListenerState listener_state) { if (state == null) return; - if (state.data.companion != null) - companion = state.data.companion; + if (state.companion != null) + companion = state.companion; info_reset(); info_add_row(0, "Companion board", "%s", board_name()); if (companion != null) { diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java index c7b561d5..af6c245b 100644 --- a/altosui/AltosDataChooser.java +++ b/altosui/AltosDataChooser.java @@ -36,7 +36,7 @@ public class AltosDataChooser extends JFileChooser { return file; } - public AltosRecordIterable runDialog() { + public AltosStateIterable runDialog() { int ret; ret = showOpenDialog(frame); @@ -48,16 +48,10 @@ public class AltosDataChooser extends JFileChooser { try { if (filename.endsWith("eeprom")) { FileInputStream in = new FileInputStream(file); - return new AltosEepromIterable(in); + return new AltosEepromFile(in); } else if (filename.endsWith("telem")) { FileInputStream in = new FileInputStream(file); - return new AltosTelemetryIterable(in); - } else if (filename.endsWith("mega")) { - FileInputStream in = new FileInputStream(file); - return new AltosEepromMegaIterable(in); - } else if (filename.endsWith("mini")) { - FileInputStream in = new FileInputStream(file); - return new AltosEepromMiniIterable(in); + return null; // new AltosTelemetryIterable(in); } else { throw new FileNotFoundException(); } diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 29d33ddc..2b6575cb 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -256,10 +256,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Speed extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - double speed = state.accel_speed; - if (!state.ascent) - speed = state.baro_speed; - show(AltosConvert.speed, speed); + show(AltosConvert.speed, state.speed); } public Speed (GridBagLayout layout, int x, int y) { super (layout, x, y, "Speed"); @@ -325,8 +322,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Apogee extends DescentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.drogue_sense); - lights.set(state.drogue_sense > 3.2); + show("%4.2f V", state.apogee_voltage); + lights.set(state.apogee_voltage > 3.7); } public Apogee (GridBagLayout layout, int y) { super(layout, y, "Apogee Igniter Voltage"); @@ -337,8 +334,8 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Main extends DescentStatus { void show (AltosState state, AltosListenerState listener_state) { - show("%4.2f V", state.main_sense); - lights.set(state.main_sense > 3.2); + show("%4.2f V", state.main_voltage); + lights.set(state.main_voltage > 3.7); } public Main (GridBagLayout layout, int y) { super(layout, y, "Main Igniter Voltage"); @@ -430,11 +427,11 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { lat.hide(); lon.hide(); } - if (state.main_sense != AltosRecord.MISSING) + if (state.main_voltage != AltosRecord.MISSING) main.show(state, listener_state); else main.hide(); - if (state.drogue_sense != AltosRecord.MISSING) + if (state.apogee_voltage != AltosRecord.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 095bed99..70144fb2 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -113,7 +113,7 @@ public class AltosDisplayThread extends Thread { System.currentTimeMillis() - state.report_time >= 15000 || state.state == Altos.ao_flight_landed)) { - if (Math.abs(state.baro_speed) < 20 && state.height < 100) + if (Math.abs(state.speed) < 20 && state.height < 100) voice.speak("rocket landed safely"); else voice.speak("rocket may have crashed"); @@ -181,11 +181,11 @@ public class AltosDisplayThread extends Thread { synchronized boolean tell() { boolean ret = false; if (old_state == null || old_state.state != state.state) { - voice.speak(state.data.state()); + voice.speak(state.state_name()); if ((old_state == null || old_state.state <= Altos.ao_flight_boost) && state.state > Altos.ao_flight_boost) { voice.speak("max speed: %s.", - AltosConvert.speed.say_units(state.max_accel_speed + 0.5)); + AltosConvert.speed.say_units(state.max_speed + 0.5)); ret = true; } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) && state.state >= Altos.ao_flight_drogue) { @@ -218,11 +218,9 @@ public class AltosDisplayThread extends Thread { try { for (;;) { try { - AltosRecord record = reader.read(); - if (record == null) + state = reader.read(); + if (state == null) break; - old_state = state; - state = new AltosState(record, state); reader.update(state); show_safely(); told = tell(); diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 46715db6..95b17e2a 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -418,8 +418,9 @@ public class AltosEepromDownload implements Runnable { extension = "mega"; CaptureMega(eechunk); break; - case AltosLib.AO_LOG_FORMAT_MINI: - extension = "mini"; + case AltosLib.AO_LOG_FORMAT_EASYMINI: + case AltosLib.AO_LOG_FORMAT_TELEMINI: + extension = "eeprom"; CaptureMini(eechunk); break; } diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index dee31a8d..50deb6c8 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -24,8 +24,7 @@ public class AltosFlightStats { double max_height; double max_speed; double max_acceleration; - double[] state_accel_speed = new double[Altos.ao_flight_invalid + 1]; - double[] state_baro_speed = new double[Altos.ao_flight_invalid + 1]; + double[] state_speed = new double[Altos.ao_flight_invalid + 1]; double[] state_accel = new double[Altos.ao_flight_invalid + 1]; int[] state_count = new int[Altos.ao_flight_invalid + 1]; double[] state_start = new double[Altos.ao_flight_invalid + 1]; @@ -40,15 +39,18 @@ public class AltosFlightStats { boolean has_other_adc; boolean has_rssi; - double landed_time(AltosRecordIterable iterable) { - AltosState state = null; - for (AltosRecord record : iterable) { - state = new AltosState(record, state); + double landed_time(AltosStateIterable states) { + AltosState state = null; + for (AltosState s : states) { + state = s; if (state.state == Altos.ao_flight_landed) break; } + if (state == null) + return 0; + double landed_height = state.height; state = null; @@ -57,8 +59,8 @@ public class AltosFlightStats { double landed_time = -1000; - for (AltosRecord record : iterable) { - state = new AltosState(record, state); + for (AltosState s : states) { + state = s; if (state.height > landed_height + 10) { above = true; @@ -74,80 +76,70 @@ public class AltosFlightStats { return landed_time; } - double boost_time(AltosRecordIterable iterable) { - double boost_time = -1000; - - AltosState state = null; + double boost_time(AltosStateIterable states) { + double boost_time = AltosRecord.MISSING; + AltosState state = null; - for (AltosRecord record : iterable) { - state = new AltosState(record, state); - + for (AltosState s : states) { + state = s; if (state.acceleration < 1) boost_time = state.time; if (state.state >= Altos.ao_flight_boost) break; } - if (boost_time == -1000) + if (state == null) + return 0; + + if (boost_time == AltosRecord.MISSING) boost_time = state.time; return boost_time; } - public AltosFlightStats(AltosRecordIterable iterable) throws InterruptedException, IOException { - AltosState state = null; - AltosState new_state = null; - double boost_time = boost_time(iterable); + public AltosFlightStats(AltosStateIterable states) throws InterruptedException, IOException { + double boost_time = boost_time(states); double end_time = 0; - double landed_time = landed_time(iterable); + double landed_time = landed_time(states); - year = month = day = -1; - hour = minute = second = -1; - serial = flight = -1; - lat = lon = -1; + year = month = day = AltosRecord.MISSING; + hour = minute = second = AltosRecord.MISSING; + serial = flight = AltosRecord.MISSING; + lat = lon = AltosRecord.MISSING; has_gps = false; has_other_adc = false; has_rssi = false; - for (AltosRecord record : iterable) { - if (serial < 0) - serial = record.serial; - if ((record.seen & AltosRecord.seen_flight) != 0 && flight < 0) - flight = record.flight; - if ((record.seen & AltosRecord.seen_temp_volt) != 0) + for (AltosState state : states) { + if (serial == AltosRecord.MISSING && state.serial != AltosRecord.MISSING) + serial = state.serial; + if (flight == AltosRecord.MISSING && state.flight != AltosRecord.MISSING) + flight = state.flight; + if (state.battery_voltage != AltosRecord.MISSING) has_other_adc = true; - if (record.rssi != 0) + if (state.rssi != AltosRecord.MISSING) has_rssi = true; - new_state = new AltosState(record, state); - end_time = new_state.time; - state = new_state; + end_time = state.time; if (state.time >= boost_time && state.state < Altos.ao_flight_boost) state.state = Altos.ao_flight_boost; if (state.time >= landed_time && state.state < Altos.ao_flight_landed) state.state = Altos.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; + } if (0 <= state.state && state.state < Altos.ao_flight_invalid) { - if (state.state >= Altos.ao_flight_boost) { - if (state.gps != null && state.gps.locked && - year < 0) { - year = state.gps.year; - month = state.gps.month; - day = state.gps.day; - hour = state.gps.hour; - minute = state.gps.minute; - second = state.gps.second; - } - } state_accel[state.state] += state.acceleration; - state_accel_speed[state.state] += state.accel_speed; - state_baro_speed[state.state] += state.baro_speed; + state_speed[state.state] += state.speed; state_count[state.state]++; if (state_start[state.state] == 0.0) state_start[state.state] = state.time; if (state_end[state.state] < state.time) state_end[state.state] = state.time; max_height = state.max_height; - if (state.max_accel_speed != 0) - max_speed = state.max_accel_speed; - else - max_speed = state.max_baro_speed; + max_speed = state.max_speed; max_acceleration = state.max_acceleration; } if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { @@ -162,8 +154,7 @@ public class AltosFlightStats { } for (int s = Altos.ao_flight_startup; s <= Altos.ao_flight_landed; s++) { if (state_count[s] > 0) { - state_accel_speed[s] /= state_count[s]; - state_baro_speed[s] /= state_count[s]; + state_speed[s] /= state_count[s]; state_accel[s] /= state_count[s]; } if (state_start[s] == 0) diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java index a35b5f63..f8a2d4de 100644 --- a/altosui/AltosFlightStatsTable.java +++ b/altosui/AltosFlightStatsTable.java @@ -106,11 +106,11 @@ public class AltosFlightStatsTable extends JComponent { String.format("%5.0f G", AltosConvert.meters_to_g(stats.state_accel[Altos.ao_flight_boost]))); } new FlightStat(layout, y++, "Drogue descent rate", - String.format("%5.0f m/s", stats.state_baro_speed[Altos.ao_flight_drogue]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_drogue]))); + String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_drogue]), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]))); new FlightStat(layout, y++, "Main descent rate", - String.format("%5.0f m/s", stats.state_baro_speed[Altos.ao_flight_main]), - String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_main]))); + String.format("%5.0f m/s", stats.state_speed[Altos.ao_flight_main]), + String.format("%5.0f ft/s", AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]))); new FlightStat(layout, y++, "Ascent time", String.format("%6.1f s %s", stats.state_end[AltosLib.ao_flight_boost] - stats.state_start[AltosLib.ao_flight_boost], AltosLib.state_name(Altos.ao_flight_boost)), diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index d2910414..0be7bb51 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -65,7 +65,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Call extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - value.setText(state.data.callsign); + value.setText(state.callsign); } public Call (GridBagLayout layout, int x) { super (layout, x, "Callsign"); @@ -76,10 +76,10 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Serial extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.data.serial == AltosRecord.MISSING) + if (state.serial == AltosRecord.MISSING) value.setText("none"); else - value.setText(String.format("%d", state.data.serial)); + value.setText(String.format("%d", state.serial)); } public Serial (GridBagLayout layout, int x) { super (layout, x, "Serial"); @@ -90,10 +90,10 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Flight extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.data.flight == AltosRecord.MISSING) + if (state.flight == AltosRecord.MISSING) value.setText("none"); else - value.setText(String.format("%d", state.data.flight)); + value.setText(String.format("%d", state.flight)); } public Flight (GridBagLayout layout, int x) { super (layout, x, "Flight"); @@ -104,7 +104,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class FlightState extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - value.setText(state.data.state()); + value.setText(state.state_name()); } public FlightState (GridBagLayout layout, int x) { super (layout, x, "State"); @@ -115,7 +115,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class RSSI extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - value.setText(String.format("%d", state.data.rssi)); + value.setText(String.format("%d", state.rssi())); } public RSSI (GridBagLayout layout, int x) { super (layout, x, "RSSI"); diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 6d010d23..423cf10c 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -130,7 +130,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A flightStatus.show(state, listener_state); flightInfo.show(state, listener_state); - if (state.data.companion != null) { + if (state.companion != null) { if (!has_companion) { pane.add("Companion", companion); has_companion= true; diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index 7454f447..537efc44 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -42,9 +42,10 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public static final int data_pressure = 15; public double x() throws AltosUIDataMissing { - if (state.data.time < -2) + double time = state.time_since_boost(); + if (time < -2) throw new AltosUIDataMissing(-1); - return state.data.time; + return time; } public double y(int index) throws AltosUIDataMissing { @@ -63,16 +64,16 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { y = state.temperature; break; case data_battery_voltage: - y = state.battery; + y = state.battery_voltage; break; case data_drogue_voltage: - y = state.drogue_sense; + y = state.apogee_voltage; break; case data_main_voltage: - y = state.main_sense; + y = state.main_voltage; break; case data_rssi: - y = state.data.rssi; + y = state.rssi; break; case data_gps_height: y = state.gps_height; @@ -106,7 +107,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public int id(int index) { if (index == data_state) { - int s = state.data.state; + int s = state.state; if (s < Altos.ao_flight_boost || s > Altos.ao_flight_landed) return -1; return s; @@ -116,7 +117,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { public String id_name(int index) { if (index == data_state) - return state.data.state(); + return state.state_name(); return ""; } diff --git a/altosui/AltosGraphDataSet.java b/altosui/AltosGraphDataSet.java index dc047e9a..1e469c8a 100644 --- a/altosui/AltosGraphDataSet.java +++ b/altosui/AltosGraphDataSet.java @@ -25,34 +25,31 @@ import org.altusmetrum.altosuilib_1.*; class AltosGraphIterator implements Iterator { AltosGraphDataSet dataSet; - Iterator iterator; - - AltosState state; + Iterator iterator; public boolean hasNext() { return iterator.hasNext(); } public AltosUIDataPoint next() { - state = new AltosState(iterator.next(), state); + AltosState state = iterator.next(); - if ((state.data.seen & AltosRecord.seen_flight) != 0) { - if (dataSet.callsign == null && state.data.callsign != null) - dataSet.callsign = state.data.callsign; + if (state.flight != AltosRecord.MISSING) { + if (dataSet.callsign == null && state.callsign != null) + dataSet.callsign = state.callsign; - if (dataSet.serial == 0 && state.data.serial != 0) - dataSet.serial = state.data.serial; + if (dataSet.serial == 0 && state.serial != 0) + dataSet.serial = state.serial; - if (dataSet.flight == 0 && state.data.flight != 0) - dataSet.flight = state.data.flight; + if (dataSet.flight == 0 && state.flight != 0) + dataSet.flight = state.flight; } return new AltosGraphDataPoint(state); } - public AltosGraphIterator (Iterator iterator, AltosGraphDataSet dataSet) { + public AltosGraphIterator (Iterator iterator, AltosGraphDataSet dataSet) { this.iterator = iterator; - this.state = null; this.dataSet = dataSet; } @@ -64,7 +61,7 @@ class AltosGraphIterable implements Iterable { AltosGraphDataSet dataSet; public Iterator iterator() { - return new AltosGraphIterator(dataSet.records.iterator(), dataSet); + return new AltosGraphIterator(dataSet.states.iterator(), dataSet); } public AltosGraphIterable(AltosGraphDataSet dataSet) { @@ -76,7 +73,7 @@ public class AltosGraphDataSet implements AltosUIDataSet { String callsign; int serial; int flight; - AltosRecordIterable records; + AltosStateIterable states; public String name() { if (callsign != null) @@ -89,8 +86,8 @@ public class AltosGraphDataSet implements AltosUIDataSet { return new AltosGraphIterable(this); } - public AltosGraphDataSet (AltosRecordIterable records) { - this.records = records; + public AltosGraphDataSet (AltosStateIterable states) { + this.states = states; this.callsign = null; this.serial = 0; this.flight = 0; diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index d8b8f6dd..376e9910 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -28,10 +28,9 @@ public class AltosGraphUI extends AltosUIFrame AltosFlightStatsTable statsTable; boolean has_gps; - void fill_map(AltosRecordIterable records) { + void fill_map(AltosStateIterable states) { boolean any_gps = false; - for (AltosRecord record : records) { - state = new AltosState(record, state); + for (AltosState state : states) { if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { if (map == null) map = new AltosSiteMap(); @@ -41,7 +40,7 @@ public class AltosGraphUI extends AltosUIFrame } } - AltosGraphUI(AltosRecordIterable records, File file) throws InterruptedException, IOException { + AltosGraphUI(AltosStateIterable states, File file) throws InterruptedException, IOException { super(file.getName()); state = null; @@ -49,8 +48,8 @@ public class AltosGraphUI extends AltosUIFrame enable = new AltosUIEnable(); - stats = new AltosFlightStats(records); - graphDataSet = new AltosGraphDataSet(records); + stats = new AltosFlightStats(states); + graphDataSet = new AltosGraphDataSet(states); graph = new AltosGraph(enable, stats, graphDataSet); @@ -61,7 +60,7 @@ public class AltosGraphUI extends AltosUIFrame pane.add("Flight Statistics", statsTable); has_gps = false; - fill_map(records); + fill_map(states); if (has_gps) pane.add("Map", map); diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 3d16faf2..8601d76f 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -122,15 +122,15 @@ public class AltosInfoTable extends JTable { if (state.speed() != AltosRecord.MISSING) info_add_row(0, "Speed", "%8.1f m/s", state.speed()); if (state.speed() != AltosRecord.MISSING) - info_add_row(0, "Max Speed", "%8.1f m/s", state.max_accel_speed); + info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed); if (state.temperature != AltosRecord.MISSING) info_add_row(0, "Temperature", "%9.2f °C", state.temperature); - if (state.battery != AltosRecord.MISSING) - info_add_row(0, "Battery", "%9.2f V", state.battery); - if (state.drogue_sense != AltosRecord.MISSING) - info_add_row(0, "Drogue", "%9.2f V", state.drogue_sense); - if (state.main_sense != AltosRecord.MISSING) - info_add_row(0, "Main", "%9.2f V", state.main_sense); + if (state.battery_voltage != AltosRecord.MISSING) + info_add_row(0, "Battery", "%9.2f V", state.battery_voltage); + if (state.apogee_voltage != AltosRecord.MISSING) + info_add_row(0, "Drogue", "%9.2f V", state.apogee_voltage); + if (state.main_voltage != AltosRecord.MISSING) + info_add_row(0, "Main", "%9.2f V", state.main_voltage); } if (listener_state != null) { info_add_row(0, "CRC Errors", "%6d", listener_state.crc_errors); @@ -148,13 +148,13 @@ public class AltosInfoTable extends JTable { else info_add_row(1, "GPS state", "wait (%d)", state.gps_waiting); - if (state.data.gps.locked) + if (state.gps.locked) info_add_row(1, "GPS", " locked"); - else if (state.data.gps.connected) + else if (state.gps.connected) info_add_row(1, "GPS", " unlocked"); else info_add_row(1, "GPS", " missing"); - info_add_row(1, "Satellites", "%6d", state.data.gps.nsat); + info_add_row(1, "Satellites", "%6d", state.gps.nsat); info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); info_add_row(1, "GPS altitude", "%6d", state.gps.alt); diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index 140f3f07..b79f5c9e 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -24,8 +24,8 @@ public class AltosKML implements AltosWriter { File name; PrintStream out; - int state = -1; - AltosRecord prev = null; + int flight_state = -1; + AltosState prev = null; double gps_start_altitude; static final String[] kml_state_colors = { @@ -83,7 +83,7 @@ public class AltosKML implements AltosWriter { "\n" + "\n"; - void start (AltosRecord record) { + 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); @@ -94,30 +94,30 @@ public class AltosKML implements AltosWriter { boolean started = false; - void state_start(AltosRecord record) { - String state_name = Altos.state_name(record.state); - out.printf(kml_style_start, state_name, kml_state_colors[record.state]); + void state_start(AltosState state) { + String state_name = Altos.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(AltosRecord record) { + void state_end(AltosState state) { out.printf("%s", kml_placemark_end); } - void coord(AltosRecord record) { - AltosGPS gps = record.gps; + void coord(AltosState state) { + AltosGPS gps = state.gps; double altitude; - if (record.height() != AltosRecord.MISSING) - altitude = record.height() + gps_start_altitude; + if (state.height != AltosRecord.MISSING) + altitude = state.height + gps_start_altitude; else altitude = gps.alt; out.printf(kml_coord_fmt, gps.lon, gps.lat, altitude, (double) gps.alt, - record.time, gps.nsat); + state.time, gps.nsat); } void end() { @@ -132,38 +132,40 @@ public class AltosKML implements AltosWriter { } } - public void write(AltosRecord record) { - AltosGPS gps = record.gps; + public void write(AltosState state) { + AltosGPS gps = state.gps; if (gps == null) return; - if ((record.seen & (AltosRecord.seen_gps_lat)) == 0) + if (gps.lat == AltosRecord.MISSING) return; - if ((record.seen & (AltosRecord.seen_gps_lon)) == 0) + if (gps.lon == AltosRecord.MISSING) return; if (!started) { - start(record); + start(state); started = true; gps_start_altitude = gps.alt; } - if (prev != null && prev.gps_sequence == record.gps_sequence) + if (prev != null && prev.gps_sequence == state.gps_sequence) return; - if (record.state != state) { - state = record.state; + if (state.state != flight_state) { + flight_state = state.state; if (prev != null) { - coord(record); + coord(state); state_end(prev); } - state_start(record); + state_start(state); } - coord(record); - prev = record; + coord(state); + prev = state; } - public void write(AltosRecordIterable iterable) { - for (AltosRecord record : iterable) - write(record); + 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 { diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 9dab52c4..38f273cf 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -243,24 +243,18 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio if (file != null) { String filename = file.getName(); try { - AltosRecordIterable records = null; + AltosStateIterable states = null; if (filename.endsWith("eeprom")) { FileInputStream in = new FileInputStream(file); - records = new AltosEepromIterable(in); + states = new AltosEepromFile(in); } else if (filename.endsWith("telem")) { FileInputStream in = new FileInputStream(file); - records = new AltosTelemetryIterable(in); - } else if (filename.endsWith("mega")) { - FileInputStream in = new FileInputStream(file); - records = new AltosEepromMegaIterable(in); - } else if (filename.endsWith("mini")) { - FileInputStream in = new FileInputStream(file); - records = new AltosEepromMiniIterable(in); + states = null; // new AltosTelemetryIterable(in); } else { throw new FileNotFoundException(filename); } try { - new AltosGraphUI(records, file); + new AltosGraphUI(states, file); } catch (InterruptedException ie) { } catch (IOException ie) { } diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index e2316a13..fed009cc 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -176,11 +176,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Battery extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.battery == AltosRecord.MISSING) + if (state == null || state.battery_voltage == AltosRecord.MISSING) hide(); else { - show("%4.2f V", state.battery); - lights.set(state.battery > 3.7); + show("%4.2f V", state.battery_voltage); + lights.set(state.battery_voltage > 3.7); } } public Battery (GridBagLayout layout, int y) { @@ -192,11 +192,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Apogee extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.drogue_sense == AltosRecord.MISSING) + if (state == null || state.apogee_voltage == AltosRecord.MISSING) hide(); else { - show("%4.2f V", state.drogue_sense); - lights.set(state.drogue_sense > 3.2); + show("%4.2f V", state.apogee_voltage); + lights.set(state.apogee_voltage > 3.7); } } public Apogee (GridBagLayout layout, int y) { @@ -208,11 +208,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Main extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.main_sense == AltosRecord.MISSING) + if (state == null || state.main_voltage == AltosRecord.MISSING) hide(); else { - show("%4.2f V", state.main_sense); - lights.set(state.main_sense > 3.2); + show("%4.2f V", state.main_voltage); + lights.set(state.main_voltage > 3.7); } } public Main (GridBagLayout layout, int y) { @@ -224,19 +224,19 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class LoggingReady extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.data.flight == AltosRecord.MISSING) { + if (state == null || state.flight == AltosRecord.MISSING) { hide(); } else { - if (state.data.flight != 0) { - if (state.data.state <= Altos.ao_flight_pad) + if (state.flight != 0) { + if (state.state <= Altos.ao_flight_pad) show("Ready to record"); - else if (state.data.state < Altos.ao_flight_landed) + else if (state.state < Altos.ao_flight_landed) show("Recording data"); else show("Recorded data"); } else show("Storage full"); - lights.set(state.data.flight != 0); + lights.set(state.flight != 0); } } public LoggingReady (GridBagLayout layout, int y) { diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 0c903873..224e1e61 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -184,13 +184,13 @@ public class AltosScanUI try { for (;;) { try { - AltosRecord record = reader.read(); - if (record == null) + AltosState state = reader.read(); + if (state == null) continue; - if ((record.seen & AltosRecord.seen_flight) != 0) { - final AltosScanResult result = new AltosScanResult(record.callsign, - record.serial, - record.flight, + if (state.flight != AltosRecord.MISSING) { + final AltosScanResult result = new AltosScanResult(state.callsign, + state.serial, + state.flight, frequencies[frequency_index], telemetry); Runnable r = new Runnable() { diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java index 23085f3e..c0926919 100644 --- a/altosui/AltosSiteMap.java +++ b/altosui/AltosSiteMap.java @@ -271,27 +271,34 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { int last_state = -1; public void show(double lat, double lon) { - initMaps(lat, lon); - scrollRocketToVisible(pt(lat, lon)); + System.out.printf ("show %g %g\n", lat, lon); + return; +// initMaps(lat, lon); +// scrollRocketToVisible(pt(lat, lon)); } public void show(final AltosState state, final AltosListenerState listener_state) { // if insufficient gps data, nothing to update - if (!state.gps.locked && state.gps.nsat < 4) + AltosGPS gps = state.gps; + + if (gps == null) + return; + + if (!gps.locked && gps.nsat < 4) return; if (!initialised) { - if (state.pad_lat != 0 || state.pad_lon != 0) { + if (state.pad_lat != AltosRecord.MISSING && state.pad_lon != AltosRecord.MISSING) { initMaps(state.pad_lat, state.pad_lon); initialised = true; - } else if (state.gps.lat != 0 || state.gps.lon != 0) { - initMaps(state.gps.lat, state.gps.lon); + } else if (gps.lat != AltosRecord.MISSING && gps.lon != AltosRecord.MISSING) { + initMaps(gps.lat, gps.lon); initialised = true; } else { return; } } - final Point2D.Double pt = pt(state.gps.lat, state.gps.lon); + final Point2D.Double pt = pt(gps.lat, gps.lon); if (last_pt == pt && last_state == state.state) return; diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 4362e36c..6d5ce185 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -290,9 +290,9 @@ public class AltosUI extends AltosUIFrame { AltosDataChooser chooser = new AltosDataChooser( AltosUI.this); - AltosRecordIterable iterable = chooser.runDialog(); - if (iterable != null) { - AltosFlightReader reader = new AltosReplayReader(iterable.iterator(), + Iterable states = chooser.runDialog(); + if (states != null) { + AltosFlightReader reader = new AltosReplayReader(states.iterator(), chooser.file()); new AltosFlightUI(voice, reader); } @@ -312,10 +312,10 @@ public class AltosUI extends AltosUIFrame { private void ExportData() { AltosDataChooser chooser; chooser = new AltosDataChooser(this); - AltosRecordIterable record_reader = chooser.runDialog(); - if (record_reader == null) + AltosStateIterable states = chooser.runDialog(); + if (states == null) return; - new AltosCSVUI(AltosUI.this, record_reader, chooser.file()); + new AltosCSVUI(AltosUI.this, states, chooser.file()); } /* Load a flight log CSV file and display a pretty graph. @@ -324,11 +324,11 @@ public class AltosUI extends AltosUIFrame { private void GraphData() { AltosDataChooser chooser; chooser = new AltosDataChooser(this); - AltosRecordIterable record_reader = chooser.runDialog(); - if (record_reader == null) + AltosStateIterable states = chooser.runDialog(); + if (states == null) return; try { - new AltosGraphUI(record_reader, chooser.file()); + new AltosGraphUI(states, chooser.file()); } catch (InterruptedException ie) { } catch (IOException ie) { } @@ -345,19 +345,15 @@ public class AltosUI extends AltosUIFrame { } } - static AltosRecordIterable open_logfile(File file) { + static AltosStateIterable open_logfile(File file) { try { FileInputStream in; in = new FileInputStream(file); if (file.getName().endsWith("eeprom")) - return new AltosEepromIterable(in); - else if (file.getName().endsWith("mega")) - return new AltosEepromMegaIterable(in); - else if (file.getName().endsWith("mini")) - return new AltosEepromMiniIterable(in); + return new AltosEepromFile(in); else - return new AltosTelemetryIterable(in); + return null; // new AltosTelemetryIterable(in); } catch (FileNotFoundException fe) { System.out.printf("%s\n", fe.getMessage()); return null; @@ -388,10 +384,11 @@ public class AltosUI extends AltosUIFrame { static final int process_graph = 3; static final int process_replay = 4; static final int process_summary = 5; + static final int process_cat = 6; static boolean process_csv(File input) { - AltosRecordIterable iterable = open_logfile(input); - if (iterable == null) + AltosStateIterable states = open_logfile(input); + if (states == null) return false; File output = Altos.replace_extension(input,".csv"); @@ -403,15 +400,15 @@ public class AltosUI extends AltosUIFrame { AltosWriter writer = open_csv(output); if (writer == null) return false; - writer.write(iterable); + writer.write(states); writer.close(); } return true; } static boolean process_kml(File input) { - AltosRecordIterable iterable = open_logfile(input); - if (iterable == null) + AltosStateIterable states = open_logfile(input); + if (states == null) return false; File output = Altos.replace_extension(input,".kml"); @@ -423,13 +420,13 @@ public class AltosUI extends AltosUIFrame { AltosWriter writer = open_kml(output); if (writer == null) return false; - writer.write(iterable); + writer.write(states); writer.close(); return true; } } - static AltosRecordIterable record_iterable(File file) { + static AltosStateIterable record_iterable(File file) { FileInputStream in; try { in = new FileInputStream(file); @@ -437,25 +434,18 @@ public class AltosUI extends AltosUIFrame { System.out.printf("Failed to open file '%s'\n", file); return null; } - AltosRecordIterable recs; - //AltosReplayReader reader; if (file.getName().endsWith("eeprom")) { - recs = new AltosEepromIterable(in); - } else if (file.getName().endsWith("mega")) { - recs = new AltosEepromMegaIterable(in); - } else if (file.getName().endsWith("mini")) { - recs = new AltosEepromMiniIterable(in); + return new AltosEepromFile(in); } else { - recs = new AltosTelemetryIterable(in); + return null; // new AltosTelemetryIterable(in); } - return recs; } static AltosReplayReader replay_file(File file) { - AltosRecordIterable recs = record_iterable(file); - if (recs == null) + AltosStateIterable states = record_iterable(file); + if (states == null) return null; - return new AltosReplayReader(recs.iterator(), file); + return new AltosReplayReader(states.iterator(), file); } static boolean process_replay(File file) { @@ -468,11 +458,11 @@ public class AltosUI extends AltosUIFrame { } static boolean process_graph(File file) { - AltosRecordIterable recs = record_iterable(file); - if (recs == null) + AltosStateIterable states = record_iterable(file); + if (states == null) return false; try { - new AltosGraphUI(recs, file); + new AltosGraphUI(states, file); return true; } catch (InterruptedException ie) { } catch (IOException ie) { @@ -481,11 +471,11 @@ public class AltosUI extends AltosUIFrame { } static boolean process_summary(File file) { - AltosRecordIterable iterable = record_iterable(file); - if (iterable == null) + AltosStateIterable states = record_iterable(file); + if (states == null) return false; try { - AltosFlightStats stats = new AltosFlightStats(iterable); + AltosFlightStats stats = new AltosFlightStats(states); if (stats.serial > 0) System.out.printf("Serial: %5d\n", stats.serial); if (stats.flight > 0) @@ -510,11 +500,11 @@ public class AltosUI extends AltosUIFrame { AltosConvert.meters_to_g(stats.max_acceleration)); } System.out.printf("Drogue rate: %6.0f m/s %6.0f ft/s\n", - stats.state_baro_speed[Altos.ao_flight_drogue], - AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_drogue])); + stats.state_speed[Altos.ao_flight_drogue], + AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue])); System.out.printf("Main rate: %6.0f m/s %6.0f ft/s\n", - stats.state_baro_speed[Altos.ao_flight_main], - AltosConvert.meters_to_feet(stats.state_baro_speed[Altos.ao_flight_main])); + stats.state_speed[Altos.ao_flight_main], + AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main])); System.out.printf("Flight time: %6.0f s\n", stats.state_end[Altos.ao_flight_main] - stats.state_start[Altos.ao_flight_boost]); @@ -525,6 +515,27 @@ public class AltosUI extends AltosUIFrame { return false; } + static boolean process_cat(File file) { + try { + FileInputStream input = new FileInputStream(file); + AltosEepromFile eef = new AltosEepromFile(input); + + for (AltosState state : eef) { + if ((state.set & AltosState.set_gps) != 0) + System.out.printf ("time %g lat %g lon %g alt %g\n", + state.time_since_boost(), + state.gps.lat, + state.gps.lon, + state.gps.alt); + } + + } catch (Exception e) { + System.out.printf("Failed to open file '%s'\n", file); + return false; + } + return true; + } + public static void help(int code) { System.out.printf("Usage: altosui [OPTION]... [FILE]...\n"); System.out.printf(" Options:\n"); @@ -574,6 +585,8 @@ public class AltosUI extends AltosUIFrame { process = process_graph; else if (args[i].equals("--summary")) process = process_summary; + else if (args[i].equals("--cat")) + process = process_cat; else if (args[i].startsWith("--")) help(1); else { @@ -600,6 +613,9 @@ public class AltosUI extends AltosUIFrame { if (!process_summary(file)) ++errors; break; + case process_cat: + if (!process_cat(file)) + ++errors; } } } diff --git a/altosui/AltosWriter.java b/altosui/AltosWriter.java index 2f70b472..8de11bc9 100644 --- a/altosui/AltosWriter.java +++ b/altosui/AltosWriter.java @@ -22,9 +22,9 @@ import org.altusmetrum.altoslib_1.*; public interface AltosWriter { - public void write(AltosRecord record); + public void write(AltosState state); - public void write(AltosRecordIterable iterable); + public void write(AltosStateIterable states); public void close(); } -- cgit v1.2.3 From f07f6d55edf5b97020680b3ce1d9e00bb3df64a6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 31 Aug 2013 01:48:02 -0500 Subject: altoslib/altosui: Get legacy telem working with new AltosState structure Make AltosTelemetry work without AltosRecord Signed-off-by: Keith Packard --- altoslib/AltosEepromFile.java | 21 +- altoslib/AltosFile.java | 15 +- altoslib/AltosGPS.java | 40 +-- altoslib/AltosLog.java | 23 +- altoslib/AltosState.java | 20 +- altoslib/AltosTelemetry.java | 337 ++++++++------------- altoslib/AltosTelemetryFile.java | 94 ++++++ altoslib/AltosTelemetryIterable.java | 71 +---- altoslib/AltosTelemetryLegacy.java | 556 +++++++++++++++++++++++++++++++++++ altoslib/AltosTelemetryReader.java | 9 +- altoslib/Makefile.am | 14 +- altosui/AltosUI.java | 6 +- 12 files changed, 866 insertions(+), 340 deletions(-) create mode 100644 altoslib/AltosTelemetryFile.java create mode 100644 altoslib/AltosTelemetryLegacy.java (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index bcc7171e..2f4c54d7 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -57,6 +57,7 @@ public class AltosEepromFile extends AltosStateIterable { AltosEepromIterable headers; AltosEepromIterable body; + AltosState start; public void write_comments(PrintStream out) { headers.write(out); @@ -70,9 +71,9 @@ public class AltosEepromFile extends AltosStateIterable { public AltosEepromFile(FileInputStream input) { headers = new AltosEepromIterable(AltosEepromHeader.read(input)); - AltosState state = headers.state(); + start = headers.state(); - switch (state.log_format) { + switch (start.log_format) { case AltosLib.AO_LOG_FORMAT_FULL: body = new AltosEepromIterable(AltosEepromTM.read(input)); break; @@ -86,26 +87,24 @@ public class AltosEepromFile extends AltosStateIterable { body = new AltosEepromIterable(AltosEepromMini.read(input)); break; } - } - int boost_tick (AltosState start) { + /* Find boost tick */ AltosState state = start.clone(); for (AltosEeprom eeprom : body) { eeprom.update_state(state); - if (state.state >= AltosLib.ao_flight_boost) - return state.tick; + if (state.state >= AltosLib.ao_flight_boost) { + start.set_boost_tick(state.tick); + break; + } } - return 0; } public Iterator iterator() { - - AltosState state = headers.state(); - Iterator i = body.iterator(); + AltosState state = start.clone(); + Iterator i = body.iterator(); while (i.hasNext() && !state.valid()) i.next().update_state(state); - state.set_boost_tick(boost_tick(state)); return new AltosEepromIterator(state, i); } } \ No newline at end of file diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index 90dbc6db..54c54824 100644 --- a/altoslib/AltosFile.java +++ b/altoslib/AltosFile.java @@ -22,10 +22,17 @@ import java.util.*; public class AltosFile extends File { + static String number(int n) { + if (n == AltosRecord.MISSING) + return "unk"; + else + return String.format("%03d", n); + } + public AltosFile(int year, int month, int day, int serial, int flight, String extension) { super (AltosPreferences.logdir(), - String.format("%04d-%02d-%02d-serial-%03d-flight-%03d.%s", - year, month, day, serial, flight, extension)); + String.format("%04d-%02d-%02d-serial-%s-flight-%s.%s", + year, month, day, number(serial), number(flight), extension)); } public AltosFile(int serial, int flight, String extension) { @@ -37,7 +44,7 @@ public class AltosFile extends File { extension); } - public AltosFile(AltosRecord telem) { - this(telem.serial, telem.flight, "telem"); + public AltosFile(AltosState state) { + this(state.serial, state.flight, "telem"); } } diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index eb384e4d..399e95b1 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -70,35 +70,35 @@ public class AltosGPS implements Cloneable { } public AltosGPS(AltosTelemetryMap map) throws ParseException { - String state = map.get_string(AltosTelemetry.AO_TELEM_GPS_STATE, - AltosTelemetry.AO_TELEM_GPS_STATE_ERROR); + String state = map.get_string(AltosTelemetryLegacy.AO_TELEM_GPS_STATE, + AltosTelemetryLegacy.AO_TELEM_GPS_STATE_ERROR); - nsat = map.get_int(AltosTelemetry.AO_TELEM_GPS_NUM_SAT, 0); - if (state.equals(AltosTelemetry.AO_TELEM_GPS_STATE_LOCKED)) { + nsat = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_NUM_SAT, 0); + if (state.equals(AltosTelemetryLegacy.AO_TELEM_GPS_STATE_LOCKED)) { connected = true; locked = true; - lat = map.get_double(AltosTelemetry.AO_TELEM_GPS_LATITUDE, MISSING, 1.0e-7); - lon = map.get_double(AltosTelemetry.AO_TELEM_GPS_LONGITUDE, MISSING, 1.0e-7); - alt = map.get_int(AltosTelemetry.AO_TELEM_GPS_ALTITUDE, MISSING); - year = map.get_int(AltosTelemetry.AO_TELEM_GPS_YEAR, MISSING); + lat = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_LATITUDE, MISSING, 1.0e-7); + lon = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_LONGITUDE, MISSING, 1.0e-7); + alt = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_ALTITUDE, MISSING); + year = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_YEAR, MISSING); if (year != MISSING) year += 2000; - month = map.get_int(AltosTelemetry.AO_TELEM_GPS_MONTH, MISSING); - day = map.get_int(AltosTelemetry.AO_TELEM_GPS_DAY, MISSING); + month = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_MONTH, MISSING); + day = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_DAY, MISSING); - hour = map.get_int(AltosTelemetry.AO_TELEM_GPS_HOUR, 0); - minute = map.get_int(AltosTelemetry.AO_TELEM_GPS_MINUTE, 0); - second = map.get_int(AltosTelemetry.AO_TELEM_GPS_SECOND, 0); + hour = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HOUR, 0); + minute = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_MINUTE, 0); + second = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_SECOND, 0); - ground_speed = map.get_double(AltosTelemetry.AO_TELEM_GPS_HORIZONTAL_SPEED, + ground_speed = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HORIZONTAL_SPEED, AltosRecord.MISSING, 1/100.0); - course = map.get_int(AltosTelemetry.AO_TELEM_GPS_COURSE, + course = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_COURSE, AltosRecord.MISSING); - hdop = map.get_double(AltosTelemetry.AO_TELEM_GPS_HDOP, MISSING, 1.0); - vdop = map.get_double(AltosTelemetry.AO_TELEM_GPS_VDOP, MISSING, 1.0); - h_error = map.get_int(AltosTelemetry.AO_TELEM_GPS_HERROR, MISSING); - v_error = map.get_int(AltosTelemetry.AO_TELEM_GPS_VERROR, MISSING); - } else if (state.equals(AltosTelemetry.AO_TELEM_GPS_STATE_UNLOCKED)) { + hdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HDOP, MISSING, 1.0); + vdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_VDOP, MISSING, 1.0); + h_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HERROR, MISSING); + v_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_VERROR, MISSING); + } else if (state.equals(AltosTelemetryLegacy.AO_TELEM_GPS_STATE_UNLOCKED)) { connected = true; locked = false; } else { diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index 974c9f0f..7f69bb65 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -57,8 +57,8 @@ public class AltosLog implements Runnable { return file; } - boolean open (AltosRecord telem) throws IOException { - AltosFile a = new AltosFile(telem); + boolean open (AltosState state) throws IOException { + AltosFile a = new AltosFile(state); log_file = new FileWriter(a, true); if (log_file != null) { @@ -78,22 +78,25 @@ public class AltosLog implements Runnable { public void run () { try { - AltosRecord previous = null; + AltosState state = null; for (;;) { AltosLine line = input_queue.take(); if (line.line == null) continue; try { - AltosRecord telem = AltosTelemetry.parse(line.line, previous); - if ((telem.seen & AltosRecord.seen_flight) != 0 && - (telem.serial != serial || telem.flight != flight || log_file == null)) + AltosTelemetry telem = new AltosTelemetryLegacy(line.line); + if (state != null) + state = state.clone(); + else + state = new AltosState(); + telem.update_state(state); + if (state.serial != serial || state.flight != flight || log_file == null) { close_log_file(); - serial = telem.serial; - flight = telem.flight; - open(telem); + serial = state.serial; + flight = state.flight; + open(state); } - previous = telem; } catch (ParseException pe) { } catch (AltosCRCException ce) { } diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index daf06c19..52650062 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -104,6 +104,7 @@ public class AltosState implements Cloneable { public double accel_minus_g; public double accel; public double ground_accel; + public double ground_accel_avg; public int log_format; @@ -201,6 +202,7 @@ public class AltosState implements Cloneable { accel_minus_g = AltosRecord.MISSING; accel = AltosRecord.MISSING; ground_accel = AltosRecord.MISSING; + ground_accel_avg = AltosRecord.MISSING; log_format = AltosRecord.MISSING; serial = AltosRecord.MISSING; @@ -306,6 +308,7 @@ public class AltosState implements Cloneable { accel_minus_g = old.accel_minus_g; accel = old.accel; ground_accel = old.ground_accel; + ground_accel_avg = old.ground_accel_avg; log_format = old.log_format; serial = old.serial; @@ -396,9 +399,13 @@ public class AltosState implements Cloneable { } void update_accel() { + double ground = ground_accel; + + if (ground == AltosRecord.MISSING) + ground = ground_accel_avg; if (accel == AltosRecord.MISSING) return; - if (ground_accel == AltosRecord.MISSING) + if (ground == AltosRecord.MISSING) return; if (accel_plus_g == AltosRecord.MISSING) return; @@ -408,7 +415,7 @@ public class AltosState implements Cloneable { double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; double counts_per_mss = counts_per_g / 9.80665; - acceleration = (ground_accel - accel) / counts_per_mss; + acceleration = (ground - accel) / counts_per_mss; /* Only look at accelerometer data under boost */ if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) @@ -556,9 +563,6 @@ public class AltosState implements Cloneable { public void set_gps(AltosGPS gps, int sequence) { if (gps != null) { - System.out.printf ("gps date: %d-%d-%d time %d:%d:%d\n", - gps.year, gps.month, gps.day, - gps.hour, gps.minute, gps.second); this.gps = gps.clone(); gps_sequence = sequence; update_gps(); @@ -623,6 +627,12 @@ public class AltosState implements Cloneable { public void set_accel(double accel) { if (accel != AltosRecord.MISSING) { this.accel = accel; + if (state == AltosLib.ao_flight_pad) { + if (ground_accel_avg == AltosRecord.MISSING) + ground_accel_avg = accel; + else + ground_accel_avg = (ground_accel_avg * 7 + accel) / 8; + } } update_accel(); } diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index e7322349..b84455d3 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -23,217 +23,136 @@ import java.text.*; * Telemetry data contents */ +public abstract class AltosTelemetry implements AltosStateUpdate { + + /* All telemetry packets have these fields */ + public int tick; + public int serial; + public int rssi; + public int status; + + /* Mark when we received the packet */ + long received_time; + + static boolean cksum(int[] bytes) { + int sum = 0x5a; + for (int i = 1; i < bytes.length - 1; i++) + sum += bytes[i]; + sum &= 0xff; + return sum == bytes[bytes.length - 1]; + } + + public void update_state(AltosState state) { + } + final static int PKT_APPEND_STATUS_1_CRC_OK = (1 << 7); + final static int PKT_APPEND_STATUS_1_LQI_MASK = (0x7f); + final static int PKT_APPEND_STATUS_1_LQI_SHIFT = 0; + + final static int packet_type_TM_sensor = 0x01; + final static int packet_type_Tm_sensor = 0x02; + final static int packet_type_Tn_sensor = 0x03; + final static int packet_type_configuration = 0x04; + final static int packet_type_location = 0x05; + final static int packet_type_satellite = 0x06; + final static int packet_type_companion = 0x07; + final static int packet_type_MM_sensor = 0x08; + final static int packet_type_MM_data = 0x09; + final static int packet_type_Mini = 0x10; + + static AltosTelemetry parse_hex(String hex) throws ParseException, AltosCRCException { + AltosTelemetry telem = null; + + int[] bytes; + try { + bytes = AltosLib.hexbytes(hex); + } catch (NumberFormatException ne) { + throw new ParseException(ne.getMessage(), 0); + } + + /* one for length, one for checksum */ + if (bytes[0] != bytes.length - 2) + throw new ParseException(String.format("invalid length %d != %d\n", + bytes[0], + bytes.length - 2), 0); + if (!cksum(bytes)) + throw new ParseException(String.format("invalid line \"%s\"", hex), 0); + + int rssi = AltosLib.int8(bytes, bytes.length - 3) / 2 - 74; + int status = AltosLib.uint8(bytes, bytes.length - 2); + + if ((status & PKT_APPEND_STATUS_1_CRC_OK) == 0) + throw new AltosCRCException(rssi); + + /* length, data ..., rssi, status, checksum -- 4 bytes extra */ + switch (bytes.length) { + case AltosLib.ao_telemetry_standard_len + 4: + int type = AltosLib.uint8(bytes, 4 + 1); /* - * The packet format is a simple hex dump of the raw telemetry frame. - * It starts with 'TELEM', then contains hex digits with a checksum as the last - * byte on the line. - * - * Version 4 is a replacement with consistent syntax. Each telemetry line - * contains a sequence of space-separated names and values, the values are - * either integers or strings. The names are all unique. All values are - * optional - * - * VERSION 4 c KD7SQG n 236 f 18 r -25 s pad t 513 r_a 15756 r_b 26444 r_t 20944 - * r_v 26640 r_d 512 r_m 208 c_a 15775 c_b 26439 c_p 15749 c_m 16281 a_a 15764 - * a_s 0 a_b 26439 g_s u g_n 0 s_n 0 - * - * VERSION 4 c KD7SQG n 19 f 0 r -23 s pad t 513 r_b 26372 r_t 21292 r_v 26788 - * r_d 136 r_m 140 c_b 26370 k_h 0 k_s 0 k_a 0 - * - * General header fields - * - * Name Value - * - * VERSION Telemetry version number (4 or more). Must be first. - * c Callsign (string, no spaces allowed) - * n Flight unit serial number (integer) - * f Flight number (integer) - * r Packet RSSI value (integer) - * s Flight computer state (string, no spaces allowed) - * t Flight computer clock (integer in centiseconds) - * - * Version 3 is Version 2 with fixed RSSI numbers -- the radio reports - * in 1/2dB increments while this protocol provides only integers. So, - * the syntax didn't change just the interpretation of the RSSI - * values. - * - * Version 2 of the telemetry data stream is a bit of a mess, with no - * consistent formatting. In particular, the GPS data is formatted for - * viewing instead of parsing. However, the key feature is that every - * telemetry line contains all of the information necessary to - * describe the current rocket state, including the calibration values - * for accelerometer and barometer. - * - * GPS unlocked: - * - * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -68 STATUS ff STATE pad 1001 \ - * a: 16032 p: 21232 t: 20284 v: 25160 d: 204 m: 204 fa: 16038 ga: 16032 fv: 0 \ - * fp: 21232 gp: 21230 a+: 16049 a-: 16304 GPS 0 sat unlocked SAT 1 15 30 - * - * GPS locked: - * - * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -71 STATUS ff STATE pad 2504 \ - * a: 16028 p: 21220 t: 20360 v: 25004 d: 208 m: 200 fa: 16031 ga: 16032 fv: 330 \ - * fp: 21231 gp: 21230 a+: 16049 a-: 16304 \ - * GPS 9 sat 2010-02-13 17:16:51 35°20.0803'N 106°45.2235'W 1790m \ - * 0.00m/s(H) 0° 0.00m/s(V) 1.0(hdop) 0(herr) 0(verr) \ - * SAT 10 29 30 24 28 5 25 21 20 15 33 1 23 30 24 18 26 10 29 2 26 - * - */ + switch (type) { + case packet_type_TM_sensor: + case packet_type_Tm_sensor: + case packet_type_Tn_sensor: + telem = new AltosTelemetrySensor(bytes); + break; + case packet_type_configuration: + telem = new AltosTelemetryConfiguration(bytes); + break; + case packet_type_location: + telem = new AltosTelemetryLocation(bytes); + break; + case packet_type_satellite: + telem = new AltosTelemetrySatellite(bytes); + break; + case packet_type_companion: + telem = new AltosTelemetryCompanion(bytes); + break; + case packet_type_MM_sensor: + telem = new AltosTelemetryMegaSensor(bytes); + break; + case packet_type_MM_data: + telem = new AltosTelemetryMegaData(bytes); + break; + default: + telem = new AltosTelemetryRaw(bytes); + break; + } +*/ + break; + case AltosLib.ao_telemetry_0_9_len + 4: + telem = new AltosTelemetryLegacy(bytes); + break; + case AltosLib.ao_telemetry_0_8_len + 4: + telem = new AltosTelemetryLegacy(bytes); + break; + default: + throw new ParseException(String.format("Invalid packet length %d", bytes.length), 0); + } + if (telem != null) { + telem.received_time = System.currentTimeMillis(); + telem.rssi = rssi; + telem.status = status; + } + return telem; + } + + public static AltosTelemetry parse(String line) throws ParseException, AltosCRCException { + String[] word = line.split("\\s+"); + int i =0; + + if (word[i].equals("CRC") && word[i+1].equals("INVALID")) { + i += 2; + AltosParse.word(word[i++], "RSSI"); + throw new AltosCRCException(AltosParse.parse_int(word[i++])); + } + + AltosTelemetry telem; -public abstract class AltosTelemetry extends AltosRecord { - - /* - * General header fields - * - * Name Value - * - * VERSION Telemetry version number (4 or more). Must be first. - * c Callsign (string, no spaces allowed) - * n Flight unit serial number (integer) - * f Flight number (integer) - * r Packet RSSI value (integer) - * s Flight computer state (string, no spaces allowed) - * t Flight computer clock (integer in centiseconds) - */ - - final static String AO_TELEM_VERSION = "VERSION"; - final static String AO_TELEM_CALL = "c"; - final static String AO_TELEM_SERIAL = "n"; - final static String AO_TELEM_FLIGHT = "f"; - final static String AO_TELEM_RSSI = "r"; - final static String AO_TELEM_STATE = "s"; - final static String AO_TELEM_TICK = "t"; - - /* - * Raw sensor values - * - * Name Value - * r_a Accelerometer reading (integer) - * r_b Barometer reading (integer) - * r_t Thermometer reading (integer) - * r_v Battery reading (integer) - * r_d Drogue continuity (integer) - * r_m Main continuity (integer) - */ - - final static String AO_TELEM_RAW_ACCEL = "r_a"; - final static String AO_TELEM_RAW_BARO = "r_b"; - final static String AO_TELEM_RAW_THERMO = "r_t"; - final static String AO_TELEM_RAW_BATT = "r_v"; - final static String AO_TELEM_RAW_DROGUE = "r_d"; - final static String AO_TELEM_RAW_MAIN = "r_m"; - - /* - * Sensor calibration values - * - * Name Value - * c_a Ground accelerometer reading (integer) - * c_b Ground barometer reading (integer) - * c_p Accelerometer reading for +1g - * c_m Accelerometer reading for -1g - */ - - final static String AO_TELEM_CAL_ACCEL_GROUND = "c_a"; - final static String AO_TELEM_CAL_BARO_GROUND = "c_b"; - final static String AO_TELEM_CAL_ACCEL_PLUS = "c_p"; - final static String AO_TELEM_CAL_ACCEL_MINUS = "c_m"; - - /* - * Kalman state values - * - * Name Value - * k_h Height above pad (integer, meters) - * k_s Vertical speeed (integer, m/s * 16) - * k_a Vertical acceleration (integer, m/s² * 16) - */ - - final static String AO_TELEM_KALMAN_HEIGHT = "k_h"; - final static String AO_TELEM_KALMAN_SPEED = "k_s"; - final static String AO_TELEM_KALMAN_ACCEL = "k_a"; - - /* - * Ad-hoc flight values - * - * Name Value - * a_a Acceleration (integer, sensor units) - * a_s Speed (integer, integrated acceleration value) - * a_b Barometer reading (integer, sensor units) - */ - - final static String AO_TELEM_ADHOC_ACCEL = "a_a"; - final static String AO_TELEM_ADHOC_SPEED = "a_s"; - final static String AO_TELEM_ADHOC_BARO = "a_b"; - - /* - * GPS values - * - * Name Value - * g_s GPS state (string): - * l locked - * u unlocked - * e error (missing or broken) - * g_n Number of sats used in solution - * g_ns Latitude (degrees * 10e7) - * g_ew Longitude (degrees * 10e7) - * g_a Altitude (integer meters) - * g_Y GPS year (integer) - * g_M GPS month (integer - 1-12) - * g_D GPS day (integer - 1-31) - * g_h GPS hour (integer - 0-23) - * g_m GPS minute (integer - 0-59) - * g_s GPS second (integer - 0-59) - * g_v GPS vertical speed (integer, cm/sec) - * g_s GPS horizontal speed (integer, cm/sec) - * g_c GPS course (integer, 0-359) - * g_hd GPS hdop (integer * 10) - * g_vd GPS vdop (integer * 10) - * g_he GPS h error (integer) - * g_ve GPS v error (integer) - */ - - final static String AO_TELEM_GPS_STATE = "g"; - final static String AO_TELEM_GPS_STATE_LOCKED = "l"; - final static String AO_TELEM_GPS_STATE_UNLOCKED = "u"; - final static String AO_TELEM_GPS_STATE_ERROR = "e"; - final static String AO_TELEM_GPS_NUM_SAT = "g_n"; - final static String AO_TELEM_GPS_LATITUDE = "g_ns"; - final static String AO_TELEM_GPS_LONGITUDE = "g_ew"; - final static String AO_TELEM_GPS_ALTITUDE = "g_a"; - final static String AO_TELEM_GPS_YEAR = "g_Y"; - final static String AO_TELEM_GPS_MONTH = "g_M"; - final static String AO_TELEM_GPS_DAY = "g_D"; - final static String AO_TELEM_GPS_HOUR = "g_h"; - final static String AO_TELEM_GPS_MINUTE = "g_m"; - final static String AO_TELEM_GPS_SECOND = "g_s"; - final static String AO_TELEM_GPS_VERTICAL_SPEED = "g_v"; - final static String AO_TELEM_GPS_HORIZONTAL_SPEED = "g_g"; - final static String AO_TELEM_GPS_COURSE = "g_c"; - final static String AO_TELEM_GPS_HDOP = "g_hd"; - final static String AO_TELEM_GPS_VDOP = "g_vd"; - final static String AO_TELEM_GPS_HERROR = "g_he"; - final static String AO_TELEM_GPS_VERROR = "g_ve"; - - /* - * GPS satellite values - * - * Name Value - * s_n Number of satellites reported (integer) - * s_v0 Space vehicle ID (integer) for report 0 - * s_c0 C/N0 number (integer) for report 0 - * s_v1 Space vehicle ID (integer) for report 1 - * s_c1 C/N0 number (integer) for report 1 - * ... - */ - - final static String AO_TELEM_SAT_NUM = "s_n"; - final static String AO_TELEM_SAT_SVID = "s_v"; - final static String AO_TELEM_SAT_C_N_0 = "s_c"; - - static public AltosRecord parse(String line, AltosRecord previous) throws ParseException, AltosCRCException { - AltosTelemetryRecord r = AltosTelemetryRecord.parse(line); - - return r.update_state(previous); + if (word[i].equals("TELEM")) { + telem = parse_hex(word[i+1]); + } else { + telem = new AltosTelemetryLegacy(line); + } + return telem; } } diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java new file mode 100644 index 00000000..9e992576 --- /dev/null +++ b/altoslib/AltosTelemetryFile.java @@ -0,0 +1,94 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +class AltosTelemetryIterator implements Iterator { + AltosState state; + Iterator telems; + AltosTelemetry next; + boolean seen; + + public boolean hasNext() { + return !seen || telems.hasNext(); + } + + public AltosState next() { + if (seen) { + AltosState n = state.clone(); + AltosTelemetry t = telems.next(); + + t.update_state(n); + state = n; + } + seen = true; + return state; + } + + public void remove () { + } + + public AltosTelemetryIterator(AltosState start, Iterator telems) { + this.state = start; + this.telems = telems; + this.seen = false; + } +} + +public class AltosTelemetryFile extends AltosStateIterable { + + AltosTelemetryIterable telems; + AltosState start; + + public void write_comments(PrintStream out) { + } + + public void write(PrintStream out) { + + } + + public AltosTelemetryFile(FileInputStream input) { + telems = new AltosTelemetryIterable(input); + start = new AltosState(); + + /* Find boost tick */ + AltosState state = start.clone(); + + for (AltosTelemetry telem : telems) { + telem.update_state(state); + if (state.state >= AltosLib.ao_flight_boost) { + start.set_boost_tick(state.tick); + break; + } + } + } + + public Iterator iterator() { + AltosState state = start.clone(); + Iterator i = telems.iterator(); + + while (i.hasNext() && !state.valid()) { + AltosTelemetry t = i.next(); + t.update_state(state); + } + return new AltosTelemetryIterator(state, i); + } +} \ No newline at end of file diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index 57033638..b7489f77 100644 --- a/altoslib/AltosTelemetryIterable.java +++ b/altoslib/AltosTelemetryIterable.java @@ -21,27 +21,15 @@ import java.io.*; import java.util.*; import java.text.*; -public class AltosTelemetryIterable extends AltosRecordIterable { - TreeSet records; +public class AltosTelemetryIterable implements Iterable { + LinkedList telems; - public Iterator iterator () { - return records.iterator(); + public Iterator iterator () { + return telems.iterator(); } - boolean has_gps = false; - boolean has_accel = false; - boolean has_ignite = false; - public boolean has_gps() { return has_gps; } - public boolean has_accel() { return has_accel; } - public boolean has_ignite() { return has_ignite; }; - public AltosTelemetryIterable (FileInputStream input) { - boolean saw_boost = false; - int current_tick = 0; - int boost_tick = 0; - - AltosRecord previous = null; - records = new TreeSet (); + telems = new LinkedList (); try { for (;;) { @@ -50,32 +38,10 @@ public class AltosTelemetryIterable extends AltosRecordIterable { break; } try { - AltosRecord record = AltosTelemetry.parse(line, previous); - if (record == null) + AltosTelemetry telem = AltosTelemetry.parse(line); + if (telem == null) break; - if (records.isEmpty()) { - current_tick = record.tick; - } else { - int tick = record.tick; - while (tick < current_tick - 0x1000) - tick += 0x10000; - current_tick = tick; - record.tick = current_tick; - } - if (!saw_boost && record.state >= AltosLib.ao_flight_boost) - { - saw_boost = true; - boost_tick = record.tick; - } - if (record.acceleration() != AltosRecord.MISSING) - has_accel = true; - if (record.gps != null) - has_gps = true; - if (record.main_voltage() != AltosRecord.MISSING) - has_ignite = true; - if (previous != null && previous.tick != record.tick) - records.add(previous); - previous = record; + telems.add(telem); } catch (ParseException pe) { System.out.printf("parse exception %s\n", pe.getMessage()); } catch (AltosCRCException ce) { @@ -84,26 +50,5 @@ public class AltosTelemetryIterable extends AltosRecordIterable { } catch (IOException io) { System.out.printf("io exception\n"); } - - if (previous != null) - records.add(previous); - - /* Adjust all tick counts to match expected eeprom values, - * which starts with a 16-bit tick count 16 samples before boost - */ - - int tick_adjust = (boost_tick - 16) & 0xffff0000; - for (AltosRecord r : this) - r.tick -= tick_adjust; - boost_tick -= tick_adjust; - - /* adjust all tick counts to be relative to boost time */ - for (AltosRecord r : this) - r.time = (r.tick - boost_tick) / 100.0; - - try { - input.close(); - } catch (IOException ie) { - } } } diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java new file mode 100644 index 00000000..45e5c315 --- /dev/null +++ b/altoslib/AltosTelemetryLegacy.java @@ -0,0 +1,556 @@ +/* + * Copyright © 2010 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.text.*; + +/* + * Telemetry data contents + */ + + +/* + * The packet format is a simple hex dump of the raw telemetry frame. + * It starts with 'TELEM', then contains hex digits with a checksum as the last + * byte on the line. + * + * Version 4 is a replacement with consistent syntax. Each telemetry line + * contains a sequence of space-separated names and values, the values are + * either integers or strings. The names are all unique. All values are + * optional + * + * VERSION 4 c KD7SQG n 236 f 18 r -25 s pad t 513 r_a 15756 r_b 26444 r_t 20944 + * r_v 26640 r_d 512 r_m 208 c_a 15775 c_b 26439 c_p 15749 c_m 16281 a_a 15764 + * a_s 0 a_b 26439 g_s u g_n 0 s_n 0 + * + * VERSION 4 c KD7SQG n 19 f 0 r -23 s pad t 513 r_b 26372 r_t 21292 r_v 26788 + * r_d 136 r_m 140 c_b 26370 k_h 0 k_s 0 k_a 0 + * + * General header fields + * + * Name Value + * + * VERSION Telemetry version number (4 or more). Must be first. + * c Callsign (string, no spaces allowed) + * n Flight unit serial number (integer) + * f Flight number (integer) + * r Packet RSSI value (integer) + * s Flight computer state (string, no spaces allowed) + * t Flight computer clock (integer in centiseconds) + * + * Version 3 is Version 2 with fixed RSSI numbers -- the radio reports + * in 1/2dB increments while this protocol provides only integers. So, + * the syntax didn't change just the interpretation of the RSSI + * values. + * + * Version 2 of the telemetry data stream is a bit of a mess, with no + * consistent formatting. In particular, the GPS data is formatted for + * viewing instead of parsing. However, the key feature is that every + * telemetry line contains all of the information necessary to + * describe the current rocket state, including the calibration values + * for accelerometer and barometer. + * + * GPS unlocked: + * + * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -68 STATUS ff STATE pad 1001 \ + * a: 16032 p: 21232 t: 20284 v: 25160 d: 204 m: 204 fa: 16038 ga: 16032 fv: 0 \ + * fp: 21232 gp: 21230 a+: 16049 a-: 16304 GPS 0 sat unlocked SAT 1 15 30 + * + * GPS locked: + * + * VERSION 2 CALL KB0G SERIAL 51 FLIGHT 2 RSSI -71 STATUS ff STATE pad 2504 \ + * a: 16028 p: 21220 t: 20360 v: 25004 d: 208 m: 200 fa: 16031 ga: 16032 fv: 330 \ + * fp: 21231 gp: 21230 a+: 16049 a-: 16304 \ + * GPS 9 sat 2010-02-13 17:16:51 35°20.0803'N 106°45.2235'W 1790m \ + * 0.00m/s(H) 0° 0.00m/s(V) 1.0(hdop) 0(herr) 0(verr) \ + * SAT 10 29 30 24 28 5 25 21 20 15 33 1 23 30 24 18 26 10 29 2 26 + * + */ + +public class AltosTelemetryLegacy extends AltosTelemetry { + /* + * General header fields + * + * Name Value + * + * VERSION Telemetry version number (4 or more). Must be first. + * c Callsign (string, no spaces allowed) + * n Flight unit serial number (integer) + * f Flight number (integer) + * r Packet RSSI value (integer) + * s Flight computer state (string, no spaces allowed) + * t Flight computer clock (integer in centiseconds) + */ + + final static String AO_TELEM_VERSION = "VERSION"; + final static String AO_TELEM_CALL = "c"; + final static String AO_TELEM_SERIAL = "n"; + final static String AO_TELEM_FLIGHT = "f"; + final static String AO_TELEM_RSSI = "r"; + final static String AO_TELEM_STATE = "s"; + final static String AO_TELEM_TICK = "t"; + + /* + * Raw sensor values + * + * Name Value + * r_a Accelerometer reading (integer) + * r_b Barometer reading (integer) + * r_t Thermometer reading (integer) + * r_v Battery reading (integer) + * r_d Drogue continuity (integer) + * r_m Main continuity (integer) + */ + + final static String AO_TELEM_RAW_ACCEL = "r_a"; + final static String AO_TELEM_RAW_BARO = "r_b"; + final static String AO_TELEM_RAW_THERMO = "r_t"; + final static String AO_TELEM_RAW_BATT = "r_v"; + final static String AO_TELEM_RAW_DROGUE = "r_d"; + final static String AO_TELEM_RAW_MAIN = "r_m"; + + /* + * Sensor calibration values + * + * Name Value + * c_a Ground accelerometer reading (integer) + * c_b Ground barometer reading (integer) + * c_p Accelerometer reading for +1g + * c_m Accelerometer reading for -1g + */ + + final static String AO_TELEM_CAL_ACCEL_GROUND = "c_a"; + final static String AO_TELEM_CAL_BARO_GROUND = "c_b"; + final static String AO_TELEM_CAL_ACCEL_PLUS = "c_p"; + final static String AO_TELEM_CAL_ACCEL_MINUS = "c_m"; + + /* + * Kalman state values + * + * Name Value + * k_h Height above pad (integer, meters) + * k_s Vertical speeed (integer, m/s * 16) + * k_a Vertical acceleration (integer, m/s² * 16) + */ + + final static String AO_TELEM_KALMAN_HEIGHT = "k_h"; + final static String AO_TELEM_KALMAN_SPEED = "k_s"; + final static String AO_TELEM_KALMAN_ACCEL = "k_a"; + + /* + * Ad-hoc flight values + * + * Name Value + * a_a Acceleration (integer, sensor units) + * a_s Speed (integer, integrated acceleration value) + * a_b Barometer reading (integer, sensor units) + */ + + final static String AO_TELEM_ADHOC_ACCEL = "a_a"; + final static String AO_TELEM_ADHOC_SPEED = "a_s"; + final static String AO_TELEM_ADHOC_BARO = "a_b"; + + /* + * GPS values + * + * Name Value + * g_s GPS state (string): + * l locked + * u unlocked + * e error (missing or broken) + * g_n Number of sats used in solution + * g_ns Latitude (degrees * 10e7) + * g_ew Longitude (degrees * 10e7) + * g_a Altitude (integer meters) + * g_Y GPS year (integer) + * g_M GPS month (integer - 1-12) + * g_D GPS day (integer - 1-31) + * g_h GPS hour (integer - 0-23) + * g_m GPS minute (integer - 0-59) + * g_s GPS second (integer - 0-59) + * g_v GPS vertical speed (integer, cm/sec) + * g_s GPS horizontal speed (integer, cm/sec) + * g_c GPS course (integer, 0-359) + * g_hd GPS hdop (integer * 10) + * g_vd GPS vdop (integer * 10) + * g_he GPS h error (integer) + * g_ve GPS v error (integer) + */ + + final static String AO_TELEM_GPS_STATE = "g"; + final static String AO_TELEM_GPS_STATE_LOCKED = "l"; + final static String AO_TELEM_GPS_STATE_UNLOCKED = "u"; + final static String AO_TELEM_GPS_STATE_ERROR = "e"; + final static String AO_TELEM_GPS_NUM_SAT = "g_n"; + final static String AO_TELEM_GPS_LATITUDE = "g_ns"; + final static String AO_TELEM_GPS_LONGITUDE = "g_ew"; + final static String AO_TELEM_GPS_ALTITUDE = "g_a"; + final static String AO_TELEM_GPS_YEAR = "g_Y"; + final static String AO_TELEM_GPS_MONTH = "g_M"; + final static String AO_TELEM_GPS_DAY = "g_D"; + final static String AO_TELEM_GPS_HOUR = "g_h"; + final static String AO_TELEM_GPS_MINUTE = "g_m"; + final static String AO_TELEM_GPS_SECOND = "g_s"; + final static String AO_TELEM_GPS_VERTICAL_SPEED = "g_v"; + final static String AO_TELEM_GPS_HORIZONTAL_SPEED = "g_g"; + final static String AO_TELEM_GPS_COURSE = "g_c"; + final static String AO_TELEM_GPS_HDOP = "g_hd"; + final static String AO_TELEM_GPS_VDOP = "g_vd"; + final static String AO_TELEM_GPS_HERROR = "g_he"; + final static String AO_TELEM_GPS_VERROR = "g_ve"; + + /* + * GPS satellite values + * + * Name Value + * s_n Number of satellites reported (integer) + * s_v0 Space vehicle ID (integer) for report 0 + * s_c0 C/N0 number (integer) for report 0 + * s_v1 Space vehicle ID (integer) for report 1 + * s_c1 C/N0 number (integer) for report 1 + * ... + */ + + final static String AO_TELEM_SAT_NUM = "s_n"; + final static String AO_TELEM_SAT_SVID = "s_v"; + final static String AO_TELEM_SAT_C_N_0 = "s_c"; + + public int version; + public String callsign; + public int flight; + public int state; + + public AltosGPS gps; + public int gps_sequence; + + /* Telemetry sources have these values recorded from the flight computer */ + public double kalman_height; + public double kalman_speed; + public double kalman_acceleration; + + /* Sensor values */ + public int accel; + public int pres; + public int temp; + public int batt; + public int apogee; + public int main; + + public int ground_accel; + public int ground_pres; + public int accel_plus_g; + public int accel_minus_g; + + public int flight_accel; + public int flight_vel; + public int flight_pres; + + private void parse_v4(String[] words, int i) throws ParseException { + AltosTelemetryMap map = new AltosTelemetryMap(words, i); + + callsign = map.get_string(AO_TELEM_CALL, "N0CALL"); + serial = map.get_int(AO_TELEM_SERIAL, AltosRecord.MISSING); + flight = map.get_int(AO_TELEM_FLIGHT, AltosRecord.MISSING); + rssi = map.get_int(AO_TELEM_RSSI, AltosRecord.MISSING); + state = AltosLib.state(map.get_string(AO_TELEM_STATE, "invalid")); + tick = map.get_int(AO_TELEM_TICK, 0); + + /* raw sensor values */ + accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosRecord.MISSING); + pres = map.get_int(AO_TELEM_RAW_BARO, AltosRecord.MISSING); + temp = map.get_int(AO_TELEM_RAW_THERMO, AltosRecord.MISSING); + batt = map.get_int(AO_TELEM_RAW_BATT, AltosRecord.MISSING); + apogee = map.get_int(AO_TELEM_RAW_DROGUE, AltosRecord.MISSING); + main = map.get_int(AO_TELEM_RAW_MAIN, AltosRecord.MISSING); + + /* sensor calibration information */ + ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosRecord.MISSING); + ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosRecord.MISSING); + accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosRecord.MISSING); + accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosRecord.MISSING); + + /* flight computer values */ + kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); + kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); + kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); + + flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosRecord.MISSING); + flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosRecord.MISSING); + flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosRecord.MISSING); + + if (map.has(AO_TELEM_GPS_STATE)) + gps = new AltosGPS(map); + else + gps = null; + } + + private void parse_legacy(String[] words, int i) throws ParseException { + + AltosParse.word (words[i++], "CALL"); + callsign = words[i++]; + + AltosParse.word (words[i++], "SERIAL"); + serial = AltosParse.parse_int(words[i++]); + + if (version >= 2) { + AltosParse.word (words[i++], "FLIGHT"); + flight = AltosParse.parse_int(words[i++]); + } else + flight = 0; + + AltosParse.word(words[i++], "RSSI"); + rssi = AltosParse.parse_int(words[i++]); + + /* Older telemetry data had mis-computed RSSI value */ + if (version <= 2) + rssi = (rssi + 74) / 2 - 74; + + AltosParse.word(words[i++], "STATUS"); + status = AltosParse.parse_hex(words[i++]); + + AltosParse.word(words[i++], "STATE"); + state = AltosLib.state(words[i++]); + + tick = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "a:"); + accel = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "p:"); + pres = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "t:"); + temp = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "v:"); + batt = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "d:"); + apogee = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "m:"); + main = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "fa:"); + flight_accel = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "ga:"); + ground_accel = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "fv:"); + flight_vel = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "fp:"); + flight_pres = AltosParse.parse_int(words[i++]); + + /* Old TeleDongle code with kalman-reporting TeleMetrum code */ + if ((flight_vel & 0xffff0000) == 0x80000000) { + kalman_speed = ((short) flight_vel) / 16.0; + kalman_acceleration = flight_accel / 16.0; + kalman_height = flight_pres; + flight_vel = AltosRecord.MISSING; + flight_pres = AltosRecord.MISSING; + flight_accel = AltosRecord.MISSING; + } else { + kalman_speed = AltosRecord.MISSING; + kalman_acceleration = AltosRecord.MISSING; + kalman_height = AltosRecord.MISSING; + } + + AltosParse.word(words[i++], "gp:"); + ground_pres = AltosParse.parse_int(words[i++]); + + if (version >= 1) { + AltosParse.word(words[i++], "a+:"); + accel_plus_g = AltosParse.parse_int(words[i++]); + + AltosParse.word(words[i++], "a-:"); + accel_minus_g = AltosParse.parse_int(words[i++]); + } else { + accel_plus_g = ground_accel; + accel_minus_g = ground_accel + 530; + } + + gps = new AltosGPS(words, i, version); + gps_sequence++; + } + + public AltosTelemetryLegacy(String line) throws ParseException, AltosCRCException { + String[] words = line.split("\\s+"); + int i = 0; + + if (words[i].equals("CRC") && words[i+1].equals("INVALID")) { + i += 2; + AltosParse.word(words[i++], "RSSI"); + rssi = AltosParse.parse_int(words[i++]); + throw new AltosCRCException(rssi); + } + if (words[i].equals("CALL")) { + version = 0; + } else { + AltosParse.word (words[i++], "VERSION"); + version = AltosParse.parse_int(words[i++]); + } + + if (version < 4) + parse_legacy(words, i); + else + parse_v4(words, i); + } + + /* + * Given a hex dump of a legacy telemetry line, construct an AltosRecordTM from that + */ + + int[] bytes; + int adjust; + + /* + private int int8(int i) { + return AltosLib.int8(bytes, i + 1 + adjust); + } + */ + private int uint8(int i) { + return AltosLib.uint8(bytes, i + 1 + adjust); + } + private int int16(int i) { + return AltosLib.int16(bytes, i + 1 + adjust); + } + private int uint16(int i) { + return AltosLib.uint16(bytes, i + 1 + adjust); + } + private int uint32(int i) { + return AltosLib.uint32(bytes, i + 1 + adjust); + } + private String string(int i, int l) { + return AltosLib.string(bytes, i + 1 + adjust, l); + } + + static final int AO_GPS_NUM_SAT_MASK = (0xf << 0); + static final int AO_GPS_NUM_SAT_SHIFT = (0); + + static final int AO_GPS_VALID = (1 << 4); + static final int AO_GPS_RUNNING = (1 << 5); + static final int AO_GPS_DATE_VALID = (1 << 6); + static final int AO_GPS_COURSE_VALID = (1 << 7); + + public AltosTelemetryLegacy(int[] in_bytes) { + bytes = in_bytes; + version = 4; + adjust = 0; + + if (bytes.length == AltosLib.ao_telemetry_0_8_len + 4) { + serial = uint8(0); + adjust = -1; + } else + serial = uint16(0); + + callsign = string(62, 8); + flight = uint16(2); + state = uint8(4); + tick = uint16(21); + accel = int16(23); + pres = int16(25); + temp = int16(27); + batt = int16(29); + apogee = int16(31); + main = int16(33); + + ground_accel = int16(7); + ground_pres = int16(15); + accel_plus_g = int16(17); + accel_minus_g = int16(19); + + if (uint16(11) == 0x8000) { + kalman_acceleration = int16(5); + kalman_speed = int16(9); + kalman_height = int16(13); + flight_accel = AltosRecord.MISSING; + flight_vel = AltosRecord.MISSING; + flight_pres = AltosRecord.MISSING; + } else { + flight_accel = int16(5); + flight_vel = uint32(9); + flight_pres = int16(13); + kalman_acceleration = AltosRecord.MISSING; + kalman_speed = AltosRecord.MISSING; + kalman_height = AltosRecord.MISSING; + } + + gps = null; + + int gps_flags = uint8(41); + + if ((gps_flags & (AO_GPS_VALID|AO_GPS_RUNNING)) != 0) { + gps = new AltosGPS(); + gps_sequence++; + + gps.nsat = (gps_flags & AO_GPS_NUM_SAT_MASK); + gps.locked = (gps_flags & AO_GPS_VALID) != 0; + gps.connected = true; + gps.lat = uint32(42) / 1.0e7; + gps.lon = uint32(46) / 1.0e7; + gps.alt = int16(50); + gps.ground_speed = uint16(52) / 100.0; + gps.course = uint8(54) * 2; + gps.hdop = uint8(55) / 5.0; + gps.h_error = uint16(58); + gps.v_error = uint16(60); + + int n_tracking_reported = uint8(70); + if (n_tracking_reported > 12) + n_tracking_reported = 12; + int n_tracking_actual = 0; + for (int i = 0; i < n_tracking_reported; i++) { + if (uint8(71 + i*2) != 0) + n_tracking_actual++; + } + if (n_tracking_actual > 0) { + gps.cc_gps_sat = new AltosGPSSat[n_tracking_actual]; + + n_tracking_actual = 0; + for (int i = 0; i < n_tracking_reported; i++) { + int svid = uint8(71 + i*2); + int c_n0 = uint8(72 + i*2); + if (svid != 0) + gps.cc_gps_sat[n_tracking_actual++] = new AltosGPSSat(svid, c_n0); + } + } + } + } + + public void update_state(AltosState state) { + state.set_tick(tick); + state.set_state(this.state); + state.set_flight(flight); + state.set_serial(serial); + state.set_rssi(rssi, status); + + state.set_pressure(AltosConvert.barometer_to_pressure(pres)); + state.set_accel_g(accel_plus_g, accel_minus_g); + state.set_accel(accel); + if (kalman_height != AltosRecord.MISSING) + state.set_kalman(kalman_height, kalman_speed, kalman_acceleration); + state.set_temperature(AltosEepromTM.thermometer_to_temperature(temp)); + state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt)); + state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(apogee)); + state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main)); + if (gps != null) + state.set_gps(gps, gps_sequence); + } +} diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index 3915927c..b1cc009c 100644 --- a/altoslib/AltosTelemetryReader.java +++ b/altoslib/AltosTelemetryReader.java @@ -35,9 +35,12 @@ public class AltosTelemetryReader extends AltosFlightReader { AltosLine l = telem.take(); if (l.line == null) throw new IOException("IO error"); - AltosRecord next = AltosTelemetry.parse(l.line, previous); - previous = next; - state = new AltosState (next, state); + AltosTelemetry telem = AltosTelemetryLegacy.parse(l.line); + if (state == null) + state = new AltosState(); + else + state = state.clone(); + telem.update_state(state); return state; } diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index bbcca906..59e0ec1c 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -72,21 +72,11 @@ altoslib_JAVA = \ AltosStateIterable.java \ AltosStateUpdate.java \ AltosTelemetry.java \ + AltosTelemetryFile.java \ AltosTelemetryIterable.java \ + AltosTelemetryLegacy.java \ AltosTelemetryMap.java \ AltosTelemetryReader.java \ - AltosTelemetryRecordCompanion.java \ - AltosTelemetryRecordConfiguration.java \ - AltosTelemetryRecordGeneral.java \ - AltosTelemetryRecord.java \ - AltosTelemetryRecordLegacy.java \ - AltosTelemetryRecordLocation.java \ - AltosTelemetryRecordRaw.java \ - AltosTelemetryRecordSatellite.java \ - AltosTelemetryRecordSensor.java \ - AltosTelemetryRecordMegaSensor.java \ - AltosTelemetryRecordMegaData.java \ - AltosTelemetryRecordMini.java \ AltosUnitsListener.java \ AltosMs5607.java \ AltosIMU.java \ diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 6d5ce185..72b2c0d9 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -437,7 +437,7 @@ public class AltosUI extends AltosUIFrame { if (file.getName().endsWith("eeprom")) { return new AltosEepromFile(in); } else { - return null; // new AltosTelemetryIterable(in); + return new AltosTelemetryFile(in); } } @@ -517,9 +517,9 @@ public class AltosUI extends AltosUIFrame { static boolean process_cat(File file) { try { - FileInputStream input = new FileInputStream(file); - AltosEepromFile eef = new AltosEepromFile(input); + AltosStateIterable eef = record_iterable(file); + System.out.printf ("process cat\n"); for (AltosState state : eef) { if ((state.set & AltosState.set_gps) != 0) System.out.printf ("time %g lat %g lon %g alt %g\n", -- cgit v1.2.3 From 017ed54ff69ef2f7740ea2578e22bf72e88deafb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 31 Aug 2013 08:19:28 -0500 Subject: altoslib/altosui: Fixes for state changes Format for gps alt (now double). Use new code for csv file loading. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 2 +- altosui/AltosCSV.java | 2 +- altosui/AltosUI.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 52650062..aa3de432 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -350,7 +350,7 @@ public class AltosState implements Cloneable { } double motion_filter_value() { - return 1/ Math.exp(time_change/10.0); + return 1/ Math.exp(time_change/2.0); } void update_speed() { diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index 0b5a74e9..c96c815e 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -170,7 +170,7 @@ public class AltosCSV implements AltosWriter { if (from_pad == null) from_pad = new AltosGreatCircle(); - out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%6d,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f", + 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, diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 72b2c0d9..b47df0d9 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -353,7 +353,7 @@ public class AltosUI extends AltosUIFrame { if (file.getName().endsWith("eeprom")) return new AltosEepromFile(in); else - return null; // new AltosTelemetryIterable(in); + return new AltosTelemetryFile(in); } catch (FileNotFoundException fe) { System.out.printf("%s\n", fe.getMessage()); return null; -- cgit v1.2.3 From 77dc89ed5b7bf8f5b3fa3b6131660f1a98f583ea Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 31 Aug 2013 23:11:39 -0500 Subject: altoslib/altosui: Further AltosState transition work Parses most eeprom and telem records now; altosui updated to show from AltosState info. Signed-off-by: Keith Packard --- altoslib/AltosConvert.java | 22 ++ altoslib/AltosEeprom.java | 45 +++- altoslib/AltosEepromChunk.java | 26 +++ altoslib/AltosEepromFile.java | 5 + altoslib/AltosEepromGPS.java | 178 ++++++++++++++++ altoslib/AltosEepromHeader.java | 6 +- altoslib/AltosEepromMega.java | 262 +++++++++++------------ altoslib/AltosEepromMetrum.java | 2 + altoslib/AltosEepromMetrum2.java | 178 ++++++++++++++++ altoslib/AltosEepromMini.java | 20 +- altoslib/AltosEepromTM.java | 14 +- altoslib/AltosEepromTeleScience.java | 2 + altoslib/AltosGPS.java | 10 +- altoslib/AltosLib.java | 1 + altoslib/AltosState.java | 129 +++++++++--- altoslib/AltosTelemetry.java | 44 +--- altoslib/AltosTelemetryConfiguration.java | 55 +++++ altoslib/AltosTelemetryLegacy.java | 2 +- altoslib/AltosTelemetryLocation.java | 88 ++++++++ altoslib/AltosTelemetryMegaData.java | 85 ++++++++ altoslib/AltosTelemetryMegaSensor.java | 84 ++++++++ altoslib/AltosTelemetryMetrumData.java | 42 ++++ altoslib/AltosTelemetryMetrumSensor.java | 69 ++++++ altoslib/AltosTelemetryRaw.java | 28 +++ altoslib/AltosTelemetrySatellite.java | 50 +++++ altoslib/AltosTelemetrySensor.java | 80 +++++++ altoslib/AltosTelemetryStandard.java | 106 ++++++++++ altoslib/Makefile.am | 34 ++- altosui/AltosAscent.java | 4 +- altosui/AltosDescent.java | 4 +- altosui/AltosDisplayThread.java | 2 +- altosui/AltosEepromDownload.java | 340 ++++-------------------------- altosui/AltosFlightStatus.java | 2 +- altosui/AltosFlightUI.java | 2 +- altosui/AltosIdleMonitorUI.java | 8 +- altosui/AltosInfoTable.java | 30 +-- altosui/AltosLanded.java | 5 +- altosui/AltosPad.java | 74 ++++--- altosui/AltosUI.java | 15 +- src/core/ao_log.h | 3 +- 40 files changed, 1552 insertions(+), 604 deletions(-) create mode 100644 altoslib/AltosEepromGPS.java create mode 100644 altoslib/AltosEepromMetrum2.java create mode 100644 altoslib/AltosTelemetryConfiguration.java create mode 100644 altoslib/AltosTelemetryLocation.java create mode 100644 altoslib/AltosTelemetryMegaData.java create mode 100644 altoslib/AltosTelemetryMegaSensor.java create mode 100644 altoslib/AltosTelemetryMetrumData.java create mode 100644 altoslib/AltosTelemetryMetrumSensor.java create mode 100644 altoslib/AltosTelemetryRaw.java create mode 100644 altoslib/AltosTelemetrySatellite.java create mode 100644 altoslib/AltosTelemetrySensor.java create mode 100644 altoslib/AltosTelemetryStandard.java (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index a1e2cdca..cf2bc59f 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -196,6 +196,28 @@ public class AltosConvert { return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0; } + static double + thermometer_to_temperature(double thermo) + { + return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; + } + + static double mega_adc(int raw) { + return raw / 4095.0; + } + + static public double mega_battery_voltage(int v_batt) { + if (v_batt != AltosRecord.MISSING) + return 3.3 * mega_adc(v_batt) * (15.0 + 27.0) / 27.0; + return AltosRecord.MISSING; + } + + static double mega_pyro_voltage(int raw) { + if (raw != AltosRecord.MISSING) + return 3.3 * mega_adc(raw) * (100.0 + 27.0) / 27.0; + return AltosRecord.MISSING; + } + public static double radio_to_frequency(int freq, int setting, int cal, int channel) { double f; diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index 31646c7e..081b3be1 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -27,8 +27,26 @@ public abstract class AltosEeprom implements AltosStateUpdate { public int data8[]; public boolean valid; + public int data8(int i) { + return data8[i]; + } + + public int data16(int i) { + return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; + } + + public int data24(int i) { + return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16); + } + + public int data32(int i) { + return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); + } + public final static int header_length = 4; + public abstract int record_length(); + public abstract void update_state(AltosState state); public void write(PrintStream out) { @@ -40,14 +58,28 @@ public abstract class AltosEeprom implements AltosStateUpdate { out.printf ("\n"); } - void parse_chunk(AltosEepromChunk chunk, int start, int record_length) throws ParseException { + public String string() { + String s; + + s = String.format("%c %04x", cmd, tick); + if (data8 != null) { + for (int i = 0; i < data8.length; i++) { + String d = String.format(" %02x", data8[i]); + s = s.concat(d); + } + } + s = s.concat("\n"); + return s; + } + + void parse_chunk(AltosEepromChunk chunk, int start) throws ParseException { cmd = chunk.data(start); - int data_length = record_length - header_length; + int data_length = record_length() - header_length; - valid = !chunk.erased(start, record_length); + valid = !chunk.erased(start, record_length()); if (valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) + if (AltosConvert.checksum(chunk.data, start, record_length()) != 0) throw new ParseException(String.format("invalid checksum at 0x%x", chunk.address + start), 0); } else { @@ -61,12 +93,12 @@ public abstract class AltosEeprom implements AltosStateUpdate { data8[i] = chunk.data(start + header_length + i); } - void parse_string(String line, int record_length) { + void parse_string(String line) { valid = false; tick = 0; cmd = AltosLib.AO_LOG_INVALID; - int data_length = record_length - header_length; + int data_length = record_length() - header_length; if (line == null) return; @@ -79,6 +111,7 @@ public abstract class AltosEeprom implements AltosStateUpdate { tick = Integer.parseInt(tokens[1],16); valid = true; data8 = new int[data_length]; + for (int i = 0; i < data_length; i++) data8[i] = Integer.parseInt(tokens[2 + i],16); } diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index b1bba3bb..1709352b 100644 --- a/altoslib/AltosEepromChunk.java +++ b/altoslib/AltosEepromChunk.java @@ -62,6 +62,32 @@ public class AltosEepromChunk { return true; } + public AltosEeprom eeprom(int offset, int log_format) { + AltosEeprom eeprom = null; + try { + switch (log_format) { + case AltosLib.AO_LOG_FORMAT_FULL: + eeprom = new AltosEepromTM(this, offset); + break; + case AltosLib.AO_LOG_FORMAT_TINY: + case AltosLib.AO_LOG_FORMAT_TELEMETRY: + case AltosLib.AO_LOG_FORMAT_TELESCIENCE: + case AltosLib.AO_LOG_FORMAT_TELEMEGA: + eeprom = new AltosEepromMega(this, offset); + break; + case AltosLib.AO_LOG_FORMAT_TELEMETRUM: + eeprom = new AltosEepromMetrum2(this, offset); + break; + case AltosLib.AO_LOG_FORMAT_TELEMINI: + case AltosLib.AO_LOG_FORMAT_EASYMINI: + eeprom = new AltosEepromMini(this, offset); + break; + } + } catch (ParseException e) { + } + return eeprom; + } + public AltosEepromChunk(AltosLink link, int block, boolean flush) throws TimeoutException, InterruptedException { diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 2f4c54d7..367b6791 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -72,6 +72,7 @@ public class AltosEepromFile extends AltosStateIterable { headers = new AltosEepromIterable(AltosEepromHeader.read(input)); start = headers.state(); + start.set_state(AltosLib.ao_flight_pad); switch (start.log_format) { case AltosLib.AO_LOG_FORMAT_FULL: @@ -81,6 +82,10 @@ public class AltosEepromFile extends AltosStateIterable { case AltosLib.AO_LOG_FORMAT_TELEMETRY: case AltosLib.AO_LOG_FORMAT_TELESCIENCE: case AltosLib.AO_LOG_FORMAT_TELEMEGA: + body = new AltosEepromIterable(AltosEepromMega.read(input)); + break; + case AltosLib.AO_LOG_FORMAT_TELEMETRUM: + body = new AltosEepromIterable(AltosEepromMetrum2.read(input)); break; case AltosLib.AO_LOG_FORMAT_TELEMINI: case AltosLib.AO_LOG_FORMAT_EASYMINI: diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java new file mode 100644 index 00000000..d8e47a6e --- /dev/null +++ b/altoslib/AltosEepromGPS.java @@ -0,0 +1,178 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromGPS extends AltosEeprom { + public static final int record_length = 16; + + public int record_length() { return record_length; } + + /* AO_LOG_FLIGHT elements */ + public int flight() { return data16(0); } + public int ground_accel() { return data16(2); } + public int ground_pres() { return data32(4); } + public int ground_temp() { return data32(8); } + + /* AO_LOG_STATE elements */ + public int state() { return data16(0); } + public int reason() { return data16(2); } + + /* AO_LOG_SENSOR elements */ + public int pres() { return data32(0); } + public int temp() { return data32(4); } + public int accel() { return data16(8); } + + /* AO_LOG_TEMP_VOLT elements */ + public int v_batt() { return data16(0); } + public int sense_a() { return data16(2); } + public int sense_m() { return data16(4); } + + /* AO_LOG_GPS_POS elements */ + public int latitude() { return data32(0); } + public int longitude() { return data32(4); } + public int altitude() { return data16(8); } + + /* AO_LOG_GPS_TIME elements */ + public int hour() { return data8(0); } + public int minute() { return data8(1); } + public int second() { return data8(2); } + public int flags() { return data8(3); } + public int year() { return data8(4); } + public int month() { return data8(5); } + public int day() { return data8(6); } + + /* AO_LOG_GPS_SAT elements */ + public int nsat() { return data8(0); } + public int more() { return data8(1); } + public int svid(int n) { return data8(2 + n * 2); } + public int c_n(int n) { return data8(2 + n * 2 + 1); } + + public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException { + parse_chunk(chunk, start); + } + + public void update_state(AltosState state) { + AltosGPS gps; + + /* Flush any pending GPS changes */ + if (state.gps_pending) { + switch (cmd) { + case AltosLib.AO_LOG_GPS_POS: + case AltosLib.AO_LOG_GPS_LAT: + case AltosLib.AO_LOG_GPS_LON: + case AltosLib.AO_LOG_GPS_ALT: + case AltosLib.AO_LOG_GPS_SAT: + case AltosLib.AO_LOG_GPS_DATE: + break; + default: + state.set_temp_gps(); + break; + } + } + + if (cmd != AltosLib.AO_LOG_FLIGHT) + state.set_tick(tick); + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.set_boost_tick(tick); + state.set_flight(flight()); + state.set_ground_accel(ground_accel()); + state.set_ground_pressure(ground_pres()); +// state.set_temperature(ground_temp() / 100.0); + break; + case AltosLib.AO_LOG_STATE: + state.set_state(state()); + break; + case AltosLib.AO_LOG_SENSOR: + state.set_ms5607(pres(), temp()); + state.set_accel(accel()); + + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a())); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m())); + + break; + case AltosLib.AO_LOG_GPS_POS: + gps = state.make_temp_gps(); + gps.lat = latitude() / 1e7; + gps.lon = longitude() / 1e7; + gps.alt = altitude(); + break; + case AltosLib.AO_LOG_GPS_TIME: + gps = state.make_temp_gps(); + + gps.hour = hour(); + gps.minute = minute(); + gps.second = second(); + + int flags = flags(); + + gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + + gps.year = year(); + gps.month = month(); + gps.day = day(); + break; + case AltosLib.AO_LOG_GPS_SAT: + state.set_tick(tick); + gps = state.make_temp_gps(); + + int n = nsat(); + for (int i = 0; i < n; i++) + gps.add_sat(svid(i), c_n(i)); + break; + } + } + + public AltosEepromMetrum2 (String line) { + parse_string(line); + } + + static public LinkedList read(FileInputStream input) { + LinkedList megas = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + try { + AltosEepromMetrum2 mega = new AltosEepromMetrum2(line); + if (mega.cmd != AltosLib.AO_LOG_INVALID) + megas.add(mega); + } catch (Exception e) { + System.out.printf ("exception\n"); + } + } catch (IOException ie) { + break; + } + } + + return megas; + } +} diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index a06f05ed..35a03a12 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -29,6 +29,9 @@ public class AltosEepromHeader extends AltosEeprom { public boolean last; public boolean valid; + public int record_length () { return 0; } + + /* XXX pull rest of config data to state */ public void update_state(AltosState state) { switch (cmd) { case AltosLib.AO_LOG_CONFIG_VERSION: @@ -40,7 +43,7 @@ public class AltosEepromHeader extends AltosEeprom { case AltosLib.AO_LOG_RADIO_CHANNEL: break; case AltosLib.AO_LOG_CALLSIGN: - state.callsign = data; + state.set_callsign(data); break; case AltosLib.AO_LOG_ACCEL_CAL: state.set_accel_g(config_a, config_b); @@ -90,6 +93,7 @@ public class AltosEepromHeader extends AltosEeprom { state.baro.crc = config_a; break; case AltosLib.AO_LOG_SOFTWARE_VERSION: + state.set_firmware_version(data); break; } } diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 0804c392..e8f9b1fc 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -17,32 +17,14 @@ package org.altusmetrum.altoslib_1; +import java.io.*; +import java.util.*; import java.text.*; -public class AltosEepromMega { - public int cmd; - public int tick; - public boolean valid; - public String data; - public int config_a, config_b; - - public int data8[]; - +public class AltosEepromMega extends AltosEeprom { public static final int record_length = 32; - static final int header_length = 4; - static final int data_length = record_length - header_length; - - public int data8(int i) { - return data8[i]; - } - public int data16(int i) { - return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; - } - - public int data32(int i) { - return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); - } + public int record_length() { return record_length; } /* AO_LOG_FLIGHT elements */ public int flight() { return data16(0); } @@ -68,7 +50,7 @@ public class AltosEepromMega { public int mag_z() { return data16(24); } public int accel() { return data16(26); } - /* AO_LOG_VOLT elements */ + /* AO_LOG_TEMP_VOLT elements */ public int v_batt() { return data16(0); } public int v_pbatt() { return data16(2); } public int nsense() { return data16(4); } @@ -91,131 +73,137 @@ public class AltosEepromMega { public int nsat() { return data16(0); } public int svid(int n) { return data8(2 + n * 2); } public int c_n(int n) { return data8(2 + n * 2 + 1); } + public AltosEepromMega (AltosEepromChunk chunk, int start) throws ParseException { - cmd = chunk.data(start); - - valid = !chunk.erased(start, record_length); - if (valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x", - chunk.address + start), 0); - } else { - cmd = AltosLib.AO_LOG_INVALID; - } + parse_chunk(chunk, start); + } - tick = chunk.data16(start+2); + public void update_state(AltosState state) { + AltosGPS gps; + + /* Flush any pending GPS changes */ + if (state.gps_pending) { + switch (cmd) { + case AltosLib.AO_LOG_GPS_LAT: + case AltosLib.AO_LOG_GPS_LON: + case AltosLib.AO_LOG_GPS_ALT: + case AltosLib.AO_LOG_GPS_SAT: + case AltosLib.AO_LOG_GPS_DATE: + break; + default: + state.set_temp_gps(); + break; + } + } - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = chunk.data(start + header_length + i); + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.set_boost_tick(tick); + state.set_flight(flight()); + state.set_ground_accel(ground_accel()); + state.set_ground_pressure(ground_pres()); + state.set_temperature(ground_temp() / 100.0); + break; + case AltosLib.AO_LOG_STATE: + state.set_tick(tick); + state.set_state(state()); + break; + case AltosLib.AO_LOG_SENSOR: + state.set_tick(tick); + state.set_ms5607(pres(), temp()); + + AltosIMU imu = new AltosIMU(); + imu.accel_x = accel_x(); + imu.accel_y = accel_y(); + imu.accel_z = accel_z(); + + imu.gyro_x = gyro_x(); + imu.gyro_y = gyro_y(); + imu.gyro_z = gyro_z(); + state.imu = imu; + + AltosMag mag = new AltosMag(); + mag.x = mag_x(); + mag.y = mag_y(); + mag.z = mag_z(); + + state.mag = mag; + + state.set_accel(accel()); + + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); + state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt())); + + int nsense = nsense(); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2))); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1))); + + double voltages[] = new double[nsense-2]; + for (int i = 0; i < nsense-2; i++) + voltages[i] = AltosConvert.mega_pyro_voltage(sense(i)); + + state.set_ignitor_voltage(voltages); + break; + case AltosLib.AO_LOG_GPS_TIME: + state.set_tick(tick); + gps = state.make_temp_gps(); + gps.lat = latitude() / 1e7; + gps.lon = longitude() / 1e7; + gps.alt = altitude(); + + gps.hour = hour(); + gps.minute = minute(); + gps.second = second(); + + int flags = flags(); + + gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + + gps.year = year(); + gps.month = month(); + gps.day = day(); + break; + case AltosLib.AO_LOG_GPS_SAT: + state.set_tick(tick); + gps = state.make_temp_gps(); + + int n = nsat(); + for (int i = 0; i < n; i++) + gps.add_sat(svid(i), c_n(i)); + break; + } } public AltosEepromMega (String line) { - valid = false; - tick = 0; + parse_string(line); + } - if (line == null) { - cmd = AltosLib.AO_LOG_INVALID; - line = ""; - } else { + static public LinkedList read(FileInputStream input) { + LinkedList megas = new LinkedList(); + + for (;;) { try { - String[] tokens = line.split("\\s+"); - - if (tokens[0].length() == 1) { - if (tokens.length != 2 + data_length) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } else { - cmd = tokens[0].codePointAt(0); - tick = Integer.parseInt(tokens[1],16); - valid = true; - data8 = new int[data_length]; - for (int i = 0; i < data_length; i++) - data8[i] = Integer.parseInt(tokens[2 + i],16); - } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - config_a = Integer.parseInt(tokens[3]); - config_b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - config_a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - config_a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; - } else if (tokens[0].equals("ms5607")) { - if (tokens[1].equals("reserved:")) { - cmd = AltosLib.AO_LOG_BARO_RESERVED; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("sens:")) { - cmd = AltosLib.AO_LOG_BARO_SENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("off:")) { - cmd = AltosLib.AO_LOG_BARO_OFF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tcs:")) { - cmd = AltosLib.AO_LOG_BARO_TCS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tco:")) { - cmd = AltosLib.AO_LOG_BARO_TCO; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tref:")) { - cmd = AltosLib.AO_LOG_BARO_TREF; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("tempsens:")) { - cmd = AltosLib.AO_LOG_BARO_TEMPSENS; - config_a = Integer.parseInt(tokens[2]); - } else if (tokens[1].equals("crc:")) { - cmd = AltosLib.AO_LOG_BARO_CRC; - config_a = Integer.parseInt(tokens[2]); - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; + String line = AltosLib.gets(input); + if (line == null) + break; + try { + AltosEepromMega mega = new AltosEepromMega(line); + if (mega.cmd != AltosLib.AO_LOG_INVALID) + megas.add(mega); + } catch (Exception e) { + System.out.printf ("exception\n"); } - } catch (NumberFormatException ne) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; + } catch (IOException ie) { + break; } } - } - public AltosEepromMega(int in_cmd, int in_tick) { - cmd = in_cmd; - tick = in_tick; - valid = true; + return megas; } } diff --git a/altoslib/AltosEepromMetrum.java b/altoslib/AltosEepromMetrum.java index 72887032..e035e5fd 100644 --- a/altoslib/AltosEepromMetrum.java +++ b/altoslib/AltosEepromMetrum.java @@ -32,6 +32,8 @@ public class AltosEepromMetrum { static final int header_length = 4; static final int data_length = record_length - header_length; + public int record_length() { return record_length; } + public int data8(int i) { return data8[i]; } diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java new file mode 100644 index 00000000..5a616e6c --- /dev/null +++ b/altoslib/AltosEepromMetrum2.java @@ -0,0 +1,178 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromMetrum2 extends AltosEeprom { + public static final int record_length = 16; + + public int record_length() { return record_length; } + + /* AO_LOG_FLIGHT elements */ + public int flight() { return data16(0); } + public int ground_accel() { return data16(2); } + public int ground_pres() { return data32(4); } + public int ground_temp() { return data32(8); } + + /* AO_LOG_STATE elements */ + public int state() { return data16(0); } + public int reason() { return data16(2); } + + /* AO_LOG_SENSOR elements */ + public int pres() { return data32(0); } + public int temp() { return data32(4); } + public int accel() { return data16(8); } + + /* AO_LOG_TEMP_VOLT elements */ + public int v_batt() { return data16(0); } + public int sense_a() { return data16(2); } + public int sense_m() { return data16(4); } + + /* AO_LOG_GPS_POS elements */ + public int latitude() { return data32(0); } + public int longitude() { return data32(4); } + public int altitude() { return data16(8); } + + /* AO_LOG_GPS_TIME elements */ + public int hour() { return data8(0); } + public int minute() { return data8(1); } + public int second() { return data8(2); } + public int flags() { return data8(3); } + public int year() { return data8(4); } + public int month() { return data8(5); } + public int day() { return data8(6); } + + /* AO_LOG_GPS_SAT elements */ + public int nsat() { return data8(0); } + public int more() { return data8(1); } + public int svid(int n) { return data8(2 + n * 2); } + public int c_n(int n) { return data8(2 + n * 2 + 1); } + + public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException { + parse_chunk(chunk, start); + } + + public void update_state(AltosState state) { + AltosGPS gps; + + /* Flush any pending GPS changes */ + if (state.gps_pending) { + switch (cmd) { + case AltosLib.AO_LOG_GPS_POS: + case AltosLib.AO_LOG_GPS_LAT: + case AltosLib.AO_LOG_GPS_LON: + case AltosLib.AO_LOG_GPS_ALT: + case AltosLib.AO_LOG_GPS_SAT: + case AltosLib.AO_LOG_GPS_DATE: + break; + default: + state.set_temp_gps(); + break; + } + } + + if (cmd != AltosLib.AO_LOG_FLIGHT) + state.set_tick(tick); + switch (cmd) { + case AltosLib.AO_LOG_FLIGHT: + state.set_boost_tick(tick); + state.set_flight(flight()); + state.set_ground_accel(ground_accel()); + state.set_ground_pressure(ground_pres()); +// state.set_temperature(ground_temp() / 100.0); + break; + case AltosLib.AO_LOG_STATE: + state.set_state(state()); + break; + case AltosLib.AO_LOG_SENSOR: + state.set_ms5607(pres(), temp()); + state.set_accel(accel()); + + break; + case AltosLib.AO_LOG_TEMP_VOLT: + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a())); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m())); + + break; + case AltosLib.AO_LOG_GPS_POS: + gps = state.make_temp_gps(); + gps.lat = latitude() / 1e7; + gps.lon = longitude() / 1e7; + gps.alt = altitude(); + break; + case AltosLib.AO_LOG_GPS_TIME: + gps = state.make_temp_gps(); + + gps.hour = hour(); + gps.minute = minute(); + gps.second = second(); + + int flags = flags(); + + gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; + gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; + gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> + AltosLib.AO_GPS_NUM_SAT_SHIFT; + + gps.year = year(); + gps.month = month(); + gps.day = day(); + break; + case AltosLib.AO_LOG_GPS_SAT: + state.set_tick(tick); + gps = state.make_temp_gps(); + + int n = nsat(); + for (int i = 0; i < n; i++) + gps.add_sat(svid(i), c_n(i)); + break; + } + } + + public AltosEepromMetrum2 (String line) { + parse_string(line); + } + + static public LinkedList read(FileInputStream input) { + LinkedList megas = new LinkedList(); + + for (;;) { + try { + String line = AltosLib.gets(input); + if (line == null) + break; + try { + AltosEepromMetrum2 mega = new AltosEepromMetrum2(line); + if (mega.cmd != AltosLib.AO_LOG_INVALID) + megas.add(mega); + } catch (Exception e) { + System.out.printf ("exception\n"); + } + } catch (IOException ie) { + break; + } + } + + return megas; + } +} diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index 1e0ff1b9..15ec1929 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -24,21 +24,7 @@ import java.text.*; public class AltosEepromMini extends AltosEeprom { public static final int record_length = 16; - public int data8(int i) { - return data8[i]; - } - - public int data16(int i) { - return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; - } - - public int data24(int i) { - return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16); - } - - public int data32(int i) { - return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); - } + public int record_length() { return record_length; } /* AO_LOG_FLIGHT elements */ public int flight() { return data16(0); } @@ -84,11 +70,11 @@ public class AltosEepromMini extends AltosEeprom { } public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException { - parse_chunk(chunk, start, record_length); + parse_chunk(chunk, start); } public AltosEepromMini (String line) { - parse_string(line, record_length); + parse_string(line); } public AltosEepromMini(int in_cmd, int in_tick) { diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index 6945468b..461a7a9c 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -30,16 +30,16 @@ public class AltosEepromTM extends AltosEeprom { public static final int record_length = 8; - static double - thermometer_to_temperature(double thermo) - { - return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; - } - public void write(PrintStream out) { out.printf("%c %4x %4x %4x\n", cmd, tick, a, b); } + public int record_length() { return record_length; } + + public String string() { + return String.format("%c %4x %4x %4x\n", cmd, tick, a, b); + } + public void update_state(AltosState state) { AltosGPS gps; @@ -77,7 +77,7 @@ public class AltosEepromTM extends AltosEeprom { break; case AltosLib.AO_LOG_TEMP_VOLT: state.set_tick(tick); - state.set_temperature(thermometer_to_temperature(a)); + state.set_temperature(AltosConvert.thermometer_to_temperature(a)); state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(b)); break; case AltosLib.AO_LOG_DEPLOY: diff --git a/altoslib/AltosEepromTeleScience.java b/altoslib/AltosEepromTeleScience.java index 2a828cf3..bacd66b5 100644 --- a/altoslib/AltosEepromTeleScience.java +++ b/altoslib/AltosEepromTeleScience.java @@ -33,6 +33,8 @@ public class AltosEepromTeleScience { static final int max_data = 12; public static final int record_length = 32; + public int record_length() { return record_length; } + public AltosEepromTeleScience (AltosEepromChunk chunk, int start) throws ParseException { type = chunk.data(start); diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index 399e95b1..a8c19e4a 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -65,8 +65,8 @@ public class AltosGPS implements Cloneable { } public void ClearGPSTime() { - year = month = day = 0; - hour = minute = second = 0; + year = month = day = AltosRecord.MISSING; + hour = minute = second = AltosRecord.MISSING; } public AltosGPS(AltosTelemetryMap map) throws ParseException { @@ -212,6 +212,9 @@ public class AltosGPS implements Cloneable { } public AltosGPS() { + lat = AltosRecord.MISSING; + lon = AltosRecord.MISSING; + alt = AltosRecord.MISSING; ClearGPSTime(); cc_gps_sat = null; } @@ -280,6 +283,9 @@ public class AltosGPS implements Cloneable { } } } else { + lat = AltosRecord.MISSING; + lon = AltosRecord.MISSING; + alt = AltosRecord.MISSING; ClearGPSTime(); cc_gps_sat = null; } diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 4ca8ad9d..d6d78ca8 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -28,6 +28,7 @@ public class AltosLib { public static final int AO_LOG_TEMP_VOLT = 'T'; public static final int AO_LOG_DEPLOY = 'D'; public static final int AO_LOG_STATE = 'S'; + public static final int AO_LOG_GPS_POS = 'P'; public static final int AO_LOG_GPS_TIME = 'G'; public static final int AO_LOG_GPS_LAT = 'N'; public static final int AO_LOG_GPS_LON = 'W'; diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index aa3de432..b80d7b2e 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -32,7 +32,7 @@ public class AltosState implements Cloneable { /* derived data */ - public long report_time; + public long received_time; public double time; public double prev_time; @@ -48,6 +48,12 @@ public class AltosState implements Cloneable { public boolean boost; /* under power */ public int rssi; public int status; + public int device_type; + public int config_major; + public int config_minor; + public int apogee_delay; + public int main_deploy; + public int flight_log_max; public double ground_altitude; public double ground_pressure; @@ -61,11 +67,16 @@ public class AltosState implements Cloneable { public double apogee_voltage; public double main_voltage; public double speed; + public double ignitor_voltage[]; public double prev_height; public double prev_speed; public double prev_acceleration; + public double prev_max_height; + public double prev_max_acceleration; + public double prev_max_speed; + public double max_height; public double max_acceleration; public double max_speed; @@ -100,6 +111,8 @@ public class AltosState implements Cloneable { public double speak_altitude; public String callsign; + public String firmware_version; + public double accel_plus_g; public double accel_minus_g; public double accel; @@ -133,7 +146,7 @@ public class AltosState implements Cloneable { set = 0; - report_time = System.currentTimeMillis(); + received_time = System.currentTimeMillis(); time = AltosRecord.MISSING; time_change = AltosRecord.MISSING; prev_time = AltosRecord.MISSING; @@ -145,6 +158,12 @@ public class AltosState implements Cloneable { boost = false; rssi = AltosRecord.MISSING; status = 0; + device_type = AltosRecord.MISSING; + config_major = AltosRecord.MISSING; + config_minor = AltosRecord.MISSING; + apogee_delay = AltosRecord.MISSING; + main_deploy = AltosRecord.MISSING; + flight_log_max = AltosRecord.MISSING; ground_altitude = AltosRecord.MISSING; ground_pressure = AltosRecord.MISSING; @@ -158,10 +177,15 @@ public class AltosState implements Cloneable { prev_speed = AltosRecord.MISSING; prev_acceleration = AltosRecord.MISSING; + prev_max_height = 0; + prev_max_speed = 0; + prev_max_acceleration = 0; + battery_voltage = AltosRecord.MISSING; pyro_voltage = AltosRecord.MISSING; apogee_voltage = AltosRecord.MISSING; main_voltage = AltosRecord.MISSING; + ignitor_voltage = null; speed = AltosRecord.MISSING; @@ -219,7 +243,7 @@ public class AltosState implements Cloneable { return; } - report_time = old.report_time; + received_time = old.received_time; time = old.time; time_change = 0; tick = old.tick; @@ -232,6 +256,12 @@ public class AltosState implements Cloneable { boost = old.boost; rssi = old.rssi; status = old.status; + device_type = old.device_type; + config_major = old.config_major; + config_minor = old.config_minor; + apogee_delay = old.apogee_delay; + main_deploy = old.main_deploy; + flight_log_max = old.flight_log_max; set = 0; @@ -245,11 +275,16 @@ public class AltosState implements Cloneable { temperature = old.temperature; apogee_voltage = old.apogee_voltage; main_voltage = old.main_voltage; + ignitor_voltage = old.ignitor_voltage; speed = old.speed; prev_height = old.height; prev_speed = old.speed; prev_acceleration = old.acceleration; + + prev_max_height = old.max_height; + prev_max_speed = old.max_speed; + prev_max_acceleration = old.max_acceleration; prev_time = old.time; max_height = old.max_height; @@ -343,7 +378,7 @@ public class AltosState implements Cloneable { else height = AltosRecord.MISSING; - if (height != AltosRecord.MISSING && height > max_height) + if (height != AltosRecord.MISSING && height > prev_max_height) max_height = height; update_speed(); @@ -394,31 +429,34 @@ public class AltosState implements Cloneable { } } } - if (boost && speed != AltosRecord.MISSING && speed > max_speed) + if (boost && speed != AltosRecord.MISSING && speed > prev_max_speed) max_speed = speed; } void update_accel() { - double ground = ground_accel; - - if (ground == AltosRecord.MISSING) - ground = ground_accel_avg; - if (accel == AltosRecord.MISSING) - return; - if (ground == AltosRecord.MISSING) - return; - if (accel_plus_g == AltosRecord.MISSING) - return; - if (accel_minus_g == AltosRecord.MISSING) - return; - - double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; - double counts_per_mss = counts_per_g / 9.80665; - - acceleration = (ground - accel) / counts_per_mss; + if (kalman_acceleration != AltosRecord.MISSING) { + acceleration = kalman_acceleration; + } else { + double ground = ground_accel; + + if (ground == AltosRecord.MISSING) + ground = ground_accel_avg; + if (accel == AltosRecord.MISSING) + return; + if (ground == AltosRecord.MISSING) + return; + if (accel_plus_g == AltosRecord.MISSING) + return; + if (accel_minus_g == AltosRecord.MISSING) + return; + + double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; + double counts_per_mss = counts_per_g / 9.80665; + acceleration = (ground - accel) / counts_per_mss; + } /* Only look at accelerometer data under boost */ - if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) + if (boost && acceleration != AltosRecord.MISSING && acceleration > prev_max_acceleration) max_acceleration = acceleration; update_speed(); } @@ -502,6 +540,26 @@ public class AltosState implements Cloneable { } + public void set_device_type(int device_type) { + this.device_type = device_type; + } + + public void set_config(int major, int minor, int apogee_delay, int main_deploy, int flight_log_max) { + config_major = major; + config_minor = minor; + this.apogee_delay = apogee_delay; + this.main_deploy = main_deploy; + this.flight_log_max = flight_log_max; + } + + public void set_callsign(String callsign) { + this.callsign = callsign; + } + + public void set_firmware_version(String version) { + firmware_version = version; + } + public void set_flight(int flight) { /* When the flight changes, reset the state */ @@ -538,6 +596,10 @@ public class AltosState implements Cloneable { } } + public void set_received_time(long ms) { + received_time = ms; + } + public void set_altitude(double altitude) { if (altitude != AltosRecord.MISSING) { this.altitude = altitude; @@ -577,6 +639,8 @@ public class AltosState implements Cloneable { kalman_speed = speed; kalman_acceleration = acceleration; update_vertical_pos(); + update_speed(); + update_accel(); } } @@ -672,6 +736,9 @@ public class AltosState implements Cloneable { } } + public void set_ignitor_voltage(double[] voltage) { + this.ignitor_voltage = voltage; + } public double time_since_boost() { if (tick == AltosRecord.MISSING) @@ -702,6 +769,13 @@ public class AltosState implements Cloneable { temp_gps = null; } + public AltosState clone() { + AltosState s = new AltosState(); + s.copy(this); + return s; + } + + public void init (AltosRecord cur, AltosState prev_state) { System.out.printf ("init\n"); @@ -721,7 +795,7 @@ public class AltosState implements Cloneable { set_kalman(cur.kalman_height, cur.kalman_speed, cur.kalman_acceleration); - report_time = System.currentTimeMillis(); + received_time = System.currentTimeMillis(); set_temperature(cur.temperature()); set_apogee_voltage(cur.drogue_voltage()); @@ -742,12 +816,6 @@ public class AltosState implements Cloneable { } - public AltosState clone() { - AltosState s = new AltosState(); - s.copy(this); - return s; - } - public AltosState(AltosRecord cur) { init(cur, null); } @@ -756,6 +824,7 @@ public class AltosState implements Cloneable { init(cur, prev); } + public AltosState () { init(); } diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index b84455d3..82e5400e 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -43,6 +43,10 @@ public abstract class AltosTelemetry implements AltosStateUpdate { } public void update_state(AltosState state) { + state.set_serial(serial); + state.set_tick(tick); + state.set_rssi(rssi, status); + state.set_received_time(received_time); } final static int PKT_APPEND_STATUS_1_CRC_OK = (1 << 7); @@ -56,9 +60,11 @@ public abstract class AltosTelemetry implements AltosStateUpdate { final static int packet_type_location = 0x05; final static int packet_type_satellite = 0x06; final static int packet_type_companion = 0x07; - final static int packet_type_MM_sensor = 0x08; - final static int packet_type_MM_data = 0x09; - final static int packet_type_Mini = 0x10; + final static int packet_type_mega_sensor = 0x08; + final static int packet_type_mega_data = 0x09; + final static int packet_type_metrum_sensor = 0x0a; + final static int packet_type_metrum_data = 0x0b; + final static int packet_type_mini = 0x10; static AltosTelemetry parse_hex(String hex) throws ParseException, AltosCRCException { AltosTelemetry telem = null; @@ -87,37 +93,7 @@ public abstract class AltosTelemetry implements AltosStateUpdate { /* length, data ..., rssi, status, checksum -- 4 bytes extra */ switch (bytes.length) { case AltosLib.ao_telemetry_standard_len + 4: - int type = AltosLib.uint8(bytes, 4 + 1); -/* - switch (type) { - case packet_type_TM_sensor: - case packet_type_Tm_sensor: - case packet_type_Tn_sensor: - telem = new AltosTelemetrySensor(bytes); - break; - case packet_type_configuration: - telem = new AltosTelemetryConfiguration(bytes); - break; - case packet_type_location: - telem = new AltosTelemetryLocation(bytes); - break; - case packet_type_satellite: - telem = new AltosTelemetrySatellite(bytes); - break; - case packet_type_companion: - telem = new AltosTelemetryCompanion(bytes); - break; - case packet_type_MM_sensor: - telem = new AltosTelemetryMegaSensor(bytes); - break; - case packet_type_MM_data: - telem = new AltosTelemetryMegaData(bytes); - break; - default: - telem = new AltosTelemetryRaw(bytes); - break; - } -*/ + telem = AltosTelemetryStandard.parse_hex(bytes); break; case AltosLib.ao_telemetry_0_9_len + 4: telem = new AltosTelemetryLegacy(bytes); diff --git a/altoslib/AltosTelemetryConfiguration.java b/altoslib/AltosTelemetryConfiguration.java new file mode 100644 index 00000000..4c9bdd1f --- /dev/null +++ b/altoslib/AltosTelemetryConfiguration.java @@ -0,0 +1,55 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryConfiguration extends AltosTelemetryStandard { + int device_type; + int flight; + int config_major; + int config_minor; + int apogee_delay; + int main_deploy; + int flight_log_max; + String callsign; + String version; + + public AltosTelemetryConfiguration(int[] bytes) { + super(bytes); + + device_type = uint8(5); + flight = uint16(6); + config_major = uint8(8); + config_minor = uint8(9); + apogee_delay = uint16(10); + main_deploy = uint16(12); + flight_log_max = uint16(14); + callsign = string(16, 8); + version = string(24, 8); + } + + public void update_state(AltosState state) { + super.update_state(state); + state.set_device_type(device_type); + state.set_flight(flight); + state.set_config(config_major, config_minor, apogee_delay, main_deploy, flight_log_max); + + state.set_callsign(callsign); + state.set_firmware_version(version); + } +} diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index 45e5c315..95cbbeed 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -546,7 +546,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry { state.set_accel(accel); if (kalman_height != AltosRecord.MISSING) state.set_kalman(kalman_height, kalman_speed, kalman_acceleration); - state.set_temperature(AltosEepromTM.thermometer_to_temperature(temp)); + state.set_temperature(AltosConvert.thermometer_to_temperature(temp)); state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt)); state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(apogee)); state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main)); diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java new file mode 100644 index 00000000..fa3c24d0 --- /dev/null +++ b/altoslib/AltosTelemetryLocation.java @@ -0,0 +1,88 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryLocation extends AltosTelemetryStandard { + int flags; + int altitude; + int latitude; + int longitude; + int year; + int month; + int day; + int hour; + int minute; + int second; + int pdop; + int hdop; + int vdop; + int mode; + int ground_speed; + int climb_rate; + int course; + + public AltosTelemetryLocation(int[] bytes) { + super(bytes); + + flags = uint8(5); + altitude = int16(6); + latitude = uint32(8); + longitude = uint32(12); + year = uint8(16); + month = uint8(17); + day = uint8(18); + hour = uint8(19); + minute = uint8(20); + second = uint8(21); + pdop = uint8(22); + hdop = uint8(23); + vdop = uint8(24); + mode = uint8(25); + ground_speed = uint16(26); + climb_rate = int16(28); + course = uint8(30); + } + + public void update_state(AltosState state) { + super.update_state(state); + AltosGPS gps = state.make_temp_gps(); + + gps.nsat = flags & 0xf; + gps.locked = (flags & (1 << 4)) != 0; + gps.connected = (flags & (1 << 5)) != 0; + + if (gps.locked) { + gps.lat = latitude * 1.0e-7; + gps.lon = longitude * 1.0e-7; + gps.alt = altitude; + gps.year = 2000 + year; + gps.month = month; + gps.day = day; + gps.hour = hour; + gps.minute = minute; + gps.second = second; + gps.ground_speed = ground_speed * 1.0e-2; + gps.course = course * 2; + gps.climb_rate = climb_rate * 1.0e-2; + gps.hdop = hdop; + gps.vdop = vdop; + } + state.set_temp_gps(); + } +} diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java new file mode 100644 index 00000000..5e6cd580 --- /dev/null +++ b/altoslib/AltosTelemetryMegaData.java @@ -0,0 +1,85 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosTelemetryMegaData extends AltosTelemetryStandard { + int state; + + int v_batt; + int v_pyro; + int sense[]; + + int ground_pres; + int ground_accel; + int accel_plus_g; + int accel_minus_g; + + int acceleration; + int speed; + int height; + + public AltosTelemetryMegaData(int[] bytes) { + super(bytes); + + state = int8(5); + + v_batt = int16(6); + v_pyro = int16(8); + + sense = new int[6]; + + for (int i = 0; i < 6; i++) { + sense[i] = int8(10 + i) << 4; + sense[i] |= sense[i] >> 8; + } + + ground_pres = int32(16); + ground_accel = int16(20); + accel_plus_g = int16(22); + accel_minus_g = int16(24); + + acceleration = int16(26); + speed = int16(28); + height = int16(30); + } + + public void update_state(AltosState state) { + super.update_state(state); + + state.set_state(this.state); + + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt)); + state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro)); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense[4])); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense[5])); + + double voltages[] = new double[4]; + for (int i = 0; i < 4; i++) + voltages[i] = AltosConvert.mega_pyro_voltage(sense[i]); + + state.set_ignitor_voltage(voltages); + + state.set_ground_accel(ground_accel); + state.set_ground_pressure(ground_pres); + state.set_accel_g(accel_plus_g, accel_minus_g); + + state.set_kalman(height, speed/16.0, acceleration / 16.0); + } +} + diff --git a/altoslib/AltosTelemetryMegaSensor.java b/altoslib/AltosTelemetryMegaSensor.java new file mode 100644 index 00000000..7c385cfd --- /dev/null +++ b/altoslib/AltosTelemetryMegaSensor.java @@ -0,0 +1,84 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosTelemetryMegaSensor extends AltosTelemetryStandard { + int accel; + int pres; + int temp; + + int accel_x; + int accel_y; + int accel_z; + + int gyro_x; + int gyro_y; + int gyro_z; + + int mag_x; + int mag_y; + int mag_z; + + public AltosTelemetryMegaSensor(int[] bytes) { + super(bytes); + + accel = int16(6); + pres = int32(8); + temp = int16(12); + + accel_x = int16(14); + accel_y = int16(16); + accel_z = int16(18); + + gyro_x = int16(20); + gyro_y = int16(22); + gyro_z = int16(24); + + mag_x = int16(26); + mag_y = int16(28); + mag_z = int16(30); + } + + public void update_state(AltosState state) { + super.update_state(state); + + state.set_accel(accel); + state.set_pressure(pres); + state.set_temperature(temp / 100.0); + + AltosIMU imu = new AltosIMU(); + + imu.accel_x = accel_x; + imu.accel_y = accel_y; + imu.accel_z = accel_z; + + imu.gyro_x = gyro_x; + imu.gyro_y = gyro_y; + imu.gyro_z = gyro_z; + + state.imu = imu; + + AltosMag mag = new AltosMag(); + + mag.x = mag_x; + mag.y = mag_y; + mag.z = mag_z; + + state.mag = mag; + } +} diff --git a/altoslib/AltosTelemetryMetrumData.java b/altoslib/AltosTelemetryMetrumData.java new file mode 100644 index 00000000..d419ab80 --- /dev/null +++ b/altoslib/AltosTelemetryMetrumData.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryMetrumData extends AltosTelemetryStandard { + + int ground_pres; + int ground_accel; + int accel_plus_g; + int accel_minus_g; + + public AltosTelemetryMetrumData(int[] bytes) { + super(bytes); + + ground_pres = int32(8); + ground_accel = int16(12); + accel_plus_g = int16(14); + accel_minus_g = int16(16); + } + + public void update_state(AltosState state) { + state.set_ground_accel(ground_accel); + state.set_accel_g(accel_plus_g, accel_minus_g); + state.set_ground_pressure(ground_pres); + } +} diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java new file mode 100644 index 00000000..59d34dba --- /dev/null +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -0,0 +1,69 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { + int state; + + int accel; + int pres; + int temp; + + int acceleration; + int speed; + int height; + + int v_batt; + int sense_a; + int sense_m; + + public AltosTelemetryMetrumSensor(int[] bytes) { + super(bytes); + + state = int8(5); + accel = int16(6); + pres = int32(8); + temp = int16(12); + + acceleration = int16(14); + speed = int16(16); + height = int16(18); + + v_batt = int16(20); + sense_a = int16(22); + sense_m = int16(24); + } + + public void update_state(AltosState state) { + super.update_state(state); + + state.set_state(this.state); + + state.set_accel(accel); + state.set_ms5607(pres, temp); + + state.set_kalman(height, speed/16.0, acceleration/16.0); + + state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt)); + + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a)); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m)); + System.out.printf ("sense_a %d apogee voltage %g\n", sense_a, state.apogee_voltage); + } +} diff --git a/altoslib/AltosTelemetryRaw.java b/altoslib/AltosTelemetryRaw.java new file mode 100644 index 00000000..9ef7787e --- /dev/null +++ b/altoslib/AltosTelemetryRaw.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosTelemetryRaw extends AltosTelemetryStandard { + public AltosTelemetryRaw(int[] bytes) { + super(bytes); + } + + public void update_state(AltosState state) { + super.update_state(state); + } +} diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java new file mode 100644 index 00000000..3f70f212 --- /dev/null +++ b/altoslib/AltosTelemetrySatellite.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +public class AltosTelemetrySatellite extends AltosTelemetryStandard { + int channels; + AltosGPSSat[] sats; + + public AltosTelemetrySatellite(int[] bytes) { + super(bytes); + + channels = uint8(5); + if (channels > 12) + channels = 12; + if (channels == 0) + sats = null; + else { + sats = new AltosGPSSat[channels]; + for (int i = 0; i < channels; i++) { + int svid = uint8(6 + i * 2 + 0); + int c_n_1 = uint8(6 + i * 2 + 1); + sats[i] = new AltosGPSSat(svid, c_n_1); + } + } + } + + public void update_state(AltosState state) { + super.update_state(state); + + AltosGPS gps = state.make_temp_gps(); + + gps.cc_gps_sat = sats; + state.set_temp_gps(); + } +} diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java new file mode 100644 index 00000000..f89e56c3 --- /dev/null +++ b/altoslib/AltosTelemetrySensor.java @@ -0,0 +1,80 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + + +public class AltosTelemetrySensor extends AltosTelemetryStandard { + int state; + int accel; + int pres; + int temp; + int v_batt; + int sense_d; + int sense_m; + + int acceleration; + int speed; + int height; + + int ground_accel; + int ground_pres; + int accel_plus_g; + int accel_minus_g; + + public AltosTelemetrySensor(int[] bytes) { + super(bytes); + state = uint8(5); + + accel = int16(6); + pres = int16(8); + temp = int16(10); + v_batt = int16(12); + sense_d = int16(14); + sense_m = int16(16); + + acceleration = int16(18); + speed = int16(20); + height = int16(22); + + ground_pres = int16(24); + ground_accel = int16(26); + accel_plus_g = int16(28); + accel_minus_g = int16(30); + } + + public void update_state(AltosState state) { + super.update_state(state); + + state.set_state(this.state); + if (type == packet_type_TM_sensor) { + state.set_ground_accel(ground_accel); + state.set_accel_g(accel_plus_g, accel_minus_g); + state.set_accel(accel); + } + state.set_ground_pressure(AltosConvert.barometer_to_pressure(ground_pres)); + state.set_pressure(AltosConvert.barometer_to_pressure(pres)); + state.set_temperature(AltosConvert.thermometer_to_temperature(temp)); + state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt)); + if (type == packet_type_TM_sensor || type == packet_type_Tm_sensor) { + state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d)); + state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m)); + } + + state.set_kalman(height, speed/16.0, acceleration / 16.0); + } +} diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java new file mode 100644 index 00000000..fa86bf8e --- /dev/null +++ b/altoslib/AltosTelemetryStandard.java @@ -0,0 +1,106 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +public abstract class AltosTelemetryStandard extends AltosTelemetry { + int[] bytes; + int type; + + public int int8(int off) { + return AltosLib.int8(bytes, off + 1); + } + + public int uint8(int off) { + return AltosLib.uint8(bytes, off + 1); + } + + public int int16(int off) { + return AltosLib.int16(bytes, off + 1); + } + + public int uint16(int off) { + return AltosLib.uint16(bytes, off + 1); + } + + public int uint32(int off) { + return AltosLib.uint32(bytes, off + 1); + } + + public int int32(int off) { + return AltosLib.int32(bytes, off + 1); + } + + public String string(int off, int l) { + return AltosLib.string(bytes, off + 1, l); + } + + public static AltosTelemetry parse_hex(int[] bytes) { + int type = AltosLib.uint8(bytes, 4 + 1); + + AltosTelemetry telem; + switch (type) { + case packet_type_TM_sensor: + case packet_type_Tm_sensor: + case packet_type_Tn_sensor: + telem = new AltosTelemetrySensor(bytes); + break; + case packet_type_configuration: + telem = new AltosTelemetryConfiguration(bytes); + break; + case packet_type_location: + telem = new AltosTelemetryLocation(bytes); + break; + case packet_type_satellite: + telem = new AltosTelemetrySatellite(bytes); + break; +/* + case packet_type_companion: + telem = new AltosTelemetryCompanion(bytes); + break; +*/ + case packet_type_mega_sensor: + telem = new AltosTelemetryMegaSensor(bytes); + break; + case packet_type_mega_data: + telem = new AltosTelemetryMegaData(bytes); + break; + case packet_type_metrum_sensor: + telem = new AltosTelemetryMetrumSensor(bytes); + break; + case packet_type_metrum_data: + telem = new AltosTelemetryMetrumData(bytes); + break; + default: + telem = new AltosTelemetryRaw(bytes); + break; + } + return telem; + } + + public AltosTelemetryStandard(int[] bytes) { + this.bytes = bytes; + + serial = uint16(0); + tick = uint16(2); + type = uint8(4); + } + + public void update_state(AltosState state) { + super.update_state(state); + } +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 59e0ec1c..87d4d898 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -10,7 +10,19 @@ SRC=. altoslibdir = $(datadir)/java +record_files = \ + AltosEepromRecord.java \ + AltosEepromTeleScience.java \ + AltosRecordCompanion.java \ + AltosRecordIterable.java \ + AltosRecord.java \ + AltosRecordNone.java \ + AltosRecordTM.java \ + AltosRecordMM.java \ + AltosRecordMini.java + altoslib_JAVA = \ + $(record_files) \ AltosLib.java \ AltosConfigData.java \ AltosConfigValues.java \ @@ -25,11 +37,8 @@ altoslib_JAVA = \ AltosEepromIterable.java \ AltosEepromLog.java \ AltosEepromMega.java \ - AltosEepromMegaIterable.java \ - AltosEepromRecord.java \ - AltosEepromTeleScience.java \ + AltosEepromMetrum2.java \ AltosEepromMini.java \ - AltosEepromOldIterable.java \ AltosFile.java \ AltosFlash.java \ AltosFlashListener.java \ @@ -57,13 +66,6 @@ altoslib_JAVA = \ AltosParse.java \ AltosPreferences.java \ AltosPreferencesBackend.java \ - AltosRecordCompanion.java \ - AltosRecordIterable.java \ - AltosRecord.java \ - AltosRecordNone.java \ - AltosRecordTM.java \ - AltosRecordMM.java \ - AltosRecordMini.java \ AltosReplayReader.java \ AltosRomconfig.java \ AltosSensorMM.java \ @@ -72,11 +74,21 @@ altoslib_JAVA = \ AltosStateIterable.java \ AltosStateUpdate.java \ AltosTelemetry.java \ + AltosTelemetryConfiguration.java \ AltosTelemetryFile.java \ AltosTelemetryIterable.java \ AltosTelemetryLegacy.java \ + AltosTelemetryLocation.java \ AltosTelemetryMap.java \ + AltosTelemetryMegaSensor.java \ + AltosTelemetryMegaData.java \ + AltosTelemetryMetrumSensor.java \ + AltosTelemetryMetrumData.java \ AltosTelemetryReader.java \ + AltosTelemetryRaw.java \ + AltosTelemetrySensor.java \ + AltosTelemetrySatellite.java \ + AltosTelemetryStandard.java \ AltosUnitsListener.java \ AltosMs5607.java \ AltosIMU.java \ diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index f8435037..ceba2d1d 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -308,7 +308,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Lat extends AscentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -322,7 +322,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Lon extends AscentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) show(pos(state.gps.lon,"E", "W")); else show("???"); diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 2b6575cb..35efce16 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -278,7 +278,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Lat extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -292,7 +292,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Lon extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) show(pos(state.gps.lon,"W", "E")); else show("???"); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 70144fb2..7a750c86 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -110,7 +110,7 @@ public class AltosDisplayThread extends Thread { */ if (state.state >= Altos.ao_flight_drogue && (last || - System.currentTimeMillis() - state.report_time >= 15000 || + System.currentTimeMillis() - state.received_time >= 15000 || state.state == Altos.ao_flight_landed)) { if (Math.abs(state.speed) < 20 && state.height < 100) diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 95b17e2a..931b55fd 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -33,9 +33,6 @@ public class AltosEepromDownload implements Runnable { Thread eeprom_thread; AltosEepromMonitor monitor; - int flight; - int serial; - int year, month, day; boolean want_file; FileWriter eeprom_file; LinkedList eeprom_pending; @@ -44,7 +41,7 @@ public class AltosEepromDownload implements Runnable { ActionListener listener; boolean success; ParseException parse_exception; - String extension; + AltosState state; private void FlushPending() throws IOException { for (String s : flights.config_data) { @@ -59,15 +56,19 @@ public class AltosEepromDownload implements Runnable { private void CheckFile(boolean force) throws IOException { if (eeprom_file != null) return; - if (force || (flight != 0 && want_file)) { + if (force || (state.flight != 0 && want_file)) { AltosFile eeprom_name; - - if (extension == null) - extension = "data"; - if (year != 0 && month != 0 && day != 0) - eeprom_name = new AltosFile(year, month, day, serial, flight, extension); - else - eeprom_name = new AltosFile(serial, flight, extension); + AltosGPS gps = state.gps; + + if (gps != null && + gps.year != AltosRecord.MISSING && + gps.month != AltosRecord.MISSING && + gps.day != AltosRecord.MISSING) + { + eeprom_name = new AltosFile(gps.year, gps.month, gps.day, + state.serial, state.flight, "eeprom"); + } else + eeprom_name = new AltosFile(state.serial, state.flight, "eeprom"); eeprom_file = new FileWriter(eeprom_name); if (eeprom_file != null) { @@ -78,270 +79,49 @@ public class AltosEepromDownload implements Runnable { } } - void Log(AltosEepromRecord r) throws IOException { + boolean done; + boolean start; + + void LogEeprom(AltosEeprom r) throws IOException { if (r.cmd != Altos.AO_LOG_INVALID) { - String log_line = String.format("%c %4x %4x %4x\n", - r.cmd, r.tick, r.a, r.b); + String line = r.string(); if (eeprom_file != null) - eeprom_file.write(log_line); + eeprom_file.write(line); else - eeprom_pending.add(log_line); + eeprom_pending.add(line); } } - void set_serial(int in_serial) { - serial = in_serial; - monitor.set_serial(serial); - } - - void set_flight(int in_flight) { - flight = in_flight; - monitor.set_flight(flight); - } - - boolean done; - int state; - - void CaptureFull(AltosEepromChunk eechunk) throws IOException { - boolean any_valid = false; - - extension = "eeprom"; - set_serial(flights.config_data.serial); - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromRecord.record_length) { - try { - AltosEepromRecord r = new AltosEepromRecord(eechunk, i); - if (r.cmd == Altos.AO_LOG_FLIGHT) - set_flight(r.b); - - /* Monitor state transitions to update display */ - if (r.cmd == Altos.AO_LOG_STATE && r.a <= Altos.ao_flight_landed) { - state = r.a; - if (state > Altos.ao_flight_pad) - want_file = true; - } - - if (r.cmd == Altos.AO_LOG_GPS_DATE) { - year = 2000 + (r.a & 0xff); - month = (r.a >> 8) & 0xff; - day = (r.b & 0xff); - want_file = true; - } - if (r.cmd == Altos.AO_LOG_STATE && r.a == Altos.ao_flight_landed) - done = true; - if (r.cmd != AltosLib.AO_LOG_INVALID) - any_valid = true; - Log(r); - } catch (ParseException pe) { - if (parse_exception == null) - parse_exception = pe; - } - } - - if (!any_valid) - done = true; - - CheckFile(false); - } - - boolean start; - int tiny_tick; - - void CaptureTiny (AltosEepromChunk eechunk) throws IOException { + void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException { boolean any_valid = false; - extension = "eeprom"; - set_serial(flights.config_data.serial); - for (int i = 0; i < eechunk.data.length && !done; i += 2) { - int v = eechunk.data16(i); - AltosEepromRecord r; - - if (i == 0 && start) { - tiny_tick = 0; - start = false; - set_flight(v); - r = new AltosEepromRecord(Altos.AO_LOG_FLIGHT, tiny_tick, 0, v); - any_valid = true; - } else { - int s = v ^ 0x8000; - - if (Altos.ao_flight_startup <= s && s <= Altos.ao_flight_invalid) { - state = s; - r = new AltosEepromRecord(Altos.AO_LOG_STATE, tiny_tick, state, 0); - if (state == Altos.ao_flight_landed) - done = true; - state = s; - any_valid = true; - } else { - if (v != 0xffff) - any_valid = true; - - r = new AltosEepromRecord(Altos.AO_LOG_PRESSURE, tiny_tick, 0, v); - - /* - * The flight software records ascent data every 100ms, and descent - * data every 1s. - */ - if (state < Altos.ao_flight_drogue) - tiny_tick += 10; - else - tiny_tick += 100; - } - } - Log(r); - } - CheckFile(false); - if (!any_valid) - done = true; - } - - void LogTeleScience(AltosEepromTeleScience r) throws IOException { - if (r.type != Altos.AO_LOG_INVALID) { - String log_line = String.format("%c %4x %4x %d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", - r.type, r.tick, r.tm_tick, r.tm_state, - r.data[0], r.data[1], r.data[2], r.data[3], - r.data[4], r.data[5], r.data[6], r.data[7], - r.data[8], r.data[9], r.data[10], r.data[11]); - if (eeprom_file != null) - eeprom_file.write(log_line); - else - eeprom_pending.add(log_line); - } - } - - boolean telescience_start; - - void CaptureTeleScience (AltosEepromChunk eechunk) throws IOException { - boolean any_valid = false; - - extension = "science"; - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromTeleScience.record_length) { - try { - AltosEepromTeleScience r = new AltosEepromTeleScience(eechunk, i); - if (r.type == AltosEepromTeleScience.AO_LOG_TELESCIENCE_START) { - if (telescience_start) { - done = true; - break; - } - set_serial(r.data[0]); - set_flight(r.data[1]); - telescience_start = true; - } else { - if (!telescience_start) - break; - } - state = r.tm_state; - want_file =true; - any_valid = true; - LogTeleScience(r); - } catch (ParseException pe) { - if (parse_exception == null) - parse_exception = pe; - } - } + int record_length = 8; - CheckFile(false); - if (!any_valid) - done = true; - } + state.set_serial(flights.config_data.serial); - void LogMega(AltosEepromMega r) throws IOException { - if (r.cmd != Altos.AO_LOG_INVALID) { - String log_line = String.format("%c %4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", - r.cmd, r.tick, - r.data8[0], r.data8[1], r.data8[2], r.data8[3], - r.data8[4], r.data8[5], r.data8[6], r.data8[7], - r.data8[8], r.data8[9], r.data8[10], r.data8[11], - r.data8[12], r.data8[13], r.data8[14], r.data8[15], - r.data8[16], r.data8[17], r.data8[18], r.data8[19], - r.data8[20], r.data8[21], r.data8[22], r.data8[23], - r.data8[24], r.data8[25], r.data8[26], r.data8[27]); - if (eeprom_file != null) - eeprom_file.write(log_line); - else - eeprom_pending.add(log_line); - } - } + for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { + AltosEeprom r = eechunk.eeprom(i, log_format); - void CaptureMega(AltosEepromChunk eechunk) throws IOException { - boolean any_valid = false; + record_length = r.record_length(); - extension = "mega"; - set_serial(flights.config_data.serial); - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromMega.record_length) { - try { - AltosEepromMega r = new AltosEepromMega(eechunk, i); - if (r.cmd == Altos.AO_LOG_FLIGHT) - set_flight(r.data16(0)); - - /* Monitor state transitions to update display */ - if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) <= Altos.ao_flight_landed) { - state = r.data16(0); - if (state > Altos.ao_flight_pad) - want_file = true; - } + r.update_state(state); - if (r.cmd == Altos.AO_LOG_GPS_TIME) { - year = 2000 + r.data8(14); - month = r.data8(15); - day = r.data8(16); + /* Monitor state transitions to update display */ + if (state.state != AltosLib.ao_flight_invalid && + state.state <= AltosLib.ao_flight_landed) + { + if (state.state > Altos.ao_flight_pad) want_file = true; - } - - if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed) + if (state.state == AltosLib.ao_flight_landed) done = true; - if (r.cmd != AltosLib.AO_LOG_INVALID) - any_valid = true; - LogMega(r); - } catch (ParseException pe) { - if (parse_exception == null) - parse_exception = pe; } - } - if (!any_valid) - done = true; - CheckFile(false); - } - - void LogMini(AltosEepromMini r) throws IOException { - if (r.cmd != Altos.AO_LOG_INVALID) { - String log_line = String.format("%c %4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", - r.cmd, r.tick, - r.data8[0], r.data8[1], r.data8[2], r.data8[3], - r.data8[4], r.data8[5], r.data8[6], r.data8[7], - r.data8[8], r.data8[9], r.data8[10], r.data8[11]); - if (eeprom_file != null) - eeprom_file.write(log_line); - else - eeprom_pending.add(log_line); - } - } + if (state.gps != null) + want_file = true; - void CaptureMini(AltosEepromChunk eechunk) throws IOException { - boolean any_valid = false; - - extension = "mini"; - set_serial(flights.config_data.serial); - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromMini.record_length) { - try { - AltosEepromMini r = new AltosEepromMini(eechunk, i); - if (r.cmd == Altos.AO_LOG_FLIGHT) - set_flight(r.data16(0)); - - /* Monitor state transitions to update display */ - if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) <= Altos.ao_flight_landed) { - state = r.data16(0); - if (state > Altos.ao_flight_pad) - want_file = true; - } - - if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed) - done = true; + if (r.valid) { any_valid = true; - LogMini(r); - } catch (ParseException pe) { - if (parse_exception == null) - parse_exception = pe; + LogEeprom(r); } } if (!any_valid) @@ -350,15 +130,12 @@ public class AltosEepromDownload implements Runnable { CheckFile(false); } - void CaptureTelemetry(AltosEepromChunk eechunk) throws IOException { - - } - void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException { int block, state_block = 0; int log_format = flights.config_data.log_format; - state = 0; + state = new AltosState(); + done = false; start = true; @@ -366,10 +143,6 @@ public class AltosEepromDownload implements Runnable { throw new IOException("no serial number found"); /* Reset per-capture variables */ - flight = 0; - year = 0; - month = 0; - day = 0; want_file = false; eeprom_file = null; eeprom_pending = new LinkedList(); @@ -377,9 +150,12 @@ public class AltosEepromDownload implements Runnable { /* Set serial number in the monitor dialog window */ /* Now scan the eeprom, reading blocks of data and converting to .eeprom file form */ - state = 0; state_block = log.start_block; + state_block = log.start_block; for (block = log.start_block; !done && block < log.end_block; block++) { - monitor.set_value(AltosLib.state_name(state), state, block - state_block, block - log.start_block); + monitor.set_value(state.state_name(), + state.state, + block - state_block, + block - log.start_block); AltosEepromChunk eechunk = new AltosEepromChunk(serial_line, block, block == log.start_block); @@ -397,33 +173,7 @@ public class AltosEepromDownload implements Runnable { } } - switch (log_format) { - case AltosLib.AO_LOG_FORMAT_FULL: - extension = "eeprom"; - CaptureFull(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_TINY: - extension = "eeprom"; - CaptureTiny(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_TELEMETRY: - extension = "telem"; - CaptureTelemetry(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_TELESCIENCE: - extension = "science"; - CaptureTeleScience(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_TELEMEGA: - extension = "mega"; - CaptureMega(eechunk); - break; - case AltosLib.AO_LOG_FORMAT_EASYMINI: - case AltosLib.AO_LOG_FORMAT_TELEMINI: - extension = "eeprom"; - CaptureMini(eechunk); - break; - } + CaptureEeprom (eechunk, log_format); } CheckFile(true); if (eeprom_file != null) { diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index 0be7bb51..6383e5b9 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -126,7 +126,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class LastPacket extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - long secs = (System.currentTimeMillis() - state.report_time + 500) / 1000; + long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000; value.setText(String.format("%d", secs)); } public LastPacket(GridBagLayout layout, int x) { diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 423cf10c..1c450ce3 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -102,7 +102,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A status_update.saved_state = state; if (state == null) - state = new AltosState(new AltosRecord()); + state = new AltosState(); pad.show(state, listener_state); diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index bbab017f..f6a91de8 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -65,13 +65,13 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl public void show(AltosState state, AltosListenerState listener_state) { status_update.saved_state = state; - try { +// try { pad.show(state, listener_state); flightStatus.show(state, listener_state); flightInfo.show(state, listener_state); - } catch (Exception e) { - System.out.print("Show exception" + e); - } +// } catch (Exception e) { +// System.out.print("Show exception " + e); +// } } public void update(final AltosState state, final AltosListenerState listener_state) { diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 8601d76f..8906920b 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -155,10 +155,14 @@ public class AltosInfoTable extends JTable { else info_add_row(1, "GPS", " missing"); info_add_row(1, "Satellites", "%6d", state.gps.nsat); - info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); - info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); - info_add_row(1, "GPS altitude", "%6d", state.gps.alt); - info_add_row(1, "GPS height", "%6.0f", state.gps_height); + if (state.gps.lat != AltosRecord.MISSING) + info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); + if (state.gps.lon != AltosRecord.MISSING) + info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); + if (state.gps.alt != AltosRecord.MISSING) + info_add_row(1, "GPS altitude", "%8.1f", state.gps.alt); + if (state.gps_height != AltosRecord.MISSING) + info_add_row(1, "GPS height", "%8.1f", state.gps_height); /* The SkyTraq GPS doesn't report these values */ /* @@ -195,14 +199,16 @@ public class AltosInfoTable extends JTable { info_add_deg(1, "Pad longitude", state.pad_lon, 'E', 'W'); info_add_row(1, "Pad GPS alt", "%6.0f m", state.pad_alt); } - info_add_row(1, "GPS date", "%04d-%02d-%02d", - state.gps.year, - state.gps.month, - state.gps.day); - info_add_row(1, "GPS time", " %02d:%02d:%02d", - state.gps.hour, - state.gps.minute, - state.gps.second); + if (state.gps.year != AltosRecord.MISSING) + info_add_row(1, "GPS date", "%04d-%02d-%02d", + state.gps.year, + state.gps.month, + state.gps.day); + if (state.gps.hour != AltosRecord.MISSING) + info_add_row(1, "GPS time", " %02d:%02d:%02d", + state.gps.hour, + state.gps.minute, + state.gps.second); //int nsat_vis = 0; int c; diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 38f273cf..4cdaa3df 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -103,7 +103,8 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Lat extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected) + show(); + if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -118,7 +119,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Lon extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { show(); - if (state.gps != null && state.gps.connected) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) show(pos(state.gps.lon,"E", "W")); else show("???"); diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index fed009cc..e9c973de 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -310,17 +310,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadLat extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.gps == null) { - hide(); - } else { - if (state.state < AltosLib.ao_flight_pad) { - show(pos(state.gps.lat,"N", "S")); - set_label("Latitude"); - } else { - show(pos(state.pad_lat,"N", "S")); - set_label("Pad Latitude"); + double lat = AltosRecord.MISSING; + String label = null; + + if (state != null) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lat != AltosRecord.MISSING) { + lat = state.gps.lat; + label = "Latitude"; + } else { + lat = state.pad_lat; + label = "Pad Latitude"; } } + if (lat != AltosRecord.MISSING) { + show(pos(lat,"E", "W")); + set_label(label); + } else + hide(); } public PadLat (GridBagLayout layout, int y) { super (layout, y, "Pad Latitude"); @@ -331,17 +337,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadLon extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.gps == null) { - hide(); - } else { - if (state.state < AltosLib.ao_flight_pad) { - show(pos(state.gps.lon,"E", "W")); - set_label("Longitude"); - } else { - show(pos(state.pad_lon,"E", "W")); - set_label("Pad Longitude"); + double lon = AltosRecord.MISSING; + String label = null; + + if (state != null) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lon != AltosRecord.MISSING) { + lon = state.gps.lon; + label = "Longitude"; + } else { + lon = state.pad_lon; + label = "Pad Longitude"; } } + if (lon != AltosRecord.MISSING) { + show(pos(lon,"E", "W")); + set_label(label); + } else + hide(); } public PadLon (GridBagLayout layout, int y) { super (layout, y, "Pad Longitude"); @@ -352,21 +364,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadAlt extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - if (state == null) - hide(); - else { - if (state.state < AltosLib.ao_flight_pad && state.gps != null) { - show("%4.0f m", state.gps.alt); - set_label("Altitude"); + double alt = AltosRecord.MISSING; + String label = null; + + if (state != null) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.alt != AltosRecord.MISSING) { + alt = state.gps.alt; + label = "Altitude"; } else { - if (state.pad_alt == AltosRecord.MISSING) - hide(); - else { - show("%4.0f m", state.pad_alt); - set_label("Pad Altitude"); - } + alt = state.pad_alt; + label = "Pad Altitude"; } } + if (alt != AltosRecord.MISSING) { + show("%4.0f m", state.gps.alt); + set_label(label); + } else + hide(); } public PadAlt (GridBagLayout layout, int y) { super (layout, y, "Pad Altitude"); diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index b47df0d9..151f68fd 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -350,10 +350,10 @@ public class AltosUI extends AltosUIFrame { FileInputStream in; in = new FileInputStream(file); - if (file.getName().endsWith("eeprom")) - return new AltosEepromFile(in); - else + if (file.getName().endsWith("telem")) return new AltosTelemetryFile(in); + else + return new AltosEepromFile(in); } catch (FileNotFoundException fe) { System.out.printf("%s\n", fe.getMessage()); return null; @@ -434,11 +434,10 @@ public class AltosUI extends AltosUIFrame { System.out.printf("Failed to open file '%s'\n", file); return null; } - if (file.getName().endsWith("eeprom")) { - return new AltosEepromFile(in); - } else { + if (file.getName().endsWith("telem")) return new AltosTelemetryFile(in); - } + else + return new AltosEepromFile(in); } static AltosReplayReader replay_file(File file) { @@ -521,6 +520,8 @@ public class AltosUI extends AltosUIFrame { System.out.printf ("process cat\n"); for (AltosState state : eef) { + System.out.printf ("tick %d state %d height %g\n", + state.tick, state.state, state.height); if ((state.set & AltosState.set_gps) != 0) System.out.printf ("time %g lat %g lon %g alt %g\n", state.time_since_boost(), diff --git a/src/core/ao_log.h b/src/core/ao_log.h index a2f342d7..4b09faeb 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -276,7 +276,8 @@ struct ao_log_metrum { uint16_t flight; /* 4 */ int16_t ground_accel; /* 6 */ uint32_t ground_pres; /* 8 */ - } flight; /* 12 */ + uint32_t ground_temp; /* 12 */ + } flight; /* 16 */ /* AO_LOG_STATE */ struct { uint16_t state; /* 4 */ -- cgit v1.2.3 From 528e2e41112cad8a81bccbb89c3bd202b818a506 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 2 Sep 2013 23:10:23 -0600 Subject: altoslib: More AltosState hacking EasyMini graphs are looking good now. Signed-off-by: Keith Packard --- altoslib/AltosEeprom.java | 7 +- altoslib/AltosEepromGPS.java | 6 +- altoslib/AltosEepromMega.java | 6 +- altoslib/AltosEepromMetrum2.java | 11 +- altoslib/AltosEepromMini.java | 2 + altoslib/AltosEepromTM.java | 12 +- altoslib/AltosState.java | 675 ++++++++++++++++++++++------------ altoslib/AltosTelemetry.java | 2 + altoslib/AltosTelemetryFile.java | 5 +- altoslib/AltosTelemetryLocation.java | 2 +- altoslib/AltosTelemetrySatellite.java | 2 +- altosui/AltosAscent.java | 6 +- altosui/AltosCSV.java | 12 +- altosui/AltosDescent.java | 4 +- altosui/AltosDisplayThread.java | 10 +- altosui/AltosFlightStats.java | 18 +- altosui/AltosFlightStatsTable.java | 6 +- altosui/AltosGraphDataPoint.java | 6 +- altosui/AltosInfoTable.java | 28 +- altosui/AltosKML.java | 4 +- altosui/AltosLanded.java | 4 +- altosui/AltosUI.java | 2 +- 22 files changed, 514 insertions(+), 316 deletions(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index 081b3be1..3a996ae0 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -47,7 +47,12 @@ public abstract class AltosEeprom implements AltosStateUpdate { public abstract int record_length(); - public abstract void update_state(AltosState state); + public void update_state(AltosState state) { + if (cmd == AltosLib.AO_LOG_FLIGHT) + state.set_boost_tick(tick); + else + state.set_tick(tick); + } public void write(PrintStream out) { out.printf("%c %04x", cmd, tick); diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index d8e47a6e..f97fbbf9 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -71,6 +71,8 @@ public class AltosEepromGPS extends AltosEeprom { } public void update_state(AltosState state) { + super.update_state(state); + AltosGPS gps; /* Flush any pending GPS changes */ @@ -89,11 +91,8 @@ public class AltosEepromGPS extends AltosEeprom { } } - if (cmd != AltosLib.AO_LOG_FLIGHT) - state.set_tick(tick); switch (cmd) { case AltosLib.AO_LOG_FLIGHT: - state.set_boost_tick(tick); state.set_flight(flight()); state.set_ground_accel(ground_accel()); state.set_ground_pressure(ground_pres()); @@ -139,7 +138,6 @@ public class AltosEepromGPS extends AltosEeprom { gps.day = day(); break; case AltosLib.AO_LOG_GPS_SAT: - state.set_tick(tick); gps = state.make_temp_gps(); int n = nsat(); diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index e8f9b1fc..bccfc621 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -79,6 +79,8 @@ public class AltosEepromMega extends AltosEeprom { } public void update_state(AltosState state) { + super.update_state(state); + AltosGPS gps; /* Flush any pending GPS changes */ @@ -149,7 +151,7 @@ public class AltosEepromMega extends AltosEeprom { break; case AltosLib.AO_LOG_GPS_TIME: state.set_tick(tick); - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; gps.alt = altitude(); @@ -171,7 +173,7 @@ public class AltosEepromMega extends AltosEeprom { break; case AltosLib.AO_LOG_GPS_SAT: state.set_tick(tick); - gps = state.make_temp_gps(); + gps = state.make_temp_gps(true); int n = nsat(); for (int i = 0; i < n; i++) diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index 5a616e6c..3b494839 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -71,6 +71,8 @@ public class AltosEepromMetrum2 extends AltosEeprom { } public void update_state(AltosState state) { + super.update_state(state); + AltosGPS gps; /* Flush any pending GPS changes */ @@ -89,11 +91,8 @@ public class AltosEepromMetrum2 extends AltosEeprom { } } - if (cmd != AltosLib.AO_LOG_FLIGHT) - state.set_tick(tick); switch (cmd) { case AltosLib.AO_LOG_FLIGHT: - state.set_boost_tick(tick); state.set_flight(flight()); state.set_ground_accel(ground_accel()); state.set_ground_pressure(ground_pres()); @@ -115,13 +114,13 @@ public class AltosEepromMetrum2 extends AltosEeprom { break; case AltosLib.AO_LOG_GPS_POS: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.lat = latitude() / 1e7; gps.lon = longitude() / 1e7; gps.alt = altitude(); break; case AltosLib.AO_LOG_GPS_TIME: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.hour = hour(); gps.minute = minute(); @@ -140,7 +139,7 @@ public class AltosEepromMetrum2 extends AltosEeprom { break; case AltosLib.AO_LOG_GPS_SAT: state.set_tick(tick); - gps = state.make_temp_gps(); + gps = state.make_temp_gps(true); int n = nsat(); for (int i = 0; i < n; i++) diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index 15ec1929..e0eedb73 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -52,6 +52,8 @@ public class AltosEepromMini extends AltosEeprom { } public void update_state(AltosState state) { + super.update_state(state); + switch (cmd) { case AltosLib.AO_LOG_FLIGHT: state.set_flight(flight()); diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index 461a7a9c..08f9af5a 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -90,7 +90,7 @@ public class AltosEepromTM extends AltosEeprom { state.set_state(a); break; case AltosLib.AO_LOG_GPS_TIME: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.hour = (a & 0xff); gps.minute = (a >> 8); @@ -104,29 +104,29 @@ public class AltosEepromTM extends AltosEeprom { AltosLib.AO_GPS_NUM_SAT_SHIFT; break; case AltosLib.AO_LOG_GPS_LAT: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); int lat32 = a | (b << 16); gps.lat = (double) lat32 / 1e7; break; case AltosLib.AO_LOG_GPS_LON: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); int lon32 = a | (b << 16); gps.lon = (double) lon32 / 1e7; break; case AltosLib.AO_LOG_GPS_ALT: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.alt = a; break; case AltosLib.AO_LOG_GPS_SAT: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(true); int svid = a; int c_n0 = b >> 8; gps.add_sat(svid, c_n0); break; case AltosLib.AO_LOG_GPS_DATE: - gps = state.make_temp_gps(); + gps = state.make_temp_gps(false); gps.year = (a & 0xff) + 2000; gps.month = a >> 8; gps.day = b & 0xff; diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index b80d7b2e..7817c76a 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -30,6 +30,8 @@ public class AltosState implements Cloneable { public int set; + static final double filter_len = 0.5; + /* derived data */ public long received_time; @@ -38,8 +40,199 @@ public class AltosState implements Cloneable { public double prev_time; public double time_change; public int tick; + private int prev_tick; public int boost_tick; + class AltosValue { + private double value; + private double prev_value; + private double max_value; + private double set_time; + private double prev_set_time; + private double max_rate = 1000.0; + + void set(double new_value, double time) { + if (new_value != AltosRecord.MISSING) { + value = new_value; + if (max_value == AltosRecord.MISSING || value > max_value) { + max_value = value; + } + set_time = time; + } + } + + double value() { + return value; + } + + double max() { + return max_value; + } + + double prev() { + return prev_value; + } + + double change() { + if (value != AltosRecord.MISSING && prev_value != AltosRecord.MISSING) + return value - prev_value; + return AltosRecord.MISSING; + } + + double rate() { + double c = change(); + double t = set_time - prev_set_time; + + if (c != AltosRecord.MISSING && t != 0) + return c / t; + return AltosRecord.MISSING; + } + + double integrate() { + if (value == AltosRecord.MISSING) + return AltosRecord.MISSING; + if (prev_value == AltosRecord.MISSING) + return AltosRecord.MISSING; + + return (value + prev_value) / 2 * (set_time - prev_set_time); + } + + double time() { + return set_time; + } + + void set_derivative(AltosValue in) { + double new_value = in.rate(); + + if (new_value == AltosRecord.MISSING) + return; + + /* Clip changes to reduce noise */ + if (prev_value != AltosRecord.MISSING) { + double ddt = in.time() - prev_set_time; + double ddv = (new_value - prev_value) / ddt; + + /* 100gs */ + if (Math.abs(ddv) > 1000) { + if (new_value > prev_value) + new_value = prev_value + ddt * 1000; + else + new_value = prev_value - ddt * 1000; + } + + double f = 1/Math.exp(ddt/ filter_len); + new_value = prev_value * f + new_value * (1-f); + } + + set(new_value, in.time()); + } + + void set_integral(AltosValue in) { + double change = in.integrate(); + + if (change != AltosRecord.MISSING) + set(prev_value + change, in.time()); + } + + void copy(AltosValue old) { + value = old.value; + set_time = old.set_time; + prev_value = old.value; + prev_set_time = old.set_time; + max_value = old.max_value; + } + + AltosValue() { + value = AltosRecord.MISSING; + prev_value = AltosRecord.MISSING; + max_value = AltosRecord.MISSING; + } + } + + class AltosCValue { + AltosValue measured; + AltosValue computed; + + double value() { + double v = measured.value(); + if (v != AltosRecord.MISSING) + return v; + return computed.value(); + } + + boolean is_measured() { + return measured.value() != AltosRecord.MISSING; + } + + double max() { + double m = measured.max(); + + if (m != AltosRecord.MISSING) + return m; + return computed.max(); + } + + double prev_value() { + if (measured.value != AltosRecord.MISSING && measured.prev_value != AltosRecord.MISSING) + return measured.prev_value; + return computed.prev_value; + } + + AltosValue altos_value() { + if (measured.value() != AltosRecord.MISSING) + return measured; + return computed; + } + + double change() { + double c = measured.change(); + if (c == AltosRecord.MISSING) + c = computed.change(); + return c; + } + + double rate() { + double r = measured.rate(); + if (r == AltosRecord.MISSING) + r = computed.rate(); + return r; + } + + void set_measured(double new_value, double time) { + measured.set(new_value, time); + } + + void set_computed(double new_value, double time) { + computed.set(new_value, time); + } + + void set_derivative(AltosValue in) { + computed.set_derivative(in); + } + + void set_derivative(AltosCValue in) { + set_derivative(in.altos_value()); + } + + 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); + } + + AltosCValue() { + measured = new AltosValue(); + computed = new AltosValue(); + } + } + public int state; public int flight; public int serial; @@ -55,36 +248,191 @@ public class AltosState implements Cloneable { public int main_deploy; public int flight_log_max; - public double ground_altitude; - public double ground_pressure; - public double altitude; - public double height; - public double pressure; - public double acceleration; + private double pressure_to_altitude(double p) { + if (p == AltosRecord.MISSING) + return AltosRecord.MISSING; + return AltosConvert.pressure_to_altitude(p); + } + + private AltosCValue ground_altitude; + + public double ground_altitude() { + return ground_altitude.value(); + } + + public void set_ground_altitude(double a) { + ground_altitude.set_measured(a, time); + } + + class AltosGroundPressure extends AltosValue { + void set(double p, double time) { + super.set(p, time); + ground_altitude.set_computed(pressure_to_altitude(p), time); + } + } + + private AltosGroundPressure ground_pressure; + + public double ground_pressure() { + return ground_pressure.value(); + } + + public void set_ground_pressure (double pressure) { + ground_pressure.set(pressure, time); + } + + class AltosAltitude extends AltosCValue { + + private void set_speed(AltosValue v) { + if (!acceleration.is_measured() || !ascent) + speed.set_derivative(this); + } + + void set_computed(double a, double time) { + super.set_computed(a,time); + set_speed(computed); + set |= set_position; + } + + void set_measured(double a, double time) { + super.set_measured(a,time); + set_speed(measured); + set |= set_position; + } + } + + private AltosAltitude altitude; + + public double altitude() { + double a = altitude.value(); + if (a != AltosRecord.MISSING) + return a; + if (gps != null) + return gps.alt; + return AltosRecord.MISSING; + } + + public double max_altitude() { + double a = altitude.max(); + if (a != AltosRecord.MISSING) + return a; + return AltosRecord.MISSING; + } + + public void set_altitude(double new_altitude) { + altitude.set_measured(new_altitude, time); + } + + class AltosPressure extends AltosValue { + void set(double p, double time) { + super.set(p, time); + altitude.set_computed(pressure_to_altitude(p), time); + } + } + + private AltosPressure pressure; + + public double pressure() { + return pressure.value(); + } + + public void set_pressure(double p) { + pressure.set(p, time); + } + + public double height() { + double k = kalman_height.value(); + if (k != AltosRecord.MISSING) + return k; + + double a = altitude(); + double g = ground_altitude(); + if (a != AltosRecord.MISSING && g != AltosRecord.MISSING) + return a - g; + return AltosRecord.MISSING; + } + + public double max_height() { + double k = kalman_height.max(); + if (k != AltosRecord.MISSING) + return k; + + double a = altitude.max(); + double g = ground_altitude(); + if (a != AltosRecord.MISSING && g != AltosRecord.MISSING) + return a - g; + return AltosRecord.MISSING; + } + + class AltosSpeed extends AltosCValue { + + void set_accel() { + acceleration.set_derivative(this); + } + + void set_derivative(AltosCValue in) { + super.set_derivative(in); + set_accel(); + } + + void set_computed(double new_value, double time) { + super.set_computed(new_value, time); + set_accel(); + } + + void set_measured(double new_value, double time) { + super.set_measured(new_value, time); + set_accel(); + } + } + + private AltosSpeed speed; + + public double speed() { + return speed.value(); + } + + public double max_speed() { + return speed.max(); + } + + class AltosAccel extends AltosCValue { + void set_measured(double a, double time) { + super.set_measured(a, time); + if (ascent) + speed.set_integral(this.measured); + } + } + + AltosAccel acceleration; + + public double acceleration() { + return acceleration.value(); + } + + public double max_acceleration() { + return acceleration.max(); + } + + public AltosValue kalman_height, kalman_speed, kalman_acceleration; + + public void set_kalman(double height, double speed, double acceleration) { + kalman_height.set(height, time); + kalman_speed.set(speed, time); + kalman_acceleration.set(acceleration, time); + } + public double battery_voltage; public double pyro_voltage; public double temperature; public double apogee_voltage; public double main_voltage; - public double speed; - public double ignitor_voltage[]; - - public double prev_height; - public double prev_speed; - public double prev_acceleration; - public double prev_max_height; - public double prev_max_acceleration; - public double prev_max_speed; - - public double max_height; - public double max_acceleration; - public double max_speed; - - public double kalman_height, kalman_speed, kalman_acceleration; + public double ignitor_voltage[]; public AltosGPS gps; public AltosGPS temp_gps; + public boolean temp_gps_clear_sats_pending; public boolean gps_pending; public int gps_sequence; @@ -125,14 +473,6 @@ public class AltosState implements Cloneable { public AltosRecordCompanion companion; - public double speed() { - return speed; - } - - public double max_speed() { - return max_speed; - } - public void set_npad(int npad) { this.npad = npad; gps_waiting = MIN_PAD_SAMPLES - npad; @@ -151,6 +491,7 @@ public class AltosState implements Cloneable { time_change = AltosRecord.MISSING; prev_time = AltosRecord.MISSING; tick = AltosRecord.MISSING; + prev_tick = AltosRecord.MISSING; boost_tick = AltosRecord.MISSING; state = AltosLib.ao_flight_invalid; flight = AltosRecord.MISSING; @@ -165,40 +506,27 @@ public class AltosState implements Cloneable { main_deploy = AltosRecord.MISSING; flight_log_max = AltosRecord.MISSING; - ground_altitude = AltosRecord.MISSING; - ground_pressure = AltosRecord.MISSING; - altitude = AltosRecord.MISSING; - height = AltosRecord.MISSING; - pressure = AltosRecord.MISSING; - acceleration = AltosRecord.MISSING; - temperature = AltosRecord.MISSING; - - prev_height = AltosRecord.MISSING; - prev_speed = AltosRecord.MISSING; - prev_acceleration = AltosRecord.MISSING; - - prev_max_height = 0; - prev_max_speed = 0; - prev_max_acceleration = 0; + ground_altitude = new AltosCValue(); + ground_pressure = new AltosGroundPressure(); + altitude = new AltosAltitude(); + pressure = new AltosPressure(); + speed = new AltosSpeed(); + acceleration = new AltosAccel(); + temperature = AltosRecord.MISSING; battery_voltage = AltosRecord.MISSING; pyro_voltage = AltosRecord.MISSING; apogee_voltage = AltosRecord.MISSING; main_voltage = AltosRecord.MISSING; ignitor_voltage = null; - speed = AltosRecord.MISSING; - - kalman_height = AltosRecord.MISSING; - kalman_speed = AltosRecord.MISSING; - kalman_acceleration = AltosRecord.MISSING; - - max_speed = 0; - max_height = 0; - max_acceleration = 0; + kalman_height = new AltosValue(); + kalman_speed = new AltosValue(); + kalman_acceleration = new AltosValue(); gps = null; temp_gps = null; + temp_gps_clear_sats_pending = false; gps_sequence = 0; gps_pending = false; @@ -225,8 +553,10 @@ public class AltosState implements Cloneable { accel_plus_g = AltosRecord.MISSING; accel_minus_g = AltosRecord.MISSING; accel = AltosRecord.MISSING; + ground_accel = AltosRecord.MISSING; ground_accel_avg = AltosRecord.MISSING; + log_format = AltosRecord.MISSING; serial = AltosRecord.MISSING; @@ -247,6 +577,7 @@ public class AltosState implements Cloneable { time = old.time; time_change = 0; tick = old.tick; + prev_tick = old.tick; boost_tick = old.boost_tick; state = old.state; @@ -265,35 +596,22 @@ public class AltosState implements Cloneable { set = 0; - ground_altitude = old.ground_altitude; - altitude = old.altitude; - height = old.height; - pressure = old.pressure; - acceleration = old.acceleration; + ground_altitude.copy(old.ground_altitude); + altitude.copy(old.altitude); + pressure.copy(old.pressure); + speed.copy(old.speed); + acceleration.copy(old.acceleration); + battery_voltage = old.battery_voltage; pyro_voltage = old.pyro_voltage; temperature = old.temperature; apogee_voltage = old.apogee_voltage; main_voltage = old.main_voltage; ignitor_voltage = old.ignitor_voltage; - speed = old.speed; - - prev_height = old.height; - prev_speed = old.speed; - prev_acceleration = old.acceleration; - - prev_max_height = old.max_height; - prev_max_speed = old.max_speed; - prev_max_acceleration = old.max_acceleration; - prev_time = old.time; - max_height = old.max_height; - max_acceleration = old.max_acceleration; - max_speed = old.max_speed; - - kalman_height = old.kalman_height; - kalman_speed = old.kalman_speed; - kalman_acceleration = old.kalman_acceleration; + kalman_height.copy(old.kalman_height); + kalman_speed.copy(old.kalman_speed); + kalman_acceleration.copy(old.kalman_acceleration); if (old.gps != null) gps = old.gps.clone(); @@ -303,6 +621,7 @@ public class AltosState implements Cloneable { temp_gps = old.temp_gps.clone(); else temp_gps = null; + temp_gps_clear_sats_pending = old.temp_gps_clear_sats_pending; gps_sequence = old.gps_sequence; gps_pending = old.gps_pending; @@ -351,122 +670,8 @@ public class AltosState implements Cloneable { baro = old.baro; companion = old.companion; } - - double altitude() { - if (altitude != AltosRecord.MISSING) - return altitude; - if (gps != null) - return gps.alt; - return AltosRecord.MISSING; - } - - void update_vertical_pos() { - - double alt = altitude(); - - if (state == AltosLib.ao_flight_pad && alt != AltosRecord.MISSING && ground_pressure == AltosRecord.MISSING) { - if (ground_altitude == AltosRecord.MISSING) - ground_altitude = alt; - else - ground_altitude = (ground_altitude * 7 + alt) / 8; - } - - if (kalman_height != AltosRecord.MISSING) - height = kalman_height; - else if (altitude != AltosRecord.MISSING && ground_altitude != AltosRecord.MISSING) - height = altitude - ground_altitude; - else - height = AltosRecord.MISSING; - - if (height != AltosRecord.MISSING && height > prev_max_height) - max_height = height; - - update_speed(); - } - - double motion_filter_value() { - return 1/ Math.exp(time_change/2.0); - } - - void update_speed() { - if (kalman_speed != AltosRecord.MISSING) - speed = kalman_speed; - else if (state != AltosLib.ao_flight_invalid && - time_change != AltosRecord.MISSING) - { - if (ascent && acceleration != AltosRecord.MISSING) - { - if (prev_speed == AltosRecord.MISSING) - speed = acceleration * time_change; - else - speed = prev_speed + acceleration * time_change; - } - else if (height != AltosRecord.MISSING && - prev_height != AltosRecord.MISSING && - time_change != 0) - { - double new_speed = (height - prev_height) / time_change; - - if (prev_speed == AltosRecord.MISSING) - speed = new_speed; - else { - double filter = motion_filter_value(); - - speed = prev_speed * filter + new_speed * (1-filter); - } - } - } - if (acceleration == AltosRecord.MISSING) { - if (prev_speed != AltosRecord.MISSING && time_change != 0) { - double new_acceleration = (speed - prev_speed) / time_change; - - if (prev_acceleration == AltosRecord.MISSING) - acceleration = new_acceleration; - else { - double filter = motion_filter_value(); - - acceleration = prev_acceleration * filter + new_acceleration * (1-filter); - } - } - } - if (boost && speed != AltosRecord.MISSING && speed > prev_max_speed) - max_speed = speed; - } - void update_accel() { - if (kalman_acceleration != AltosRecord.MISSING) { - acceleration = kalman_acceleration; - } else { - double ground = ground_accel; - - if (ground == AltosRecord.MISSING) - ground = ground_accel_avg; - if (accel == AltosRecord.MISSING) - return; - if (ground == AltosRecord.MISSING) - return; - if (accel_plus_g == AltosRecord.MISSING) - return; - if (accel_minus_g == AltosRecord.MISSING) - return; - - double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; - double counts_per_mss = counts_per_g / 9.80665; - acceleration = (ground - accel) / counts_per_mss; - } - - /* Only look at accelerometer data under boost */ - if (boost && acceleration != AltosRecord.MISSING && acceleration > prev_max_acceleration) - max_acceleration = acceleration; - update_speed(); - } - void update_time() { - if (tick != AltosRecord.MISSING) { - time = tick / 100.0; - if (prev_time != AltosRecord.MISSING) - time_change = time - prev_time; - } } void update_gps() { @@ -497,7 +702,7 @@ public class AltosState implements Cloneable { pad_lat != AltosRecord.MISSING && pad_lon != AltosRecord.MISSING) { - double h = height; + double h = height(); if (h == AltosRecord.MISSING) h = 0; @@ -508,16 +713,15 @@ public class AltosState implements Cloneable { } } - public void set_tick(int tick) { - if (tick != AltosRecord.MISSING) { - if (this.tick != AltosRecord.MISSING) { - while (tick < this.tick) - tick += 65536; - time_change = (tick - this.tick) / 100.0; - } else - time_change = 0; - this.tick = tick; - update_time(); + public void set_tick(int new_tick) { + if (new_tick != AltosRecord.MISSING) { + if (prev_tick != AltosRecord.MISSING) { + while (new_tick < prev_tick - 32767) { + new_tick += 65536; + } + } + tick = new_tick; + time = tick / 100.0; } } @@ -600,57 +804,15 @@ public class AltosState implements Cloneable { received_time = ms; } - public void set_altitude(double altitude) { - if (altitude != AltosRecord.MISSING) { - this.altitude = altitude; - update_vertical_pos(); - set |= set_position; - } - } - - public void set_ground_altitude(double ground_altitude) { - if (ground_altitude != AltosRecord.MISSING) { - this.ground_altitude = ground_altitude; - update_vertical_pos(); - } - } - - public void set_ground_pressure (double pressure) { - if (pressure != AltosRecord.MISSING) { - this.ground_pressure = pressure; - set_ground_altitude(AltosConvert.pressure_to_altitude(pressure)); - update_vertical_pos(); - } - } - public void set_gps(AltosGPS gps, int sequence) { if (gps != null) { this.gps = gps.clone(); gps_sequence = sequence; update_gps(); - update_vertical_pos(); set |= set_gps; } } - public void set_kalman(double height, double speed, double acceleration) { - if (height != AltosRecord.MISSING) { - kalman_height = height; - kalman_speed = speed; - kalman_acceleration = acceleration; - update_vertical_pos(); - update_speed(); - update_accel(); - } - } - - public void set_pressure(double pressure) { - if (pressure != AltosRecord.MISSING) { - this.pressure = pressure; - set_altitude(AltosConvert.pressure_to_altitude(pressure)); - } - } - public void make_baro() { if (baro == null) baro = new AltosMs5607(); @@ -674,6 +836,25 @@ public class AltosState implements Cloneable { this.companion = companion; } + void update_accel() { + double ground = ground_accel; + + if (ground == AltosRecord.MISSING) + ground = ground_accel_avg; + if (accel == AltosRecord.MISSING) + return; + if (ground == AltosRecord.MISSING) + return; + if (accel_plus_g == AltosRecord.MISSING) + return; + if (accel_minus_g == AltosRecord.MISSING) + return; + + double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; + double counts_per_mss = counts_per_g / 9.80665; + acceleration.set_computed((ground - accel) / counts_per_mss, time); + } + public void set_accel_g(double accel_plus_g, double accel_minus_g) { if (accel_plus_g != AltosRecord.MISSING) { this.accel_plus_g = accel_plus_g; @@ -681,6 +862,7 @@ public class AltosState implements Cloneable { update_accel(); } } + public void set_ground_accel(double ground_accel) { if (ground_accel != AltosRecord.MISSING) { this.ground_accel = ground_accel; @@ -754,12 +936,17 @@ public class AltosState implements Cloneable { return tick != AltosRecord.MISSING && serial != AltosRecord.MISSING; } - public AltosGPS make_temp_gps() { + public AltosGPS make_temp_gps(boolean sats) { if (temp_gps == null) { temp_gps = new AltosGPS(gps); - temp_gps.cc_gps_sat = null; } gps_pending = true; + if (!sats) + temp_gps_clear_sats_pending = true; + else if (temp_gps_clear_sats_pending) { + temp_gps.cc_gps_sat = null; + temp_gps_clear_sats_pending = false; + } return temp_gps; } diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index 82e5400e..642e7421 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -43,6 +43,8 @@ public abstract class AltosTelemetry implements AltosStateUpdate { } public void update_state(AltosState state) { + 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); diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java index 9e992576..33872688 100644 --- a/altoslib/AltosTelemetryFile.java +++ b/altoslib/AltosTelemetryFile.java @@ -72,13 +72,16 @@ public class AltosTelemetryFile extends AltosStateIterable { /* Find boost tick */ AltosState state = start.clone(); + System.out.printf ("Searching for boost\n"); for (AltosTelemetry telem : telems) { telem.update_state(state); - if (state.state >= AltosLib.ao_flight_boost) { + if (state.state != AltosLib.ao_flight_invalid && state.state >= AltosLib.ao_flight_boost) { + System.out.printf ("boost tick %d\n", state.tick); start.set_boost_tick(state.tick); break; } } + System.out.printf ("Found boost %d\n", start.boost_tick); } public Iterator iterator() { diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index fa3c24d0..50b9dcfc 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -61,7 +61,7 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard { public void update_state(AltosState state) { super.update_state(state); - AltosGPS gps = state.make_temp_gps(); + AltosGPS gps = state.make_temp_gps(false); gps.nsat = flags & 0xf; gps.locked = (flags & (1 << 4)) != 0; diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java index 3f70f212..bd94740f 100644 --- a/altoslib/AltosTelemetrySatellite.java +++ b/altoslib/AltosTelemetrySatellite.java @@ -42,7 +42,7 @@ public class AltosTelemetrySatellite extends AltosTelemetryStandard { public void update_state(AltosState state) { super.update_state(state); - AltosGPS gps = state.make_temp_gps(); + AltosGPS gps = state.make_temp_gps(true); gps.cc_gps_sat = sats; state.set_temp_gps(); diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index ceba2d1d..20474f52 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -240,7 +240,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Height extends AscentValueHold { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.height, state.height); + show(AltosConvert.height, state.height()); } public Height (GridBagLayout layout, int y) { super (layout, y, "Height"); @@ -251,7 +251,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Speed extends AscentValueHold { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.speed, state.speed); + show(AltosConvert.speed, state.speed()); } public Speed (GridBagLayout layout, int y) { super (layout, y, "Speed"); @@ -262,7 +262,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Accel extends AscentValueHold { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.accel, state.acceleration); + show(AltosConvert.accel, state.acceleration()); } public Accel (GridBagLayout layout, int y) { super (layout, y, "Acceleration"); diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index c96c815e..bcff393f 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -127,12 +127,12 @@ public class AltosCSV implements AltosWriter { 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.acceleration(), + state.pressure(), + state.altitude(), + state.height(), + state.speed(), + state.speed(), state.temperature, state.battery_voltage, state.apogee_voltage, diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 35efce16..e85717bb 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -245,7 +245,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Height extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.height, state.height); + show(AltosConvert.height, state.height()); } public Height (GridBagLayout layout, int x, int y) { super (layout, x, y, "Height"); @@ -256,7 +256,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Speed extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.speed, state.speed); + show(AltosConvert.speed, state.speed()); } public Speed (GridBagLayout layout, int x, int y) { super (layout, x, y, "Speed"); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 7a750c86..c894c2d0 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -92,14 +92,14 @@ public class AltosDisplayThread extends Thread { state.range >= 0) { voice.speak("Height %s, bearing %s %d, elevation %d, range %s.\n", - AltosConvert.height.say(state.height), + AltosConvert.height.say(state.height()), state.from_pad.bearing_words( AltosGreatCircle.BEARING_VOICE), (int) (state.from_pad.bearing + 0.5), (int) (state.elevation + 0.5), AltosConvert.distance.say(state.range)); } else if (state.state > Altos.ao_flight_pad) { - voice.speak(AltosConvert.height.say_units(state.height)); + voice.speak(AltosConvert.height.say_units(state.height())); } else { reported_landing = 0; } @@ -113,7 +113,7 @@ public class AltosDisplayThread extends Thread { System.currentTimeMillis() - state.received_time >= 15000 || state.state == Altos.ao_flight_landed)) { - if (Math.abs(state.speed) < 20 && state.height < 100) + if (Math.abs(state.speed()) < 20 && state.height() < 100) voice.speak("rocket landed safely"); else voice.speak("rocket may have crashed"); @@ -185,12 +185,12 @@ public class AltosDisplayThread extends Thread { if ((old_state == null || old_state.state <= Altos.ao_flight_boost) && state.state > Altos.ao_flight_boost) { voice.speak("max speed: %s.", - AltosConvert.speed.say_units(state.max_speed + 0.5)); + AltosConvert.speed.say_units(state.max_speed() + 0.5)); ret = true; } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) && state.state >= Altos.ao_flight_drogue) { voice.speak("max height: %s.", - AltosConvert.height.say_units(state.max_height + 0.5)); + AltosConvert.height.say_units(state.max_height() + 0.5)); ret = true; } } diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index 50deb6c8..f278012f 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -51,7 +51,7 @@ public class AltosFlightStats { if (state == null) return 0; - double landed_height = state.height; + double landed_height = state.height(); state = null; @@ -62,10 +62,10 @@ public class AltosFlightStats { for (AltosState s : states) { state = s; - if (state.height > landed_height + 10) { + if (state.height() > landed_height + 10) { above = true; } else { - if (above && state.height < landed_height + 2) { + if (above && state.height() < landed_height + 2) { above = false; landed_time = state.time; } @@ -82,7 +82,7 @@ public class AltosFlightStats { for (AltosState s : states) { state = s; - if (state.acceleration < 1) + if (state.acceleration() < 1) boost_time = state.time; if (state.state >= Altos.ao_flight_boost) break; @@ -131,16 +131,16 @@ public class AltosFlightStats { second = state.gps.second; } if (0 <= state.state && state.state < Altos.ao_flight_invalid) { - state_accel[state.state] += state.acceleration; - state_speed[state.state] += state.speed; + state_accel[state.state] += state.acceleration(); + state_speed[state.state] += state.speed(); state_count[state.state]++; if (state_start[state.state] == 0.0) state_start[state.state] = state.time; if (state_end[state.state] < state.time) state_end[state.state] = state.time; - max_height = state.max_height; - max_speed = state.max_speed; - max_acceleration = state.max_acceleration; + max_height = state.max_height(); + max_speed = state.max_speed(); + max_acceleration = state.max_acceleration(); } if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { if (state.state <= Altos.ao_flight_pad) { diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java index f8a2d4de..b5a92683 100644 --- a/altosui/AltosFlightStatsTable.java +++ b/altosui/AltosFlightStatsTable.java @@ -76,15 +76,15 @@ public class AltosFlightStatsTable extends JComponent { int y = 0; new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial)); new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight)); - if (stats.year > 0 && stats.hour > 0) + if (stats.year != AltosRecord.MISSING && stats.hour != AltosRecord.MISSING) new FlightStat(layout, y++, "Date/Time", String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day), String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); else { - if (stats.year > 0) + if (stats.year != AltosRecord.MISSING) new FlightStat(layout, y++, "Date", String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day)); - if (stats.hour > 0) + if (stats.hour != AltosRecord.MISSING) new FlightStat(layout, y++, "Time", String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); } diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index 537efc44..85a19b00 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -52,13 +52,13 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { double y = AltosRecord.MISSING; switch (index) { case data_height: - y = state.height; + y = state.height(); break; case data_speed: y = state.speed(); break; case data_accel: - y = state.acceleration; + y = state.acceleration(); break; case data_temp: y = state.temperature; @@ -97,7 +97,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { y = state.from_pad.distance; break; case data_pressure: - y = state.pressure; + y = state.pressure(); break; } if (y == AltosRecord.MISSING) diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 8906920b..cf4642bc 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -107,22 +107,22 @@ public class AltosInfoTable extends JTable { public void show(AltosState state, AltosListenerState listener_state) { info_reset(); if (state != null) { - if (state.altitude != AltosRecord.MISSING) - info_add_row(0, "Altitude", "%6.0f m", state.altitude); - if (state.ground_altitude != AltosRecord.MISSING) - info_add_row(0, "Pad altitude", "%6.0f m", state.ground_altitude); - if (state.height != AltosRecord.MISSING) - info_add_row(0, "Height", "%6.0f m", state.height); - if (state.height != AltosRecord.MISSING) - info_add_row(0, "Max height", "%6.0f m", state.max_height); - if (state.acceleration != AltosRecord.MISSING) - info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration); - if (state.acceleration != AltosRecord.MISSING) - info_add_row(0, "Max acceleration", "%8.1f m/s²", state.max_acceleration); + if (state.altitude() != AltosRecord.MISSING) + info_add_row(0, "Altitude", "%6.0f m", state.altitude()); + if (state.ground_altitude() != AltosRecord.MISSING) + info_add_row(0, "Pad altitude", "%6.0f m", state.ground_altitude()); + if (state.height() != AltosRecord.MISSING) + info_add_row(0, "Height", "%6.0f m", state.height()); + if (state.max_height() != AltosRecord.MISSING) + info_add_row(0, "Max height", "%6.0f m", state.max_height()); + if (state.acceleration() != AltosRecord.MISSING) + info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration()); + if (state.max_acceleration() != AltosRecord.MISSING) + info_add_row(0, "Max acceleration", "%8.1f m/s²", state.max_acceleration()); if (state.speed() != AltosRecord.MISSING) info_add_row(0, "Speed", "%8.1f m/s", state.speed()); - if (state.speed() != AltosRecord.MISSING) - info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed); + if (state.max_speed() != AltosRecord.MISSING) + info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed()); if (state.temperature != AltosRecord.MISSING) info_add_row(0, "Temperature", "%9.2f °C", state.temperature); if (state.battery_voltage != AltosRecord.MISSING) diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index b79f5c9e..8679178f 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -110,8 +110,8 @@ public class AltosKML implements AltosWriter { AltosGPS gps = state.gps; double altitude; - if (state.height != AltosRecord.MISSING) - altitude = state.height + gps_start_altitude; + if (state.height() != AltosRecord.MISSING) + altitude = state.height() + gps_start_altitude; else altitude = gps.alt; out.printf(kml_coord_fmt, diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 4cdaa3df..630527a0 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -163,7 +163,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Height extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.height, state.max_height); + show(AltosConvert.height, state.max_height()); } public Height (GridBagLayout layout, int y) { super (layout, y, "Maximum Height"); @@ -185,7 +185,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Accel extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { - show(AltosConvert.accel, state.max_acceleration); + show(AltosConvert.accel, state.max_acceleration()); } public Accel (GridBagLayout layout, int y) { super (layout, y, "Maximum Acceleration"); diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 151f68fd..31d5a54d 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -521,7 +521,7 @@ public class AltosUI extends AltosUIFrame { System.out.printf ("process cat\n"); for (AltosState state : eef) { System.out.printf ("tick %d state %d height %g\n", - state.tick, state.state, state.height); + state.tick, state.state, state.height()); if ((state.set & AltosState.set_gps) != 0) System.out.printf ("time %g lat %g lon %g alt %g\n", state.time_since_boost(), -- cgit v1.2.3 From 6ee99c1861ef1898a77aead41d80383e697bd248 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:38:20 -0600 Subject: altoslib: Make Ascent/descent use different filter values. Always filter. In derivative code, use a shorter filter during ascent as the baro sensor is cleaner then. Then, make sure to always filter the values as the very first few baro samples can be noisy, which generates a bad starting speed. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 7817c76a..a920d425 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -30,7 +30,8 @@ public class AltosState implements Cloneable { public int set; - static final double filter_len = 0.5; + static final double ascent_filter_len = 0.1; + static final double descent_filter_len = 2.0; /* derived data */ @@ -102,29 +103,42 @@ public class AltosState implements Cloneable { } void set_derivative(AltosValue in) { - double new_value = in.rate(); + double n = in.rate(); - if (new_value == AltosRecord.MISSING) + if (n == AltosRecord.MISSING) return; + double p = prev_value; + double pt = prev_set_time; + + if (p == AltosRecord.MISSING) { + p = 0; + pt = in.time() - 0.01; + } + /* Clip changes to reduce noise */ - if (prev_value != AltosRecord.MISSING) { - double ddt = in.time() - prev_set_time; - double ddv = (new_value - prev_value) / ddt; + double ddt = in.time() - pt; + double ddv = (n - p) / ddt; - /* 100gs */ - if (Math.abs(ddv) > 1000) { - if (new_value > prev_value) - new_value = prev_value + ddt * 1000; - else - new_value = prev_value - ddt * 1000; - } - - double f = 1/Math.exp(ddt/ filter_len); - new_value = prev_value * f + new_value * (1-f); + /* 100gs */ + if (Math.abs(ddv) > 1000) { + if (n > p) + n = p + ddt * 1000; + else + n = p - ddt * 1000; } - set(new_value, in.time()); + double filter_len; + + if (ascent) + filter_len = ascent_filter_len; + else + filter_len = descent_filter_len; + + double f = 1/Math.exp(ddt/ filter_len); + n = p * f + n * (1-f); + + set(n, in.time()); } void set_integral(AltosValue in) { -- cgit v1.2.3 From cfd8e4ebb3cb63937a71537095adb911d6211817 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:40:04 -0600 Subject: altoslib: Use first few baro samples for ground pressure on TM TM didn't record the ground baro reading in the log file, so pull out the first few measured baro samples and use those instead. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index a920d425..726c3041 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -62,6 +62,12 @@ public class AltosState implements Cloneable { } } + void set_filtered(double new_value, double time) { + if (prev_value != AltosRecord.MISSING) + new_value = (prev_value * 15.0 + new_value) / 16.0; + set(new_value, time); + } + double value() { return value; } @@ -278,9 +284,14 @@ public class AltosState implements Cloneable { ground_altitude.set_measured(a, time); } - class AltosGroundPressure extends AltosValue { - void set(double p, double time) { - super.set(p, time); + class AltosGroundPressure extends AltosCValue { + void set_filtered(double p, double time) { + computed.set_filtered(p, time); + ground_altitude.set_computed(pressure_to_altitude(computed.value()), time); + } + + void set_measured(double p, double time) { + super.set_measured(p, time); ground_altitude.set_computed(pressure_to_altitude(p), time); } } @@ -292,7 +303,7 @@ public class AltosState implements Cloneable { } public void set_ground_pressure (double pressure) { - ground_pressure.set(pressure, time); + ground_pressure.set_measured(pressure, time); } class AltosAltitude extends AltosCValue { @@ -340,7 +351,10 @@ public class AltosState implements Cloneable { class AltosPressure extends AltosValue { void set(double p, double time) { super.set(p, time); - altitude.set_computed(pressure_to_altitude(p), time); + if (state == AltosLib.ao_flight_pad) + ground_pressure.set_filtered(p, time); + double a = pressure_to_altitude(p); + altitude.set_computed(a, time); } } -- cgit v1.2.3 From 4de934c283a839fcbb246b36aa15362f3cf8629c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:41:12 -0600 Subject: altoslib: Start integrated value at 0 by default Check for MISSING and start at zero in that case Signed-off-by: Keith Packard --- altoslib/AltosState.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 726c3041..e874a498 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -150,8 +150,12 @@ public class AltosState implements Cloneable { void set_integral(AltosValue in) { double change = in.integrate(); - if (change != AltosRecord.MISSING) - set(prev_value + change, in.time()); + if (change != AltosRecord.MISSING) { + double prev = prev_value; + if (prev == AltosRecord.MISSING) + prev = 0; + set(prev + change, in.time()); + } } void copy(AltosValue old) { -- cgit v1.2.3 From 96a651cc1b81b30f4cbde454e34cf80ed8825945 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:42:00 -0600 Subject: altoslib: Clear sat data when tick changes Sat data comes in multiple records, but the tick is always the same, so use that to tell when the set of sats is new Signed-off-by: Keith Packard --- altoslib/AltosState.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index e874a498..e32a1fe5 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -464,7 +464,7 @@ public class AltosState implements Cloneable { public AltosGPS gps; public AltosGPS temp_gps; - public boolean temp_gps_clear_sats_pending; + public int temp_gps_sat_tick; public boolean gps_pending; public int gps_sequence; @@ -558,7 +558,7 @@ public class AltosState implements Cloneable { gps = null; temp_gps = null; - temp_gps_clear_sats_pending = false; + temp_gps_sat_tick = 0; gps_sequence = 0; gps_pending = false; @@ -653,7 +653,7 @@ public class AltosState implements Cloneable { temp_gps = old.temp_gps.clone(); else temp_gps = null; - temp_gps_clear_sats_pending = old.temp_gps_clear_sats_pending; + temp_gps_sat_tick = old.temp_gps_sat_tick; gps_sequence = old.gps_sequence; gps_pending = old.gps_pending; @@ -973,11 +973,10 @@ public class AltosState implements Cloneable { temp_gps = new AltosGPS(gps); } gps_pending = true; - if (!sats) - temp_gps_clear_sats_pending = true; - else if (temp_gps_clear_sats_pending) { - temp_gps.cc_gps_sat = null; - temp_gps_clear_sats_pending = false; + if (sats) { + if (tick != temp_gps_sat_tick) + temp_gps.cc_gps_sat = null; + temp_gps_sat_tick = tick; } return temp_gps; } -- cgit v1.2.3 From b984ff81d6b8979574e0248ffe8876634b8e1942 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Sep 2013 17:42:42 -0600 Subject: altoslib: Set measured acceleration for measured acceleration Was setting computed acceleration even for measured data Signed-off-by: Keith Packard --- altoslib/AltosState.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index e32a1fe5..1c400bab 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -884,7 +884,7 @@ public class AltosState implements Cloneable { double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; double counts_per_mss = counts_per_g / 9.80665; - acceleration.set_computed((ground - accel) / counts_per_mss, time); + acceleration.set_measured((ground - accel) / counts_per_mss, time); } public void set_accel_g(double accel_plus_g, double accel_minus_g) { -- cgit v1.2.3 From 5b976a6651f4eb05d30afc08b9e1f27c7e52ae00 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 11:33:48 -0700 Subject: altoslib: Finish AltosState changes. Update version number. Removes all of the AltosRecord bits, changes the monitor idle bits to have per-object state updaters. Signed-off-by: Keith Packard --- .../org/altusmetrum/AltosDroid/AltosBluetooth.java | 2 +- .../src/org/altusmetrum/AltosDroid/AltosDroid.java | 8 +- .../AltosDroid/AltosDroidPreferences.java | 2 +- .../org/altusmetrum/AltosDroid/AltosDroidTab.java | 2 +- .../src/org/altusmetrum/AltosDroid/AltosVoice.java | 2 +- .../src/org/altusmetrum/AltosDroid/TabAscent.java | 6 +- .../src/org/altusmetrum/AltosDroid/TabDescent.java | 6 +- .../src/org/altusmetrum/AltosDroid/TabLanded.java | 2 +- .../src/org/altusmetrum/AltosDroid/TabMap.java | 2 +- .../src/org/altusmetrum/AltosDroid/TabPad.java | 10 +- .../altusmetrum/AltosDroid/TelemetryLogger.java | 2 +- .../altusmetrum/AltosDroid/TelemetryReader.java | 2 +- .../altusmetrum/AltosDroid/TelemetryService.java | 2 +- altoslib/AltosAccel.java | 2 +- altoslib/AltosCRCException.java | 2 +- altoslib/AltosCompanion.java | 2 +- altoslib/AltosConfigData.java | 2 +- altoslib/AltosConfigValues.java | 2 +- altoslib/AltosConvert.java | 22 +- altoslib/AltosDebug.java | 2 +- altoslib/AltosDistance.java | 2 +- altoslib/AltosEeprom.java | 2 +- altoslib/AltosEepromBody.java | 2 +- altoslib/AltosEepromBodyIterable.java | 2 +- altoslib/AltosEepromChunk.java | 2 +- altoslib/AltosEepromFile.java | 7 +- altoslib/AltosEepromGPS.java | 2 +- altoslib/AltosEepromHeader.java | 2 +- altoslib/AltosEepromHeaderIterable.java | 2 +- altoslib/AltosEepromIterable.java | 2 +- altoslib/AltosEepromLog.java | 6 +- altoslib/AltosEepromMega.java | 2 +- altoslib/AltosEepromMegaIterable.java | 2 +- altoslib/AltosEepromMetrum.java | 2 +- altoslib/AltosEepromMetrum2.java | 2 +- altoslib/AltosEepromMetrumIterable.java | 2 +- altoslib/AltosEepromMini.java | 9 +- altoslib/AltosEepromMiniIterable.java | 2 +- altoslib/AltosEepromOldIterable.java | 2 +- altoslib/AltosEepromRecord.java | 135 --------- altoslib/AltosEepromTM.java | 2 +- altoslib/AltosEepromTeleScience.java | 57 ---- altoslib/AltosFile.java | 4 +- altoslib/AltosFlash.java | 2 +- altoslib/AltosFlashListener.java | 2 +- altoslib/AltosFlightReader.java | 4 +- altoslib/AltosFrequency.java | 2 +- altoslib/AltosGPS.java | 107 ++++++- altoslib/AltosGPSQuery.java | 97 ------- altoslib/AltosGPSSat.java | 2 +- altoslib/AltosGreatCircle.java | 2 +- altoslib/AltosHeight.java | 2 +- altoslib/AltosHexfile.java | 2 +- altoslib/AltosIMU.java | 56 +++- altoslib/AltosIMUQuery.java | 46 --- altoslib/AltosIdle.java | 39 +++ altoslib/AltosIdleFetch.java | 149 ++++++++++ altoslib/AltosIdleMonitor.java | 115 ++------ altoslib/AltosIdleMonitorListener.java | 2 +- altoslib/AltosIgnite.java | 2 +- altoslib/AltosLib.java | 4 +- altoslib/AltosLine.java | 2 +- altoslib/AltosLink.java | 13 +- altoslib/AltosListenerState.java | 4 +- altoslib/AltosLog.java | 2 +- altoslib/AltosMag.java | 48 ++- altoslib/AltosMma655x.java | 69 +++++ altoslib/AltosMs5607.java | 57 +++- altoslib/AltosMs5607Query.java | 36 --- altoslib/AltosOrderedMegaRecord.java | 52 ---- altoslib/AltosOrderedMetrumRecord.java | 2 +- altoslib/AltosOrderedMiniRecord.java | 52 ---- altoslib/AltosOrderedRecord.java | 63 ---- altoslib/AltosParse.java | 2 +- altoslib/AltosPreferences.java | 2 +- altoslib/AltosPreferencesBackend.java | 2 +- altoslib/AltosPyro.java | 2 +- altoslib/AltosRecord.java | 179 ------------ altoslib/AltosRecordCompanion.java | 38 --- altoslib/AltosRecordIterable.java | 29 -- altoslib/AltosRecordMM.java | 178 ------------ altoslib/AltosRecordMini.java | 133 --------- altoslib/AltosRecordNone.java | 38 --- altoslib/AltosRecordTM.java | 186 ------------ altoslib/AltosRecordTM2.java | 2 +- altoslib/AltosReplayReader.java | 2 +- altoslib/AltosRomconfig.java | 2 +- altoslib/AltosSelfFlash.java | 2 +- altoslib/AltosSensorEMini.java | 70 +++++ altoslib/AltosSensorMM.java | 2 +- altoslib/AltosSensorMega.java | 109 +++++++ altoslib/AltosSensorMetrum.java | 13 +- altoslib/AltosSensorTM.java | 36 ++- altoslib/AltosSpeed.java | 2 +- altoslib/AltosState.java | 321 ++++++++++----------- altoslib/AltosStateIterable.java | 2 +- altoslib/AltosStateUpdate.java | 2 +- altoslib/AltosTelemetry.java | 2 +- altoslib/AltosTelemetryConfiguration.java | 2 +- altoslib/AltosTelemetryFile.java | 7 +- altoslib/AltosTelemetryIterable.java | 65 ++++- altoslib/AltosTelemetryLegacy.java | 66 ++--- altoslib/AltosTelemetryLocation.java | 2 +- altoslib/AltosTelemetryMap.java | 2 +- altoslib/AltosTelemetryMegaData.java | 2 +- altoslib/AltosTelemetryMegaSensor.java | 2 +- altoslib/AltosTelemetryMetrumData.java | 2 +- altoslib/AltosTelemetryMetrumSensor.java | 2 +- altoslib/AltosTelemetryRaw.java | 2 +- altoslib/AltosTelemetryReader.java | 5 +- altoslib/AltosTelemetryRecord.java | 2 +- altoslib/AltosTelemetryRecordCompanion.java | 2 +- altoslib/AltosTelemetryRecordConfiguration.java | 2 +- altoslib/AltosTelemetryRecordGeneral.java | 2 +- altoslib/AltosTelemetryRecordLegacy.java | 58 ++-- altoslib/AltosTelemetryRecordLocation.java | 2 +- altoslib/AltosTelemetryRecordMegaData.java | 2 +- altoslib/AltosTelemetryRecordMegaSensor.java | 2 +- altoslib/AltosTelemetryRecordMetrumData.java | 2 +- altoslib/AltosTelemetryRecordMetrumSensor.java | 2 +- altoslib/AltosTelemetryRecordMini.java | 2 +- altoslib/AltosTelemetryRecordRaw.java | 2 +- altoslib/AltosTelemetryRecordSatellite.java | 2 +- altoslib/AltosTelemetryRecordSensor.java | 14 +- altoslib/AltosTelemetrySatellite.java | 2 +- altoslib/AltosTelemetrySensor.java | 2 +- altoslib/AltosTelemetryStandard.java | 2 +- altoslib/AltosTemperature.java | 2 +- altoslib/AltosUnits.java | 2 +- altoslib/AltosUnitsListener.java | 2 +- altoslib/Makefile.am | 26 +- altosui/Altos.java | 2 +- altosui/AltosAscent.java | 16 +- altosui/AltosBTKnown.java | 2 +- altosui/AltosCSV.java | 4 +- altosui/AltosCSVUI.java | 2 +- altosui/AltosCompanionInfo.java | 6 +- altosui/AltosConfig.java | 2 +- altosui/AltosConfigFreqUI.java | 2 +- altosui/AltosConfigPyroUI.java | 2 +- altosui/AltosConfigTD.java | 2 +- altosui/AltosConfigTDUI.java | 2 +- altosui/AltosConfigUI.java | 2 +- altosui/AltosDataChooser.java | 2 +- altosui/AltosDescent.java | 10 +- altosui/AltosDisplayThread.java | 2 +- altosui/AltosEepromDelete.java | 2 +- altosui/AltosEepromDownload.java | 8 +- altosui/AltosEepromList.java | 2 +- altosui/AltosEepromManage.java | 2 +- altosui/AltosEepromSelect.java | 2 +- altosui/AltosFlashUI.java | 2 +- altosui/AltosFlightDisplay.java | 2 +- altosui/AltosFlightStats.java | 22 +- altosui/AltosFlightStatsTable.java | 10 +- altosui/AltosFlightStatus.java | 6 +- altosui/AltosFlightStatusTableModel.java | 2 +- altosui/AltosFlightStatusUpdate.java | 2 +- altosui/AltosFlightUI.java | 2 +- altosui/AltosFreqList.java | 2 +- altosui/AltosGraph.java | 2 +- altosui/AltosGraphDataPoint.java | 6 +- altosui/AltosGraphDataSet.java | 4 +- altosui/AltosGraphUI.java | 2 +- altosui/AltosIdleMonitorUI.java | 2 +- altosui/AltosIgniteUI.java | 2 +- altosui/AltosInfoTable.java | 44 +-- altosui/AltosKML.java | 8 +- altosui/AltosLanded.java | 6 +- altosui/AltosPad.java | 32 +- altosui/AltosRomconfigUI.java | 2 +- altosui/AltosScanUI.java | 4 +- altosui/AltosSerial.java | 2 +- altosui/AltosSiteMap.java | 6 +- altosui/AltosSiteMapTile.java | 2 +- altosui/AltosUI.java | 4 +- altosui/AltosUIPreferencesBackend.java | 2 +- altosui/AltosWriter.java | 2 +- altosuilib/AltosUIAxis.java | 2 +- altosuilib/AltosUIEnable.java | 2 +- altosuilib/AltosUIGraph.java | 2 +- altosuilib/AltosUIGrapher.java | 2 +- altosuilib/AltosUILib.java | 2 +- altosuilib/AltosUIMarker.java | 2 +- altosuilib/AltosUIPreferences.java | 2 +- altosuilib/AltosUIPreferencesBackend.java | 2 +- altosuilib/AltosUISeries.java | 21 +- configure.ac | 2 +- micropeak/MicroData.java | 2 +- micropeak/MicroDownload.java | 2 +- micropeak/MicroExport.java | 2 +- micropeak/MicroFile.java | 2 +- micropeak/MicroFileChooser.java | 2 +- micropeak/MicroGraph.java | 2 +- micropeak/MicroPeak.java | 2 +- micropeak/MicroRaw.java | 2 +- micropeak/MicroSave.java | 2 +- micropeak/MicroStats.java | 2 +- micropeak/MicroStatsTable.java | 2 +- 199 files changed, 1367 insertions(+), 1968 deletions(-) delete mode 100644 altoslib/AltosEepromRecord.java delete mode 100644 altoslib/AltosEepromTeleScience.java delete mode 100644 altoslib/AltosGPSQuery.java delete mode 100644 altoslib/AltosIMUQuery.java create mode 100644 altoslib/AltosIdle.java create mode 100644 altoslib/AltosIdleFetch.java create mode 100644 altoslib/AltosMma655x.java delete mode 100644 altoslib/AltosMs5607Query.java delete mode 100644 altoslib/AltosOrderedMegaRecord.java delete mode 100644 altoslib/AltosOrderedMiniRecord.java delete mode 100644 altoslib/AltosOrderedRecord.java delete mode 100644 altoslib/AltosRecord.java delete mode 100644 altoslib/AltosRecordCompanion.java delete mode 100644 altoslib/AltosRecordIterable.java delete mode 100644 altoslib/AltosRecordMM.java delete mode 100644 altoslib/AltosRecordMini.java delete mode 100644 altoslib/AltosRecordNone.java delete mode 100644 altoslib/AltosRecordTM.java create mode 100644 altoslib/AltosSensorEMini.java create mode 100644 altoslib/AltosSensorMega.java (limited to 'altoslib/AltosState.java') diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java index 0aea06f1..0ed31437 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosBluetooth.java @@ -31,7 +31,7 @@ import android.os.Handler; //import android.os.Message; import android.util.Log; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosBluetooth extends AltosLink { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index e10982f7..6f378777 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -49,7 +49,7 @@ import android.widget.Toast; import android.app.AlertDialog; import android.location.Location; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosDroid extends FragmentActivity { // Debugging @@ -266,7 +266,7 @@ public class AltosDroid extends FragmentActivity { static String pos(double p, String pos, String neg) { String h = pos; - if (p == AltosRecord.MISSING) + if (p == AltosLib.MISSING) return ""; if (p < 0) { h = neg; @@ -278,13 +278,13 @@ public class AltosDroid extends FragmentActivity { } static String number(String format, double value) { - if (value == AltosRecord.MISSING) + if (value == AltosLib.MISSING) return ""; return String.format(format, value); } static String integer(String format, int value) { - if (value == AltosRecord.MISSING) + if (value == AltosLib.MISSING) return ""; return String.format(format, value); } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java index fd4b0768..59fef842 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java @@ -23,7 +23,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.Environment; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosDroidPreferences implements AltosPreferencesBackend { public final static String NAME = "org.altusmetrum.AltosDroid"; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java index 6ebb47f7..c652a169 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.location.Location; public interface AltosDroidTab { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java index b3dba626..df7409c4 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosVoice.java @@ -21,7 +21,7 @@ package org.altusmetrum.AltosDroid; import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech.OnInitListener; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosVoice { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java index 0e141ae4..69bc68c9 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabAscent.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.app.Activity; import android.os.Bundle; @@ -103,10 +103,10 @@ public class TabAscent extends Fragment implements AltosDroidTab { } mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense)); - mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosRecord.MISSING); + mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosLib.MISSING); mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense)); - mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosRecord.MISSING); + mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosLib.MISSING); } } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java index 09e7169b..ee09ea88 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabDescent.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.app.Activity; import android.os.Bundle; @@ -112,10 +112,10 @@ public class TabDescent extends Fragment implements AltosDroidTab { } mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense)); - mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosRecord.MISSING); + mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosLib.MISSING); mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense)); - mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosRecord.MISSING); + mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosLib.MISSING); } } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java index f42b46b5..a57ae514 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabLanded.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.app.Activity; import android.os.Bundle; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java index d831f117..a4e224aa 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java @@ -19,7 +19,7 @@ package org.altusmetrum.AltosDroid; import java.util.Arrays; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java index 066c1353..f9d30b34 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabPad.java @@ -17,7 +17,7 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.app.Activity; import android.os.Bundle; @@ -104,13 +104,13 @@ public class TabPad extends Fragment implements AltosDroidTab { public void update_ui(AltosState state, AltosGreatCircle from_receiver, Location receiver) { if (state != null) { mBatteryVoltageView.setText(AltosDroid.number("%4.2f V", state.battery)); - mBatteryLights.set(state.battery > 3.7, state.battery == AltosRecord.MISSING); + mBatteryLights.set(state.battery > 3.7, state.battery == AltosLib.MISSING); mApogeeVoltageView.setText(AltosDroid.number("%4.2f V", state.drogue_sense)); - mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosRecord.MISSING); + mApogeeLights.set(state.drogue_sense > 3.2, state.drogue_sense == AltosLib.MISSING); mMainVoltageView.setText(AltosDroid.number("%4.2f V", state.main_sense)); - mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosRecord.MISSING); + mMainLights.set(state.main_sense > 3.2, state.main_sense == AltosLib.MISSING); if (state.data.flight != 0) { if (state.data.state <= AltosLib.ao_flight_pad) @@ -122,7 +122,7 @@ public class TabPad extends Fragment implements AltosDroidTab { } else { mDataLoggingView.setText("Storage full"); } - mDataLoggingLights.set(state.data.flight != 0, state.data.flight == AltosRecord.MISSING); + mDataLoggingLights.set(state.data.flight != 0, state.data.flight == AltosLib.MISSING); if (state.gps != null) { mGPSLockedView.setText(AltosDroid.integer("%4d sats", state.gps.nsat)); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java index 3ece04ac..4d793413 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryLogger.java @@ -1,6 +1,6 @@ package org.altusmetrum.AltosDroid; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import android.content.BroadcastReceiver; import android.content.Context; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java index 716ec589..e37019fd 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java @@ -25,7 +25,7 @@ import java.util.concurrent.*; import android.util.Log; import android.os.Handler; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class TelemetryReader extends Thread { diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index 940ad792..76efa749 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -44,7 +44,7 @@ import android.location.LocationManager; import android.location.LocationListener; import android.location.Criteria; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class TelemetryService extends Service implements LocationListener { diff --git a/altoslib/AltosAccel.java b/altoslib/AltosAccel.java index d02b3238..08eba359 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_1; +package org.altusmetrum.altoslib_2; public class AltosAccel extends AltosUnits { diff --git a/altoslib/AltosCRCException.java b/altoslib/AltosCRCException.java index 76e79add..be2ec4fe 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_1; +package org.altusmetrum.altoslib_2; public class AltosCRCException extends Exception { public int rssi; diff --git a/altoslib/AltosCompanion.java b/altoslib/AltosCompanion.java index 1572fdae..57bb21af 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_1; +package org.altusmetrum.altoslib_2; public class AltosCompanion { public final static int board_id_telescience = 0x0a; diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index 2ca5a7a5..d92f42c3 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_1; +package org.altusmetrum.altoslib_2; import java.util.*; import java.text.*; diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java index 027d10f4..fd5584c2 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_1; +package org.altusmetrum.altoslib_2; public interface AltosConfigValues { /* set and get all of the dialog values */ diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index cf2bc59f..760d9eb9 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -18,7 +18,7 @@ /* * Sensor data conversion functions */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosConvert { /* @@ -207,15 +207,27 @@ public class AltosConvert { } static public double mega_battery_voltage(int v_batt) { - if (v_batt != AltosRecord.MISSING) + if (v_batt != AltosLib.MISSING) return 3.3 * mega_adc(v_batt) * (15.0 + 27.0) / 27.0; - return AltosRecord.MISSING; + return AltosLib.MISSING; } static double mega_pyro_voltage(int raw) { - if (raw != AltosRecord.MISSING) + if (raw != AltosLib.MISSING) return 3.3 * mega_adc(raw) * (100.0 + 27.0) / 27.0; - return AltosRecord.MISSING; + return AltosLib.MISSING; + } + + static double tele_mini_voltage(int sensor) { + double supply = 3.3; + + return sensor / 32767.0 * supply * 127/27; + } + + static double easy_mini_voltage(int sensor) { + double supply = 3.0; + + return sensor / 32767.0 * supply * 127/27; } public static double radio_to_frequency(int freq, int setting, int cal, int channel) { diff --git a/altoslib/AltosDebug.java b/altoslib/AltosDebug.java index 4d8e3ae7..76c13d57 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java index 25028ac7..56257165 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_1; +package org.altusmetrum.altoslib_2; public class AltosDistance extends AltosUnits { diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index 3a996ae0..dd5993c7 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromBody.java b/altoslib/AltosEepromBody.java index 60aa8881..444102ce 100644 --- a/altoslib/AltosEepromBody.java +++ b/altoslib/AltosEepromBody.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromBodyIterable.java b/altoslib/AltosEepromBodyIterable.java index 33dc0ac8..4d32c66a 100644 --- a/altoslib/AltosEepromBodyIterable.java +++ b/altoslib/AltosEepromBodyIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index 1709352b..918481fa 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_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.util.concurrent.*; diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 082c23ca..f87bf916 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; @@ -100,6 +100,7 @@ public class AltosEepromFile extends AltosStateIterable { AltosState state = start.clone(); for (AltosEeprom eeprom : body) { eeprom.update_state(state); + state.finish_update(); if (state.state >= AltosLib.ao_flight_boost) { start.set_boost_tick(state.tick); break; @@ -111,8 +112,10 @@ public class AltosEepromFile extends AltosStateIterable { AltosState state = start.clone(); Iterator i = body.iterator(); - while (i.hasNext() && !state.valid()) + while (i.hasNext() && !state.valid()) { i.next().update_state(state); + state.finish_update(); + } return new AltosEepromIterator(state, i); } } \ No newline at end of file diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index f97fbbf9..43ed3392 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index 35a03a12..0aeb78dd 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromHeaderIterable.java b/altoslib/AltosEepromHeaderIterable.java index 01953f0e..920a4382 100644 --- a/altoslib/AltosEepromHeaderIterable.java +++ b/altoslib/AltosEepromHeaderIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromIterable.java b/altoslib/AltosEepromIterable.java index 1e0f7f75..fc793579 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromLog.java b/altoslib/AltosEepromLog.java index 20026c6d..95c0c3f6 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_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.util.concurrent.*; @@ -72,9 +72,9 @@ public class AltosEepromLog { for (block = in_start_block; block < in_end_block; block++) { AltosEepromChunk eechunk = new AltosEepromChunk(link, block, block == in_start_block); - for (int i = 0; i < AltosEepromChunk.chunk_size; i += AltosEepromRecord.record_length) { + for (int i = 0; i < AltosEepromChunk.chunk_size; i += AltosEepromTM.record_length) { try { - AltosEepromRecord r = new AltosEepromRecord(eechunk, i); + AltosEepromTM r = new AltosEepromTM(eechunk, i); if (r.cmd == AltosLib.AO_LOG_FLIGHT) { flight = r.b; diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index b85c04bf..7a4ee52d 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromMegaIterable.java b/altoslib/AltosEepromMegaIterable.java index 5736f937..8243aa88 100644 --- a/altoslib/AltosEepromMegaIterable.java +++ b/altoslib/AltosEepromMegaIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromMetrum.java b/altoslib/AltosEepromMetrum.java index e035e5fd..7b2fcb3c 100644 --- a/altoslib/AltosEepromMetrum.java +++ b/altoslib/AltosEepromMetrum.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index ea38edf2..c1d62c0c 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromMetrumIterable.java b/altoslib/AltosEepromMetrumIterable.java index 0387319e..de4cc919 100644 --- a/altoslib/AltosEepromMetrumIterable.java +++ b/altoslib/AltosEepromMetrumIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index e0eedb73..a09a62ce 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; @@ -42,13 +42,10 @@ public class AltosEepromMini extends AltosEeprom { public int v_batt() { return data16(10); } double voltage(AltosState state, int sensor) { - double supply; - if (state.log_format == AltosLib.AO_LOG_FORMAT_EASYMINI) - supply = 3.0; + return AltosConvert.easy_mini_voltage(sensor); else - supply = 3.3; - return sensor / 32767.0 * supply * 127/27; + return AltosConvert.tele_mini_voltage(sensor); } public void update_state(AltosState state) { diff --git a/altoslib/AltosEepromMiniIterable.java b/altoslib/AltosEepromMiniIterable.java index 495495eb..31e667d8 100644 --- a/altoslib/AltosEepromMiniIterable.java +++ b/altoslib/AltosEepromMiniIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromOldIterable.java b/altoslib/AltosEepromOldIterable.java index ef82828b..43b2362b 100644 --- a/altoslib/AltosEepromOldIterable.java +++ b/altoslib/AltosEepromOldIterable.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java deleted file mode 100644 index 70ac1113..00000000 --- a/altoslib/AltosEepromRecord.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.*; - -public class AltosEepromRecord { - public int cmd; - public int tick; - public int a; - public int b; - public String data; - public boolean tick_valid; - - public static final int record_length = 8; - - public AltosEepromRecord (AltosEepromChunk chunk, int start) throws ParseException { - - cmd = chunk.data(start); - tick_valid = true; - - tick_valid = !chunk.erased(start, record_length); - if (tick_valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x", - chunk.address + start), 0); - } else { - cmd = AltosLib.AO_LOG_INVALID; - } - - tick = chunk.data16(start + 2); - a = chunk.data16(start + 4); - b = chunk.data16(start + 6); - - data = null; - } - - public AltosEepromRecord (String line) { - tick_valid = false; - tick = 0; - a = 0; - b = 0; - data = null; - if (line == null) { - cmd = AltosLib.AO_LOG_INVALID; - data = ""; - } else { - try { - String[] tokens = line.split("\\s+"); - - if (tokens[0].length() == 1) { - if (tokens.length != 4) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } else { - cmd = tokens[0].codePointAt(0); - tick = Integer.parseInt(tokens[1],16); - tick_valid = true; - a = Integer.parseInt(tokens[2],16); - b = Integer.parseInt(tokens[3],16); - } - } else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { - cmd = AltosLib.AO_LOG_CONFIG_VERSION; - data = tokens[2]; - } else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { - cmd = AltosLib.AO_LOG_MAIN_DEPLOY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { - cmd = AltosLib.AO_LOG_APOGEE_DELAY; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { - cmd = AltosLib.AO_LOG_RADIO_CHANNEL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Callsign:")) { - cmd = AltosLib.AO_LOG_CALLSIGN; - data = tokens[1].replaceAll("\"",""); - } else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { - cmd = AltosLib.AO_LOG_ACCEL_CAL; - a = Integer.parseInt(tokens[3]); - b = Integer.parseInt(tokens[5]); - } else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { - cmd = AltosLib.AO_LOG_RADIO_CAL; - a = Integer.parseInt(tokens[2]); - } else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { - cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; - a = Integer.parseInt(tokens[3]); - } else if (tokens[0].equals("manufacturer")) { - cmd = AltosLib.AO_LOG_MANUFACTURER; - data = tokens[1]; - } else if (tokens[0].equals("product")) { - cmd = AltosLib.AO_LOG_PRODUCT; - data = tokens[1]; - } else if (tokens[0].equals("serial-number")) { - cmd = AltosLib.AO_LOG_SERIAL_NUMBER; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("log-format")) { - cmd = AltosLib.AO_LOG_LOG_FORMAT; - a = Integer.parseInt(tokens[1]); - } else if (tokens[0].equals("software-version")) { - cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; - data = tokens[1]; - } else { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } catch (NumberFormatException ne) { - cmd = AltosLib.AO_LOG_INVALID; - data = line; - } - } - } - - public AltosEepromRecord(int in_cmd, int in_tick, int in_a, int in_b) { - tick_valid = true; - cmd = in_cmd; - tick = in_tick; - a = in_a; - b = in_b; - } -} diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index 2bb9d974..a38c2dae 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosEepromTeleScience.java b/altoslib/AltosEepromTeleScience.java deleted file mode 100644 index bacd66b5..00000000 --- a/altoslib/AltosEepromTeleScience.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.*; - -public class AltosEepromTeleScience { - public int type; - public int tick; - public int tm_state; - public int tm_tick; - public int[] data; - public boolean valid; - - public static final int AO_LOG_TELESCIENCE_START = 's'; - public static final int AO_LOG_TELESCIENCE_DATA = 'd'; - - static final int max_data = 12; - public static final int record_length = 32; - - public int record_length() { return record_length; } - - public AltosEepromTeleScience (AltosEepromChunk chunk, int start) throws ParseException { - type = chunk.data(start); - - valid = !chunk.erased(start, record_length); - if (valid) { - if (AltosConvert.checksum(chunk.data, start, record_length) != 0) - throw new ParseException(String.format("invalid checksum at 0x%x", - chunk.address + start), 0); - } else { - type = AltosLib.AO_LOG_INVALID; - } - - tick = chunk.data16(start+2); - tm_tick = chunk.data16(start+4); - tm_state = chunk.data(start+6); - data = new int[max_data]; - for (int i = 0; i < max_data; i++) - data[i] = chunk.data16(start + 8 + i * 2); - } -} diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index 54c54824..9802f883 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_1; +package org.altusmetrum.altoslib_2; import java.io.File; import java.util.*; @@ -23,7 +23,7 @@ import java.util.*; public class AltosFile extends File { static String number(int n) { - if (n == AltosRecord.MISSING) + if (n == AltosLib.MISSING) return "unk"; else return String.format("%03d", n); diff --git a/altoslib/AltosFlash.java b/altoslib/AltosFlash.java index 010274b9..d8069157 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; diff --git a/altoslib/AltosFlashListener.java b/altoslib/AltosFlashListener.java index ab50b74a..777ae635 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_1; +package org.altusmetrum.altoslib_2; public interface AltosFlashListener { public void position(String label, int percent); diff --git a/altoslib/AltosFlightReader.java b/altoslib/AltosFlightReader.java index 5a415274..4a722e42 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_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.io.*; @@ -48,5 +48,5 @@ public class AltosFlightReader { public boolean has_monitor_battery() { return false; } - public double monitor_battery() { return AltosRecord.MISSING; } + public double monitor_battery() { return AltosLib.MISSING; } } diff --git a/altoslib/AltosFrequency.java b/altoslib/AltosFrequency.java index 484a2fd9..ece7525a 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_1; +package org.altusmetrum.altoslib_2; public class AltosFrequency { public double frequency; diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index a8c19e4a..1d5b0755 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -15,13 +15,14 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; +import java.util.concurrent.*; public class AltosGPS implements Cloneable { - public final static int MISSING = AltosRecord.MISSING; + public final static int MISSING = AltosLib.MISSING; public int nsat; public boolean locked; @@ -65,8 +66,8 @@ public class AltosGPS implements Cloneable { } public void ClearGPSTime() { - year = month = day = AltosRecord.MISSING; - hour = minute = second = AltosRecord.MISSING; + year = month = day = AltosLib.MISSING; + hour = minute = second = AltosLib.MISSING; } public AltosGPS(AltosTelemetryMap map) throws ParseException { @@ -91,9 +92,9 @@ public class AltosGPS implements Cloneable { second = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_SECOND, 0); ground_speed = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HORIZONTAL_SPEED, - AltosRecord.MISSING, 1/100.0); + AltosLib.MISSING, 1/100.0); course = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_COURSE, - AltosRecord.MISSING); + AltosLib.MISSING); hdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HDOP, MISSING, 1.0); vdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_VDOP, MISSING, 1.0); h_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HERROR, MISSING); @@ -107,6 +108,62 @@ public class AltosGPS implements Cloneable { } } + public boolean parse_string (String line, boolean says_done) { + String[] bits = line.split("\\s+"); + if (bits.length == 0) + return false; + if (line.startsWith("Date:")) { + if (bits.length < 2) + return false; + String[] d = bits[1].split("/"); + if (d.length < 3) + return false; + year = Integer.parseInt(d[0]) + 2000; + month = Integer.parseInt(d[1]); + day = Integer.parseInt(d[2]); + } else if (line.startsWith("Time:")) { + if (bits.length < 2) + return false; + String[] d = bits[1].split(":"); + if (d.length < 3) + return false; + hour = Integer.parseInt(d[0]); + minute = Integer.parseInt(d[1]); + second = Integer.parseInt(d[2]); + } else if (line.startsWith("Lat/Lon:")) { + if (bits.length < 3) + return false; + lat = Integer.parseInt(bits[1]) * 1.0e-7; + lon = Integer.parseInt(bits[2]) * 1.0e-7; + } else if (line.startsWith("Alt:")) { + if (bits.length < 2) + return false; + alt = Integer.parseInt(bits[1]); + } else if (line.startsWith("Flags:")) { + if (bits.length < 2) + return false; + int status = Integer.decode(bits[1]); + connected = (status & AltosLib.AO_GPS_RUNNING) != 0; + locked = (status & AltosLib.AO_GPS_VALID) != 0; + if (!says_done) + return false; + } else if (line.startsWith("Sats:")) { + if (bits.length < 2) + return false; + nsat = Integer.parseInt(bits[1]); + cc_gps_sat = new AltosGPSSat[nsat]; + for (int i = 0; i < nsat; i++) { + int svid = Integer.parseInt(bits[2+i*2]); + int cc_n0 = Integer.parseInt(bits[3+i*2]); + cc_gps_sat[i] = new AltosGPSSat(svid, cc_n0); + } + } else if (line.startsWith("done")) { + return false; + } else + return false; + return true; + } + public AltosGPS(String[] words, int i, int version) throws ParseException { AltosParse.word(words[i++], "GPS"); nsat = AltosParse.parse_int(words[i++]); @@ -212,9 +269,9 @@ public class AltosGPS implements Cloneable { } public AltosGPS() { - lat = AltosRecord.MISSING; - lon = AltosRecord.MISSING; - alt = AltosRecord.MISSING; + lat = AltosLib.MISSING; + lon = AltosLib.MISSING; + alt = AltosLib.MISSING; ClearGPSTime(); cc_gps_sat = null; } @@ -283,11 +340,37 @@ public class AltosGPS implements Cloneable { } } } else { - lat = AltosRecord.MISSING; - lon = AltosRecord.MISSING; - alt = AltosRecord.MISSING; + lat = AltosLib.MISSING; + lon = AltosLib.MISSING; + alt = AltosLib.MISSING; ClearGPSTime(); cc_gps_sat = null; } } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosGPS gps = new AltosGPS(link, config_data); + + if (gps != null) { + state.set_gps(gps, state.gps_sequence++); + return; + } + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + state.set_gps(null, 0); + } + + public AltosGPS (AltosLink link, AltosConfigData config_data) throws TimeoutException, InterruptedException { + boolean says_done = config_data.compare_version("1.0") >= 0; + link.printf("g\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) + throw new TimeoutException(); + if (!parse_string(line, says_done)) + break; + } + } } diff --git a/altoslib/AltosGPSQuery.java b/altoslib/AltosGPSQuery.java deleted file mode 100644 index deb9d201..00000000 --- a/altoslib/AltosGPSQuery.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -import java.util.concurrent.*; - -class AltosGPSQuery extends AltosGPS { - public AltosGPSQuery (AltosLink link, AltosConfigData config_data) - throws TimeoutException, InterruptedException { - boolean says_done = config_data.compare_version("1.0") >= 0; - link.printf("g\n"); - for (;;) { - String line = link.get_reply_no_dialog(5000); - if (line == null) - throw new TimeoutException(); - String[] bits = line.split("\\s+"); - if (bits.length == 0) - continue; - if (line.startsWith("Date:")) { - if (bits.length < 2) - continue; - String[] d = bits[1].split(":"); - if (d.length < 3) - continue; - year = Integer.parseInt(d[0]) + 2000; - month = Integer.parseInt(d[1]); - day = Integer.parseInt(d[2]); - continue; - } - if (line.startsWith("Time:")) { - if (bits.length < 2) - continue; - String[] d = bits[1].split("/"); - if (d.length < 3) - continue; - hour = Integer.parseInt(d[0]); - minute = Integer.parseInt(d[1]); - second = Integer.parseInt(d[2]); - continue; - } - if (line.startsWith("Lat/Lon:")) { - if (bits.length < 3) - continue; - lat = Integer.parseInt(bits[1]) * 1.0e-7; - lon = Integer.parseInt(bits[2]) * 1.0e-7; - continue; - } - if (line.startsWith("Alt:")) { - if (bits.length < 2) - continue; - alt = Integer.parseInt(bits[1]); - continue; - } - if (line.startsWith("Flags:")) { - if (bits.length < 2) - continue; - int status = Integer.decode(bits[1]); - connected = (status & AltosLib.AO_GPS_RUNNING) != 0; - locked = (status & AltosLib.AO_GPS_VALID) != 0; - if (!says_done) - break; - continue; - } - if (line.startsWith("Sats:")) { - if (bits.length < 2) - continue; - nsat = Integer.parseInt(bits[1]); - cc_gps_sat = new AltosGPSSat[nsat]; - for (int i = 0; i < nsat; i++) { - int svid = Integer.parseInt(bits[2+i*2]); - int cc_n0 = Integer.parseInt(bits[3+i*2]); - cc_gps_sat[i] = new AltosGPSSat(svid, cc_n0); - } - } - if (line.startsWith("done")) - break; - if (line.startsWith("Syntax error")) - break; - } - } -} - diff --git a/altoslib/AltosGPSSat.java b/altoslib/AltosGPSSat.java index 8714dd8a..0e17d7f2 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_1; +package org.altusmetrum.altoslib_2; public class AltosGPSSat { public int svid; diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java index 770c3c6c..2c84bf4a 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_1; +package org.altusmetrum.altoslib_2; import java.lang.Math; diff --git a/altoslib/AltosHeight.java b/altoslib/AltosHeight.java index 96f5722b..1d2e4dbc 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_1; +package org.altusmetrum.altoslib_2; public class AltosHeight extends AltosUnits { diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java index 2140228a..90352927 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.LinkedList; diff --git a/altoslib/AltosIMU.java b/altoslib/AltosIMU.java index c5ebbb16..c231dda7 100644 --- a/altoslib/AltosIMU.java +++ b/altoslib/AltosIMU.java @@ -15,7 +15,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.*; public class AltosIMU implements Cloneable { public int accel_x; @@ -26,6 +28,23 @@ public class AltosIMU implements Cloneable { public int gyro_y; public int gyro_z; + public boolean parse_string(String line) { + if (!line.startsWith("Accel:")) + return false; + + String[] items = line.split("\\s+"); + + if (items.length >= 8) { + accel_x = Integer.parseInt(items[1]); + accel_y = Integer.parseInt(items[2]); + accel_z = Integer.parseInt(items[3]); + gyro_x = Integer.parseInt(items[5]); + gyro_y = Integer.parseInt(items[6]); + gyro_z = Integer.parseInt(items[7]); + } + return true; + } + public AltosIMU clone() { AltosIMU n = new AltosIMU(); @@ -38,5 +57,38 @@ public class AltosIMU implements Cloneable { n.gyro_z = gyro_z; return n; } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosIMU imu = new AltosIMU(link); + + if (imu != null) + state.set_imu(imu); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosIMU() { + accel_x = AltosLib.MISSING; + accel_y = AltosLib.MISSING; + accel_z = AltosLib.MISSING; + + gyro_x = AltosLib.MISSING; + gyro_y = AltosLib.MISSING; + gyro_z = AltosLib.MISSING; + } + + public AltosIMU(AltosLink link) throws InterruptedException, TimeoutException { + this(); + link.printf("I\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (parse_string(line)) + break; + } + } } - \ No newline at end of file diff --git a/altoslib/AltosIMUQuery.java b/altoslib/AltosIMUQuery.java deleted file mode 100644 index 4ea5d963..00000000 --- a/altoslib/AltosIMUQuery.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -import java.util.concurrent.TimeoutException; - -class AltosIMUQuery extends AltosIMU { - - public AltosIMUQuery (AltosLink link) throws InterruptedException, TimeoutException { - link.printf("I\n"); - for (;;) { - String line = link.get_reply_no_dialog(5000); - if (line == null) { - throw new TimeoutException(); - } - if (!line.startsWith("Accel:")) - continue; - String[] items = line.split("\\s+"); - if (items.length >= 8) { - accel_x = Integer.parseInt(items[1]); - accel_y = Integer.parseInt(items[2]); - accel_z = Integer.parseInt(items[3]); - gyro_x = Integer.parseInt(items[5]); - gyro_y = Integer.parseInt(items[6]); - gyro_z = Integer.parseInt(items[7]); - } - break; - } - } -} - diff --git a/altoslib/AltosIdle.java b/altoslib/AltosIdle.java new file mode 100644 index 00000000..456a9247 --- /dev/null +++ b/altoslib/AltosIdle.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_2; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +public abstract class AltosIdle { + AltosLink link; + AltosConfigData config_data; + + public void printf(String format, Object ... arguments) { + link.printf(format, arguments); + } + + public abstract void update_state(AltosState state) throws InterruptedException, TimeoutException; + + public AltosIdle(AltosLink link, AltosConfigData config_data) { + this.link = link; + this.config_data = config_data; + } +} diff --git a/altoslib/AltosIdleFetch.java b/altoslib/AltosIdleFetch.java new file mode 100644 index 00000000..42943c07 --- /dev/null +++ b/altoslib/AltosIdleFetch.java @@ -0,0 +1,149 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_2; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +class AltosIdler { + String prefix; + int[] idlers; + + static final int idle_gps = 0; + static final int idle_imu = 1; + static final int idle_mag = 2; + static final int idle_ms5607 = 3; + static final int idle_mma655x = 4; + + + static final int idle_sensor_tm = 10; + static final int idle_sensor_metrum = 11; + static final int idle_sensor_mega = 12; + static final int idle_sensor_emini = 13; + + public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException { + for (int idler : idlers) { + AltosIdle idle = null; + switch (idler) { + case idle_gps: + AltosGPS.update_state(state, link, config_data); + break; + case idle_imu: + AltosIMU.update_state(state, link, config_data); + break; + case idle_mag: + AltosMag.update_state(state, link, config_data); + break; + case idle_ms5607: + AltosMs5607.update_state(state, link, config_data); + break; + case idle_mma655x: + AltosMma655x.update_state(state, link, config_data); + break; + case idle_sensor_tm: + AltosSensorTM.update_state(state, link, config_data); + break; + case idle_sensor_metrum: + AltosSensorMetrum.update_state(state, link, config_data); + break; + case idle_sensor_mega: + AltosSensorMega.update_state(state, link, config_data); + break; + case idle_sensor_emini: + AltosSensorEMini.update_state(state, link, config_data); + break; + } + if (idle != null) + idle.update_state(state); + } + } + + public boolean matches(AltosConfigData config_data) { + return config_data.product.startsWith(prefix); + } + + public AltosIdler(String prefix, int ... idlers) { + this.prefix = prefix; + this.idlers = idlers; + } +} + + +public class AltosIdleFetch implements AltosStateUpdate { + + static final AltosIdler[] idlers = { + + new AltosIdler("EasyMini", + AltosIdler.idle_ms5607, + AltosIdler.idle_sensor_emini), + + new AltosIdler("TeleMini-v1", + AltosIdler.idle_sensor_tm), + + new AltosIdler("TeleMini-v2", + AltosIdler.idle_ms5607, + AltosIdler.idle_sensor_tm), + + new AltosIdler("TeleMetrum-v1", + AltosIdler.idle_gps, + AltosIdler.idle_sensor_tm), + + new AltosIdler("TeleMetrum-v2", + AltosIdler.idle_gps, + AltosIdler.idle_ms5607, AltosIdler.idle_mma655x, + AltosIdler.idle_sensor_metrum), + + new AltosIdler("TeleMega", + AltosIdler.idle_gps, + AltosIdler.idle_ms5607, AltosIdler.idle_mma655x, + AltosIdler.idle_imu, AltosIdler.idle_mag, + AltosIdler.idle_sensor_mega), + }; + + AltosLink link; + + double frequency; + String callsign; + + public void update_state(AltosState state) { + try { + AltosConfigData config_data = new AltosConfigData(link); + state.set_state(AltosLib.ao_flight_startup); + state.set_serial(config_data.serial); + state.set_callsign(config_data.callsign); + state.set_ground_accel(config_data.accel_cal_plus); + state.set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus); + for (AltosIdler idler : idlers) { + if (idler.matches(config_data)) { + idler.update_state(state, link, config_data); + break; + } + } + state.set_received_time(System.currentTimeMillis()); + } catch (InterruptedException ie) { + } catch (TimeoutException te) { + } + + } + + public AltosIdleFetch(AltosLink link) { + this.link = link; + } +} diff --git a/altoslib/AltosIdleMonitor.java b/altoslib/AltosIdleMonitor.java index b3ce5b20..d858845a 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.concurrent.*; @@ -24,11 +24,13 @@ import java.util.concurrent.*; public class AltosIdleMonitor extends Thread { AltosLink link; AltosIdleMonitorListener listener; - AltosState state; + + AltosIdleFetch fetch; + boolean remote; double frequency; String callsign; - AltosState previous_state; + AltosListenerState listener_state; AltosConfigData config_data; AltosGPS gps; @@ -47,86 +49,35 @@ public class AltosIdleMonitor extends Thread { return rssi; } - boolean has_sensor_tm(AltosConfigData config_data) { - return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("TeleMini"); - } - - boolean has_sensor_mm(AltosConfigData config_data) { - return config_data.product.startsWith("TeleMega"); - } - - boolean has_gps(AltosConfigData config_data) { - return config_data.product.startsWith("TeleMetrum") || config_data.product.startsWith("TeleMega"); + void start_link() throws InterruptedException, TimeoutException { + if (remote) { + link.set_radio_frequency(frequency); + link.set_callsign(callsign); + link.start_remote(); + } else + link.flush_input(); } - AltosRecord sensor_mm(AltosConfigData config_data) throws InterruptedException, TimeoutException { - AltosRecordMM record_mm = new AltosRecordMM(); - AltosSensorMM sensor = new AltosSensorMM(link); - AltosMs5607 ms5607 = new AltosMs5607Query(link); - AltosIMU imu = new AltosIMUQuery(link); - - record_mm.accel_plus_g = config_data.accel_cal_plus; - record_mm.accel_minus_g = config_data.accel_cal_minus; - - record_mm.ground_accel = sensor.accel; - record_mm.accel = sensor.accel; - record_mm.ground_pres = ms5607.pa; - record_mm.pres = ms5607.pa; - record_mm.temp = ms5607.cc; - - record_mm.v_batt = sensor.v_batt; - record_mm.v_pyro = sensor.v_pyro; - record_mm.sense = sensor.sense; - - record_mm.imu = imu; - - return record_mm; + void stop_link() throws InterruptedException, TimeoutException { + if (remote) + link.stop_remote(); } - void update_state() throws InterruptedException, TimeoutException { - AltosRecord record = null; + void update_state(AltosState state) throws InterruptedException, TimeoutException { + boolean worked = false; try { - if (remote) { - link.set_radio_frequency(frequency); - link.set_callsign(callsign); - link.start_remote(); - } else - link.flush_input(); - config_data = new AltosConfigData(link); - - if (has_sensor_tm(config_data)) - record = new AltosSensorTM(link, config_data); - else if (has_sensor_mm(config_data)) - record = sensor_mm(config_data); - else - record = new AltosRecordNone(); - - if (has_gps(config_data)) - gps = new AltosGPSQuery(link, config_data); - - record.version = 0; - record.callsign = config_data.callsign; - record.serial = config_data.serial; - record.flight = config_data.log_available() > 0 ? 255 : 0; - record.status = 0; - record.state = AltosLib.ao_flight_idle; - record.gps = gps; - record.gps_sequence++; - state = new AltosState (record, state); + start_link(); + fetch.update_state(state); + worked = true; } finally { - if (remote) { - link.stop_remote(); - if (record != null) { - record.rssi = link.rssi(); - listener_state.battery = link.monitor_battery(); - } - } else { - if (record != null) - record.rssi = 0; + stop_link(); + if (worked) { + if (remote) + state.set_rssi(link.rssi(), 0); + listener_state.battery = link.monitor_battery(); } } - } public void set_frequency(double in_frequency) { @@ -139,10 +90,6 @@ public class AltosIdleMonitor extends Thread { link.abort_reply(); } - public void post_state() { - listener.update(state, listener_state); - } - public void abort() { if (isAlive()) { interrupt(); @@ -155,18 +102,20 @@ public class AltosIdleMonitor extends Thread { } public void run() { + AltosState state = new AltosState(); try { - for (;;) { + while (!link.has_error) { try { - update_state(); - post_state(); + link.config_data(); + update_state(state); + listener.update(state, listener_state); } catch (TimeoutException te) { } Thread.sleep(1000); } } catch (InterruptedException ie) { - link.close(); } + link.close(); } public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote) @@ -174,7 +123,7 @@ public class AltosIdleMonitor extends Thread { listener = in_listener; link = in_link; remote = in_remote; - state = null; listener_state = new AltosListenerState(); + fetch = new AltosIdleFetch(link); } } diff --git a/altoslib/AltosIdleMonitorListener.java b/altoslib/AltosIdleMonitorListener.java index 27e36dea..0b03b897 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_1; +package org.altusmetrum.altoslib_2; public interface AltosIdleMonitorListener { public void update(AltosState state, AltosListenerState listener_state); diff --git a/altoslib/AltosIgnite.java b/altoslib/AltosIgnite.java index 85905900..42169989 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.concurrent.*; diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index d6d78ca8..f8a3974a 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_1; +package org.altusmetrum.altoslib_2; import java.util.*; import java.io.*; @@ -63,6 +63,8 @@ public class AltosLib { public static final int AO_LOG_SOFTWARE_VERSION = 9999; + public final static int MISSING = 0x7fffffff; + /* Added to flag invalid records */ public static final int AO_LOG_INVALID = -1; diff --git a/altoslib/AltosLine.java b/altoslib/AltosLine.java index b3bd20f9..e5dd13fc 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_1; +package org.altusmetrum.altoslib_2; public class AltosLine { public String line; diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index 159ebfe1..b1bf525b 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.concurrent.*; @@ -32,6 +32,9 @@ public abstract class AltosLink implements Runnable { public static boolean debug = false; public static void set_debug(boolean in_debug) { debug = in_debug; } + + public boolean has_error; + LinkedList pending_output = new LinkedList(); public LinkedList> monitors = new LinkedList> ();; @@ -107,6 +110,7 @@ public abstract class AltosLink implements Runnable { if (c == ERROR) { if (debug) System.out.printf("ERROR\n"); + has_error = true; add_telem (new AltosLine()); add_reply (new AltosLine()); break; @@ -399,7 +403,7 @@ public abstract class AltosLink implements Runnable { } public double monitor_battery() { - int monitor_batt = AltosRecord.MISSING; + int monitor_batt = AltosLib.MISSING; if (config_data.has_monitor_battery()) { try { @@ -416,12 +420,13 @@ public abstract class AltosLink implements Runnable { } catch (TimeoutException te) { } } - if (monitor_batt == AltosRecord.MISSING) - return AltosRecord.MISSING; + if (monitor_batt == AltosLib.MISSING) + return AltosLib.MISSING; return AltosConvert.cc_battery_to_voltage(monitor_batt); } public AltosLink() { callsign = ""; + has_error = false; } } diff --git a/altoslib/AltosListenerState.java b/altoslib/AltosListenerState.java index 2fb4673e..01dd7afb 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_1; +package org.altusmetrum.altoslib_2; public class AltosListenerState { public int crc_errors; @@ -23,6 +23,6 @@ public class AltosListenerState { public AltosListenerState() { crc_errors = 0; - battery = AltosRecord.MISSING; + battery = AltosLib.MISSING; } } diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index 7f69bb65..17b04970 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.text.ParseException; diff --git a/altoslib/AltosMag.java b/altoslib/AltosMag.java index cb6826f3..56add8f3 100644 --- a/altoslib/AltosMag.java +++ b/altoslib/AltosMag.java @@ -15,13 +15,29 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.*; public class AltosMag implements Cloneable { public int x; public int y; public int z; + public boolean parse_string(String line) { + if (!line.startsWith("X:")) + return false; + + String[] items = line.split("\\s+"); + + if (items.length >= 6) { + x = Integer.parseInt(items[1]); + y = Integer.parseInt(items[3]); + z = Integer.parseInt(items[5]); + } + return true; + } + public AltosMag clone() { AltosMag n = new AltosMag(); @@ -30,5 +46,35 @@ public class AltosMag implements Cloneable { n.z = z; return n; } + + public AltosMag() { + x = AltosLib.MISSING; + y = AltosLib.MISSING; + z = AltosLib.MISSING; + } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosMag mag = new AltosMag(link); + + if (mag != null) + state.set_mag(mag); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosMag(AltosLink link) throws InterruptedException, TimeoutException { + this(); + link.printf("M\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (parse_string(line)) + break; + } + } } \ No newline at end of file diff --git a/altoslib/AltosMma655x.java b/altoslib/AltosMma655x.java new file mode 100644 index 00000000..8dc947db --- /dev/null +++ b/altoslib/AltosMma655x.java @@ -0,0 +1,69 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.*; + +public class AltosMma655x implements Cloneable { + + int accel; + + public boolean parse_line(String line) { + String[] items = line.split("\\s+"); + if (line.startsWith("MMA655X value:")) { + if (items.length >= 3) + accel = Integer.parseInt(items[1]); + } else + return false; + return true; + } + + public AltosMma655x() { + accel = AltosLib.MISSING; + } + + public AltosMma655x clone() { + AltosMma655x n = new AltosMma655x(); + + n.accel = accel; + return n; + } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosMma655x mma655x = new AltosMma655x(link); + + if (mma655x != null) + state.set_accel(mma655x.accel); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosMma655x(AltosLink link) throws InterruptedException, TimeoutException { + this(); + link.printf("A\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) + throw new TimeoutException(); + if (!parse_line(line)) + break; + } + } +} diff --git a/altoslib/AltosMs5607.java b/altoslib/AltosMs5607.java index 606916b7..b29fa9ae 100644 --- a/altoslib/AltosMs5607.java +++ b/altoslib/AltosMs5607.java @@ -15,7 +15,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.*; public class AltosMs5607 { public int reserved; @@ -83,10 +85,13 @@ public class AltosMs5607 { } public boolean parse_line(String line) { + System.out.printf ("parse %s\n", line); String[] items = line.split("\\s+"); if (line.startsWith("Pressure:")) { - if (items.length >= 2) + if (items.length >= 2) { raw_pres = Integer.parseInt(items[1]); + System.out.printf ("raw_pres %d\n", raw_pres); + } } else if (line.startsWith("Temperature:")) { if (items.length >= 2) raw_temp = Integer.parseInt(items[1]); @@ -94,8 +99,11 @@ public class AltosMs5607 { if (items.length >= 3) reserved = Integer.parseInt(items[2]); } else if (line.startsWith("ms5607 sens:")) { - if (items.length >= 3) + System.out.printf ("found sens length %d\n", items.length); + if (items.length >= 3) { sens = Integer.parseInt(items[2]); + System.out.printf ("sens %d\n", sens); + } } else if (line.startsWith("ms5607 off:")) { if (items.length >= 3) off = Integer.parseInt(items[2]); @@ -114,15 +122,48 @@ public class AltosMs5607 { } else if (line.startsWith("ms5607 crc:")) { if (items.length >= 3) crc = Integer.parseInt(items[2]); - } else if (line.startsWith("Altitude")) + } else if (line.startsWith("Altitude:")) { return false; + } return true; } + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosMs5607 ms5607 = new AltosMs5607(link); + + if (ms5607 != null) { + state.set_ms5607(ms5607); + return; + } + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + public AltosMs5607() { - raw_pres = AltosRecord.MISSING; - raw_temp = AltosRecord.MISSING; - pa = AltosRecord.MISSING; - cc = AltosRecord.MISSING; + raw_pres = AltosLib.MISSING; + raw_temp = AltosLib.MISSING; + pa = AltosLib.MISSING; + cc = AltosLib.MISSING; + } + + public AltosMs5607 (AltosLink link) throws InterruptedException, TimeoutException { + this(); + link.printf("c s\nB\n"); + for (;;) { + String line = link.get_reply_no_dialog(5000); + if (line == null) { + throw new TimeoutException(); + } + if (!parse_line(line)) { + System.out.printf ("stop parsing at %s\n", line); + break; + } + } + System.out.printf ("sens %d off %d tcs %d tco %d tref %d tempsens %d crc %d pres %d temp %d\n", + sens, off, tcs, tco, tref, tempsens, crc, raw_pres, raw_temp); + convert(); + System.out.printf ("pa %d cc %d\n", pa, cc); } } diff --git a/altoslib/AltosMs5607Query.java b/altoslib/AltosMs5607Query.java deleted file mode 100644 index d39dbf26..00000000 --- a/altoslib/AltosMs5607Query.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -import java.util.concurrent.TimeoutException; - -class AltosMs5607Query extends AltosMs5607 { - public AltosMs5607Query (AltosLink link) throws InterruptedException, TimeoutException { - link.printf("v\nB\n"); - for (;;) { - String line = link.get_reply_no_dialog(5000); - if (line == null) { - throw new TimeoutException(); - } - if (!parse_line(line)) - break; - } - convert(); - } -} - diff --git a/altoslib/AltosOrderedMegaRecord.java b/altoslib/AltosOrderedMegaRecord.java deleted file mode 100644 index b20a5bbd..00000000 --- a/altoslib/AltosOrderedMegaRecord.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.ParseException; - -/* - * AltosRecords with an index field so they can be sorted by tick while preserving - * the original ordering for elements with matching ticks - */ -class AltosOrderedMegaRecord extends AltosEepromMega implements Comparable { - - public int index; - - public AltosOrderedMegaRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) - throws ParseException { - super(line); - if (prev_tick_valid) { - tick |= (prev_tick & ~0xffff); - if (tick < prev_tick) { - if (prev_tick - tick > 0x8000) - tick += 0x10000; - } else { - if (tick - prev_tick > 0x8000) - tick -= 0x10000; - } - } - index = in_index; - } - - public int compareTo(AltosOrderedMegaRecord o) { - int tick_diff = tick - o.tick; - if (tick_diff != 0) - return tick_diff; - return index - o.index; - } -} diff --git a/altoslib/AltosOrderedMetrumRecord.java b/altoslib/AltosOrderedMetrumRecord.java index 02cdf1fe..cc034bff 100644 --- a/altoslib/AltosOrderedMetrumRecord.java +++ b/altoslib/AltosOrderedMetrumRecord.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.ParseException; diff --git a/altoslib/AltosOrderedMiniRecord.java b/altoslib/AltosOrderedMiniRecord.java deleted file mode 100644 index 96888941..00000000 --- a/altoslib/AltosOrderedMiniRecord.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.ParseException; - -/* - * AltosRecords with an index field so they can be sorted by tick while preserving - * the original ordering for elements with matching ticks - */ -class AltosOrderedMiniRecord extends AltosEepromMini implements Comparable { - - public int index; - - public AltosOrderedMiniRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) - throws ParseException { - super(line); - if (prev_tick_valid) { - tick |= (prev_tick & ~0xffff); - if (tick < prev_tick) { - if (prev_tick - tick > 0x8000) - tick += 0x10000; - } else { - if (tick - prev_tick > 0x8000) - tick -= 0x10000; - } - } - index = in_index; - } - - public int compareTo(AltosOrderedMiniRecord o) { - int tick_diff = tick - o.tick; - if (tick_diff != 0) - return tick_diff; - return index - o.index; - } -} diff --git a/altoslib/AltosOrderedRecord.java b/altoslib/AltosOrderedRecord.java deleted file mode 100644 index 63507d39..00000000 --- a/altoslib/AltosOrderedRecord.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -import java.text.ParseException; - -/* - * AltosRecords with an index field so they can be sorted by tick while preserving - * the original ordering for elements with matching ticks - */ -class AltosOrderedRecord extends AltosEepromRecord implements Comparable { - - public int index; - - public AltosOrderedRecord(String line, int in_index, int prev_tick, boolean prev_tick_valid) - throws ParseException { - super(line); - if (prev_tick_valid) { - tick |= (prev_tick & ~0xffff); - if (tick < prev_tick) { - if (prev_tick - tick > 0x8000) - tick += 0x10000; - } else { - if (tick - prev_tick > 0x8000) - tick -= 0x10000; - } - } - index = in_index; - } - - public AltosOrderedRecord(int in_cmd, int in_tick, int in_a, int in_b, int in_index) { - super(in_cmd, in_tick, in_a, in_b); - index = in_index; - } - - public String toString() { - return String.format("%d.%d %04x %04x %04x", - cmd, index, tick, a, b); - } - - public int compareTo(AltosOrderedRecord o) { - int tick_diff = tick - o.tick; - if (tick_diff != 0) - return tick_diff; - return index - o.index; - } -} - diff --git a/altoslib/AltosParse.java b/altoslib/AltosParse.java index 66bbeed5..ca96a8f9 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_1; +package org.altusmetrum.altoslib_2; import java.text.*; diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java index 088ca3d7..c4051f9b 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosPreferencesBackend.java b/altoslib/AltosPreferencesBackend.java index fb8a235a..1ea28b01 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_1; +package org.altusmetrum.altoslib_2; import java.io.File; diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java index 4dbb4223..0142eac8 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_1; +package org.altusmetrum.altoslib_2; import java.util.*; import java.text.*; diff --git a/altoslib/AltosRecord.java b/altoslib/AltosRecord.java deleted file mode 100644 index 0c8e1db9..00000000 --- a/altoslib/AltosRecord.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecord implements Comparable , Cloneable { - - public static final int seen_flight = 1; - public static final int seen_sensor = 2; - public static final int seen_temp_volt = 4; - public static final int seen_deploy = 8; - public static final int seen_gps_time = 16; - public static final int seen_gps_lat = 32; - public static final int seen_gps_lon = 64; - public static final int seen_companion = 128; - - public int seen; - - public final static int MISSING = 0x7fffffff; - - /* Every AltosRecord implementation provides these fields */ - - public int version; - public String callsign; - public int serial; - public int flight; - public int rssi; - public int status; - public int state; - public int tick; - - public AltosGPS gps; - public int gps_sequence; - - public double time; /* seconds since boost */ - - public int device_type; - public int config_major; - public int config_minor; - public int apogee_delay; - public int main_deploy; - public int flight_log_max; - public String firmware_version; - - public double accel_plus_g, accel_minus_g; - public double ground_accel; - public double accel; - - public AltosRecordCompanion companion; - - /* Telemetry sources have these values recorded from the flight computer */ - public double kalman_height; - public double kalman_speed; - public double kalman_acceleration; - - /* - * Abstract methods that convert record data - * to standard units: - * - * pressure: Pa - * voltage: V - * acceleration: m/s² - * speed: m/s - * height: m - * temperature: °C - */ - - public double pressure() { return MISSING; } - public double ground_pressure() { return MISSING; } - public double acceleration() { return MISSING; } - - public double altitude() { - double p = pressure(); - - if (p == MISSING) - return MISSING; - return AltosConvert.pressure_to_altitude(p); - } - - public double ground_altitude() { - double p = ground_pressure(); - - if (p == MISSING) - return MISSING; - return AltosConvert.pressure_to_altitude(p); - } - - public double height() { - double g = ground_altitude(); - double a = altitude(); - - if (g == MISSING) - return MISSING; - if (a == MISSING) - return MISSING; - return a - g; - } - - public double battery_voltage() { return MISSING; } - - public double main_voltage() { return MISSING; } - - public double drogue_voltage() { return MISSING; } - - public double temperature() { return MISSING; } - - public AltosIMU imu() { return null; } - - public AltosMag mag() { return null; } - - public String state() { - return AltosLib.state_name(state); - } - - public int compareTo(AltosRecord o) { - return tick - o.tick; - } - - public AltosRecord clone() { - AltosRecord n = new AltosRecord(); - n.copy(this); - return n; - } - - public void copy(AltosRecord old) { - seen = old.seen; - version = old.version; - callsign = old.callsign; - serial = old.serial; - flight = old.flight; - rssi = old.rssi; - status = old.status; - state = old.state; - tick = old.tick; - gps = new AltosGPS(old.gps); - gps_sequence = old.gps_sequence; - companion = old.companion; - kalman_acceleration = old.kalman_acceleration; - kalman_speed = old.kalman_speed; - kalman_height = old.kalman_height; - } - - public AltosRecord() { - seen = 0; - version = 0; - callsign = "N0CALL"; - serial = MISSING; - flight = MISSING; - rssi = 0; - status = 0; - state = AltosLib.ao_flight_startup; - tick = 0; - gps = null; - gps_sequence = 0; - companion = null; - - kalman_acceleration = MISSING; - kalman_speed = MISSING; - kalman_height = MISSING; - - accel_plus_g = MISSING; - accel_minus_g = MISSING; - - } -} diff --git a/altoslib/AltosRecordCompanion.java b/altoslib/AltosRecordCompanion.java deleted file mode 100644 index b153fb5b..00000000 --- a/altoslib/AltosRecordCompanion.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright © 2011 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordCompanion { - public final static int board_id_telescience = 0x0a; - public final static int MAX_CHANNELS = 12; - - public int tick; - public int board_id; - public int update_period; - public int channels; - public int[] companion_data; - - public AltosRecordCompanion(int in_channels) { - channels = in_channels; - if (channels < 0) - channels = 0; - if (channels > MAX_CHANNELS) - channels = MAX_CHANNELS; - companion_data = new int[channels]; - } -} diff --git a/altoslib/AltosRecordIterable.java b/altoslib/AltosRecordIterable.java deleted file mode 100644 index 62dbdfe3..00000000 --- a/altoslib/AltosRecordIterable.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright © 2010 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -import java.io.*; -import java.util.*; - -public abstract class AltosRecordIterable implements Iterable { - public abstract Iterator iterator(); - public void write_comments(PrintStream out) { } - public boolean has_accel() { return false; } - public boolean has_gps() { return false; } - public boolean has_ignite() { return false; }; -} diff --git a/altoslib/AltosRecordMM.java b/altoslib/AltosRecordMM.java deleted file mode 100644 index d697111c..00000000 --- a/altoslib/AltosRecordMM.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordMM extends AltosRecord { - - /* Sensor values */ - public int accel; - public int pres; - public int temp; - - public int v_batt; - public int v_pyro; - public int sense[]; - - public int ground_accel; - public int ground_pres; - public int accel_plus_g; - public int accel_minus_g; - - public int flight_accel; - public int flight_vel; - public int flight_pres; - - public final static int num_sense = 6; - - public AltosIMU imu; - public AltosMag mag; - - static double adc(int raw) { - return raw / 4095.0; - } - - public double pressure() { - if (pres != MISSING) - return pres; - return MISSING; - } - - public double ground_pressure() { - if (ground_pres != MISSING) - return ground_pres; - return MISSING; - } - - public double battery_voltage() { - if (v_batt != MISSING) - return 3.3 * adc(v_batt) * (15.0 + 27.0) / 27.0; - return MISSING; - } - - static double pyro(int raw) { - if (raw != MISSING) - return 3.3 * adc(raw) * (100.0 + 27.0) / 27.0; - return MISSING; - } - - public double main_voltage() { - return pyro(sense[5]); - } - - public double drogue_voltage() { - return pyro(sense[4]); - } - - public double temperature() { - if (temp != MISSING) - return temp / 100.0; - return MISSING; - } - - public AltosIMU imu() { return imu; } - - public AltosMag mag() { return mag; } - - double accel_counts_per_mss() { - double counts_per_g = Math.abs(accel_minus_g - accel_plus_g) / 2; - - return counts_per_g / 9.80665; - } - - public double acceleration() { - if (ground_accel == MISSING || accel == MISSING) - return MISSING; - - if (accel_minus_g == MISSING || accel_plus_g == MISSING) - return MISSING; - - return (ground_accel - accel) / accel_counts_per_mss(); - } - - public void copy (AltosRecordMM old) { - super.copy(old); - - accel = old.accel; - pres = old.pres; - temp = old.temp; - - v_batt = old.v_batt; - v_pyro = old.v_pyro; - sense = new int[num_sense]; - - for (int i = 0; i < num_sense; i++) - sense[i] = old.sense[i]; - - ground_accel = old.ground_accel; - ground_pres = old.ground_pres; - accel_plus_g = old.accel_plus_g; - accel_minus_g = old.accel_minus_g; - - flight_accel = old.flight_accel; - flight_vel = old.flight_vel; - flight_pres = old.flight_pres; - - imu = old.imu; - mag = old.mag; - } - - - - public AltosRecordMM clone() { - return new AltosRecordMM(this); - } - - void make_missing() { - - accel = MISSING; - pres = MISSING; - temp = MISSING; - - v_batt = MISSING; - v_pyro = MISSING; - sense = new int[num_sense]; - for (int i = 0; i < num_sense; i++) - sense[i] = MISSING; - - ground_accel = MISSING; - ground_pres = MISSING; - accel_plus_g = MISSING; - accel_minus_g = MISSING; - - flight_accel = 0; - flight_vel = 0; - flight_pres = 0; - - imu = new AltosIMU(); - mag = new AltosMag(); - } - - public AltosRecordMM(AltosRecord old) { - super.copy(old); - make_missing(); - } - - public AltosRecordMM(AltosRecordMM old) { - copy(old); - } - - public AltosRecordMM() { - super(); - make_missing(); - } -} diff --git a/altoslib/AltosRecordMini.java b/altoslib/AltosRecordMini.java deleted file mode 100644 index dacd89b8..00000000 --- a/altoslib/AltosRecordMini.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordMini extends AltosRecord { - - /* Sensor values */ - public int pres; - public int temp; - - public int sense_a; - public int sense_m; - public int v_batt; - - public int ground_pres; - - public int flight_accel; - public int flight_vel; - public int flight_height; - - public int flight_pres; - - static double adc(int raw) { - return raw / 4095.0; - } - - public double pressure() { - if (pres != MISSING) - return pres; - return MISSING; - } - - public double temperature() { - if (temp != MISSING) - return temp; - return MISSING; - } - - public double ground_pressure() { - if (ground_pres != MISSING) - return ground_pres; - return MISSING; - } - - public double battery_voltage() { - if (v_batt != MISSING) - return 3.3 * adc(v_batt) * (15.0 + 27.0) / 27.0; - return MISSING; - } - - static double pyro(int raw) { - if (raw != MISSING) - return 3.3 * adc(raw) * (100.0 + 27.0) / 27.0; - return MISSING; - } - - public double main_voltage() { - return pyro(sense_m); - } - - public double apogee_voltage() { - return pyro(sense_a); - } - - public void copy (AltosRecordMini old) { - super.copy(old); - - pres = old.pres; - temp = old.temp; - - sense_a = old.sense_a; - sense_m = old.sense_m; - v_batt = old.v_batt; - - ground_pres = old.ground_pres; - - flight_accel = old.flight_accel; - flight_vel = old.flight_vel; - flight_height = old.flight_height; - flight_pres = old.flight_pres; - } - - - - public AltosRecordMini clone() { - return new AltosRecordMini(this); - } - - void make_missing() { - - pres = MISSING; - - sense_a = MISSING; - sense_m = MISSING; - v_batt = MISSING; - - ground_pres = MISSING; - - flight_accel = 0; - flight_vel = 0; - flight_height = 0; - flight_pres = 0; - } - - public AltosRecordMini(AltosRecord old) { - super.copy(old); - make_missing(); - } - - public AltosRecordMini(AltosRecordMini old) { - copy(old); - } - - public AltosRecordMini() { - super(); - make_missing(); - } -} diff --git a/altoslib/AltosRecordNone.java b/altoslib/AltosRecordNone.java deleted file mode 100644 index a95b6a9c..00000000 --- a/altoslib/AltosRecordNone.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordNone extends AltosRecord { - - public double pressure() { return MISSING; } - public double ground_pressure() { return MISSING; } - public double temperature() { return MISSING; } - public double acceleration() { return MISSING; } - - public AltosRecordNone(AltosRecord old) { - super.copy(old); - } - - public AltosRecordNone clone() { - return new AltosRecordNone(this); - } - - public AltosRecordNone() { - super(); - } -} diff --git a/altoslib/AltosRecordTM.java b/altoslib/AltosRecordTM.java deleted file mode 100644 index c6cf3646..00000000 --- a/altoslib/AltosRecordTM.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright © 2012 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -package org.altusmetrum.altoslib_1; - -public class AltosRecordTM extends AltosRecord { - - /* Sensor values */ - public int accel; - public int pres; - public int temp; - public int batt; - public int drogue; - public int main; - - public int ground_accel; - public int ground_pres; - public int accel_plus_g; - public int accel_minus_g; - - public int flight_accel; - public int flight_vel; - public int flight_pres; - - /* - * Values for our MP3H6115A pressure sensor - * - * From the data sheet: - * - * Pressure range: 15-115 kPa - * Voltage at 115kPa: 2.82 - * Output scale: 27mV/kPa - * - * - * 27 mV/kPa * 2047 / 3300 counts/mV = 16.75 counts/kPa - * 2.82V * 2047 / 3.3 counts/V = 1749 counts/115 kPa - */ - - static final double counts_per_kPa = 27 * 2047 / 3300; - static final double counts_at_101_3kPa = 1674.0; - - static double - barometer_to_pressure(double count) - { - return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0; - } - - public double pressure() { - if (pres == MISSING) - return MISSING; - return barometer_to_pressure(pres); - } - - public double ground_pressure() { - if (ground_pres == MISSING) - return MISSING; - return barometer_to_pressure(ground_pres); - } - - public double battery_voltage() { - if (batt == MISSING) - return MISSING; - return AltosConvert.cc_battery_to_voltage(batt); - } - - public double main_voltage() { - if (main == MISSING) - return MISSING; - return AltosConvert.cc_ignitor_to_voltage(main); - } - - public double drogue_voltage() { - if (drogue == MISSING) - return MISSING; - return AltosConvert.cc_ignitor_to_voltage(drogue); - } - - /* Value for the CC1111 built-in temperature sensor - * Output voltage at 0°C = 0.755V - * Coefficient = 0.00247V/°C - * Reference voltage = 1.25V - * - * temp = ((value / 32767) * 1.25 - 0.755) / 0.00247 - * = (value - 19791.268) / 32768 * 1.25 / 0.00247 - */ - - static double - thermometer_to_temperature(double thermo) - { - return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; - } - - public double temperature() { - if (temp == MISSING) - return MISSING; - return thermometer_to_temperature(temp); - } - - double accel_counts_per_mss() { - double counts_per_g = Math.abs(accel_minus_g - accel_plus_g) / 2; - - return counts_per_g / 9.80665; - } - - public double acceleration() { - if (ground_accel == MISSING || accel == MISSING) - return MISSING; - return (ground_accel - accel) / accel_counts_per_mss(); - } - - public void copy(AltosRecordTM old) { - super.copy(old); - - version = old.version; - callsign = old.callsign; - serial = old.serial; - flight = old.flight; - rssi = old.rssi; - status = old.status; - state = old.state; - tick = old.tick; - accel = old.accel; - pres = old.pres; - temp = old.temp; - batt = old.batt; - drogue = old.drogue; - main = old.main; - flight_accel = old.flight_accel; - ground_accel = old.ground_accel; - flight_vel = old.flight_vel; - flight_pres = old.flight_pres; - ground_pres = old.ground_pres; - accel_plus_g = old.accel_plus_g; - accel_minus_g = old.accel_minus_g; - } - - public AltosRecordTM clone() { - return new AltosRecordTM(this); - } - - void make_missing() { - accel = MISSING; - pres = MISSING; - temp = MISSING; - batt = MISSING; - drogue = MISSING; - main = MISSING; - - flight_accel = MISSING; - flight_vel = MISSING; - flight_pres = MISSING; - - ground_accel = MISSING; - ground_pres = MISSING; - accel_plus_g = MISSING; - accel_minus_g = MISSING; - } - - public AltosRecordTM(AltosRecord old) { - super.copy(old); - make_missing(); - } - - public AltosRecordTM(AltosRecordTM old) { - copy(old); - } - - public AltosRecordTM() { - super(); - make_missing(); - } -} diff --git a/altoslib/AltosRecordTM2.java b/altoslib/AltosRecordTM2.java index 0cd54f2c..da2d948c 100644 --- a/altoslib/AltosRecordTM2.java +++ b/altoslib/AltosRecordTM2.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosRecordTM2 extends AltosRecord { diff --git a/altoslib/AltosReplayReader.java b/altoslib/AltosReplayReader.java index 0c14dee4..f65caaa0 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java index 0800a2c4..e9d3147e 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java index 07917d5d..0ae797a0 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; diff --git a/altoslib/AltosSensorEMini.java b/altoslib/AltosSensorEMini.java new file mode 100644 index 00000000..cbc65143 --- /dev/null +++ b/altoslib/AltosSensorEMini.java @@ -0,0 +1,70 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.TimeoutException; + +public class AltosSensorEMini { + public int tick; + public int apogee; + public int main; + public int batt; + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosSensorEMini sensor_emini = new AltosSensorEMini(link); + + 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)); + + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } + + public AltosSensorEMini(AltosLink link) throws InterruptedException, TimeoutException { + String[] items = link.adc(); + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("apogee:")) { + apogee = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("main:")) { + main = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("batt:")) { + batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + } +} + diff --git a/altoslib/AltosSensorMM.java b/altoslib/AltosSensorMM.java index 6d1b61c0..0ef42cf6 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_1; +package org.altusmetrum.altoslib_2; import java.util.concurrent.TimeoutException; diff --git a/altoslib/AltosSensorMega.java b/altoslib/AltosSensorMega.java new file mode 100644 index 00000000..3afb8a64 --- /dev/null +++ b/altoslib/AltosSensorMega.java @@ -0,0 +1,109 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_2; + +import java.util.concurrent.TimeoutException; + +class AltosSensorMega { + int tick; + int[] sense; + int v_batt; + int v_pbatt; + int temp; + + public AltosSensorMega() { + sense = new int[6]; + } + + public AltosSensorMega(AltosLink link) throws InterruptedException, TimeoutException { + this(); + String[] items = link.adc(); + for (int i = 0; i < items.length;) { + if (items[i].equals("tick:")) { + tick = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("A:")) { + sense[0] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("B:")) { + sense[1] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("C:")) { + sense[2] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("D:")) { + sense[3] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("drogue:")) { + sense[4] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("main:")) { + sense[5] = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("batt:")) { + v_batt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("pbatt:")) { + v_pbatt = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + if (items[i].equals("temp:")) { + temp = Integer.parseInt(items[i+1]); + i += 2; + continue; + } + i++; + } + } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosSensorMega sensor_mega = new AltosSensorMega(link); + + state.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_mega.v_batt)); + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[4])); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[5])); + + double[] ignitor_voltage = new double[4]; + for (int i = 0; i < 4; i++) + ignitor_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]); + state.set_ignitor_voltage(ignitor_voltage); + + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } +} + diff --git a/altoslib/AltosSensorMetrum.java b/altoslib/AltosSensorMetrum.java index 686c78a8..4a51d492 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_1; +package org.altusmetrum.altoslib_2; import java.util.concurrent.TimeoutException; @@ -51,5 +51,16 @@ class AltosSensorMetrum { i++; } } + + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosSensorMetrum sensor_metrum = new AltosSensorMetrum(link); + state.set_battery_voltage(AltosConvert.mega_battery_voltage(sensor_metrum.v_batt)); + state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_a)); + state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_metrum.sense_m)); + } catch (TimeoutException te) { + } catch (InterruptedException ie) { + } + } } diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java index 754dc5bb..2696a308 100644 --- a/altoslib/AltosSensorTM.java +++ b/altoslib/AltosSensorTM.java @@ -15,14 +15,38 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.util.concurrent.TimeoutException; -class AltosSensorTM extends AltosRecordTM { +public class AltosSensorTM { + public int tick; + public int accel; + public int pres; + public int temp; + public int batt; + public int drogue; + public int main; - public AltosSensorTM(AltosLink link, AltosConfigData config_data) throws InterruptedException, TimeoutException { - super(); + static public void update_state(AltosState state, AltosLink link, AltosConfigData config_data) { + try { + AltosSensorTM sensor_tm = new AltosSensorTM(link); + + if (sensor_tm == null) + return; + state.set_accel(sensor_tm.accel); + state.set_pressure(AltosConvert.barometer_to_pressure(sensor_tm.pres)); + state.set_temperature(AltosConvert.thermometer_to_temperature(sensor_tm.temp)); + 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) { + } catch (InterruptedException ie) { + } + } + + public AltosSensorTM(AltosLink link) throws InterruptedException, TimeoutException { String[] items = link.adc(); for (int i = 0; i < items.length;) { if (items[i].equals("tick:")) { @@ -62,10 +86,6 @@ class AltosSensorTM extends AltosRecordTM { } i++; } - ground_accel = config_data.accel_cal_plus; - ground_pres = pres; - accel_plus_g = config_data.accel_cal_plus; - accel_minus_g = config_data.accel_cal_minus; } } diff --git a/altoslib/AltosSpeed.java b/altoslib/AltosSpeed.java index 6fb624fb..9b9f7240 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_1; +package org.altusmetrum.altoslib_2; public class AltosSpeed extends AltosUnits { diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 1c400bab..dba9bff8 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -19,10 +19,9 @@ * Track flight state from telemetry or eeprom data stream */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosState implements Cloneable { - public AltosRecord record; public static final int set_position = 1; public static final int set_gps = 2; @@ -53,9 +52,9 @@ public class AltosState implements Cloneable { private double max_rate = 1000.0; void set(double new_value, double time) { - if (new_value != AltosRecord.MISSING) { + if (new_value != AltosLib.MISSING) { value = new_value; - if (max_value == AltosRecord.MISSING || value > max_value) { + if (max_value == AltosLib.MISSING || value > max_value) { max_value = value; } set_time = time; @@ -63,7 +62,7 @@ public class AltosState implements Cloneable { } void set_filtered(double new_value, double time) { - if (prev_value != AltosRecord.MISSING) + if (prev_value != AltosLib.MISSING) new_value = (prev_value * 15.0 + new_value) / 16.0; set(new_value, time); } @@ -81,25 +80,25 @@ public class AltosState implements Cloneable { } double change() { - if (value != AltosRecord.MISSING && prev_value != AltosRecord.MISSING) + if (value != AltosLib.MISSING && prev_value != AltosLib.MISSING) return value - prev_value; - return AltosRecord.MISSING; + return AltosLib.MISSING; } double rate() { double c = change(); double t = set_time - prev_set_time; - if (c != AltosRecord.MISSING && t != 0) + if (c != AltosLib.MISSING && t != 0) return c / t; - return AltosRecord.MISSING; + return AltosLib.MISSING; } double integrate() { - if (value == AltosRecord.MISSING) - return AltosRecord.MISSING; - if (prev_value == AltosRecord.MISSING) - return AltosRecord.MISSING; + if (value == AltosLib.MISSING) + return AltosLib.MISSING; + if (prev_value == AltosLib.MISSING) + return AltosLib.MISSING; return (value + prev_value) / 2 * (set_time - prev_set_time); } @@ -111,13 +110,13 @@ public class AltosState implements Cloneable { void set_derivative(AltosValue in) { double n = in.rate(); - if (n == AltosRecord.MISSING) + if (n == AltosLib.MISSING) return; double p = prev_value; double pt = prev_set_time; - if (p == AltosRecord.MISSING) { + if (p == AltosLib.MISSING) { p = 0; pt = in.time() - 0.01; } @@ -150,9 +149,9 @@ public class AltosState implements Cloneable { void set_integral(AltosValue in) { double change = in.integrate(); - if (change != AltosRecord.MISSING) { + if (change != AltosLib.MISSING) { double prev = prev_value; - if (prev == AltosRecord.MISSING) + if (prev == AltosLib.MISSING) prev = 0; set(prev + change, in.time()); } @@ -166,10 +165,15 @@ public class AltosState implements Cloneable { max_value = old.max_value; } + void finish_update() { + prev_value = value; + prev_set_time = set_time; + } + AltosValue() { - value = AltosRecord.MISSING; - prev_value = AltosRecord.MISSING; - max_value = AltosRecord.MISSING; + value = AltosLib.MISSING; + prev_value = AltosLib.MISSING; + max_value = AltosLib.MISSING; } } @@ -179,45 +183,45 @@ public class AltosState implements Cloneable { double value() { double v = measured.value(); - if (v != AltosRecord.MISSING) + if (v != AltosLib.MISSING) return v; return computed.value(); } boolean is_measured() { - return measured.value() != AltosRecord.MISSING; + return measured.value() != AltosLib.MISSING; } double max() { double m = measured.max(); - if (m != AltosRecord.MISSING) + if (m != AltosLib.MISSING) return m; return computed.max(); } double prev_value() { - if (measured.value != AltosRecord.MISSING && measured.prev_value != AltosRecord.MISSING) + if (measured.value != AltosLib.MISSING && measured.prev_value != AltosLib.MISSING) return measured.prev_value; return computed.prev_value; } AltosValue altos_value() { - if (measured.value() != AltosRecord.MISSING) + if (measured.value() != AltosLib.MISSING) return measured; return computed; } double change() { double c = measured.change(); - if (c == AltosRecord.MISSING) + if (c == AltosLib.MISSING) c = computed.change(); return c; } double rate() { double r = measured.rate(); - if (r == AltosRecord.MISSING) + if (r == AltosLib.MISSING) r = computed.rate(); return r; } @@ -251,6 +255,11 @@ public class AltosState implements Cloneable { computed.copy(old.computed); } + void finish_update() { + measured.finish_update(); + computed.finish_update(); + } + AltosCValue() { measured = new AltosValue(); computed = new AltosValue(); @@ -273,8 +282,8 @@ public class AltosState implements Cloneable { public int flight_log_max; private double pressure_to_altitude(double p) { - if (p == AltosRecord.MISSING) - return AltosRecord.MISSING; + if (p == AltosLib.MISSING) + return AltosLib.MISSING; return AltosConvert.pressure_to_altitude(p); } @@ -334,18 +343,18 @@ public class AltosState implements Cloneable { public double altitude() { double a = altitude.value(); - if (a != AltosRecord.MISSING) + if (a != AltosLib.MISSING) return a; if (gps != null) return gps.alt; - return AltosRecord.MISSING; + return AltosLib.MISSING; } public double max_altitude() { double a = altitude.max(); - if (a != AltosRecord.MISSING) + if (a != AltosLib.MISSING) return a; - return AltosRecord.MISSING; + return AltosLib.MISSING; } public void set_altitude(double new_altitude) { @@ -374,26 +383,26 @@ public class AltosState implements Cloneable { public double height() { double k = kalman_height.value(); - if (k != AltosRecord.MISSING) + if (k != AltosLib.MISSING) return k; double a = altitude(); double g = ground_altitude(); - if (a != AltosRecord.MISSING && g != AltosRecord.MISSING) + if (a != AltosLib.MISSING && g != AltosLib.MISSING) return a - g; - return AltosRecord.MISSING; + return AltosLib.MISSING; } public double max_height() { double k = kalman_height.max(); - if (k != AltosRecord.MISSING) + if (k != AltosLib.MISSING) return k; double a = altitude.max(); double g = ground_altitude(); - if (a != AltosRecord.MISSING && g != AltosRecord.MISSING) + if (a != AltosLib.MISSING && g != AltosLib.MISSING) return a - g; - return AltosRecord.MISSING; + return AltosLib.MISSING; } class AltosSpeed extends AltosCValue { @@ -421,10 +430,16 @@ public class AltosState implements Cloneable { private AltosSpeed speed; public double speed() { + double v = kalman_speed.value(); + if (v != AltosLib.MISSING) + return v; return speed.value(); } public double max_speed() { + double v = kalman_speed.max(); + if (v != AltosLib.MISSING) + return v; return speed.max(); } @@ -503,7 +518,7 @@ public class AltosState implements Cloneable { public AltosMs5607 baro; - public AltosRecordCompanion companion; + public AltosCompanion companion; public void set_npad(int npad) { this.npad = npad; @@ -514,29 +529,27 @@ public class AltosState implements Cloneable { } public void init() { - record = null; - set = 0; received_time = System.currentTimeMillis(); - time = AltosRecord.MISSING; - time_change = AltosRecord.MISSING; - prev_time = AltosRecord.MISSING; - tick = AltosRecord.MISSING; - prev_tick = AltosRecord.MISSING; - boost_tick = AltosRecord.MISSING; + time = AltosLib.MISSING; + time_change = AltosLib.MISSING; + prev_time = AltosLib.MISSING; + tick = AltosLib.MISSING; + prev_tick = AltosLib.MISSING; + boost_tick = AltosLib.MISSING; state = AltosLib.ao_flight_invalid; - flight = AltosRecord.MISSING; + flight = AltosLib.MISSING; landed = false; boost = false; - rssi = AltosRecord.MISSING; + rssi = AltosLib.MISSING; status = 0; - device_type = AltosRecord.MISSING; - config_major = AltosRecord.MISSING; - config_minor = AltosRecord.MISSING; - apogee_delay = AltosRecord.MISSING; - main_deploy = AltosRecord.MISSING; - flight_log_max = AltosRecord.MISSING; + device_type = AltosLib.MISSING; + config_major = AltosLib.MISSING; + config_minor = AltosLib.MISSING; + apogee_delay = AltosLib.MISSING; + main_deploy = AltosLib.MISSING; + flight_log_max = AltosLib.MISSING; ground_altitude = new AltosCValue(); ground_pressure = new AltosGroundPressure(); @@ -545,11 +558,11 @@ public class AltosState implements Cloneable { speed = new AltosSpeed(); acceleration = new AltosAccel(); - temperature = AltosRecord.MISSING; - battery_voltage = AltosRecord.MISSING; - pyro_voltage = AltosRecord.MISSING; - apogee_voltage = AltosRecord.MISSING; - main_voltage = AltosRecord.MISSING; + temperature = AltosLib.MISSING; + battery_voltage = AltosLib.MISSING; + pyro_voltage = AltosLib.MISSING; + apogee_voltage = AltosLib.MISSING; + main_voltage = AltosLib.MISSING; ignitor_voltage = null; kalman_height = new AltosValue(); @@ -569,36 +582,48 @@ public class AltosState implements Cloneable { ngps = 0; from_pad = null; - elevation = AltosRecord.MISSING; - range = AltosRecord.MISSING; - gps_height = AltosRecord.MISSING; + elevation = AltosLib.MISSING; + range = AltosLib.MISSING; + gps_height = AltosLib.MISSING; - pad_lat = AltosRecord.MISSING; - pad_lon = AltosRecord.MISSING; - pad_alt = AltosRecord.MISSING; + pad_lat = AltosLib.MISSING; + pad_lon = AltosLib.MISSING; + pad_alt = AltosLib.MISSING; - speak_tick = AltosRecord.MISSING; - speak_altitude = AltosRecord.MISSING; + speak_tick = AltosLib.MISSING; + speak_altitude = AltosLib.MISSING; callsign = null; - accel_plus_g = AltosRecord.MISSING; - accel_minus_g = AltosRecord.MISSING; - accel = AltosRecord.MISSING; + accel_plus_g = AltosLib.MISSING; + accel_minus_g = AltosLib.MISSING; + accel = AltosLib.MISSING; - ground_accel = AltosRecord.MISSING; - ground_accel_avg = AltosRecord.MISSING; + ground_accel = AltosLib.MISSING; + ground_accel_avg = AltosLib.MISSING; - log_format = AltosRecord.MISSING; - serial = AltosRecord.MISSING; + log_format = AltosLib.MISSING; + serial = AltosLib.MISSING; baro = null; companion = null; } - void copy(AltosState old) { + void finish_update() { + prev_tick = tick; - record = null; + ground_altitude.finish_update(); + altitude.finish_update(); + pressure.finish_update(); + speed.finish_update(); + acceleration.finish_update(); + + kalman_height.finish_update(); + kalman_speed.finish_update(); + kalman_acceleration.finish_update(); + } + + void copy(AltosState old) { if (old == null) { init(); @@ -718,25 +743,25 @@ public class AltosState implements Cloneable { /* Track consecutive 'good' gps reports, waiting for 10 of them */ if (state == AltosLib.ao_flight_pad) { set_npad(npad+1); - if (pad_lat != AltosRecord.MISSING) { + if (pad_lat != AltosLib.MISSING) { pad_lat = (pad_lat * 31 + gps.lat) / 32; pad_lon = (pad_lon * 31 + gps.lon) / 32; pad_alt = (pad_alt * 31 + gps.alt) / 32; } } - if (pad_lat == AltosRecord.MISSING) { + if (pad_lat == AltosLib.MISSING) { pad_lat = gps.lat; pad_lon = gps.lon; pad_alt = gps.alt; } } if (gps.lat != 0 && gps.lon != 0 && - pad_lat != AltosRecord.MISSING && - pad_lon != AltosRecord.MISSING) + pad_lat != AltosLib.MISSING && + pad_lon != AltosLib.MISSING) { double h = height(); - if (h == AltosRecord.MISSING) + if (h == AltosLib.MISSING) h = 0; from_pad = new AltosGreatCircle(pad_lat, pad_lon, 0, gps.lat, gps.lon, h); elevation = from_pad.elevation; @@ -746,9 +771,9 @@ public class AltosState implements Cloneable { } public void set_tick(int new_tick) { - if (new_tick != AltosRecord.MISSING) { - if (prev_tick != AltosRecord.MISSING) { - while (new_tick < prev_tick - 32767) { + if (new_tick != AltosLib.MISSING) { + if (prev_tick != AltosLib.MISSING) { + while (new_tick < prev_tick - 1000) { new_tick += 65536; } } @@ -758,7 +783,7 @@ public class AltosState implements Cloneable { } public void set_boost_tick(int boost_tick) { - if (boost_tick != AltosRecord.MISSING) + if (boost_tick != AltosLib.MISSING) this.boost_tick = boost_tick; } @@ -799,8 +824,8 @@ public class AltosState implements Cloneable { public void set_flight(int flight) { /* When the flight changes, reset the state */ - if (flight != AltosRecord.MISSING) { - if (this.flight != AltosRecord.MISSING && + if (flight != AltosLib.MISSING && flight != 0) { + if (this.flight != AltosLib.MISSING && this.flight != flight) { init(); } @@ -810,8 +835,8 @@ public class AltosState implements Cloneable { public void set_serial(int serial) { /* When the serial changes, reset the state */ - if (serial != AltosRecord.MISSING) { - if (this.serial != AltosRecord.MISSING && + if (serial != AltosLib.MISSING) { + if (this.serial != AltosLib.MISSING && this.serial != serial) { init(); } @@ -820,13 +845,13 @@ public class AltosState implements Cloneable { } public int rssi() { - if (rssi == AltosRecord.MISSING) + if (rssi == AltosLib.MISSING) return 0; return rssi; } public void set_rssi(int rssi, int status) { - if (rssi != AltosRecord.MISSING) { + if (rssi != AltosLib.MISSING) { this.rssi = rssi; this.status = status; } @@ -845,9 +870,29 @@ public class AltosState implements Cloneable { } } - public void make_baro() { + public void set_imu(AltosIMU imu) { + if (imu != null) + imu = imu.clone(); + this.imu = imu; + } + + public void set_mag(AltosMag mag) { + this.mag = mag.clone(); + } + + public AltosMs5607 make_baro() { if (baro == null) baro = new AltosMs5607(); + return baro; + } + + public void set_ms5607(AltosMs5607 ms5607) { + baro = ms5607; + + if (baro != null) { + set_pressure(baro.pa); + set_temperature(baro.cc / 100.0); + } } public void set_ms5607(int pres, int temp) { @@ -861,25 +906,25 @@ public class AltosState implements Cloneable { public void make_companion (int nchannels) { if (companion == null) - companion = new AltosRecordCompanion(nchannels); + companion = new AltosCompanion(nchannels); } - public void set_companion(AltosRecordCompanion companion) { + public void set_companion(AltosCompanion companion) { this.companion = companion; } void update_accel() { double ground = ground_accel; - if (ground == AltosRecord.MISSING) + if (ground == AltosLib.MISSING) ground = ground_accel_avg; - if (accel == AltosRecord.MISSING) + if (accel == AltosLib.MISSING) return; - if (ground == AltosRecord.MISSING) + if (ground == AltosLib.MISSING) return; - if (accel_plus_g == AltosRecord.MISSING) + if (accel_plus_g == AltosLib.MISSING) return; - if (accel_minus_g == AltosRecord.MISSING) + if (accel_minus_g == AltosLib.MISSING) return; double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; @@ -888,7 +933,7 @@ public class AltosState implements Cloneable { } public void set_accel_g(double accel_plus_g, double accel_minus_g) { - if (accel_plus_g != AltosRecord.MISSING) { + if (accel_plus_g != AltosLib.MISSING) { this.accel_plus_g = accel_plus_g; this.accel_minus_g = accel_minus_g; update_accel(); @@ -896,17 +941,17 @@ public class AltosState implements Cloneable { } public void set_ground_accel(double ground_accel) { - if (ground_accel != AltosRecord.MISSING) { + if (ground_accel != AltosLib.MISSING) { this.ground_accel = ground_accel; update_accel(); } } public void set_accel(double accel) { - if (accel != AltosRecord.MISSING) { + if (accel != AltosLib.MISSING) { this.accel = accel; if (state == AltosLib.ao_flight_pad) { - if (ground_accel_avg == AltosRecord.MISSING) + if (ground_accel_avg == AltosLib.MISSING) ground_accel_avg = accel; else ground_accel_avg = (ground_accel_avg * 7 + accel) / 8; @@ -916,35 +961,35 @@ public class AltosState implements Cloneable { } public void set_temperature(double temperature) { - if (temperature != AltosRecord.MISSING) { + if (temperature != AltosLib.MISSING) { this.temperature = temperature; set |= set_data; } } public void set_battery_voltage(double battery_voltage) { - if (battery_voltage != AltosRecord.MISSING) { + if (battery_voltage != AltosLib.MISSING) { this.battery_voltage = battery_voltage; set |= set_data; } } public void set_pyro_voltage(double pyro_voltage) { - if (pyro_voltage != AltosRecord.MISSING) { + if (pyro_voltage != AltosLib.MISSING) { this.pyro_voltage = pyro_voltage; set |= set_data; } } public void set_apogee_voltage(double apogee_voltage) { - if (apogee_voltage != AltosRecord.MISSING) { + if (apogee_voltage != AltosLib.MISSING) { this.apogee_voltage = apogee_voltage; set |= set_data; } } public void set_main_voltage(double main_voltage) { - if (main_voltage != AltosRecord.MISSING) { + if (main_voltage != AltosLib.MISSING) { this.main_voltage = main_voltage; set |= set_data; } @@ -955,17 +1000,17 @@ public class AltosState implements Cloneable { } public double time_since_boost() { - if (tick == AltosRecord.MISSING) + if (tick == AltosLib.MISSING) return 0.0; - if (boost_tick != AltosRecord.MISSING) { + if (boost_tick != AltosLib.MISSING) { return (tick - boost_tick) / 100.0; } return tick / 100.0; } public boolean valid() { - return tick != AltosRecord.MISSING && serial != AltosRecord.MISSING; + return tick != AltosLib.MISSING && serial != AltosLib.MISSING; } public AltosGPS make_temp_gps(boolean sats) { @@ -993,56 +1038,6 @@ public class AltosState implements Cloneable { return s; } - - public void init (AltosRecord cur, AltosState prev_state) { - - System.out.printf ("init\n"); - if (cur == null) - cur = new AltosRecord(); - - record = cur; - - /* Discard previous state if it was for a different board */ - if (prev_state != null && prev_state.serial != cur.serial) - prev_state = null; - - copy(prev_state); - - set_ground_altitude(cur.ground_altitude()); - set_altitude(cur.altitude()); - - set_kalman(cur.kalman_height, cur.kalman_speed, cur.kalman_acceleration); - - received_time = System.currentTimeMillis(); - - set_temperature(cur.temperature()); - set_apogee_voltage(cur.drogue_voltage()); - set_main_voltage(cur.main_voltage()); - set_battery_voltage(cur.battery_voltage()); - - set_pressure(cur.pressure()); - - set_tick(cur.tick); - set_state(cur.state); - - set_accel_g (cur.accel_minus_g, cur.accel_plus_g); - set_ground_accel(cur.ground_accel); - set_accel (cur.accel); - - if (cur.gps_sequence != gps_sequence) - set_gps(cur.gps, cur.gps_sequence); - - } - - public AltosState(AltosRecord cur) { - init(cur, null); - } - - public AltosState (AltosRecord cur, AltosState prev) { - init(cur, prev); - } - - public AltosState () { init(); } diff --git a/altoslib/AltosStateIterable.java b/altoslib/AltosStateIterable.java index db4a2568..6d637419 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; diff --git a/altoslib/AltosStateUpdate.java b/altoslib/AltosStateUpdate.java index 50460e21..ec4f7609 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_1; +package org.altusmetrum.altoslib_2; public interface AltosStateUpdate { public void update_state(AltosState state); diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index 642e7421..03ca9f80 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_1; +package org.altusmetrum.altoslib_2; import java.text.*; diff --git a/altoslib/AltosTelemetryConfiguration.java b/altoslib/AltosTelemetryConfiguration.java index 4c9bdd1f..e5d444dd 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_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryConfiguration extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java index 33872688..7566d946 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_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; @@ -72,16 +72,14 @@ public class AltosTelemetryFile extends AltosStateIterable { /* Find boost tick */ AltosState state = start.clone(); - System.out.printf ("Searching for boost\n"); for (AltosTelemetry telem : telems) { telem.update_state(state); + state.finish_update(); if (state.state != AltosLib.ao_flight_invalid && state.state >= AltosLib.ao_flight_boost) { - System.out.printf ("boost tick %d\n", state.tick); start.set_boost_tick(state.tick); break; } } - System.out.printf ("Found boost %d\n", start.boost_tick); } public Iterator iterator() { @@ -91,6 +89,7 @@ public class AltosTelemetryFile extends AltosStateIterable { while (i.hasNext() && !state.valid()) { AltosTelemetry t = i.next(); t.update_state(state); + state.finish_update(); } return new AltosTelemetryIterator(state, i); } diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index b7489f77..8075b8a3 100644 --- a/altoslib/AltosTelemetryIterable.java +++ b/altoslib/AltosTelemetryIterable.java @@ -15,17 +15,78 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.io.*; import java.util.*; import java.text.*; +class AltosTelemetryOrdered implements Comparable { + AltosTelemetry telem; + int index; + int tick; + + public int compareTo(AltosTelemetryOrdered o) { + int tick_diff = tick - o.tick; + + if (tick_diff != 0) + return tick_diff; + return index - o.index; + } + + AltosTelemetryOrdered (AltosTelemetry telem, int index, int tick) { + this.telem = telem; + this.index = index; + this.tick = tick; + } +} + +class AltosTelemetryOrderedIterator implements Iterator { + TreeSet olist; + Iterator oiterator; + + public AltosTelemetryOrderedIterator(Iterable telems) { + olist = new TreeSet(); + + int tick = 0; + int index = 0; + boolean first = true; + + for (AltosTelemetry e : telems) { + int t = e.tick; + if (first) + tick = t; + else { + while (t < tick - 32767) + t += 65536; + tick = t; + } + olist.add(new AltosTelemetryOrdered(e, index++, tick)); + first = false; + } + + oiterator = olist.iterator(); + } + + public boolean hasNext() { + return oiterator.hasNext(); + } + + public AltosTelemetry next() { + return oiterator.next().telem; + } + + public void remove () { + } +} + public class AltosTelemetryIterable implements Iterable { LinkedList telems; public Iterator iterator () { - return telems.iterator(); + if (telems == null) + telems = new LinkedList(); + return new AltosTelemetryOrderedIterator(telems); } public AltosTelemetryIterable (FileInputStream input) { diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index 95cbbeed..132b9e80 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_1; +package org.altusmetrum.altoslib_2; import java.text.*; @@ -264,34 +264,34 @@ public class AltosTelemetryLegacy extends AltosTelemetry { AltosTelemetryMap map = new AltosTelemetryMap(words, i); callsign = map.get_string(AO_TELEM_CALL, "N0CALL"); - serial = map.get_int(AO_TELEM_SERIAL, AltosRecord.MISSING); - flight = map.get_int(AO_TELEM_FLIGHT, AltosRecord.MISSING); - rssi = map.get_int(AO_TELEM_RSSI, AltosRecord.MISSING); + serial = map.get_int(AO_TELEM_SERIAL, AltosLib.MISSING); + flight = map.get_int(AO_TELEM_FLIGHT, AltosLib.MISSING); + rssi = map.get_int(AO_TELEM_RSSI, AltosLib.MISSING); state = AltosLib.state(map.get_string(AO_TELEM_STATE, "invalid")); tick = map.get_int(AO_TELEM_TICK, 0); /* raw sensor values */ - accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosRecord.MISSING); - pres = map.get_int(AO_TELEM_RAW_BARO, AltosRecord.MISSING); - temp = map.get_int(AO_TELEM_RAW_THERMO, AltosRecord.MISSING); - batt = map.get_int(AO_TELEM_RAW_BATT, AltosRecord.MISSING); - apogee = map.get_int(AO_TELEM_RAW_DROGUE, AltosRecord.MISSING); - main = map.get_int(AO_TELEM_RAW_MAIN, AltosRecord.MISSING); + accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosLib.MISSING); + pres = map.get_int(AO_TELEM_RAW_BARO, AltosLib.MISSING); + temp = map.get_int(AO_TELEM_RAW_THERMO, AltosLib.MISSING); + batt = map.get_int(AO_TELEM_RAW_BATT, AltosLib.MISSING); + apogee = map.get_int(AO_TELEM_RAW_DROGUE, AltosLib.MISSING); + main = map.get_int(AO_TELEM_RAW_MAIN, AltosLib.MISSING); /* sensor calibration information */ - ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosRecord.MISSING); - ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosRecord.MISSING); - accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosRecord.MISSING); - accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosRecord.MISSING); + ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosLib.MISSING); + ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosLib.MISSING); + accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosLib.MISSING); + accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosLib.MISSING); /* flight computer values */ - kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); - kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); - kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); + kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosLib.MISSING, 1/16.0); + kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosLib.MISSING, 1/16.0); + kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosLib.MISSING); - flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosRecord.MISSING); - flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosRecord.MISSING); - flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosRecord.MISSING); + flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosLib.MISSING); + flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosLib.MISSING); + flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosLib.MISSING); if (map.has(AO_TELEM_GPS_STATE)) gps = new AltosGPS(map); @@ -363,13 +363,13 @@ public class AltosTelemetryLegacy extends AltosTelemetry { kalman_speed = ((short) flight_vel) / 16.0; kalman_acceleration = flight_accel / 16.0; kalman_height = flight_pres; - flight_vel = AltosRecord.MISSING; - flight_pres = AltosRecord.MISSING; - flight_accel = AltosRecord.MISSING; + flight_vel = AltosLib.MISSING; + flight_pres = AltosLib.MISSING; + flight_accel = AltosLib.MISSING; } else { - kalman_speed = AltosRecord.MISSING; - kalman_acceleration = AltosRecord.MISSING; - kalman_height = AltosRecord.MISSING; + kalman_speed = AltosLib.MISSING; + kalman_acceleration = AltosLib.MISSING; + kalman_height = AltosLib.MISSING; } AltosParse.word(words[i++], "gp:"); @@ -480,16 +480,16 @@ public class AltosTelemetryLegacy extends AltosTelemetry { kalman_acceleration = int16(5); kalman_speed = int16(9); kalman_height = int16(13); - flight_accel = AltosRecord.MISSING; - flight_vel = AltosRecord.MISSING; - flight_pres = AltosRecord.MISSING; + flight_accel = AltosLib.MISSING; + flight_vel = AltosLib.MISSING; + flight_pres = AltosLib.MISSING; } else { flight_accel = int16(5); flight_vel = uint32(9); flight_pres = int16(13); - kalman_acceleration = AltosRecord.MISSING; - kalman_speed = AltosRecord.MISSING; - kalman_height = AltosRecord.MISSING; + kalman_acceleration = AltosLib.MISSING; + kalman_speed = AltosLib.MISSING; + kalman_height = AltosLib.MISSING; } gps = null; @@ -544,7 +544,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry { state.set_pressure(AltosConvert.barometer_to_pressure(pres)); state.set_accel_g(accel_plus_g, accel_minus_g); state.set_accel(accel); - if (kalman_height != AltosRecord.MISSING) + if (kalman_height != AltosLib.MISSING) state.set_kalman(kalman_height, kalman_speed, kalman_acceleration); state.set_temperature(AltosConvert.thermometer_to_temperature(temp)); state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt)); diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index 50b9dcfc..6e880914 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_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryLocation extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMap.java b/altoslib/AltosTelemetryMap.java index 7cca98b0..37883a1c 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_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.util.HashMap; diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java index 5e6cd580..f5cc01d0 100644 --- a/altoslib/AltosTelemetryMegaData.java +++ b/altoslib/AltosTelemetryMegaData.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryMegaData extends AltosTelemetryStandard { int state; diff --git a/altoslib/AltosTelemetryMegaSensor.java b/altoslib/AltosTelemetryMegaSensor.java index 7c385cfd..23b67af8 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_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryMegaSensor extends AltosTelemetryStandard { int accel; diff --git a/altoslib/AltosTelemetryMetrumData.java b/altoslib/AltosTelemetryMetrumData.java index d419ab80..b6239971 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_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryMetrumData extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java index 59d34dba..72d2f564 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_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryRaw.java b/altoslib/AltosTelemetryRaw.java index 9ef7787e..dbe70fe9 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_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRaw extends AltosTelemetryStandard { public AltosTelemetryRaw(int[] bytes) { diff --git a/altoslib/AltosTelemetryReader.java b/altoslib/AltosTelemetryReader.java index b1cc009c..dfbad5fb 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_1; +package org.altusmetrum.altoslib_2; import java.text.*; import java.io.*; @@ -24,7 +24,6 @@ import java.util.concurrent.*; public class AltosTelemetryReader extends AltosFlightReader { AltosLink link; AltosLog log; - AltosRecord previous; double frequency; int telemetry; AltosState state = null; @@ -49,7 +48,6 @@ public class AltosTelemetryReader extends AltosFlightReader { } public void reset() { - previous = null; flush(); } @@ -126,7 +124,6 @@ public class AltosTelemetryReader extends AltosFlightReader { try { log = new AltosLog(link); name = link.name; - previous = null; telem = new LinkedBlockingQueue(); frequency = AltosPreferences.frequency(link.serial); set_frequency(frequency); diff --git a/altoslib/AltosTelemetryRecord.java b/altoslib/AltosTelemetryRecord.java index a744e61a..a46c1a33 100644 --- a/altoslib/AltosTelemetryRecord.java +++ b/altoslib/AltosTelemetryRecord.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; public abstract class AltosTelemetryRecord { diff --git a/altoslib/AltosTelemetryRecordCompanion.java b/altoslib/AltosTelemetryRecordCompanion.java index 2231df13..9c38ba0a 100644 --- a/altoslib/AltosTelemetryRecordCompanion.java +++ b/altoslib/AltosTelemetryRecordCompanion.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordCompanion extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordConfiguration.java b/altoslib/AltosTelemetryRecordConfiguration.java index 47fc3488..48474fa5 100644 --- a/altoslib/AltosTelemetryRecordConfiguration.java +++ b/altoslib/AltosTelemetryRecordConfiguration.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordConfiguration extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordGeneral.java b/altoslib/AltosTelemetryRecordGeneral.java index 08cd6065..258678c7 100644 --- a/altoslib/AltosTelemetryRecordGeneral.java +++ b/altoslib/AltosTelemetryRecordGeneral.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; diff --git a/altoslib/AltosTelemetryRecordLegacy.java b/altoslib/AltosTelemetryRecordLegacy.java index f2d3f868..5f86d671 100644 --- a/altoslib/AltosTelemetryRecordLegacy.java +++ b/altoslib/AltosTelemetryRecordLegacy.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; import java.text.*; @@ -236,34 +236,34 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { AltosTelemetryMap map = new AltosTelemetryMap(words, i); record.callsign = map.get_string(AO_TELEM_CALL, "N0CALL"); - record.serial = map.get_int(AO_TELEM_SERIAL, AltosRecord.MISSING); - record.flight = map.get_int(AO_TELEM_FLIGHT, AltosRecord.MISSING); - record.rssi = map.get_int(AO_TELEM_RSSI, AltosRecord.MISSING); + record.serial = map.get_int(AO_TELEM_SERIAL, AltosLib.MISSING); + record.flight = map.get_int(AO_TELEM_FLIGHT, AltosLib.MISSING); + record.rssi = map.get_int(AO_TELEM_RSSI, AltosLib.MISSING); record.state = AltosLib.state(map.get_string(AO_TELEM_STATE, "invalid")); record.tick = map.get_int(AO_TELEM_TICK, 0); /* raw sensor values */ - record.accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosRecord.MISSING); - record.pres = map.get_int(AO_TELEM_RAW_BARO, AltosRecord.MISSING); - record.temp = map.get_int(AO_TELEM_RAW_THERMO, AltosRecord.MISSING); - record.batt = map.get_int(AO_TELEM_RAW_BATT, AltosRecord.MISSING); - record.drogue = map.get_int(AO_TELEM_RAW_DROGUE, AltosRecord.MISSING); - record.main = map.get_int(AO_TELEM_RAW_MAIN, AltosRecord.MISSING); + record.accel = map.get_int(AO_TELEM_RAW_ACCEL, AltosLib.MISSING); + record.pres = map.get_int(AO_TELEM_RAW_BARO, AltosLib.MISSING); + record.temp = map.get_int(AO_TELEM_RAW_THERMO, AltosLib.MISSING); + record.batt = map.get_int(AO_TELEM_RAW_BATT, AltosLib.MISSING); + record.drogue = map.get_int(AO_TELEM_RAW_DROGUE, AltosLib.MISSING); + record.main = map.get_int(AO_TELEM_RAW_MAIN, AltosLib.MISSING); /* sensor calibration information */ - record.ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosRecord.MISSING); - record.ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosRecord.MISSING); - record.accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosRecord.MISSING); - record.accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosRecord.MISSING); + record.ground_accel = map.get_int(AO_TELEM_CAL_ACCEL_GROUND, AltosLib.MISSING); + record.ground_pres = map.get_int(AO_TELEM_CAL_BARO_GROUND, AltosLib.MISSING); + record.accel_plus_g = map.get_int(AO_TELEM_CAL_ACCEL_PLUS, AltosLib.MISSING); + record.accel_minus_g = map.get_int(AO_TELEM_CAL_ACCEL_MINUS, AltosLib.MISSING); /* flight computer values */ - record.kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosRecord.MISSING, 1/16.0); - record.kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosRecord.MISSING, 1/16.0); - record.kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosRecord.MISSING); + record.kalman_acceleration = map.get_double(AO_TELEM_KALMAN_ACCEL, AltosLib.MISSING, 1/16.0); + record.kalman_speed = map.get_double(AO_TELEM_KALMAN_SPEED, AltosLib.MISSING, 1/16.0); + record.kalman_height = map.get_int(AO_TELEM_KALMAN_HEIGHT, AltosLib.MISSING); - record.flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosRecord.MISSING); - record.flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosRecord.MISSING); - record.flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosRecord.MISSING); + record.flight_accel = map.get_int(AO_TELEM_ADHOC_ACCEL, AltosLib.MISSING); + record.flight_vel = map.get_int(AO_TELEM_ADHOC_SPEED, AltosLib.MISSING); + record.flight_pres = map.get_int(AO_TELEM_ADHOC_BARO, AltosLib.MISSING); if (map.has(AO_TELEM_GPS_STATE)) { record.gps = new AltosGPS(map); @@ -337,9 +337,9 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.kalman_speed = ((short) record.flight_vel) / 16.0; record.kalman_acceleration = record.flight_accel / 16.0; record.kalman_height = record.flight_pres; - record.flight_vel = AltosRecord.MISSING; - record.flight_pres = AltosRecord.MISSING; - record.flight_accel = AltosRecord.MISSING; + record.flight_vel = AltosLib.MISSING; + record.flight_pres = AltosLib.MISSING; + record.flight_accel = AltosLib.MISSING; } AltosParse.word(words[i++], "gp:"); @@ -458,16 +458,16 @@ public class AltosTelemetryRecordLegacy extends AltosTelemetryRecord { record.kalman_acceleration = int16(5); record.kalman_speed = int16(9); record.kalman_height = int16(13); - record.flight_accel = AltosRecord.MISSING; - record.flight_vel = AltosRecord.MISSING; - record.flight_pres = AltosRecord.MISSING; + record.flight_accel = AltosLib.MISSING; + record.flight_vel = AltosLib.MISSING; + record.flight_pres = AltosLib.MISSING; } else { record.flight_accel = int16(5); record.flight_vel = uint32(9); record.flight_pres = int16(13); - record.kalman_acceleration = AltosRecord.MISSING; - record.kalman_speed = AltosRecord.MISSING; - record.kalman_height = AltosRecord.MISSING; + record.kalman_acceleration = AltosLib.MISSING; + record.kalman_speed = AltosLib.MISSING; + record.kalman_height = AltosLib.MISSING; } record.gps = null; diff --git a/altoslib/AltosTelemetryRecordLocation.java b/altoslib/AltosTelemetryRecordLocation.java index 0236d291..0eea8361 100644 --- a/altoslib/AltosTelemetryRecordLocation.java +++ b/altoslib/AltosTelemetryRecordLocation.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordLocation extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMegaData.java b/altoslib/AltosTelemetryRecordMegaData.java index a484ef4e..ee9442d2 100644 --- a/altoslib/AltosTelemetryRecordMegaData.java +++ b/altoslib/AltosTelemetryRecordMegaData.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMegaData extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMegaSensor.java b/altoslib/AltosTelemetryRecordMegaSensor.java index 2a4b17a4..234cda27 100644 --- a/altoslib/AltosTelemetryRecordMegaSensor.java +++ b/altoslib/AltosTelemetryRecordMegaSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMegaSensor extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMetrumData.java b/altoslib/AltosTelemetryRecordMetrumData.java index 70179b28..ade2494f 100644 --- a/altoslib/AltosTelemetryRecordMetrumData.java +++ b/altoslib/AltosTelemetryRecordMetrumData.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMetrumData extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMetrumSensor.java b/altoslib/AltosTelemetryRecordMetrumSensor.java index e41242c5..d6d29b15 100644 --- a/altoslib/AltosTelemetryRecordMetrumSensor.java +++ b/altoslib/AltosTelemetryRecordMetrumSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMetrumSensor extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordMini.java b/altoslib/AltosTelemetryRecordMini.java index 75a66c16..3c290208 100644 --- a/altoslib/AltosTelemetryRecordMini.java +++ b/altoslib/AltosTelemetryRecordMini.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordMini extends AltosTelemetryRecordRaw { diff --git a/altoslib/AltosTelemetryRecordRaw.java b/altoslib/AltosTelemetryRecordRaw.java index f94789bb..93d0ca50 100644 --- a/altoslib/AltosTelemetryRecordRaw.java +++ b/altoslib/AltosTelemetryRecordRaw.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordRaw extends AltosTelemetryRecord { int[] bytes; diff --git a/altoslib/AltosTelemetryRecordSatellite.java b/altoslib/AltosTelemetryRecordSatellite.java index 9835389b..5de16ab4 100644 --- a/altoslib/AltosTelemetryRecordSatellite.java +++ b/altoslib/AltosTelemetryRecordSatellite.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordSatellite extends AltosTelemetryRecordRaw { int channels; diff --git a/altoslib/AltosTelemetryRecordSensor.java b/altoslib/AltosTelemetryRecordSensor.java index e0e92c13..d1d9dd7e 100644 --- a/altoslib/AltosTelemetryRecordSensor.java +++ b/altoslib/AltosTelemetryRecordSensor.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { @@ -70,7 +70,7 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { if (type == packet_type_TM_sensor) next.accel = accel; else - next.accel = AltosRecord.MISSING; + next.accel = AltosLib.MISSING; next.pres = pres; next.temp = temp; next.batt = v_batt; @@ -78,8 +78,8 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { next.drogue = sense_d; next.main = sense_m; } else { - next.drogue = AltosRecord.MISSING; - next.main = AltosRecord.MISSING; + next.drogue = AltosLib.MISSING; + next.main = AltosLib.MISSING; } next.kalman_acceleration = acceleration / 16.0; @@ -92,9 +92,9 @@ public class AltosTelemetryRecordSensor extends AltosTelemetryRecordRaw { next.accel_plus_g = accel_plus_g; next.accel_minus_g = accel_minus_g; } else { - next.ground_accel = AltosRecord.MISSING; - next.accel_plus_g = AltosRecord.MISSING; - next.accel_minus_g = AltosRecord.MISSING; + next.ground_accel = AltosLib.MISSING; + next.accel_plus_g = AltosLib.MISSING; + next.accel_minus_g = AltosLib.MISSING; } next.seen |= AltosRecord.seen_sensor | AltosRecord.seen_temp_volt; diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java index bd94740f..fde3d86d 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_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetrySatellite extends AltosTelemetryStandard { int channels; diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java index f89e56c3..e1106440 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_1; +package org.altusmetrum.altoslib_2; public class AltosTelemetrySensor extends AltosTelemetryStandard { diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java index fa86bf8e..fbcc970c 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_1; +package org.altusmetrum.altoslib_2; public abstract class AltosTelemetryStandard extends AltosTelemetry { int[] bytes; diff --git a/altoslib/AltosTemperature.java b/altoslib/AltosTemperature.java index 2749eac0..0105fe53 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_1; +package org.altusmetrum.altoslib_2; public class AltosTemperature extends AltosUnits { diff --git a/altoslib/AltosUnits.java b/altoslib/AltosUnits.java index b8b3254c..ee74f916 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_1; +package org.altusmetrum.altoslib_2; public abstract class AltosUnits { diff --git a/altoslib/AltosUnitsListener.java b/altoslib/AltosUnitsListener.java index 61a181a4..1e3ad655 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_1; +package org.altusmetrum.altoslib_2; public interface AltosUnitsListener { public void units_changed(boolean imperial_units); diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 87d4d898..62159bcc 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -10,20 +10,9 @@ SRC=. altoslibdir = $(datadir)/java -record_files = \ - AltosEepromRecord.java \ - AltosEepromTeleScience.java \ - AltosRecordCompanion.java \ - AltosRecordIterable.java \ - AltosRecord.java \ - AltosRecordNone.java \ - AltosRecordTM.java \ - AltosRecordMM.java \ - AltosRecordMini.java - altoslib_JAVA = \ - $(record_files) \ AltosLib.java \ + AltosCompanion.java \ AltosConfigData.java \ AltosConfigValues.java \ AltosConvert.java \ @@ -45,31 +34,32 @@ altoslib_JAVA = \ AltosFlightReader.java \ AltosFrequency.java \ AltosGPS.java \ - AltosGPSQuery.java \ AltosGPSSat.java \ AltosGreatCircle.java \ AltosHexfile.java \ + AltosIdle.java \ + AltosIdleFetch.java \ AltosIdleMonitor.java \ AltosIdleMonitorListener.java \ AltosIgnite.java \ AltosIMU.java \ - AltosIMUQuery.java \ AltosLine.java \ AltosLink.java \ AltosListenerState.java \ AltosLog.java \ + AltosMag.java \ + AltosMma655x.java \ AltosMs5607.java \ - AltosMs5607Query.java \ - AltosOrderedRecord.java \ - AltosOrderedMegaRecord.java \ - AltosOrderedMiniRecord.java \ AltosParse.java \ AltosPreferences.java \ AltosPreferencesBackend.java \ AltosReplayReader.java \ AltosRomconfig.java \ AltosSensorMM.java \ + AltosSensorEMini.java \ AltosSensorTM.java \ + AltosSensorMega.java \ + AltosSensorMetrum.java \ AltosState.java \ AltosStateIterable.java \ AltosStateUpdate.java \ diff --git a/altosui/Altos.java b/altosui/Altos.java index d25736bf..07280b4a 100644 --- a/altosui/Altos.java +++ b/altosui/Altos.java @@ -20,7 +20,7 @@ package altosui; import java.awt.*; import libaltosJNI.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class Altos extends AltosUILib { diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index 20474f52..1d9af546 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosAscent extends JComponent implements AltosFlightDisplay { GridBagLayout layout; @@ -179,7 +179,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { void reset() { value.setText(""); max_value.setText(""); - max = AltosRecord.MISSING; + max = AltosLib.MISSING; } void set_font() { @@ -189,12 +189,12 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { } void show(AltosUnits units, double v) { - if (v == AltosRecord.MISSING) { + if (v == AltosLib.MISSING) { value.setText("Missing"); max_value.setText("Missing"); } else { value.setText(units.show(8, v)); - if (v > max || max == AltosRecord.MISSING) { + if (v > max || max == AltosLib.MISSING) { max_value.setText(units.show(8, v)); max = v; } @@ -308,7 +308,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Lat extends AscentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -322,7 +322,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { class Lon extends AscentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) show(pos(state.gps.lon,"E", "W")); else show("???"); @@ -365,11 +365,11 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay { lon.hide(); } height.show(state, listener_state); - if (state.main_voltage != AltosRecord.MISSING) + if (state.main_voltage != AltosLib.MISSING) main.show(state, listener_state); else main.hide(); - if (state.apogee_voltage != AltosRecord.MISSING) + if (state.apogee_voltage != AltosLib.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosBTKnown.java b/altosui/AltosBTKnown.java index 1d42365b..a1652ec4 100644 --- a/altosui/AltosBTKnown.java +++ b/altosui/AltosBTKnown.java @@ -17,7 +17,7 @@ package altosui; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosBTKnown implements Iterable { diff --git a/altosui/AltosCSV.java b/altosui/AltosCSV.java index bcff393f..7598eca0 100644 --- a/altosui/AltosCSV.java +++ b/altosui/AltosCSV.java @@ -19,7 +19,7 @@ package altosui; import java.io.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosCSV implements AltosWriter { File name; @@ -222,7 +222,7 @@ public class AltosCSV implements AltosWriter { } void write_companion(AltosState state) { - AltosRecordCompanion companion = state.companion; + AltosCompanion companion = state.companion; int channels_written = 0; if (companion == null) { diff --git a/altosui/AltosCSVUI.java b/altosui/AltosCSVUI.java index 4b48bdf6..c41ea74b 100644 --- a/altosui/AltosCSVUI.java +++ b/altosui/AltosCSVUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosCSVUI diff --git a/altosui/AltosCompanionInfo.java b/altosui/AltosCompanionInfo.java index 1ed2c425..1f446700 100644 --- a/altosui/AltosCompanionInfo.java +++ b/altosui/AltosCompanionInfo.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosCompanionInfo extends JTable { private AltosFlightInfoTableModel model; @@ -70,13 +70,13 @@ public class AltosCompanionInfo extends JTable { model.clear(); } - AltosRecordCompanion companion; + AltosCompanion companion; public String board_name() { if (companion == null) return "None"; switch (companion.board_id) { - case AltosRecordCompanion.board_id_telescience: + case AltosCompanion.board_id_telescience: return "TeleScience"; default: return String.format("%02x\n", companion.board_id); diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index 4927d3f8..a6e6094f 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -22,7 +22,7 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.text.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfig implements ActionListener { diff --git a/altosui/AltosConfigFreqUI.java b/altosui/AltosConfigFreqUI.java index c90b168f..555af3b6 100644 --- a/altosui/AltosConfigFreqUI.java +++ b/altosui/AltosConfigFreqUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class AltosEditFreqUI extends AltosUIDialog implements ActionListener { diff --git a/altosui/AltosConfigPyroUI.java b/altosui/AltosConfigPyroUI.java index 3cac56c3..2f5c199d 100644 --- a/altosui/AltosConfigPyroUI.java +++ b/altosui/AltosConfigPyroUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfigPyroUI diff --git a/altosui/AltosConfigTD.java b/altosui/AltosConfigTD.java index 16c9e357..f879ff88 100644 --- a/altosui/AltosConfigTD.java +++ b/altosui/AltosConfigTD.java @@ -21,7 +21,7 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfigTD implements ActionListener { diff --git a/altosui/AltosConfigTDUI.java b/altosui/AltosConfigTDUI.java index 125780a9..b5a6cd7c 100644 --- a/altosui/AltosConfigTDUI.java +++ b/altosui/AltosConfigTDUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfigTDUI diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index 9723e660..a6d27977 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosConfigUI diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java index af6c245b..0d0b0b0a 100644 --- a/altosui/AltosDataChooser.java +++ b/altosui/AltosDataChooser.java @@ -20,7 +20,7 @@ package altosui; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosDataChooser extends JFileChooser { diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index e85717bb..77776ff2 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosDescent extends JComponent implements AltosFlightDisplay { GridBagLayout layout; @@ -278,7 +278,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Lat extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -292,7 +292,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { class Lon extends DescentValue { void show (AltosState state, AltosListenerState listener_state) { - if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) show(pos(state.gps.lon,"W", "E")); else show("???"); @@ -427,11 +427,11 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay { lat.hide(); lon.hide(); } - if (state.main_voltage != AltosRecord.MISSING) + if (state.main_voltage != AltosLib.MISSING) main.show(state, listener_state); else main.hide(); - if (state.apogee_voltage != AltosRecord.MISSING) + if (state.apogee_voltage != AltosLib.MISSING) apogee.show(state, listener_state); else apogee.hide(); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index c894c2d0..37f6adf9 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -21,7 +21,7 @@ import java.awt.*; import javax.swing.*; import java.io.*; import java.text.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosDisplayThread extends Thread { diff --git a/altosui/AltosEepromDelete.java b/altosui/AltosEepromDelete.java index e81a35d1..9984d1a2 100644 --- a/altosui/AltosEepromDelete.java +++ b/altosui/AltosEepromDelete.java @@ -21,7 +21,7 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosEepromDelete implements Runnable { AltosEepromList flights; diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 931b55fd..c3bdd159 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -23,7 +23,7 @@ import java.io.*; import java.util.*; import java.text.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosEepromDownload implements Runnable { @@ -61,9 +61,9 @@ public class AltosEepromDownload implements Runnable { AltosGPS gps = state.gps; if (gps != null && - gps.year != AltosRecord.MISSING && - gps.month != AltosRecord.MISSING && - gps.day != AltosRecord.MISSING) + gps.year != AltosLib.MISSING && + gps.month != AltosLib.MISSING && + gps.day != AltosLib.MISSING) { eeprom_name = new AltosFile(gps.year, gps.month, gps.day, state.serial, state.flight, "eeprom"); diff --git a/altosui/AltosEepromList.java b/altosui/AltosEepromList.java index a63d173d..258c421a 100644 --- a/altosui/AltosEepromList.java +++ b/altosui/AltosEepromList.java @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.text.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; /* * Temporary structure to hold the list of stored flights; diff --git a/altosui/AltosEepromManage.java b/altosui/AltosEepromManage.java index 7a721196..b2d8a130 100644 --- a/altosui/AltosEepromManage.java +++ b/altosui/AltosEepromManage.java @@ -21,7 +21,7 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosEepromManage implements ActionListener { diff --git a/altosui/AltosEepromSelect.java b/altosui/AltosEepromSelect.java index a451aa3a..8f86eebf 100644 --- a/altosui/AltosEepromSelect.java +++ b/altosui/AltosEepromSelect.java @@ -21,7 +21,7 @@ import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class AltosEepromItem implements ActionListener { diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java index f4e52218..6eccface 100644 --- a/altosui/AltosFlashUI.java +++ b/altosui/AltosFlashUI.java @@ -23,7 +23,7 @@ import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosFlashUI diff --git a/altosui/AltosFlightDisplay.java b/altosui/AltosFlightDisplay.java index 4f4c158e..289ddd01 100644 --- a/altosui/AltosFlightDisplay.java +++ b/altosui/AltosFlightDisplay.java @@ -17,7 +17,7 @@ package altosui; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public interface AltosFlightDisplay { void reset(); diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index f278012f..11a3f1a9 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -18,7 +18,7 @@ package altosui; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStats { double max_height; @@ -77,7 +77,7 @@ public class AltosFlightStats { } double boost_time(AltosStateIterable states) { - double boost_time = AltosRecord.MISSING; + double boost_time = AltosLib.MISSING; AltosState state = null; for (AltosState s : states) { @@ -90,7 +90,7 @@ public class AltosFlightStats { if (state == null) return 0; - if (boost_time == AltosRecord.MISSING) + if (boost_time == AltosLib.MISSING) boost_time = state.time; return boost_time; } @@ -101,21 +101,21 @@ public class AltosFlightStats { double end_time = 0; double landed_time = landed_time(states); - year = month = day = AltosRecord.MISSING; - hour = minute = second = AltosRecord.MISSING; - serial = flight = AltosRecord.MISSING; - lat = lon = AltosRecord.MISSING; + year = month = day = AltosLib.MISSING; + hour = minute = second = AltosLib.MISSING; + serial = flight = AltosLib.MISSING; + lat = lon = AltosLib.MISSING; has_gps = false; has_other_adc = false; has_rssi = false; for (AltosState state : states) { - if (serial == AltosRecord.MISSING && state.serial != AltosRecord.MISSING) + if (serial == AltosLib.MISSING && state.serial != AltosLib.MISSING) serial = state.serial; - if (flight == AltosRecord.MISSING && state.flight != AltosRecord.MISSING) + if (flight == AltosLib.MISSING && state.flight != AltosLib.MISSING) flight = state.flight; - if (state.battery_voltage != AltosRecord.MISSING) + if (state.battery_voltage != AltosLib.MISSING) has_other_adc = true; - if (state.rssi != AltosRecord.MISSING) + if (state.rssi != AltosLib.MISSING) has_rssi = true; end_time = state.time; if (state.time >= boost_time && state.state < Altos.ao_flight_boost) diff --git a/altosui/AltosFlightStatsTable.java b/altosui/AltosFlightStatsTable.java index b5a92683..db875b3b 100644 --- a/altosui/AltosFlightStatsTable.java +++ b/altosui/AltosFlightStatsTable.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStatsTable extends JComponent { GridBagLayout layout; @@ -76,15 +76,15 @@ public class AltosFlightStatsTable extends JComponent { int y = 0; new FlightStat(layout, y++, "Serial", String.format("%d", stats.serial)); new FlightStat(layout, y++, "Flight", String.format("%d", stats.flight)); - if (stats.year != AltosRecord.MISSING && stats.hour != AltosRecord.MISSING) + if (stats.year != AltosLib.MISSING && stats.hour != AltosLib.MISSING) new FlightStat(layout, y++, "Date/Time", String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day), String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); else { - if (stats.year != AltosRecord.MISSING) + if (stats.year != AltosLib.MISSING) new FlightStat(layout, y++, "Date", String.format("%04d-%02d-%02d", stats.year, stats.month, stats.day)); - if (stats.hour != AltosRecord.MISSING) + if (stats.hour != AltosLib.MISSING) new FlightStat(layout, y++, "Time", String.format("%02d:%02d:%02d UTC", stats.hour, stats.minute, stats.second)); } @@ -95,7 +95,7 @@ public class AltosFlightStatsTable extends JComponent { String.format("%5.0f m/s", stats.max_speed), String.format("%5.0f mph", AltosConvert.meters_to_mph(stats.max_speed)), String.format("Mach %4.1f", AltosConvert.meters_to_mach(stats.max_speed))); - if (stats.max_acceleration != AltosRecord.MISSING) { + if (stats.max_acceleration != AltosLib.MISSING) { new FlightStat(layout, y++, "Maximum boost acceleration", String.format("%5.0f m/s²", stats.max_acceleration), String.format("%5.0f ft/s²", AltosConvert.meters_to_feet(stats.max_acceleration)), diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index 6383e5b9..9d575e4c 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStatus extends JComponent implements AltosFlightDisplay { GridBagLayout layout; @@ -76,7 +76,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Serial extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.serial == AltosRecord.MISSING) + if (state.serial == AltosLib.MISSING) value.setText("none"); else value.setText(String.format("%d", state.serial)); @@ -90,7 +90,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay class Flight extends FlightValue { void show(AltosState state, AltosListenerState listener_state) { - if (state.flight == AltosRecord.MISSING) + if (state.flight == AltosLib.MISSING) value.setText("none"); else value.setText(String.format("%d", state.flight)); diff --git a/altosui/AltosFlightStatusTableModel.java b/altosui/AltosFlightStatusTableModel.java index 6a327841..08154fda 100644 --- a/altosui/AltosFlightStatusTableModel.java +++ b/altosui/AltosFlightStatusTableModel.java @@ -27,7 +27,7 @@ import java.util.*; import java.text.*; import java.util.prefs.*; import java.util.concurrent.LinkedBlockingQueue; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStatusTableModel extends AbstractTableModel { private String[] columnNames = { diff --git a/altosui/AltosFlightStatusUpdate.java b/altosui/AltosFlightStatusUpdate.java index 962a08f7..7821a777 100644 --- a/altosui/AltosFlightStatusUpdate.java +++ b/altosui/AltosFlightStatusUpdate.java @@ -18,7 +18,7 @@ package altosui; import java.awt.event.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosFlightStatusUpdate implements ActionListener { diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 1c450ce3..c151177e 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener { diff --git a/altosui/AltosFreqList.java b/altosui/AltosFreqList.java index 7464ac3e..917ac364 100644 --- a/altosui/AltosFreqList.java +++ b/altosui/AltosFreqList.java @@ -18,7 +18,7 @@ package altosui; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosFreqList extends JComboBox { diff --git a/altosui/AltosGraph.java b/altosui/AltosGraph.java index a73e3fd8..e6cd7bd8 100644 --- a/altosui/AltosGraph.java +++ b/altosui/AltosGraph.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; import org.jfree.ui.*; diff --git a/altosui/AltosGraphDataPoint.java b/altosui/AltosGraphDataPoint.java index 85a19b00..d8191f5d 100644 --- a/altosui/AltosGraphDataPoint.java +++ b/altosui/AltosGraphDataPoint.java @@ -18,7 +18,7 @@ package altosui; import org.altusmetrum.altosuilib_1.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosGraphDataPoint implements AltosUIDataPoint { @@ -49,7 +49,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { } public double y(int index) throws AltosUIDataMissing { - double y = AltosRecord.MISSING; + double y = AltosLib.MISSING; switch (index) { case data_height: y = state.height(); @@ -100,7 +100,7 @@ public class AltosGraphDataPoint implements AltosUIDataPoint { y = state.pressure(); break; } - if (y == AltosRecord.MISSING) + if (y == AltosLib.MISSING) throw new AltosUIDataMissing(index); return y; } diff --git a/altosui/AltosGraphDataSet.java b/altosui/AltosGraphDataSet.java index 1e469c8a..4e6c46d1 100644 --- a/altosui/AltosGraphDataSet.java +++ b/altosui/AltosGraphDataSet.java @@ -20,7 +20,7 @@ package altosui; import java.lang.*; import java.io.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class AltosGraphIterator implements Iterator { @@ -34,7 +34,7 @@ class AltosGraphIterator implements Iterator { public AltosUIDataPoint next() { AltosState state = iterator.next(); - if (state.flight != AltosRecord.MISSING) { + if (state.flight != AltosLib.MISSING) { if (dataSet.callsign == null && state.callsign != null) dataSet.callsign = state.callsign; diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index 376e9910..c42f7b5f 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -9,7 +9,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; import org.jfree.chart.ChartPanel; diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index f6a91de8..f4e16243 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -23,7 +23,7 @@ import javax.swing.*; import javax.swing.event.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosFontListener, AltosIdleMonitorListener, DocumentListener { diff --git a/altosui/AltosIgniteUI.java b/altosui/AltosIgniteUI.java index 14d4eebc..c8024aae 100644 --- a/altosui/AltosIgniteUI.java +++ b/altosui/AltosIgniteUI.java @@ -23,7 +23,7 @@ import javax.swing.*; import java.io.*; import java.text.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosIgniteUI diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index cf4642bc..d7871aa6 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -20,7 +20,7 @@ package altosui; import java.awt.*; import javax.swing.*; import javax.swing.table.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosInfoTable extends JTable { private AltosFlightInfoTableModel model; @@ -107,40 +107,44 @@ public class AltosInfoTable extends JTable { public void show(AltosState state, AltosListenerState listener_state) { info_reset(); if (state != null) { - if (state.altitude() != AltosRecord.MISSING) + if (state.altitude() != AltosLib.MISSING) info_add_row(0, "Altitude", "%6.0f m", state.altitude()); - if (state.ground_altitude() != AltosRecord.MISSING) + if (state.ground_altitude() != AltosLib.MISSING) info_add_row(0, "Pad altitude", "%6.0f m", state.ground_altitude()); - if (state.height() != AltosRecord.MISSING) + if (state.height() != AltosLib.MISSING) info_add_row(0, "Height", "%6.0f m", state.height()); - if (state.max_height() != AltosRecord.MISSING) + if (state.max_height() != AltosLib.MISSING) info_add_row(0, "Max height", "%6.0f m", state.max_height()); - if (state.acceleration() != AltosRecord.MISSING) + if (state.acceleration() != AltosLib.MISSING) info_add_row(0, "Acceleration", "%8.1f m/s²", state.acceleration()); - if (state.max_acceleration() != AltosRecord.MISSING) + if (state.max_acceleration() != AltosLib.MISSING) info_add_row(0, "Max acceleration", "%8.1f m/s²", state.max_acceleration()); - if (state.speed() != AltosRecord.MISSING) + if (state.speed() != AltosLib.MISSING) info_add_row(0, "Speed", "%8.1f m/s", state.speed()); - if (state.max_speed() != AltosRecord.MISSING) + if (state.max_speed() != AltosLib.MISSING) info_add_row(0, "Max Speed", "%8.1f m/s", state.max_speed()); - if (state.temperature != AltosRecord.MISSING) + if (state.temperature != AltosLib.MISSING) info_add_row(0, "Temperature", "%9.2f °C", state.temperature); - if (state.battery_voltage != AltosRecord.MISSING) + if (state.battery_voltage != AltosLib.MISSING) info_add_row(0, "Battery", "%9.2f V", state.battery_voltage); - if (state.apogee_voltage != AltosRecord.MISSING) + if (state.apogee_voltage != AltosLib.MISSING) info_add_row(0, "Drogue", "%9.2f V", state.apogee_voltage); - if (state.main_voltage != AltosRecord.MISSING) + if (state.main_voltage != AltosLib.MISSING) info_add_row(0, "Main", "%9.2f V", state.main_voltage); } if (listener_state != null) { info_add_row(0, "CRC Errors", "%6d", listener_state.crc_errors); - if (listener_state.battery != AltosRecord.MISSING) + if (listener_state.battery != AltosLib.MISSING) info_add_row(0, "Receiver Battery", "%9.2f", listener_state.battery); } if (state != null) { if (state.gps == null || !state.gps.connected) { + if (state.gps == null) + System.out.printf ("null gps\n"); + else + System.out.printf ("not connected gps\n"); info_add_row(1, "GPS", "not available"); } else { if (state.gps_ready) @@ -155,13 +159,13 @@ public class AltosInfoTable extends JTable { else info_add_row(1, "GPS", " missing"); info_add_row(1, "Satellites", "%6d", state.gps.nsat); - if (state.gps.lat != AltosRecord.MISSING) + if (state.gps.lat != AltosLib.MISSING) info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); - if (state.gps.lon != AltosRecord.MISSING) + if (state.gps.lon != AltosLib.MISSING) info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); - if (state.gps.alt != AltosRecord.MISSING) + if (state.gps.alt != AltosLib.MISSING) info_add_row(1, "GPS altitude", "%8.1f", state.gps.alt); - if (state.gps_height != AltosRecord.MISSING) + if (state.gps_height != AltosLib.MISSING) info_add_row(1, "GPS height", "%8.1f", state.gps_height); /* The SkyTraq GPS doesn't report these values */ @@ -199,12 +203,12 @@ public class AltosInfoTable extends JTable { info_add_deg(1, "Pad longitude", state.pad_lon, 'E', 'W'); info_add_row(1, "Pad GPS alt", "%6.0f m", state.pad_alt); } - if (state.gps.year != AltosRecord.MISSING) + if (state.gps.year != AltosLib.MISSING) info_add_row(1, "GPS date", "%04d-%02d-%02d", state.gps.year, state.gps.month, state.gps.day); - if (state.gps.hour != AltosRecord.MISSING) + if (state.gps.hour != AltosLib.MISSING) info_add_row(1, "GPS time", " %02d:%02d:%02d", state.gps.hour, state.gps.minute, diff --git a/altosui/AltosKML.java b/altosui/AltosKML.java index 8679178f..fbb0ece4 100644 --- a/altosui/AltosKML.java +++ b/altosui/AltosKML.java @@ -18,7 +18,7 @@ package altosui; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosKML implements AltosWriter { @@ -110,7 +110,7 @@ public class AltosKML implements AltosWriter { AltosGPS gps = state.gps; double altitude; - if (state.height() != AltosRecord.MISSING) + if (state.height() != AltosLib.MISSING) altitude = state.height() + gps_start_altitude; else altitude = gps.alt; @@ -138,9 +138,9 @@ public class AltosKML implements AltosWriter { if (gps == null) return; - if (gps.lat == AltosRecord.MISSING) + if (gps.lat == AltosLib.MISSING) return; - if (gps.lon == AltosRecord.MISSING) + if (gps.lon == AltosLib.MISSING) return; if (!started) { start(state); diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 630527a0..139b81b6 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -21,7 +21,7 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosLanded extends JComponent implements AltosFlightDisplay, ActionListener { GridBagLayout layout; @@ -104,7 +104,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Lat extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { show(); - if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING) show(pos(state.gps.lat,"N", "S")); else show("???"); @@ -119,7 +119,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio class Lon extends LandedValue { void show (AltosState state, AltosListenerState listener_state) { show(); - if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING) + if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING) show(pos(state.gps.lon,"E", "W")); else show("???"); diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index e9c973de..b35bd23a 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -19,7 +19,7 @@ package altosui; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosPad extends JComponent implements AltosFlightDisplay { GridBagLayout layout; @@ -176,7 +176,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Battery extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.battery_voltage == AltosRecord.MISSING) + if (state == null || state.battery_voltage == AltosLib.MISSING) hide(); else { show("%4.2f V", state.battery_voltage); @@ -192,7 +192,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Apogee extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.apogee_voltage == AltosRecord.MISSING) + if (state == null || state.apogee_voltage == AltosLib.MISSING) hide(); else { show("%4.2f V", state.apogee_voltage); @@ -208,7 +208,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class Main extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.main_voltage == AltosRecord.MISSING) + if (state == null || state.main_voltage == AltosLib.MISSING) hide(); else { show("%4.2f V", state.main_voltage); @@ -224,7 +224,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class LoggingReady extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (state == null || state.flight == AltosRecord.MISSING) { + if (state == null || state.flight == AltosLib.MISSING) { hide(); } else { if (state.flight != 0) { @@ -283,7 +283,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class ReceiverBattery extends LaunchStatus { void show (AltosState state, AltosListenerState listener_state) { - if (listener_state == null || listener_state.battery == AltosRecord.MISSING) + if (listener_state == null || listener_state.battery == AltosLib.MISSING) hide(); else { show("%4.2f V", listener_state.battery); @@ -310,11 +310,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadLat extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - double lat = AltosRecord.MISSING; + double lat = AltosLib.MISSING; String label = null; if (state != null) { - if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lat != AltosRecord.MISSING) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lat != AltosLib.MISSING) { lat = state.gps.lat; label = "Latitude"; } else { @@ -322,8 +322,8 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { label = "Pad Latitude"; } } - if (lat != AltosRecord.MISSING) { - show(pos(lat,"E", "W")); + if (lat != AltosLib.MISSING) { + show(pos(lat,"N", "S")); set_label(label); } else hide(); @@ -337,11 +337,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadLon extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - double lon = AltosRecord.MISSING; + double lon = AltosLib.MISSING; String label = null; if (state != null) { - if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lon != AltosRecord.MISSING) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lon != AltosLib.MISSING) { lon = state.gps.lon; label = "Longitude"; } else { @@ -349,7 +349,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { label = "Pad Longitude"; } } - if (lon != AltosRecord.MISSING) { + if (lon != AltosLib.MISSING) { show(pos(lon,"E", "W")); set_label(label); } else @@ -364,11 +364,11 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { class PadAlt extends LaunchValue { void show (AltosState state, AltosListenerState listener_state) { - double alt = AltosRecord.MISSING; + double alt = AltosLib.MISSING; String label = null; if (state != null) { - if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.alt != AltosRecord.MISSING) { + if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.alt != AltosLib.MISSING) { alt = state.gps.alt; label = "Altitude"; } else { @@ -376,7 +376,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay { label = "Pad Altitude"; } } - if (alt != AltosRecord.MISSING) { + if (alt != AltosLib.MISSING) { show("%4.0f m", state.gps.alt); set_label(label); } else diff --git a/altosui/AltosRomconfigUI.java b/altosui/AltosRomconfigUI.java index 909e72a0..6f9d9dc6 100644 --- a/altosui/AltosRomconfigUI.java +++ b/altosui/AltosRomconfigUI.java @@ -20,7 +20,7 @@ package altosui; import java.awt.*; import java.awt.event.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosRomconfigUI diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 224e1e61..a5ccb15a 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -25,7 +25,7 @@ import java.io.*; import java.util.*; import java.text.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class AltosScanResult { @@ -187,7 +187,7 @@ public class AltosScanUI AltosState state = reader.read(); if (state == null) continue; - if (state.flight != AltosRecord.MISSING) { + if (state.flight != AltosLib.MISSING) { final AltosScanResult result = new AltosScanResult(state.callsign, state.serial, state.flight, diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java index e869f1ab..697ad539 100644 --- a/altosui/AltosSerial.java +++ b/altosui/AltosSerial.java @@ -25,7 +25,7 @@ import java.io.*; import java.util.*; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; import libaltosJNI.*; diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java index c0926919..9491ce2b 100644 --- a/altosui/AltosSiteMap.java +++ b/altosui/AltosSiteMap.java @@ -23,7 +23,7 @@ import java.io.*; import java.lang.Math; import java.awt.geom.Point2D; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { @@ -287,10 +287,10 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay { return; if (!initialised) { - if (state.pad_lat != AltosRecord.MISSING && state.pad_lon != AltosRecord.MISSING) { + if (state.pad_lat != AltosLib.MISSING && state.pad_lon != AltosLib.MISSING) { initMaps(state.pad_lat, state.pad_lon); initialised = true; - } else if (gps.lat != AltosRecord.MISSING && gps.lon != AltosRecord.MISSING) { + } else if (gps.lat != AltosLib.MISSING && gps.lon != AltosLib.MISSING) { initMaps(gps.lat, gps.lon); initialised = true; } else { diff --git a/altosui/AltosSiteMapTile.java b/altosui/AltosSiteMapTile.java index 365e4b6c..172e6397 100644 --- a/altosui/AltosSiteMapTile.java +++ b/altosui/AltosSiteMapTile.java @@ -22,7 +22,7 @@ import java.awt.image.*; import javax.swing.*; import java.awt.geom.Point2D; import java.awt.geom.Line2D; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosSiteMapTile extends JLayeredPane { JLabel mapLabel; diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 31d5a54d..9dad8718 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -22,7 +22,7 @@ import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class AltosUI extends AltosUIFrame { @@ -492,7 +492,7 @@ public class AltosUI extends AltosUIFrame { stats.max_speed, AltosConvert.meters_to_feet(stats.max_speed), AltosConvert.meters_to_mach(stats.max_speed)); - if (stats.max_acceleration != AltosRecord.MISSING) { + if (stats.max_acceleration != AltosLib.MISSING) { System.out.printf("Max accel: %6.0f m/s² %6.0f ft/s² %6.2f g\n", stats.max_acceleration, AltosConvert.meters_to_feet(stats.max_acceleration), diff --git a/altosui/AltosUIPreferencesBackend.java b/altosui/AltosUIPreferencesBackend.java index 0dac9fc7..fb5f8520 100644 --- a/altosui/AltosUIPreferencesBackend.java +++ b/altosui/AltosUIPreferencesBackend.java @@ -19,7 +19,7 @@ package altosui; import java.io.File; import java.util.prefs.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import javax.swing.filechooser.FileSystemView; public class AltosUIPreferencesBackend implements AltosPreferencesBackend { diff --git a/altosui/AltosWriter.java b/altosui/AltosWriter.java index 8de11bc9..d664d6e8 100644 --- a/altosui/AltosWriter.java +++ b/altosui/AltosWriter.java @@ -17,7 +17,7 @@ package altosui; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public interface AltosWriter { diff --git a/altosuilib/AltosUIAxis.java b/altosuilib/AltosUIAxis.java index 867b0384..a38cba63 100644 --- a/altosuilib/AltosUIAxis.java +++ b/altosuilib/AltosUIAxis.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUIEnable.java b/altosuilib/AltosUIEnable.java index 55486dea..84803c0e 100644 --- a/altosuilib/AltosUIEnable.java +++ b/altosuilib/AltosUIEnable.java @@ -23,7 +23,7 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUIGraph.java b/altosuilib/AltosUIGraph.java index 5f3a2eef..ef0cc677 100644 --- a/altosuilib/AltosUIGraph.java +++ b/altosuilib/AltosUIGraph.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUIGrapher.java b/altosuilib/AltosUIGrapher.java index 8f0ce801..d826072f 100644 --- a/altosuilib/AltosUIGrapher.java +++ b/altosuilib/AltosUIGrapher.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUILib.java b/altosuilib/AltosUILib.java index 1b121405..9fcaf6d4 100644 --- a/altosuilib/AltosUILib.java +++ b/altosuilib/AltosUILib.java @@ -20,7 +20,7 @@ package org.altusmetrum.altosuilib_1; import java.awt.*; import libaltosJNI.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosUILib extends AltosLib { diff --git a/altosuilib/AltosUIMarker.java b/altosuilib/AltosUIMarker.java index 0949be6f..e4262abd 100644 --- a/altosuilib/AltosUIMarker.java +++ b/altosuilib/AltosUIMarker.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; diff --git a/altosuilib/AltosUIPreferences.java b/altosuilib/AltosUIPreferences.java index 49321bce..fc14f24b 100644 --- a/altosuilib/AltosUIPreferences.java +++ b/altosuilib/AltosUIPreferences.java @@ -21,7 +21,7 @@ import java.io.*; import java.util.*; import java.awt.Component; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; public class AltosUIPreferences extends AltosPreferences { diff --git a/altosuilib/AltosUIPreferencesBackend.java b/altosuilib/AltosUIPreferencesBackend.java index 8a5386c3..55da8d48 100644 --- a/altosuilib/AltosUIPreferencesBackend.java +++ b/altosuilib/AltosUIPreferencesBackend.java @@ -19,7 +19,7 @@ package org.altusmetrum.altosuilib_1; import java.io.File; import java.util.prefs.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import javax.swing.filechooser.FileSystemView; public class AltosUIPreferencesBackend implements AltosPreferencesBackend { diff --git a/altosuilib/AltosUISeries.java b/altosuilib/AltosUISeries.java index ac09a3cc..ff430d1a 100644 --- a/altosuilib/AltosUISeries.java +++ b/altosuilib/AltosUISeries.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.jfree.ui.*; import org.jfree.chart.*; @@ -34,6 +34,20 @@ import org.jfree.chart.labels.*; import org.jfree.data.xy.*; import org.jfree.data.*; +class AltosUITime extends AltosUnits { + public double value(double v) { return v; } + public String show_units() { return "s"; } + public String say_units() { return "seconds"; } + + public int show_fraction(int width) { + if (width < 5) + return 0; + return width - 5; + } + + public int say_fraction() { return 0; } +} + public class AltosUISeries extends XYSeries implements AltosUIGrapher { AltosUIAxis axis; String label; @@ -47,11 +61,12 @@ public class AltosUISeries extends XYSeries implements AltosUIGrapher { axis.set_units(); StandardXYToolTipGenerator ttg; - String example = units.graph_format(4); + String time_example = (new AltosUITime()).graph_format(7); + String example = units.graph_format(7); ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", units.show_units()), - new java.text.DecimalFormat(example), + new java.text.DecimalFormat(time_example), new java.text.DecimalFormat(example)); renderer.setBaseToolTipGenerator(ttg); } diff --git a/configure.ac b/configure.ac index 4d0a2ef6..e88109f9 100644 --- a/configure.ac +++ b/configure.ac @@ -31,7 +31,7 @@ dnl ========================================================================== dnl Java library versions ALTOSUILIB_VERSION=1 -ALTOSLIB_VERSION=1 +ALTOSLIB_VERSION=2 AC_SUBST(ALTOSLIB_VERSION) AC_DEFINE(ALTOSLIB_VERSION,$ALTOSLIB_VERSION,[Version of the AltosLib package]) diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java index 4c0ed4c3..07806fa4 100644 --- a/micropeak/MicroData.java +++ b/micropeak/MicroData.java @@ -20,7 +20,7 @@ package org.altusmetrum.micropeak; import java.lang.*; import java.io.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; class MicroIterator implements Iterator { diff --git a/micropeak/MicroDownload.java b/micropeak/MicroDownload.java index bd6795f8..a9095f9c 100644 --- a/micropeak/MicroDownload.java +++ b/micropeak/MicroDownload.java @@ -23,7 +23,7 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener { diff --git a/micropeak/MicroExport.java b/micropeak/MicroExport.java index 20a6f79a..5af767c6 100644 --- a/micropeak/MicroExport.java +++ b/micropeak/MicroExport.java @@ -23,7 +23,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroExport extends JFileChooser { diff --git a/micropeak/MicroFile.java b/micropeak/MicroFile.java index cdd42e66..2b02e20a 100644 --- a/micropeak/MicroFile.java +++ b/micropeak/MicroFile.java @@ -19,7 +19,7 @@ package org.altusmetrum.micropeak; import java.io.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroFile { diff --git a/micropeak/MicroFileChooser.java b/micropeak/MicroFileChooser.java index d52eab2c..3ca128ee 100644 --- a/micropeak/MicroFileChooser.java +++ b/micropeak/MicroFileChooser.java @@ -20,7 +20,7 @@ package org.altusmetrum.micropeak; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroFileChooser extends JFileChooser { diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java index 50508a61..fba62907 100644 --- a/micropeak/MicroGraph.java +++ b/micropeak/MicroGraph.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; import org.jfree.ui.*; diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index cb1c68cb..27a8db02 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -23,7 +23,7 @@ import javax.swing.*; import java.io.*; import java.util.concurrent.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroPeak extends MicroFrame implements ActionListener, ItemListener { diff --git a/micropeak/MicroRaw.java b/micropeak/MicroRaw.java index 7337a1de..0520fa71 100644 --- a/micropeak/MicroRaw.java +++ b/micropeak/MicroRaw.java @@ -20,7 +20,7 @@ package org.altusmetrum.micropeak; import java.awt.*; import java.io.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroRaw extends JTextArea { diff --git a/micropeak/MicroSave.java b/micropeak/MicroSave.java index 99f621ce..1f1ef3cb 100644 --- a/micropeak/MicroSave.java +++ b/micropeak/MicroSave.java @@ -24,7 +24,7 @@ import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; import java.util.concurrent.*; import java.util.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroSave extends JFileChooser { diff --git a/micropeak/MicroStats.java b/micropeak/MicroStats.java index 99479cb4..32d94432 100644 --- a/micropeak/MicroStats.java +++ b/micropeak/MicroStats.java @@ -18,7 +18,7 @@ package org.altusmetrum.micropeak; import java.io.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroStats { diff --git a/micropeak/MicroStatsTable.java b/micropeak/MicroStatsTable.java index 145bb70e..4400a317 100644 --- a/micropeak/MicroStatsTable.java +++ b/micropeak/MicroStatsTable.java @@ -19,7 +19,7 @@ package org.altusmetrum.micropeak; import java.awt.*; import javax.swing.*; -import org.altusmetrum.altoslib_1.*; +import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; public class MicroStatsTable extends JComponent implements AltosFontListener { -- cgit v1.2.3 From effc62354fc82bb937c6f445a147fc92153a0731 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Sep 2013 22:54:02 -0700 Subject: altoslib: Record time_change in AltosState correctly time_change is used to make real-time playback work. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index dba9bff8..42259057 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -632,7 +632,9 @@ public class AltosState implements Cloneable { received_time = old.received_time; time = old.time; - time_change = 0; + time_change = old.time_change; + prev_time = old.time; + tick = old.tick; prev_tick = old.tick; boost_tick = old.boost_tick; @@ -779,6 +781,7 @@ public class AltosState implements Cloneable { } tick = new_tick; time = tick / 100.0; + time_change = time - prev_time; } } -- cgit v1.2.3 From 4e22b34bde421a9df090c9196fd4347468c8176a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 6 Sep 2013 16:54:07 -0700 Subject: altoslib: Add receiver serial to telem file names Makes it easy to record telemetry from multiple sites and compare them later. Signed-off-by: Keith Packard --- altoslib/AltosFile.java | 33 +++++++++++++++++++++++++++------ altoslib/AltosLog.java | 17 ++++++++++------- altoslib/AltosState.java | 8 ++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosFile.java b/altoslib/AltosFile.java index 9802f883..f39c3962 100644 --- a/altoslib/AltosFile.java +++ b/altoslib/AltosFile.java @@ -24,15 +24,35 @@ public class AltosFile extends File { static String number(int n) { if (n == AltosLib.MISSING) - return "unk"; + return "unkn"; else - return String.format("%03d", n); + return String.format("%04d", n); } - public AltosFile(int year, int month, int day, int serial, int flight, String extension) { + static String receiver(int receiver) { + if (receiver == AltosLib.MISSING) + return ""; + return String.format("-via-%04d", receiver); + } + + public AltosFile(int year, int month, int day, int serial, int flight, int receiver, String extension) { super (AltosPreferences.logdir(), - String.format("%04d-%02d-%02d-serial-%s-flight-%s.%s", - year, month, day, number(serial), number(flight), extension)); + String.format("%04d-%02d-%02d-serial-%s-flight-%s%s.%s", + year, month, day, number(serial), number(flight), receiver(receiver), extension)); + } + + public AltosFile(int year, int month, int day, int serial, int flight, String extension) { + this(year, month, day, serial, flight, AltosLib.MISSING, extension); + } + + public AltosFile(int serial, int flight, int receiver, String extension) { + this(Calendar.getInstance().get(Calendar.YEAR), + Calendar.getInstance().get(Calendar.MONTH) + 1, + Calendar.getInstance().get(Calendar.DAY_OF_MONTH), + serial, + flight, + receiver, + extension); } public AltosFile(int serial, int flight, String extension) { @@ -41,10 +61,11 @@ public class AltosFile extends File { Calendar.getInstance().get(Calendar.DAY_OF_MONTH), serial, flight, + AltosLib.MISSING, extension); } public AltosFile(AltosState state) { - this(state.serial, state.flight, "telem"); + this(state.serial, state.flight, state.receiver_serial, "telem"); } } diff --git a/altoslib/AltosLog.java b/altoslib/AltosLog.java index ed59ef71..015d9f65 100644 --- a/altoslib/AltosLog.java +++ b/altoslib/AltosLog.java @@ -18,8 +18,8 @@ package org.altusmetrum.altoslib_2; import java.io.*; -import java.text.ParseException; -import java.util.concurrent.LinkedBlockingQueue; +import java.text.*; +import java.util.concurrent.*; /* * This creates a thread to capture telemetry data and write it to @@ -31,9 +31,11 @@ public class AltosLog implements Runnable { LinkedBlockingQueue pending_queue; int serial; int flight; + int receiver_serial; FileWriter log_file; Thread log_thread; AltosFile file; + AltosLink link; private void close_log_file() { if (log_file != null) { @@ -78,17 +80,16 @@ public class AltosLog implements Runnable { public void run () { try { - AltosState state = null; + AltosState state = new AltosState(); + AltosConfigData receiver_config = link.config_data(); + state.set_receiver_serial(receiver_config.serial); for (;;) { AltosLine line = input_queue.take(); if (line.line == null) continue; try { AltosTelemetry telem = AltosTelemetry.parse(line.line); - if (state != null) - state = state.clone(); - else - state = new AltosState(); + state = state.clone(); telem.update_state(state); if (state.serial != serial || state.flight != flight || log_file == null) { @@ -109,6 +110,7 @@ public class AltosLog implements Runnable { pending_queue.put(line.line); } } catch (InterruptedException ie) { + } catch (TimeoutException te) { } catch (IOException ie) { } close(); @@ -120,6 +122,7 @@ public class AltosLog implements Runnable { link.add_monitor(input_queue); serial = -1; flight = -1; + this.link = link; log_file = null; log_thread = new Thread(this); log_thread.start(); diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 42259057..5a805fc6 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -269,6 +269,7 @@ public class AltosState implements Cloneable { public int state; public int flight; public int serial; + public int receiver_serial; public boolean landed; public boolean ascent; /* going up? */ public boolean boost; /* under power */ @@ -604,6 +605,7 @@ public class AltosState implements Cloneable { log_format = AltosLib.MISSING; serial = AltosLib.MISSING; + receiver_serial = AltosLib.MISSING; baro = null; companion = null; @@ -725,6 +727,7 @@ public class AltosState implements Cloneable { log_format = old.log_format; serial = old.serial; + receiver_serial = old.receiver_serial; baro = old.baro; companion = old.companion; @@ -847,6 +850,11 @@ public class AltosState implements Cloneable { } } + public void set_receiver_serial(int serial) { + if (serial != AltosLib.MISSING) + receiver_serial = serial; + } + public int rssi() { if (rssi == AltosLib.MISSING) return 0; -- cgit v1.2.3 From be7f56b86478ef4a23a2af77338c580b9c9e5e3b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 19 Sep 2013 00:26:24 -0500 Subject: altoslib: Prefer averaged ground pres for ground alt computation If ground pressure is recorded (as from an eeprom file), then prefer that value to the average of the pre-boost ground pressures when computing the ground altitude. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 5a805fc6..a9bb1e70 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -301,7 +301,8 @@ public class AltosState implements Cloneable { class AltosGroundPressure extends AltosCValue { void set_filtered(double p, double time) { computed.set_filtered(p, time); - ground_altitude.set_computed(pressure_to_altitude(computed.value()), time); + if (!is_measured()) + ground_altitude.set_computed(pressure_to_altitude(computed.value()), time); } void set_measured(double p, double time) { @@ -657,6 +658,7 @@ public class AltosState implements Cloneable { set = 0; + ground_pressure.copy(old.ground_pressure); ground_altitude.copy(old.ground_altitude); altitude.copy(old.altitude); pressure.copy(old.pressure); -- cgit v1.2.3 From 71666409624bf544e8a55fa5ee91d2f8514a03ca Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 7 Oct 2013 21:49:55 -0700 Subject: Change differentiation filter constants and limits Larger limits avoids clipping legit data. Using the same filter time for both ascent and descent makes the results look a bit cleaner. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index a9bb1e70..a01cddb7 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -29,8 +29,8 @@ public class AltosState implements Cloneable { public int set; - static final double ascent_filter_len = 0.1; - static final double descent_filter_len = 2.0; + static final double ascent_filter_len = 0.5; + static final double descent_filter_len = 0.5; /* derived data */ @@ -49,7 +49,6 @@ public class AltosState implements Cloneable { private double max_value; private double set_time; private double prev_set_time; - private double max_rate = 1000.0; void set(double new_value, double time) { if (new_value != AltosLib.MISSING) { @@ -125,12 +124,14 @@ public class AltosState implements Cloneable { double ddt = in.time() - pt; double ddv = (n - p) / ddt; + final double max = 100000; + /* 100gs */ - if (Math.abs(ddv) > 1000) { + if (Math.abs(ddv) > max) { if (n > p) - n = p + ddt * 1000; + n = p + ddt * max; else - n = p - ddt * 1000; + n = p - ddt * max; } double filter_len; -- cgit v1.2.3 From db4cd8b3838d27bebdeb6a085a739a36f7634a91 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 14 Oct 2013 20:42:14 -0700 Subject: altoslib,altosui: Be more robust when graphing bogus .telem files Deal with files containing multiple serial number/flight number values by preserving the boost_tick value across state resets. Check for invalid state when computing actual boost time for the stats window. Ignore invalid speed/accel values when computing averages. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 11 +++++++---- altoslib/AltosTelemetryIterable.java | 2 +- altosui/AltosFlightStats.java | 34 ++++++++++++++++++++-------------- 3 files changed, 28 insertions(+), 19 deletions(-) (limited to 'altoslib/AltosState.java') diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index a01cddb7..6d55b833 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -836,7 +836,9 @@ public class AltosState implements Cloneable { if (flight != AltosLib.MISSING && flight != 0) { if (this.flight != AltosLib.MISSING && this.flight != flight) { + int bt = boost_tick; init(); + boost_tick = bt; } this.flight = flight; } @@ -847,7 +849,9 @@ public class AltosState implements Cloneable { if (serial != AltosLib.MISSING) { if (this.serial != AltosLib.MISSING && this.serial != serial) { + int bt = boost_tick; init(); + boost_tick = bt; } this.serial = serial; } @@ -1017,10 +1021,9 @@ public class AltosState implements Cloneable { if (tick == AltosLib.MISSING) return 0.0; - if (boost_tick != AltosLib.MISSING) { - return (tick - boost_tick) / 100.0; - } - return tick / 100.0; + if (boost_tick == AltosLib.MISSING) + return tick / 100.0; + return (tick - boost_tick) / 100.0; } public boolean valid() { diff --git a/altoslib/AltosTelemetryIterable.java b/altoslib/AltosTelemetryIterable.java index 9da3b0e6..bf30b4c8 100644 --- a/altoslib/AltosTelemetryIterable.java +++ b/altoslib/AltosTelemetryIterable.java @@ -68,7 +68,7 @@ public class AltosTelemetryIterable implements Iterable { public void add (AltosTelemetry telem) { int t = telem.tick; if (!telems.isEmpty()) { - while (t < tick - 32767) + while (t < tick - 1000) t += 65536; } tick = t; diff --git a/altosui/AltosFlightStats.java b/altosui/AltosFlightStats.java index 11a3f1a9..552210c3 100644 --- a/altosui/AltosFlightStats.java +++ b/altosui/AltosFlightStats.java @@ -84,7 +84,7 @@ public class AltosFlightStats { state = s; if (state.acceleration() < 1) boost_time = state.time; - if (state.state >= Altos.ao_flight_boost) + if (state.state >= AltosLib.ao_flight_boost && state.state <= AltosLib.ao_flight_landed) break; } if (state == null) @@ -118,10 +118,12 @@ public class AltosFlightStats { if (state.rssi != AltosLib.MISSING) has_rssi = true; end_time = state.time; - if (state.time >= boost_time && state.state < Altos.ao_flight_boost) - state.state = Altos.ao_flight_boost; - if (state.time >= landed_time && state.state < Altos.ao_flight_landed) - state.state = Altos.ao_flight_landed; + + int state_id = state.state; + if (state.time >= boost_time && state_id < Altos.ao_flight_boost) + state_id = Altos.ao_flight_boost; + if (state.time >= landed_time && state_id < Altos.ao_flight_landed) + state_id = Altos.ao_flight_landed; if (state.gps != null && state.gps.locked) { year = state.gps.year; month = state.gps.month; @@ -130,20 +132,24 @@ public class AltosFlightStats { minute = state.gps.minute; second = state.gps.second; } - if (0 <= state.state && state.state < Altos.ao_flight_invalid) { - state_accel[state.state] += state.acceleration(); - state_speed[state.state] += state.speed(); - state_count[state.state]++; - if (state_start[state.state] == 0.0) - state_start[state.state] = state.time; - if (state_end[state.state] < state.time) - state_end[state.state] = state.time; + if (0 <= state_id && state_id < Altos.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; max_height = state.max_height(); max_speed = state.max_speed(); max_acceleration = state.max_acceleration(); } if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) { - if (state.state <= Altos.ao_flight_pad) { + if (state_id <= Altos.ao_flight_pad) { pad_lat = state.gps.lat; pad_lon = state.gps.lon; } -- cgit v1.2.3