diff options
Diffstat (limited to 'altoslib/AltosEepromMiniIterable.java')
| -rw-r--r-- | altoslib/AltosEepromMiniIterable.java | 297 | 
1 files changed, 297 insertions, 0 deletions
| diff --git a/altoslib/AltosEepromMiniIterable.java b/altoslib/AltosEepromMiniIterable.java new file mode 100644 index 00000000..1f221187 --- /dev/null +++ b/altoslib/AltosEepromMiniIterable.java @@ -0,0 +1,297 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromMiniIterable extends AltosRecordIterable { + +	static final int	seen_flight = 1; +	static final int	seen_sensor = 2; + +	static final int	seen_basic = seen_flight|seen_sensor; + +	boolean			has_accel; +	boolean			has_gps; +	boolean			has_ignite; + +	AltosEepromMini	flight_record; + +	TreeSet<AltosOrderedMiniRecord>	records; + +	AltosMs5607		baro; + +	LinkedList<AltosRecord>	list; + +	class EepromState { +		int	seen; +		int	n_pad_samples; +		double	ground_pres; +		int	boost_tick; +		int	sensor_tick; + +		EepromState() { +			seen = 0; +			n_pad_samples = 0; +			ground_pres = 0.0; +		} +	} + +	void update_state(AltosRecordMini state, AltosEepromMini record, EepromState eeprom) { +		state.tick = record.tick; +		switch (record.cmd) { +		case AltosLib.AO_LOG_FLIGHT: +			eeprom.seen |= seen_flight; +			state.ground_pres = record.ground_pres(); +			state.flight_pres = state.ground_pres; +			state.flight = record.data16(0); +			eeprom.boost_tick = record.tick; +			break; +		case AltosLib.AO_LOG_SENSOR: +			baro.set(record.pres(), record.temp()); +			state.pres = baro.pa; +			state.temp = baro.cc; +			state.sense_m = record.sense_m(); +			state.sense_a = record.sense_a(); +			state.v_batt = record.v_batt(); +			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; +			} +			if ((eeprom.seen & seen_sensor) == 0) +				eeprom.sensor_tick = record.tick - 1; +			eeprom.seen |= seen_sensor; +			eeprom.sensor_tick = record.tick; +			break; +		case AltosLib.AO_LOG_STATE: +			state.state = record.state(); +			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_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<AltosRecord> make_list() { +		LinkedList<AltosRecord>		list = new LinkedList<AltosRecord>(); +		Iterator<AltosOrderedMiniRecord> iterator = records.iterator(); +		AltosOrderedMiniRecord		record = null; +		AltosRecordMini			state = new AltosRecordMini(); +		//boolean			last_reported = false; +		EepromState			eeprom = new EepromState(); + +		state.state = AltosLib.ao_flight_pad; + +		/* Pull in static data from the flight records */ +		if (flight_record != null) +			update_state(state, flight_record, eeprom); + +		while (iterator.hasNext()) { +			record = iterator.next(); +			if ((eeprom.seen & seen_basic) == seen_basic && record.tick != state.tick) { +				AltosRecordMini r = state.clone(); +				r.time = (r.tick - eeprom.boost_tick) / 100.0; +				list.add(r); +			} +			update_state(state, record, eeprom); +		} +		AltosRecordMini r = state.clone(); +		r.time = (r.tick - eeprom.boost_tick) / 100.0; +		list.add(r); +		return list; +	} + +	public Iterator<AltosRecord> 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<AltosOrderedMiniRecord>	iterator = records.iterator(); +		out.printf("# Comments\n"); +		while (iterator.hasNext()) { +			AltosOrderedMiniRecord	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 +	 */ +	public AltosEepromMiniIterable (FileInputStream input) { +		records = new TreeSet<AltosOrderedMiniRecord>(); + +		AltosOrderedMiniRecord 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; +				AltosOrderedMiniRecord record = new AltosOrderedMiniRecord(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) { +		} +	} +} | 
