diff options
89 files changed, 1220 insertions, 377 deletions
diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java index 7e3d6d07..4a9278d9 100644 --- a/altoslib/AltosCSV.java +++ b/altoslib/AltosCSV.java @@ -29,6 +29,14 @@ public class AltosCSV implements AltosWriter {  	LinkedList<AltosState>	pad_states;  	AltosState		state; +	static boolean		has_basic; +	static boolean		has_battery; +	static boolean		has_flight_state; +	static boolean		has_advanced; +	static boolean		has_gps; +	static boolean		has_gps_sat; +	static boolean		has_companion; +  	static final int ALTOS_CSV_VERSION = 5;  	/* Version 4 format: @@ -55,10 +63,12 @@ public class AltosCSV implements AltosWriter {  	 *	accelerometer speed (m/s)  	 *	barometer speed (m/s)  	 *	temp (°C) -	 *	battery (V)  	 *	drogue (V)  	 *	main (V)  	 * +	 * Battery +	 *	battery (V) +	 *  	 * Advanced sensors (if available)  	 *	accel_x (m/s²)  	 *	accel_y (m/s²) @@ -87,7 +97,9 @@ public class AltosCSV implements AltosWriter {  	 *	from_pad_azimuth (deg true)  	 *	from_pad_range (m)  	 *	from_pad_elevation (deg from horizon) +	 *	pdop  	 *	hdop +	 *	vdop  	 *  	 * GPS Sat data  	 *	C/N0 data for all 32 valid SDIDs @@ -107,7 +119,7 @@ public class AltosCSV implements AltosWriter {  	void write_general(AltosState state) {  		out.printf("%s, %d, %d, %s, %8.2f, %8.2f, %4d, %3d",  			   ALTOS_CSV_VERSION, state.serial, state.flight, state.callsign, -			   (double) state.time, (double) state.tick / 100.0, +			   (double) state.time_since_boost(), (double) state.tick / 100.0,  			   state.rssi,  			   state.status & 0x7f);  	} @@ -121,11 +133,11 @@ public class AltosCSV implements AltosWriter {  	}  	void write_basic_header() { -		out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,battery_voltage,drogue_voltage,main_voltage"); +		out.printf("acceleration,pressure,altitude,height,accel_speed,baro_speed,temperature,drogue_voltage,main_voltage");  	}  	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", +		out.printf("%8.2f,%10.2f,%8.2f,%8.2f,%8.2f,%8.2f,%5.1f,%5.2f,%5.2f",  			   state.acceleration(),  			   state.pressure(),  			   state.altitude(), @@ -133,11 +145,18 @@ public class AltosCSV implements AltosWriter {  			   state.speed(),  			   state.speed(),  			   state.temperature, -			   state.battery_voltage,  			   state.apogee_voltage,  			   state.main_voltage);  	} +	void write_battery_header() { +		out.printf("battery_voltage"); +	} + +	void write_battery(AltosState state) { +		out.printf("%5.2f", state.battery_voltage); +	} +  	void write_advanced_header() {  		out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z");  	} @@ -150,14 +169,14 @@ public class AltosCSV implements AltosWriter {  			imu = new AltosIMU();  		if (mag == null)  			mag = new AltosMag(); -		out.printf("%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d", +		out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f",  			   imu.accel_x, imu.accel_y, imu.accel_z,  			   imu.gyro_x, imu.gyro_y, imu.gyro_z,  			   mag.x, mag.y, mag.z);  	}  	void write_gps_header() { -		out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,hdop"); +		out.printf("connected,locked,nsat,latitude,longitude,altitude,year,month,day,hour,minute,second,pad_dist,pad_range,pad_az,pad_el,pdop,hdop,vdop");  	}  	void write_gps(AltosState state) { @@ -169,7 +188,7 @@ public class AltosCSV implements AltosWriter {  		if (from_pad == null)  			from_pad = new AltosGreatCircle(); -		out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f", +		out.printf("%2d,%2d,%3d,%12.7f,%12.7f,%8.1f,%5d,%3d,%3d,%3d,%3d,%3d,%9.0f,%9.0f,%4.0f,%4.0f,%6.1f,%6.1f,%6.1f",  			   gps.connected?1:0,  			   gps.locked?1:0,  			   gps.nsat, @@ -186,7 +205,9 @@ public class AltosCSV implements AltosWriter {  			   state.range,  			   from_pad.bearing,  			   state.elevation, -			   gps.hdop); +			   gps.pdop, +			   gps.hdop, +			   gps.vdop);  	}  	void write_gps_sat_header() { @@ -239,52 +260,83 @@ public class AltosCSV implements AltosWriter {  			out.printf(",0");  	} -	void write_header(boolean advanced, boolean gps, boolean companion) { +	void write_header() {  		out.printf("#"); write_general_header(); -		out.printf(","); write_flight_header(); -		out.printf(","); write_basic_header(); -		if (advanced) -			out.printf(","); write_advanced_header(); -		if (gps) { -			out.printf(","); write_gps_header(); -			out.printf(","); write_gps_sat_header(); +		if (has_flight_state) { +			out.printf(","); +			write_flight_header();  		} -		if (companion) { -			out.printf(","); write_companion_header(); +		if (has_basic) { +			out.printf(","); +			write_basic_header(); +		} +		if (has_battery) { +			out.printf(","); +			write_battery_header(); +		} +		if (has_advanced) { +			out.printf(","); +			write_advanced_header(); +		} +		if (has_gps) { +			out.printf(","); +			write_gps_header(); +		} +		if (has_gps_sat) { +			out.printf(","); +			write_gps_sat_header(); +		} +		if (has_companion) { +			out.printf(","); +			write_companion_header();  		}  		out.printf ("\n");  	}  	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_general(state); +		if (has_flight_state) { +			out.printf(","); +			write_flight(state); +		} +		if (has_basic) { +			out.printf(","); +			write_basic(state); +		} +		if (has_battery) { +			out.printf(","); +			write_battery(state); +		} +		if (has_advanced) { +			out.printf(",");  			write_advanced(state); -		if (state.gps != null) { +		} +		if (has_gps) { +			out.printf(","); +			write_gps(state); +		} +		if (has_gps_sat) {  			out.printf(","); -			write_gps(state); out.printf(",");  			write_gps_sat(state);  		} -		if (state.companion != null) { +		if (has_companion) {  			out.printf(",");  			write_companion(state);  		}  		out.printf ("\n");  	} -	void flush_pad() { +	private void flush_pad() {  		while (!pad_states.isEmpty()) {  			write_one (pad_states.remove());  		}  	} -	public void write(AltosState state) { +	private void write(AltosState state) {  		if (state.state == AltosLib.ao_flight_startup)  			return;  		if (!header_written) { -			write_header(state.imu != null || state.mag != null, -				     state.gps != null, state.companion != null); +			write_header();  			header_written = true;  		}  		if (!seen_boost) { @@ -300,7 +352,7 @@ public class AltosCSV implements AltosWriter {  			pad_states.add(state);  	} -	public PrintStream out() { +	private PrintStream out() {  		return out;  	} @@ -314,6 +366,31 @@ public class AltosCSV implements AltosWriter {  	public void write(AltosStateIterable states) {  		states.write_comments(out()); + +		has_flight_state = false; +		has_basic = false; +		has_battery = false; +		has_advanced = false; +		has_gps = false; +		has_gps_sat = false; +		has_companion = false; +		for (AltosState state : states) { +			if (state.state != AltosLib.ao_flight_stateless && state.state != AltosLib.ao_flight_invalid && state.state != AltosLib.ao_flight_startup) +				has_flight_state = true; +			if (state.acceleration() != AltosLib.MISSING || state.pressure() != AltosLib.MISSING) +				has_basic = true; +			if (state.battery_voltage != AltosLib.MISSING) +				has_battery = true; +			if (state.imu != null || state.mag != null) +				has_advanced = true; +			if (state.gps != null) { +				has_gps = true; +				if (state.gps.cc_gps_sat != null) +					has_gps_sat = true; +			} +			if (state.companion != null) +				has_companion = true; +		}  		for (AltosState state : states)  			write(state);  	} diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index 847436cd..134a0ed2 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -31,6 +31,7 @@ public class AltosConfigData implements Iterable<String> {  	public int	log_format;  	public int	log_space;  	public String	version; +	public int	altitude_32;  	/* Strings returned */  	public LinkedList<String>	lines; @@ -274,6 +275,7 @@ public class AltosConfigData implements Iterable<String> {  		try { flight = get_int(line, "current-flight"); } catch (Exception e) {}  		try { log_format = get_int(line, "log-format"); } catch (Exception e) {}  		try { log_space = get_int(line, "log-space"); } catch (Exception e) {} +		try { altitude_32 = get_int(line, "altitude-32"); } catch (Exception e) {}  		try { version = get_string(line, "software-version"); } catch (Exception e) {}  		/* Version also contains MS5607 info, which we ignore here */ @@ -484,6 +486,7 @@ public class AltosConfigData implements Iterable<String> {  		dest.set_serial(serial);  		dest.set_product(product);  		dest.set_version(version); +		dest.set_altitude_32(altitude_32);  		dest.set_main_deploy(main_deploy);  		dest.set_apogee_delay(apogee_delay);  		dest.set_apogee_lockout(apogee_lockout); diff --git a/altoslib/AltosConfigValues.java b/altoslib/AltosConfigValues.java index 987da53b..3f0a7075 100644 --- a/altoslib/AltosConfigValues.java +++ b/altoslib/AltosConfigValues.java @@ -25,6 +25,8 @@ public interface AltosConfigValues {  	public abstract void set_serial(int serial); +	public abstract void set_altitude_32(int altitude_32); +  	public abstract void set_main_deploy(int new_main_deploy);  	public abstract int main_deploy() throws AltosConfigDataException; diff --git a/altoslib/AltosEepromGPS.java b/altoslib/AltosEepromGPS.java index 2514b4fc..482f0b5f 100644 --- a/altoslib/AltosEepromGPS.java +++ b/altoslib/AltosEepromGPS.java @@ -37,7 +37,7 @@ public class AltosEepromGPS extends AltosEeprom {  	/* AO_LOG_GPS_TIME elements */  	public int latitude() { return data32(0); }  	public int longitude() { return data32(4); } -	public int altitude() { return data16(8); } +	public int altitude_low() { return data16(8); }  	public int hour() { return data8(10); }  	public int minute() { return data8(11); }  	public int second() { return data8(12); } @@ -52,6 +52,7 @@ public class AltosEepromGPS extends AltosEeprom {  	public int hdop() { return data8(23); }  	public int vdop() { return data8(24); }  	public int mode() { return data8(25); } +	public int altitude_high() { return data16(26); }  	public boolean has_seconds() { return cmd == AltosLib.AO_LOG_GPS_TIME; } @@ -99,7 +100,10 @@ public class AltosEepromGPS extends AltosEeprom {  			gps = state.make_temp_gps(false);  			gps.lat = latitude() / 1e7;  			gps.lon = longitude() / 1e7; -			gps.alt = altitude(); +			if (state.altitude_32()) +				gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16); +			else +				gps.alt = altitude_low();  			gps.hour = hour();  			gps.minute = minute(); @@ -118,8 +122,21 @@ public class AltosEepromGPS extends AltosEeprom {  			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(); +			if (state.compare_version("1.4.9") >= 0) { +				gps.pdop = pdop() / 10.0; +				gps.hdop = hdop() / 10.0; +				gps.vdop = vdop() / 10.0; +			} else { +				gps.pdop = pdop() / 100.0; +				if (gps.pdop < 0.8) +					gps.pdop += 2.56; +				gps.hdop = hdop() / 100.0; +				if (gps.hdop < 0.8) +					gps.hdop += 2.56; +				gps.vdop = vdop() / 100.0; +				if (gps.vdop < 0.8) +					gps.vdop += 2.56; +			}  			break;  		}  	} diff --git a/altoslib/AltosEepromHeader.java b/altoslib/AltosEepromHeader.java index 47e9eceb..71030655 100644 --- a/altoslib/AltosEepromHeader.java +++ b/altoslib/AltosEepromHeader.java @@ -96,6 +96,22 @@ public class AltosEepromHeader extends AltosEeprom {  		case AltosLib.AO_LOG_SOFTWARE_VERSION:  			state.set_firmware_version(data);  			break; +		case AltosLib.AO_LOG_FREQUENCY: +		case AltosLib.AO_LOG_APOGEE_LOCKOUT: +		case AltosLib.AO_LOG_RADIO_RATE: +		case AltosLib.AO_LOG_IGNITE_MODE: +		case AltosLib.AO_LOG_PAD_ORIENTATION: +		case AltosLib.AO_LOG_RADIO_ENABLE: +		case AltosLib.AO_LOG_AES_KEY: +		case AltosLib.AO_LOG_APRS: +		case AltosLib.AO_LOG_BEEP_SETTING: +		case AltosLib.AO_LOG_TRACKER_SETTING: +		case AltosLib.AO_LOG_PYRO_TIME: +		case AltosLib.AO_LOG_APRS_ID: +			break; +		case AltosLib.AO_LOG_ALTITUDE_32: +			state.set_altitude_32(config_a); +			break;  		}  	} @@ -161,6 +177,22 @@ public class AltosEepromHeader extends AltosEeprom {  		case AltosLib.AO_LOG_BARO_CRC:  			out.printf ("# Baro crc: %d\n", config_a);  			break; +		case AltosLib.AO_LOG_FREQUENCY: +		case AltosLib.AO_LOG_APOGEE_LOCKOUT: +		case AltosLib.AO_LOG_RADIO_RATE: +		case AltosLib.AO_LOG_IGNITE_MODE: +		case AltosLib.AO_LOG_PAD_ORIENTATION: +		case AltosLib.AO_LOG_RADIO_ENABLE: +		case AltosLib.AO_LOG_AES_KEY: +		case AltosLib.AO_LOG_APRS: +		case AltosLib.AO_LOG_BEEP_SETTING: +		case AltosLib.AO_LOG_TRACKER_SETTING: +		case AltosLib.AO_LOG_PYRO_TIME: +		case AltosLib.AO_LOG_APRS_ID: +			break; +		case AltosLib.AO_LOG_ALTITUDE_32: +			out.printf("# Altitude-32: %d\n", config_a); +			break;  		}  	} @@ -205,6 +237,9 @@ public class AltosEepromHeader extends AltosEeprom {  			} else if (tokens[0].equals("log-format")) {  				cmd = AltosLib.AO_LOG_LOG_FORMAT;  				config_a = Integer.parseInt(tokens[1]); +			} else if (tokens[0].equals("altitude-32")) { +				cmd = AltosLib.AO_LOG_ALTITUDE_32; +				config_a = Integer.parseInt(tokens[1]);  			} else if (tokens[0].equals("software-version")) {  				cmd = AltosLib.AO_LOG_SOFTWARE_VERSION;  				data = tokens[1]; diff --git a/altoslib/AltosEepromMega.java b/altoslib/AltosEepromMega.java index 5d5f3fef..adaa7f31 100644 --- a/altoslib/AltosEepromMega.java +++ b/altoslib/AltosEepromMega.java @@ -67,7 +67,7 @@ public class AltosEepromMega extends AltosEeprom {  	/* AO_LOG_GPS_TIME elements */  	public int latitude() { return data32(0); }  	public int longitude() { return data32(4); } -	public int altitude() { return data16(8); } +	public int altitude_low() { return data16(8); }  	public int hour() { return data8(10); }  	public int minute() { return data8(11); }  	public int second() { return data8(12); } @@ -82,6 +82,7 @@ public class AltosEepromMega extends AltosEeprom {  	public int hdop() { return data8(23); }  	public int vdop() { return data8(24); }  	public int mode() { return data8(25); } +	public int altitude_high() { return data16(26); }  	/* AO_LOG_GPS_SAT elements */  	public int nsat() { return data16(0); } @@ -168,7 +169,11 @@ public class AltosEepromMega extends AltosEeprom {  			gps = state.make_temp_gps(false);  			gps.lat = latitude() / 1e7;  			gps.lon = longitude() / 1e7; -			gps.alt = altitude(); + +			if (state.altitude_32()) +				gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16); +			else +				gps.alt = altitude_low();  			gps.hour = hour();  			gps.minute = minute(); @@ -187,8 +192,21 @@ public class AltosEepromMega extends AltosEeprom {  			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(); +			if (state.compare_version("1.4.9") >= 0) { +				gps.pdop = pdop() / 10.0; +				gps.hdop = hdop() / 10.0; +				gps.vdop = vdop() / 10.0; +			} else { +				gps.pdop = pdop() / 100.0; +				if (gps.pdop < 0.8) +					gps.pdop += 2.56; +				gps.hdop = hdop() / 100.0; +				if (gps.hdop < 0.8) +					gps.hdop += 2.56; +				gps.vdop = vdop() / 100.0; +				if (gps.vdop < 0.8) +					gps.vdop += 2.56; +			}  			break;  		case AltosLib.AO_LOG_GPS_SAT:  			state.set_tick(tick); diff --git a/altoslib/AltosEepromMetrum2.java b/altoslib/AltosEepromMetrum2.java index 24277118..d9a65989 100644 --- a/altoslib/AltosEepromMetrum2.java +++ b/altoslib/AltosEepromMetrum2.java @@ -49,7 +49,8 @@ public class AltosEepromMetrum2 extends AltosEeprom {  	/* AO_LOG_GPS_POS elements */  	public int latitude() { return data32(0); }  	public int longitude() { return data32(4); } -	public int altitude() { return data16(8); } +	public int altitude_low() { return data16(8); } +	public int altitude_high() { return data16(10); }  	/* AO_LOG_GPS_TIME elements */  	public int hour() { return data8(0); } @@ -59,6 +60,7 @@ public class AltosEepromMetrum2 extends AltosEeprom {  	public int year() { return data8(4); }  	public int month() { return data8(5); }  	public int day() { return data8(6); } +	public int pdop() { return data8(7); }  	/* AO_LOG_GPS_SAT elements */  	public int nsat() { return data8(0); } @@ -117,7 +119,10 @@ public class AltosEepromMetrum2 extends AltosEeprom {  			gps = state.make_temp_gps(false);  			gps.lat = latitude() / 1e7;  			gps.lon = longitude() / 1e7; -			gps.alt = altitude(); +			if (state.altitude_32()) +				gps.alt = (altitude_low() & 0xffff) | (altitude_high() << 16); +			else +				gps.alt = altitude_low();  			break;  		case AltosLib.AO_LOG_GPS_TIME:  			gps = state.make_temp_gps(false); @@ -136,6 +141,7 @@ public class AltosEepromMetrum2 extends AltosEeprom {  			gps.year = 2000 + year();  			gps.month = month();  			gps.day = day(); +			gps.pdop = pdop() / 10.0;  			break;  		case AltosLib.AO_LOG_GPS_SAT:  			gps = state.make_temp_gps(true); diff --git a/altoslib/AltosGPS.java b/altoslib/AltosGPS.java index aabcfc5b..0154e95d 100644 --- a/altoslib/AltosGPS.java +++ b/altoslib/AltosGPS.java @@ -40,10 +40,11 @@ public class AltosGPS implements Cloneable {  	public double	ground_speed;	/* m/s */  	public int	course;		/* degrees */  	public double	climb_rate;	/* m/s */ +	public double	pdop;		/* unitless */  	public double	hdop;		/* unitless */  	public double	vdop;		/* unitless */ -	public int	h_error;	/* m */ -	public int	v_error;	/* m */ +	public double	h_error;	/* m */ +	public double	v_error;	/* m */  	public AltosGPSSat[] cc_gps_sat;	/* tracking data */ @@ -95,6 +96,7 @@ public class AltosGPS implements Cloneable {  						      AltosLib.MISSING, 1/100.0);  			course = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_COURSE,  					     AltosLib.MISSING); +			pdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_PDOP, MISSING, 1.0);  			hdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_HDOP, MISSING, 1.0);  			vdop = map.get_double(AltosTelemetryLegacy.AO_TELEM_GPS_VDOP, MISSING, 1.0);  			h_error = map.get_int(AltosTelemetryLegacy.AO_TELEM_GPS_HERROR, MISSING); @@ -268,14 +270,26 @@ public class AltosGPS implements Cloneable {  		cc_gps_sat[cc_gps_sat.length - 1] = sat;  	} -	public AltosGPS() { +	private void init() {  		lat = AltosLib.MISSING;  		lon = AltosLib.MISSING;  		alt = AltosLib.MISSING; +		ground_speed = AltosLib.MISSING; +		course = AltosLib.MISSING; +		climb_rate = AltosLib.MISSING; +		pdop = AltosLib.MISSING; +		hdop = AltosLib.MISSING; +		vdop = AltosLib.MISSING; +		h_error = AltosLib.MISSING; +		v_error = AltosLib.MISSING;  		ClearGPSTime();  		cc_gps_sat = null;  	} +	public AltosGPS() { +		init(); +	} +  	public AltosGPS clone() {  		AltosGPS	g = new AltosGPS(); @@ -295,7 +309,9 @@ public class AltosGPS implements Cloneable {  		g.ground_speed = ground_speed;	/* m/s */  		g.course = course;		/* degrees */  		g.climb_rate = climb_rate;	/* m/s */ -		g.hdop = hdop;		/* unitless? */ +		g.pdop = pdop;		/* unitless */ +		g.hdop = hdop;		/* unitless */ +		g.vdop = vdop;		/* unitless */  		g.h_error = h_error;	/* m */  		g.v_error = v_error;	/* m */ @@ -327,9 +343,11 @@ public class AltosGPS implements Cloneable {  			ground_speed = old.ground_speed;	/* m/s */  			course = old.course;		/* degrees */  			climb_rate = old.climb_rate;	/* m/s */ +			pdop = old.pdop;		/* unitless? */  			hdop = old.hdop;		/* unitless? */ -			h_error = old.h_error;	/* m */ -			v_error = old.v_error;	/* m */ +			vdop = old.vdop;		/* unitless? */ +			h_error = old.h_error;		/* m */ +			v_error = old.v_error;		/* m */  			if (old.cc_gps_sat != null) {  				cc_gps_sat = new AltosGPSSat[old.cc_gps_sat.length]; @@ -340,11 +358,7 @@ public class AltosGPS implements Cloneable {  				}  			}  		} else { -			lat = AltosLib.MISSING; -			lon = AltosLib.MISSING; -			alt = AltosLib.MISSING; -			ClearGPSTime(); -			cc_gps_sat = null; +			init();  		}  	} diff --git a/altoslib/AltosKML.java b/altoslib/AltosKML.java index e31ddfba..e701fda3 100644 --- a/altoslib/AltosKML.java +++ b/altoslib/AltosKML.java @@ -28,18 +28,25 @@ public class AltosKML implements AltosWriter {  	double			gps_start_altitude;  	static final String[] kml_state_colors = { -		"FF000000", -		"FF000000", -		"FF000000", -		"FF0000FF", -		"FF4080FF", -		"FF00FFFF", -		"FFFF0000", -		"FF00FF00", -		"FF000000", -		"FFFFFFFF" +		"FF000000",	// startup +		"FF000000",	// idle +		"FF000000",	// pad +		"FF0000FF",	// boost +		"FF4080FF",	// fast +		"FF00FFFF",	// coast +		"FFFF0000",	// drogue +		"FF00FF00",	// main +		"FF000000",	// landed +		"FFFFFFFF",	// invalid +		"FFFF0000",	// stateless  	}; +	static String state_color(int state) { +		if (state < 0 || kml_state_colors.length <= state) +			return kml_state_colors[AltosLib.ao_flight_invalid]; +		return kml_state_colors[state]; +	} +  	static final String kml_header_start =  		"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +  		"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" + @@ -95,7 +102,8 @@ public class AltosKML implements AltosWriter {  	void state_start(AltosState state) {  		String	state_name = AltosLib.state_name(state.state); -		out.printf(kml_style_start, state_name, kml_state_colors[state.state]); +		String	state_color = state_color(state.state); +		out.printf(kml_style_start, state_name, state_color);  		out.printf("\tState: %s\n", state_name);  		out.printf("%s", kml_style_end);  		out.printf(kml_placemark_start, state_name, state_name); diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index c2ec0e3b..68bdd17f 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -51,6 +51,20 @@ public class AltosLib {  	public static final int AO_LOG_SERIAL_NUMBER = 2002;  	public static final int AO_LOG_LOG_FORMAT = 2003; +	public static final int AO_LOG_FREQUENCY = 2004; +	public static final int AO_LOG_APOGEE_LOCKOUT = 2005; +	public static final int AO_LOG_RADIO_RATE = 2006; +	public static final int AO_LOG_IGNITE_MODE = 2007; +	public static final int AO_LOG_PAD_ORIENTATION = 2008; +	public static final int AO_LOG_RADIO_ENABLE = 2009; +	public static final int AO_LOG_AES_KEY = 2010; +	public static final int AO_LOG_APRS = 2011; +	public static final int AO_LOG_BEEP_SETTING = 2012; +	public static final int AO_LOG_TRACKER_SETTING = 2013; +	public static final int AO_LOG_PYRO_TIME = 2014; +	public static final int AO_LOG_APRS_ID = 2015; +	public static final int AO_LOG_ALTITUDE_32 = 2016; +  	/* Added for header fields in telemega files */  	public static final int AO_LOG_BARO_RESERVED = 3000;  	public static final int AO_LOG_BARO_SENS = 3001; @@ -215,6 +229,31 @@ public class AltosLib {  								 telemetry));  	} +	private static int[] split_version(String version) { +		String[] tokens = version.split("\\."); +		int[] ret = new int[tokens.length]; +		for (int i = 0; i < tokens.length; i++) +			ret[i] = Integer.parseInt(tokens[i]); +		return ret; +	} + +	public static int compare_version(String version_a, String version_b) { +		int[] a = split_version(version_a); +		int[] b = split_version(version_b); + +		for (int i = 0; i < Math.min(a.length, b.length); i++) { +			if (a[i] < b[i]) +				return -1; +			if (a[i] > b[i]) +				return 1; +		} +		if (a.length < b.length) +			return -1; +		if (a.length > b.length) +			return 1; +		return 0; +	} +  	private static String[] state_to_string = {  		"startup",  		"idle", diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 5e7908af..5fce15c4 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -271,6 +271,7 @@ public class AltosState implements Cloneable {  	public int	state;  	public int	flight;  	public int	serial; +	public int	altitude_32;  	public int	receiver_serial;  	public boolean	landed;  	public boolean	ascent;	/* going up? */ @@ -472,15 +473,23 @@ public class AltosState implements Cloneable {  		pressure.set(p, time);  	} +	public double baro_height() { +		double a = altitude(); +		double g = ground_altitude(); +		if (a != AltosLib.MISSING && g != AltosLib.MISSING) +			return a - g; +		return AltosLib.MISSING; +	} +  	public double height() {  		double k = kalman_height.value();  		if (k != AltosLib.MISSING)  			return k; -		double a = altitude(); -		double g = ground_altitude(); -		if (a != AltosLib.MISSING && g != AltosLib.MISSING) -			return a - g; +		double b = baro_height(); +		if (b != AltosLib.MISSING) +			return b; +  		return gps_height();  	} @@ -762,6 +771,7 @@ public class AltosState implements Cloneable {  		product = null;  		serial = AltosLib.MISSING;  		receiver_serial = AltosLib.MISSING; +		altitude_32 = AltosLib.MISSING;  		baro = null;  		companion = null; @@ -899,6 +909,7 @@ public class AltosState implements Cloneable {  		product = old.product;  		serial = old.serial;  		receiver_serial = old.receiver_serial; +		altitude_32 = old.altitude_32;  		baro = old.baro;  		companion = old.companion; @@ -1024,6 +1035,12 @@ public class AltosState implements Cloneable {  		firmware_version = version;  	} +	public int compare_version(String other_version) { +		if (firmware_version == null) +			return AltosLib.MISSING; +		return AltosLib.compare_version(firmware_version, other_version); +	} +  	private void re_init() {  		int bt = boost_tick;  		int rs = receiver_serial; @@ -1060,6 +1077,15 @@ public class AltosState implements Cloneable {  			receiver_serial = serial;  	} +	public boolean altitude_32() { +		return altitude_32 == 1; +	} + +	public void set_altitude_32(int altitude_32) { +		if (altitude_32 != AltosLib.MISSING) +			this.altitude_32 = altitude_32; +	} +  	public int rssi() {  		if (rssi == AltosLib.MISSING)  			return 0; diff --git a/altoslib/AltosTelemetry.java b/altoslib/AltosTelemetry.java index 4d50a059..2f15cd89 100644 --- a/altoslib/AltosTelemetry.java +++ b/altoslib/AltosTelemetry.java @@ -114,6 +114,35 @@ public abstract class AltosTelemetry implements AltosStateUpdate {  		return telem;  	} +	public static int extend_height(AltosState state, int height_16) { +		double	compare_height; +		int	height = height_16; + +		System.out.printf("state kalman height %g altitude %g ground_altitude %g gps_height %g\n", +				  state.kalman_height.value(), state.altitude(), state.ground_altitude(), state.gps_height()); +		if (state.gps != null && state.gps.alt != AltosLib.MISSING) { +			compare_height = state.gps_height(); +		} else { +			compare_height = state.height(); +		} + +		if (compare_height != AltosLib.MISSING) { +			int	high_bits = (int) Math.floor (compare_height / 65536.0); + +			height = (high_bits << 16) | (height_16 & 0xffff); + +			if (Math.abs(height + 65536 - compare_height) < Math.abs(height - compare_height)) +				height += 65536; +			else if (Math.abs(height - 65536 - compare_height) < Math.abs(height - compare_height)) +				height -= 65536; +			if (height != height_16) { +				System.out.printf("Height adjusted from %d to %d with %g\n", +						  height_16, height, compare_height); +			} +		} +		return height; +	} +  	public static AltosTelemetry parse(String line) throws ParseException, AltosCRCException {  		String[] word = line.split("\\s+");  		int i =0; diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index b7aae3c4..72a8bc4a 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -186,6 +186,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry {  	 *	g_v		GPS vertical speed (integer, cm/sec)  	 *	g_s		GPS horizontal speed (integer, cm/sec)  	 *	g_c		GPS course (integer, 0-359) +	 *	g_pd		GPS pdop (integer * 10)  	 *	g_hd		GPS hdop (integer * 10)  	 *	g_vd		GPS vdop (integer * 10)  	 *	g_he		GPS h error (integer) @@ -209,6 +210,7 @@ public class AltosTelemetryLegacy extends AltosTelemetry {  	final static String AO_TELEM_GPS_VERTICAL_SPEED		= "g_v";  	final static String AO_TELEM_GPS_HORIZONTAL_SPEED	= "g_g";  	final static String AO_TELEM_GPS_COURSE			= "g_c"; +	final static String AO_TELEM_GPS_PDOP			= "g_pd";  	final static String AO_TELEM_GPS_HDOP			= "g_hd";  	final static String AO_TELEM_GPS_VDOP			= "g_vd";  	final static String AO_TELEM_GPS_HERROR			= "g_he"; diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index 32ca7608..427ae16e 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -37,11 +37,12 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard {  	int	climb_rate;  	int	course; +	public static final int	AO_GPS_MODE_ALTITUDE_24 = (1 << 0);	/* Reports 24-bits of altitude */ +  	public AltosTelemetryLocation(int[] bytes) {  		super(bytes);  		flags          = uint8(5); -		altitude       = int16(6);  		latitude       = uint32(8);  		longitude      = uint32(12);  		year	       = uint8(16); @@ -57,6 +58,11 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard {  		ground_speed   = uint16(26);  		climb_rate     = int16(28);  		course	       = uint8(30); + +		if ((mode & AO_GPS_MODE_ALTITUDE_24) != 0) { +			altitude = (int8(31) << 16) | uint16(6); +		} else +			altitude = int16(6);  	}  	public void update_state(AltosState state) { @@ -80,8 +86,9 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard {  			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; +			gps.pdop = pdop / 10.0; +			gps.hdop = hdop / 10.0; +			gps.vdop = vdop / 10.0;  		}  		state.set_temp_gps();  	} diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java index 93610118..8b1869bb 100644 --- a/altoslib/AltosTelemetryMegaData.java +++ b/altoslib/AltosTelemetryMegaData.java @@ -31,7 +31,7 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard {  	int	acceleration;  	int	speed; -	int	height; +	int	height_16;  	public AltosTelemetryMegaData(int[] bytes) {  		super(bytes); @@ -55,7 +55,8 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard {  		acceleration = int16(26);  		speed = int16(28); -		height = int16(30); + +		height_16 = int16(30);  	}  	public void update_state(AltosState state) { @@ -79,7 +80,13 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard {  		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); +		/* Fill in the high bits of height from recent GPS +		 * data if available, otherwise guess using the +		 * previous kalman height +		 */ + +		state.set_kalman(extend_height(state, height_16), +				 speed/16.0, acceleration / 16.0);  	}  } diff --git a/altoslib/AltosTelemetryMetrumSensor.java b/altoslib/AltosTelemetryMetrumSensor.java index 3e0abedc..beab6da9 100644 --- a/altoslib/AltosTelemetryMetrumSensor.java +++ b/altoslib/AltosTelemetryMetrumSensor.java @@ -27,7 +27,7 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {  	int	acceleration;  	int	speed; -	int	height; +	int	height_16;  	int	v_batt;  	int	sense_a; @@ -43,7 +43,7 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {  		acceleration  = int16(14);  		speed         = int16(16); -		height        = int16(18); +		height_16     = int16(18);  		v_batt        = int16(20);  		sense_a       = int16(22); @@ -59,7 +59,8 @@ public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {  		state.set_pressure(pres);  		state.set_temperature(temp/100.0); -		state.set_kalman(height, speed/16.0, acceleration/16.0); +		state.set_kalman(extend_height(state, height_16), +				 speed/16.0, acceleration/16.0);  		state.set_battery_voltage(AltosConvert.mega_battery_voltage(v_batt)); diff --git a/altoslib/AltosWriter.java b/altoslib/AltosWriter.java index 9df52250..fb208b02 100644 --- a/altoslib/AltosWriter.java +++ b/altoslib/AltosWriter.java @@ -19,8 +19,6 @@ package org.altusmetrum.altoslib_5;  public interface AltosWriter { -	public void write(AltosState state); -  	public void write(AltosStateIterable states);  	public void close(); diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index 043cb876..9fcace61 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -926,6 +926,9 @@ public class AltosConfigUI  		serial_value.setText(String.format("%d", serial));  	} +	public void set_altitude_32(int altitude_32) { +	} +  	public void set_main_deploy(int new_main_deploy) {  		main_deploy_value.setSelectedItem(AltosConvert.height.say(new_main_deploy));  		main_deploy_value.setEnabled(new_main_deploy >= 0); diff --git a/altosui/AltosConfigureUI.java b/altosui/AltosConfigureUI.java index 80d6d341..85a3f6c0 100644 --- a/altosui/AltosConfigureUI.java +++ b/altosui/AltosConfigureUI.java @@ -89,6 +89,8 @@ public class AltosConfigureUI  		row++;  	} +	boolean has_bluetooth; +  	public void add_bluetooth() {  		JButton manage_bluetooth = new JButton("Manage Bluetooth");  		manage_bluetooth.addActionListener(new ActionListener() { @@ -98,6 +100,7 @@ public class AltosConfigureUI  			});  		pane.add(manage_bluetooth, constraints(0, 2));  		/* in the same row as add_frequencies, so don't bump row */ +		has_bluetooth = true;  	}  	public void add_frequencies() { @@ -108,7 +111,10 @@ public class AltosConfigureUI  				}  			});  		manage_frequencies.setToolTipText("Configure which values are shown in frequency menus"); -		pane.add(manage_frequencies, constraints(2, 1)); +		if (has_bluetooth) +			pane.add(manage_frequencies, constraints(2, 1)); +		else +			pane.add(manage_frequencies, constraints(0, 3));  		row++;  	} diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java index 50c1ea31..7c50adac 100644 --- a/altosui/AltosLanded.java +++ b/altosui/AltosLanded.java @@ -151,6 +151,12 @@ public class AltosLanded extends AltosUIFlightTab implements ActionListener {  		return "Landed";  	} +	public void show(AltosState state, AltosListenerState listener_state) { +		super.show(state, listener_state); +		if (reader.backing_file() != null) +			graph.setEnabled(true); +	} +  	public AltosLanded(AltosFlightReader in_reader) {  		reader = in_reader; diff --git a/altosui/Makefile.am b/altosui/Makefile.am index c79e27c0..44258fd2 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -104,6 +104,14 @@ MACOSX_ICONS	=\  	$(ICONDIR)/application-vnd.altusmetrum.eeprom.icns \  	$(ICONDIR)/application-vnd.altusmetrum.telemetry.icns +LINUX_ICONS	=\ +	$(ICONDIR)/altusmetrum-altosui.svg \ +	$(ICONDIR)/application-vnd.altusmetrum.eeprom.svg \ +	$(ICONDIR)/application-vnd.altusmetrum.telemetry.svg + +LINUX_MIMETYPE	=\ +	$(ICONDIR)/org-altusmetrum-mimetypes.xml +  # Firmware  FIRMWARE_TD_0_2=$(top_srcdir)/src/teledongle-v0.2/teledongle-v0.2-$(VERSION).ihx  FIRMWARE_TD=$(FIRMWARE_TD_0_2) @@ -152,7 +160,7 @@ FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFR  LINUX_LIBS=libaltos32.so libaltos64.so -LINUX_FILES=$(FAT_FILES) $(LINUX_LIBS) $(FIRMWARE) $(DOC) $(desktop_file).in $(ICONDIR)/altusmetrum-altosui.svg +LINUX_FILES=$(FAT_FILES) $(LINUX_LIBS) $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)  LINUX_EXTRA=altosui-fat  MACOSX_INFO_PLIST=Info.plist diff --git a/altosui/linux-install.sh b/altosui/linux-install.sh index 957b1aad..2e44c2aa 100644 --- a/altosui/linux-install.sh +++ b/altosui/linux-install.sh @@ -130,6 +130,7 @@ esac  #  # Create the .desktop file by editing the paths  # +  case "$target" in  /*)      target_abs="$target" @@ -149,43 +150,46 @@ for infile in "$target"/AltOS/*.desktop.in; do  done  # -# Figure out where to install the .desktop files. If we can, write it -# to the public /usr/share/applications, otherwise, write it to the -# per-user ~/.local/share/applications +# Install the .desktop file  # -public=/usr/share/applications -private=$HOME/.local/share/applications -apps="" +for desktop in "$target"/AltOS/*.desktop; do +    case `id -u` in +	0) +	    xdg-desktop-menu install --mode system "$desktop" +	    ;; +	*) +	    xdg-desktop-menu install --mode user "$desktop" +	    ;; +    esac +done -if [ -d "$public" -a -w "$public" ]; then -    apps="$public" -else -    mkdir -p "$private" >/dev/null 2>&1  -    if [ -d "$private" -a -w "$private" ]; then -	apps="$private" -    fi -fi -	 -case "$apps" in -"") -    echo "Cannot install application icon" -    finish 1 -    ;; -esac +# +# Install mime type file +# + +for mimetype in "$target"/AltOS/*-mimetypes.xml; do +    case `id -u` in +	0) +	    xdg-mime install --mode system "$mimetype" +	    ;; +	*) +	    xdg-mime install --mode user "$mimetype" +	    ;; +    esac +done -echo -n "Installing .desktop files to $apps..." +# +# Install icons +# -cp "$target"/AltOS/*.desktop "$apps" +for icon_dir in /usr/share/icons/hicolor/scalable/mimetypes "$HOME/.icons" "$HOME/.kde/share/icons"; do +    if [ -w "$icon_dir" ]; then +	cp "$target"/AltOS/*.svg "$icon_dir" +	update-icon-caches "$icon_dir" +    fi +done -case "$?" in -0) -    echo " done." -    ;; -*) -    echo " failed." -    ;; -esac  #  # Install icon to desktop if desired @@ -222,13 +226,14 @@ if [ -d $HOME/Desktop ]; then  	esac      done -    echo -n "Installing desktop icons..."      case "$do_desktop" in -    [yY]*) -	for d in "$target"/AltOS/*.desktop; do -	    ln -f -s "$d" "$HOME/Desktop/" -	done -	;; +	[yY]*) +	    echo -n "Installing desktop icons..." +	    for d in "$target"/AltOS/*.desktop; do +		base=`basename $d` +		cp --remove-destination "$d" "$HOME/Desktop/" +	    done +	    ;;      esac      echo " done." diff --git a/altosuilib/AltosDeviceDialog.java b/altosuilib/AltosDeviceDialog.java index 0875bea7..d2ccd5e7 100644 --- a/altosuilib/AltosDeviceDialog.java +++ b/altosuilib/AltosDeviceDialog.java @@ -131,7 +131,8 @@ public abstract class AltosDeviceDialog extends AltosUIDialog implements ActionL  		buttonPane.add(cancel_button);  		buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); -		add_bluetooth(); +		if (AltosUILib.has_bluetooth) +			add_bluetooth();  		buttonPane.add(select_button); diff --git a/altosuilib/AltosGraph.java b/altosuilib/AltosGraph.java index 292437de..522eea1e 100644 --- a/altosuilib/AltosGraph.java +++ b/altosuilib/AltosGraph.java @@ -172,6 +172,29 @@ class AltosMagUnits extends AltosUnits {  	}  } +class AltosDopUnits extends AltosUnits { + +	public double value(double p, boolean imperial_units) { +		return p; +	} + +	public double inverse(double p, boolean imperial_units) { +		return p; +	} + +	public String show_units(boolean imperial_units) { +		return null; +	} + +	public String say_units(boolean imperial_units) { +		return null; +	} + +	public int show_fraction(int width, boolean imperial_units) { +		return 1; +	} +} +  public class AltosGraph extends AltosUIGraph {  	static final private Color height_color = new Color(194,31,31); @@ -191,6 +214,9 @@ public class AltosGraph extends AltosUIGraph {  	static final private Color gps_course_color = new Color (100, 31, 112);  	static final private Color gps_ground_speed_color = new Color (31, 112, 100);  	static final private Color gps_climb_rate_color = new Color (31, 31, 112); +	static final private Color gps_pdop_color = new Color(50, 194, 0); +	static final private Color gps_hdop_color = new Color(50, 0, 194); +	static final private Color gps_vdop_color = new Color(194, 0, 50);  	static final private Color temperature_color = new Color (31, 194, 194);  	static final private Color dbm_color = new Color(31, 100, 100);  	static final private Color state_color = new Color(0,0,0); @@ -212,11 +238,12 @@ public class AltosGraph extends AltosUIGraph {  	static AltosGyroUnits gyro_units = new AltosGyroUnits();  	static AltosOrient orient_units = new AltosOrient();  	static AltosMagUnits mag_units = new AltosMagUnits(); +	static AltosDopUnits dop_units = new AltosDopUnits();  	AltosUIAxis	height_axis, speed_axis, accel_axis, voltage_axis, temperature_axis, nsat_axis, dbm_axis;  	AltosUIAxis	distance_axis, pressure_axis;  	AltosUIAxis	gyro_axis, orient_axis, mag_axis; -	AltosUIAxis	course_axis; +	AltosUIAxis	course_axis, dop_axis;  	public AltosGraph(AltosUIEnable enable, AltosFlightStats stats, AltosGraphDataSet dataSet) {  		super(enable); @@ -236,6 +263,7 @@ public class AltosGraph extends AltosUIGraph {  		orient_axis = newAxis("Tilt Angle", orient_units, orient_color, 0);  		mag_axis = newAxis("Magnetic Field", mag_units, mag_x_color, 0);  		course_axis = newAxis("Course", orient_units, gps_course_color, 0); +		dop_axis = newAxis("Dilution of Precision", dop_units, gps_pdop_color, 0);  		addMarker("State", AltosGraphDataPoint.data_state, state_color); @@ -325,6 +353,24 @@ public class AltosGraph extends AltosUIGraph {  				  gps_climb_rate_color,  				  enable_gps,  				  speed_axis); +			addSeries("GPS Position DOP", +				  AltosGraphDataPoint.data_gps_pdop, +				  dop_units, +				  gps_pdop_color, +				  false, +				  dop_axis); +			addSeries("GPS Horizontal DOP", +				  AltosGraphDataPoint.data_gps_hdop, +				  dop_units, +				  gps_hdop_color, +				  false, +				  dop_axis); +			addSeries("GPS Vertical DOP", +				  AltosGraphDataPoint.data_gps_vdop, +				  dop_units, +				  gps_vdop_color, +				  false, +				  dop_axis);  		}  		if (stats.has_rssi)  			addSeries("Received Signal Strength", diff --git a/altosuilib/AltosGraphDataPoint.java b/altosuilib/AltosGraphDataPoint.java index 14486abf..56dadb8b 100644 --- a/altosuilib/AltosGraphDataPoint.java +++ b/altosuilib/AltosGraphDataPoint.java @@ -53,7 +53,10 @@ public class AltosGraphDataPoint implements AltosUIDataPoint {  	public static final int data_gps_course = 27;  	public static final int data_gps_ground_speed = 28;  	public static final int data_gps_climb_rate = 29; -	public static final int data_ignitor_0 = 30; +	public static final int data_gps_pdop = 30; +	public static final int data_gps_hdop = 31; +	public static final int data_gps_vdop = 32; +	public static final int data_ignitor_0 = 33;  	public static final int data_ignitor_num = 32;  	public static final int data_ignitor_max = data_ignitor_0 + data_ignitor_num - 1;  	public static final int data_ignitor_fired_0 = data_ignitor_0 + data_ignitor_num; @@ -194,6 +197,24 @@ public class AltosGraphDataPoint implements AltosUIDataPoint {  			else  				y = AltosLib.MISSING;  			break; +		case data_gps_pdop: +			if (state.gps != null) +				y = state.gps.pdop; +			else +				y = AltosLib.MISSING; +			break; +		case data_gps_hdop: +			if (state.gps != null) +				y = state.gps.hdop; +			else +				y = AltosLib.MISSING; +			break; +		case data_gps_vdop: +			if (state.gps != null) +				y = state.gps.vdop; +			else +				y = AltosLib.MISSING; +			break;  		default:  			if (data_ignitor_0 <= index && index <= data_ignitor_max) {  				int ignitor = index - data_ignitor_0; diff --git a/altosuilib/AltosInfoTable.java b/altosuilib/AltosInfoTable.java index ce986ac5..625fe76f 100644 --- a/altosuilib/AltosInfoTable.java +++ b/altosuilib/AltosInfoTable.java @@ -198,24 +198,28 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay, Hierar  				if (state.gps_height != AltosLib.MISSING)  					info_add_row(1, "GPS height", "%8.1f", state.gps_height); -				/* The SkyTraq GPS doesn't report these values */ -				/* -				  if (false) { -				  info_add_row(1, "GPS ground speed", "%8.1f m/s %3d°", -				  state.gps.ground_speed, -				  state.gps.course); -				  info_add_row(1, "GPS climb rate", "%8.1f m/s", -				  state.gps.climb_rate); -				  info_add_row(1, "GPS error", "%6d m(h)%3d m(v)", -				  state.gps.h_error, state.gps.v_error); -				  } -				*/ - -				info_add_row(1, "GPS hdop", "%8.1f", state.gps.hdop); +				if (state.gps.ground_speed != AltosLib.MISSING && state.gps.course != AltosLib.MISSING) +					info_add_row(1, "GPS ground speed", "%6.1f m/s %3d°", +						     state.gps.ground_speed, +						     state.gps.course); +				if (state.gps.climb_rate != AltosLib.MISSING) +					info_add_row(1, "GPS climb rate", "%6.1f m/s", +						     state.gps.climb_rate); + +				if (state.gps.h_error != AltosLib.MISSING && state.gps.v_error != AltosLib.MISSING) +					info_add_row(1, "GPS error", "%6d m(h)%3d m(v)", +						     state.gps.h_error, state.gps.v_error); +				if (state.gps.pdop != AltosLib.MISSING && +				    state.gps.hdop != AltosLib.MISSING && +				    state.gps.vdop != AltosLib.MISSING) +					info_add_row(1, "GPS dop", "%3.1fp/%3.1fh/%3.1fv", +						     state.gps.pdop, +						     state.gps.hdop, +						     state.gps.vdop);  				if (state.npad > 0) {  					if (state.from_pad != null) { -						info_add_row(1, "Distance from pad", "%6d m", +						info_add_row(1, "Ground pad dist", "%6d m",  							     (int) (state.from_pad.distance + 0.5));  						info_add_row(1, "Direction from pad", "%6d°",  							     (int) (state.from_pad.bearing + 0.5)); @@ -234,12 +238,12 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay, Hierar  					info_add_row(1, "Pad GPS alt", "%6.0f m", state.pad_alt);  				}  				if (state.gps.year != AltosLib.MISSING) -					info_add_row(1, "GPS date", "%04d-%02d-%02d", +					info_add_row(2, "GPS date", "%04d-%02d-%02d",  						     state.gps.year,  						     state.gps.month,  						     state.gps.day);  				if (state.gps.hour != AltosLib.MISSING) -					info_add_row(1, "GPS time", "  %02d:%02d:%02d", +					info_add_row(2, "GPS time", "  %02d:%02d:%02d",  						     state.gps.hour,  						     state.gps.minute,  						     state.gps.second); diff --git a/altosuilib/AltosScanUI.java b/altosuilib/AltosScanUI.java index 7b5f2c7e..7e51a55a 100644 --- a/altosuilib/AltosScanUI.java +++ b/altosuilib/AltosScanUI.java @@ -356,10 +356,13 @@ public class AltosScanUI  				if (r != null) {  					if (device != null) {  						if (reader != null) { +							System.out.printf("frequency %g rate %d\n", r.frequency.frequency, r.rate);  							reader.set_telemetry(r.telemetry);  							reader.set_telemetry_rate(r.rate);  							reader.set_frequency(r.frequency.frequency);  							reader.save_frequency(); +							reader.save_telemetry(); +							reader.save_telemetry_rate();  							owner.scan_device_selected(device);  						}  					} @@ -519,7 +522,7 @@ public class AltosScanUI  				rate_boxes[k].addActionListener(this);  				rate_boxes[k].setSelected((scanning_rate & (1 << k)) != 0);  			} -			y_offset_rate += AltosLib.ao_telemetry_rate_max; +			y_offset_rate += AltosLib.ao_telemetry_rate_max + 1;  		}  		if (select_telemetry) { diff --git a/altosuilib/AltosUIAxis.java b/altosuilib/AltosUIAxis.java index 1b5b9205..9e98ddb7 100644 --- a/altosuilib/AltosUIAxis.java +++ b/altosuilib/AltosUIAxis.java @@ -48,7 +48,11 @@ public class AltosUIAxis extends NumberAxis {  	public final static int axis_default = axis_include_zero;  	public void set_units() { -		setLabel(String.format("%s (%s)", label, units.show_units())); +		String u = units.show_units(); +		if (u != null) +			setLabel(String.format("%s (%s)", label, u)); +		else +			setLabel(label);  	}  	public void set_enable(boolean enable) { diff --git a/altosuilib/AltosUIConfigure.java b/altosuilib/AltosUIConfigure.java index 5648d1df..9c0f3bc7 100644 --- a/altosuilib/AltosUIConfigure.java +++ b/altosuilib/AltosUIConfigure.java @@ -283,7 +283,8 @@ public class AltosUIConfigure  		add_look_and_feel();  		add_position();  		add_map_cache(); -		add_bluetooth(); +		if (AltosUILib.has_bluetooth) +			add_bluetooth();  		add_frequencies();  		/* And a close button at the bottom */ diff --git a/altosuilib/AltosUIFrame.java b/altosuilib/AltosUIFrame.java index 5b915e85..2e886932 100644 --- a/altosuilib/AltosUIFrame.java +++ b/altosuilib/AltosUIFrame.java @@ -36,12 +36,12 @@ public class AltosUIFrame extends JFrame implements AltosUIListener, AltosPositi  	}  	static String[] altos_icon_names = { -		"/altus-metrum-16.png", -		"/altus-metrum-32.png", -		"/altus-metrum-48.png", -		"/altus-metrum-64.png", -		"/altus-metrum-128.png", -		"/altus-metrum-256.png" +		"/altusmetrum-altosui-16.png", +		"/altusmetrum-altosui-32.png", +		"/altusmetrum-altosui-48.png", +		"/altusmetrum-altosui-64.png", +		"/altusmetrum-altosui-128.png", +		"/altusmetrum-altosui-256.png"  	};  	static public String[] icon_names; diff --git a/altosuilib/AltosUILib.java b/altosuilib/AltosUILib.java index 0050f12c..8fa7dfe6 100644 --- a/altosuilib/AltosUILib.java +++ b/altosuilib/AltosUILib.java @@ -80,6 +80,7 @@ public class AltosUILib extends AltosLib {  	static public boolean initialized = false;  	static public boolean loaded_library = false; +	static public boolean has_bluetooth = false;  	static final String[] library_names = { "altos", "altos32", "altos64" }; @@ -96,6 +97,13 @@ public class AltosUILib extends AltosLib {  					loaded_library = false;  				}  			} + +			String OS = System.getProperty("os.name"); + +			if (OS.startsWith("Linux")) { +				has_bluetooth = true; +			} +  			initialized = true;  		}  		return loaded_library; diff --git a/ao-tools/lib/cc-convert.c b/ao-tools/lib/cc-convert.c index 8d6876a0..b82dd778 100644 --- a/ao-tools/lib/cc-convert.c +++ b/ao-tools/lib/cc-convert.c @@ -108,6 +108,29 @@ cc_altitude_to_pressure(double altitude)     return pressure;  } +double +cc_altitude_to_temperature(double altitude) +{ + +   double base_temperature = LAYER0_BASE_TEMPERATURE; +   double temperature; + +   int layer_number; /* identifies layer in the atmosphere */ +   double delta_z; /* difference between two altitudes */ + +   /* calculate the base temperature for the atmospheric layer +      associated with the inputted altitude */ +   for(layer_number = 0; layer_number < NUMBER_OF_LAYERS - 1 && altitude > base_altitude[layer_number + 1]; layer_number++) { +      delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number]; +      base_temperature += delta_z * lapse_rate[layer_number]; +   } + +   /* calculate the pressure at the inputted altitude */ +   delta_z = altitude - base_altitude[layer_number]; +   temperature = base_temperature + lapse_rate[layer_number] * delta_z; + +   return temperature - 273.15; +}  /* outputs the altitude associated with the given pressure. the altitude     returned is measured with respect to the mean sea level */ diff --git a/ao-tools/lib/cc.h b/ao-tools/lib/cc.h index c07f8cd0..bff4b2c9 100644 --- a/ao-tools/lib/cc.h +++ b/ao-tools/lib/cc.h @@ -346,6 +346,143 @@ struct ao_log_mega {  	} u;  }; +struct ao_log_metrum { +	char			type;			/* 0 */ +	uint8_t			csum;			/* 1 */ +	uint16_t		tick;			/* 2 */ +	union {						/* 4 */ +		/* AO_LOG_FLIGHT */ +		struct { +			uint16_t	flight;		/* 4 */ +			int16_t		ground_accel;	/* 6 */ +			uint32_t	ground_pres;	/* 8 */ +			uint32_t	ground_temp;	/* 12 */ +		} flight;	/* 16 */ +		/* AO_LOG_STATE */ +		struct { +			uint16_t	state;		/* 4 */ +			uint16_t	reason;		/* 6 */ +		} state;	/* 8 */ +		/* AO_LOG_SENSOR */ +		struct { +			uint32_t	pres;		/* 4 */ +			uint32_t	temp;		/* 8 */ +			int16_t		accel;		/* 12 */ +		} sensor;	/* 14 */ +		/* AO_LOG_TEMP_VOLT */ +		struct { +			int16_t		v_batt;		/* 4 */ +			int16_t		sense_a;	/* 6 */ +			int16_t		sense_m;	/* 8 */ +		} volt;		/* 10 */ +		/* AO_LOG_GPS_POS */ +		struct { +			int32_t		latitude;	/* 4 */ +			int32_t		longitude;	/* 8 */ +			uint16_t	altitude_low;	/* 12 */ +			int16_t		altitude_high;	/* 14 */ +		} gps;		/* 16 */ +		/* AO_LOG_GPS_TIME */ +		struct { +			uint8_t		hour;		/* 4 */ +			uint8_t		minute;		/* 5 */ +			uint8_t		second;		/* 6 */ +			uint8_t		flags;		/* 7 */ +			uint8_t		year;		/* 8 */ +			uint8_t		month;		/* 9 */ +			uint8_t		day;		/* 10 */ +			uint8_t		pdop;		/* 11 */ +		} gps_time;	/* 12 */ +		/* AO_LOG_GPS_SAT (up to three packets) */ +		struct { +			uint8_t	channels;		/* 4 */ +			uint8_t	more;			/* 5 */ +			struct { +				uint8_t	svid; +				uint8_t c_n; +			} sats[4];			/* 6 */ +		} gps_sat;				/* 14 */ +		uint8_t		raw[12];		/* 4 */ +	} u;	/* 16 */ +}; + +struct ao_log_mini { +	char		type;				/* 0 */ +	uint8_t		csum;				/* 1 */ +	uint16_t	tick;				/* 2 */ +	union {						/* 4 */ +		/* AO_LOG_FLIGHT */ +		struct { +			uint16_t	flight;		/* 4 */ +			uint16_t	r6; +			uint32_t	ground_pres;	/* 8 */ +		} flight; +		/* AO_LOG_STATE */ +		struct { +			uint16_t	state;		/* 4 */ +			uint16_t	reason;		/* 6 */ +		} state; +		/* AO_LOG_SENSOR */ +		struct { +			uint8_t		pres[3];	/* 4 */ +			uint8_t		temp[3];	/* 7 */ +			int16_t		sense_a;	/* 10 */ +			int16_t		sense_m;	/* 12 */ +			int16_t		v_batt;		/* 14 */ +		} sensor;				/* 16 */ +	} u;						/* 16 */ +};							/* 16 */ + +#define ao_log_pack24(dst,value) do {		\ +		(dst)[0] = (value);		\ +		(dst)[1] = (value) >> 8;	\ +		(dst)[2] = (value) >> 16;	\ +	} while (0) + +struct ao_log_gps { +	char			type;			/* 0 */ +	uint8_t			csum;			/* 1 */ +	uint16_t		tick;			/* 2 */ +	union {						/* 4 */ +		/* AO_LOG_FLIGHT */ +		struct { +			uint16_t	flight;			/* 4 */ +			int16_t		start_altitude;		/* 6 */ +			int32_t		start_latitude;		/* 8 */ +			int32_t		start_longitude;	/* 12 */ +		} flight;					/* 16 */ +		/* AO_LOG_GPS_TIME */ +		struct { +			int32_t		latitude;	/* 4 */ +			int32_t		longitude;	/* 8 */ +			uint16_t	altitude_low;	/* 12 */ +			uint8_t		hour;		/* 14 */ +			uint8_t		minute;		/* 15 */ +			uint8_t		second;		/* 16 */ +			uint8_t		flags;		/* 17 */ +			uint8_t		year;		/* 18 */ +			uint8_t		month;		/* 19 */ +			uint8_t		day;		/* 20 */ +			uint8_t		course;		/* 21 */ +			uint16_t	ground_speed;	/* 22 */ +			int16_t		climb_rate;	/* 24 */ +			uint8_t		pdop;		/* 26 */ +			uint8_t		hdop;		/* 27 */ +			uint8_t		vdop;		/* 28 */ +			uint8_t		mode;		/* 29 */ +			int16_t		altitude_high;	/* 30 */ +		} gps;	/* 31 */ +		/* AO_LOG_GPS_SAT */ +		struct { +			uint16_t	channels;	/* 4 */ +			struct { +				uint8_t	svid; +				uint8_t c_n; +			} sats[12];			/* 6 */ +		} gps_sat;				/* 30 */ +	} u; +}; +  #define AO_CONFIG_CONFIG		1  #define AO_CONFIG_MAIN			2  #define AO_CONFIG_APOGEE		3 @@ -380,9 +517,30 @@ struct ao_log_mega {  #define AO_LOG_GPS_ALT		'H'  #define AO_LOG_GPS_SAT		'V'  #define AO_LOG_GPS_DATE		'Y' +#define AO_LOG_GPS_POS		'P'  #define AO_LOG_CONFIG		'c' +#define AO_GPS_NUM_SAT_MASK	(0xf << 0) +#define AO_GPS_NUM_SAT_SHIFT	(0) + +#define AO_GPS_VALID		(1 << 4) +#define AO_GPS_RUNNING		(1 << 5) +#define AO_GPS_DATE_VALID	(1 << 6) +#define AO_GPS_COURSE_VALID	(1 << 7) + +#define AO_LOG_FORMAT_UNKNOWN		0	/* unknown; altosui will have to guess */ +#define AO_LOG_FORMAT_FULL		1	/* 8 byte typed log records */ +#define AO_LOG_FORMAT_TINY		2	/* two byte state/baro records */ +#define AO_LOG_FORMAT_TELEMETRY		3	/* 32 byte ao_telemetry records */ +#define AO_LOG_FORMAT_TELESCIENCE	4	/* 32 byte typed telescience records */ +#define AO_LOG_FORMAT_TELEMEGA		5	/* 32 byte typed telemega records */ +#define AO_LOG_FORMAT_EASYMINI		6	/* 16-byte MS5607 baro only, 3.0V supply */ +#define AO_LOG_FORMAT_TELEMETRUM	7	/* 16-byte typed telemetrum records */ +#define AO_LOG_FORMAT_TELEMINI		8	/* 16-byte MS5607 baro only, 3.3V supply */ +#define AO_LOG_FORMAT_TELEGPS		9	/* 32 byte telegps records */ +#define AO_LOG_FORMAT_NONE		127	/* No log at all */ +  int  cc_mega_parse(const char *input_line, struct ao_log_mega *l); @@ -399,6 +557,9 @@ double  cc_altitude_to_pressure(double altitude);  double +cc_altitude_to_temperature(double altitude); + +double  cc_barometer_to_pressure(double baro);  double diff --git a/configure.ac b/configure.ac index 8cc5adc1..c2b8b55c 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl  dnl Process this file with autoconf to create configure.  AC_PREREQ(2.57) -AC_INIT([altos], 1.4.9.1) +AC_INIT([altos], 1.4.9.2)  AC_CONFIG_SRCDIR([src/kernel/ao.h])  AM_INIT_AUTOMAKE([foreign dist-bzip2])  AM_MAINTAINER_MODE diff --git a/libaltos/Makefile.am b/libaltos/Makefile.am index d2531133..1db2d486 100644 --- a/libaltos/Makefile.am +++ b/libaltos/Makefile.am @@ -41,8 +41,7 @@ cjnitest64_LDADD=libaltos64.la  endif - -LIBS=-lbluetooth +LIBS=-ldl  HFILES=libaltos.h diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index b7ec98fc..4e3bc2c5 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -643,6 +643,49 @@ altos_list_finish(struct altos_list *usbdevs)  	free(usbdevs);  } +#include <dlfcn.h> + +static void *libbt; +static int bt_initialized; + +static int init_bt(void) { +	if (!bt_initialized) { +		bt_initialized = 1; +		libbt = dlopen("libbluetooth.so.3", RTLD_LAZY); +		if (!libbt) +			printf("failed to find bluetooth library\n"); +	} +	return libbt != NULL; +} + +#define join(a,b)	a ## b +#define bt_func(name, ret, fail, formals, actuals)			\ +	static ret join(altos_, name) formals {				\ +				      static ret (*name) formals;	\ +				      if (!init_bt()) return fail;	\ +				      name = dlsym(libbt, #name);	\ +				      if (!name) return fail;		\ +				      return name actuals;		\ +				      } + +bt_func(ba2str, int, -1, (const bdaddr_t *ba, char *str), (ba, str)) +#define ba2str altos_ba2str + +bt_func(str2ba, int, -1, (const char *str, bdaddr_t *ba), (str, ba)) +#define str2ba altos_str2ba + +bt_func(hci_read_remote_name, int, -1, (int sock, const bdaddr_t *ba, int len, char *name, int timeout), (sock, ba, len, name, timeout)) +#define hci_read_remote_name altos_hci_read_remote_name + +bt_func(hci_open_dev, int, -1, (int dev_id), (dev_id)) +#define hci_open_dev altos_hci_open_dev + +bt_func(hci_get_route, int, -1, (bdaddr_t *bdaddr), (bdaddr)) +#define hci_get_route altos_hci_get_route + +bt_func(hci_inquiry, int, -1, (int adapter_id, int len, int max_rsp, const uint8_t *lap, inquiry_info **devs, long flags), (adapter_id, len, max_rsp, lap, devs, flags)) +#define hci_inquiry altos_hci_inquiry +  struct altos_bt_list {  	inquiry_info	*ii;  	int		sock; @@ -706,7 +749,8 @@ altos_bt_list_next(struct altos_bt_list *bt_list,  		return 0;  	ii = &bt_list->ii[bt_list->rsp]; -	ba2str(&ii->bdaddr, device->addr); +	if (ba2str(&ii->bdaddr, device->addr) < 0) +		return 0;  	memset(&device->name, '\0', sizeof (device->name));  	if (hci_read_remote_name(bt_list->sock, &ii->bdaddr,  				 sizeof (device->name), @@ -742,11 +786,17 @@ altos_bt_open(struct altos_bt_device *device)  	struct altos_file *file;  	file = calloc(1, sizeof (struct altos_file)); -	if (!file) +	if (!file) { +		errno = ENOMEM; +		altos_set_last_posix_error();  		goto no_file; +	}  	addr.rc_family = AF_BLUETOOTH;  	addr.rc_channel = 1; -	str2ba(device->addr, &addr.rc_bdaddr); +	if (str2ba(device->addr, &addr.rc_bdaddr) < 0) { +		altos_set_last_posix_error(); +		goto no_sock; +	}  	for (i = 0; i < 5; i++) {  		file->fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index e3b77c8a..15865606 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -82,6 +82,13 @@ MACOSX_ICONS	=\  	../icon/altusmetrum-micropeak.icns \  	../icon/application-vnd.altusmetrum.micropeak.icns +LINUX_ICONS	=\ +	$(ICONDIR)/altusmetrum-micropeak.svg \ +	$(ICONDIR)/application-vnd.altusmetrum.micropeak.svg + +LINUX_MIMETYPE	=\ +	$(ICONDIR)/org-altusmetrum-mimetypes.xml +  desktopdir = $(datadir)/applications  desktop_file = altusmetrum-micropeak.desktop  desktop_SCRIPTS = $(desktop_file) @@ -114,7 +121,7 @@ DOC=$(MICROPEAK_DOC)  FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) -LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in ../icon/altusmetrum-micropeak.svg +LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)  LINUX_EXTRA=micropeak-fat $(desktop_file).in  MACOSX_DRIVER_URL=http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_18.dmg diff --git a/micropeak/MicroFrame.java b/micropeak/MicroFrame.java index f82d1c5e..8b3d49b5 100644 --- a/micropeak/MicroFrame.java +++ b/micropeak/MicroFrame.java @@ -25,12 +25,12 @@ import org.altusmetrum.altosuilib_3.*;  public class MicroFrame extends AltosUIFrame {  	static String[] micro_icon_names = { -		"/micropeak-16.png", -		"/micropeak-32.png", -		"/micropeak-48.png", -		"/micropeak-64.png", -		"/micropeak-128.png", -		"/micropeak-256.png" +		"/altusmetrum-micropeak-16.png", +		"/altusmetrum-micropeak-32.png", +		"/altusmetrum-micropeak-48.png", +		"/altusmetrum-micropeak-64.png", +		"/altusmetrum-micropeak-128.png", +		"/altusmetrum-micropeak-256.png"  	};  	static { set_icon_names(micro_icon_names); } diff --git a/src/Makefile b/src/Makefile index a7a26b26..3494ba62 100644 --- a/src/Makefile +++ b/src/Makefile @@ -109,7 +109,7 @@ altitude-pa.h: make-altitude-pa  altitude-pa-small.h: make-altitude-pa  	nickle $< --sample 3 > $@ -ao_kalman.h: make-kalman kalman.5c kalman_filter.5c load_csv.5c matrix.5c +ao_kalman.h: make-kalman kalman.5c kalman_micro.5c kalman_filter.5c load_csv.5c matrix.5c  	bash $< kalman > $@  ao_whiten.h: make-whiten diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 1bc3d716..e12f813f 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -20,6 +20,8 @@  #define HAS_RADIO		1  #define DISABLE_LOG_SPACE	1 +#define AO_VALUE_32		0 +#define HAS_WIDE_GPS		0  #if defined(TELEMETRUM_V_1_0)  	/* Discontinued and was never built with CC1111 chips needing this */ diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index a9047149..19beb78f 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -713,7 +713,7 @@ static int tncPositionPacket(void)      if (ao_gps_data.flags & AO_GPS_VALID) {  	latitude = ao_gps_data.latitude;  	longitude = ao_gps_data.longitude; -	altitude = ao_gps_data.altitude; +	altitude = AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data);  	if (altitude < 0)  	    altitude = 0;      } diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 944a37f9..066df6ff 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -278,16 +278,17 @@ ao_nmea_gga(void)  	ao_gps_lexchar();  	i = ao_gps_decimal(0xff); -	if (i <= 50) { -		i = (uint8_t) 5 * i; +	if (i <= 25) { +		i = (uint8_t) 10 * i;  		if (ao_gps_char == '.') -			i = (i + ((uint8_t) ao_gps_decimal(1) >> 1)); +			i = (i + ((uint8_t) ao_gps_decimal(1)));  	} else  		i = 255;  	ao_gps_next.hdop = i;  	ao_gps_skip_field(); -	ao_gps_next.altitude = ao_gps_decimal(0xff); +	AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_next, ao_gps_decimal(0xff)); +  	ao_gps_skip_field();	/* skip any fractional portion */  	ao_nmea_finish(); diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 077698a9..74c29e0a 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -728,7 +728,7 @@ ao_gps(void) __reentrant  				if (nav_timeutc.valid & (1 << NAV_TIMEUTC_VALID_UTC))  					ao_gps_data.flags |= AO_GPS_DATE_VALID; -				ao_gps_data.altitude = nav_posllh.alt_msl / 1000; +				AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_data, nav_posllh.alt_msl / 1000);  				ao_gps_data.latitude = nav_posllh.lat;  				ao_gps_data.longitude = nav_posllh.lon; @@ -740,11 +740,11 @@ ao_gps(void) __reentrant  				ao_gps_data.minute = nav_timeutc.min;  				ao_gps_data.second = nav_timeutc.sec; -				ao_gps_data.pdop = nav_dop.pdop; -				ao_gps_data.hdop = nav_dop.hdop; -				ao_gps_data.vdop = nav_dop.vdop; - -				/* mode is not set */ +				/* we report dop scaled by 10, but ublox provides dop scaled by 100 +				 */ +				ao_gps_data.pdop = nav_dop.pdop / 10; +				ao_gps_data.hdop = nav_dop.hdop / 10; +				ao_gps_data.vdop = nav_dop.vdop / 10;  				ao_gps_data.ground_speed = nav_velned.g_speed;  				ao_gps_data.climb_rate = -nav_velned.vel_d; diff --git a/src/drivers/ao_lco_func.c b/src/drivers/ao_lco_func.c index 9e642836..32c00068 100644 --- a/src/drivers/ao_lco_func.c +++ b/src/drivers/ao_lco_func.c @@ -28,7 +28,21 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset)  {  	int8_t		r;  	uint16_t	sent_time; +	uint16_t	timeout = AO_MS_TO_TICKS(10); +#if HAS_RADIO_RATE +	switch (ao_config.radio_rate) { +	case AO_RADIO_RATE_38400: +	default: +		break; +	case AO_RADIO_RATE_9600: +		timeout = AO_MS_TO_TICKS(20); +		break; +	case AO_RADIO_RATE_2400: +		timeout = AO_MS_TO_TICKS(80); +		break; +	} +#endif  	ao_mutex_get(&ao_lco_mutex);  	command.tick = ao_time() - *tick_offset;  	command.box = box; @@ -36,7 +50,7 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset)  	command.channels = 0;  	ao_radio_cmac_send(&command, sizeof (command));  	sent_time = ao_time(); -	r = ao_radio_cmac_recv(query, sizeof (*query), AO_MS_TO_TICKS(10)); +	r = ao_radio_cmac_recv(query, sizeof (*query), timeout);  	if (r == AO_RADIO_CMAC_OK)  		*tick_offset = sent_time - query->tick;  	ao_mutex_put(&ao_lco_mutex); diff --git a/src/kalman/kalman.5c b/src/kalman/kalman.5c index 46fa8e1f..55fde04c 100755 --- a/src/kalman/kalman.5c +++ b/src/kalman/kalman.5c @@ -457,7 +457,7 @@ void main() {  					name = sprintf("%s_K%d_%d", prefix, i, time_inc);  				else  					name = sprintf("%s_K%d%d_%d", prefix, i, j, time_inc); -				printf ("#define %s to_fix32(%12.10f)\n", name, k[i,j]); +				printf ("#define %s to_fix_k(%12.10f)\n", name, k[i,j]);  			}  		printf ("\n");  		exit(0); diff --git a/src/kalman/kalman_micro.5c b/src/kalman/kalman_micro.5c index 266a1182..1b080384 100644 --- a/src/kalman/kalman_micro.5c +++ b/src/kalman/kalman_micro.5c @@ -307,7 +307,7 @@ void main() {  					name = sprintf("%s_K%d_%d", prefix, i, time_inc);  				else  					name = sprintf("%s_K%d%d_%d", prefix, i, j, time_inc); -				printf ("#define %s to_fix32(%12.10f)\n", name, k[i,j]); +				printf ("#define %s to_fix_k(%12.10f)\n", name, k[i,j]);  			}  		printf ("\n");  		exit(0); diff --git a/src/kernel/ao.h b/src/kernel/ao.h index a225bc4a..ad5bbf8e 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -278,15 +278,17 @@ ao_report_init(void);   * Given raw data, convert to SI units   */ +#if HAS_BARO  /* pressure from the sensor to altitude in meters */ -int16_t -ao_pres_to_altitude(int16_t pres) __reentrant; +alt_t +ao_pres_to_altitude(pres_t pres) __reentrant; -int16_t -ao_altitude_to_pres(int16_t alt) __reentrant; +pres_t +ao_altitude_to_pres(alt_t alt) __reentrant;  int16_t  ao_temp_to_dC(int16_t temp) __reentrant; +#endif  /*   * ao_convert_pa.c @@ -296,11 +298,13 @@ ao_temp_to_dC(int16_t temp) __reentrant;  #include <ao_data.h> +#if HAS_BARO  alt_t -ao_pa_to_altitude(int32_t pa); +ao_pa_to_altitude(pres_t pa);  int32_t  ao_altitude_to_pa(alt_t alt); +#endif  #if HAS_DBG  #include <ao_dbg.h> diff --git a/src/kernel/ao_cmd.c b/src/kernel/ao_cmd.c index 0052bdce..d2f583ef 100644 --- a/src/kernel/ao_cmd.c +++ b/src/kernel/ao_cmd.c @@ -290,6 +290,9 @@ version(void)  #if defined(AO_BOOT_APPLICATION_BASE) && defined(AO_BOOT_APPLICATION_BOUND)  	       "program-space    %u\n"  #endif +#if AO_VALUE_32 +	       "altitude-32      1\n" +#endif  	       , ao_manufacturer  	       , ao_product  	       , ao_serial_number diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 32a0967c..d73a3733 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -518,6 +518,9 @@ ao_config_radio_rate_set(void) __reentrant  	ao_telemetry_reset_interval();  #endif  	_ao_config_edit_finish(); +#if HAS_RADIO_RECV +	ao_radio_recv_abort(); +#endif  }  #endif diff --git a/src/kernel/ao_convert.c b/src/kernel/ao_convert.c index aa9b5f48..db1f2301 100644 --- a/src/kernel/ao_convert.c +++ b/src/kernel/ao_convert.c @@ -19,14 +19,16 @@  #include "ao.h"  #endif -static const int16_t altitude_table[] = { +#include <ao_sample.h> + +static const ao_v_t altitude_table[] = {  #include "altitude.h"  };  #define ALT_FRAC_SCALE	(1 << ALT_FRAC_BITS)  #define ALT_FRAC_MASK	(ALT_FRAC_SCALE - 1) -int16_t +ao_v_t  ao_pres_to_altitude(int16_t pres) __reentrant  {  	uint8_t	o; @@ -43,9 +45,9 @@ ao_pres_to_altitude(int16_t pres) __reentrant  #if AO_NEED_ALTITUDE_TO_PRES  int16_t -ao_altitude_to_pres(int16_t alt) __reentrant +ao_altitude_to_pres(ao_v_t alt) __reentrant  { -	int16_t span, sub_span; +	ao_v_t span, sub_span;  	uint8_t	l, h, m;  	int32_t pres; diff --git a/src/kernel/ao_convert_pa.c b/src/kernel/ao_convert_pa.c index 20162c1f..410815b6 100644 --- a/src/kernel/ao_convert_pa.c +++ b/src/kernel/ao_convert_pa.c @@ -39,11 +39,11 @@ static const alt_t altitude_table[] AO_CONST_ATTRIB = {  #define ALT_MASK	(ALT_SCALE - 1)  alt_t -ao_pa_to_altitude(int32_t pa) +ao_pa_to_altitude(pres_t pa)  {  	int16_t	o;  	int16_t	part; -	int32_t low, high; +	alt_t low, high;  	if (pa < 0)  		pa = 0; @@ -52,16 +52,16 @@ ao_pa_to_altitude(int32_t pa)  	o = pa >> ALT_SHIFT;  	part = pa & ALT_MASK; -	low = (int32_t) FETCH_ALT(o) * (ALT_SCALE - part); -	high = (int32_t) FETCH_ALT(o+1) * part + (ALT_SCALE >> 1); +	low = (alt_t) FETCH_ALT(o) * (ALT_SCALE - part); +	high = (alt_t) FETCH_ALT(o+1) * part + (ALT_SCALE >> 1);  	return (low + high) >> ALT_SHIFT;  }  #ifdef AO_CONVERT_TEST -int32_t -ao_altitude_to_pa(int32_t alt) +pres_t +ao_altitude_to_pa(alt_t alt)  { -	int32_t 	span, sub_span; +	alt_t 	span, sub_span;  	uint16_t	l, h, m;  	int32_t 	pa; @@ -76,7 +76,7 @@ ao_altitude_to_pa(int32_t alt)  	}  	span = altitude_table[l] - altitude_table[h];  	sub_span = altitude_table[l] - alt; -	pa = ((((int32_t) l * (span - sub_span) + (int32_t) h * sub_span) << ALT_SHIFT) + (span >> 1)) / span; +	pa = ((((alt_t) l * (span - sub_span) + (alt_t) h * sub_span) << ALT_SHIFT) + (span >> 1)) / span;  	if (pa > 120000)  		pa = 120000;  	if (pa < 0) diff --git a/src/kernel/ao_convert_pa_test.c b/src/kernel/ao_convert_pa_test.c index 7d5b1922..95422862 100644 --- a/src/kernel/ao_convert_pa_test.c +++ b/src/kernel/ao_convert_pa_test.c @@ -18,6 +18,7 @@  #include <stdint.h>  #define AO_CONVERT_TEST  typedef int32_t alt_t; +typedef int32_t pres_t;  #include "ao_host.h"  #include "ao_convert_pa.c" diff --git a/src/kernel/ao_data.h b/src/kernel/ao_data.h index c4b062fd..8f75ad87 100644 --- a/src/kernel/ao_data.h +++ b/src/kernel/ao_data.h @@ -117,9 +117,7 @@ extern volatile __data uint8_t		ao_data_count;  typedef int32_t	pres_t; -#ifndef AO_ALT_TYPE  #define AO_ALT_TYPE	int32_t -#endif  typedef AO_ALT_TYPE	alt_t; @@ -146,10 +144,6 @@ typedef int16_t alt_t;  #endif -#if !HAS_BARO -typedef int16_t alt_t; -#endif -  /*   * Need a few macros to pull data from the sensors:   * diff --git a/src/kernel/ao_flight.c b/src/kernel/ao_flight.c index 2b433ee9..251dbc02 100644 --- a/src/kernel/ao_flight.c +++ b/src/kernel/ao_flight.c @@ -60,10 +60,10 @@ __xdata uint8_t			ao_sensor_errors;   * resting   */  static __data uint16_t		ao_interval_end; -static __data int16_t		ao_interval_min_height; -static __data int16_t		ao_interval_max_height; +static __data ao_v_t		ao_interval_min_height; +static __data ao_v_t		ao_interval_max_height;  #if HAS_ACCEL -static __data int16_t		ao_coast_avg_accel; +static __data ao_v_t		ao_coast_avg_accel;  #endif  __pdata uint8_t			ao_flight_force_idle; @@ -398,14 +398,14 @@ ao_flight(void)  }  #if HAS_FLIGHT_DEBUG -static inline int int_part(int16_t i)	{ return i >> 4; } -static inline int frac_part(int16_t i)	{ return ((i & 0xf) * 100 + 8) / 16; } +static inline int int_part(ao_v_t i)	{ return i >> 4; } +static inline int frac_part(ao_v_t i)	{ return ((i & 0xf) * 100 + 8) / 16; }  static void  ao_flight_dump(void)  {  #if HAS_ACCEL -	int16_t	accel; +	ao_v_t	accel;  	accel = ((ao_config.accel_plus_g - ao_sample_accel) * ao_accel_scale) >> 16;  #endif diff --git a/src/kernel/ao_gps_print.c b/src/kernel/ao_gps_print.c index 47c945d7..d26021da 100644 --- a/src/kernel/ao_gps_print.c +++ b/src/kernel/ao_gps_print.c @@ -20,6 +20,10 @@  #endif  #include "ao_telem.h" +#ifndef AO_TELEMETRY_LOCATION_ALTITUDE +#define AO_TELEMETRY_LOCATION_ALTITUDE(l)	((l)->altitude) +#endif +  void  ao_gps_print(__xdata struct ao_gps_orig *gps_data) __reentrant  { @@ -42,7 +46,7 @@ ao_gps_print(__xdata struct ao_gps_orig *gps_data) __reentrant  	       AO_TELEM_GPS_ALTITUDE " %d ",  	       (long) gps_data->latitude,  	       (long) gps_data->longitude, -	       gps_data->altitude); +	       AO_TELEMETRY_LOCATION_ALTITUDE(gps_data));  	if (gps_data->flags & AO_GPS_DATE_VALID)  		printf(AO_TELEM_GPS_YEAR " %d " diff --git a/src/kernel/ao_gps_report.c b/src/kernel/ao_gps_report.c index 07201ac2..7ef98a97 100644 --- a/src/kernel/ao_gps_report.c +++ b/src/kernel/ao_gps_report.c @@ -52,8 +52,12 @@ ao_gps_report(void)  			gps_log.u.gps_longitude = gps_data.longitude;  			ao_log_data(&gps_log);  			gps_log.type = AO_LOG_GPS_ALT; -			gps_log.u.gps_altitude.altitude = gps_data.altitude; -			gps_log.u.gps_altitude.unused = 0xffff; +			gps_log.u.gps_altitude.altitude_low = gps_data.altitude_low; +#if HAS_WIDE_GPS +			gps_log.u.gps_altitude.altitude_high = gps_data.altitude_high; +#else +			gps_log.u.gps_altitude.altitude_high = 0xffff; +#endif  			ao_log_data(&gps_log);  			if (!date_reported && (gps_data.flags & AO_GPS_DATE_VALID)) {  				gps_log.type = AO_LOG_GPS_DATE; diff --git a/src/kernel/ao_gps_report_mega.c b/src/kernel/ao_gps_report_mega.c index cb0c0fd9..f3711fb1 100644 --- a/src/kernel/ao_gps_report_mega.c +++ b/src/kernel/ao_gps_report_mega.c @@ -78,7 +78,8 @@ ao_gps_report_mega(void)  #if GPS_SPARSE_LOG  		/* Don't log data if GPS has a fix and hasn't moved for a while */  		if ((gps_data.flags & AO_GPS_VALID) && -		    !ao_gps_sparse_should_log(gps_data.latitude, gps_data.longitude, gps_data.altitude)) +		    !ao_gps_sparse_should_log(gps_data.latitude, gps_data.longitude, +					      AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data))  			continue;  #endif  		if ((new & AO_GPS_NEW_DATA) && (gps_data.flags & AO_GPS_VALID)) { @@ -87,8 +88,8 @@ ao_gps_report_mega(void)  			gps_log.type = AO_LOG_GPS_TIME;  			gps_log.u.gps.latitude = gps_data.latitude;  			gps_log.u.gps.longitude = gps_data.longitude; -			gps_log.u.gps.altitude = gps_data.altitude; - +			gps_log.u.gps.altitude_low = gps_data.altitude_low; +			gps_log.u.gps.altitude_high = gps_data.altitude_high;  			gps_log.u.gps.hour = gps_data.hour;  			gps_log.u.gps.minute = gps_data.minute;  			gps_log.u.gps.second = gps_data.second; diff --git a/src/kernel/ao_gps_report_metrum.c b/src/kernel/ao_gps_report_metrum.c index 696a833b..8ce074fe 100644 --- a/src/kernel/ao_gps_report_metrum.c +++ b/src/kernel/ao_gps_report_metrum.c @@ -44,7 +44,8 @@ ao_gps_report_metrum(void)  			gps_log.type = AO_LOG_GPS_POS;  			gps_log.u.gps.latitude = gps_data.latitude;  			gps_log.u.gps.longitude = gps_data.longitude; -			gps_log.u.gps.altitude = gps_data.altitude; +			gps_log.u.gps.altitude_low = gps_data.altitude_low; +			gps_log.u.gps.altitude_high = gps_data.altitude_high;  			ao_log_metrum(&gps_log);  			gps_log.type = AO_LOG_GPS_TIME; @@ -55,6 +56,7 @@ ao_gps_report_metrum(void)  			gps_log.u.gps_time.year = gps_data.year;  			gps_log.u.gps_time.month = gps_data.month;  			gps_log.u.gps_time.day = gps_data.day; +			gps_log.u.gps_time.pdop = gps_data.pdop;  			ao_log_metrum(&gps_log);  		} diff --git a/src/kernel/ao_gps_show.c b/src/kernel/ao_gps_show.c index 3a05e35a..e45cd795 100644 --- a/src/kernel/ao_gps_show.c +++ b/src/kernel/ao_gps_show.c @@ -19,6 +19,8 @@  #include <ao.h>  #endif +#include <ao_data.h> +  void  ao_gps_show(void) __reentrant  { @@ -27,7 +29,11 @@ ao_gps_show(void) __reentrant  	printf ("Date: %02d/%02d/%02d\n", ao_gps_data.year, ao_gps_data.month, ao_gps_data.day);  	printf ("Time: %02d:%02d:%02d\n", ao_gps_data.hour, ao_gps_data.minute, ao_gps_data.second);  	printf ("Lat/Lon: %ld %ld\n", (long) ao_gps_data.latitude, (long) ao_gps_data.longitude); -	printf ("Alt: %d\n", ao_gps_data.altitude); +#if HAS_WIDE_GPS +	printf ("Alt: %ld\n", (long) AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data)); +#else +	printf ("Alt: %d\n", AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data)); +#endif  	printf ("Flags: 0x%x\n", ao_gps_data.flags);  	printf ("Sats: %d", ao_gps_tracking_data.channels);  	for (i = 0; i < ao_gps_tracking_data.channels; i++) diff --git a/src/kernel/ao_kalman.c b/src/kernel/ao_kalman.c index 9aea1f14..7b0f8145 100644 --- a/src/kernel/ao_kalman.c +++ b/src/kernel/ao_kalman.c @@ -23,32 +23,31 @@  #include "ao_sample.h"  #include "ao_kalman.h" +static __pdata ao_k_t		ao_k_height; +static __pdata ao_k_t		ao_k_speed; +static __pdata ao_k_t		ao_k_accel; -static __pdata int32_t		ao_k_height; -static __pdata int32_t		ao_k_speed; -static __pdata int32_t		ao_k_accel; +#define AO_K_STEP_100		to_fix_v(0.01) +#define AO_K_STEP_2_2_100	to_fix_v(0.00005) -#define AO_K_STEP_100		to_fix16(0.01) -#define AO_K_STEP_2_2_100	to_fix16(0.00005) +#define AO_K_STEP_10		to_fix_v(0.1) +#define AO_K_STEP_2_2_10	to_fix_v(0.005) -#define AO_K_STEP_10		to_fix16(0.1) -#define AO_K_STEP_2_2_10	to_fix16(0.005) +#define AO_K_STEP_1		to_fix_v(1) +#define AO_K_STEP_2_2_1		to_fix_v(0.5) -#define AO_K_STEP_1		to_fix16(1) -#define AO_K_STEP_2_2_1		to_fix16(0.5) +__pdata ao_v_t			ao_height; +__pdata ao_v_t			ao_speed; +__pdata ao_v_t			ao_accel; +__xdata ao_v_t			ao_max_height; +static __pdata ao_k_t		ao_avg_height_scaled; +__xdata ao_v_t			ao_avg_height; -__pdata int16_t			ao_height; -__pdata int16_t			ao_speed; -__pdata int16_t			ao_accel; -__xdata int16_t			ao_max_height; -static __pdata int32_t		ao_avg_height_scaled; -__xdata int16_t			ao_avg_height; - -__pdata int16_t			ao_error_h; -__pdata int16_t			ao_error_h_sq_avg; +__pdata ao_v_t			ao_error_h; +__pdata ao_v_t			ao_error_h_sq_avg;  #if HAS_ACCEL -__pdata int16_t			ao_error_a; +__pdata ao_v_t			ao_error_a;  #endif  static void @@ -56,40 +55,40 @@ ao_kalman_predict(void)  {  #ifdef AO_FLIGHT_TEST  	if (ao_sample_tick - ao_sample_prev_tick > 50) { -		ao_k_height += ((int32_t) ao_speed * AO_K_STEP_1 + -				(int32_t) ao_accel * AO_K_STEP_2_2_1) >> 4; -		ao_k_speed += (int32_t) ao_accel * AO_K_STEP_1; +		ao_k_height += ((ao_k_t) ao_speed * AO_K_STEP_1 + +				(ao_k_t) ao_accel * AO_K_STEP_2_2_1) >> 4; +		ao_k_speed += (ao_k_t) ao_accel * AO_K_STEP_1;  		return;  	}  	if (ao_sample_tick - ao_sample_prev_tick > 5) { -		ao_k_height += ((int32_t) ao_speed * AO_K_STEP_10 + -				(int32_t) ao_accel * AO_K_STEP_2_2_10) >> 4; -		ao_k_speed += (int32_t) ao_accel * AO_K_STEP_10; +		ao_k_height += ((ao_k_t) ao_speed * AO_K_STEP_10 + +				(ao_k_t) ao_accel * AO_K_STEP_2_2_10) >> 4; +		ao_k_speed += (ao_k_t) ao_accel * AO_K_STEP_10;  		return;  	}  	if (ao_flight_debug) {  		printf ("predict speed %g + (%g * %g) = %g\n",  			ao_k_speed / (65536.0 * 16.0), ao_accel / 16.0, AO_K_STEP_100 / 65536.0, -			(ao_k_speed + (int32_t) ao_accel * AO_K_STEP_100) / (65536.0 * 16.0)); +			(ao_k_speed + (ao_k_t) ao_accel * AO_K_STEP_100) / (65536.0 * 16.0));  	}  #endif -	ao_k_height += ((int32_t) ao_speed * AO_K_STEP_100 + -			(int32_t) ao_accel * AO_K_STEP_2_2_100) >> 4; -	ao_k_speed += (int32_t) ao_accel * AO_K_STEP_100; +	ao_k_height += ((ao_k_t) ao_speed * AO_K_STEP_100 + +			(ao_k_t) ao_accel * AO_K_STEP_2_2_100) >> 4; +	ao_k_speed += (ao_k_t) ao_accel * AO_K_STEP_100;  }  static void  ao_kalman_err_height(void)  { -	int16_t	e; -	int16_t height_distrust; +	ao_v_t	e; +	ao_v_t height_distrust;  #if HAS_ACCEL -	int16_t	speed_distrust; +	ao_v_t	speed_distrust;  #endif -	ao_error_h = ao_sample_height - (int16_t) (ao_k_height >> 16); +	ao_error_h = ao_sample_height - (ao_v_t) (ao_k_height >> 16);  	e = ao_error_h;  	if (e < 0) @@ -123,7 +122,7 @@ ao_kalman_err_height(void)  #endif  		if (height_distrust > 0x100)  			height_distrust = 0x100; -		ao_error_h = (int16_t) (((int32_t) ao_error_h * (0x100 - height_distrust)) >> 8); +		ao_error_h = (ao_v_t) (((ao_k_t) ao_error_h * (0x100 - height_distrust)) >> 8);  #ifdef AO_FLIGHT_TEST  		if (ao_flight_debug) {  			printf("over height %g over speed %g distrust: %g height: error %d -> %d\n", @@ -142,21 +141,21 @@ ao_kalman_correct_baro(void)  	ao_kalman_err_height();  #ifdef AO_FLIGHT_TEST  	if (ao_sample_tick - ao_sample_prev_tick > 50) { -		ao_k_height += (int32_t) AO_BARO_K0_1 * ao_error_h; -		ao_k_speed  += (int32_t) AO_BARO_K1_1 * ao_error_h; -		ao_k_accel  += (int32_t) AO_BARO_K2_1 * ao_error_h; +		ao_k_height += (ao_k_t) AO_BARO_K0_1 * ao_error_h; +		ao_k_speed  += (ao_k_t) AO_BARO_K1_1 * ao_error_h; +		ao_k_accel  += (ao_k_t) AO_BARO_K2_1 * ao_error_h;  		return;  	}  	if (ao_sample_tick - ao_sample_prev_tick > 5) { -		ao_k_height += (int32_t) AO_BARO_K0_10 * ao_error_h; -		ao_k_speed  += (int32_t) AO_BARO_K1_10 * ao_error_h; -		ao_k_accel  += (int32_t) AO_BARO_K2_10 * ao_error_h; +		ao_k_height += (ao_k_t) AO_BARO_K0_10 * ao_error_h; +		ao_k_speed  += (ao_k_t) AO_BARO_K1_10 * ao_error_h; +		ao_k_accel  += (ao_k_t) AO_BARO_K2_10 * ao_error_h;  		return;  	}  #endif -	ao_k_height += (int32_t) AO_BARO_K0_100 * ao_error_h; -	ao_k_speed  += (int32_t) AO_BARO_K1_100 * ao_error_h; -	ao_k_accel  += (int32_t) AO_BARO_K2_100 * ao_error_h; +	ao_k_height += (ao_k_t) AO_BARO_K0_100 * ao_error_h; +	ao_k_speed  += (ao_k_t) AO_BARO_K1_100 * ao_error_h; +	ao_k_accel  += (ao_k_t) AO_BARO_K2_100 * ao_error_h;  }  #if HAS_ACCEL @@ -164,7 +163,7 @@ ao_kalman_correct_baro(void)  static void  ao_kalman_err_accel(void)  { -	int32_t	accel; +	ao_k_t	accel;  	accel = (ao_config.accel_plus_g - ao_sample_accel) * ao_accel_scale; @@ -187,18 +186,18 @@ ao_kalman_correct_both(void)  				(double) ao_error_h, AO_BOTH_K10_1 / 65536.0,  				(double) ao_error_a, AO_BOTH_K11_1 / 65536.0,  				(ao_k_speed + -				 (int32_t) AO_BOTH_K10_1 * ao_error_h + -				 (int32_t) AO_BOTH_K11_1 * ao_error_a) / (65536.0 * 16.0)); +				 (ao_k_t) AO_BOTH_K10_1 * ao_error_h + +				 (ao_k_t) AO_BOTH_K11_1 * ao_error_a) / (65536.0 * 16.0));  		}  		ao_k_height += -			(int32_t) AO_BOTH_K00_1 * ao_error_h + -			(int32_t) AO_BOTH_K01_1 * ao_error_a; +			(ao_k_t) AO_BOTH_K00_1 * ao_error_h + +			(ao_k_t) AO_BOTH_K01_1 * ao_error_a;  		ao_k_speed += -			(int32_t) AO_BOTH_K10_1 * ao_error_h + -			(int32_t) AO_BOTH_K11_1 * ao_error_a; +			(ao_k_t) AO_BOTH_K10_1 * ao_error_h + +			(ao_k_t) AO_BOTH_K11_1 * ao_error_a;  		ao_k_accel += -			(int32_t) AO_BOTH_K20_1 * ao_error_h + -			(int32_t) AO_BOTH_K21_1 * ao_error_a; +			(ao_k_t) AO_BOTH_K20_1 * ao_error_h + +			(ao_k_t) AO_BOTH_K21_1 * ao_error_a;  		return;  	}  	if (ao_sample_tick - ao_sample_prev_tick > 5) { @@ -208,18 +207,18 @@ ao_kalman_correct_both(void)  				(double) ao_error_h, AO_BOTH_K10_10 / 65536.0,  				(double) ao_error_a, AO_BOTH_K11_10 / 65536.0,  				(ao_k_speed + -				 (int32_t) AO_BOTH_K10_10 * ao_error_h + -				 (int32_t) AO_BOTH_K11_10 * ao_error_a) / (65536.0 * 16.0)); +				 (ao_k_t) AO_BOTH_K10_10 * ao_error_h + +				 (ao_k_t) AO_BOTH_K11_10 * ao_error_a) / (65536.0 * 16.0));  		}  		ao_k_height += -			(int32_t) AO_BOTH_K00_10 * ao_error_h + -			(int32_t) AO_BOTH_K01_10 * ao_error_a; +			(ao_k_t) AO_BOTH_K00_10 * ao_error_h + +			(ao_k_t) AO_BOTH_K01_10 * ao_error_a;  		ao_k_speed += -			(int32_t) AO_BOTH_K10_10 * ao_error_h + -			(int32_t) AO_BOTH_K11_10 * ao_error_a; +			(ao_k_t) AO_BOTH_K10_10 * ao_error_h + +			(ao_k_t) AO_BOTH_K11_10 * ao_error_a;  		ao_k_accel += -			(int32_t) AO_BOTH_K20_10 * ao_error_h + -			(int32_t) AO_BOTH_K21_10 * ao_error_a; +			(ao_k_t) AO_BOTH_K20_10 * ao_error_h + +			(ao_k_t) AO_BOTH_K21_10 * ao_error_a;  		return;  	}  	if (ao_flight_debug) { @@ -228,19 +227,19 @@ ao_kalman_correct_both(void)  			(double) ao_error_h, AO_BOTH_K10_100 / 65536.0,  			(double) ao_error_a, AO_BOTH_K11_100 / 65536.0,  			(ao_k_speed + -			 (int32_t) AO_BOTH_K10_100 * ao_error_h + -			 (int32_t) AO_BOTH_K11_100 * ao_error_a) / (65536.0 * 16.0)); +			 (ao_k_t) AO_BOTH_K10_100 * ao_error_h + +			 (ao_k_t) AO_BOTH_K11_100 * ao_error_a) / (65536.0 * 16.0));  	}  #endif  	ao_k_height += -		(int32_t) AO_BOTH_K00_100 * ao_error_h + -		(int32_t) AO_BOTH_K01_100 * ao_error_a; +		(ao_k_t) AO_BOTH_K00_100 * ao_error_h + +		(ao_k_t) AO_BOTH_K01_100 * ao_error_a;  	ao_k_speed += -		(int32_t) AO_BOTH_K10_100 * ao_error_h + -		(int32_t) AO_BOTH_K11_100 * ao_error_a; +		(ao_k_t) AO_BOTH_K10_100 * ao_error_h + +		(ao_k_t) AO_BOTH_K11_100 * ao_error_a;  	ao_k_accel += -		(int32_t) AO_BOTH_K20_100 * ao_error_h + -		(int32_t) AO_BOTH_K21_100 * ao_error_a; +		(ao_k_t) AO_BOTH_K20_100 * ao_error_h + +		(ao_k_t) AO_BOTH_K21_100 * ao_error_a;  }  #else @@ -251,14 +250,14 @@ ao_kalman_correct_accel(void)  	ao_kalman_err_accel();  	if (ao_sample_tick - ao_sample_prev_tick > 5) { -		ao_k_height +=(int32_t) AO_ACCEL_K0_10 * ao_error_a; -		ao_k_speed  += (int32_t) AO_ACCEL_K1_10 * ao_error_a; -		ao_k_accel  += (int32_t) AO_ACCEL_K2_10 * ao_error_a; +		ao_k_height +=(ao_k_t) AO_ACCEL_K0_10 * ao_error_a; +		ao_k_speed  += (ao_k_t) AO_ACCEL_K1_10 * ao_error_a; +		ao_k_accel  += (ao_k_t) AO_ACCEL_K2_10 * ao_error_a;  		return;  	} -	ao_k_height += (int32_t) AO_ACCEL_K0_100 * ao_error_a; -	ao_k_speed  += (int32_t) AO_ACCEL_K1_100 * ao_error_a; -	ao_k_accel  += (int32_t) AO_ACCEL_K2_100 * ao_error_a; +	ao_k_height += (ao_k_t) AO_ACCEL_K0_100 * ao_error_a; +	ao_k_speed  += (ao_k_t) AO_ACCEL_K1_100 * ao_error_a; +	ao_k_accel  += (ao_k_t) AO_ACCEL_K2_100 * ao_error_a;  }  #endif /* else FORCE_ACCEL */ diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index 33cda3eb..da20e067 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -176,8 +176,8 @@ struct ao_log_record {  		int32_t		gps_latitude;  		int32_t		gps_longitude;  		struct { -			int16_t		altitude; -			uint16_t	unused; +			uint16_t	altitude_low; +			int16_t		altitude_high;  		} gps_altitude;  		struct {  			uint16_t	svid; @@ -246,7 +246,7 @@ struct ao_log_mega {  		struct {  			int32_t		latitude;	/* 4 */  			int32_t		longitude;	/* 8 */ -			int16_t		altitude;	/* 12 */ +			uint16_t	altitude_low;	/* 12 */  			uint8_t		hour;		/* 14 */  			uint8_t		minute;		/* 15 */  			uint8_t		second;		/* 16 */ @@ -261,7 +261,8 @@ struct ao_log_mega {  			uint8_t		hdop;		/* 27 */  			uint8_t		vdop;		/* 28 */  			uint8_t		mode;		/* 29 */ -		} gps;	/* 30 */ +			int16_t		altitude_high;	/* 30 */ +		} gps;	/* 32 */  		/* AO_LOG_GPS_SAT */  		struct {  			uint16_t	channels;	/* 4 */ @@ -273,6 +274,11 @@ struct ao_log_mega {  	} u;  }; +#define AO_LOG_MEGA_GPS_ALTITUDE(l)	((int32_t) ((l)->u.gps.altitude_high << 16) | ((l)->u.gps.altitude_low)) +#define AO_LOG_MEGA_SET_GPS_ALTITUDE(l,a)	(((l)->u.gps.mode |= AO_GPS_MODE_ALTITUDE_24), \ +						 ((l)->u.gps.altitude_high = (a) >> 16), \ +						 (l)->u.gps.altitude_low = (a)) +  struct ao_log_metrum {  	char			type;			/* 0 */  	uint8_t			csum;			/* 1 */ @@ -306,8 +312,9 @@ struct ao_log_metrum {  		struct {  			int32_t		latitude;	/* 4 */  			int32_t		longitude;	/* 8 */ -			int16_t		altitude;	/* 12 */ -		} gps;		/* 14 */ +			uint16_t	altitude_low;	/* 12 */ +			int16_t		altitude_high;	/* 14 */ +		} gps;		/* 16 */  		/* AO_LOG_GPS_TIME */  		struct {  			uint8_t		hour;		/* 4 */ @@ -317,7 +324,7 @@ struct ao_log_metrum {  			uint8_t		year;		/* 8 */  			uint8_t		month;		/* 9 */  			uint8_t		day;		/* 10 */ -			uint8_t		pad;		/* 11 */ +			uint8_t		pdop;		/* 11 */  		} gps_time;	/* 12 */  		/* AO_LOG_GPS_SAT (up to three packets) */  		struct { @@ -381,7 +388,7 @@ struct ao_log_gps {  		struct {  			int32_t		latitude;	/* 4 */  			int32_t		longitude;	/* 8 */ -			int16_t		altitude;	/* 12 */ +			uint16_t	altitude_low;	/* 12 */  			uint8_t		hour;		/* 14 */  			uint8_t		minute;		/* 15 */  			uint8_t		second;		/* 16 */ @@ -396,7 +403,7 @@ struct ao_log_gps {  			uint8_t		hdop;		/* 27 */  			uint8_t		vdop;		/* 28 */  			uint8_t		mode;		/* 29 */ -			uint8_t		state;		/* 30 */ +			int16_t		altitude_high;	/* 30 */  		} gps;	/* 31 */  		/* AO_LOG_GPS_SAT */  		struct { diff --git a/src/kernel/ao_log_gps.c b/src/kernel/ao_log_gps.c index 3b728c25..a5a6358b 100644 --- a/src/kernel/ao_log_gps.c +++ b/src/kernel/ao_log_gps.c @@ -75,7 +75,8 @@ ao_log_gps_data(uint16_t tick, struct ao_telemetry_location *gps_data)  	log.type = AO_LOG_GPS_TIME;  	log.u.gps.latitude = gps_data->latitude;  	log.u.gps.longitude = gps_data->longitude; -	log.u.gps.altitude = gps_data->altitude; +	log.u.gps.altitude_low = gps_data->altitude_low; +	log.u.gps.altitude_high = gps_data->altitude_high;  	log.u.gps.hour = gps_data->hour;  	log.u.gps.minute = gps_data->minute; diff --git a/src/kernel/ao_log_gps.h b/src/kernel/ao_log_gps.h index 5851f4d1..a9e8c831 100644 --- a/src/kernel/ao_log_gps.h +++ b/src/kernel/ao_log_gps.h @@ -21,9 +21,6 @@  #ifndef _AO_LOG_GPS_H_  #define _AO_LOG_GPS_H_ -uint8_t -ao_log_gps_should_log(int32_t lat, int32_t lon, int16_t alt); -  void  ao_log_gps_flight(void); diff --git a/src/kernel/ao_microkalman.c b/src/kernel/ao_microkalman.c index 0684ea2b..75a29cc4 100644 --- a/src/kernel/ao_microkalman.c +++ b/src/kernel/ao_microkalman.c @@ -22,19 +22,19 @@  #define FIX_BITS	16 -#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) -#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) +#define to_fix_v(x) ((int16_t) ((x) * 65536.0 + 0.5)) +#define to_fix_k(x) ((int32_t) ((x) * 65536.0 + 0.5))  #define from_fix8(x)	((x) >> 8)  #define from_fix(x)	((x) >> 16) -#define fix8_to_fix16(x)	((x) << 8) +#define fix8_to_fix_v(x)	((x) << 8)  #define fix16_to_fix8(x)	((x) >> 8)  #include <ao_kalman.h>  /* Basic time step (96ms) */ -#define AO_MK_STEP	to_fix16(0.096) +#define AO_MK_STEP	to_fix_v(0.096)  /* step ** 2 / 2 */ -#define AO_MK_STEP_2_2	to_fix16(0.004608) +#define AO_MK_STEP_2_2	to_fix_v(0.004608)  uint32_t	ao_k_pa;		/* 24.8 fixed point */  int32_t		ao_k_pa_speed;		/* 16.16 fixed point */ @@ -49,7 +49,7 @@ ao_microkalman_init(void)  {  	ao_pa = pa;  	ao_k_pa = pa << 8; -}	 +}  void  ao_microkalman_predict(void) diff --git a/src/kernel/ao_sample.c b/src/kernel/ao_sample.c index 34658951..29bf2bf6 100644 --- a/src/kernel/ao_sample.c +++ b/src/kernel/ao_sample.c @@ -245,7 +245,7 @@ ao_sample_preflight(void)  	} else {  #if HAS_ACCEL  		ao_accel_2g = ao_config.accel_minus_g - ao_config.accel_plus_g; -		ao_accel_scale = to_fix32(GRAVITY * 2 * 16) / ao_accel_2g; +		ao_accel_scale = to_fix_32(GRAVITY * 2 * 16) / ao_accel_2g;  #endif  		ao_sample_preflight_set();  		ao_preflight = FALSE; diff --git a/src/kernel/ao_sample.h b/src/kernel/ao_sample.h index 16d4c507..2ec998bd 100644 --- a/src/kernel/ao_sample.h +++ b/src/kernel/ao_sample.h @@ -24,6 +24,24 @@   * ao_sample.c   */ +#ifndef AO_VALUE_32 +#define AO_VALUE_32	1 +#endif + +#if AO_VALUE_32 +/* + * For 32-bit computed values, use 64-bit intermediates. + */ +typedef int64_t			ao_k_t; +typedef int32_t			ao_v_t; +#else +/* + * For 16-bit computed values, use 32-bit intermediates. + */ +typedef int32_t			ao_k_t; +typedef int16_t			ao_v_t; +#endif +  /*   * Barometer calibration   * @@ -87,9 +105,9 @@   * 2047m/s² (over 200g)   */ -#define AO_M_TO_HEIGHT(m)	((int16_t) (m)) -#define AO_MS_TO_SPEED(ms)	((int16_t) ((ms) * 16)) -#define AO_MSS_TO_ACCEL(mss)	((int16_t) ((mss) * 16)) +#define AO_M_TO_HEIGHT(m)	((ao_v_t) (m)) +#define AO_MS_TO_SPEED(ms)	((ao_v_t) ((ms) * 16)) +#define AO_MSS_TO_ACCEL(mss)	((ao_v_t) ((mss) * 16))  extern __pdata uint16_t	ao_sample_tick;		/* time of last data */  extern __data uint8_t	ao_sample_adc;		/* Ring position of last processed sample */ @@ -134,21 +152,33 @@ uint8_t ao_sample(void);   * ao_kalman.c   */ -#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) -#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) +#define to_fix_16(x) ((int16_t) ((x) * 65536.0 + 0.5)) +#define to_fix_32(x) ((int32_t) ((x) * 65536.0 + 0.5)) +#define to_fix_64(x) ((int64_t) ((x) * 65536.0 + 0.5)) + +#ifdef AO_VALUE_32 +#if AO_VALUE_32 +#define to_fix_v(x)	to_fix_32(x) +#define to_fix_k(x)	to_fix_64(x) +#else +#define to_fix_v(x)	to_fix_16(x) +#define to_fix_k(x)	to_fix_32(x) +#endif +  #define from_fix(x)	((x) >> 16) -extern __pdata int16_t			ao_height;	/* meters */ -extern __pdata int16_t			ao_speed;	/* m/s * 16 */ -extern __pdata int16_t			ao_accel;	/* m/s² * 16 */ -extern __xdata int16_t			ao_max_height;	/* max of ao_height */ -extern __xdata int16_t			ao_avg_height;	/* running average of height */ +extern __pdata ao_v_t			ao_height;	/* meters */ +extern __pdata ao_v_t			ao_speed;	/* m/s * 16 */ +extern __pdata ao_v_t			ao_accel;	/* m/s² * 16 */ +extern __xdata ao_v_t			ao_max_height;	/* max of ao_height */ +extern __xdata ao_v_t			ao_avg_height;	/* running average of height */ -extern __pdata int16_t			ao_error_h; -extern __pdata int16_t			ao_error_h_sq_avg; +extern __pdata ao_v_t			ao_error_h; +extern __pdata ao_v_t			ao_error_h_sq_avg;  #if HAS_ACCEL -extern __pdata int16_t			ao_error_a; +extern __pdata ao_v_t			ao_error_a; +#endif  #endif  void ao_kalman(void); diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index d321c8ff..56bd715e 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -344,7 +344,7 @@ ao_send_location(void)  		ao_mutex_get(&ao_gps_mutex);  		ao_xmemcpy(&telemetry.location.flags,  		       &ao_gps_data.flags, -		       26); +		       27);  		telemetry.location.tick = ao_gps_tick;  		ao_mutex_put(&ao_gps_mutex);  		ao_radio_send(&telemetry, sizeof (telemetry)); diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h index be7d0340..83d432cf 100644 --- a/src/kernel/ao_telemetry.h +++ b/src/kernel/ao_telemetry.h @@ -86,12 +86,9 @@ struct ao_telemetry_configuration {  #define AO_TELEMETRY_LOCATION		0x05 -#define AO_GPS_MODE_NOT_VALID		'N' -#define AO_GPS_MODE_AUTONOMOUS		'A' -#define AO_GPS_MODE_DIFFERENTIAL	'D' -#define AO_GPS_MODE_ESTIMATED		'E' -#define AO_GPS_MODE_MANUAL		'M' -#define AO_GPS_MODE_SIMULATED		'S' +/* Mode bits */ + +#define AO_GPS_MODE_ALTITUDE_24		(1 << 0)	/* reports 24-bits of altitude */  struct ao_telemetry_location {  	uint16_t	serial;		/*  0 */ @@ -99,7 +96,7 @@ struct ao_telemetry_location {  	uint8_t		type;		/*  4 */  	uint8_t         flags;		/*  5 Number of sats and other flags */ -	int16_t         altitude;	/*  6 GPS reported altitude (m) */ +	uint16_t        altitude_low;	/*  6 GPS reported altitude (m) */  	int32_t         latitude;	/*  8 latitude (degrees * 10⁷) */  	int32_t         longitude;	/* 12 longitude (degrees * 10⁷) */  	uint8_t         year;		/* 16 (- 2000) */ @@ -115,10 +112,31 @@ struct ao_telemetry_location {  	uint16_t	ground_speed;	/* 26 cm/s */  	int16_t		climb_rate;	/* 28 cm/s */  	uint8_t		course;		/* 30 degrees / 2 */ -	uint8_t		unused;		/* 31 unused */ +	int8_t		altitude_high;	/* 31 high byte of altitude */  	/* 32 */  }; +#if HAS_GPS + +#ifndef HAS_WIDE_GPS +#define HAS_WIDE_GPS	1 +#endif + +#if HAS_WIDE_GPS +typedef int32_t		gps_alt_t; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) 	(((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->mode |= AO_GPS_MODE_ALTITUDE_24), \ +						 ((l)->altitude_high = (a) >> 16), \ +						 ((l)->altitude_low = (a))) +#else +typedef int16_t		gps_alt_t; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l)	((gps_alt_t) (l)->altitude_low) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a)	(((l)->mode = 0, \ +						  (l)->altitude_low = (a))) +#endif /* HAS_WIDE_GPS */ + +#endif /* HAS_GPS */ +  #define AO_TELEMETRY_SATELLITE		0x06  struct ao_telemetry_satellite_info { diff --git a/src/kernel/ao_tracker.c b/src/kernel/ao_tracker.c index 9febc7f0..d9434048 100644 --- a/src/kernel/ao_tracker.c +++ b/src/kernel/ao_tracker.c @@ -36,9 +36,9 @@ ao_usb_connected(void)  #endif  struct gps_position { -	int32_t	latitude; -	int32_t	longitude; -	int16_t	altitude; +	int32_t		latitude; +	int32_t		longitude; +	gps_alt_t	altitude;  };  #define GPS_RING	16 @@ -122,12 +122,13 @@ ao_tracker(void)  			{  				uint8_t	ring;  				uint8_t	moving = 0; +				gps_alt_t altitude = AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data);  				for (ring = ao_gps_ring_next(gps_head); ring != gps_head; ring = ao_gps_ring_next(ring)) {  					ground_distance = ao_distance(gps_data.latitude, gps_data.longitude,  								      gps_position[ring].latitude,  								      gps_position[ring].longitude); -					height = gps_position[ring].altitude - gps_data.altitude; +					height = gps_position[ring].altitude - altitude;  					if (height < 0)  						height = -height; @@ -153,7 +154,7 @@ ao_tracker(void)  					ao_log_gps_data(gps_tick, &gps_data);  					gps_position[gps_head].latitude = gps_data.latitude;  					gps_position[gps_head].longitude = gps_data.longitude; -					gps_position[gps_head].altitude = gps_data.altitude; +					gps_position[gps_head].altitude = altitude;  					gps_head = ao_gps_ring_next(gps_head);  					ao_mutex_put(&tracker_mutex);  				} @@ -203,7 +204,7 @@ ao_tracker_set_telem(void)  	printf ("log_started: %d\n", log_started);  	printf ("latitude: %ld\n", (long) gps_data.latitude);  	printf ("longitude: %ld\n", (long) gps_data.longitude); -	printf ("altitude: %d\n", gps_data.altitude); +	printf ("altitude: %ld\n", AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data));  	printf ("log_running: %d\n", ao_log_running);  	printf ("log_start_pos: %ld\n", (long) ao_log_start_pos);  	printf ("log_cur_pos: %ld\n", (long) ao_log_current_pos); diff --git a/src/product/Makefile.telemetrum b/src/product/Makefile.telemetrum index dbbf57d8..e9b144c0 100644 --- a/src/product/Makefile.telemetrum +++ b/src/product/Makefile.telemetrum @@ -24,6 +24,7 @@ INC = \  	altitude.h \  	ao_kalman.h \  	ao_product.h \ +	ao_telemetry.h \  	$(TM_INC)  CORE_SRC = \ diff --git a/src/telefire-v0.1/Makefile b/src/telefire-v0.1/Makefile index 25267268..99d29826 100644 --- a/src/telefire-v0.1/Makefile +++ b/src/telefire-v0.1/Makefile @@ -25,7 +25,6 @@ INC = \  CORE_SRC = \  	ao_cmd.c \  	ao_config.c \ -	ao_convert.c \  	ao_mutex.c \  	ao_panic.c \  	ao_stdio.c \ diff --git a/src/telefire-v0.2/Makefile b/src/telefire-v0.2/Makefile index ad5065c1..944543c5 100644 --- a/src/telefire-v0.2/Makefile +++ b/src/telefire-v0.2/Makefile @@ -25,7 +25,6 @@ INC = \  CORE_SRC = \  	ao_cmd.c \  	ao_config.c \ -	ao_convert.c \  	ao_mutex.c \  	ao_panic.c \  	ao_stdio.c \ diff --git a/src/telefire-v0.2/ao_pins.h b/src/telefire-v0.2/ao_pins.h index 9e6631ce..ef2d4822 100644 --- a/src/telefire-v0.2/ao_pins.h +++ b/src/telefire-v0.2/ao_pins.h @@ -19,6 +19,7 @@  #define _AO_PINS_H_  #define HAS_RADIO		1 +#define HAS_RADIO_RATE		1  #define HAS_TELEMETRY		0  #define HAS_FLIGHT		0 diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c index b3f5bb16..4b5f7a9b 100644 --- a/src/telelco-v0.2/ao_lco.c +++ b/src/telelco-v0.2/ao_lco.c @@ -258,7 +258,7 @@ ao_lco_search(void)  	for (box = 0; box < AO_PAD_MAX_BOXES; box++) {  		if ((box % 10) == 0)  			ao_lco_set_box(box); -		for (try = 0; try < 5; try++) { +		for (try = 0; try < 3; try++) {  			tick_offset = 0;  			r = ao_lco_query(box, &ao_pad_query, &tick_offset);  			PRINTD("box %d result %d\n", box, r); diff --git a/src/telelco-v0.2/ao_pins.h b/src/telelco-v0.2/ao_pins.h index a6fd4ff8..da790b14 100644 --- a/src/telelco-v0.2/ao_pins.h +++ b/src/telelco-v0.2/ao_pins.h @@ -48,6 +48,7 @@  #define HAS_USB			1  #define HAS_BEEP		1  #define HAS_RADIO		1 +#define HAS_RADIO_RATE		1  #define HAS_TELEMETRY		0  #define HAS_AES			1 diff --git a/src/telemega-v1.0/Makefile b/src/telemega-v1.0/Makefile index 46c768e4..4a1b3908 100644 --- a/src/telemega-v1.0/Makefile +++ b/src/telemega-v1.0/Makefile @@ -31,6 +31,7 @@ INC = \  	ao_mpu.h \  	stm32l.h \  	math.h \ +	ao_ms5607_convert.c \  	Makefile  # diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index 948310e5..ed911798 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -22,6 +22,7 @@  #define HAS_FLIGHT		1  #define HAS_USB			1 +#define AO_VALUE_32		0  #define HAS_USB_PULLUP	1  #define AO_USB_PULLUP_PORT	P1 diff --git a/src/teleterra-v0.2/ao_pins.h b/src/teleterra-v0.2/ao_pins.h index 60d627ad..472af534 100644 --- a/src/teleterra-v0.2/ao_pins.h +++ b/src/teleterra-v0.2/ao_pins.h @@ -72,6 +72,8 @@  	#define BATTERY_PIN		5  	#define HAS_TELEMETRY		0 + +	#define AO_VALUE_32		0  #endif  #if DBG_ON_P1 diff --git a/src/test/Makefile b/src/test/Makefile index 017f7f71..02e1d22b 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -1,6 +1,7 @@  vpath % ..:../kernel:../drivers:../util:../micropeak:../aes:../product  PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \ +	ao_flight_test_metrum \  	ao_gps_test ao_gps_test_skytraq ao_gps_test_ublox ao_convert_test ao_convert_pa_test ao_fec_test \  	ao_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test \  	ao_ms5607_convert_test ao_quaternion_test @@ -33,6 +34,9 @@ ao_flight_test_accel: ao_flight_test.c ao_host.h ao_flight.c  ao_sample.c ao_kal  ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS)  	cc -DTELEMEGA=1 $(CFLAGS) -o $@ $< -lm +ao_flight_test_metrum: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS) +	cc -DTELEMETRUM_V2=1 $(CFLAGS) -o $@ $< -lm +  ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h  	cc $(CFLAGS) -o $@ $< diff --git a/src/test/ao_aprs_test.c b/src/test/ao_aprs_test.c index 573b5cb2..ae505dea 100644 --- a/src/test/ao_aprs_test.c +++ b/src/test/ao_aprs_test.c @@ -21,6 +21,8 @@  #include <stdint.h>  #include <stdarg.h> +#define HAS_GPS	1 +  #include <ao_telemetry.h>  #define AO_GPS_NUM_SAT_MASK	(0xf << 0) @@ -100,14 +102,11 @@ audio_gap(int secs)  // This is where we go after reset.  int main(int argc, char **argv)  { -	int	e, x; -	int	a; -      audio_gap(1);      ao_gps_data.latitude = (45.0 + 28.25 / 60.0) * 10000000;      ao_gps_data.longitude = (-(122 + 44.2649 / 60.0)) * 10000000; -    ao_gps_data.altitude = 84; +    AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_data, 84);      ao_gps_data.flags = (AO_GPS_VALID|AO_GPS_RUNNING);      /* Transmit one packet */ diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 1ab22e5b..8b737ca1 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -34,15 +34,21 @@  #define ao_data_ring_next(n)	(((n) + 1) & (AO_DATA_RING - 1))  #define ao_data_ring_prev(n)	(((n) - 1) & (AO_DATA_RING - 1)) +#if 0  #define AO_M_TO_HEIGHT(m)	((int16_t) (m))  #define AO_MS_TO_SPEED(ms)	((int16_t) ((ms) * 16))  #define AO_MSS_TO_ACCEL(mss)	((int16_t) ((mss) * 16)) +#endif  #define AO_GPS_NEW_DATA		1  #define AO_GPS_NEW_TRACKING	2  int ao_gps_new; +#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) +#define TELEMETRUM_V1 1 +#endif +  #if TELEMEGA  #define AO_ADC_NUM_SENSE	6  #define HAS_MS5607		1 @@ -58,7 +64,25 @@ struct ao_adc {  	int16_t			v_pbatt;  	int16_t			temp;  }; -#else +#endif + +#if TELEMETRUM_V2 +#define AO_ADC_NUM_SENSE	2 +#define HAS_MS5607		1 +#define HAS_MMA655X		1 +#define HAS_BEEP		1 +#define AO_CONFIG_MAX_SIZE	1024 + +struct ao_adc { +	int16_t			sense_a; +	int16_t			sense_m; +	int16_t			v_batt; +	int16_t			temp; +}; +#endif + + +#if TELEMETRUM_V1  /*   * One set of samples read from the A/D converter   */ @@ -93,6 +117,7 @@ struct ao_adc {  #include <ao_data.h>  #include <ao_log.h>  #include <ao_telemetry.h> +#include <ao_sample.h>  #if TELEMEGA  int ao_gps_count; @@ -175,7 +200,7 @@ ao_gps_angle(void)  			ao_gps_static.latitude / 1e7,  			ao_gps_static.longitude / 1e7,  			&dist, &bearing); -	height = ao_gps_static.altitude - ao_gps_prev.altitude; +	height = AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_static) - AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_prev);  	angle = atan2(dist, height);  	return angle * 180/M_PI; @@ -186,17 +211,6 @@ ao_gps_angle(void)  #define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5))  #define from_fix(x)	((x) >> 16) -/* - * Above this height, the baro sensor doesn't work - */ -#define AO_BARO_SATURATE	13000 -#define AO_MIN_BARO_VALUE	ao_altitude_to_pres(AO_BARO_SATURATE) - -/* - * Above this speed, baro measurements are unreliable - */ -#define AO_MAX_BARO_SPEED	200 -  #define ACCEL_NOSE_UP	(ao_accel_2g >> 2)  extern enum ao_flight_state ao_flight_state; @@ -234,7 +248,7 @@ double	main_time;  int	tick_offset; -static int32_t	ao_k_height; +static ao_k_t	ao_k_height;  int16_t  ao_time(void) @@ -306,7 +320,7 @@ struct ao_cmds {  #define ao_xmemcmp(d,s,c) memcmp(d,s,c)  #define AO_NEED_ALTITUDE_TO_PRES 1 -#if TELEMEGA +#if TELEMEGA || TELEMETRUM_V2  #include "ao_convert_pa.c"  #include <ao_ms5607.h>  struct ao_ms5607_prom	ao_ms5607_prom; @@ -456,7 +470,7 @@ ao_insert(void)  #else  		double	accel = 0.0;  #endif -#if TELEMEGA +#if TELEMEGA || TELEMETRUM_V2  		double	height;  		ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked); @@ -551,6 +565,7 @@ ao_insert(void)  				mag_azel.el,  				mag_azel.az);  #endif +#if 0  			printf ("%7.2f state %-8.8s height %8.4f tilt %4d rot %4d dist %12.2f gps_tilt %4d gps_sats %2d\n",  				time,  				ao_state_names[ao_flight_state], @@ -560,6 +575,7 @@ ao_insert(void)  				(int) floor (ao_gps_angle() + 0.5),  				(ao_gps_static.flags & 0xf) * 10); +#endif  #if 0  			printf ("\t\tstate %-8.8s ground az: %4d el %4d mag az %4d el %4d rot az %4d el %4d el_diff %4d az_diff %4d angle %4d tilt %4d ground %8.5f %8.5f %8.5f cur %8.5f %8.5f %8.5f rot %8.5f %8.5f %8.5f\n",  				ao_state_names[ao_flight_state], @@ -582,9 +598,9 @@ ao_insert(void)  #endif  #endif -#if 0 +#if 1  			printf("%7.2f height %8.2f accel %8.3f " -#if TELEMEGA +#if TELEMEGA && 0  			       "angle %5d "  			       "accel_x %8.3f accel_y %8.3f accel_z %8.3f gyro_x %8.3f gyro_y %8.3f gyro_z %8.3f mag_x %8d mag_y %8d, mag_z %8d mag_angle %4d "  #endif @@ -592,7 +608,7 @@ ao_insert(void)  			       time,  			       height,  			       accel, -#if TELEMEGA +#if TELEMEGA && 0  			       ao_sample_orient,  			       ao_mpu6000_accel(ao_data_static.mpu6000.accel_x), @@ -675,7 +691,8 @@ ao_sleep(void *wchan)  			{  #if TELEMEGA  				ao_data_static.mpu6000 = ao_ground_mpu6000; -#else +#endif +#if TELEMETRUM_V1  				ao_data_static.adc.accel = ao_flight_ground_accel;  #endif  				ao_insert(); @@ -756,7 +773,10 @@ ao_sleep(void *wchan)  					ao_gps_static.tick = tick;  					ao_gps_static.latitude = int32(bytes, 0);  					ao_gps_static.longitude = int32(bytes, 4); -					ao_gps_static.altitude = int32(bytes, 8); +					{ +						int32_t	altitude = int32(bytes, 8); +						AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_static, altitude); +					}  					ao_gps_static.flags = bytes[13];  					if (!ao_gps_count)  						ao_gps_first = ao_gps_static; @@ -801,7 +821,59 @@ ao_sleep(void *wchan)  					}  				}  			} -#else +#endif +#if TELEMETRUM_V2 +			if (log_format == AO_LOG_FORMAT_TELEMETRUM && nword == 14 && strlen(words[0]) == 1) { +				int	i; +				struct ao_ms5607_value	value; + +				type = words[0][0]; +				tick = strtoul(words[1], NULL, 16); +//				printf ("%c %04x", type, tick); +				for (i = 2; i < nword; i++) { +					bytes[i - 2] = strtoul(words[i], NULL, 16); +//					printf(" %02x", bytes[i-2]); +				} +//				printf ("\n"); +				switch (type) { +				case 'F': +					ao_flight_ground_accel = int16(bytes, 2); +					ao_flight_started = 1; +					ao_ground_pres = int32(bytes, 4); +					ao_ground_height = ao_pa_to_altitude(ao_ground_pres); +					break; +				case 'A': +					ao_data_static.tick = tick; +					ao_data_static.ms5607_raw.pres = int32(bytes, 0); +					ao_data_static.ms5607_raw.temp = int32(bytes, 4); +					ao_ms5607_convert(&ao_data_static.ms5607_raw, &value); +					ao_data_static.mma655x = int16(bytes, 8); +					ao_records_read++; +					ao_insert(); +					return; +				} +				continue; +			} else if (nword == 3 && strcmp(words[0], "ms5607") == 0) { +				if (strcmp(words[1], "reserved:") == 0) +					ao_ms5607_prom.reserved = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "sens:") == 0) +					ao_ms5607_prom.sens = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "off:") == 0) +					ao_ms5607_prom.off = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "tcs:") == 0) +					ao_ms5607_prom.tcs = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "tco:") == 0) +					ao_ms5607_prom.tco = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "tref:") == 0) +					ao_ms5607_prom.tref = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "tempsens:") == 0) +					ao_ms5607_prom.tempsens = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "crc:") == 0) +					ao_ms5607_prom.crc = strtoul(words[2], NULL, 10); +				continue; +			} +#endif +#if TELEMETRUM_V1  			if (nword == 4 && log_format != AO_LOG_FORMAT_TELEMEGA) {  				type = words[0][0];  				tick = strtoul(words[1], NULL, 16); @@ -926,7 +998,7 @@ ao_sleep(void *wchan)  			if (type != 'F' && !ao_flight_started)  				continue; -#if TELEMEGA +#if TELEMEGA || TELEMETRUM_V2  			(void) a;  			(void) b;  #else @@ -947,8 +1019,6 @@ ao_sleep(void *wchan)  				ao_data_static.tick = tick;  				ao_data_static.adc.accel = a;  				ao_data_static.adc.pres_real = b; -				if (b < AO_MIN_BARO_VALUE) -					b = AO_MIN_BARO_VALUE;  				ao_data_static.adc.pres = b;  				ao_records_read++;  				ao_insert(); diff --git a/src/test/ao_gps_test.c b/src/test/ao_gps_test.c index e799ab0f..543bbcc3 100644 --- a/src/test/ao_gps_test.c +++ b/src/test/ao_gps_test.c @@ -53,6 +53,9 @@ struct ao_gps_orig {  	uint16_t		v_error;	/* m */  }; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) 	((l)->altitude) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) ((l)->altitude = (a)) +  #define SIRF_SAT_STATE_ACQUIRED			(1 << 0)  #define SIRF_SAT_STATE_CARRIER_PHASE_VALID	(1 << 1)  #define SIRF_SAT_BIT_SYNC_COMPLETE		(1 << 2) @@ -433,7 +436,7 @@ ao_dump_state(void *wchan)  	if (wchan != &ao_gps_new)  		return; -	 +  	if (ao_gps_new & AO_GPS_NEW_DATA) {  		ao_gps_print(&ao_gps_data);  		putchar('\n'); diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c index 1b590d5e..5eb7118d 100644 --- a/src/test/ao_gps_test_skytraq.c +++ b/src/test/ao_gps_test_skytraq.c @@ -16,6 +16,7 @@   */  #define AO_GPS_TEST +#define HAS_GPS 1  #include "ao_host.h"  #include <termios.h>  #include <errno.h> @@ -53,6 +54,9 @@ struct ao_gps_orig {  	uint16_t		v_error;	/* m */  }; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) 	((l)->altitude) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) ((l)->altitude = (a)) +  #define SIRF_SAT_STATE_ACQUIRED			(1 << 0)  #define SIRF_SAT_STATE_CARRIER_PHASE_VALID	(1 << 1)  #define SIRF_SAT_BIT_SYNC_COMPLETE		(1 << 2) diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index 4eb4b837..5ea205d6 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -16,6 +16,7 @@   */  #define AO_GPS_TEST +#define HAS_GPS	1  #include "ao_host.h"  #include <termios.h>  #include <errno.h> @@ -44,7 +45,7 @@ struct ao_telemetry_location {  	uint8_t			flags;  	int32_t			latitude;	/* degrees * 10⁷ */  	int32_t			longitude;	/* degrees * 10⁷ */ -	int16_t			altitude;	/* m */ +	int16_t			altitude_low;	/* m */  	uint16_t		ground_speed;	/* cm/s */  	uint8_t			course;		/* degrees / 2 */  	uint8_t			pdop;		/* * 5 */ @@ -53,8 +54,14 @@ struct ao_telemetry_location {  	int16_t			climb_rate;	/* cm/s */  	uint16_t		h_error;	/* m */  	uint16_t		v_error;	/* m */ +	int16_t			altitude_high;	/* m */  }; +typedef int32_t		gps_alt_t; +#define AO_TELEMETRY_LOCATION_ALTITUDE(l) 	(((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) +#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->altitude_high = (a) >> 16), \ +						 ((l)->altitude_low = (a))) +  #define UBLOX_SAT_STATE_ACQUIRED		(1 << 0)  #define UBLOX_SAT_STATE_CARRIER_PHASE_VALID	(1 << 1)  #define UBLOX_SAT_BIT_SYNC_COMPLETE		(1 << 2) diff --git a/src/test/ao_micropeak_test.c b/src/test/ao_micropeak_test.c index 5961bd93..f4af707e 100644 --- a/src/test/ao_micropeak_test.c +++ b/src/test/ao_micropeak_test.c @@ -33,6 +33,7 @@ uint8_t ao_flight_debug;  #define AO_FLIGHT_TEST  typedef int32_t alt_t; +typedef int32_t pres_t;  #define AO_MS_TO_TICKS(ms)	((ms) / 10) diff --git a/src/test/plottest b/src/test/plottest index 76af5ee7..7d253ff1 100755 --- a/src/test/plottest +++ b/src/test/plottest @@ -10,7 +10,7 @@ plot "$1" using 1:3 with lines axes x1y1 title "raw height",\  "$1" using 1:9 with lines axes x1y1 title "height",\  "$1" using 1:11 with lines axes x1y2 title "speed",\  "$1" using 1:13 with lines axes x1y2 title "accel",\ -"$1" using 1:15 with lines axes x1y1 title "drogue",\ -"$1" using 1:17 with lines axes x1y1 title "main",\ -"$1" using 1:19 with lines axes x1y1 title "error" +"$1" using 1:17 with lines axes x1y1 title "drogue",\ +"$1" using 1:19 with lines axes x1y1 title "main",\ +"$1" using 1:21 with lines axes x1y1 title "error"  EOF diff --git a/telegps/Makefile.am b/telegps/Makefile.am index 6138b004..3b33428e 100644 --- a/telegps/Makefile.am +++ b/telegps/Makefile.am @@ -87,6 +87,14 @@ MACOSX_ICONS	=\  	../icon/application-vnd.altusmetrum.eeprom.icns \  	../icon/application-vnd.altusmetrum.telemetry.icns +LINUX_ICONS	=\ +	$(ICONDIR)/altusmetrum-altosui.svg \ +	$(ICONDIR)/application-vnd.altusmetrum.eeprom.svg \ +	$(ICONDIR)/application-vnd.altusmetrum.telemetry.svg + +LINUX_MIMETYPE	=\ +	$(ICONDIR)/org-altusmetrum-mimetypes.xml +  # Firmware  FIRMWARE_TD_0_2=$(top_srcdir)/src/teledongle-v0.2/teledongle-v0.2-$(VERSION).ihx  FIRMWARE_TD=$(FIRMWARE_TD_0_2) @@ -131,7 +139,7 @@ DOC=$(TELEGPS_DOC)  FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) -LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in ../icon/altusmetrum-telegps.svg +LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)  LINUX_EXTRA=telegps-fat $(desktop_file).in  MACOSX_INFO_PLIST=Info.plist diff --git a/telegps/TeleGPS.java b/telegps/TeleGPS.java index d4b7bacf..a4b221e8 100644 --- a/telegps/TeleGPS.java +++ b/telegps/TeleGPS.java @@ -32,12 +32,12 @@ public class TeleGPS  {  	static String[] telegps_icon_names = { -		"/telegps-16.png", -		"/telegps-32.png", -		"/telegps-48.png", -		"/telegps-64.png", -		"/telegps-128.png", -		"/telegps-256.png" +		"/altusmetrum-telegps-16.png", +		"/altusmetrum-telegps-32.png", +		"/altusmetrum-telegps-48.png", +		"/altusmetrum-telegps-64.png", +		"/altusmetrum-telegps-128.png", +		"/altusmetrum-telegps-256.png"  	};  	static { set_icon_names(telegps_icon_names); } diff --git a/telegps/TeleGPSConfigUI.java b/telegps/TeleGPSConfigUI.java index 2bd1d2df..7a59bf48 100644 --- a/telegps/TeleGPSConfigUI.java +++ b/telegps/TeleGPSConfigUI.java @@ -670,6 +670,9 @@ public class TeleGPSConfigUI  		serial_value.setText(String.format("%d", serial));  	} +	public void set_altitude_32(int altitude_32) { +	} +  	public void set_main_deploy(int new_main_deploy) {  	}  | 
