X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosEepromDownload.java;h=280414f8e9a32d5b81906ec50a7fd6b73c527519;hp=594f053f5cc012e3f71289f2855fb9fb28891617;hb=06b1fc72c8a694b3295262f1e0b50e8c88c53585;hpb=926522c6791c2a5529ea24ebd67eea45350e3526 diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java index 594f053f..280414f8 100644 --- a/altoslib/AltosEepromDownload.java +++ b/altoslib/AltosEepromDownload.java @@ -3,7 +3,8 @@ * * 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. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,13 +16,61 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_8; +package org.altusmetrum.altoslib_13; import java.io.*; import java.util.*; import java.text.*; import java.util.concurrent.*; +class AltosEepromNameData extends AltosDataListener { + AltosGPS gps = null; + + public void set_rssi(int rssi, int status) { } + public void set_received_time(long received_time) { } + + public void set_acceleration(double accel) { } + public void set_pressure(double pa) { } + public void set_thrust(double N) { } + + public void set_temperature(double deg_c) { } + public void set_battery_voltage(double volts) { } + + public void set_apogee_voltage(double volts) { } + public void set_main_voltage(double volts) { } + + public void set_gps(AltosGPS gps) { + super.set_gps(gps); + if (gps != null && + gps.year != AltosLib.MISSING && + gps.month != AltosLib.MISSING && + gps.day != AltosLib.MISSING) { + this.gps = gps; + } + } + + public boolean done() { + if (gps == null) + return false; + return true; + } + + public void set_gyro(double roll, double pitch, double yaw) { } + public void set_accel_ground(double along, double across, double through) { } + public void set_accel(double along, double across, double through) { } + public void set_mag(double along, double across, double through) { } + public void set_pyro_voltage(double volts) { } + public void set_igniter_voltage(double[] voltage) { } + public void set_pyro_fired(int pyro_mask) { } + public void set_companion(AltosCompanion companion) { } + public void set_kalman(double height, double speed, double acceleration) { } + public void set_orient(double new_orient) { } + + public AltosEepromNameData(AltosCalData cal_data) { + super(cal_data); + } +} + public class AltosEepromDownload implements Runnable { AltosLink link; @@ -29,65 +78,38 @@ public class AltosEepromDownload implements Runnable { Thread eeprom_thread; AltosEepromMonitor monitor; - boolean want_file; - FileWriter eeprom_file; - LinkedList eeprom_pending; - AltosEepromList flights; - boolean success; String parse_errors; - AltosState state; - private void FlushPending() throws IOException { - for (String s : flights.config_data) { - eeprom_file.write(s); - eeprom_file.write('\n'); - } + private boolean has_gps_date(AltosState state) { + if (state == null) + return false; - for (String s : eeprom_pending) - eeprom_file.write(s); + AltosGPS gps = state.gps; + + return gps != null && + gps.year != AltosLib.MISSING && + gps.month != AltosLib.MISSING && + gps.day != AltosLib.MISSING; } - private void CheckFile(boolean force) throws IOException { - if (eeprom_file != null) - return; - if (force || (state.flight != 0 && want_file)) { - AltosFile eeprom_name; - AltosGPS gps = state.gps; - - if (gps != null && - 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"); - } else - eeprom_name = new AltosFile(state.serial, state.flight, "eeprom"); - - eeprom_file = new FileWriter(eeprom_name); - if (eeprom_file != null) { - monitor.set_filename(eeprom_name.getName()); - FlushPending(); - eeprom_pending = null; - } - } + private AltosFile MakeFile(int serial, int flight, AltosEepromNameData name_data) throws IOException { + AltosFile eeprom_name; + + if (name_data.gps != null) { + AltosGPS gps = name_data.gps; + eeprom_name = new AltosFile(gps.year, gps.month, gps.day, + serial, flight, "eeprom"); + } else + eeprom_name = new AltosFile(serial, flight, "eeprom"); + + return eeprom_name; } boolean done; int prev_state; int state_block; - void LogEeprom(AltosEeprom r) throws IOException { - if (r.cmd != AltosLib.AO_LOG_INVALID) { - String line = r.string(); - if (eeprom_file != null) - eeprom_file.write(line); - else - eeprom_pending.add(line); - } - } - void LogError(String error) { if (parse_errors != null) parse_errors.concat(error.concat("\n")); @@ -95,142 +117,147 @@ public class AltosEepromDownload implements Runnable { parse_errors = error; } - void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException, ParseException { - boolean any_valid = false; - boolean got_flight = false; - - int record_length = 8; + class BlockCache extends Hashtable { + AltosEepromLog log; - state.set_serial(flights.config_data.serial); - monitor.set_serial(flights.config_data.serial); - - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { - AltosEeprom r = null; - - try { - r = eechunk.eeprom(i, log_format, state); - } catch (ParseException pe) { - LogError(pe.getMessage()); - r = null; - } - - if (r == null) - continue; - - record_length = r.record_length(); - - r.update_state(state); + AltosEepromChunk get(int start, boolean add) throws TimeoutException, InterruptedException { + if (contains(start)) + return super.get(start); + AltosEepromChunk eechunk = new AltosEepromChunk(link, start, start == log.start_block); + if (add) + put(start, eechunk); + return eechunk; + } - if (!got_flight && state.flight != AltosLib.MISSING) - monitor.set_flight(state.flight); + public BlockCache(AltosEepromLog log) { + this.log = log; + } + } - /* Monitor state transitions to update display */ - if (state.state() != AltosLib.ao_flight_invalid && - state.state() <= AltosLib.ao_flight_landed) - { - if (state.state() > AltosLib.ao_flight_pad) - want_file = true; - if (state.state() == AltosLib.ao_flight_landed) - done = true; - } + int FindLastLog(AltosEepromLog log, BlockCache cache) throws TimeoutException, InterruptedException { + int low = log.start_block; + int high = log.end_block - 1; - if (state.gps != null) - want_file = true; + while (low <= high) { + int mid = (high + low) / 2; - if (r.valid) { - any_valid = true; - LogEeprom(r); - } + if (!cache.get(mid, true).erased()) + low = mid + 1; + else + high = mid - 1; } - if (!any_valid) - done = true; - - CheckFile(false); + return low; } void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException, ParseException { int block, state_block = 0; int log_format = flights.config_data.log_format; - - state = new AltosState(); + BlockCache cache = new BlockCache(log); done = false; if (flights.config_data.serial < 0) throw new IOException("no serial number found"); - /* Reset per-capture variables */ - want_file = false; - eeprom_pending = new LinkedList(); - /* Set serial number in the monitor dialog window */ - /* Now scan the eeprom, reading blocks of data and converting to .eeprom file form */ - - state_block = log.start_block; - prev_state = AltosLib.ao_flight_startup; - for (block = log.start_block; !done && block < log.end_block; block++) { - AltosEepromChunk eechunk = new AltosEepromChunk(link, block, block == log.start_block); - - /* - * Guess what kind of data is there if the device - * didn't tell us - */ - - if (log_format == AltosLib.AO_LOG_FORMAT_UNKNOWN) { - if (block == log.start_block) { - if (eechunk.data(0) == AltosLib.AO_LOG_FLIGHT) - log_format = AltosLib.AO_LOG_FORMAT_FULL; - else - log_format = AltosLib.AO_LOG_FORMAT_TINY; - } - } + monitor.set_serial(log.serial); + monitor.set_flight(log.flight); - CaptureEeprom (eechunk, log_format); + int start_block = log.start_block; + int end_block = FindLastLog(log, cache); - if (state.state() != prev_state && state.state() != AltosLib.ao_flight_invalid) { - state_block = block; - prev_state = state.state(); - } + monitor.set_max(end_block - start_block - 1); + + ArrayList data = new ArrayList(); + + /* Now scan the eeprom, reading blocks of data to create a byte array of data */ + + for (block = start_block; block < end_block; block++) { + monitor.set_block(block - start_block); - monitor.set_value(state.state_name(), - state.state(), - block - state_block, - block - log.start_block); + AltosEepromChunk eechunk = cache.get(block, false); + + for (int i = 0; i < eechunk.data.length; i++) + data.add((byte) eechunk.data[i]); + } + + /* Construct our internal representation of the eeprom data */ + AltosEeprom eeprom = new AltosEeprom(flights.config_data, data); + + /* Now see if we can't actually parse the resulting + * file to generate a better filename. Note that this + * doesn't need to work; we'll still save the data using + * a less accurate name. + */ + AltosEepromRecordSet set = new AltosEepromRecordSet(eeprom); + AltosEepromNameData name_data = new AltosEepromNameData(set.cal_data()); + + for (AltosEepromRecord record : set.ordered) { + record.provide_data(name_data, set.cal_data()); + if (name_data.done()) + break; } - CheckFile(true); + + AltosFile f = MakeFile(flights.config_data.serial, log.flight, name_data); + + log.set_file(f); + + boolean do_write = true; + + if (f.exists()) + do_write = monitor.check_overwrite(f); + + if (do_write) { + FileWriter w = new FileWriter(f); + + eeprom.write(w); + w.close(); + } + + if (eeprom.errors != 0) + throw new ParseException(String.format("%d CRC Errors", eeprom.errors), 0); + } + + static String label(int flight) { + if (flight < 0) + return "Corrupt"; + else + return "Flight"; + } + + static int flight(int flight) { + if (flight < 0) + return -flight; + return flight; } public void run () { + boolean success = false; + try { - boolean failed = false; if (remote) link.start_remote(); for (AltosEepromLog log : flights) { parse_errors = null; - if (log.selected) { + if (log.download_selected) { monitor.reset(); - eeprom_file = null; try { CaptureLog(log); } catch (ParseException e) { LogError(e.getMessage()); } - if (eeprom_file != null) { - eeprom_file.flush(); - eeprom_file.close(); - } } + success = true; if (parse_errors != null) { - failed = true; - monitor.show_message(String.format("Flight %d download error. Valid log data saved\n%s", - log.flight, + monitor.show_message(String.format("%s %d download error. Valid log data saved\n%s", + label(log.flight), + flight(log.flight), parse_errors), link.name, AltosEepromMonitor.WARNING_MESSAGE); } } - success = !failed; } catch (IOException ee) { monitor.show_message(ee.getLocalizedMessage(), link.name, @@ -272,12 +299,6 @@ public class AltosEepromDownload implements Runnable { link = given_link; remote = given_remote; flights = given_flights; - success = false; - - if (flights.config_data.log_has_state()) - monitor.set_states(AltosLib.ao_flight_boost, AltosLib.ao_flight_landed); - else - monitor.set_states(AltosLib.ao_flight_invalid, AltosLib.ao_flight_invalid); monitor.start(); }