diff options
Diffstat (limited to 'src/kernel/ao_kalman.c')
| -rw-r--r-- | src/kernel/ao_kalman.c | 147 | 
1 files changed, 73 insertions, 74 deletions
| 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 */ | 
