diff options
40 files changed, 1552 insertions, 604 deletions
| diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index a1e2cdca..cf2bc59f 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -196,6 +196,28 @@ public class AltosConvert {  		return ((count / 16.0) / 2047.0 + 0.095) / 0.009 * 1000.0;  	} +	static double +	thermometer_to_temperature(double thermo) +	{ +		return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; +	} + +	static double mega_adc(int raw) { +		return raw / 4095.0; +	} + +	static public double mega_battery_voltage(int v_batt) { +		if (v_batt != AltosRecord.MISSING) +			return 3.3 * mega_adc(v_batt) * (15.0 + 27.0) / 27.0; +		return AltosRecord.MISSING; +	} + +	static double mega_pyro_voltage(int raw) { +		if (raw != AltosRecord.MISSING) +			return 3.3 * mega_adc(raw) * (100.0 + 27.0) / 27.0; +		return AltosRecord.MISSING; +	} +  	public static double radio_to_frequency(int freq, int setting, int cal, int channel) {  		double	f; diff --git a/altoslib/AltosEeprom.java b/altoslib/AltosEeprom.java index 31646c7e..081b3be1 100644 --- a/altoslib/AltosEeprom.java +++ b/altoslib/AltosEeprom.java @@ -27,8 +27,26 @@ public abstract class AltosEeprom implements AltosStateUpdate {  	public int	data8[];  	public boolean	valid; +	public int data8(int i) { +		return data8[i]; +	} + +	public int data16(int i) { +		return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; +	} + +	public int data24(int i) { +		return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16); +	} + +	public int data32(int i) { +		return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); +	} +  	public final static int header_length = 4; +	public abstract int record_length(); +  	public abstract void update_state(AltosState state);  	public void write(PrintStream out) { @@ -40,14 +58,28 @@ public abstract class AltosEeprom implements AltosStateUpdate {  		out.printf ("\n");  	} -	void parse_chunk(AltosEepromChunk chunk, int start, int record_length) throws ParseException { +	public String string() { +		String	s; + +		s = String.format("%c %04x", cmd, tick); +		if (data8 != null) { +			for (int i = 0; i < data8.length; i++) { +				String	d = String.format(" %02x", data8[i]); +				s = s.concat(d); +			} +		} +		s = s.concat("\n"); +		return s; +	} + +	void parse_chunk(AltosEepromChunk chunk, int start) throws ParseException {  		cmd = chunk.data(start); -		int data_length = record_length - header_length; +		int data_length = record_length() - header_length; -		valid = !chunk.erased(start, record_length); +		valid = !chunk.erased(start, record_length());  		if (valid) { -			if (AltosConvert.checksum(chunk.data, start, record_length) != 0) +			if (AltosConvert.checksum(chunk.data, start, record_length()) != 0)  				throw new ParseException(String.format("invalid checksum at 0x%x",  								       chunk.address + start), 0);  		} else { @@ -61,12 +93,12 @@ public abstract class AltosEeprom implements AltosStateUpdate {  			data8[i] = chunk.data(start + header_length + i);  	} -	void parse_string(String line, int record_length) { +	void parse_string(String line) {  		valid = false;  		tick = 0;  		cmd = AltosLib.AO_LOG_INVALID; -		int data_length = record_length - header_length; +		int data_length = record_length() - header_length;  		if (line == null)  			return; @@ -79,6 +111,7 @@ public abstract class AltosEeprom implements AltosStateUpdate {  					tick = Integer.parseInt(tokens[1],16);  					valid = true;  					data8 = new int[data_length]; +  					for (int i = 0; i < data_length; i++)  						data8[i] = Integer.parseInt(tokens[2 + i],16);  				} diff --git a/altoslib/AltosEepromChunk.java b/altoslib/AltosEepromChunk.java index b1bba3bb..1709352b 100644 --- a/altoslib/AltosEepromChunk.java +++ b/altoslib/AltosEepromChunk.java @@ -62,6 +62,32 @@ public class AltosEepromChunk {  		return true;  	} +	public AltosEeprom eeprom(int offset, int log_format) { +		AltosEeprom	eeprom = null; +		try { +			switch (log_format) { +			case AltosLib.AO_LOG_FORMAT_FULL: +				eeprom = new AltosEepromTM(this, offset); +				break; +			case AltosLib.AO_LOG_FORMAT_TINY: +			case AltosLib.AO_LOG_FORMAT_TELEMETRY: +			case AltosLib.AO_LOG_FORMAT_TELESCIENCE: +			case AltosLib.AO_LOG_FORMAT_TELEMEGA: +				eeprom = new AltosEepromMega(this, offset); +				break; +			case AltosLib.AO_LOG_FORMAT_TELEMETRUM: +				eeprom = new AltosEepromMetrum2(this, offset); +				break; +			case AltosLib.AO_LOG_FORMAT_TELEMINI: +			case AltosLib.AO_LOG_FORMAT_EASYMINI: +				eeprom = new AltosEepromMini(this, offset); +				break; +			} +		} catch (ParseException e) { +		} +		return eeprom; +	} +  	public AltosEepromChunk(AltosLink link, int block, boolean flush)  		throws TimeoutException, InterruptedException { diff --git a/altoslib/AltosEepromFile.java b/altoslib/AltosEepromFile.java index 2f4c54d7..367b6791 100644 --- a/altoslib/AltosEepromFile.java +++ b/altoslib/AltosEepromFile.java @@ -72,6 +72,7 @@ public class AltosEepromFile extends AltosStateIterable {  		headers = new AltosEepromIterable(AltosEepromHeader.read(input));  		start = headers.state(); +		start.set_state(AltosLib.ao_flight_pad);  		switch (start.log_format) {  		case AltosLib.AO_LOG_FORMAT_FULL: @@ -81,6 +82,10 @@ public class AltosEepromFile extends AltosStateIterable {  		case AltosLib.AO_LOG_FORMAT_TELEMETRY:  		case AltosLib.AO_LOG_FORMAT_TELESCIENCE:  		case AltosLib.AO_LOG_FORMAT_TELEMEGA: +			body = new AltosEepromIterable(AltosEepromMega.read(input)); +			break; +		case AltosLib.AO_LOG_FORMAT_TELEMETRUM: +			body = new AltosEepromIterable(AltosEepromMetrum2.read(input));  			break;  		case AltosLib.AO_LOG_FORMAT_TELEMINI:  		case AltosLib.AO_LOG_FORMAT_EASYMINI: diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java new file mode 100644 index 00000000..d8e47a6e --- /dev/null +++ b/altoslib/AltosEepromGPS.java @@ -0,0 +1,178 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromGPS extends AltosEeprom { +	public static final int	record_length = 16; + +	public int record_length() { return record_length; } + +	/* AO_LOG_FLIGHT elements */ +	public int flight() { return data16(0); } +	public int ground_accel() { return data16(2); } +	public int ground_pres() { return data32(4); } +	public int ground_temp() { return data32(8); } + +	/* AO_LOG_STATE elements */ +	public int state() { return data16(0); } +	public int reason() { return data16(2); } + +	/* AO_LOG_SENSOR elements */ +	public int pres() { return data32(0); } +	public int temp() { return data32(4); } +	public int accel() { return data16(8); } + +	/* AO_LOG_TEMP_VOLT elements */ +	public int v_batt() { return data16(0); } +	public int sense_a() { return data16(2); } +	public int sense_m() { return data16(4); } + +	/* AO_LOG_GPS_POS elements */ +	public int latitude() { return data32(0); } +	public int longitude() { return data32(4); } +	public int altitude() { return data16(8); } + +	/* AO_LOG_GPS_TIME elements */ +	public int hour() { return data8(0); } +	public int minute() { return data8(1); } +	public int second() { return data8(2); } +	public int flags() { return data8(3); } +	public int year() { return data8(4); } +	public int month() { return data8(5); } +	public int day() { return data8(6); } +	 +	/* AO_LOG_GPS_SAT elements */ +	public int nsat() { return data8(0); } +	public int more() { return data8(1); } +	public int svid(int n) { return data8(2 + n * 2); } +	public int c_n(int n) { return data8(2 + n * 2 + 1); } + +	public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException { +		parse_chunk(chunk, start); +	} + +	public void update_state(AltosState state) { +		AltosGPS	gps; + +		/* Flush any pending GPS changes */ +		if (state.gps_pending) { +			switch (cmd) { +			case AltosLib.AO_LOG_GPS_POS: +			case AltosLib.AO_LOG_GPS_LAT: +			case AltosLib.AO_LOG_GPS_LON: +			case AltosLib.AO_LOG_GPS_ALT: +			case AltosLib.AO_LOG_GPS_SAT: +			case AltosLib.AO_LOG_GPS_DATE: +				break; +			default: +				state.set_temp_gps(); +				break; +			} +		} + +		if (cmd != AltosLib.AO_LOG_FLIGHT) +			state.set_tick(tick); +		switch (cmd) { +		case AltosLib.AO_LOG_FLIGHT: +			state.set_boost_tick(tick); +			state.set_flight(flight()); +			state.set_ground_accel(ground_accel()); +			state.set_ground_pressure(ground_pres()); +//			state.set_temperature(ground_temp() / 100.0); +			break; +		case AltosLib.AO_LOG_STATE: +			state.set_state(state()); +			break; +		case AltosLib.AO_LOG_SENSOR: +			state.set_ms5607(pres(), temp()); +			state.set_accel(accel()); + +			break; +		case AltosLib.AO_LOG_TEMP_VOLT: +			state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); + +			state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a())); +			state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m())); + +			break; +		case AltosLib.AO_LOG_GPS_POS: +			gps = state.make_temp_gps(); +			gps.lat = latitude() / 1e7; +			gps.lon = longitude() / 1e7; +			gps.alt = altitude(); +			break; +		case AltosLib.AO_LOG_GPS_TIME: +			gps = state.make_temp_gps(); + +			gps.hour = hour(); +			gps.minute = minute(); +			gps.second = second(); + +			int flags = flags(); + +			gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; +			gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; +			gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> +				AltosLib.AO_GPS_NUM_SAT_SHIFT; + +			gps.year = year(); +			gps.month = month(); +			gps.day = day(); +			break; +		case AltosLib.AO_LOG_GPS_SAT: +			state.set_tick(tick); +			gps = state.make_temp_gps(); + +			int n = nsat(); +			for (int i = 0; i < n; i++) +				gps.add_sat(svid(i), c_n(i)); +			break; +		} +	} + +	public AltosEepromMetrum2 (String line) { +		parse_string(line); +	} + +	static public LinkedList<AltosEeprom> read(FileInputStream input) { +		LinkedList<AltosEeprom> megas = new LinkedList<AltosEeprom>(); + +		for (;;) { +			try { +				String line = AltosLib.gets(input); +				if (line == null) +					break; +				try { +					AltosEepromMetrum2 mega = new AltosEepromMetrum2(line); +					if (mega.cmd != AltosLib.AO_LOG_INVALID) +						megas.add(mega); +				} catch (Exception e) { +					System.out.printf ("exception\n"); +				} +			} catch (IOException ie) { +				break; +			} +		} + +		return megas; +	} +} diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index a06f05ed..35a03a12 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -29,6 +29,9 @@ public class AltosEepromHeader extends AltosEeprom {  	public boolean	last;  	public boolean	valid; +	public int record_length () { return 0; } + +	/* XXX pull rest of config data to state */  	public void update_state(AltosState state) {  		switch (cmd) {  		case AltosLib.AO_LOG_CONFIG_VERSION: @@ -40,7 +43,7 @@ public class AltosEepromHeader extends AltosEeprom {  		case AltosLib.AO_LOG_RADIO_CHANNEL:  			break;  		case AltosLib.AO_LOG_CALLSIGN: -			state.callsign = data; +			state.set_callsign(data);  			break;  		case AltosLib.AO_LOG_ACCEL_CAL:  			state.set_accel_g(config_a, config_b); @@ -90,6 +93,7 @@ public class AltosEepromHeader extends AltosEeprom {  			state.baro.crc = config_a;  			break;  		case AltosLib.AO_LOG_SOFTWARE_VERSION: +			state.set_firmware_version(data);  			break;  		}  	} diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 0804c392..e8f9b1fc 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -17,32 +17,14 @@  package org.altusmetrum.altoslib_1; +import java.io.*; +import java.util.*;  import java.text.*; -public class AltosEepromMega { -	public int	cmd; -	public int	tick; -	public boolean	valid; -	public String	data; -	public int	config_a, config_b; - -	public int	data8[]; - +public class AltosEepromMega extends AltosEeprom {  	public static final int	record_length = 32; -	static final int	header_length = 4; -	static final int	data_length = record_length - header_length; - -	public int data8(int i) { -		return data8[i]; -	} -	public int data16(int i) { -		return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; -	} - -	public int data32(int i) { -		return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); -	} +	public int record_length() { return record_length; }  	/* AO_LOG_FLIGHT elements */  	public int flight() { return data16(0); } @@ -68,7 +50,7 @@ public class AltosEepromMega {  	public int mag_z() { return data16(24); }  	public int accel() { return data16(26); } -	/* AO_LOG_VOLT elements */ +	/* AO_LOG_TEMP_VOLT elements */  	public int v_batt() { return data16(0); }  	public int v_pbatt() { return data16(2); }  	public int nsense() { return data16(4); } @@ -91,131 +73,137 @@ public class AltosEepromMega {  	public int nsat() { return data16(0); }  	public int svid(int n) { return data8(2 + n * 2); }  	public int c_n(int n) { return data8(2 + n * 2 + 1); } +  	public AltosEepromMega (AltosEepromChunk chunk, int start) throws ParseException { -		cmd = chunk.data(start); - -		valid = !chunk.erased(start, record_length); -		if (valid) { -			if (AltosConvert.checksum(chunk.data, start, record_length) != 0) -				throw new ParseException(String.format("invalid checksum at 0x%x", -								       chunk.address + start), 0); -		} else { -			cmd = AltosLib.AO_LOG_INVALID; -		} +		parse_chunk(chunk, start); +	} -		tick = chunk.data16(start+2); +	public void update_state(AltosState state) { +		AltosGPS	gps; + +		/* Flush any pending GPS changes */ +		if (state.gps_pending) { +			switch (cmd) { +			case AltosLib.AO_LOG_GPS_LAT: +			case AltosLib.AO_LOG_GPS_LON: +			case AltosLib.AO_LOG_GPS_ALT: +			case AltosLib.AO_LOG_GPS_SAT: +			case AltosLib.AO_LOG_GPS_DATE: +				break; +			default: +				state.set_temp_gps(); +				break; +			} +		} -		data8 = new int[data_length]; -		for (int i = 0; i < data_length; i++) -			data8[i] = chunk.data(start + header_length + i); +		switch (cmd) { +		case AltosLib.AO_LOG_FLIGHT: +			state.set_boost_tick(tick); +			state.set_flight(flight()); +			state.set_ground_accel(ground_accel()); +			state.set_ground_pressure(ground_pres()); +			state.set_temperature(ground_temp() / 100.0); +			break; +		case AltosLib.AO_LOG_STATE: +			state.set_tick(tick); +			state.set_state(state()); +			break; +		case AltosLib.AO_LOG_SENSOR: +			state.set_tick(tick); +			state.set_ms5607(pres(), temp()); + +			AltosIMU imu = new AltosIMU(); +			imu.accel_x = accel_x(); +			imu.accel_y = accel_y(); +			imu.accel_z = accel_z(); + +			imu.gyro_x = gyro_x(); +			imu.gyro_y = gyro_y(); +			imu.gyro_z = gyro_z(); +			state.imu = imu; + +			AltosMag mag = new AltosMag(); +			mag.x = mag_x(); +			mag.y = mag_y(); +			mag.z = mag_z(); + +			state.mag = mag; + +			state.set_accel(accel()); + +			break; +		case AltosLib.AO_LOG_TEMP_VOLT: +			state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); +			state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pbatt())); + +			int nsense = nsense(); + +			state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-2))); +			state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense(nsense-1))); + +			double voltages[] = new double[nsense-2]; +			for (int i = 0; i < nsense-2; i++) +				voltages[i] = AltosConvert.mega_pyro_voltage(sense(i)); + +			state.set_ignitor_voltage(voltages); +			break; +		case AltosLib.AO_LOG_GPS_TIME: +			state.set_tick(tick); +			gps = state.make_temp_gps(); +			gps.lat = latitude() / 1e7; +			gps.lon = longitude() / 1e7; +			gps.alt = altitude(); + +			gps.hour = hour(); +			gps.minute = minute(); +			gps.second = second(); + +			int flags = flags(); + +			gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; +			gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; +			gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> +				AltosLib.AO_GPS_NUM_SAT_SHIFT; + +			gps.year = year(); +			gps.month = month(); +			gps.day = day(); +			break; +		case AltosLib.AO_LOG_GPS_SAT: +			state.set_tick(tick); +			gps = state.make_temp_gps(); + +			int n = nsat(); +			for (int i = 0; i < n; i++) +				gps.add_sat(svid(i), c_n(i)); +			break; +		}  	}  	public AltosEepromMega (String line) { -		valid = false; -		tick = 0; +		parse_string(line); +	} -		if (line == null) { -			cmd = AltosLib.AO_LOG_INVALID; -			line = ""; -		} else { +	static public LinkedList<AltosEeprom> read(FileInputStream input) { +		LinkedList<AltosEeprom> megas = new LinkedList<AltosEeprom>(); + +		for (;;) {  			try { -				String[] tokens = line.split("\\s+"); - -				if (tokens[0].length() == 1) { -					if (tokens.length != 2 + data_length) { -						cmd = AltosLib.AO_LOG_INVALID; -						data = line; -					} else { -						cmd = tokens[0].codePointAt(0); -						tick = Integer.parseInt(tokens[1],16); -						valid = true; -						data8 = new int[data_length]; -						for (int i = 0; i < data_length; i++) -							data8[i] = Integer.parseInt(tokens[2 + i],16); -					} -				} else if (tokens[0].equals("Config") && tokens[1].equals("version:")) { -					cmd = AltosLib.AO_LOG_CONFIG_VERSION; -					data = tokens[2]; -				} else if (tokens[0].equals("Main") && tokens[1].equals("deploy:")) { -					cmd = AltosLib.AO_LOG_MAIN_DEPLOY; -					config_a = Integer.parseInt(tokens[2]); -				} else if (tokens[0].equals("Apogee") && tokens[1].equals("delay:")) { -					cmd = AltosLib.AO_LOG_APOGEE_DELAY; -					config_a = Integer.parseInt(tokens[2]); -				} else if (tokens[0].equals("Radio") && tokens[1].equals("channel:")) { -					cmd = AltosLib.AO_LOG_RADIO_CHANNEL; -					config_a = Integer.parseInt(tokens[2]); -				} else if (tokens[0].equals("Callsign:")) { -					cmd = AltosLib.AO_LOG_CALLSIGN; -					data = tokens[1].replaceAll("\"",""); -				} else if (tokens[0].equals("Accel") && tokens[1].equals("cal")) { -					cmd = AltosLib.AO_LOG_ACCEL_CAL; -					config_a = Integer.parseInt(tokens[3]); -					config_b = Integer.parseInt(tokens[5]); -				} else if (tokens[0].equals("Radio") && tokens[1].equals("cal:")) { -					cmd = AltosLib.AO_LOG_RADIO_CAL; -					config_a = Integer.parseInt(tokens[2]); -				} else if (tokens[0].equals("Max") && tokens[1].equals("flight") && tokens[2].equals("log:")) { -					cmd = AltosLib.AO_LOG_MAX_FLIGHT_LOG; -					config_a = Integer.parseInt(tokens[3]); -				} else if (tokens[0].equals("manufacturer")) { -					cmd = AltosLib.AO_LOG_MANUFACTURER; -					data = tokens[1]; -				} else if (tokens[0].equals("product")) { -					cmd = AltosLib.AO_LOG_PRODUCT; -					data = tokens[1]; -				} else if (tokens[0].equals("serial-number")) { -					cmd = AltosLib.AO_LOG_SERIAL_NUMBER; -					config_a = Integer.parseInt(tokens[1]); -				} else if (tokens[0].equals("log-format")) { -					cmd = AltosLib.AO_LOG_LOG_FORMAT; -					config_a = Integer.parseInt(tokens[1]); -				} else if (tokens[0].equals("software-version")) { -					cmd = AltosLib.AO_LOG_SOFTWARE_VERSION; -					data = tokens[1]; -				} else if (tokens[0].equals("ms5607")) { -					if (tokens[1].equals("reserved:")) { -						cmd = AltosLib.AO_LOG_BARO_RESERVED; -						config_a = Integer.parseInt(tokens[2]); -					} else if (tokens[1].equals("sens:")) { -						cmd = AltosLib.AO_LOG_BARO_SENS; -						config_a = Integer.parseInt(tokens[2]); -					} else if (tokens[1].equals("off:")) { -						cmd = AltosLib.AO_LOG_BARO_OFF; -						config_a = Integer.parseInt(tokens[2]); -					} else if (tokens[1].equals("tcs:")) { -						cmd = AltosLib.AO_LOG_BARO_TCS; -						config_a = Integer.parseInt(tokens[2]); -					} else if (tokens[1].equals("tco:")) { -						cmd = AltosLib.AO_LOG_BARO_TCO; -						config_a = Integer.parseInt(tokens[2]); -					} else if (tokens[1].equals("tref:")) { -						cmd = AltosLib.AO_LOG_BARO_TREF; -						config_a = Integer.parseInt(tokens[2]); -					} else if (tokens[1].equals("tempsens:")) { -						cmd = AltosLib.AO_LOG_BARO_TEMPSENS; -						config_a = Integer.parseInt(tokens[2]); -					} else if (tokens[1].equals("crc:")) { -						cmd = AltosLib.AO_LOG_BARO_CRC; -						config_a = Integer.parseInt(tokens[2]); -					} else { -						cmd = AltosLib.AO_LOG_INVALID; -						data = line; -					} -				} else { -					cmd = AltosLib.AO_LOG_INVALID; -					data = line; +				String line = AltosLib.gets(input); +				if (line == null) +					break; +				try { +					AltosEepromMega mega = new AltosEepromMega(line); +					if (mega.cmd != AltosLib.AO_LOG_INVALID) +						megas.add(mega); +				} catch (Exception e) { +					System.out.printf ("exception\n");  				} -			} catch (NumberFormatException ne) { -				cmd = AltosLib.AO_LOG_INVALID; -				data = line; +			} catch (IOException ie) { +				break;  			}  		} -	} -	public AltosEepromMega(int in_cmd, int in_tick) { -		cmd = in_cmd; -		tick = in_tick; -		valid = true; +		return megas;  	}  } diff --git a/altoslib/AltosEepromMetrum.java b/altoslib/AltosEepromMetrum.java index 72887032..e035e5fd 100644 --- a/altoslib/AltosEepromMetrum.java +++ b/altoslib/AltosEepromMetrum.java @@ -32,6 +32,8 @@ public class AltosEepromMetrum {  	static final int	header_length = 4;  	static final int	data_length = record_length - header_length; +	public int record_length() { return record_length; } +  	public int data8(int i) {  		return data8[i];  	} diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java new file mode 100644 index 00000000..5a616e6c --- /dev/null +++ b/altoslib/AltosEepromMetrum2.java @@ -0,0 +1,178 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_1; + +import java.io.*; +import java.util.*; +import java.text.*; + +public class AltosEepromMetrum2 extends AltosEeprom { +	public static final int	record_length = 16; + +	public int record_length() { return record_length; } + +	/* AO_LOG_FLIGHT elements */ +	public int flight() { return data16(0); } +	public int ground_accel() { return data16(2); } +	public int ground_pres() { return data32(4); } +	public int ground_temp() { return data32(8); } + +	/* AO_LOG_STATE elements */ +	public int state() { return data16(0); } +	public int reason() { return data16(2); } + +	/* AO_LOG_SENSOR elements */ +	public int pres() { return data32(0); } +	public int temp() { return data32(4); } +	public int accel() { return data16(8); } + +	/* AO_LOG_TEMP_VOLT elements */ +	public int v_batt() { return data16(0); } +	public int sense_a() { return data16(2); } +	public int sense_m() { return data16(4); } + +	/* AO_LOG_GPS_POS elements */ +	public int latitude() { return data32(0); } +	public int longitude() { return data32(4); } +	public int altitude() { return data16(8); } + +	/* AO_LOG_GPS_TIME elements */ +	public int hour() { return data8(0); } +	public int minute() { return data8(1); } +	public int second() { return data8(2); } +	public int flags() { return data8(3); } +	public int year() { return data8(4); } +	public int month() { return data8(5); } +	public int day() { return data8(6); } +	 +	/* AO_LOG_GPS_SAT elements */ +	public int nsat() { return data8(0); } +	public int more() { return data8(1); } +	public int svid(int n) { return data8(2 + n * 2); } +	public int c_n(int n) { return data8(2 + n * 2 + 1); } + +	public AltosEepromMetrum2 (AltosEepromChunk chunk, int start) throws ParseException { +		parse_chunk(chunk, start); +	} + +	public void update_state(AltosState state) { +		AltosGPS	gps; + +		/* Flush any pending GPS changes */ +		if (state.gps_pending) { +			switch (cmd) { +			case AltosLib.AO_LOG_GPS_POS: +			case AltosLib.AO_LOG_GPS_LAT: +			case AltosLib.AO_LOG_GPS_LON: +			case AltosLib.AO_LOG_GPS_ALT: +			case AltosLib.AO_LOG_GPS_SAT: +			case AltosLib.AO_LOG_GPS_DATE: +				break; +			default: +				state.set_temp_gps(); +				break; +			} +		} + +		if (cmd != AltosLib.AO_LOG_FLIGHT) +			state.set_tick(tick); +		switch (cmd) { +		case AltosLib.AO_LOG_FLIGHT: +			state.set_boost_tick(tick); +			state.set_flight(flight()); +			state.set_ground_accel(ground_accel()); +			state.set_ground_pressure(ground_pres()); +//			state.set_temperature(ground_temp() / 100.0); +			break; +		case AltosLib.AO_LOG_STATE: +			state.set_state(state()); +			break; +		case AltosLib.AO_LOG_SENSOR: +			state.set_ms5607(pres(), temp()); +			state.set_accel(accel()); + +			break; +		case AltosLib.AO_LOG_TEMP_VOLT: +			state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt())); + +			state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a())); +			state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m())); + +			break; +		case AltosLib.AO_LOG_GPS_POS: +			gps = state.make_temp_gps(); +			gps.lat = latitude() / 1e7; +			gps.lon = longitude() / 1e7; +			gps.alt = altitude(); +			break; +		case AltosLib.AO_LOG_GPS_TIME: +			gps = state.make_temp_gps(); + +			gps.hour = hour(); +			gps.minute = minute(); +			gps.second = second(); + +			int flags = flags(); + +			gps.connected = (flags & AltosLib.AO_GPS_RUNNING) != 0; +			gps.locked = (flags & AltosLib.AO_GPS_VALID) != 0; +			gps.nsat = (flags & AltosLib.AO_GPS_NUM_SAT_MASK) >> +				AltosLib.AO_GPS_NUM_SAT_SHIFT; + +			gps.year = year(); +			gps.month = month(); +			gps.day = day(); +			break; +		case AltosLib.AO_LOG_GPS_SAT: +			state.set_tick(tick); +			gps = state.make_temp_gps(); + +			int n = nsat(); +			for (int i = 0; i < n; i++) +				gps.add_sat(svid(i), c_n(i)); +			break; +		} +	} + +	public AltosEepromMetrum2 (String line) { +		parse_string(line); +	} + +	static public LinkedList<AltosEeprom> read(FileInputStream input) { +		LinkedList<AltosEeprom> megas = new LinkedList<AltosEeprom>(); + +		for (;;) { +			try { +				String line = AltosLib.gets(input); +				if (line == null) +					break; +				try { +					AltosEepromMetrum2 mega = new AltosEepromMetrum2(line); +					if (mega.cmd != AltosLib.AO_LOG_INVALID) +						megas.add(mega); +				} catch (Exception e) { +					System.out.printf ("exception\n"); +				} +			} catch (IOException ie) { +				break; +			} +		} + +		return megas; +	} +} diff --git a/altoslib/AltosEepromMini.java b/altoslib/AltosEepromMini.java index 1e0ff1b9..15ec1929 100644 --- a/altoslib/AltosEepromMini.java +++ b/altoslib/AltosEepromMini.java @@ -24,21 +24,7 @@ import java.text.*;  public class AltosEepromMini extends AltosEeprom {  	public static final int	record_length = 16; -	public int data8(int i) { -		return data8[i]; -	} - -	public int data16(int i) { -		return ((data8[i] | (data8[i+1] << 8)) << 16) >> 16; -	} - -	public int data24(int i) { -		return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16); -	} - -	public int data32(int i) { -		return data8[i] | (data8[i+1] << 8) | (data8[i+2] << 16) | (data8[i+3] << 24); -	} +	public int record_length() { return record_length; }  	/* AO_LOG_FLIGHT elements */  	public int flight() { return data16(0); } @@ -84,11 +70,11 @@ public class AltosEepromMini extends AltosEeprom {  	}  	public AltosEepromMini (AltosEepromChunk chunk, int start) throws ParseException { -		parse_chunk(chunk, start, record_length); +		parse_chunk(chunk, start);  	}  	public AltosEepromMini (String line) { -		parse_string(line, record_length); +		parse_string(line);  	}  	public AltosEepromMini(int in_cmd, int in_tick) { diff --git a/altoslib/AltosEepromTM.java b/altoslib/AltosEepromTM.java index 6945468b..461a7a9c 100644 --- a/altoslib/AltosEepromTM.java +++ b/altoslib/AltosEepromTM.java @@ -30,16 +30,16 @@ public class AltosEepromTM extends AltosEeprom {  	public static final int	record_length = 8; -	static double -	thermometer_to_temperature(double thermo) -	{ -		return (thermo - 19791.268) / 32728.0 * 1.25 / 0.00247; -	} -  	public void write(PrintStream out) {  		out.printf("%c %4x %4x %4x\n", cmd, tick, a, b);  	} +	public int record_length() { return record_length; } + +	public String string() { +		return String.format("%c %4x %4x %4x\n", cmd, tick, a, b); +	} +  	public void update_state(AltosState state) {  		AltosGPS	gps; @@ -77,7 +77,7 @@ public class AltosEepromTM extends AltosEeprom {  			break;  		case AltosLib.AO_LOG_TEMP_VOLT:  			state.set_tick(tick); -			state.set_temperature(thermometer_to_temperature(a)); +			state.set_temperature(AltosConvert.thermometer_to_temperature(a));  			state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(b));  			break;  		case AltosLib.AO_LOG_DEPLOY: diff --git a/altoslib/AltosEepromTeleScience.java b/altoslib/AltosEepromTeleScience.java index 2a828cf3..bacd66b5 100644 --- a/altoslib/AltosEepromTeleScience.java +++ b/altoslib/AltosEepromTeleScience.java @@ -33,6 +33,8 @@ public class AltosEepromTeleScience {  	static final int	max_data = 12;  	public static final int	record_length = 32; +	public int record_length() { return record_length; } +  	public AltosEepromTeleScience (AltosEepromChunk chunk, int start) throws ParseException {  		type = chunk.data(start); diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index 399e95b1..a8c19e4a 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -65,8 +65,8 @@ public class AltosGPS implements Cloneable {  	}  	public void ClearGPSTime() { -		year = month = day = 0; -		hour = minute = second = 0; +		year = month = day = AltosRecord.MISSING; +		hour = minute = second = AltosRecord.MISSING;  	}  	public AltosGPS(AltosTelemetryMap map) throws ParseException { @@ -212,6 +212,9 @@ public class AltosGPS implements Cloneable {  	}  	public AltosGPS() { +		lat = AltosRecord.MISSING; +		lon = AltosRecord.MISSING; +		alt = AltosRecord.MISSING;  		ClearGPSTime();  		cc_gps_sat = null;  	} @@ -280,6 +283,9 @@ public class AltosGPS implements Cloneable {  				}  			}  		} else { +			lat = AltosRecord.MISSING; +			lon = AltosRecord.MISSING; +			alt = AltosRecord.MISSING;  			ClearGPSTime();  			cc_gps_sat = null;  		} diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 4ca8ad9d..d6d78ca8 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -28,6 +28,7 @@ public class AltosLib {  	public static final int AO_LOG_TEMP_VOLT = 'T';  	public static final int AO_LOG_DEPLOY = 'D';  	public static final int AO_LOG_STATE = 'S'; +	public static final int AO_LOG_GPS_POS = 'P';  	public static final int AO_LOG_GPS_TIME = 'G';  	public static final int AO_LOG_GPS_LAT = 'N';  	public static final int AO_LOG_GPS_LON = 'W'; diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index aa3de432..b80d7b2e 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -32,7 +32,7 @@ public class AltosState implements Cloneable {  	/* derived data */ -	public long  	report_time; +	public long	received_time;  	public double	time;  	public double	prev_time; @@ -48,6 +48,12 @@ public class AltosState implements Cloneable {  	public boolean	boost;	/* under power */  	public int	rssi;  	public int	status; +	public int	device_type; +	public int	config_major; +	public int	config_minor; +	public int	apogee_delay; +	public int	main_deploy; +	public int	flight_log_max;  	public double	ground_altitude;  	public double	ground_pressure; @@ -61,11 +67,16 @@ public class AltosState implements Cloneable {  	public double	apogee_voltage;  	public double	main_voltage;  	public double	speed; +	public double	ignitor_voltage[];  	public double	prev_height;  	public double	prev_speed;  	public double	prev_acceleration; +	public double	prev_max_height; +	public double	prev_max_acceleration; +	public double	prev_max_speed; +  	public double	max_height;  	public double	max_acceleration;  	public double	max_speed; @@ -100,6 +111,8 @@ public class AltosState implements Cloneable {  	public double	speak_altitude;  	public String	callsign; +	public String	firmware_version; +  	public double	accel_plus_g;  	public double	accel_minus_g;  	public double	accel; @@ -133,7 +146,7 @@ public class AltosState implements Cloneable {  		set = 0; -		report_time = System.currentTimeMillis(); +		received_time = System.currentTimeMillis();  		time = AltosRecord.MISSING;  		time_change = AltosRecord.MISSING;  		prev_time = AltosRecord.MISSING; @@ -145,6 +158,12 @@ public class AltosState implements Cloneable {  		boost = false;  		rssi = AltosRecord.MISSING;  		status = 0; +		device_type = AltosRecord.MISSING; +		config_major = AltosRecord.MISSING; +		config_minor = AltosRecord.MISSING; +		apogee_delay = AltosRecord.MISSING; +		main_deploy = AltosRecord.MISSING; +		flight_log_max = AltosRecord.MISSING;  		ground_altitude = AltosRecord.MISSING;  		ground_pressure = AltosRecord.MISSING; @@ -158,10 +177,15 @@ public class AltosState implements Cloneable {  		prev_speed = AltosRecord.MISSING;  		prev_acceleration = AltosRecord.MISSING; +		prev_max_height = 0; +		prev_max_speed = 0; +		prev_max_acceleration = 0; +  		battery_voltage = AltosRecord.MISSING;  		pyro_voltage = AltosRecord.MISSING;  		apogee_voltage = AltosRecord.MISSING;  		main_voltage = AltosRecord.MISSING; +		ignitor_voltage = null;  		speed = AltosRecord.MISSING; @@ -219,7 +243,7 @@ public class AltosState implements Cloneable {  			return;  		} -		report_time = old.report_time; +		received_time = old.received_time;  		time = old.time;  		time_change = 0;  		tick = old.tick; @@ -232,6 +256,12 @@ public class AltosState implements Cloneable {  		boost = old.boost;  		rssi = old.rssi;  		status = old.status; +		device_type = old.device_type; +		config_major = old.config_major; +		config_minor = old.config_minor; +		apogee_delay = old.apogee_delay; +		main_deploy = old.main_deploy; +		flight_log_max = old.flight_log_max;  		set = 0; @@ -245,11 +275,16 @@ public class AltosState implements Cloneable {  		temperature = old.temperature;  		apogee_voltage = old.apogee_voltage;  		main_voltage = old.main_voltage; +		ignitor_voltage = old.ignitor_voltage;  		speed = old.speed;  		prev_height = old.height;  		prev_speed = old.speed;  		prev_acceleration = old.acceleration; + +		prev_max_height = old.max_height; +		prev_max_speed = old.max_speed; +		prev_max_acceleration = old.max_acceleration;  		prev_time = old.time;  		max_height = old.max_height; @@ -343,7 +378,7 @@ public class AltosState implements Cloneable {  		else  			height = AltosRecord.MISSING; -		if (height != AltosRecord.MISSING && height > max_height) +		if (height != AltosRecord.MISSING && height > prev_max_height)  			max_height = height;  		update_speed(); @@ -394,31 +429,34 @@ public class AltosState implements Cloneable {  				}  			}  		} -		if (boost && speed != AltosRecord.MISSING && speed > max_speed) +		if (boost && speed != AltosRecord.MISSING && speed > prev_max_speed)  			max_speed = speed;  	}  	void update_accel() { -		double	ground = ground_accel; - -		if (ground == AltosRecord.MISSING) -			ground = ground_accel_avg; -		if (accel == AltosRecord.MISSING) -			return; -		if (ground == AltosRecord.MISSING) -			return; -		if (accel_plus_g == AltosRecord.MISSING) -			return; -		if (accel_minus_g == AltosRecord.MISSING) -			return; - -		double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; -		double counts_per_mss = counts_per_g / 9.80665; - -		acceleration = (ground - accel) / counts_per_mss; +		if (kalman_acceleration != AltosRecord.MISSING) { +			acceleration = kalman_acceleration; +		} else { +			double	ground = ground_accel; + +			if (ground == AltosRecord.MISSING) +				ground = ground_accel_avg; +			if (accel == AltosRecord.MISSING) +				return; +			if (ground == AltosRecord.MISSING) +				return; +			if (accel_plus_g == AltosRecord.MISSING) +				return; +			if (accel_minus_g == AltosRecord.MISSING) +				return; + +			double counts_per_g = (accel_minus_g - accel_plus_g) / 2.0; +			double counts_per_mss = counts_per_g / 9.80665; +			acceleration = (ground - accel) / counts_per_mss; +		}  		/* Only look at accelerometer data under boost */ -		if (boost && acceleration != AltosRecord.MISSING && (max_acceleration == AltosRecord.MISSING || acceleration > max_acceleration)) +		if (boost && acceleration != AltosRecord.MISSING && acceleration > prev_max_acceleration)  			max_acceleration = acceleration;  		update_speed();  	} @@ -502,6 +540,26 @@ public class AltosState implements Cloneable {  	} +	public void set_device_type(int device_type) { +		this.device_type = device_type; +	} + +	public void set_config(int major, int minor, int apogee_delay, int main_deploy, int flight_log_max) { +		config_major = major; +		config_minor = minor; +		this.apogee_delay = apogee_delay; +		this.main_deploy = main_deploy; +		this.flight_log_max = flight_log_max; +	} + +	public void set_callsign(String callsign) { +		this.callsign = callsign; +	} + +	public void set_firmware_version(String version) { +		firmware_version = version; +	} +  	public void set_flight(int flight) {  		/* When the flight changes, reset the state */ @@ -538,6 +596,10 @@ public class AltosState implements Cloneable {  		}  	} +	public void set_received_time(long ms) { +		received_time = ms; +	} +  	public void set_altitude(double altitude) {  		if (altitude != AltosRecord.MISSING) {  			this.altitude = altitude; @@ -577,6 +639,8 @@ public class AltosState implements Cloneable {  			kalman_speed = speed;  			kalman_acceleration = acceleration;  			update_vertical_pos(); +			update_speed(); +			update_accel();  		}  	} @@ -672,6 +736,9 @@ public class AltosState implements Cloneable {  		}  	} +	public void set_ignitor_voltage(double[] voltage) { +		this.ignitor_voltage = voltage; +	}  	public double time_since_boost() {  		if (tick == AltosRecord.MISSING) @@ -702,6 +769,13 @@ public class AltosState implements Cloneable {  		temp_gps = null;  	} +	public AltosState clone() { +		AltosState s = new AltosState(); +		s.copy(this); +		return s; +	} + +  	public void init (AltosRecord cur, AltosState prev_state) {  		System.out.printf ("init\n"); @@ -721,7 +795,7 @@ public class AltosState implements Cloneable {  		set_kalman(cur.kalman_height, cur.kalman_speed, cur.kalman_acceleration); -		report_time = System.currentTimeMillis(); +		received_time = System.currentTimeMillis();  		set_temperature(cur.temperature());  		set_apogee_voltage(cur.drogue_voltage()); @@ -742,12 +816,6 @@ public class AltosState implements Cloneable {  	} -	public AltosState clone() { -		AltosState s = new AltosState(); -		s.copy(this); -		return s; -	} -  	public AltosState(AltosRecord cur) {  		init(cur, null);  	} @@ -756,6 +824,7 @@ public class AltosState implements Cloneable {  		init(cur, prev);  	} +  	public AltosState () {  		init();  	} diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index b84455d3..82e5400e 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -43,6 +43,10 @@ public abstract class AltosTelemetry implements AltosStateUpdate {  	}  	public void update_state(AltosState state) { +		state.set_serial(serial); +		state.set_tick(tick); +		state.set_rssi(rssi, status); +		state.set_received_time(received_time);  	}  	final static int PKT_APPEND_STATUS_1_CRC_OK		= (1 << 7); @@ -56,9 +60,11 @@ public abstract class AltosTelemetry implements AltosStateUpdate {  	final static int packet_type_location = 0x05;  	final static int packet_type_satellite = 0x06;  	final static int packet_type_companion = 0x07; -	final static int packet_type_MM_sensor = 0x08; -	final static int packet_type_MM_data = 0x09; -	final static int packet_type_Mini = 0x10; +	final static int packet_type_mega_sensor = 0x08; +	final static int packet_type_mega_data = 0x09; +	final static int packet_type_metrum_sensor = 0x0a; +	final static int packet_type_metrum_data = 0x0b; +	final static int packet_type_mini = 0x10;  	static AltosTelemetry parse_hex(String hex)  throws ParseException, AltosCRCException {  		AltosTelemetry	telem = null; @@ -87,37 +93,7 @@ public abstract class AltosTelemetry implements AltosStateUpdate {  		/* length, data ..., rssi, status, checksum -- 4 bytes extra */  		switch (bytes.length) {  		case AltosLib.ao_telemetry_standard_len + 4: -			int	type = AltosLib.uint8(bytes, 4 + 1); -/* -			switch (type) { -			case packet_type_TM_sensor: -			case packet_type_Tm_sensor: -			case packet_type_Tn_sensor: -				telem = new AltosTelemetrySensor(bytes); -				break; -			case packet_type_configuration: -				telem = new AltosTelemetryConfiguration(bytes); -				break; -			case packet_type_location: -				telem = new AltosTelemetryLocation(bytes); -				break; -			case packet_type_satellite: -				telem = new AltosTelemetrySatellite(bytes); -				break; -			case packet_type_companion: -				telem = new AltosTelemetryCompanion(bytes); -				break; -			case packet_type_MM_sensor: -				telem = new AltosTelemetryMegaSensor(bytes); -				break; -			case packet_type_MM_data: -				telem = new AltosTelemetryMegaData(bytes); -				break; -			default: -				telem = new AltosTelemetryRaw(bytes); -				break; -			} -*/ +			telem = AltosTelemetryStandard.parse_hex(bytes);  			break;  		case AltosLib.ao_telemetry_0_9_len + 4:  			telem = new AltosTelemetryLegacy(bytes); diff --git a/altoslib/AltosTelemetryConfiguration.java b/altoslib/AltosTelemetryConfiguration.java new file mode 100644 index 00000000..4c9bdd1f --- /dev/null +++ b/altoslib/AltosTelemetryConfiguration.java @@ -0,0 +1,55 @@ +/* + * Copyright © 2011 Keith Packard <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; + + +public class AltosTelemetryConfiguration extends AltosTelemetryStandard { +	int	device_type; +	int	flight; +	int	config_major; +	int	config_minor; +	int	apogee_delay; +	int	main_deploy; +	int	flight_log_max; +	String	callsign; +	String	version; + +	public AltosTelemetryConfiguration(int[] bytes) { +		super(bytes); + +		device_type    = uint8(5); +		flight         = uint16(6); +		config_major   = uint8(8); +		config_minor   = uint8(9); +		apogee_delay   = uint16(10); +		main_deploy    = uint16(12); +		flight_log_max = uint16(14); +		callsign       = string(16, 8); +		version        = string(24, 8); +	} + +	public void update_state(AltosState state) { +		super.update_state(state); +		state.set_device_type(device_type); +		state.set_flight(flight); +		state.set_config(config_major, config_minor, apogee_delay, main_deploy, flight_log_max); + +		state.set_callsign(callsign); +		state.set_firmware_version(version); +	} +} diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index 45e5c315..95cbbeed 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -546,7 +546,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry {  		state.set_accel(accel);  		if (kalman_height != AltosRecord.MISSING)  			state.set_kalman(kalman_height, kalman_speed, kalman_acceleration); -		state.set_temperature(AltosEepromTM.thermometer_to_temperature(temp)); +		state.set_temperature(AltosConvert.thermometer_to_temperature(temp));  		state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt));  		state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(apogee));  		state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main)); diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java new file mode 100644 index 00000000..fa3c24d0 --- /dev/null +++ b/altoslib/AltosTelemetryLocation.java @@ -0,0 +1,88 @@ +/* + * Copyright © 2011 Keith Packard <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; + + +public class AltosTelemetryLocation extends AltosTelemetryStandard { +	int	flags; +	int	altitude; +	int	latitude; +	int	longitude; +	int	year; +	int	month; +	int	day; +	int	hour; +	int	minute; +	int	second; +	int	pdop; +	int	hdop; +	int	vdop; +	int	mode; +	int	ground_speed; +	int	climb_rate; +	int	course; + +	public AltosTelemetryLocation(int[] bytes) { +		super(bytes); + +		flags          = uint8(5); +		altitude       = int16(6); +		latitude       = uint32(8); +		longitude      = uint32(12); +		year	       = uint8(16); +		month	       = uint8(17); +		day	       = uint8(18); +		hour	       = uint8(19); +		minute	       = uint8(20); +		second	       = uint8(21); +		pdop	       = uint8(22); +		hdop	       = uint8(23); +		vdop	       = uint8(24); +		mode	       = uint8(25); +		ground_speed   = uint16(26); +		climb_rate     = int16(28); +		course	       = uint8(30); +	} + +	public void update_state(AltosState state) { +		super.update_state(state); +		AltosGPS	gps = state.make_temp_gps(); + +		gps.nsat = flags & 0xf; +		gps.locked = (flags & (1 << 4)) != 0; +		gps.connected = (flags & (1 << 5)) != 0; + +		if (gps.locked) { +			gps.lat = latitude * 1.0e-7; +			gps.lon = longitude * 1.0e-7; +			gps.alt = altitude; +			gps.year = 2000 + year; +			gps.month = month; +			gps.day = day; +			gps.hour = hour; +			gps.minute = minute; +			gps.second = second; +			gps.ground_speed = ground_speed * 1.0e-2; +			gps.course = course * 2; +			gps.climb_rate = climb_rate * 1.0e-2; +			gps.hdop = hdop; +			gps.vdop = vdop; +		} +		state.set_temp_gps(); +	} +} diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java new file mode 100644 index 00000000..5e6cd580 --- /dev/null +++ b/altoslib/AltosTelemetryMegaData.java @@ -0,0 +1,85 @@ +/* + * Copyright © 2011 Keith Packard <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; + +public class AltosTelemetryMegaData extends AltosTelemetryStandard { +	int	state; +	 +	int	v_batt; +	int	v_pyro; +	int	sense[]; + +	int	ground_pres; +	int	ground_accel; +	int	accel_plus_g; +	int	accel_minus_g; + +	int	acceleration; +	int	speed; +	int	height; + +	public AltosTelemetryMegaData(int[] bytes) { +		super(bytes); + +		state = int8(5); + +		v_batt = int16(6); +		v_pyro = int16(8); + +		sense = new int[6];	 + +		for (int i = 0; i < 6; i++) { +			sense[i] = int8(10 + i) << 4; +			sense[i] |= sense[i] >> 8; +		} + +		ground_pres = int32(16); +		ground_accel = int16(20); +		accel_plus_g = int16(22); +		accel_minus_g = int16(24); + +		acceleration = int16(26); +		speed = int16(28); +		height = int16(30); +	} + +	public void update_state(AltosState state) { +		super.update_state(state); + +		state.set_state(this.state); +			 +		state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt)); +		state.set_pyro_voltage(AltosConvert.mega_pyro_voltage(v_pyro)); + +		state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense[4])); +		state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense[5])); + +		double voltages[] = new double[4]; +		for (int i = 0; i < 4; i++) +			voltages[i] = AltosConvert.mega_pyro_voltage(sense[i]); + +		state.set_ignitor_voltage(voltages); + +		state.set_ground_accel(ground_accel); +		state.set_ground_pressure(ground_pres); +		state.set_accel_g(accel_plus_g, accel_minus_g); + +		state.set_kalman(height, speed/16.0, acceleration / 16.0); +	} +} + diff --git a/altoslib/AltosTelemetryMegaSensor.java b/altoslib/AltosTelemetryMegaSensor.java new file mode 100644 index 00000000..7c385cfd --- /dev/null +++ b/altoslib/AltosTelemetryMegaSensor.java @@ -0,0 +1,84 @@ +/* + * Copyright © 2011 Keith Packard <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; + +public class AltosTelemetryMegaSensor extends AltosTelemetryStandard { +	int	accel; +	int	pres; +	int	temp; + +	int	accel_x; +	int	accel_y; +	int	accel_z; + +	int	gyro_x; +	int	gyro_y; +	int	gyro_z; + +	int	mag_x; +	int	mag_y; +	int	mag_z; + +	public AltosTelemetryMegaSensor(int[] bytes) { +		super(bytes); + +		accel         = int16(6); +		pres          = int32(8); +		temp          = int16(12); + +		accel_x	      = int16(14); +		accel_y	      = int16(16); +		accel_z	      = int16(18); + +		gyro_x	      = int16(20); +		gyro_y	      = int16(22); +		gyro_z	      = int16(24); + +		mag_x	      = int16(26); +		mag_y	      = int16(28); +		mag_z	      = int16(30); +	} + +	public void update_state(AltosState state) { +		super.update_state(state); + +		state.set_accel(accel); +		state.set_pressure(pres); +		state.set_temperature(temp / 100.0); + +		AltosIMU imu = new AltosIMU(); +		 +		imu.accel_x = accel_x; +		imu.accel_y = accel_y; +		imu.accel_z = accel_z; + +		imu.gyro_x = gyro_x; +		imu.gyro_y = gyro_y; +		imu.gyro_z = gyro_z; + +		state.imu = imu; + +		AltosMag mag = new AltosMag(); + +		mag.x = mag_x; +		mag.y = mag_y; +		mag.z = mag_z; + +		state.mag = mag; +	} +} diff --git a/altoslib/AltosTelemetryMetrumData.java b/altoslib/AltosTelemetryMetrumData.java new file mode 100644 index 00000000..d419ab80 --- /dev/null +++ b/altoslib/AltosTelemetryMetrumData.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2011 Keith Packard <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; + + +public class AltosTelemetryMetrumData extends AltosTelemetryStandard { + +	int	ground_pres; +	int	ground_accel; +	int	accel_plus_g; +	int	accel_minus_g; + +	public AltosTelemetryMetrumData(int[] bytes) { +		super(bytes); + +		ground_pres = int32(8); +		ground_accel = int16(12); +		accel_plus_g = int16(14); +		accel_minus_g = int16(16); +	} + +	public void update_state(AltosState state) { +		state.set_ground_accel(ground_accel); +		state.set_accel_g(accel_plus_g, accel_minus_g); +		state.set_ground_pressure(ground_pres); +	} +} diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java new file mode 100644 index 00000000..59d34dba --- /dev/null +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -0,0 +1,69 @@ +/* + * Copyright © 2011 Keith Packard <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; + + +public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard { +	int	state; + +	int	accel; +	int	pres; +	int	temp; + +	int	acceleration; +	int	speed; +	int	height; + +	int	v_batt; +	int	sense_a; +	int	sense_m; + +	public AltosTelemetryMetrumSensor(int[] bytes) { +		super(bytes); + +		state	      = int8(5); +		accel         = int16(6); +		pres          = int32(8); +		temp          = int16(12); + +		acceleration  = int16(14); +		speed         = int16(16); +		height        = int16(18); + +		v_batt        = int16(20); +		sense_a       = int16(22); +		sense_m       = int16(24); +	} + +	public void update_state(AltosState state) { +		super.update_state(state); + +		state.set_state(this.state); + +		state.set_accel(accel); +		state.set_ms5607(pres, temp); + +		state.set_kalman(height, speed/16.0, acceleration/16.0); + +		state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt)); + +		state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sense_a)); +		state.set_main_voltage(AltosConvert.mega_pyro_voltage(sense_m)); +		System.out.printf ("sense_a %d apogee voltage %g\n", sense_a, state.apogee_voltage); +	} +} diff --git a/altoslib/AltosTelemetryRaw.java b/altoslib/AltosTelemetryRaw.java new file mode 100644 index 00000000..9ef7787e --- /dev/null +++ b/altoslib/AltosTelemetryRaw.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2011 Keith Packard <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; + +public class AltosTelemetryRaw extends AltosTelemetryStandard { +	public AltosTelemetryRaw(int[] bytes) { +		super(bytes); +	} + +	public void update_state(AltosState state) { +		super.update_state(state); +	} +} diff --git a/altoslib/AltosTelemetrySatellite.java b/altoslib/AltosTelemetrySatellite.java new file mode 100644 index 00000000..3f70f212 --- /dev/null +++ b/altoslib/AltosTelemetrySatellite.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2011 Keith Packard <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; + +public class AltosTelemetrySatellite extends AltosTelemetryStandard { +	int		channels; +	AltosGPSSat[]	sats; + +	public AltosTelemetrySatellite(int[] bytes) { +		super(bytes); + +		channels = uint8(5); +		if (channels > 12) +			channels = 12; +		if (channels == 0) +			sats = null; +		else { +			sats = new AltosGPSSat[channels]; +			for (int i = 0; i < channels; i++) { +				int	svid =  uint8(6 + i * 2 + 0); +				int	c_n_1 = uint8(6 + i * 2 + 1); +				sats[i] = new AltosGPSSat(svid, c_n_1); +			} +		} +	} + +	public void update_state(AltosState state) { +		super.update_state(state); + +		AltosGPS	gps = state.make_temp_gps(); +		 +		gps.cc_gps_sat = sats; +		state.set_temp_gps(); +	} +} diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java new file mode 100644 index 00000000..f89e56c3 --- /dev/null +++ b/altoslib/AltosTelemetrySensor.java @@ -0,0 +1,80 @@ +/* + * Copyright © 2011 Keith Packard <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; + + +public class AltosTelemetrySensor extends AltosTelemetryStandard { +	int	state; +	int	accel; +	int	pres; +	int	temp; +	int	v_batt; +	int	sense_d; +	int	sense_m; + +	int	acceleration; +	int	speed; +	int	height; + +	int	ground_accel; +	int	ground_pres; +	int	accel_plus_g; +	int	accel_minus_g; + +	public AltosTelemetrySensor(int[] bytes) { +		super(bytes); +		state         = uint8(5); + +		accel         = int16(6); +		pres          = int16(8); +		temp          = int16(10); +		v_batt        = int16(12); +		sense_d       = int16(14); +		sense_m       = int16(16); + +		acceleration  = int16(18); +		speed         = int16(20); +		height        = int16(22); + +		ground_pres   = int16(24); +		ground_accel  = int16(26); +		accel_plus_g  = int16(28); +		accel_minus_g = int16(30); +	} + +	public void update_state(AltosState state) { +		super.update_state(state); + +		state.set_state(this.state); +		if (type == packet_type_TM_sensor) { +			state.set_ground_accel(ground_accel); +			state.set_accel_g(accel_plus_g, accel_minus_g); +			state.set_accel(accel); +		} +		state.set_ground_pressure(AltosConvert.barometer_to_pressure(ground_pres)); +		state.set_pressure(AltosConvert.barometer_to_pressure(pres)); +		state.set_temperature(AltosConvert.thermometer_to_temperature(temp)); +		state.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt)); +		if (type == packet_type_TM_sensor || type == packet_type_Tm_sensor) { +			state.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d)); +			state.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m)); +		} + +		state.set_kalman(height, speed/16.0, acceleration / 16.0); +	} +} diff --git a/altoslib/AltosTelemetryStandard.java b/altoslib/AltosTelemetryStandard.java new file mode 100644 index 00000000..fa86bf8e --- /dev/null +++ b/altoslib/AltosTelemetryStandard.java @@ -0,0 +1,106 @@ +/* + * Copyright © 2011 Keith Packard <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; + +public abstract class AltosTelemetryStandard extends AltosTelemetry { +	int[]	bytes; +	int	type; + +	public int int8(int off) { +		return AltosLib.int8(bytes, off + 1); +	} + +	public int uint8(int off) { +		return AltosLib.uint8(bytes, off + 1); +	} + +	public int int16(int off) { +		return AltosLib.int16(bytes, off + 1); +	} + +	public int uint16(int off) { +		return AltosLib.uint16(bytes, off + 1); +	} + +	public int uint32(int off) { +		return AltosLib.uint32(bytes, off + 1); +	} + +	public int int32(int off) { +		return AltosLib.int32(bytes, off + 1); +	} + +	public String string(int off, int l) { +		return AltosLib.string(bytes, off + 1, l); +	} + +	public static AltosTelemetry parse_hex(int[] bytes) { +		int	type = AltosLib.uint8(bytes, 4 + 1); + +		AltosTelemetry	telem; +		switch (type) { +		case packet_type_TM_sensor: +		case packet_type_Tm_sensor: +		case packet_type_Tn_sensor: +			telem = new AltosTelemetrySensor(bytes); +			break; +		case packet_type_configuration: +			telem = new AltosTelemetryConfiguration(bytes); +			break; +		case packet_type_location: +			telem = new AltosTelemetryLocation(bytes); +			break; +		case packet_type_satellite: +			telem = new AltosTelemetrySatellite(bytes); +			break; +/* +		case packet_type_companion: +			telem = new AltosTelemetryCompanion(bytes); +			break; +*/ +		case packet_type_mega_sensor: +			telem = new AltosTelemetryMegaSensor(bytes); +			break; +		case packet_type_mega_data: +			telem = new AltosTelemetryMegaData(bytes); +			break; +		case packet_type_metrum_sensor: +			telem = new AltosTelemetryMetrumSensor(bytes); +			break; +		case packet_type_metrum_data: +			telem = new AltosTelemetryMetrumData(bytes); +			break; +		default: +			telem = new AltosTelemetryRaw(bytes); +			break; +		} +		return telem; +	} + +	public AltosTelemetryStandard(int[] bytes) { +		this.bytes = bytes; + +		serial = uint16(0); +		tick   = uint16(2); +		type   = uint8(4); +	} + +	public void update_state(AltosState state) { +		super.update_state(state); +	} +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 59e0ec1c..87d4d898 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -10,7 +10,19 @@ SRC=.  altoslibdir = $(datadir)/java +record_files = \ +	AltosEepromRecord.java \ +	AltosEepromTeleScience.java \ +	AltosRecordCompanion.java \ +	AltosRecordIterable.java \ +	AltosRecord.java \ +	AltosRecordNone.java \ +	AltosRecordTM.java \ +	AltosRecordMM.java \ +	AltosRecordMini.java +  altoslib_JAVA = \ +	$(record_files) \  	AltosLib.java \  	AltosConfigData.java \  	AltosConfigValues.java \ @@ -25,11 +37,8 @@ altoslib_JAVA = \  	AltosEepromIterable.java \  	AltosEepromLog.java \  	AltosEepromMega.java \ -	AltosEepromMegaIterable.java \ -	AltosEepromRecord.java \ -	AltosEepromTeleScience.java \ +	AltosEepromMetrum2.java \  	AltosEepromMini.java \ -	AltosEepromOldIterable.java \  	AltosFile.java \  	AltosFlash.java \  	AltosFlashListener.java \ @@ -57,13 +66,6 @@ altoslib_JAVA = \  	AltosParse.java \  	AltosPreferences.java \  	AltosPreferencesBackend.java \ -	AltosRecordCompanion.java \ -	AltosRecordIterable.java \ -	AltosRecord.java \ -	AltosRecordNone.java \ -	AltosRecordTM.java \ -	AltosRecordMM.java \ -	AltosRecordMini.java \  	AltosReplayReader.java \  	AltosRomconfig.java \  	AltosSensorMM.java \ @@ -72,11 +74,21 @@ altoslib_JAVA = \  	AltosStateIterable.java \  	AltosStateUpdate.java \  	AltosTelemetry.java \ +	AltosTelemetryConfiguration.java \  	AltosTelemetryFile.java \  	AltosTelemetryIterable.java \  	AltosTelemetryLegacy.java \ +	AltosTelemetryLocation.java \  	AltosTelemetryMap.java \ +	AltosTelemetryMegaSensor.java \ +	AltosTelemetryMegaData.java \ +	AltosTelemetryMetrumSensor.java \ +	AltosTelemetryMetrumData.java \  	AltosTelemetryReader.java \ +	AltosTelemetryRaw.java \ +	AltosTelemetrySensor.java \ +	AltosTelemetrySatellite.java \ +	AltosTelemetryStandard.java \  	AltosUnitsListener.java \  	AltosMs5607.java \  	AltosIMU.java \ diff --git a/altosui/AltosAscent.java b/altosui/AltosAscent.java index f8435037..ceba2d1d 100644 --- a/altosui/AltosAscent.java +++ b/altosui/AltosAscent.java @@ -308,7 +308,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {  	class Lat extends AscentValue {  		void show (AltosState state, AltosListenerState listener_state) { -			if (state.gps != null) +			if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING)  				show(pos(state.gps.lat,"N", "S"));  			else  				show("???"); @@ -322,7 +322,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {  	class Lon extends AscentValue {  		void show (AltosState state, AltosListenerState listener_state) { -			if (state.gps != null) +			if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING)  				show(pos(state.gps.lon,"E", "W"));  			else  				show("???"); diff --git a/altosui/AltosDescent.java b/altosui/AltosDescent.java index 2b6575cb..35efce16 100644 --- a/altosui/AltosDescent.java +++ b/altosui/AltosDescent.java @@ -278,7 +278,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {  	class Lat extends DescentValue {  		void show (AltosState state, AltosListenerState listener_state) { -			if (state.gps != null && state.gps.connected) +			if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING)  				show(pos(state.gps.lat,"N", "S"));  			else  				show("???"); @@ -292,7 +292,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {  	class Lon extends DescentValue {  		void show (AltosState state, AltosListenerState listener_state) { -			if (state.gps != null && state.gps.connected) +			if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING)  				show(pos(state.gps.lon,"W", "E"));  			else  				show("???"); diff --git a/altosui/AltosDisplayThread.java b/altosui/AltosDisplayThread.java index 70144fb2..7a750c86 100644 --- a/altosui/AltosDisplayThread.java +++ b/altosui/AltosDisplayThread.java @@ -110,7 +110,7 @@ public class AltosDisplayThread extends Thread {  			 */  			if (state.state >= Altos.ao_flight_drogue &&  			    (last || -			     System.currentTimeMillis() - state.report_time >= 15000 || +			     System.currentTimeMillis() - state.received_time >= 15000 ||  			     state.state == Altos.ao_flight_landed))  			{  				if (Math.abs(state.speed) < 20 && state.height < 100) diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 95b17e2a..931b55fd 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -33,9 +33,6 @@ public class AltosEepromDownload implements Runnable {  	Thread			eeprom_thread;  	AltosEepromMonitor	monitor; -	int			flight; -	int			serial; -	int			year, month, day;  	boolean			want_file;  	FileWriter		eeprom_file;  	LinkedList<String>	eeprom_pending; @@ -44,7 +41,7 @@ public class AltosEepromDownload implements Runnable {  	ActionListener		listener;  	boolean			success;  	ParseException		parse_exception; -	String			extension; +	AltosState		state;  	private void FlushPending() throws IOException {  		for (String s : flights.config_data) { @@ -59,15 +56,19 @@ public class AltosEepromDownload implements Runnable {  	private void CheckFile(boolean force) throws IOException {  		if (eeprom_file != null)  			return; -		if (force || (flight != 0 && want_file)) { +		if (force || (state.flight != 0 && want_file)) {  			AltosFile		eeprom_name; - -			if (extension == null) -				extension = "data"; -			if (year != 0 && month != 0 && day != 0) -				eeprom_name = new AltosFile(year, month, day, serial, flight, extension); -			else -				eeprom_name = new AltosFile(serial, flight, extension); +			AltosGPS		gps = state.gps; + +			if (gps != null && +			    gps.year != AltosRecord.MISSING && +			    gps.month != AltosRecord.MISSING && +			    gps.day != AltosRecord.MISSING) +			{ +				eeprom_name = new AltosFile(gps.year, gps.month, gps.day, +							    state.serial, state.flight, "eeprom"); +			} else +				eeprom_name = new AltosFile(state.serial, state.flight, "eeprom");  			eeprom_file = new FileWriter(eeprom_name);  			if (eeprom_file != null) { @@ -78,270 +79,49 @@ public class AltosEepromDownload implements Runnable {  		}  	} -	void Log(AltosEepromRecord r) throws IOException { +	boolean			done; +	boolean			start; + +	void LogEeprom(AltosEeprom r) throws IOException {  		if (r.cmd != Altos.AO_LOG_INVALID) { -			String log_line = String.format("%c %4x %4x %4x\n", -							r.cmd, r.tick, r.a, r.b); +			String line = r.string();  			if (eeprom_file != null) -				eeprom_file.write(log_line); +				eeprom_file.write(line);  			else -				eeprom_pending.add(log_line); +				eeprom_pending.add(line);  		}  	} -	void set_serial(int in_serial) { -		serial = in_serial; -		monitor.set_serial(serial); -	} - -	void set_flight(int in_flight) { -		flight = in_flight; -		monitor.set_flight(flight); -	} -		 -	boolean			done; -	int			state; - -	void CaptureFull(AltosEepromChunk eechunk) throws IOException { -		boolean	any_valid = false; - -		extension = "eeprom"; -		set_serial(flights.config_data.serial); -		for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromRecord.record_length) { -			try { -				AltosEepromRecord r = new AltosEepromRecord(eechunk, i); -				if (r.cmd == Altos.AO_LOG_FLIGHT) -					set_flight(r.b); - -				/* Monitor state transitions to update display */ -				if (r.cmd == Altos.AO_LOG_STATE && r.a <= Altos.ao_flight_landed) { -					state = r.a; -					if (state > Altos.ao_flight_pad) -						want_file = true; -				} - -				if (r.cmd == Altos.AO_LOG_GPS_DATE) { -					year = 2000 + (r.a & 0xff); -					month = (r.a >> 8) & 0xff; -					day = (r.b & 0xff); -					want_file = true; -				} -				if (r.cmd == Altos.AO_LOG_STATE && r.a == Altos.ao_flight_landed) -					done = true; -				if (r.cmd != AltosLib.AO_LOG_INVALID) -					any_valid = true; -				Log(r); -			} catch (ParseException pe) { -				if (parse_exception == null) -					parse_exception = pe; -			} -		} - -		if (!any_valid) -			done = true; - -		CheckFile(false); -	} - -	boolean	start; -	int	tiny_tick; - -	void CaptureTiny (AltosEepromChunk eechunk) throws IOException { +	void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException {  		boolean any_valid = false; -		extension = "eeprom"; -		set_serial(flights.config_data.serial); -		for (int i = 0; i < eechunk.data.length && !done; i += 2) { -			int			v = eechunk.data16(i); -			AltosEepromRecord	r; - -			if (i == 0 && start) { -				tiny_tick = 0; -				start = false; -				set_flight(v); -				r = new AltosEepromRecord(Altos.AO_LOG_FLIGHT, tiny_tick, 0, v); -				any_valid = true; -			} else { -				int	s = v ^ 0x8000; - -				if (Altos.ao_flight_startup <= s && s <= Altos.ao_flight_invalid) { -					state = s; -					r = new AltosEepromRecord(Altos.AO_LOG_STATE, tiny_tick, state, 0); -					if (state == Altos.ao_flight_landed) -						done = true; -					state = s; -					any_valid = true; -				} else { -					if (v != 0xffff) -						any_valid = true; - -					r = new AltosEepromRecord(Altos.AO_LOG_PRESSURE, tiny_tick, 0, v); - -					/* -					 * The flight software records ascent data every 100ms, and descent -					 * data every 1s. -					 */ -					if (state < Altos.ao_flight_drogue) -						tiny_tick += 10; -					else -						tiny_tick += 100; -				} -			} -			Log(r); -		} -		CheckFile(false); -		if (!any_valid) -			done = true; -	} - -	void LogTeleScience(AltosEepromTeleScience r) throws IOException { -		if (r.type != Altos.AO_LOG_INVALID) { -			String log_line = String.format("%c %4x %4x %d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", -							r.type, r.tick, r.tm_tick, r.tm_state, -							r.data[0], r.data[1], r.data[2], r.data[3],  -							r.data[4], r.data[5], r.data[6], r.data[7],  -							r.data[8], r.data[9], r.data[10], r.data[11]); -			if (eeprom_file != null) -				eeprom_file.write(log_line); -			else -				eeprom_pending.add(log_line); -		} -	} -	 -	boolean	telescience_start; - -	void CaptureTeleScience (AltosEepromChunk eechunk) throws IOException { -		boolean	any_valid = false; - -		extension = "science"; -		for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromTeleScience.record_length) { -			try { -				AltosEepromTeleScience r = new AltosEepromTeleScience(eechunk, i); -				if (r.type == AltosEepromTeleScience.AO_LOG_TELESCIENCE_START) { -					if (telescience_start) { -						done = true; -						break; -					} -					set_serial(r.data[0]); -					set_flight(r.data[1]); -					telescience_start = true; -				} else { -					if (!telescience_start) -						break; -				} -				state = r.tm_state; -				want_file =true; -				any_valid = true; -				LogTeleScience(r); -			} catch (ParseException pe) { -				if (parse_exception == null) -					parse_exception = pe; -			} -		} +		int record_length = 8; -		CheckFile(false); -		if (!any_valid) -			done = true; -	} +		state.set_serial(flights.config_data.serial); -	void LogMega(AltosEepromMega r) throws IOException { -		if (r.cmd != Altos.AO_LOG_INVALID) { -			String log_line = String.format("%c %4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", -							r.cmd, r.tick, -							r.data8[0], r.data8[1], r.data8[2], r.data8[3], -							r.data8[4], r.data8[5], r.data8[6], r.data8[7], -							r.data8[8], r.data8[9], r.data8[10], r.data8[11], -							r.data8[12], r.data8[13], r.data8[14], r.data8[15], -							r.data8[16], r.data8[17], r.data8[18], r.data8[19], -							r.data8[20], r.data8[21], r.data8[22], r.data8[23], -							r.data8[24], r.data8[25], r.data8[26], r.data8[27]); -			if (eeprom_file != null) -				eeprom_file.write(log_line); -			else -				eeprom_pending.add(log_line); -		} -	} +		for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { +			AltosEeprom r = eechunk.eeprom(i, log_format); -	void CaptureMega(AltosEepromChunk eechunk) throws IOException { -		boolean any_valid = false; +			record_length = r.record_length(); -		extension = "mega"; -		set_serial(flights.config_data.serial); -		for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromMega.record_length) { -			try { -				AltosEepromMega r = new AltosEepromMega(eechunk, i); -				if (r.cmd == Altos.AO_LOG_FLIGHT) -					set_flight(r.data16(0)); - -				/* Monitor state transitions to update display */ -				if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) <= Altos.ao_flight_landed) { -					state = r.data16(0); -					if (state > Altos.ao_flight_pad) -						want_file = true; -				} +			r.update_state(state); -				if (r.cmd == Altos.AO_LOG_GPS_TIME) { -					year = 2000 + r.data8(14); -					month = r.data8(15); -					day = r.data8(16); +			/* Monitor state transitions to update display */ +			if (state.state != AltosLib.ao_flight_invalid && +			    state.state <= AltosLib.ao_flight_landed) +			{ +				if (state.state > Altos.ao_flight_pad)  					want_file = true; -				} - -				if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed) +				if (state.state == AltosLib.ao_flight_landed)  					done = true; -				if (r.cmd != AltosLib.AO_LOG_INVALID) -					any_valid = true; -				LogMega(r); -			} catch (ParseException pe) { -				if (parse_exception == null) -					parse_exception = pe;  			} -		} -		if (!any_valid) -			done = true; -		CheckFile(false); -	} -	 -	void LogMini(AltosEepromMini r) throws IOException { -		if (r.cmd != Altos.AO_LOG_INVALID) { -			String log_line = String.format("%c %4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", -							r.cmd, r.tick, -							r.data8[0], r.data8[1], r.data8[2], r.data8[3], -							r.data8[4], r.data8[5], r.data8[6], r.data8[7], -							r.data8[8], r.data8[9], r.data8[10], r.data8[11]); -			if (eeprom_file != null) -				eeprom_file.write(log_line); -			else -				eeprom_pending.add(log_line); -		} -	} +			if (state.gps != null) +				want_file = true; -	void CaptureMini(AltosEepromChunk eechunk) throws IOException { -		boolean any_valid = false; - -		extension = "mini"; -		set_serial(flights.config_data.serial); -		for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += AltosEepromMini.record_length) { -			try { -				AltosEepromMini r = new AltosEepromMini(eechunk, i); -				if (r.cmd == Altos.AO_LOG_FLIGHT) -					set_flight(r.data16(0)); - -				/* Monitor state transitions to update display */ -				if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) <= Altos.ao_flight_landed) { -					state = r.data16(0); -					if (state > Altos.ao_flight_pad) -						want_file = true; -				} - -				if (r.cmd == Altos.AO_LOG_STATE && r.data16(0) == Altos.ao_flight_landed) -					done = true; +			if (r.valid) {  				any_valid = true; -				LogMini(r); -			} catch (ParseException pe) { -				if (parse_exception == null) -					parse_exception = pe; +				LogEeprom(r);  			}  		}  		if (!any_valid) @@ -350,15 +130,12 @@ public class AltosEepromDownload implements Runnable {  		CheckFile(false);  	} -	void CaptureTelemetry(AltosEepromChunk eechunk) throws IOException { -		 -	} -  	void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException {  		int			block, state_block = 0;  		int			log_format = flights.config_data.log_format; -		state = 0; +		state = new AltosState(); +  		done = false;  		start = true; @@ -366,10 +143,6 @@ public class AltosEepromDownload implements Runnable {  			throw new IOException("no serial number found");  		/* Reset per-capture variables */ -		flight = 0; -		year = 0; -		month = 0; -		day = 0;  		want_file = false;  		eeprom_file = null;  		eeprom_pending = new LinkedList<String>(); @@ -377,9 +150,12 @@ public class AltosEepromDownload implements Runnable {  		/* Set serial number in the monitor dialog window */  		/* Now scan the eeprom, reading blocks of data and converting to .eeprom file form */ -		state = 0; state_block = log.start_block; +		state_block = log.start_block;  		for (block = log.start_block; !done && block < log.end_block; block++) { -			monitor.set_value(AltosLib.state_name(state), state, block - state_block, block - log.start_block); +			monitor.set_value(state.state_name(), +					  state.state, +					  block - state_block, +					  block - log.start_block);  			AltosEepromChunk	eechunk = new AltosEepromChunk(serial_line, block, block == log.start_block); @@ -397,33 +173,7 @@ public class AltosEepromDownload implements Runnable {  				}  			} -			switch (log_format) { -			case AltosLib.AO_LOG_FORMAT_FULL: -				extension = "eeprom"; -				CaptureFull(eechunk); -				break; -			case AltosLib.AO_LOG_FORMAT_TINY: -				extension = "eeprom"; -				CaptureTiny(eechunk); -				break; -			case AltosLib.AO_LOG_FORMAT_TELEMETRY: -				extension = "telem"; -				CaptureTelemetry(eechunk); -				break; -			case AltosLib.AO_LOG_FORMAT_TELESCIENCE: -				extension = "science"; -				CaptureTeleScience(eechunk); -				break; -			case AltosLib.AO_LOG_FORMAT_TELEMEGA: -				extension = "mega"; -				CaptureMega(eechunk); -				break; -			case AltosLib.AO_LOG_FORMAT_EASYMINI: -			case AltosLib.AO_LOG_FORMAT_TELEMINI: -				extension = "eeprom"; -				CaptureMini(eechunk); -				break; -			} +			CaptureEeprom (eechunk, log_format);  		}  		CheckFile(true);  		if (eeprom_file != null) { diff --git a/altosui/AltosFlightStatus.java b/altosui/AltosFlightStatus.java index 0be7bb51..6383e5b9 100644 --- a/altosui/AltosFlightStatus.java +++ b/altosui/AltosFlightStatus.java @@ -126,7 +126,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay  	class LastPacket extends FlightValue {  		void show(AltosState state, AltosListenerState listener_state) { -			long secs = (System.currentTimeMillis() - state.report_time + 500) / 1000; +			long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000;  			value.setText(String.format("%d", secs));  		}  		public LastPacket(GridBagLayout layout, int x) { diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 423cf10c..1c450ce3 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -102,7 +102,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay, A  		status_update.saved_state = state;  		if (state == null) -			state = new AltosState(new AltosRecord()); +			state = new AltosState();  		pad.show(state, listener_state); diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index bbab017f..f6a91de8 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -65,13 +65,13 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  	public void show(AltosState state, AltosListenerState listener_state) {  		status_update.saved_state = state; -		try { +//		try {  			pad.show(state, listener_state);  			flightStatus.show(state, listener_state);  			flightInfo.show(state, listener_state); -		} catch (Exception e) { -			System.out.print("Show exception" + e); -		} +//		} catch (Exception e) { +//			System.out.print("Show exception " + e); +//		}  	}  	public void update(final AltosState state, final AltosListenerState listener_state) { diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index 8601d76f..8906920b 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -155,10 +155,14 @@ public class AltosInfoTable extends JTable {  				else  					info_add_row(1, "GPS", "  missing");  				info_add_row(1, "Satellites", "%6d", state.gps.nsat); -				info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); -				info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); -				info_add_row(1, "GPS altitude", "%6d", state.gps.alt); -				info_add_row(1, "GPS height", "%6.0f", state.gps_height); +				if (state.gps.lat != AltosRecord.MISSING) +					info_add_deg(1, "Latitude", state.gps.lat, 'N', 'S'); +				if (state.gps.lon != AltosRecord.MISSING) +					info_add_deg(1, "Longitude", state.gps.lon, 'E', 'W'); +				if (state.gps.alt != AltosRecord.MISSING) +					info_add_row(1, "GPS altitude", "%8.1f", state.gps.alt); +				if (state.gps_height != AltosRecord.MISSING) +					info_add_row(1, "GPS height", "%8.1f", state.gps_height);  				/* The SkyTraq GPS doesn't report these values */  				/* @@ -195,14 +199,16 @@ public class AltosInfoTable extends JTable {  					info_add_deg(1, "Pad longitude", state.pad_lon, 'E', 'W');  					info_add_row(1, "Pad GPS alt", "%6.0f m", state.pad_alt);  				} -				info_add_row(1, "GPS date", "%04d-%02d-%02d", -					     state.gps.year, -					     state.gps.month, -					     state.gps.day); -				info_add_row(1, "GPS time", "  %02d:%02d:%02d", -					     state.gps.hour, -					     state.gps.minute, -					     state.gps.second); +				if (state.gps.year != AltosRecord.MISSING)  +					info_add_row(1, "GPS date", "%04d-%02d-%02d", +						     state.gps.year, +						     state.gps.month, +						     state.gps.day); +				if (state.gps.hour != AltosRecord.MISSING) +					info_add_row(1, "GPS time", "  %02d:%02d:%02d", +						     state.gps.hour, +						     state.gps.minute, +						     state.gps.second);  				//int	nsat_vis = 0;  				int	c; diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 38f273cf..4cdaa3df 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -103,7 +103,8 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio  	class Lat extends LandedValue {  		void show (AltosState state, AltosListenerState listener_state) { -			if (state.gps != null && state.gps.connected) +			show(); +			if (state.gps != null && state.gps.connected && state.gps.lat != AltosRecord.MISSING)  				show(pos(state.gps.lat,"N", "S"));  			else  				show("???"); @@ -118,7 +119,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio  	class Lon extends LandedValue {  		void show (AltosState state, AltosListenerState listener_state) {  			show(); -			if (state.gps != null && state.gps.connected) +			if (state.gps != null && state.gps.connected && state.gps.lon != AltosRecord.MISSING)  				show(pos(state.gps.lon,"E", "W"));  			else  				show("???"); diff --git a/altosui/AltosPad.java b/altosui/AltosPad.java index fed009cc..e9c973de 100644 --- a/altosui/AltosPad.java +++ b/altosui/AltosPad.java @@ -310,17 +310,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {  	class PadLat extends LaunchValue {  		void show (AltosState state, AltosListenerState listener_state) { -			if (state == null || state.gps == null) { -				hide(); -			} else { -				if (state.state < AltosLib.ao_flight_pad) { -					show(pos(state.gps.lat,"N", "S")); -					set_label("Latitude"); -				} else {  -					show(pos(state.pad_lat,"N", "S")); -					set_label("Pad Latitude"); +			double lat = AltosRecord.MISSING; +			String label = null; + +			if (state != null) { +				if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lat != AltosRecord.MISSING) { +					lat = state.gps.lat; +					label = "Latitude"; +				} else { +					lat = state.pad_lat; +					label = "Pad Latitude";  				}  			} +			if (lat != AltosRecord.MISSING) { +				show(pos(lat,"E", "W")); +				set_label(label); +			} else +				hide();  		}  		public PadLat (GridBagLayout layout, int y) {  			super (layout, y, "Pad Latitude"); @@ -331,17 +337,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {  	class PadLon extends LaunchValue {  		void show (AltosState state, AltosListenerState listener_state) { -			if (state == null || state.gps == null) { -				hide(); -			} else { -				if (state.state < AltosLib.ao_flight_pad) { -					show(pos(state.gps.lon,"E", "W")); -					set_label("Longitude"); -				} else {  -					show(pos(state.pad_lon,"E", "W")); -					set_label("Pad Longitude"); +			double lon = AltosRecord.MISSING; +			String label = null; + +			if (state != null) { +				if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.lon != AltosRecord.MISSING) { +					lon = state.gps.lon; +					label = "Longitude"; +				} else { +					lon = state.pad_lon; +					label = "Pad Longitude";  				}  			} +			if (lon != AltosRecord.MISSING) { +				show(pos(lon,"E", "W")); +				set_label(label); +			} else +				hide();  		}  		public PadLon (GridBagLayout layout, int y) {  			super (layout, y, "Pad Longitude"); @@ -352,21 +364,23 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {  	class PadAlt extends LaunchValue {  		void show (AltosState state, AltosListenerState listener_state) { -			if (state == null) -				hide(); -			else { -				if (state.state < AltosLib.ao_flight_pad && state.gps != null) { -					show("%4.0f m", state.gps.alt); -					set_label("Altitude"); +			double alt = AltosRecord.MISSING; +			String label = null; + +			if (state != null) { +				if (state.state < AltosLib.ao_flight_pad && state.gps != null && state.gps.alt != AltosRecord.MISSING) { +					alt = state.gps.alt; +					label = "Altitude";  				} else { -					if (state.pad_alt == AltosRecord.MISSING) -						hide(); -					else { -						show("%4.0f m", state.pad_alt); -						set_label("Pad Altitude"); -					} +					alt = state.pad_alt; +					label = "Pad Altitude";  				}  			} +			if (alt != AltosRecord.MISSING) { +				show("%4.0f m", state.gps.alt); +				set_label(label); +			} else +				hide();  		}  		public PadAlt (GridBagLayout layout, int y) {  			super (layout, y, "Pad Altitude"); diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index b47df0d9..151f68fd 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -350,10 +350,10 @@ public class AltosUI extends AltosUIFrame {  			FileInputStream in;  			in = new FileInputStream(file); -			if (file.getName().endsWith("eeprom")) -				return new AltosEepromFile(in); -			else +			if (file.getName().endsWith("telem"))  				return new AltosTelemetryFile(in); +			else +				return new AltosEepromFile(in);  		} catch (FileNotFoundException fe) {  			System.out.printf("%s\n", fe.getMessage());  			return null; @@ -434,11 +434,10 @@ public class AltosUI extends AltosUIFrame {  			System.out.printf("Failed to open file '%s'\n", file);  			return null;  		} -		if (file.getName().endsWith("eeprom")) { -			return new AltosEepromFile(in); -		} else { +		if (file.getName().endsWith("telem"))  			return new AltosTelemetryFile(in); -		} +		else +			return new AltosEepromFile(in);  	}  	static AltosReplayReader replay_file(File file) { @@ -521,6 +520,8 @@ public class AltosUI extends AltosUIFrame {  			System.out.printf ("process cat\n");  			for (AltosState state : eef) { +				System.out.printf ("tick %d state %d height %g\n", +						   state.tick, state.state, state.height);  				if ((state.set & AltosState.set_gps) != 0)  					System.out.printf ("time %g lat %g lon %g alt %g\n",  							   state.time_since_boost(), diff --git a/src/core/ao_log.h b/src/core/ao_log.h index a2f342d7..4b09faeb 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -276,7 +276,8 @@ struct ao_log_metrum {  			uint16_t	flight;		/* 4 */  			int16_t		ground_accel;	/* 6 */  			uint32_t	ground_pres;	/* 8 */ -		} flight;	/* 12 */ +			uint32_t	ground_temp;	/* 12 */ +		} flight;	/* 16 */  		/* AO_LOG_STATE */  		struct {  			uint16_t	state;		/* 4 */ | 
