diff options
| author | Keith Packard <keithp@keithp.com> | 2017-05-25 22:36:05 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2017-05-25 22:37:22 -0700 | 
| commit | 222158581887b5f9e8b9843d14321c313fa023fa (patch) | |
| tree | 4baab1916948932f9c5eff5960d685b58d62f470 | |
| parent | 4d497c1be534e2b206edec3c096198c8ea64cebe (diff) | |
altoslib/altosuilib/altosui: More work towards using AltosFlightSeries for analysis
Graphing and CSV seem complete now; stats still missing lots of stuff.
Signed-off-by: Keith Packard <keithp@keithp.com>
34 files changed, 555 insertions, 445 deletions
| diff --git a/altoslib/AltosCSV.java b/altoslib/AltosCSV.java index 0cfe4c94..38afdc64 100644 --- a/altoslib/AltosCSV.java +++ b/altoslib/AltosCSV.java @@ -192,31 +192,42 @@ public class AltosCSV implements AltosWriter {  		out.printf("accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z");  	} +	double accel_along() { return series.value(AltosFlightSeries.accel_along_name, indices); } +	double accel_across() { return series.value(AltosFlightSeries.accel_across_name, indices); } +	double accel_through() { return series.value(AltosFlightSeries.accel_through_name, indices); } + +	double gyro_roll() { return series.value(AltosFlightSeries.gyro_roll_name, indices); } +	double gyro_pitch() { return series.value(AltosFlightSeries.gyro_pitch_name, indices); } +	double gyro_yaw() { return series.value(AltosFlightSeries.gyro_yaw_name, indices); } + +	double mag_along() { return series.value(AltosFlightSeries.mag_along_name, indices); } +	double mag_across() { return series.value(AltosFlightSeries.mag_across_name, indices); } +	double mag_through() { return series.value(AltosFlightSeries.mag_through_name, indices); } +  	void write_advanced() { -/*  		out.printf("%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f,%7.2f", -			   state.accel_along(), state.accel_across(), state.accel_through(), -			   state.gyro_roll(), state.gyro_pitch(), state.gyro_yaw(), -			   state.mag_along(), state.mag_across(), state.mag_through()); -*/ +			   accel_along(), accel_across(), accel_through(), +			   gyro_roll(), gyro_pitch(), gyro_yaw(), +			   mag_along(), mag_across(), mag_through());  	}  	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,pdop,hdop,vdop"); -*/  	}  	void write_gps() { -/* -		AltosGPS	gps = state.gps; -		if (gps == null) -			gps = new AltosGPS(); +		AltosGPS	gps = series.gps_before(series.time(indices)); -		AltosGreatCircle from_pad = state.from_pad; -		if (from_pad == null) +		AltosGreatCircle from_pad; + +		if (series.cal_data.gps_pad != null && gps != null) +			from_pad = new AltosGreatCircle(series.cal_data.gps_pad, gps); +		else  			from_pad = new AltosGreatCircle(); +		if (gps == null) +			gps = new AltosGPS(); +  		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, @@ -231,13 +242,12 @@ public class AltosCSV implements AltosWriter {  			   gps.minute,  			   gps.second,  			   from_pad.distance, -			   state.range, +			   from_pad.range,  			   from_pad.bearing, -			   state.elevation, +			   from_pad.elevation,  			   gps.pdop,  			   gps.hdop,  			   gps.vdop); -*/  	}  	void write_gps_sat_header() { @@ -249,8 +259,7 @@ public class AltosCSV implements AltosWriter {  	}  	void write_gps_sat() { -/* -		AltosGPS	gps = state.gps; +		AltosGPS	gps = series.gps_before(series.time(indices));  		for(int i = 1; i <= 32; i++) {  			int	c_n0 = 0;  			if (gps != null && gps.cc_gps_sat != null) { @@ -264,13 +273,14 @@ public class AltosCSV implements AltosWriter {  			if (i != 32)  				out.printf(",");  		} -*/  	}  	void write_companion_header() { +/*  		out.printf("companion_id,companion_time,companion_update,companion_channels");  		for (int i = 0; i < 12; i++)  			out.printf(",companion_%02d", i); +*/  	}  	void write_companion() { @@ -401,16 +411,16 @@ public class AltosCSV implements AltosWriter {  			has_battery = true;  		if (series.has_series(AltosFlightSeries.accel_across_name))  			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; -		} -*/ + +		if (series.gps_series != null) +			has_gps = true; +		if (series.sats_in_view != null) +			has_gps_sat = true; +		/* +		if (state.companion != null) +			has_companion = true; +		*/ +  		indices = series.indices();  		for (;;) { diff --git a/altoslib/AltosCalData.java b/altoslib/AltosCalData.java index 58d34abe..3da0e400 100644 --- a/altoslib/AltosCalData.java +++ b/altoslib/AltosCalData.java @@ -204,12 +204,11 @@ public class AltosCalData {  		this.state = state;  	} -	public double		gps_ground_altitude = AltosLib.MISSING; +	public AltosGPS		gps_pad = null; -	public void set_gps_altitude(double altitude) { -		if ((state != AltosLib.MISSING && state < AltosLib.ao_flight_boost) || -		    gps_ground_altitude == AltosLib.MISSING) -			gps_ground_altitude = altitude; +	public void set_gps(AltosGPS gps) { +		if ((state != AltosLib.MISSING && state < AltosLib.ao_flight_boost) || gps_pad == null) +			gps_pad = gps;  	}  	/* @@ -226,7 +225,7 @@ public class AltosCalData {  	public void reset_temp_gps() {  		if (temp_gps != null) {  			if (temp_gps.locked && temp_gps.nsat >= 4) -				set_gps_altitude(temp_gps.alt); +				set_gps(temp_gps);  		}  		temp_gps = null;  	} diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java index 95c1a99f..5b3ff391 100644 --- a/altoslib/AltosConvert.java +++ b/altoslib/AltosConvert.java @@ -191,7 +191,7 @@ public class AltosConvert {  	}  	public static double -	cc_ignitor_to_voltage(double ignite) +	cc_igniter_to_voltage(double ignite)  	{  		return ignite / 32767 * 15.0;  	} @@ -434,6 +434,10 @@ public class AltosConvert {  	public static AltosStateName state_name = new AltosStateName(); +	public static AltosPyroName pyro_name = new AltosPyroName(); + +	public static AltosUnits magnetic_field = null; +  	public static String show_gs(String format, double a) {  		a = meters_to_g(a);  		format = format.concat(" g"); diff --git a/altoslib/AltosDataListener.java b/altoslib/AltosDataListener.java index b644e817..4a6fe04d 100644 --- a/altoslib/AltosDataListener.java +++ b/altoslib/AltosDataListener.java @@ -59,7 +59,7 @@ public abstract class AltosDataListener {  	public abstract void set_accel(double along, double across, double through);  	public abstract void set_mag(double along, double across, double through);  	public abstract void set_pyro_voltage(double volts); -	public abstract void set_ignitor_voltage(double[] voltage); +	public abstract void set_igniter_voltage(double[] voltage);  	public abstract void set_pyro_fired(int pyro_mask);  	public abstract void set_companion(AltosCompanion companion); diff --git a/altoslib/AltosDistance.java b/altoslib/AltosDistance.java index 0239c5ce..5e1b3545 100644 --- a/altoslib/AltosDistance.java +++ b/altoslib/AltosDistance.java @@ -96,7 +96,7 @@ public class AltosDistance extends AltosUnits {  				}  			}; -		range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(1000), +		range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(5280),  							"mi", "miles") {  				double value(double v) {  					return AltosConvert.meters_to_miles(v); diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java index 4e641b85..8a2053ec 100644 --- a/altoslib/AltosEepromDownload.java +++ b/altoslib/AltosEepromDownload.java @@ -59,7 +59,7 @@ class AltosEepromNameData extends AltosDataListener {  	public void set_accel(double along, double across, double through) { }  	public void set_mag(double along, double across, double through) { }  	public void set_pyro_voltage(double volts) { } -	public void set_ignitor_voltage(double[] voltage) { } +	public void set_igniter_voltage(double[] voltage) { }  	public void set_pyro_fired(int pyro_mask) { }  	public void set_companion(AltosCompanion companion) { }  	public void set_kalman(double height, double speed, double acceleration) { } diff --git a/altoslib/AltosEepromNew.java b/altoslib/AltosEepromNew.java index 5220f3a0..0da3df71 100644 --- a/altoslib/AltosEepromNew.java +++ b/altoslib/AltosEepromNew.java @@ -165,7 +165,8 @@ public class AltosEepromNew {  			int start = data.size();  			if (config_data().log_format != AltosLib.AO_LOG_FORMAT_TINY) { -				data.add((byte) tokens[0].codePointAt(0)); +				byte cmd = (byte) tokens[0].codePointAt(0); +				data.add(cmd);  				int time = AltosLib.fromhex(tokens[1]); diff --git a/altoslib/AltosEepromRecord.java b/altoslib/AltosEepromRecord.java index 08f7ebca..7dd37592 100644 --- a/altoslib/AltosEepromRecord.java +++ b/altoslib/AltosEepromRecord.java @@ -92,7 +92,7 @@ public abstract class AltosEepromRecord implements Comparable<AltosEepromRecord>  	public int next_start() {  		int	s = start + length; -		while (s + length < eeprom.data.size()) { +		while (s + length <= eeprom.data.size()) {  			if (valid(s))  				return s;  			s += length; diff --git a/altoslib/AltosEepromRecordFull.java b/altoslib/AltosEepromRecordFull.java index ea81eb3d..b4968220 100644 --- a/altoslib/AltosEepromRecordFull.java +++ b/altoslib/AltosEepromRecordFull.java @@ -62,8 +62,8 @@ public class AltosEepromRecordFull extends AltosEepromRecord {  			listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(data16(2)));  			break;  		case AltosLib.AO_LOG_DEPLOY: -			listener.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(data16(0))); -			listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(data16(2))); +			listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(data16(0))); +			listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(data16(2)));  			break;  		case AltosLib.AO_LOG_STATE:  			listener.set_state(data16(0)); diff --git a/altoslib/AltosEepromRecordMega.java b/altoslib/AltosEepromRecordMega.java index 371810ab..d4a5a0b2 100644 --- a/altoslib/AltosEepromRecordMega.java +++ b/altoslib/AltosEepromRecordMega.java @@ -143,6 +143,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {  					       ground_yaw() / 512.0);  			break;  		case AltosLib.AO_LOG_STATE: +			System.out.printf("log state %s\n", AltosLib.state_name(state()));  			listener.set_state(state());  			break;  		case AltosLib.AO_LOG_SENSOR: @@ -198,7 +199,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {  			for (int i = 0; i < nsense-2; i++)  				voltages[i] = AltosConvert.mega_pyro_voltage(sense(i)); -			listener.set_ignitor_voltage(voltages); +			listener.set_igniter_voltage(voltages);  			listener.set_pyro_fired(pyro());  			break;  		case AltosLib.AO_LOG_GPS_TIME: diff --git a/altoslib/AltosFlightListener.java b/altoslib/AltosFlightListener.java index 5b478ed0..395d8f3f 100644 --- a/altoslib/AltosFlightListener.java +++ b/altoslib/AltosFlightListener.java @@ -130,7 +130,7 @@ public abstract class AltosFlightListener {  	public abstract void set_imu(AltosIMU imu);  	public abstract void set_mag(AltosMag mag);  	public abstract void set_pyro_voltage(double volts); -	public abstract void set_ignitor_voltage(double[] voltage); +	public abstract void set_igniter_voltage(double[] voltage);  	public abstract void set_pyro_fired(int pyro_mask);  	public void copy(AltosFlightListener old) { diff --git a/altoslib/AltosFlightSeries.java b/altoslib/AltosFlightSeries.java index b7434a5c..0eea34b7 100644 --- a/altoslib/AltosFlightSeries.java +++ b/altoslib/AltosFlightSeries.java @@ -23,12 +23,17 @@ public class AltosFlightSeries extends AltosDataListener {  	public int[] indices() {  		int[] indices = new int[series.size()];  		for (int i = 0; i < indices.length; i++) -			indices[i] = 0; +			indices[i] = -1; +		step_indices(indices);  		return indices;  	}  	private double time(int id, int index) {  		AltosTimeSeries		s = series.get(id); + +		if (index < 0) +			return Double.NEGATIVE_INFINITY; +  		if (index < s.values.size())  			return s.values.get(index).time;  		return Double.POSITIVE_INFINITY; @@ -69,8 +74,30 @@ public class AltosFlightSeries extends AltosDataListener {  	public double value(String name, int[] indices) {  		for (int i = 0; i < indices.length; i++) {  			AltosTimeSeries	s = series.get(i); +			if (s.label.equals(name)) { +				int index = indices[i]; +				if (index < 0) +					index = 0; +				if (index >= s.values.size()) +					index = s.values.size() - 1; +				return s.values.get(index).value; +			} +		} +		return AltosLib.MISSING; +	} + +	public double value_before(String name, double time) { +		for (AltosTimeSeries s : series) {  			if (s.label.equals(name)) -				return s.values.get(indices[i]).value; +				return s.value_before(time); +		} +		return AltosLib.MISSING; +	} + +	public double value_after(String name, double time) { +		for (AltosTimeSeries s : series) { +			if (s.label.equals(name)) +				return s.value_after(time);  		}  		return AltosLib.MISSING;  	} @@ -105,11 +132,12 @@ public class AltosFlightSeries extends AltosDataListener {  	public static final String state_name = "State";  	public void set_state(int state) { -		this.state = state;  		if (state_series == null)  			state_series = add_series(state_name, AltosConvert.state_name); -		else if ((int) state_series.get(state_series.size()-1).value == state) +		else if (this.state == state)  			return; +		System.out.printf("state %s\n", AltosLib.state_name(state)); +		this.state = state;  		state_series.add(time(), state);  	} @@ -146,14 +174,14 @@ public class AltosFlightSeries extends AltosDataListener {  	AltosTimeSeries status_series; -	public static final String status_name = "Status"; +	public static final String status_name = "Radio Status";  	public void set_rssi(int rssi, int status) { -		if (rssi_series == null) +		if (rssi_series == null) {  			rssi_series = add_series(rssi_name, null); -		rssi_series.add(time(), rssi); -		if (status_series == null)  			status_series = add_series(status_name, null); +		} +		rssi_series.add(time(), rssi);  		status_series.add(time(), status);  	} @@ -329,6 +357,18 @@ public class AltosFlightSeries extends AltosDataListener {  		main_voltage_series.add(time(), volts);  	} +	public ArrayList<AltosGPSTimeValue> gps_series; + +	public AltosGPS gps_before(double time) { +		AltosGPS gps = null; +		for (AltosGPSTimeValue gtv : gps_series) +			if (gtv.time <= time) +				gps = gtv.gps; +			else +				break; +		return gps; +	} +  	AltosTimeSeries	sats_in_view;  	AltosTimeSeries sats_in_soln;  	AltosTimeSeries gps_altitude; @@ -337,8 +377,7 @@ public class AltosFlightSeries extends AltosDataListener {  	AltosTimeSeries gps_ascent_rate;  	AltosTimeSeries gps_course;  	AltosTimeSeries gps_speed; - -	public ArrayList<AltosGPSTimeValue> gps_series; +	AltosTimeSeries gps_pdop, gps_vdop, gps_hdop;  	public static final String sats_in_view_name = "Satellites in view";  	public static final String sats_in_soln_name = "Satellites in solution"; @@ -348,30 +387,42 @@ public class AltosFlightSeries extends AltosDataListener {  	public static final String gps_ascent_rate_name = "GPS Ascent Rate";  	public static final String gps_course_name = "GPS Course";  	public static final String gps_speed_name = "GPS Speed"; +	public static final String gps_pdop_name = "GPS Dilution of Precision"; +	public static final String gps_vdop_name = "GPS Vertical Dilution of Precision"; +	public static final String gps_hdop_name = "GPS Horizontal Dilution of Precision";  	public void set_gps(AltosGPS gps) {  		if (gps_series == null)  			gps_series = new ArrayList<AltosGPSTimeValue>();  		gps_series.add(new AltosGPSTimeValue(time(), gps)); -		if (sats_in_view == null) { -			sats_in_view = add_series(sats_in_view_name, null); +		if (sats_in_soln == null) {  			sats_in_soln = add_series(sats_in_soln_name, null); -			gps_altitude = add_series(gps_altitude_name, AltosConvert.height); -			gps_height = add_series(gps_height_name, AltosConvert.height); -			gps_ground_speed = add_series(gps_ground_speed_name, AltosConvert.speed); -			gps_ascent_rate = add_series(gps_ascent_rate_name, AltosConvert.speed); -			gps_course = add_series(gps_course_name, null); -			gps_speed = add_series(gps_speed_name, null);  		} -		if (gps.cc_gps_sat != null) -			sats_in_view.add(time(), gps.cc_gps_sat.length); +		sats_in_soln.add(time(), gps.nsat); +		if (gps.pdop != AltosLib.MISSING) { +			if (gps_pdop == null) { +				gps_pdop = add_series(gps_pdop_name, null); +				gps_hdop = add_series(gps_hdop_name, null); +				gps_vdop = add_series(gps_vdop_name, null); +			} +			gps_pdop.add(time(), gps.pdop); +			gps_hdop.add(time(), gps.hdop); +			gps_vdop.add(time(), gps.vdop); +		}  		if (gps.locked) { -			sats_in_soln.add(time(), gps.nsat); +			if (gps_altitude == null) { +				gps_altitude = add_series(gps_altitude_name, AltosConvert.height); +				gps_height = add_series(gps_height_name, AltosConvert.height); +				gps_ground_speed = add_series(gps_ground_speed_name, AltosConvert.speed); +				gps_ascent_rate = add_series(gps_ascent_rate_name, AltosConvert.speed); +				gps_course = add_series(gps_course_name, null); +				gps_speed = add_series(gps_speed_name, null); +			}  			if (gps.alt != AltosLib.MISSING) {  				gps_altitude.add(time(), gps.alt); -				if (cal_data.gps_ground_altitude != AltosLib.MISSING) -					gps_height.add(time(), gps.alt - cal_data.gps_ground_altitude); +				if (cal_data.gps_pad != null) +					gps_height.add(time(), gps.alt - cal_data.gps_pad.alt);  			}  			if (gps.ground_speed != AltosLib.MISSING)  				gps_ground_speed.add(time(), gps.ground_speed); @@ -383,33 +434,141 @@ public class AltosFlightSeries extends AltosDataListener {  				gps_speed.add(time(), Math.sqrt(gps.ground_speed * gps.ground_speed +  								gps.climb_rate * gps.climb_rate));  		} +		if (gps.cc_gps_sat != null) { +			if (sats_in_view == null) +				sats_in_view = add_series(sats_in_view_name, null); +			sats_in_view.add(time(), gps.cc_gps_sat.length); +		}  	} -	public static final String accel_across_name = "Accel Across";  	public static final String accel_along_name = "Accel Along"; +	public static final String accel_across_name = "Accel Across";  	public static final String accel_through_name = "Accel Through"; +	AltosTimeSeries accel_along, accel_across, accel_through; + +	public static final String gyro_roll_name = "Roll Rate"; +	public static final String gyro_pitch_name = "Pitch Rate"; +	public static final String gyro_yaw_name = "Yaw Rate"; + +	AltosTimeSeries gyro_roll, gyro_pitch, gyro_yaw; + +	public static final String mag_along_name = "Magnetic Field Along"; +	public static final String mag_across_name = "Magnetic Field Across"; +	public static final String mag_through_name = "Magnetic Field Through"; + +	AltosTimeSeries mag_along, mag_across, mag_through; +  	public  void set_accel(double along, double across, double through) { +		if (accel_along == null) { +			accel_along = add_series(accel_along_name, AltosConvert.accel); +			accel_across = add_series(accel_across_name, AltosConvert.accel); +			accel_through = add_series(accel_through_name, AltosConvert.accel); +		} +		accel_along.add(time(), along); +		accel_across.add(time(), across); +		accel_through.add(time(), through);  	}  	public  void set_accel_ground(double along, double across, double through) {  	}  	public  void set_gyro(double roll, double pitch, double yaw) { +		if (gyro_roll == null) { +			gyro_roll = add_series(gyro_roll_name, AltosConvert.rotation_rate); +			gyro_pitch = add_series(gyro_pitch_name, AltosConvert.rotation_rate); +			gyro_yaw = add_series(gyro_yaw_name, AltosConvert.rotation_rate); +		} +		gyro_roll.add(time(), roll); +		gyro_pitch.add(time(), pitch); +		gyro_yaw.add(time(), yaw);  	}  	public  void set_mag(double along, double across, double through) { +		if (mag_along == null) { +			mag_along = add_series(mag_along_name, AltosConvert.magnetic_field); +			mag_across = add_series(mag_across_name, AltosConvert.magnetic_field); +			mag_through = add_series(mag_through_name, AltosConvert.magnetic_field); +		} +		mag_along.add(time(), along); +		mag_across.add(time(), across); +		mag_through.add(time(), through);  	} -	public void set_orient(double new_orient) { } +	public static final String orient_name = "Tilt Angle"; + +	AltosTimeSeries orient_series; + +	public void set_orient(double orient) { +		if (orient_series == null) +			orient_series = add_series(orient_name, AltosConvert.orient); +		orient_series.add(time(), orient); +	} + +	public static final String pyro_voltage_name = "Pyro Voltage"; + +	AltosTimeSeries pyro_voltage;  	public  void set_pyro_voltage(double volts) { +		if (pyro_voltage == null) +			pyro_voltage = add_series(pyro_voltage_name, AltosConvert.voltage); +		pyro_voltage.add(time(), volts);  	} -	public  void set_ignitor_voltage(double[] voltage) { +	private static String[] igniter_voltage_names; + +	public String igniter_voltage_name(int channel) { +		if (igniter_voltage_names == null || igniter_voltage_names.length <= channel) { +			String[] new_igniter_voltage_names = new String[channel + 1]; +			int	i = 0; + +			if (igniter_voltage_names != null) { +				for (; i < igniter_voltage_names.length; i++) +					new_igniter_voltage_names[i] = igniter_voltage_names[i]; +			} +			for (; i < channel+1; i++) +				new_igniter_voltage_names[i] = AltosLib.igniter_name(i); +			igniter_voltage_names = new_igniter_voltage_names; +		} +		return igniter_voltage_names[channel]; +	} + +	AltosTimeSeries[] igniter_voltage; + +	public  void set_igniter_voltage(double[] voltage) { +		int channels = voltage.length; +		if (igniter_voltage == null || igniter_voltage.length <= channels) { +			AltosTimeSeries[]	new_igniter_voltage = new AltosTimeSeries[channels + 1]; +			int			i = 0; + +			if (igniter_voltage != null) { +				for (; i < igniter_voltage.length; i++) +					new_igniter_voltage[i] = igniter_voltage[i]; +			} +			for (; i < channels; i++) +				new_igniter_voltage[i] = add_series(igniter_voltage_name(i), AltosConvert.voltage); +			igniter_voltage = new_igniter_voltage; +		} +		for (int channel = 0; channel < voltage.length; channel++) +			igniter_voltage[channel].add(time(), voltage[channel]);  	} +	public static final String pyro_fired_name = "Pyro Channel State"; + +	AltosTimeSeries pyro_fired_series; + +	int	last_pyro_mask; +  	public  void set_pyro_fired(int pyro_mask) { +		if (pyro_fired_series == null) +			pyro_fired_series = add_series(pyro_fired_name, AltosConvert.pyro_name); +		for (int channel = 0; channel < 32; channel++) { +			if ((last_pyro_mask & (1 << channel)) == 0 && +			    (pyro_mask & (1 << channel)) != 0) { +				pyro_fired_series.add(time(), channel); +			} +		} +		last_pyro_mask = pyro_mask;  	}  	public void set_companion(AltosCompanion companion) { diff --git a/altoslib/AltosFlightStats.java b/altoslib/AltosFlightStats.java index 7179351e..54d0dd63 100644 --- a/altoslib/AltosFlightStats.java +++ b/altoslib/AltosFlightStats.java @@ -46,7 +46,7 @@ public class AltosFlightStats {  	public boolean		has_imu;  	public boolean		has_mag;  	public boolean		has_orient; -	public int		num_ignitor; +	public int		num_igniter;  	double landed_time(AltosFlightSeries series) {  		double	landed_state_time = AltosLib.MISSING; @@ -215,8 +215,8 @@ public class AltosFlightStats {  				has_mag = true;  			if (state.orient() != AltosLib.MISSING)  				has_orient = true; -			if (state.ignitor_voltage != null && state.ignitor_voltage.length > num_ignitor) -				num_ignitor = state.ignitor_voltage.length; +			if (state.igniter_voltage != null && state.igniter_voltage.length > num_igniter) +				num_igniter = state.igniter_voltage.length;  		}  */  		for (int s = AltosLib.ao_flight_startup; s <= AltosLib.ao_flight_landed; s++) { diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 2137d1d7..fb43ea20 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -571,7 +571,7 @@ public class AltosLib {  		}  	} -	public static String ignitor_name(int i) { +	public static String igniter_name(int i) {  		return String.format("Ignitor %c", 'A' + i);  	}  } diff --git a/altoslib/AltosMapLine.java b/altoslib/AltosMapLine.java index c475f52d..cf09307e 100644 --- a/altoslib/AltosMapLine.java +++ b/altoslib/AltosMapLine.java @@ -44,39 +44,9 @@ public abstract class AltosMapLine {  	}  	public String line_dist() { -		String	format;  		AltosGreatCircle	g = new AltosGreatCircle(start.lat, start.lon,  								 end.lat, end.lon); -		double	distance = g.distance; -		if (AltosConvert.imperial_units) { -			distance = AltosConvert.meters_to_feet(distance); -			if (distance < 1000) { -				format = "%4.0fft"; -			} else { -				distance /= 5280; -				if (distance < 10) -					format = "%5.3fmi"; -				else if (distance < 100) -					format = "%5.2fmi"; -				else if (distance < 1000) -					format = "%5.1fmi"; -				else -					format = "%5.0fmi"; -			} -		} else { -			if (distance < 1000) { -				format = "%4.0fm"; -			} else { -				distance /= 1000; -				if (distance < 100) -					format = "%5.2fkm"; -				else if (distance < 1000) -					format = "%5.1fkm"; -				else -					format = "%5.0fkm"; -			} -		} -		return String.format(format, distance); +		return AltosConvert.distance.show(7, g.distance);  	}  } diff --git a/altoslib/AltosPyroName.java b/altoslib/AltosPyroName.java new file mode 100644 index 00000000..18a31dd2 --- /dev/null +++ b/altoslib/AltosPyroName.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2017 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +package org.altusmetrum.altoslib_11; + +public class AltosPyroName extends AltosUnits { + +	public double value(double v, boolean imperial_units) { return v; } + +	public double inverse(double v, boolean imperial_units) { return v; } + +	public String string_value(double v, boolean imperial_units) { +		return AltosLib.igniter_name((int) v); +	} + +	public String show_units(boolean imperial_units) { return "state"; } + +	public String say_units(boolean imperial_units) { return "state"; } + +	public int show_fraction(int width, boolean imperial_units) { return 0; } +} diff --git a/altoslib/AltosSensorMega.java b/altoslib/AltosSensorMega.java index 63c7a0ce..82696038 100644 --- a/altoslib/AltosSensorMega.java +++ b/altoslib/AltosSensorMega.java @@ -97,10 +97,10 @@ class AltosSensorMega {  			state.set_apogee_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[4]));  			state.set_main_voltage(AltosConvert.mega_pyro_voltage(sensor_mega.sense[5])); -			double[]	ignitor_voltage = new double[4]; +			double[]	igniter_voltage = new double[4];  			for (int i = 0; i < 4; i++) -				ignitor_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]); -			state.set_ignitor_voltage(ignitor_voltage); +				igniter_voltage[i] = AltosConvert.mega_pyro_voltage(sensor_mega.sense[i]); +			state.set_igniter_voltage(igniter_voltage);  		} catch (TimeoutException te) {  		} diff --git a/altoslib/AltosSensorTM.java b/altoslib/AltosSensorTM.java index 7d7becfb..49f3986b 100644 --- a/altoslib/AltosSensorTM.java +++ b/altoslib/AltosSensorTM.java @@ -39,8 +39,8 @@ public class AltosSensorTM {  			listener.set_pressure(AltosConvert.barometer_to_pressure(sensor_tm.pres));  			listener.set_temperature(AltosConvert.thermometer_to_temperature(sensor_tm.temp));  			listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(sensor_tm.batt)); -			listener.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.drogue)); -			listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sensor_tm.main)); +			listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(sensor_tm.drogue)); +			listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(sensor_tm.main));  		} catch (TimeoutException te) {  		} diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index f46b12ea..889aa9a3 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -702,7 +702,7 @@ public class AltosState extends AltosDataListener {  	public double	apogee_voltage;  	public double	main_voltage; -	public double	ignitor_voltage[]; +	public double	igniter_voltage[];  	public AltosGPS	gps;  	public AltosGPS	temp_gps; @@ -786,7 +786,7 @@ public class AltosState extends AltosDataListener {  		pyro_voltage = AltosLib.MISSING;  		apogee_voltage = AltosLib.MISSING;  		main_voltage = AltosLib.MISSING; -		ignitor_voltage = null; +		igniter_voltage = null;  		kalman_height = new AltosValue();  		kalman_speed = new AltosValue(); @@ -1221,8 +1221,8 @@ public class AltosState extends AltosDataListener {  		}  	} -	public void set_ignitor_voltage(double[] voltage) { -		this.ignitor_voltage = voltage; +	public void set_igniter_voltage(double[] voltage) { +		this.igniter_voltage = voltage;  	}  	public void set_pyro_fired(int fired) { diff --git a/altoslib/AltosTelemetryFile.java b/altoslib/AltosTelemetryFile.java index 0b0e6a48..c6462872 100644 --- a/altoslib/AltosTelemetryFile.java +++ b/altoslib/AltosTelemetryFile.java @@ -46,7 +46,7 @@ class AltosTelemetryNullListener extends AltosDataListener {  	public void set_accel(double along, double across, double through) { }  	public void set_mag(double along, double across, double through) { }  	public void set_pyro_voltage(double volts) { } -	public void set_ignitor_voltage(double[] voltage) { } +	public void set_igniter_voltage(double[] voltage) { }  	public void set_pyro_fired(int pyro_mask) { }  	public void set_companion(AltosCompanion companion) { } @@ -78,7 +78,7 @@ class AltosTelemetryNullListener extends AltosDataListener {  		/*  		 * TelemetryLocation  		 */ -		if (AltosLib.has_gps(cal_data.device_type) && cal_data.gps_ground_altitude == AltosLib.MISSING) +		if (AltosLib.has_gps(cal_data.device_type) && cal_data.gps_pad == null)  			return false;  		return true; diff --git a/altoslib/AltosTelemetryLegacy.java b/altoslib/AltosTelemetryLegacy.java index 394d023c..8a86417c 100644 --- a/altoslib/AltosTelemetryLegacy.java +++ b/altoslib/AltosTelemetryLegacy.java @@ -564,8 +564,8 @@ public class AltosTelemetryLegacy extends AltosTelemetry {  			listener.set_kalman(kalman_height, kalman_speed, kalman_acceleration);  		listener.set_temperature(AltosConvert.thermometer_to_temperature(temp));  		listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(batt)); -		listener.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(apogee)); -		listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(main)); +		listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(apogee)); +		listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(main));  		if (gps != null)  			listener.set_gps(gps);  	} diff --git a/altoslib/AltosTelemetryLocation.java b/altoslib/AltosTelemetryLocation.java index 5eb727d6..c7b7fa22 100644 --- a/altoslib/AltosTelemetryLocation.java +++ b/altoslib/AltosTelemetryLocation.java @@ -58,6 +58,9 @@ public class AltosTelemetryLocation extends AltosTelemetryStandard {  		gps.nsat = flags & 0xf;  		gps.locked = (flags & (1 << 4)) != 0;  		gps.connected = (flags & (1 << 5)) != 0; +		gps.pdop = pdop() / 10.0; +		gps.hdop = hdop() / 10.0; +		gps.vdop = vdop() / 10.0;  		if (gps.locked) {  			gps.lat = latitude() * 1.0e-7; @@ -72,12 +75,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.pdop = pdop() / 10.0; -			gps.hdop = hdop() / 10.0; -			gps.vdop = vdop() / 10.0;  			if (gps.nsat >= 4) -				cal_data.set_gps_altitude(gps.alt); +				cal_data.set_gps(gps);  		}  		listener.set_gps(gps);  	} diff --git a/altoslib/AltosTelemetryMegaData.java b/altoslib/AltosTelemetryMegaData.java index c0749e87..b648f300 100644 --- a/altoslib/AltosTelemetryMegaData.java +++ b/altoslib/AltosTelemetryMegaData.java @@ -55,7 +55,7 @@ public class AltosTelemetryMegaData extends AltosTelemetryStandard {  		for (int i = 0; i < 4; i++)  			voltages[i] = AltosConvert.mega_pyro_voltage(sense(i)); -		listener.set_ignitor_voltage(voltages); +		listener.set_igniter_voltage(voltages);  		cal_data.set_ground_accel(ground_accel());  		cal_data.set_ground_pressure(ground_pres()); diff --git a/altoslib/AltosTelemetrySensor.java b/altoslib/AltosTelemetrySensor.java index 37589397..da253eea 100644 --- a/altoslib/AltosTelemetrySensor.java +++ b/altoslib/AltosTelemetrySensor.java @@ -57,8 +57,8 @@ public class AltosTelemetrySensor extends AltosTelemetryStandard {  		listener.set_temperature(AltosConvert.thermometer_to_temperature(temp()));  		listener.set_battery_voltage(AltosConvert.cc_battery_to_voltage(v_batt()));  		if (type() == packet_type_TM_sensor || type() == packet_type_Tm_sensor) { -			listener.set_apogee_voltage(AltosConvert.cc_ignitor_to_voltage(sense_d())); -			listener.set_main_voltage(AltosConvert.cc_ignitor_to_voltage(sense_m())); +			listener.set_apogee_voltage(AltosConvert.cc_igniter_to_voltage(sense_d())); +			listener.set_main_voltage(AltosConvert.cc_igniter_to_voltage(sense_m()));  		}  		listener.set_kalman(height_16(), speed()/16.0, acceleration()/16.0); diff --git a/altoslib/AltosTimeSeries.java b/altoslib/AltosTimeSeries.java index 1d3d9a6c..30b24d82 100644 --- a/altoslib/AltosTimeSeries.java +++ b/altoslib/AltosTimeSeries.java @@ -17,9 +17,9 @@ package org.altusmetrum.altoslib_11;  import java.util.*;  public class AltosTimeSeries implements Iterable<AltosTimeValue> { -	public String		label; -	public AltosUnits	units; -	List<AltosTimeValue>	values; +	public String			label; +	public AltosUnits		units; +	ArrayList<AltosTimeValue>	values;  	public void add(AltosTimeValue tv) {  		values.add(tv); @@ -33,6 +33,58 @@ public class AltosTimeSeries implements Iterable<AltosTimeValue> {  		return values.get(i);  	} +	private double lerp(AltosTimeValue v0, AltosTimeValue v1, double t) { +		/* degenerate case */ +		if (v0.time == v1.time) +			return (v0.value + v1.value) / 2; + +		return (v0.value * (v1.time - t) + v1.value * (t - v0.time)) / v1.time - v0.time; +	} + +	private int after_index(double time) { +		int	lo = 0; +		int	hi = values.size() - 1; + +		while (lo <= hi) { +			int mid = (lo + hi) / 2; + +			if (values.get(mid).time < time) +				lo = mid + 1; +			else +				hi = mid - 1; +		} +		return lo; +	} + +	/* Compute a value for an arbitrary time */ +	public double value(double time) { +		int after = after_index(time); +		if (after == 0) +			return values.get(0).value; +		if (after == values.size()) +			return values.get(after - 1).value; + +		return lerp(values.get(after-1), values.get(after), time); +	} + +	/* Find the value just before an arbitrary time */ +	public double value_before(double time) { +		int after = after_index(time); + +		if (after == 0) +			return values.get(0).value; +		return values.get(after-1).value; +	} + +	/* Find the value just after an arbitrary time */ +	public double value_after(double time) { +		int after = after_index(time); + +		if (after == values.size()) +			return values.get(after-1).value; +		return values.get(after).value; +	} +  	public int size() {  		return values.size();  	} @@ -144,11 +196,16 @@ public class AltosTimeSeries implements Iterable<AltosTimeValue> {  			int	left = find_left(i, half_width);  			int	right = find_right(i, half_width); +  			for (int j = left; j <= right; j++) {  				double	j_time = values.get(j).time;  				if (left_time <= j_time && j_time <= right_time) { -					double	coeff = filter_coeff(j_time - center_time, width); +					double	j_left = j == left ? left_time : values.get(j-1).time; +					double	j_right = j == right ? right_time : values.get(j+1).time; +					double	interval = (j_right - j_left) / 2.0; +					double	coeff = filter_coeff(j_time - center_time, width) * interval; +  					total_coeff += coeff;  					total_value += coeff * values.get(j).value;  				} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index fa0e8c1b..ffa92783 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -92,6 +92,7 @@ altoslib_JAVA = \  	AltosPreferences.java \  	AltosPreferencesBackend.java \  	AltosProgrammer.java \ +	AltosPyroName.java \  	AltosReplayReader.java \  	AltosRomconfig.java \  	AltosSavedState.java \ diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 3d33b6e5..eaf19256 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -36,7 +36,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {  	JTabbedPane	pane;  	AltosPad	pad; -	AltosIgnitor	ignitor; +	AltosIgnitor	igniter;  	AltosAscent	ascent;  	AltosDescent	descent;  	AltosLanded	landed; @@ -45,7 +45,7 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {  	boolean		has_map;  	boolean		has_companion;  	boolean		has_state; -	boolean		has_ignitor; +	boolean		has_igniter;  	private AltosFlightStatus flightStatus;  	private AltosInfoTable flightInfo; @@ -121,15 +121,15 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {  			cur_tab = tab;  		} -		if (ignitor.should_show(state)) { -			if (!has_ignitor) { -				pane.add("Ignitor", ignitor); -				has_ignitor = true; +		if (igniter.should_show(state)) { +			if (!has_igniter) { +				pane.add("Ignitor", igniter); +				has_igniter = true;  			}  		} else { -			if (has_ignitor) { -				pane.remove(ignitor); -				has_ignitor = false; +			if (has_igniter) { +				pane.remove(igniter); +				has_igniter = false;  			}  		} @@ -272,8 +272,8 @@ public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {  		displays.add(pad);  		pane.add("Status", pad); -		ignitor = new AltosIgnitor(); -		displays.add(ignitor); +		igniter = new AltosIgnitor(); +		displays.add(igniter);  		ascent = new AltosAscent();  		displays.add(ascent);  		descent = new AltosDescent(); diff --git a/altosui/AltosGraphUI.java b/altosui/AltosGraphUI.java index 5314a3b6..a3107f2b 100644 --- a/altosui/AltosGraphUI.java +++ b/altosui/AltosGraphUI.java @@ -44,19 +44,26 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt  	void fill_map(AltosFlightSeries flight_series) {  		boolean			any_gps = false; +		AltosGPSTimeValue	gtv_last = null;  		for (AltosGPSTimeValue gtv : flight_series.gps_series) { +			gtv_last = gtv;  			AltosGPS gps = gtv.gps;  			if (gps != null &&  			    gps.locked &&  			    gps.nsat >= 4) {  				if (map == null)  					map = new AltosUIMap(); -				map.show(gps, AltosLib.ao_flight_pad); +				map.show(gps, (int) flight_series.value_before(AltosFlightSeries.state_name, gtv.time));  				this.gps = gps;  				has_gps = true;  			}  		} +		if (gtv_last != null) { +			int state = (int) flight_series.value_after(AltosFlightSeries.state_name, gtv_last.time); +			if (state == AltosLib.ao_flight_landed) +				map.show(gtv_last.gps, state); +		}  	}  	public void font_size_changed(int font_size) { diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index 4d5c3b2d..afa9b944 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -34,12 +34,12 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  	AltosPad		pad;  	AltosInfoTable		flightInfo;  	AltosFlightStatus	flightStatus; -	AltosIgnitor		ignitor; +	AltosIgnitor		igniter;  	AltosIdleMonitor	thread;  	AltosUIMap      	sitemap;  	int			serial;  	boolean			remote; -	boolean			has_ignitor; +	boolean			has_igniter;  	boolean			has_map;  	void stop_display() { @@ -75,15 +75,15 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  	public void show(AltosState state, AltosListenerState listener_state) {  		status_update.saved_state = state; -		if (ignitor.should_show(state)) { -			if (!has_ignitor) { -				pane.add("Ignitor", ignitor); -				has_ignitor = true; +		if (igniter.should_show(state)) { +			if (!has_igniter) { +				pane.add("Ignitor", igniter); +				has_igniter = true;  			}  		} else { -			if (has_ignitor) { -				pane.remove(ignitor); -				has_ignitor = false; +			if (has_igniter) { +				pane.remove(igniter); +				has_igniter = false;  			}  		}  		if (state.gps != null && state.gps.connected) { @@ -102,8 +102,8 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  			pad.show(state, listener_state);  			flightStatus.show(state, listener_state);  			flightInfo.show(state, listener_state); -			if (has_ignitor) -				ignitor.show(state, listener_state); +			if (has_igniter) +				igniter.show(state, listener_state);  			if (has_map)  				sitemap.show(state, listener_state);  //		} catch (Exception e) { @@ -274,7 +274,7 @@ public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDispl  		flightInfo = new AltosInfoTable();  		pane.add("Table", new JScrollPane(flightInfo)); -		ignitor = new AltosIgnitor(); +		igniter = new AltosIgnitor();  		sitemap = new AltosUIMap(); diff --git a/altosui/AltosIgnitor.java b/altosui/AltosIgnitor.java index fabf4320..09dcdf93 100644 --- a/altosui/AltosIgnitor.java +++ b/altosui/AltosIgnitor.java @@ -27,59 +27,59 @@ import org.altusmetrum.altosuilib_11.*;  public class AltosIgnitor extends AltosUIFlightTab {  	public class Ignitor extends AltosUIUnitsIndicator { -		int		ignitor; +		int		igniter;  		public double value(AltosState state, int i) { -			if (state.ignitor_voltage == null || -			    state.ignitor_voltage.length < ignitor) +			if (state.igniter_voltage == null || +			    state.igniter_voltage.length < igniter)  				return AltosLib.MISSING; -			return state.ignitor_voltage[ignitor]; +			return state.igniter_voltage[igniter];  		}  		public double good() { return AltosLib.ao_igniter_good; }  		public Ignitor (AltosUIFlightTab container, int y) { -			super(container, y, AltosConvert.voltage, String.format ("%s Voltage", AltosLib.ignitor_name(y)), 1, true, 1); -			ignitor = y; +			super(container, y, AltosConvert.voltage, String.format ("%s Voltage", AltosLib.igniter_name(y)), 1, true, 1); +			igniter = y;  		}  	} -	Ignitor[] ignitors; +	Ignitor[] igniters;  	public void show(AltosState state, AltosListenerState listener_state) {  		if (isShowing()) -			make_ignitors(state); +			make_igniters(state);  		super.show(state, listener_state);  	}  	public boolean should_show(AltosState state) {  		if (state == null)  			return false; -		if (state.ignitor_voltage == null) +		if (state.igniter_voltage == null)  			return false; -		return state.ignitor_voltage.length > 0; +		return state.igniter_voltage.length > 0;  	} -	void make_ignitors(AltosState state) { -		int n = (state == null || state.ignitor_voltage == null) ? 0 : state.ignitor_voltage.length; -		int old_n = ignitors == null ? 0 : ignitors.length; +	void make_igniters(AltosState state) { +		int n = (state == null || state.igniter_voltage == null) ? 0 : state.igniter_voltage.length; +		int old_n = igniters == null ? 0 : igniters.length;  		if (n != old_n) { -			if (ignitors != null) { -				for (int i = 0; i < ignitors.length; i++) { -					remove(ignitors[i]); -					ignitors[i].remove(this); -					ignitors = null; +			if (igniters != null) { +				for (int i = 0; i < igniters.length; i++) { +					remove(igniters[i]); +					igniters[i].remove(this); +					igniters = null;  				}  			}  			if (n > 0) {  				setVisible(true); -				ignitors = new Ignitor[n]; +				igniters = new Ignitor[n];  				for (int i = 0; i < n; i++) { -					ignitors[i] = new Ignitor(this, i); -					add(ignitors[i]); +					igniters[i] = new Ignitor(this, i); +					add(igniters[i]);  				}  			} else  				setVisible(false); diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index a6e422e6..b0cff381 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -327,7 +327,7 @@ public class AltosUI extends AltosUIFrame {  	}  	private static AltosFlightSeries make_series(AltosRecordSet set) { -		AltosFlightSeries series = new AltosFlightSeries(new AltosCalData()); +		AltosFlightSeries series = new AltosFlightSeries(set.cal_data());  		set.capture_series(series);  		return series;  	} diff --git a/altosuilib/AltosGraphNew.java b/altosuilib/AltosGraphNew.java index dc5b7e47..a9393f94 100644 --- a/altosuilib/AltosGraphNew.java +++ b/altosuilib/AltosGraphNew.java @@ -52,6 +52,8 @@ public class AltosGraphNew extends AltosUIGraphNew {  	static final private Color battery_voltage_color = new Color(194, 194, 31);  	static final private Color drogue_voltage_color = new Color(150, 150, 31);  	static final private Color main_voltage_color = new Color(100, 100, 31); +	static final private Color igniter_voltage_color = new Color(80, 80, 31); +	static final private Color igniter_marker_color = new Color(255, 0, 0);  	static final private Color gps_nsat_color = new Color (194, 31, 194);  	static final private Color gps_nsat_solution_color = new Color (194, 31, 194);  	static final private Color gps_nsat_view_color = new Color (150, 31, 150); @@ -65,25 +67,17 @@ public class AltosGraphNew extends AltosUIGraphNew {  	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); -	static final private Color accel_x_color = new Color(255, 0, 0); -	static final private Color accel_y_color = new Color(0, 255, 0); -	static final private Color accel_z_color = new Color(0, 0, 255); -	static final private Color gyro_x_color = new Color(192, 0, 0); -	static final private Color gyro_y_color = new Color(0, 192, 0); -	static final private Color gyro_z_color = new Color(0, 0, 192); -	static final private Color mag_x_color = new Color(128, 0, 0); -	static final private Color mag_y_color = new Color(0, 128, 0); -	static final private Color mag_z_color = new Color(0, 0, 128); +	static final private Color accel_along_color = new Color(255, 0, 0); +	static final private Color accel_across_color = new Color(0, 255, 0); +	static final private Color accel_through_color = new Color(0, 0, 255); +	static final private Color gyro_roll_color = new Color(192, 0, 0); +	static final private Color gyro_pitch_color = new Color(0, 192, 0); +	static final private Color gyro_yaw_color = new Color(0, 0, 192); +	static final private Color mag_along_color = new Color(128, 0, 0); +	static final private Color mag_across_color = new Color(0, 128, 0); +	static final private Color mag_through_color = new Color(0, 0, 128);  	static final private Color orient_color = new Color(31, 31, 31); -//	static AltosNsat nsat_units = new AltosNsat(); -	static AltosUnits nsat_units = null; -//	static AltosDbm dbm_units = new AltosDbm(); -	static AltosUnits dbm_units = null; -	static AltosOrient orient_units = new AltosOrient(); -//	static AltosMagUnits mag_units = new AltosMagUnits(); -	static AltosUnits mag_units = null; -//	static AltosDopUnits dop_units = new AltosDopUnits();  	static AltosUnits dop_units = null;  	AltosUIFlightSeries flight_series; @@ -102,15 +96,15 @@ public class AltosGraphNew extends AltosUIGraphNew {  		accel_axis = newAxis("Acceleration", AltosConvert.accel, accel_color);  		voltage_axis = newAxis("Voltage", AltosConvert.voltage, voltage_color);  		temperature_axis = newAxis("Temperature", AltosConvert.temperature, temperature_color, 0); -		nsat_axis = newAxis("Satellites", nsat_units, gps_nsat_color, +		nsat_axis = newAxis("Satellites", null, gps_nsat_color,  				    AltosUIAxis.axis_include_zero | AltosUIAxis.axis_integer); -		dbm_axis = newAxis("Signal Strength", dbm_units, dbm_color, 0); +		dbm_axis = newAxis("Signal Strength", null, dbm_color, 0);  		distance_axis = newAxis("Distance", AltosConvert.distance, range_color); -		gyro_axis = newAxis("Rotation Rate", AltosConvert.rotation_rate, gyro_z_color, 0); -		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); +		gyro_axis = newAxis("Rotation Rate", AltosConvert.rotation_rate, gyro_roll_color, 0); +		orient_axis = newAxis("Tilt Angle", AltosConvert.orient, orient_color, 0); +		mag_axis = newAxis("Magnetic Field", AltosConvert.magnetic_field, mag_along_color, 0); +		course_axis = newAxis("Course", AltosConvert.orient, gps_course_color, 0);  		dop_axis = newAxis("Dilution of Precision", dop_units, gps_pdop_color, 0);  		flight_series.register_axis("default", @@ -121,7 +115,14 @@ public class AltosGraphNew extends AltosUIGraphNew {  		flight_series.register_marker(AltosUIFlightSeries.state_name,  					      state_color,  					      true, -					      plot); +					      plot, +					      true); + +		flight_series.register_marker(AltosUIFlightSeries.pyro_fired_name, +					      igniter_marker_color, +					      true, +					      plot, +					      false);  		flight_series.register_axis(AltosUIFlightSeries.accel_name,  					    accel_color, @@ -164,17 +165,50 @@ public class AltosGraphNew extends AltosUIGraphNew {  					    height_axis); +		flight_series.register_axis(AltosUIFlightSeries.temperature_name, +					    temperature_color, +					    false, +					    temperature_axis); + +		flight_series.register_axis(AltosUIFlightSeries.battery_voltage_name, +					    battery_voltage_color, +					    false, +					    voltage_axis); + +		flight_series.register_axis(AltosUIFlightSeries.apogee_voltage_name, +					    drogue_voltage_color, +					    false, +					    voltage_axis); + +		flight_series.register_axis(AltosUIFlightSeries.main_voltage_name, +					    main_voltage_color, +					    false, +					    voltage_axis); +  		flight_series.register_axis(AltosUIFlightSeries.sats_in_view_name,  					    gps_nsat_view_color,  					    false,  					    nsat_axis); -  		flight_series.register_axis(AltosUIFlightSeries.sats_in_soln_name,  					    gps_nsat_solution_color,  					    false,  					    nsat_axis); +		flight_series.register_axis(AltosUIFlightSeries.gps_pdop_name, +					    gps_pdop_color, +					    false, +					    dop_axis); + +		flight_series.register_axis(AltosUIFlightSeries.gps_hdop_name, +					    gps_hdop_color, +					    false, +					    dop_axis); + +		flight_series.register_axis(AltosUIFlightSeries.gps_vdop_name, +					    gps_vdop_color, +					    false, +					    dop_axis);  		flight_series.register_axis(AltosUIFlightSeries.gps_altitude_name,  					    gps_height_color, @@ -191,13 +225,11 @@ public class AltosGraphNew extends AltosUIGraphNew {  					    false,  					    speed_axis); -  		flight_series.register_axis(AltosUIFlightSeries.gps_ascent_rate_name,  					    gps_climb_rate_color,  					    false,  					    speed_axis); -  		flight_series.register_axis(AltosUIFlightSeries.gps_course_name,  					    gps_course_color,  					    false, @@ -208,246 +240,69 @@ public class AltosGraphNew extends AltosUIGraphNew {  					    false,  					    speed_axis); +		flight_series.register_axis(AltosUIFlightSeries.accel_along_name, +					    accel_along_color, +					    false, +					    accel_axis); + +		flight_series.register_axis(AltosUIFlightSeries.accel_across_name, +					    accel_across_color, +					    false, +					    accel_axis); + +		flight_series.register_axis(AltosUIFlightSeries.accel_through_name, +					    accel_through_color, +					    false, +					    accel_axis); + +		flight_series.register_axis(AltosUIFlightSeries.gyro_roll_name, +					    gyro_roll_color, +					    false, +					    gyro_axis); + +		flight_series.register_axis(AltosUIFlightSeries.gyro_pitch_name, +					    gyro_pitch_color, +					    false, +					    gyro_axis); + +		flight_series.register_axis(AltosUIFlightSeries.gyro_yaw_name, +					    gyro_yaw_color, +					    false, +					    gyro_axis); + +		flight_series.register_axis(AltosUIFlightSeries.mag_along_name, +					    mag_along_color, +					    false, +					    mag_axis); + +		flight_series.register_axis(AltosUIFlightSeries.mag_across_name, +					    mag_across_color, +					    false, +					    mag_axis); + +		flight_series.register_axis(AltosUIFlightSeries.mag_through_name, +					    mag_through_color, +					    false, +					    mag_axis); + +		flight_series.register_axis(AltosUIFlightSeries.orient_name, +					    orient_color, +					    false, +					    orient_axis); + +		for (int channel = 0; channel < 26; channel++) { +			flight_series.register_axis(flight_series.igniter_voltage_name(channel), +						    igniter_voltage_color, +						    false, +						    voltage_axis); +		} +  		flight_series.register_axis(AltosUIFlightSeries.thrust_name,  					    thrust_color,  					    true,  					    thrust_axis); -//		addMarker("State", AltosGraphDataPoint.data_state, state_color); -  		return flight_series.series(cal_data); -/* -		if (stats.has_flight_data) { -			addSeries("Height", -				  AltosGraphDataPoint.data_height, -				  AltosConvert.height, -				  height_color, -				  true, -				  height_axis); -			addSeries("Pressure", -				  AltosGraphDataPoint.data_pressure, -				  pressure_units, -				  pressure_color, -				  false, -				  pressure_axis); -			addSeries("Thrust", -				  AltosGraphDataPoint.data_thrust, -				  thrust_units, -				  thrust_color, -				  false, -				  thrust_axis); -			addSeries("Speed", -				  AltosGraphDataPoint.data_speed, -				  AltosConvert.speed, -				  speed_color, -				  true, -				  speed_axis); -			addSeries("Acceleration", -				  AltosGraphDataPoint.data_accel, -				  AltosConvert.accel, -				  accel_color, -				  true, -				  accel_axis); -		} -		if (stats.has_gps) { -			boolean	enable_gps = false; - -			if (!stats.has_flight_data) -				enable_gps = true; - -			addSeries("Range", -				  AltosGraphDataPoint.data_range, -				  AltosConvert.distance, -				  range_color, -				  false, -				  distance_axis); -			addSeries("Distance", -				  AltosGraphDataPoint.data_distance, -				  AltosConvert.distance, -				  distance_color, -				  enable_gps, -				  distance_axis); -			addSeries("GPS Height", -				  AltosGraphDataPoint.data_gps_height, -				  AltosConvert.height, -				  gps_height_color, -				  enable_gps, -				  height_axis); -			addSeries("GPS Altitude", -				  AltosGraphDataPoint.data_gps_altitude, -				  AltosConvert.height, -				  gps_height_color, -				  false, -				  height_axis); -			addSeries("GPS Satellites in Solution", -				  AltosGraphDataPoint.data_gps_nsat_solution, -				  nsat_units, -				  gps_nsat_solution_color, -				  false, -				  nsat_axis); -			if (stats.has_gps_sats) { -				addSeries("GPS Satellites in View", -					  AltosGraphDataPoint.data_gps_nsat_view, -					  nsat_units, -					  gps_nsat_view_color, -					  false, -					  nsat_axis); -			} -			if (stats.has_gps_detail) { -				addSeries("GPS Course", -					  AltosGraphDataPoint.data_gps_course, -					  orient_units, -					  gps_course_color, -					  false, -					  course_axis); -				addSeries("GPS Ground Speed", -					  AltosGraphDataPoint.data_gps_ground_speed, -					  AltosConvert.speed, -					  gps_ground_speed_color, -					  enable_gps, -					  speed_axis); -				addSeries("GPS Climb Rate", -					  AltosGraphDataPoint.data_gps_climb_rate, -					  AltosConvert.speed, -					  gps_climb_rate_color, -					  enable_gps, -					  speed_axis); -			} -			addSeries("GPS Position DOP", -				  AltosGraphDataPoint.data_gps_pdop, -				  dop_units, -				  gps_pdop_color, -				  false, -				  dop_axis); -			if (stats.has_gps_detail) { -				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", -				  AltosGraphDataPoint.data_rssi, -				  dbm_units, -				  dbm_color, -				  false, -				  dbm_axis); - -		if (stats.has_battery) -			addSeries("Battery Voltage", -				  AltosGraphDataPoint.data_battery_voltage, -				  voltage_units, -				  battery_voltage_color, -				  false, -				  voltage_axis); - -		if (stats.has_flight_adc) { -			addSeries("Temperature", -				  AltosGraphDataPoint.data_temperature, -				  AltosConvert.temperature, -				  temperature_color, -				  false, -				  temperature_axis); -			addSeries("Drogue Voltage", -				  AltosGraphDataPoint.data_drogue_voltage, -				  voltage_units, -				  drogue_voltage_color, -				  false, -				  voltage_axis); -			addSeries("Main Voltage", -				  AltosGraphDataPoint.data_main_voltage, -				  voltage_units, -				  main_voltage_color, -				  false, -				  voltage_axis); -		} - -		if (stats.has_imu) { -			addSeries("Acceleration Along", -				  AltosGraphDataPoint.data_accel_along, -				  AltosConvert.accel, -				  accel_x_color, -				  false, -				  accel_axis); -			addSeries("Acceleration Across", -				  AltosGraphDataPoint.data_accel_across, -				  AltosConvert.accel, -				  accel_y_color, -				  false, -				  accel_axis); -			addSeries("Acceleration Through", -				  AltosGraphDataPoint.data_accel_through, -				  AltosConvert.accel, -				  accel_z_color, -				  false, -				  accel_axis); -			addSeries("Roll Rate", -				  AltosGraphDataPoint.data_gyro_roll, -				  gyro_units, -				  gyro_x_color, -				  false, -				  gyro_axis); -			addSeries("Pitch Rate", -				  AltosGraphDataPoint.data_gyro_pitch, -				  gyro_units, -				  gyro_y_color, -				  false, -				  gyro_axis); -			addSeries("Yaw Rate", -				  AltosGraphDataPoint.data_gyro_yaw, -				  gyro_units, -				  gyro_z_color, -				  false, -				  gyro_axis); -		} -		if (stats.has_mag) { -			addSeries("Magnetometer Along", -				  AltosGraphDataPoint.data_mag_along, -				  mag_units, -				  mag_x_color, -				  false, -				  mag_axis); -			addSeries("Magnetometer Across", -				  AltosGraphDataPoint.data_mag_across, -				  mag_units, -				  mag_y_color, -				  false, -				  mag_axis); -			addSeries("Magnetometer Through", -				  AltosGraphDataPoint.data_mag_through, -				  mag_units, -				  mag_z_color, -				  false, -				  mag_axis); -		} -		if (stats.has_orient) -			addSeries("Tilt Angle", -				  AltosGraphDataPoint.data_orient, -				  orient_units, -				  orient_color, -				  false, -				  orient_axis); -		if (stats.num_ignitor > 0) { -			for (int i = 0; i < stats.num_ignitor; i++) -				addSeries(AltosLib.ignitor_name(i), -					  AltosGraphDataPoint.data_ignitor_0 + i, -					  voltage_units, -					  main_voltage_color, -					  false, -					  voltage_axis); -			for (int i = 0; i < stats.num_ignitor; i++) -				addMarker(AltosLib.ignitor_name(i), AltosGraphDataPoint.data_ignitor_fired_0 + i, state_color); -		} -*/  	}  	public AltosGraphNew(AltosUIEnable enable, AltosFlightStats stats, AltosUIFlightSeries flight_series, AltosCalData cal_data) { diff --git a/altosuilib/AltosUIFlightSeries.java b/altosuilib/AltosUIFlightSeries.java index 1840761e..0bcc8a6e 100644 --- a/altosuilib/AltosUIFlightSeries.java +++ b/altosuilib/AltosUIFlightSeries.java @@ -33,15 +33,17 @@ class AltosUITimeSeriesAxis {  	Color		color;  	boolean		enabled;  	boolean		marker; +	boolean		marker_top;  	AltosUIAxis	axis;  	XYPlot		plot; -	public AltosUITimeSeriesAxis(Color color, boolean enabled, AltosUIAxis axis, XYPlot plot, boolean marker) { +	public AltosUITimeSeriesAxis(Color color, boolean enabled, AltosUIAxis axis, XYPlot plot, boolean marker, boolean marker_top) {  		this.color = color;  		this.enabled = enabled;  		this.axis = axis;  		this.plot = plot;  		this.marker = marker; +		this.marker_top = marker_top;  	}  } @@ -57,7 +59,7 @@ public class AltosUIFlightSeries extends AltosFlightSeries {  			if (label.equals(ts.label) || (label.equals("default") && uts.color == null)) {  				if (axis.marker) -					uts.set_marker(axis.color, axis.enabled, axis.plot); +					uts.set_marker(axis.color, axis.enabled, axis.plot, axis.marker_top);  				else  					uts.set_axis(axis.color, axis.enabled, axis.axis);  			} @@ -72,6 +74,7 @@ public class AltosUIFlightSeries extends AltosFlightSeries {  								      enabled,  								      axis,  								      null, +								      false,  								      false);  		axes.put(label, tsa);  		fill_axes(label, tsa); @@ -80,12 +83,14 @@ public class AltosUIFlightSeries extends AltosFlightSeries {  	public void register_marker(String label,  				    Color color,  				    boolean enabled, -				    XYPlot plot) { +				    XYPlot plot, +				    boolean marker_top) {  		AltosUITimeSeriesAxis tsa = new AltosUITimeSeriesAxis(color,  								      enabled,  								      null,  								      plot, -								      true); +								      true, +								      marker_top);  		axes.put(label, tsa);  		fill_axes(label, tsa);  	} @@ -100,7 +105,7 @@ public class AltosUIFlightSeries extends AltosFlightSeries {  			tsa = axes.get("default");  		if (tsa != null) {  			if (tsa.marker) -				time_series.set_marker(tsa.color, tsa.enabled, tsa.plot); +				time_series.set_marker(tsa.color, tsa.enabled, tsa.plot, tsa.marker_top);  			else  				time_series.set_axis(tsa.color, tsa.enabled, tsa.axis);  		} diff --git a/altosuilib/AltosUITimeSeries.java b/altosuilib/AltosUITimeSeries.java index 0f5e35eb..7c48264e 100644 --- a/altosuilib/AltosUITimeSeries.java +++ b/altosuilib/AltosUITimeSeries.java @@ -47,6 +47,7 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher  	boolean		enable;  	AltosUIAxis	axis;  	boolean		marker; +	boolean		marker_top;  	XYItemRenderer	renderer;  	XYPlot		plot;  	AltosXYSeries	xy_series; @@ -81,8 +82,13 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher  				String s = units.string_value(v.value);  				ValueMarker marker = new ValueMarker(v.time);  				marker.setLabel(s); -				marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT); -				marker.setLabelTextAnchor(TextAnchor.TOP_LEFT); +				if (marker_top) { +					marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT); +					marker.setLabelTextAnchor(TextAnchor.TOP_LEFT); +				} else { +					marker.setLabelAnchor(RectangleAnchor.BOTTOM_RIGHT); +					marker.setLabelTextAnchor(TextAnchor.BOTTOM_LEFT); +				}  				marker.setPaint(color);  				if (enable)  					plot.addDomainMarker(marker); @@ -91,12 +97,14 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher  		} else {  			xy_series.clear(); +			xy_series.setNotify(false);  			for (AltosTimeValue v : this) {  				double value = v.value;  				if (units != null)  					value = units.graph_value(value);  				xy_series.add(v.time, value);  			} +			xy_series.setNotify(true);  		}  	} @@ -153,11 +161,12 @@ public class AltosUITimeSeries extends AltosTimeSeries implements AltosUIGrapher  		xy_series = new AltosXYSeries(label);  	} -	public void set_marker(Color color, boolean enable, XYPlot plot) { +	public void set_marker(Color color, boolean enable, XYPlot plot, boolean marker_top) {  		this.color = color;  		this.enable = enable;  		this.marker = true;  		this.plot = plot; +		this.marker_top = marker_top;  	}  	public AltosUITimeSeries(String label, AltosUnits units) { | 
