diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/kernel/ao_flight.c | 6 | ||||
| -rw-r--r-- | src/kernel/ao_kalman.c | 35 | ||||
| -rw-r--r-- | src/kernel/ao_sample.c | 2 | ||||
| -rw-r--r-- | src/kernel/ao_sample.h | 9 | ||||
| -rw-r--r-- | src/test/ao_flight_test.c | 81 | ||||
| -rwxr-xr-x | src/test/plottest | 13 | 
6 files changed, 92 insertions, 54 deletions
diff --git a/src/kernel/ao_flight.c b/src/kernel/ao_flight.c index 50f2b68f..f06125cd 100644 --- a/src/kernel/ao_flight.c +++ b/src/kernel/ao_flight.c @@ -269,7 +269,7 @@ ao_flight(void)  			 * number of seconds.  			 */  			if (ao_config.apogee_lockout) { -				if ((ao_sample_tick - ao_boost_tick) < +				if ((int16_t) (ao_sample_tick - ao_boost_tick) <  				    AO_SEC_TO_TICKS(ao_config.apogee_lockout))  					break;  			} @@ -282,9 +282,11 @@ ao_flight(void)  			 * the measured altitude reasonably closely; otherwise  			 * we're probably transsonic.  			 */ +#define AO_ERROR_BOUND	100 +  			if (ao_speed < 0  #if !HAS_ACCEL -			    && (ao_sample_alt >= AO_MAX_BARO_HEIGHT || ao_error_h_sq_avg < 100) +			    && (ao_sample_alt >= AO_MAX_BARO_HEIGHT || ao_error_h_sq_avg < AO_ERROR_BOUND)  #endif  				)  			{ diff --git a/src/kernel/ao_kalman.c b/src/kernel/ao_kalman.c index 69a1b3de..ac41085d 100644 --- a/src/kernel/ao_kalman.c +++ b/src/kernel/ao_kalman.c @@ -45,7 +45,9 @@ static __pdata ao_k_t		ao_avg_height_scaled;  __xdata ao_v_t			ao_avg_height;  __pdata ao_v_t			ao_error_h; +#if !HAS_ACCEL  __pdata ao_v_t			ao_error_h_sq_avg; +#endif  #if HAS_ACCEL  __pdata ao_v_t			ao_error_a; @@ -55,14 +57,14 @@ static void  ao_kalman_predict(void)  {  #ifdef AO_FLIGHT_TEST -	if (ao_sample_tick - ao_sample_prev_tick > 50) { +	if ((int16_t) (ao_sample_tick - ao_sample_prev_tick) > 50) {  		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) { +	if ((int16_t) (ao_sample_tick - ao_sample_prev_tick) > 5) {  		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; @@ -83,7 +85,9 @@ ao_kalman_predict(void)  static void  ao_kalman_err_height(void)  { +#if !HAS_ACCEL  	ao_v_t	e; +#endif  	ao_v_t height_distrust;  #if HAS_ACCEL  	ao_v_t	speed_distrust; @@ -91,15 +95,12 @@ ao_kalman_err_height(void)  	ao_error_h = ao_sample_height - (ao_v_t) (ao_k_height >> 16); +#if !HAS_ACCEL  	e = ao_error_h;  	if (e < 0)  		e = -e;  	if (e > 127)  		e = 127; -#if HAS_ACCEL -	ao_error_h_sq_avg -= ao_error_h_sq_avg >> 2; -	ao_error_h_sq_avg += (e * e) >> 2; -#else  	ao_error_h_sq_avg -= ao_error_h_sq_avg >> 4;  	ao_error_h_sq_avg += (e * e) >> 4;  #endif @@ -108,13 +109,13 @@ ao_kalman_err_height(void)  		return;  	height_distrust = ao_sample_alt - AO_MAX_BARO_HEIGHT;  #if HAS_ACCEL -	/* speed is stored * 16, but we need to ramp between 200 and 328, so +	/* speed is stored * 16, but we need to ramp between 248 and 328, so  	 * we want to multiply by 2. The result is a shift by 3.  	 */  	speed_distrust = (ao_speed - AO_MS_TO_SPEED(AO_MAX_BARO_SPEED)) >> (4 - 1); -	if (speed_distrust <= 0) -		speed_distrust = 0; -	else if (speed_distrust > height_distrust) +	if (speed_distrust > AO_MAX_SPEED_DISTRUST) +		speed_distrust = AO_MAX_SPEED_DISTRUST; +	if (speed_distrust > height_distrust)  		height_distrust = speed_distrust;  #endif  	if (height_distrust > 0) { @@ -141,13 +142,13 @@ ao_kalman_correct_baro(void)  {  	ao_kalman_err_height();  #ifdef AO_FLIGHT_TEST -	if (ao_sample_tick - ao_sample_prev_tick > 50) { +	if ((int16_t) (ao_sample_tick - ao_sample_prev_tick) > 50) {  		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) { +	if ((int16_t) (ao_sample_tick - ao_sample_prev_tick) > 5) {  		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; @@ -180,7 +181,7 @@ ao_kalman_correct_both(void)  	ao_kalman_err_accel();  #ifdef AO_FLIGHT_TEST -	if (ao_sample_tick - ao_sample_prev_tick > 50) { +	if ((int16_t) (ao_sample_tick - ao_sample_prev_tick) > 50) {  		if (ao_flight_debug) {  			printf ("correct speed %g + (%g * %g) + (%g * %g) = %g\n",  				ao_k_speed / (65536.0 * 16.0), @@ -201,7 +202,7 @@ ao_kalman_correct_both(void)  			(ao_k_t) AO_BOTH_K21_1 * ao_error_a;  		return;  	} -	if (ao_sample_tick - ao_sample_prev_tick > 5) { +	if ((int16_t) (ao_sample_tick - ao_sample_prev_tick) > 5) {  		if (ao_flight_debug) {  			printf ("correct speed %g + (%g * %g) + (%g * %g) = %g\n",  				ao_k_speed / (65536.0 * 16.0), @@ -250,7 +251,7 @@ ao_kalman_correct_accel(void)  {  	ao_kalman_err_accel(); -	if (ao_sample_tick - ao_sample_prev_tick > 5) { +	if ((int16_t) (ao_sample_tick - ao_sample_prev_tick) > 5) {  		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; @@ -285,9 +286,9 @@ ao_kalman(void)  		ao_max_height = ao_height;  	ao_avg_height_scaled = ao_avg_height_scaled - ao_avg_height + ao_sample_height;  #ifdef AO_FLIGHT_TEST -	if (ao_sample_tick - ao_sample_prev_tick > 50) +	if ((int16_t) (ao_sample_tick - ao_sample_prev_tick) > 50)  		ao_avg_height = (ao_avg_height_scaled + 1) >> 1; -	else if (ao_sample_tick - ao_sample_prev_tick > 5) +	else if ((int16_t) (ao_sample_tick - ao_sample_prev_tick) > 5)  		ao_avg_height = (ao_avg_height_scaled + 7) >> 4;  	else   #endif diff --git a/src/kernel/ao_sample.c b/src/kernel/ao_sample.c index 90ea07ad..f0ab0169 100644 --- a/src/kernel/ao_sample.c +++ b/src/kernel/ao_sample.c @@ -180,7 +180,7 @@ static void  ao_sample_rotate(void)  {  #ifdef AO_FLIGHT_TEST -	float	dt = (ao_sample_tick - ao_sample_prev_tick) / TIME_DIV; +	float	dt = (int16_t) (ao_sample_tick - ao_sample_prev_tick) / TIME_DIV;  #else  	static const float dt = 1/TIME_DIV;  #endif diff --git a/src/kernel/ao_sample.h b/src/kernel/ao_sample.h index da40187b..fbef031d 100644 --- a/src/kernel/ao_sample.h +++ b/src/kernel/ao_sample.h @@ -95,7 +95,12 @@ typedef int16_t			ao_v_t;  /*   * Above this speed, baro measurements are unreliable   */ -#define AO_MAX_BARO_SPEED	200 +#define AO_MAX_BARO_SPEED	248 + +/* The maximum amount (in a range of 0-256) to de-rate the + * baro sensor data based on speed. + */ +#define AO_MAX_SPEED_DISTRUST	160  #define ACCEL_NOSE_UP	(ao_accel_2g >> 2) @@ -175,7 +180,9 @@ 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 ao_v_t			ao_error_h; +#if !HAS_ACCEL  extern __pdata ao_v_t			ao_error_h_sq_avg; +#endif  #if HAS_ACCEL  extern __pdata ao_v_t			ao_error_a; diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index d3d39f2a..55bfe410 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -72,7 +72,7 @@ struct ao_adc {  #define AO_ADC_NUM_SENSE	2  #define HAS_MS5607		1  #define HAS_MMA655X		1 -#define AO_MMA655X_INVERT	1 +#define AO_MMA655X_INVERT	0  #define HAS_BEEP		1  #define AO_CONFIG_MAX_SIZE	1024 @@ -264,6 +264,7 @@ double	main_time;  int	tick_offset;  static ao_k_t	ao_k_height; +static double	simple_speed;  int16_t  ao_time(void) @@ -320,7 +321,7 @@ ao_dump_state(void);  void  ao_sleep(void *wchan); -const char const * const ao_state_names[] = { +const char * const ao_state_names[] = {  	"startup", "idle", "pad", "boost", "fast",  	"coast", "drogue", "main", "landed", "invalid"  }; @@ -361,6 +362,9 @@ extern int16_t ao_accel_2g;  typedef int16_t	accel_t; +uint16_t	ao_serial_number; +uint16_t	ao_flight_number; +  extern uint16_t	ao_sample_tick;  extern alt_t	ao_sample_height; @@ -479,7 +483,6 @@ ao_insert(void)  	double	time;  	ao_data_ring[ao_data_head] = ao_data_static; -	ao_data_head = ao_data_ring_next(ao_data_head);  	if (ao_flight_state != ao_flight_startup) {  #if HAS_ACCEL  		double  accel = ((ao_flight_ground_accel - ao_data_accel_cook(&ao_data_static)) * GRAVITY * 2.0) / @@ -487,23 +490,37 @@ ao_insert(void)  #else  		double	accel = 0.0;  #endif -#if TELEMEGA || TELEMETRUM_V2 || EASYMINI -		double	height; - -		ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked); -		height = ao_pa_to_altitude(ao_data_static.ms5607_cooked.pres) - ao_ground_height; -#else -		double	height = ao_pres_to_altitude(ao_data_static.adc.pres_real) - ao_ground_height; -#endif  		(void) accel;  		if (!tick_offset)  			tick_offset = -ao_data_static.tick;  		if ((prev_tick - ao_data_static.tick) > 0x400)  			tick_offset += 65536; +		simple_speed += accel * (ao_data_static.tick - prev_tick) / 100.0;  		prev_tick = ao_data_static.tick;  		time = (double) (ao_data_static.tick + tick_offset) / 100; +#if TELEMEGA || TELEMETRUM_V2 || EASYMINI +		ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked); +		double height = ao_pa_to_altitude(ao_data_static.ms5607_cooked.pres) - ao_ground_height; + +		/* Hack to skip baro spike at accidental drogue charge +		 * firing in 2015-09-26-serial-2093-flight-0012.eeprom +		 * so we can test the kalman filter with this data. Just +		 * keep reporting the same baro value across the pressure spike +		 */ +		{ +			static struct ao_ms5607_sample save; +			if (ao_serial_number == 2093 && ao_flight_number == 12 && 32.5 < time && time < 33.7) { +				ao_data_ring[ao_data_head].ms5607_raw = save; +			} else { +				save = ao_data_static.ms5607_raw; +			} +		} +#else +		double	height = ao_pres_to_altitude(ao_data_static.adc.pres_real) - ao_ground_height; +#endif +  		if (ao_test_max_height < height) {  			ao_test_max_height = height;  			ao_test_max_height_time = time; @@ -616,17 +633,27 @@ ao_insert(void)  #endif  #if 1 -			printf("%7.2f height %8.2f accel %8.3f " -#if TELEMEGA && 1 -			       "angle %5d " +			printf("%7.2f height %8.2f accel %8.3f accel_speed %8.3f " +			       "state %-8.8s k_height %8.2f k_speed %8.3f k_accel %8.3f avg_height %5d drogue %4d main %4d error %5d" +#if TELEMEGA +			       " 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 -			       "state %-8.8s k_height %8.2f k_speed %8.3f k_accel %8.3f avg_height %5d drogue %4d main %4d error %5d\n", +			       "\n",  			       time,  			       height,  			       accel, -#if TELEMEGA && 1 -			       ao_sample_orient, +			       simple_speed > -100.0 ? simple_speed : -100.0, +			       ao_state_names[ao_flight_state], +			       ao_k_height / 65536.0, +			       ao_k_speed / 65536.0 / 16.0, +			       ao_k_accel / 65536.0 / 16.0, +			       ao_avg_height, +			       drogue_height, +			       main_height, +			       ao_error_h_sq_avg +#if TELEMEGA +			       , ao_sample_orient,  			       ao_mpu6000_accel(ao_data_static.mpu6000.accel_x),  			       ao_mpu6000_accel(ao_data_static.mpu6000.accel_y), @@ -637,22 +664,16 @@ ao_insert(void)  			       ao_data_static.hmc5883.x,  			       ao_data_static.hmc5883.y,  			       ao_data_static.hmc5883.z, -			       ao_mag_angle, +			       ao_mag_angle  #endif -			       ao_state_names[ao_flight_state], -			       ao_k_height / 65536.0, -			       ao_k_speed / 65536.0 / 16.0, -			       ao_k_accel / 65536.0 / 16.0, -			       ao_avg_height, -			       drogue_height, -			       main_height, -			       ao_error_h_sq_avg); +				);  #endif -			 +  //			if (ao_flight_state == ao_flight_landed)  //				ao_test_exit();  		}  	} +	ao_data_head = ao_data_ring_next(ao_data_head);  } @@ -763,6 +784,7 @@ ao_sleep(void *wchan)  //				printf ("\n");  				switch (type) {  				case 'F': +					ao_flight_number = uint16(bytes, 0);  					ao_flight_ground_accel = int16(bytes, 2);  					ao_flight_started = 1;  					ao_ground_pres = int32(bytes, 4); @@ -872,6 +894,7 @@ ao_sleep(void *wchan)  				switch (type) {  				case 'F':  					ao_flight_started = 1; +					ao_flight_number = uint16(bytes, 0);  					ao_ground_pres = uint32(bytes, 4);  					ao_ground_height = ao_pa_to_altitude(ao_ground_pres);  #if 0 @@ -937,6 +960,7 @@ ao_sleep(void *wchan)  //				printf ("\n");  				switch (type) {  				case 'F': +					ao_flight_number = uint16(bytes, 0);  					ao_flight_ground_accel = int16(bytes, 2);  					ao_flight_started = 1;  					ao_ground_pres = int32(bytes, 4); @@ -985,6 +1009,8 @@ ao_sleep(void *wchan)  #endif  			else if (nword == 2 && strcmp(words[0], "log-format") == 0) {  				log_format = strtoul(words[1], NULL, 10); +			} else if (nword == 2 && strcmp(words[0], "serial-number") == 0) { +				ao_serial_number = strtoul(words[1], NULL, 10);  			} else if (nword >= 6 && strcmp(words[0], "Accel") == 0) {  				ao_config.accel_plus_g = atoi(words[3]);  				ao_config.accel_minus_g = atoi(words[5]); @@ -1107,6 +1133,7 @@ ao_sleep(void *wchan)  			switch (type) {  			case 'F':  				ao_flight_ground_accel = a; +				ao_flight_number = b;  				if (ao_config.accel_plus_g == 0) {  					ao_config.accel_plus_g = a;  					ao_config.accel_minus_g = a + 530; diff --git a/src/test/plottest b/src/test/plottest index 7d253ff1..95337f10 100755 --- a/src/test/plottest +++ b/src/test/plottest @@ -7,10 +7,11 @@ set ytics border out nomirror  set y2tics border out nomirror  plot "$1" using 1:3 with lines axes x1y1 title "raw height",\  "$1" using 1:5 with lines axes x1y2 title "raw accel",\ -"$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: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" +"$1" using 1:7 with lines axes x1y2 title "accel speed",\ +"$1" using 1:11 with lines axes x1y1 title "height",\ +"$1" using 1:13 with lines axes x1y2 title "speed",\ +"$1" using 1:15 with lines axes x1y2 title "accel",\ +"$1" using 1:19 with lines axes x1y1 title "drogue",\ +"$1" using 1:21 with lines axes x1y1 title "main",\ +"$1" using 1:23 with lines axes x1y1 title "error"  EOF  | 
