diff options
| author | Keith Packard <keithp@keithp.com> | 2013-08-29 19:24:51 -0500 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2013-08-29 19:24:51 -0500 | 
| commit | de8d9c5630ae46378c50faf97f7d2e97fe139e30 (patch) | |
| tree | e8e41e4186c5d27e1a5184d915bdb9f08926fa7a | |
| parent | ce1378385ef273010498e81c205f42d8e32c7dc1 (diff) | |
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 <keithp@keithp.com>
41 files changed, 907 insertions, 645 deletions
| 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> { +	AltosState		state; +	Iterator<AltosEeprom>	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<AltosEeprom> 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<AltosState> iterator() { + +		AltosState		state = headers.state(); +		Iterator<AltosEeprom>  	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<AltosEepromHeader> {  	}  	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<AltosEepromOrdered> { +	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<AltosEeprom> { +	TreeSet<AltosEepromOrdered>	olist; +	Iterator<AltosEepromOrdered>	oiterator; + +	public AltosEepromOrderedIterator(Iterable<AltosEeprom> eeproms) { +		olist = new TreeSet<AltosEepromOrdered>(); + +		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<AltosEeprom> {  	public LinkedList<AltosEeprom> eeproms; @@ -30,7 +98,7 @@ public class AltosEepromIterable implements Iterable<AltosEeprom> {  	}  	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<AltosEeprom> {  	public Iterator<AltosEeprom> iterator() {  		if (eeproms == null)  			eeproms = new LinkedList<AltosEeprom>(); -		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<AltosEepromMini> {  	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<AltosEeprom> read(FileInputStream input) { +		LinkedList<AltosEeprom> tms = new LinkedList<AltosEeprom>(); + +		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 <AltosRecord>, 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 <AltosRecord>, 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<AltosRecord>	iterator; +	Iterator<AltosState>	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<AltosRecord> in_iterator, File in_file) { +	public AltosReplayReader(Iterator<AltosState> 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 <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.*; + +public abstract class AltosStateIterable implements Iterable<AltosState> { + +	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<AltosLine> 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<AltosRecord>	pad_records; +	LinkedList<AltosState>	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<AltosRecord>(); +		pad_states = new LinkedList<AltosState>();  	}  	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<AltosState>	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<AltosUIDataPoint> {  	AltosGraphDataSet	dataSet; -	Iterator<AltosRecord>	iterator; - -	AltosState	state; +	Iterator<AltosState>	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<AltosRecord> iterator, AltosGraphDataSet dataSet) { +	public AltosGraphIterator (Iterator<AltosState> iterator, AltosGraphDataSet dataSet) {  		this.iterator = iterator; -		this.state = null;  		this.dataSet = dataSet;  	} @@ -64,7 +61,7 @@ class AltosGraphIterable implements Iterable<AltosUIDataPoint> {  	AltosGraphDataSet	dataSet;  	public Iterator<AltosUIDataPoint> 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 {  		"</Document>\n" +  		"</kml>\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<AltosState> 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();  } | 
