Пример #1
0
void Mat_scale ( ) {
	uint32_t  R1 = 0;
		uint32_t  C1 = 0;
		uint32_t  R2 = 0;
		uint32_t  C2 = 0;
		uint32_t  Scaling_factor = 0;
		
   arm_status status; 
     
   arm_matrix_instance_f32  A  ;
   arm_matrix_instance_f32  Scale_A__OUT  ;
	
	const float32_t  A_data[4];
	const float32_t  Scale_A__OUT_data[4];
      
    arm_mat_init_f32( &A , 
    R1  , 
    C1,
    A_data );
	  
	arm_mat_init_f32( &Scale_A__OUT ,
	C2 ,
    Scaling_factor ,
    Scale_A__OUT_data );
    
	status = arm_mat_scale_f32( &A ,
		    R2,
		    &Scale_A__OUT );		
 
	
}
int32_t main() 
{ 
 
#ifndef  USE_STATIC_INIT 
 
  	arm_matrix_instance_f32 srcA; 
  	arm_matrix_instance_f32 srcB; 
  	arm_matrix_instance_f32 dstC;  
 
	/* Input and output matrices initializations */  
	arm_mat_init_f32(&srcA, numStudents, numSubjects, (float32_t *)testMarks_f32);  
	arm_mat_init_f32(&srcB, numSubjects, 1, (float32_t *)testUnity_f32);  
	arm_mat_init_f32(&dstC, numStudents, 1, testOutput);  
 
#else 
 
	/* Static Initializations of Input and output matrix sizes and array */ 
	arm_matrix_instance_f32 srcA = {NUMSTUDENTS, NUMSUBJECTS, (float32_t *)testMarks_f32}; 
	arm_matrix_instance_f32 srcB = {NUMSUBJECTS, 1, (float32_t *)testUnity_f32}; 
	arm_matrix_instance_f32 dstC = {NUMSTUDENTS, 1, testOutput}; 
 
#endif 
 
	 
	/* ---------------------------------------------------------------------- 
	*Call the Matrix multiplication process function   
	* ------------------------------------------------------------------- */ 
	arm_mat_mult_f32(&srcA, &srcB, &dstC); 
	 
	/* ---------------------------------------------------------------------- 
	** Call the Max function to calculate max marks among numStudents 
	** ------------------------------------------------------------------- */ 
	arm_max_f32(testOutput, numStudents, &max_marks, &student_num);  
 
	/* ---------------------------------------------------------------------- 
	** Call the Min function to calculate min marks among numStudents 
	** ------------------------------------------------------------------- */ 
	arm_min_f32(testOutput, numStudents, &min_marks, &student_num);  
 
	/* ---------------------------------------------------------------------- 
	** Call the Mean function to calculate mean 
	** ------------------------------------------------------------------- */ 
	arm_mean_f32(testOutput, numStudents, &mean); 
 
	/* ---------------------------------------------------------------------- 
	** Call the std function to calculate standard deviation 
	** ------------------------------------------------------------------- */ 
	arm_std_f32(testOutput, numStudents, &std); 
 
	/* ---------------------------------------------------------------------- 
	** Call the var function to calculate variance 
	** ------------------------------------------------------------------- */ 
	arm_var_f32(testOutput, numStudents, &var); 
 
    while(1);                             /* main function does not return */
} 
/** \brief Inicilização do controle de estabilidade.
 *
 * O controlador utiliza a API de DSP da CMSIS, e portanto se baseia fortemente no uso do
 * tipo arm_matrix_instance_f32. Esta \b struct contêm os valores de número de linhas e
 * colunas de matriz, além de um ponteiro para seus elementos (na forma de array).
 * Estes arrays são prealocados globalmente (ver código fonte), para evitar overhead
 * de alocação dinâmica em cada chamada e para evitar que, a cada alocação em uma função, a memória para
 * a qual o ponteiro aponta saia de escopo e seja deletada. Uma vez que as funções são privadas e chamadas
 * em ordem determinística, mutexes não são implementadas (por simplicidade apenas)
 */
void c_rc_LQR2_control_init() {

	// Inicializa as matrizes estaticas
	arm_mat_init_f32(&c_rc_LQR2_equilibrium_control, 4, 1, (float32_t *)c_rc_LQR2_equilibrium_control_f32);
	#ifdef LQR_INTEGRATOR
		arm_mat_init_f32(&c_rc_LQR2_Ki, 4, 18, (float32_t *)c_rc_LQR2_Ki_f32);
	#else
		arm_mat_init_f32(&c_rc_LQR2_Ke, 4, 16, (float32_t *)c_rc_LQR2_Ke_f32);
	#endif
}
arm_matrix_instance_f32 c_rc_LQR2_errorStateVector(pv_type_datapr_attitude attitude,
												   pv_type_datapr_attitude attitude_reference,
												   pv_type_datapr_position position,
												   pv_type_datapr_position position_reference,
												   pv_type_datapr_servos servo,
												   pv_type_datapr_servos servo_reference){

	arm_matrix_instance_f32 c_rc_LQR2_error_state_vector, c_rc_LQR2_state_vector,  c_rc_LQR2_reference_state_vector;

		//State Vector
		c_rc_LQR2_state_vector_f32[STATE_X]=position.x;
		c_rc_LQR2_state_vector_f32[STATE_Y]=position.y;
		c_rc_LQR2_state_vector_f32[STATE_Z]=position.z;
		c_rc_LQR2_state_vector_f32[STATE_ROLL]=attitude.roll;
		c_rc_LQR2_state_vector_f32[STATE_PITCH]=attitude.pitch;
		c_rc_LQR2_state_vector_f32[STATE_YAW]=attitude.yaw;
		c_rc_LQR2_state_vector_f32[STATE_ALPHA_R]=servo.alphar;
		c_rc_LQR2_state_vector_f32[STATE_ALPHA_L]=servo.alphal;
		c_rc_LQR2_state_vector_f32[STATE_DX]=position.dotX;
		c_rc_LQR2_state_vector_f32[STATE_DY]=position.dotY;
		c_rc_LQR2_state_vector_f32[STATE_DZ]=position.dotZ;
		c_rc_LQR2_state_vector_f32[STATE_DROLL]=attitude.dotRoll;
		c_rc_LQR2_state_vector_f32[STATE_DPITCH]=attitude.dotPitch;
		c_rc_LQR2_state_vector_f32[STATE_DYAW]=attitude.dotYaw;
		c_rc_LQR2_state_vector_f32[STATE_DALPHA_R]=servo.dotAlphar;
		c_rc_LQR2_state_vector_f32[STATE_DALPHA_L]=servo.dotAlphal;

		//Updates the height equilibrium point according to the reference
		c_rc_LQR2_state_vector_reference_f32[STATE_X]=position_reference.x;
		c_rc_LQR2_state_vector_reference_f32[STATE_Y]=position_reference.y;
		c_rc_LQR2_state_vector_reference_f32[STATE_Z]=position_reference.z;
		c_rc_LQR2_state_vector_reference_f32[STATE_ROLL]=attitude_reference.roll;
		c_rc_LQR2_state_vector_reference_f32[STATE_PITCH]=attitude_reference.pitch;
		c_rc_LQR2_state_vector_reference_f32[STATE_YAW]=attitude_reference.yaw;
		c_rc_LQR2_state_vector_reference_f32[STATE_ALPHA_R]=servo_reference.alphar;
		c_rc_LQR2_state_vector_reference_f32[STATE_ALPHA_L]=servo_reference.alphal;
		c_rc_LQR2_state_vector_reference_f32[STATE_DX]=position_reference.dotX;
		c_rc_LQR2_state_vector_reference_f32[STATE_DY]=position_reference.dotY;
		c_rc_LQR2_state_vector_reference_f32[STATE_DZ]=position_reference.dotZ;
		c_rc_LQR2_state_vector_reference_f32[STATE_DROLL]=attitude_reference.dotRoll;
		c_rc_LQR2_state_vector_reference_f32[STATE_DPITCH]=attitude_reference.dotPitch;
		c_rc_LQR2_state_vector_reference_f32[STATE_DYAW]=attitude_reference.dotYaw;
		c_rc_LQR2_state_vector_reference_f32[STATE_DALPHA_R]=servo_reference.dotAlphar;
		c_rc_LQR2_state_vector_reference_f32[STATE_DALPHA_L]=servo_reference.dotAlphal;

		//Initializes the matrices
		arm_mat_init_f32(&c_rc_LQR2_state_vector, 16, 1, (float32_t *)c_rc_LQR2_state_vector_f32);
		arm_mat_init_f32(&c_rc_LQR2_reference_state_vector, 16, 1, (float32_t *)c_rc_LQR2_state_vector_reference_f32);
		arm_mat_init_f32(&c_rc_LQR2_error_state_vector, 16, 1, (float32_t *)c_rc_LQR2_error_state_vector_f32);
		//e(t)=x(k)- xr(k)
		arm_mat_sub_f32(&c_rc_LQR2_state_vector, &c_rc_LQR2_reference_state_vector, &c_rc_LQR2_error_state_vector);

	return c_rc_LQR2_error_state_vector;
}
Пример #5
0
void matrixInit(arm_matrix_instance_f32 *m, int rows, int cols) {
    float32_t *d;

    d = (float32_t *)aqDataCalloc(rows*cols, sizeof(float32_t));

    arm_mat_init_f32(m, rows, cols, d);
    arm_fill_f32(0, d, rows*cols);
}
pv_type_actuation c_rc_LQR2_controller(pv_type_datapr_attitude attitude,
				  pv_type_datapr_attitude attitude_reference,
				  pv_type_datapr_position position,
				  pv_type_datapr_position position_reference,
				  pv_type_datapr_servos servo,
				  pv_type_datapr_servos servo_reference,
				  float sample_time, bool stop){

	pv_type_actuation actuation_signals;
#ifdef LQR_INTEGRATOR
	arm_matrix_instance_f32 c_rc_LQR2_error_state_vector, c_rc_LQR2_control_output, c_rc_LQR2_i_control_output;

	//Initialize result matrices
	arm_mat_init_f32(&c_rc_LQR2_control_output, 4, 1, (float32_t *)c_rc_LQR2_control_output_f32);
	arm_mat_init_f32(&c_rc_LQR2_i_control_output, 4, 1, (float32_t *)c_rc_LQR2_i_control_output_f32);

	//e(k)=xs_a(k)-xr_a(k)
	c_rc_LQR2_error_state_vector = c_rc_LQR2_errorStateVector_I(attitude, attitude_reference, position, position_reference,servo, servo_reference,sample_time, stop);
	//u=Ke*e(t)
	arm_mat_mult_f32(&c_rc_LQR2_Ki, &c_rc_LQR2_error_state_vector, &c_rc_LQR2_i_control_output);

	arm_mat_add_f32(&c_rc_LQR2_equilibrium_control, &c_rc_LQR2_i_control_output, &c_rc_LQR2_control_output);
#else
	arm_matrix_instance_f32 c_rc_LQR2_error_state_vector, c_rc_LQR2_control_output, c_rc_LQR2_i_control_output;

	//Initialize result matrices
	arm_mat_init_f32(&c_rc_LQR2_control_output, 4, 1, (float32_t *)c_rc_LQR2_control_output_f32);
	arm_mat_init_f32(&c_rc_LQR2_i_control_output, 4, 1, (float32_t *)c_rc_LQR2_i_control_output_f32);

	//e(k)=xs_a(k)-xr_a(k)
	c_rc_LQR2_error_state_vector = c_rc_LQR2_errorStateVector(attitude, attitude_reference, position, position_reference,servo, servo_reference);
	//u=Ke*e(t)
	arm_mat_mult_f32(&c_rc_LQR2_Ke, &c_rc_LQR2_error_state_vector, &c_rc_LQR2_i_control_output);

	arm_mat_add_f32(&c_rc_LQR2_equilibrium_control, &c_rc_LQR2_i_control_output, &c_rc_LQR2_control_output);
#endif

	//The result must be in a struct pv_msg_io_actuation
	actuation_signals.escRightNewtons=(float)c_rc_LQR2_control_output.pData[0]/1000;
	actuation_signals.escLeftNewtons=(float)c_rc_LQR2_control_output.pData[1]/1000;
	actuation_signals.servoRight=(float)c_rc_LQR2_control_output.pData[2]/1000;
	actuation_signals.servoLeft=(float)c_rc_LQR2_control_output.pData[3]/1000;
	actuation_signals.escRightSpeed=0;
	actuation_signals.escLeftSpeed=0;
	return actuation_signals;
}
void Matrix_subtraction ( ) {
	uint32_t  r1 = 0;
		uint32_t  c1 = 0;
		uint32_t  cout = 0;
		uint32_t  rout = 0;
		uint32_t  c2 = 0;
		uint32_t  r2 = 0;
		
	 arm_status status; 
     
    arm_matrix_instance_f32  A  ;
    arm_matrix_instance_f32  B  ;
	arm_matrix_instance_f32  A_SUB_B_OUT  ;
	
	const float32_t  A_data[4];
	const float32_t  B_data[4];
      const float32_t  A_SUB_B_OUT_data[4];
      
      arm_mat_init_f32( &A , 
      r1  , 
      c1,
      A_data );
		
		 
      arm_mat_init_f32( &B , 
      r2  , 
      c2,
      B_data );
		
		 arm_mat_init_f32( &A_SUB_B_OUT ,
		  rout ,
		   cout ,
		  A_SUB_B_OUT_data );
		  
		  status = arm_mat_sub_f32( &A ,
&B ,  &A_SUB_B_OUT );		
 
	
}
void Rotate3dVector(float vector[3], float roll, float pitch, float yaw, float Retorno[3])
{
	roll = roll/57.3;
	pitch = pitch/57.3;
	yaw = yaw/57.3;

	float A = roll;
	float B = pitch;
	float C = yaw;

	float cosA, sinA;
	float cosB, sinB;
	float cosC, sinC;

	cosA = arm_cos_f32(A);
	sinA = arm_sin_f32(A);

	cosB = arm_cos_f32(B);
	sinB = arm_sin_f32(B);

	cosC = arm_cos_f32(C);
	sinC = arm_sin_f32(C);

	float RotationMatrix_f32[9] = 	{cosB*cosC, cosC*sinA*sinB-cosA*sinC, cosA*cosC*sinB+sinA*sinC,
									cosB*sinC, cosA*cosC+sinA*sinB*sinC, -cosC*sinA+cosA*sinB*sinC,
									-sinB, cosB*cosA, cosA*cosB};
	
	arm_matrix_instance_f32 RotationMatrix;
	arm_mat_init_f32(&RotationMatrix, 3, 3, RotationMatrix_f32);

	arm_matrix_instance_f32 InVector;
	arm_mat_init_f32(&InVector, 3, 1, vector);

	arm_matrix_instance_f32 OutVector;
	arm_mat_init_f32(&OutVector, 3, 1, Retorno);

	arm_mat_mult_f32(&RotationMatrix, &InVector, &OutVector);

}
Пример #9
0
int main(void)
{
    ///////////////////////////////////////////////////////////////////////////

    uint32_t currentTime;

	arm_matrix_instance_f32 a;
	arm_matrix_instance_f32 b;
	arm_matrix_instance_f32 x;

    systemReady = false;

    systemInit();

    systemReady = true;

    evrPush(EVR_StartingMain, 0);

    #ifdef _DTIMING

        #define LA1_ENABLE       GPIO_SetBits(GPIOA,   GPIO_Pin_4)
        #define LA1_DISABLE      GPIO_ResetBits(GPIOA, GPIO_Pin_4)
        #define LA4_ENABLE       GPIO_SetBits(GPIOC,   GPIO_Pin_5)
        #define LA4_DISABLE      GPIO_ResetBits(GPIOC, GPIO_Pin_5)
        #define LA2_ENABLE       GPIO_SetBits(GPIOC,   GPIO_Pin_2)
        #define LA2_DISABLE      GPIO_ResetBits(GPIOC, GPIO_Pin_2)
        #define LA3_ENABLE       GPIO_SetBits(GPIOC,   GPIO_Pin_3)
        #define LA3_DISABLE      GPIO_ResetBits(GPIOC, GPIO_Pin_3)

        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,   ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,   ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,   ENABLE);

        GPIO_StructInit(&GPIO_InitStructure);

        // Init pins
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_4;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

        GPIO_Init(GPIOA, &GPIO_InitStructure);

        // Init pins
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1;
      //GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
      //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

        GPIO_Init(GPIOB, &GPIO_InitStructure);

        // Init pins
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5;
      //GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
      //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

        GPIO_Init(GPIOC, &GPIO_InitStructure);

        // PB0_DISABLE;
        LA4_DISABLE;
        LA2_DISABLE;
        LA3_DISABLE;
        LA1_DISABLE;

    #endif

    while (1)
    {
        checkUsbActive(false);

        evrCheck();

        ///////////////////////////////

        if (frame_50Hz)
        {
            #ifdef _DTIMING
                LA2_ENABLE;
            #endif

            frame_50Hz = false;

            currentTime      = micros();
            deltaTime50Hz    = currentTime - previous50HzTime;
            previous50HzTime = currentTime;

            processFlightCommands();

            if (newTemperatureReading && newPressureReading)
            {
                d1Value = d1.value;
                d2Value = d2.value;

                calculateTemperature();
                calculatePressureAltitude();

                newTemperatureReading = false;
                newPressureReading    = false;
            }

            sensors.pressureAlt50Hz = firstOrderFilter(sensors.pressureAlt50Hz, &firstOrderFilters[PRESSURE_ALT_LOWPASS]);

            rssiMeasure();

            updateMax7456(currentTime, 0);

            executionTime50Hz = micros() - currentTime;

            #ifdef _DTIMING
                LA2_DISABLE;
            #endif
        }

        ///////////////////////////////

        if (frame_10Hz)
        {
            #ifdef _DTIMING
                LA4_ENABLE;
            #endif

            frame_10Hz = false;

            currentTime      = micros();
            deltaTime10Hz    = currentTime - previous10HzTime;
            previous10HzTime = currentTime;

            if (newMagData == true)
            {
			    nonRotatedMagData[XAXIS] = (rawMag[XAXIS].value * magScaleFactor[XAXIS]) - eepromConfig.magBias[XAXIS + eepromConfig.externalHMC5883];
			    nonRotatedMagData[YAXIS] = (rawMag[YAXIS].value * magScaleFactor[YAXIS]) - eepromConfig.magBias[YAXIS + eepromConfig.externalHMC5883];
			    nonRotatedMagData[ZAXIS] = (rawMag[ZAXIS].value * magScaleFactor[ZAXIS]) - eepromConfig.magBias[ZAXIS + eepromConfig.externalHMC5883];

			    arm_mat_init_f32(&a, 3, 3, (float *)hmcOrientationMatrix);

			    arm_mat_init_f32(&b, 3, 1, (float *)nonRotatedMagData);

			    arm_mat_init_f32(&x, 3, 1,          sensors.mag10Hz);

			    arm_mat_mult_f32(&a, &b, &x);

				newMagData = false;
			    magDataUpdate = true;
            }

            decodeUbloxMsg();

            batMonTick();

            cliCom();

            if (eepromConfig.mavlinkEnabled == true)
            {
				mavlinkSendAttitude();
				mavlinkSendVfrHud();
			}

            executionTime10Hz = micros() - currentTime;

            #ifdef _DTIMING
                LA4_DISABLE;
            #endif
        }

        ///////////////////////////////

        if (frame_500Hz)
        {
            #ifdef _DTIMING
                LA1_ENABLE;
            #endif

            frame_500Hz = false;

            currentTime       = micros();
            deltaTime500Hz    = currentTime - previous500HzTime;
            previous500HzTime = currentTime;

            TIM_Cmd(TIM10, DISABLE);
            timerValue = TIM_GetCounter(TIM10);
            TIM_SetCounter(TIM10, 0);
            TIM_Cmd(TIM10, ENABLE);

            dt500Hz = (float)timerValue * 0.0000005f;  // For integrations in 500 Hz loop

            computeMPU6000TCBias();

       	    nonRotatedAccelData[XAXIS] = ((float)accelSummedSamples500Hz[XAXIS] * 0.5f - accelTCBias[XAXIS]) * ACCEL_SCALE_FACTOR;
       	    nonRotatedAccelData[YAXIS] = ((float)accelSummedSamples500Hz[YAXIS] * 0.5f - accelTCBias[YAXIS]) * ACCEL_SCALE_FACTOR;
       	    nonRotatedAccelData[ZAXIS] = ((float)accelSummedSamples500Hz[ZAXIS] * 0.5f - accelTCBias[ZAXIS]) * ACCEL_SCALE_FACTOR;

		    arm_mat_init_f32(&a, 3, 3, (float *)mpuOrientationMatrix);

		    arm_mat_init_f32(&b, 3, 1, (float *)nonRotatedAccelData);

		    arm_mat_init_f32(&x, 3, 1,          sensors.accel500Hz);

		    arm_mat_mult_f32(&a, &b, &x);

            nonRotatedGyroData[ROLL ] = ((float)gyroSummedSamples500Hz[ROLL]  * 0.5f - gyroRTBias[ROLL ] - gyroTCBias[ROLL ]) * GYRO_SCALE_FACTOR;
            nonRotatedGyroData[PITCH] = ((float)gyroSummedSamples500Hz[PITCH] * 0.5f - gyroRTBias[PITCH] - gyroTCBias[PITCH]) * GYRO_SCALE_FACTOR;
            nonRotatedGyroData[YAW  ] = ((float)gyroSummedSamples500Hz[YAW]   * 0.5f - gyroRTBias[YAW  ] - gyroTCBias[YAW  ]) * GYRO_SCALE_FACTOR;

		    arm_mat_init_f32(&a, 3, 3, (float *)mpuOrientationMatrix);

		    arm_mat_init_f32(&b, 3, 1, (float *)nonRotatedGyroData);

		    arm_mat_init_f32(&x, 3, 1,          sensors.gyro500Hz);

		    arm_mat_mult_f32(&a, &b, &x);

            MargAHRSupdate(sensors.gyro500Hz[ROLL],   sensors.gyro500Hz[PITCH],  sensors.gyro500Hz[YAW],
                           sensors.accel500Hz[XAXIS], sensors.accel500Hz[YAXIS], sensors.accel500Hz[ZAXIS],
                           sensors.mag10Hz[XAXIS],    sensors.mag10Hz[YAXIS],    sensors.mag10Hz[ZAXIS],
                           eepromConfig.accelCutoff,
                           magDataUpdate,
                           dt500Hz);

            magDataUpdate = false;

            computeAxisCommands(dt500Hz);
            mixTable();
            writeServos();
            writeMotors();

            executionTime500Hz = micros() - currentTime;

            #ifdef _DTIMING
                LA1_DISABLE;
            #endif
        }

        ///////////////////////////////

        if (frame_100Hz)
        {
            #ifdef _DTIMING
                LA3_ENABLE;
            #endif

            frame_100Hz = false;

            currentTime       = micros();
            deltaTime100Hz    = currentTime - previous100HzTime;
            previous100HzTime = currentTime;

            TIM_Cmd(TIM11, DISABLE);
            timerValue = TIM_GetCounter(TIM11);
            TIM_SetCounter(TIM11, 0);
            TIM_Cmd(TIM11, ENABLE);

            dt100Hz = (float)timerValue * 0.0000005f;  // For integrations in 100 Hz loop

       	    nonRotatedAccelData[XAXIS] = ((float)accelSummedSamples100Hz[XAXIS] * 0.1f - accelTCBias[XAXIS]) * ACCEL_SCALE_FACTOR;
       	    nonRotatedAccelData[YAXIS] = ((float)accelSummedSamples100Hz[YAXIS] * 0.1f - accelTCBias[YAXIS]) * ACCEL_SCALE_FACTOR;
       	    nonRotatedAccelData[ZAXIS] = ((float)accelSummedSamples100Hz[ZAXIS] * 0.1f - accelTCBias[ZAXIS]) * ACCEL_SCALE_FACTOR;

		    arm_mat_init_f32(&a, 3, 3, (float *)mpuOrientationMatrix);

		    arm_mat_init_f32(&b, 3, 1, (float *)nonRotatedAccelData);

		    arm_mat_init_f32(&x, 3, 1,          sensors.accel100Hz);

		    arm_mat_mult_f32(&a, &b, &x);

            createRotationMatrix();
            bodyAccelToEarthAccel();
            vertCompFilter(dt100Hz);

            if (armed == true)
            {
				if ( eepromConfig.activeTelemetry == 1 )
                {
            	    // Roll Loop
					openLogPortPrintF("1,%1d,%9.4f,%9.4f,%9.4f,%9.4f,%9.4f,%9.4f\n", flightMode,
					        			                                             rateCmd[ROLL],
					        			                                             sensors.gyro500Hz[ROLL],
					        			                                             ratePID[ROLL],
                                                                                     attCmd[ROLL],
		                                                                             sensors.attitude500Hz[ROLL],
		                                                                             attPID[ROLL]);
                }

                if ( eepromConfig.activeTelemetry == 2 )
                {
            	    // Pitch Loop
					openLogPortPrintF("2,%1d,%9.4f,%9.4f,%9.4f,%9.4f,%9.4f,%9.4f\n", flightMode,
					        			                                             rateCmd[PITCH],
					        			                                             sensors.gyro500Hz[PITCH],
					        			                                             ratePID[PITCH],
                                                                                     attCmd[PITCH],
	                                                                                 sensors.attitude500Hz[PITCH],
	                                                                                 attPID[PITCH]);
                }

                if ( eepromConfig.activeTelemetry == 4 )
                {
            	    // Sensors
					openLogPortPrintF("3,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,\n", sensors.accel500Hz[XAXIS],
					        			                                                                              sensors.accel500Hz[YAXIS],
					        			                                                                              sensors.accel500Hz[ZAXIS],
					        			                                                                              sensors.gyro500Hz[ROLL],
                                                                                                                      sensors.gyro500Hz[PITCH],
	                                                                                                                  sensors.gyro500Hz[YAW],
	                                                                                                                  sensors.mag10Hz[XAXIS],
	                                                                                                                  sensors.mag10Hz[YAXIS],
	                                                                                                                  sensors.mag10Hz[ZAXIS],
	                                                                                                                  sensors.attitude500Hz[ROLL],
	                                                                                                                  sensors.attitude500Hz[PITCH],
	                                                                                                                  sensors.attitude500Hz[YAW]);

                }

                if ( eepromConfig.activeTelemetry == 8 )
                {

                }

                if ( eepromConfig.activeTelemetry == 16)
                {
               	    // Vertical Variables
            	    openLogPortPrintF("%9.4f, %9.4f, %9.4f, %4ld, %1d, %9.4f\n", verticalVelocityCmd,
            	    		                                                     hDotEstimate,
            	    		                                                     hEstimate,
            	    		                                                     ms5611Temperature,
            	    		                                                     verticalModeState,
            	    		                                                     throttleCmd);
                }
		    }

            executionTime100Hz = micros() - currentTime;

            #ifdef _DTIMING
                LA3_DISABLE;
            #endif
        }

        ///////////////////////////////

        if (frame_5Hz)
        {
            frame_5Hz = false;

            currentTime     = micros();
            deltaTime5Hz    = currentTime - previous5HzTime;
            previous5HzTime = currentTime;

            if (gpsValid() == true)
            {

			}

            //if (eepromConfig.mavlinkEnabled == true)
            //{
			//	mavlinkSendGpsRaw();
			//}

			if (batMonVeryLowWarning > 0)
			{
				LED1_TOGGLE;
				batMonVeryLowWarning--;
			}

            if (execUp == true)
                BLUE_LED_TOGGLE;

			executionTime5Hz = micros() - currentTime;
        }

        ///////////////////////////////

        if (frame_1Hz)
        {
            frame_1Hz = false;

            currentTime     = micros();
            deltaTime1Hz    = currentTime - previous1HzTime;
            previous1HzTime = currentTime;

            if (execUp == true)
                GREEN_LED_TOGGLE;

            if (execUp == false)
                execUpCount++;

            // Initialize sensors after being warmed up
            if ((execUpCount == 20) && (execUp == false))
            {
            	computeMPU6000RTData();
                initMag();
                initPressure();
			}

            // Initialize PWM and set mag after sensor warmup
            if ((execUpCount == 25) && (execUp == false))
            {
    			execUp = true;
    			pwmEscInit();
                homeData.magHeading = sensors.attitude500Hz[YAW];
			}

            if (batMonLowWarning > 0)
			{
				LED1_TOGGLE;
				batMonLowWarning--;
			}

            if (eepromConfig.mavlinkEnabled == true)
            {
				mavlinkSendHeartbeat();
				mavlinkSendSysStatus();
			}

            executionTime1Hz = micros() - currentTime;
        }

        ////////////////////////////////
    }

    ///////////////////////////////////////////////////////////////////////////
}
Пример #10
0
int32_t main(void)
{

  arm_matrix_instance_f32 A;      /* Matrix A Instance */
  arm_matrix_instance_f32 AT;     /* Matrix AT(A transpose) instance */
  arm_matrix_instance_f32 ATMA;   /* Matrix ATMA( AT multiply with A) instance */
  arm_matrix_instance_f32 ATMAI;  /* Matrix ATMAI(Inverse of ATMA) instance */
  arm_matrix_instance_f32 B;      /* Matrix B instance */
  arm_matrix_instance_f32 X;      /* Matrix X(Unknown Matrix) instance */

  uint32_t srcRows, srcColumns;  /* Temporary variables */
  arm_status status;

  /* Initialise A Matrix Instance with numRows, numCols and data array(A_f32) */
  srcRows = 4;
  srcColumns = 4;
  arm_mat_init_f32(&A, srcRows, srcColumns, (float32_t *)A_f32);

  /* Initialise Matrix Instance AT with numRows, numCols and data array(AT_f32) */
  srcRows = 4;
  srcColumns = 4;
  arm_mat_init_f32(&AT, srcRows, srcColumns, AT_f32);

  /* calculation of A transpose */
  status = arm_mat_trans_f32(&A, &AT);


  /* Initialise ATMA Matrix Instance with numRows, numCols and data array(ATMA_f32) */
  srcRows = 4;
  srcColumns = 4;
  arm_mat_init_f32(&ATMA, srcRows, srcColumns, ATMA_f32);

  /* calculation of AT Multiply with A */
  status = arm_mat_mult_f32(&AT, &A, &ATMA);

  /* Initialise ATMAI Matrix Instance with numRows, numCols and data array(ATMAI_f32) */
  srcRows = 4;
  srcColumns = 4;
  arm_mat_init_f32(&ATMAI, srcRows, srcColumns, ATMAI_f32);

  /* calculation of Inverse((Transpose(A) * A) */
  status = arm_mat_inverse_f32(&ATMA, &ATMAI);

  /* calculation of (Inverse((Transpose(A) * A)) *  Transpose(A)) */
  status = arm_mat_mult_f32(&ATMAI, &AT, &ATMA);

  /* Initialise B Matrix Instance with numRows, numCols and data array(B_f32) */
  srcRows = 4;
  srcColumns = 1;
  arm_mat_init_f32(&B, srcRows, srcColumns, (float32_t *)B_f32);

  /* Initialise X Matrix Instance with numRows, numCols and data array(X_f32) */
  srcRows = 4;
  srcColumns = 1;
  arm_mat_init_f32(&X, srcRows, srcColumns, X_f32);

  /* calculation ((Inverse((Transpose(A) * A)) *  Transpose(A)) * B) */
  status = arm_mat_mult_f32(&ATMA, &B, &X);

  /* Comparison of reference with test output */
  snr = arm_snr_f32((float32_t *)xRef_f32, X_f32, 4);

  /*------------------------------------------------------------------------------
  *            Initialise status depending on SNR calculations
  *------------------------------------------------------------------------------*/
  if( snr > SNR_THRESHOLD)
  {
    status = ARM_MATH_SUCCESS;
  }
  else
  {
    status = ARM_MATH_TEST_FAILURE;
  }


  /* ----------------------------------------------------------------------
  ** Loop here if the signals fail the PASS check.
  ** This denotes a test failure
  ** ------------------------------------------------------------------- */
  if( status != ARM_MATH_SUCCESS)
  {
    while(1);
  }

  while(1);                             /* main function does not return */
}
Пример #11
0
void UKF_New(UKF_Filter* ukf)
{
	float32_t *P = ukf->P_f32;
	float32_t *Q = ukf->Q_f32;
	float32_t *R = ukf->R_f32;
	float32_t *Wc = ukf->Wc_f32;

	//scaling factor
	float32_t lambda = UKF_alpha * UKF_alpha *((float32_t)UKF_STATE_DIM + UKF_kappa) - (float32_t)UKF_STATE_DIM;
	float32_t gamma = (float32_t)UKF_STATE_DIM + lambda;

	//weights for means
	ukf->Wm0 = lambda / gamma;
	ukf->Wmi = 0.5f / gamma;
	//weights for covariance
	arm_mat_init_f32(&ukf->Wc, UKF_SP_POINTS, UKF_SP_POINTS, ukf->Wc_f32);
	arm_mat_identity_f32(&ukf->Wc, ukf->Wmi);
	Wc[0] = ukf->Wm0 + (1.0f - UKF_alpha * UKF_alpha + UKF_beta);

	//scaling factor need to tune!
	arm_sqrt_f32(gamma, &ukf->gamma);
	//////////////////////////////////////////////////////////////////////////
	//initialise P
	arm_mat_init_f32(&ukf->P, UKF_STATE_DIM, UKF_STATE_DIM, ukf->P_f32);
	arm_mat_identity_f32(&ukf->P, 1.0f);
	P[0] = P[8] = P[16] = P[24] = UKF_PQ_INITIAL;
	P[32] = P[40] = P[48] = UKF_PW_INITIAL;

	arm_mat_init_f32(&ukf->PX, UKF_STATE_DIM, UKF_STATE_DIM, ukf->PX_f32);
	arm_mat_init_f32(&ukf->PY, UKF_MEASUREMENT_DIM, UKF_MEASUREMENT_DIM, ukf->PY_f32);
	arm_mat_init_f32(&ukf->tmpPY, UKF_MEASUREMENT_DIM, UKF_MEASUREMENT_DIM, ukf->tmpPY_f32);
	arm_mat_init_f32(&ukf->PXY, UKF_STATE_DIM, UKF_MEASUREMENT_DIM, ukf->PXY_f32);
	arm_mat_init_f32(&ukf->PXYT, UKF_MEASUREMENT_DIM, UKF_STATE_DIM, ukf->PXYT_f32);
	//initialise Q
	arm_mat_init_f32(&ukf->Q, UKF_STATE_DIM, UKF_STATE_DIM, ukf->Q_f32);
	Q[0] = Q[8] = Q[16] = Q[24] = UKF_QQ_INITIAL;
	Q[32] = Q[40] = Q[48] = UKF_QW_INITIAL;
	//initialise R
	arm_mat_init_f32(&ukf->R, UKF_MEASUREMENT_DIM, UKF_MEASUREMENT_DIM, ukf->R_f32);
	R[0] = R[14] = R[28] = R[42] = UKF_RQ_INITIAL;
	R[56] = R[70] = R[84] = UKF_RA_INITIAL;
	R[98] = R[112] = R[126] = UKF_RW_INITIAL;
	R[140] = R[154] = R[168] = UKF_RM_INITIAL;

	arm_mat_init_f32(&ukf->XSP, UKF_STATE_DIM, UKF_SP_POINTS, ukf->XSP_f32);
	arm_mat_init_f32(&ukf->tmpXSP, UKF_STATE_DIM, UKF_SP_POINTS, ukf->tmpXSP_f32);
	arm_mat_init_f32(&ukf->tmpXSPT, UKF_SP_POINTS, UKF_STATE_DIM, ukf->tmpXSPT_f32);
	arm_mat_init_f32(&ukf->tmpWcXSP, UKF_STATE_DIM, UKF_SP_POINTS, ukf->tmpWcXSP_f32);
	arm_mat_init_f32(&ukf->tmpWcYSP, UKF_MEASUREMENT_DIM, UKF_SP_POINTS, ukf->tmpWcYSP_f32);
	arm_mat_init_f32(&ukf->YSP, UKF_MEASUREMENT_DIM, UKF_SP_POINTS, ukf->YSP_f32);
	arm_mat_init_f32(&ukf->tmpYSP, UKF_MEASUREMENT_DIM, UKF_SP_POINTS, ukf->tmpYSP_f32);
	arm_mat_init_f32(&ukf->tmpYSPT, UKF_SP_POINTS, UKF_MEASUREMENT_DIM, ukf->tmpYSPT_f32);

	//////////////////////////////////////////////////////////////////////////
	arm_mat_init_f32(&ukf->K, UKF_STATE_DIM, UKF_MEASUREMENT_DIM, ukf->K_f32);
	arm_mat_init_f32(&ukf->KT, UKF_MEASUREMENT_DIM, UKF_STATE_DIM, ukf->KT_f32);
	//////////////////////////////////////////////////////////////////////////
	arm_mat_init_f32(&ukf->X, UKF_STATE_DIM, 1, ukf->X_f32);
	arm_mat_zero_f32(&ukf->X);
	arm_mat_init_f32(&ukf->tmpX, UKF_STATE_DIM, 1, ukf->tmpX_f32);
	arm_mat_zero_f32(&ukf->tmpX);
	//////////////////////////////////////////////////////////////////////////
	arm_mat_init_f32(&ukf->Y, UKF_MEASUREMENT_DIM, 1, ukf->Y_f32);
	arm_mat_zero_f32(&ukf->Y);
	arm_mat_init_f32(&ukf->tmpY, UKF_MEASUREMENT_DIM, 1, ukf->tmpY_f32);
	arm_mat_zero_f32(&ukf->tmpY);
	//////////////////////////////////////////////////////////////////////////
}
void kalman_filter(kalman_filter_state *buffer_filtro, float medida_gyro[], float medida_accel[], float medida_mag[], float angles[], uint16_t estado_motores)
{
    GPIO_ResetBits(GPIOD, GPIO_Pin_14);
    //Insf_tancias das matrizes utilizadas para o cálculo
    arm_matrix_instance_f32 X;			//Matriz de estados. [n,1]
    arm_matrix_instance_f32 F;			//Matriz de transição de estados. [n,n]
    arm_matrix_instance_f32 Ft;			//Matriz de transição de estados transposta. [n,n]
    arm_matrix_instance_f32 I;			//Matriz identidadee. [n,n]
    arm_matrix_instance_f32 P;			//Matriz de confiabilidade do processo de atualização. [n,n]
    //arm_matrix_instance_f32 h;		//Matriz de mapeamento de observabilidade [a,n]
    arm_matrix_instance_f32 H;			//Matriz Jacobiana para atualização da confiabilidade do erro [a, n].
    arm_matrix_instance_f32 Ht;			//Matriz Jacobiana transposta para atualização da confiabilidade do erro. [n, a]
    arm_matrix_instance_f32 Q;			//Matriz de covariância multiplicada de processos; [n, n]
    arm_matrix_instance_f32 R;			//Matriz de variância [a ,a]
    arm_matrix_instance_f32 S;			//Matriz .... [a, a]
    arm_matrix_instance_f32 Sinv;		//Matriz S inversa. [a, a]
    arm_matrix_instance_f32 K;			//Matriz com os ganhos de Kalman [n,a]

    //Matrices intermediàrias para cálculo

    arm_matrix_instance_f32 temp_calc_a1_0;
    arm_matrix_instance_f32 temp_calc_a1_1;

    arm_matrix_instance_f32 temp_calc_n1_0;
    arm_matrix_instance_f32 temp_calc_n1_1;
	
    arm_matrix_instance_f32 temp_calc_aa_0;
    arm_matrix_instance_f32 temp_calc_aa_1;
	
    arm_matrix_instance_f32 temp_calc_na_0;
    arm_matrix_instance_f32 temp_calc_an_0;

    arm_matrix_instance_f32 temp_calc_nn_0;
    arm_matrix_instance_f32 temp_calc_nn_1;

	//Matriz S...
    float S_f32[a*a];
    arm_mat_init_f32(&S, a, a, S_f32);

    float Sinv_f32[a*a];
    arm_mat_init_f32(&Sinv, a, a, Sinv_f32);

	//Matriz do ganho de Kalman 
    float K_f32[n*a];
    arm_mat_init_f32(&K, n, a, K_f32);

	//Matrizes de suporte para o cálculo
		//Matrizes de 9 linhas e 1 coluna
    float temp_calc_n1_0_f32[n];
    float temp_calc_n1_1_f32[n];
	
    arm_mat_init_f32(&temp_calc_n1_0, n, 1, temp_calc_n1_0_f32);
    arm_mat_init_f32(&temp_calc_n1_1, n, 1, temp_calc_n1_1_f32);

	//Matrizes de 9 linhas e 1 coluna
    float temp_calc_a1_0_f32[a];
    float temp_calc_a1_1_f32[a];
	
    arm_mat_init_f32(&temp_calc_a1_0, a, 1, temp_calc_a1_0_f32);
    arm_mat_init_f32(&temp_calc_a1_1, a, 1, temp_calc_a1_1_f32);

	//Matrizes de 6 linhas e 6 colunas
    float temp_calc_aa_0_f32[a*a];
    float temp_calc_aa_1_f32[a*a];

    arm_mat_init_f32(&temp_calc_aa_0, a, a, temp_calc_aa_0_f32);
    arm_mat_init_f32(&temp_calc_aa_1, a, a, temp_calc_aa_1_f32);
	
	//Matrizes de 9 linhas e 6 colunas
    float temp_calc_na_0_f32[n*a];

    arm_mat_init_f32(&temp_calc_na_0, n, a, temp_calc_na_0_f32);

	//Matrizes de 6 linhas e 9 colunas
    float temp_calc_an_0_f32[a*n];

    arm_mat_init_f32(&temp_calc_an_0, a, n, temp_calc_an_0_f32);

	//Matrizes de 9 linhas e 9 colunas
    float temp_calc_nn_0_f32[n*n];
    float temp_calc_nn_1_f32[n*n];

    arm_mat_init_f32(&temp_calc_nn_0, n, n, temp_calc_nn_0_f32);
    arm_mat_init_f32(&temp_calc_nn_1, n, n, temp_calc_nn_1_f32);
	
	/*************************************Atualização dos dados para cálcuo*******************************/
	//Variáveis para cálculos
	
	float dt = buffer_filtro->dt;

	/*Velocidades angulares subtraídas dos bias. */
    float p = medida_gyro[0];
    float q = medida_gyro[1];
    float r = medida_gyro[2];

	/*Atualização dos estados dos ângulos com base nas velocidades angulares e do bias estimado anteriormente*/
    float X_f32[n];
    arm_mat_init_f32(&X, n, 1, X_f32);

    arm_copy_f32(buffer_filtro->ultimo_estado, X_f32, n);

    float phi =  X_f32[0];
    float theta = X_f32[1];
    float psi =  X_f32[2];

    float bPhi = X_f32[9];
    float bTheta = X_f32[10];
    float bPsi = X_f32[11];

    //Atualizar o estado anterior - Apenas os ângulos precisam serm inicializados, uma vez que os bias são atualizados por uma identidade.
    X_f32[0] = phi + (p)*dt + f_sin(phi)*f_tan(theta)*(q)*dt + f_cos(phi)*f_tan(theta)*(r)*dt;
    X_f32[1] = theta + f_cos(phi)*(q)*dt - f_sin(phi)*(r)*dt;
    X_f32[2] = psi + f_sin(phi)*f_sec(theta)*(q)*dt + f_cos(phi)*f_sec(theta)*(r)*dt;

    phi = X_f32[0];
    theta = X_f32[1];
    psi = X_f32[2];

    //Com os angulos calculados, cálcula os senos e cossenos utilizados para agilizar os processos de cálculo.
    float cos_Phi = f_cos(phi);
    float sin_Phi = f_sin(phi);

    float cos_Theta = f_cos(theta);
    float sin_Theta = f_sin(theta);
    float tan_Theta = f_tan(theta);

    //Elementos da matriz para atualização dos estados (F).
    float F_f32[n*n] = { dt*q*cos_Phi*tan_Theta - dt*r*sin_Phi*tan_Theta + 1,               dt*r*cos_Phi*(pow(tan_Theta,2) + 1) + dt*q*sin_Phi*(pow(tan_Theta,2) + 1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                 - dt*r*cos_Phi - dt*q*sin_Phi,                                                                                 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                         (dt*q*cos_Phi)/cos_Theta - (dt*r*sin_Phi)/cos_Theta, (dt*r*cos_Phi*sin_Theta)/pow(cos_Theta,2) + (dt*q*sin_Phi*sin_Theta)/pow(cos_Theta,2), 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                                               0,                                                                                 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
                                                                               0,                                                                                 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
                                                                               0,                                                                                 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
                                                                               0,                                                                                 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
                                                                               0,                                                                                 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
                                                                               0,                                                                                 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
                                                                               0,                                                                                 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
                                                                               0,                                                                                 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
                                                                               0,                                                                                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};

    arm_mat_init_f32(&F, n, n, F_f32);

	//Matriz Jacobiana transposta para atualização de P.
    float Ft_f32[n*n];
    arm_mat_init_f32(&Ft, n, n, Ft_f32);
    arm_mat_trans_f32(&F, &Ft);

	//Processo à priori para atualização da matriz de confiabilidade P.

	//Matriz de covariâncias do processo de atualização (Q).
    float qAngles = (buffer_filtro->Q_angles);
    float qBiasAcel = (buffer_filtro->Q_bias_acel);
    float qBiasMag = (buffer_filtro->Q_bias_mag);
    float qBiasAngles = (buffer_filtro->Q_bias_angle);

    /*Matriz de confiabilidade do processo de atualização. */
    /* Pk|k-1 = Pk-1|k-1 */
    float P_f32[n*n];
    arm_copy_f32(buffer_filtro->P, P_f32, n*n);
    arm_mat_init_f32(&P, n, n, P_f32);

    //temp_calc_nn_0 = F*P
    if(arm_mat_mult_f32(&F, &P, &temp_calc_nn_0) != ARM_MATH_SUCCESS)
        while(1);

    //temp_calc_nn_1 = F*P*F'
    if(arm_mat_mult_f32(&temp_calc_nn_0, &Ft, &temp_calc_nn_1) != ARM_MATH_SUCCESS)
        while(1);


    //Atualiza a matriz de covariâncias dos processos
    float Q_f32[n*n] = {	qAngles,   0,           0,          0,          0,          0,          0,          0,          0,          0,          0,              0,
                            0,          qAngles,    0,          0,          0,          0,          0,          0,          0,          0,          0,              0,
                            0,          0,          qAngles,	0,          0,          0,          0,          0,          0,          0,          0,              0,
                            0,          0,          0,          qBiasAcel,  0,          0,          0,          0,          0,          0,          0,              0,
                            0,          0,          0,          0,          qBiasAcel,  0,          0,          0,          0,          0,          0,              0,
                            0,          0,      	0,          0,          0,          qBiasAcel,  0,          0,          0,          0,          0,              0,
                            0,          0,          0,          0,          0,          0,          qBiasMag,   0,          0,          0,          0,              0,
                            0,          0,          0,          0,          0,          0,          0,          qBiasMag,   0,          0,          0,              0,
                            0,          0,          0,          0,          0,          0,          0,          0,          qBiasMag,   0,          0,              0,
                            0,          0,          0,          0,          0,          0,          0,          0,          0,          qBiasAngles, 0,             0,
                            0,          0,          0,          0,          0,          0,          0,          0,          0,          0,          qBiasAngles,    0,
                            0,          0,          0,          0,          0,          0,          0,          0,          0,          0,          0,              qBiasAngles};

    arm_mat_init_f32(&Q, n, n, Q_f32);

    //P = temp_calc_nn_1 + Q = F*P*F' + Q
    if(arm_mat_add_f32(&temp_calc_nn_1, &Q, &P) != ARM_MATH_SUCCESS)
        while(1);

	/*Estados iniciais do magnetômetro */
    float magRefVector[3];
    float acelRefVector[3];
    arm_matrix_instance_f32 magRefMatrix;
    arm_matrix_instance_f32 acelRefMatrix;

    arm_mat_init_f32(&magRefMatrix, 3, 1, magRefVector);
    arm_mat_init_f32(&acelRefMatrix, 3, 1, acelRefVector);

    float ax = buffer_filtro->AcelInicial[0];
    float ay = buffer_filtro->AcelInicial[1];
    float az = buffer_filtro->AcelInicial[2];

    float hx = buffer_filtro->MagInicial[0];
    float hy = buffer_filtro->MagInicial[1];
    float hz = buffer_filtro->MagInicial[2];

    magRefVector[0] = hx;
    magRefVector[1] = hy;
    magRefVector[2] = hz;

    acelRefVector[0] = ax;
    acelRefVector[1] = ay;
    acelRefVector[2] = az;

    //Matrizes com o resultado das operações de rotação
    float observatedStateVector[a];

    arm_matrix_instance_f32 observatedStateMatrix;
    arm_mat_init_f32(&observatedStateMatrix, a, 1, observatedStateVector);

    //Matriz contendo os valores observados utilizados pra gerar o rezíduo (yk)
    arm_matrix_instance_f32 rotatedMagMatrix;
    arm_matrix_instance_f32 rotatedAcelMatrix;

    arm_mat_init_f32(&rotatedAcelMatrix, 3, 1, observatedStateVector);
    arm_mat_init_f32(&rotatedMagMatrix, 3, 1, observatedStateVector+3);

    //Matriz de rotação com base nos angulos estimados.
    float rotationVector[9];
    arm_matrix_instance_f32 rotationMatrix;
    arm_mat_init_f32(&rotationMatrix, 3, 3, rotationVector);
    getABCRotMatFromEulerAngles(phi-bPhi, theta-bTheta, psi-bPsi, &rotationMatrix);

    /* Cálculo das referências com base no magnetômetro e no estado do acelerômetro parado [0; 0; 1]; */
    if(arm_mat_mult_f32(&rotationMatrix, &acelRefMatrix, &rotatedAcelMatrix) != ARM_MATH_SUCCESS)
        while(1);

    if(arm_mat_mult_f32(&rotationMatrix, &magRefMatrix, &rotatedMagMatrix) != ARM_MATH_SUCCESS)
        while(1);

    //Vetor com as médidas
    float zkVector[a];

    zkVector[0] = medida_accel[0];
    zkVector[1] = medida_accel[1];
    zkVector[2] = medida_accel[2];

    zkVector[3] = medida_mag[0];
    zkVector[4] = medida_mag[1];
    zkVector[5] = medida_mag[2];

    zkVector[6] = angles[0];
    zkVector[7] = angles[1];
    zkVector[8] = angles[2];

    arm_matrix_instance_f32 zkMatrix;
    arm_mat_init_f32(&zkMatrix, a, 1, zkVector);

    //Vetor de resíduo
    float ykVector[a];
    arm_matrix_instance_f32 ykMatrix;
    arm_mat_init_f32(&ykMatrix, a, 1, ykVector);

    //Adiciona os bias estimados pelo filtro
    observatedStateVector[0] += X_f32[3];
    observatedStateVector[1] += X_f32[4];
    observatedStateVector[2] += X_f32[5];
    observatedStateVector[3] += X_f32[6];
    observatedStateVector[4] += X_f32[7];
    observatedStateVector[5] += X_f32[8];

    //Remove o bias estimado pelo filtro
    float correctedPhi =    -(X_f32[0] - X_f32[9]);
    float correctedTheta =  -(X_f32[1] - X_f32[10]);
    float correctedPsi =    -(X_f32[2] - X_f32[11]);

    //Com os angulos corrigidos calculados, cálcula os senos e cossenos utilizados para agilizar os processos de cálculo.
    float cos_correctedPhi = f_cos(correctedPhi);
    float sin_correctedPhi = f_sin(correctedPhi);

    float cos_correctedTheta = f_cos(correctedTheta);
    float sin_correctedTheta = f_sin(correctedTheta);

    float cos_correctedPsi = f_cos(correctedPsi);
    float sin_correctedPsi = f_sin(correctedPsi);
    //
    observatedStateVector[6] = -correctedPhi;
    observatedStateVector[7] = -correctedTheta;
    observatedStateVector[8] = -correctedPsi;

    if(arm_mat_sub_f32(&zkMatrix, &observatedStateMatrix, &ykMatrix) != ARM_MATH_SUCCESS)
        while(1);

    float H_f32[a*n] = {                                                                                                                                                                                                                                0,                                                 ax*sin_correctedTheta*cos_correctedPsi - az*cos_correctedTheta - ay*sin_correctedPsi*sin_correctedTheta,                                                                                                         ay*cos_correctedPsi*cos_correctedTheta + ax*sin_correctedPsi*cos_correctedTheta, 1, 0, 0, 0, 0, 0,                                                                                                                                                                                                                                  0,                                                 az*cos_correctedTheta - ax*sin_correctedTheta*cos_correctedPsi + ay*sin_correctedPsi*sin_correctedTheta,                                                                                                       - ay*cos_correctedPsi*cos_correctedTheta - ax*sin_correctedPsi*cos_correctedTheta,
                         ax*(sin_correctedPhi*sin_correctedPsi - sin_correctedTheta*cos_correctedPhi*cos_correctedPsi) + ay*(sin_correctedPhi*cos_correctedPsi + sin_correctedPsi*sin_correctedTheta*cos_correctedPhi) + az*cos_correctedPhi*cos_correctedTheta, ay*sin_correctedPhi*sin_correctedPsi*cos_correctedTheta - ax*sin_correctedPhi*cos_correctedPsi*cos_correctedTheta - az*sin_correctedPhi*sin_correctedTheta, ay*(sin_correctedPsi*cos_correctedPhi + sin_correctedPhi*sin_correctedTheta*cos_correctedPsi) - ax*(cos_correctedPhi*cos_correctedPsi - sin_correctedPhi*sin_correctedPsi*sin_correctedTheta), 0, 1, 0, 0, 0, 0, - ax*(sin_correctedPhi*sin_correctedPsi - sin_correctedTheta*cos_correctedPhi*cos_correctedPsi) - ay*(sin_correctedPhi*cos_correctedPsi + sin_correctedPsi*sin_correctedTheta*cos_correctedPhi) - az*cos_correctedPhi*cos_correctedTheta, az*sin_correctedPhi*sin_correctedTheta + ax*sin_correctedPhi*cos_correctedPsi*cos_correctedTheta - ay*sin_correctedPhi*sin_correctedPsi*cos_correctedTheta, ax*(cos_correctedPhi*cos_correctedPsi - sin_correctedPhi*sin_correctedPsi*sin_correctedTheta) - ay*(sin_correctedPsi*cos_correctedPhi + sin_correctedPhi*sin_correctedTheta*cos_correctedPsi),
                         az*sin_correctedPhi*cos_correctedTheta - ay*(cos_correctedPhi*cos_correctedPsi - sin_correctedPhi*sin_correctedPsi*sin_correctedTheta) - ax*(sin_correctedPsi*cos_correctedPhi + sin_correctedPhi*sin_correctedTheta*cos_correctedPsi), az*sin_correctedTheta*cos_correctedPhi + ax*cos_correctedPhi*cos_correctedPsi*cos_correctedTheta - ay*sin_correctedPsi*cos_correctedPhi*cos_correctedTheta, ay*(sin_correctedPhi*sin_correctedPsi - sin_correctedTheta*cos_correctedPhi*cos_correctedPsi) - ax*(sin_correctedPhi*cos_correctedPsi + sin_correctedPsi*sin_correctedTheta*cos_correctedPhi), 0, 0, 1, 0, 0, 0,   ax*(sin_correctedPsi*cos_correctedPhi + sin_correctedPhi*sin_correctedTheta*cos_correctedPsi) + ay*(cos_correctedPhi*cos_correctedPsi - sin_correctedPhi*sin_correctedPsi*sin_correctedTheta) - az*sin_correctedPhi*cos_correctedTheta, ay*sin_correctedPsi*cos_correctedPhi*cos_correctedTheta - ax*cos_correctedPhi*cos_correctedPsi*cos_correctedTheta - az*sin_correctedTheta*cos_correctedPhi, ax*(sin_correctedPhi*cos_correctedPsi + sin_correctedPsi*sin_correctedTheta*cos_correctedPhi) - ay*(sin_correctedPhi*sin_correctedPsi - sin_correctedTheta*cos_correctedPhi*cos_correctedPsi),
                                                                                                                                                                                                                                                        0,                                                 hx*sin_correctedTheta*cos_correctedPsi - hz*cos_correctedTheta - hy*sin_correctedPsi*sin_correctedTheta,                                                                                                         hy*cos_correctedPsi*cos_correctedTheta + hx*sin_correctedPsi*cos_correctedTheta, 0, 0, 0, 1, 0, 0,                                                                                                                                                                                                                                  0,                                                 hz*cos_correctedTheta - hx*sin_correctedTheta*cos_correctedPsi + hy*sin_correctedPsi*sin_correctedTheta,                                                                                                       - hy*cos_correctedPsi*cos_correctedTheta - hx*sin_correctedPsi*cos_correctedTheta,
                         hx*(sin_correctedPhi*sin_correctedPsi - sin_correctedTheta*cos_correctedPhi*cos_correctedPsi) + hy*(sin_correctedPhi*cos_correctedPsi + sin_correctedPsi*sin_correctedTheta*cos_correctedPhi) + hz*cos_correctedPhi*cos_correctedTheta, hy*sin_correctedPhi*sin_correctedPsi*cos_correctedTheta - hx*sin_correctedPhi*cos_correctedPsi*cos_correctedTheta - hz*sin_correctedPhi*sin_correctedTheta, hy*(sin_correctedPsi*cos_correctedPhi + sin_correctedPhi*sin_correctedTheta*cos_correctedPsi) - hx*(cos_correctedPhi*cos_correctedPsi - sin_correctedPhi*sin_correctedPsi*sin_correctedTheta), 0, 0, 0, 0, 1, 0, - hx*(sin_correctedPhi*sin_correctedPsi - sin_correctedTheta*cos_correctedPhi*cos_correctedPsi) - hy*(sin_correctedPhi*cos_correctedPsi + sin_correctedPsi*sin_correctedTheta*cos_correctedPhi) - hz*cos_correctedPhi*cos_correctedTheta, hz*sin_correctedPhi*sin_correctedTheta + hx*sin_correctedPhi*cos_correctedPsi*cos_correctedTheta - hy*sin_correctedPhi*sin_correctedPsi*cos_correctedTheta, hx*(cos_correctedPhi*cos_correctedPsi - sin_correctedPhi*sin_correctedPsi*sin_correctedTheta) - hy*(sin_correctedPsi*cos_correctedPhi + sin_correctedPhi*sin_correctedTheta*cos_correctedPsi),
                         hz*sin_correctedPhi*cos_correctedTheta - hy*(cos_correctedPhi*cos_correctedPsi - sin_correctedPhi*sin_correctedPsi*sin_correctedTheta) - hx*(sin_correctedPsi*cos_correctedPhi + sin_correctedPhi*sin_correctedTheta*cos_correctedPsi), hz*sin_correctedTheta*cos_correctedPhi + hx*cos_correctedPhi*cos_correctedPsi*cos_correctedTheta - hy*sin_correctedPsi*cos_correctedPhi*cos_correctedTheta, hy*(sin_correctedPhi*sin_correctedPsi - sin_correctedTheta*cos_correctedPhi*cos_correctedPsi) - hx*(sin_correctedPhi*cos_correctedPsi + sin_correctedPsi*sin_correctedTheta*cos_correctedPhi), 0, 0, 0, 0, 0, 1,   hx*(sin_correctedPsi*cos_correctedPhi + sin_correctedPhi*sin_correctedTheta*cos_correctedPsi) + hy*(cos_correctedPhi*cos_correctedPsi - sin_correctedPhi*sin_correctedPsi*sin_correctedTheta) - hz*sin_correctedPhi*cos_correctedTheta, hy*sin_correctedPsi*cos_correctedPhi*cos_correctedTheta - hx*cos_correctedPhi*cos_correctedPsi*cos_correctedTheta - hz*sin_correctedTheta*cos_correctedPhi, hx*(sin_correctedPhi*cos_correctedPsi + sin_correctedPsi*sin_correctedTheta*cos_correctedPhi) - hy*(sin_correctedPhi*sin_correctedPsi - sin_correctedTheta*cos_correctedPhi*cos_correctedPsi),
                                                                                                                                                                                                                                                        1,                                                                                                                                                        0,                                                                                                                                                                                       0, 0, 0, 0, 0, 0, 0,                                                                                                                                                                                                                                 -1,                                                                                                                                                        0,                                                                                                                                                                                       0,
                                                                                                                                                                                                                                                        0,                                                                                                                                                        1,                                                                                                                                                                                       0, 0, 0, 0, 0, 0, 0,                                                                                                                                                                                                                                  0,                                                                                                                                                       -1,                                                                                                                                                                                       0,
                                                                                                                                                                                                                                                        0,                                                                                                                                                        0,                                                                                                                                                                                       1, 0, 0, 0, 0, 0, 0,                                                                                                                                                                                                                                  0,                                                                                                                                                        0,                                                                                                                                                                                      -1};

    arm_mat_init_f32(&H, a, n, H_f32);

	/* Matriz Jacobiana transposta para cálculo da confiabilidade do erro . */
    float Ht_f32[n*a];
    arm_mat_init_f32(&Ht, n, a, Ht_f32);

    arm_mat_trans_f32(&H, &Ht);

	//Matriz de variâncias
	float Racel = buffer_filtro->R_acel;
	float Rmag = buffer_filtro->R_mag;	 //Variância inicial do magnetômetro.
    float Rangles = buffer_filtro->R_angles;

    float acelModulus = getVectorModulus(medida_accel, 3);
//    float magModulus = getVectorModulus(medida_mag, 3);
//    float magInitialModulus = getVectorModulus(buffer_filtro->MagInicial, 3);

    //Racel += 100*fabsf(1 - acelModulus);
    //Rmag += 1*fabs(magInitialModulus - magModulus);


    float R_f32[a*a] = {(Racel), 0, 0, 0, 0, 0, 0, 0, 0,
                        0, (Racel), 0, 0, 0, 0, 0, 0, 0,
                        0, 0, (Racel), 0, 0, 0, 0, 0, 0,
                        0, 0, 0, (Rmag),  0, 0, 0, 0, 0,
                        0, 0, 0, 0, (Rmag),	 0, 0, 0, 0,
                        0, 0, 0, 0, 0, (Rmag), 0, 0, 0,
                        0, 0, 0, 0, 0, 0, (Rangles), 0, 0,
                        0, 0, 0, 0, 0, 0, 0, (Rangles), 0,
                        0, 0, 0, 0, 0, 0, 0, 0, (Rangles)};

    arm_mat_init_f32(&R, a, a, R_f32);

	//Cálculos do filtro de Kalman

	//S = H*P*H' + R
    if(arm_mat_mult_f32(&H, &P, &temp_calc_an_0) != ARM_MATH_SUCCESS)
        while(1);

    if(arm_mat_mult_f32(&temp_calc_an_0, &Ht, &temp_calc_aa_0) != ARM_MATH_SUCCESS)
        while(1);

    if(arm_mat_add_f32(&temp_calc_aa_0, &R, &S) != ARM_MATH_SUCCESS)
        while(1);

    //Sinv = inv(S);
    //if(arm_mat_inverse_f32(&S, &Sinv) == ARM_MATH_SINGULAR)
    //    while(1);
    arm_mat_inverse_f32(&S, &Sinv);

    //Kk = P*Ht*S^(-1)
		//P*Ht
    if(arm_mat_mult_f32(&P, &Ht, &temp_calc_na_0) != ARM_MATH_SUCCESS)
        while(1);

    if(arm_mat_mult_f32(&temp_calc_na_0, &Sinv, &K) != ARM_MATH_SUCCESS)
        while(1);
	
    //temp_calc_n11 = Kk*y
    if(arm_mat_mult_f32(&K, &ykMatrix, &temp_calc_n1_0) != ARM_MATH_SUCCESS)
        while(1);

    //X = X + temp_calc_n1_1;
    if(arm_mat_add_f32(&X, &temp_calc_n1_0, &temp_calc_n1_1) != ARM_MATH_SUCCESS)
        while(1);

    arm_copy_f32(temp_calc_n1_1_f32, X_f32, n);

	//P = (I-K*H)*P
	
	//Matriz identidade para atualização da matriz P à posteriori.
    float I_f32[n*n] = {	1,0,0,0,0,0,0,0,0,0,0,0,
                            0,1,0,0,0,0,0,0,0,0,0,0,
                            0,0,1,0,0,0,0,0,0,0,0,0,
                            0,0,0,1,0,0,0,0,0,0,0,0,
                            0,0,0,0,1,0,0,0,0,0,0,0,
                            0,0,0,0,0,1,0,0,0,0,0,0,
                            0,0,0,0,0,0,1,0,0,0,0,0,
                            0,0,0,0,0,0,0,1,0,0,0,0,
                            0,0,0,0,0,0,0,0,1,0,0,0,
                            0,0,0,0,0,0,0,0,0,1,0,0,
                            0,0,0,0,0,0,0,0,0,0,1,0,
                            0,0,0,0,0,0,0,0,0,0,0,1};

    arm_mat_init_f32(&I, n, n, I_f32);


    if(arm_mat_mult_f32(&K, &H, &temp_calc_nn_0) != ARM_MATH_SUCCESS)
        while(1);

    if(arm_mat_sub_f32(&I, &temp_calc_nn_0, &temp_calc_nn_1) != ARM_MATH_SUCCESS)
        while(1);

    if(arm_mat_mult_f32(&temp_calc_nn_1, &P, &temp_calc_nn_0) != ARM_MATH_SUCCESS)
        while(1);

    arm_copy_f32(X_f32, buffer_filtro->ultimo_estado, n);
    arm_copy_f32(temp_calc_nn_0_f32, buffer_filtro->P, n*n);
}
Пример #13
0
void EKF_New(EKF_Filter* ekf)
{
	float32_t *H = ekf->H_f32;
	float32_t *P = ekf->P_f32;
	float32_t *Q = ekf->Q_f32;
	float32_t *R = ekf->R_f32;
	//////////////////////////////////////////////////////////////////////////
	arm_mat_init_f32(&ekf->P, EKF_STATE_DIM, EKF_STATE_DIM, ekf->P_f32);
	arm_mat_zero_f32(&ekf->P);
	P[0] = P[8] = P[16] = P[24] = EKF_PQ_INITIAL;
	P[32] = P[40] = P[48] = EKF_PW_INITIAL;
	//
	arm_mat_init_f32(&ekf->Q, EKF_STATE_DIM, EKF_STATE_DIM, ekf->Q_f32);
	arm_mat_zero_f32(&ekf->Q);
	Q[0] = Q[8] = Q[16] = Q[24] = EKF_QQ_INITIAL;
	Q[32] = Q[40] = Q[48] = EKF_QW_INITIAL;
	//
	arm_mat_init_f32(&ekf->R, EKF_MEASUREMENT_DIM, EKF_MEASUREMENT_DIM, ekf->R_f32);
	arm_mat_zero_f32(&ekf->R);
	R[0] = R[14] = R[28] = R[42] = EKF_RQ_INITIAL;
	R[56] = R[70] = R[84] = EKF_RA_INITIAL;
	R[98] = R[112] = R[126] = EKF_RW_INITIAL;
	R[140] = R[154] = R[168] = EKF_RM_INITIAL;
	//////////////////////////////////////////////////////////////////////////
	arm_mat_init_f32(&ekf->K, EKF_STATE_DIM, EKF_MEASUREMENT_DIM, ekf->K_f32);
	arm_mat_init_f32(&ekf->KT, EKF_MEASUREMENT_DIM, EKF_STATE_DIM, ekf->KT_f32);
	arm_mat_init_f32(&ekf->S, EKF_MEASUREMENT_DIM, EKF_MEASUREMENT_DIM, ekf->S_f32);
	//
	arm_mat_init_f32(&ekf->F, EKF_STATE_DIM, EKF_STATE_DIM, ekf->F_f32);
	arm_mat_zero_f32(&ekf->F);
	arm_mat_identity_f32(&ekf->F, 1.0f);
	//
	arm_mat_init_f32(&ekf->FT, EKF_STATE_DIM, EKF_STATE_DIM, ekf->FT_f32);
	//
	arm_mat_init_f32(&ekf->H, EKF_MEASUREMENT_DIM, EKF_STATE_DIM, H);
	arm_mat_zero_f32(&ekf->H);
	H[0] = H[8] = H[16] = H[24] = 1.0f; //q row 0~3, col 0~3
	H[53] = H[61] = H[69] = 1.0f; //w row 7~9, col 4~6
	//
	arm_mat_init_f32(&ekf->HT, EKF_STATE_DIM, EKF_MEASUREMENT_DIM, ekf->HT_f32);
	//////////////////////////////////////////////////////////////////////////
	arm_mat_init_f32(&ekf->I, EKF_STATE_DIM, EKF_STATE_DIM, ekf->I_f32);
	arm_mat_zero_f32(&ekf->I);
	arm_mat_identity_f32(&ekf->I, 1.0f);
	//////////////////////////////////////////////////////////////////////////
	arm_mat_init_f32(&ekf->X, EKF_STATE_DIM, 1, ekf->X_f32);
	arm_mat_zero_f32(&ekf->X);
	//////////////////////////////////////////////////////////////////////////
	arm_mat_init_f32(&ekf->Y, EKF_MEASUREMENT_DIM, 1, ekf->Y_f32);
	arm_mat_zero_f32(&ekf->Y);
	//////////////////////////////////////////////////////////////////////////
	//
	arm_mat_init_f32(&ekf->tmpP, EKF_STATE_DIM, EKF_STATE_DIM, ekf->tmpP_f32);
	arm_mat_init_f32(&ekf->tmpX, EKF_STATE_DIM, 1, ekf->tmpX_f32);
	arm_mat_init_f32(&ekf->tmpYX, EKF_MEASUREMENT_DIM, EKF_STATE_DIM, ekf->tmpYX_f32);
	arm_mat_init_f32(&ekf->tmpXY, EKF_STATE_DIM, EKF_MEASUREMENT_DIM, ekf->tmpXY_f32);
	arm_mat_init_f32(&ekf->tmpXX, EKF_STATE_DIM, EKF_STATE_DIM, ekf->tmpXX_f32);
	arm_mat_init_f32(&ekf->tmpXXT, EKF_STATE_DIM, EKF_STATE_DIM, ekf->tmpXXT_f32);
	arm_mat_init_f32(&ekf->tmpS, EKF_MEASUREMENT_DIM, EKF_MEASUREMENT_DIM, ekf->tmpS_f32);
	//////////////////////////////////////////////////////////////////////////
}
Пример #14
0
void SRCKF_New(SRCKF_Filter* srckf)
{
	float32_t kesi;
	arm_matrix_instance_f32 KesiPuls, KesiMinu;
	float32_t KesiPuls_f32[SRCKF_STATE_DIM * SRCKF_STATE_DIM], KesiMinus_f32[SRCKF_STATE_DIM * SRCKF_STATE_DIM];
	float32_t *S = srckf->S_f32;
	float32_t *SQ = srckf->SQ_f32;
	float32_t *SR = srckf->SR_f32;
	//////////////////////////////////////////////////////////////////////////
	//initialise weight
	srckf->W = 1.0f / (float32_t)SRCKF_CP_POINTS;
	arm_sqrt_f32(srckf->W, &srckf->SW);
	//initialise kesi
	//generate the cubature point
	kesi = (float32_t)SRCKF_STATE_DIM;
	arm_sqrt_f32(kesi, &kesi);
	arm_mat_init_f32(&KesiPuls, SRCKF_STATE_DIM, SRCKF_STATE_DIM, KesiPuls_f32);
	arm_mat_init_f32(&KesiMinu, SRCKF_STATE_DIM, SRCKF_STATE_DIM, KesiMinus_f32);
	arm_mat_identity_f32(&KesiPuls, kesi);
	arm_mat_identity_f32(&KesiMinu, -kesi);
	arm_mat_init_f32(&srckf->Kesi, SRCKF_STATE_DIM, SRCKF_CP_POINTS, srckf->Kesi_f32);
	arm_mat_setsubmatrix_f32(&srckf->Kesi, &KesiPuls, 0, 0);
	arm_mat_setsubmatrix_f32(&srckf->Kesi, &KesiMinu, 0, SRCKF_STATE_DIM);
	arm_mat_init_f32(&srckf->iKesi, SRCKF_STATE_DIM, 1, srckf->iKesi_f32);
	
	//initialise state covariance
	arm_mat_init_f32(&srckf->S, SRCKF_STATE_DIM, SRCKF_STATE_DIM, srckf->S_f32);
	arm_mat_zero_f32(&srckf->S);
	S[0] = S[8] = S[16] = S[24] = SRCKF_PQ_INITIAL;
	S[32] = S[40] = S[48] = SRCKF_PW_INITIAL;
	arm_mat_init_f32(&srckf->ST, SRCKF_STATE_DIM, SRCKF_STATE_DIM, srckf->ST_f32);
	//initialise measurement covariance
	arm_mat_init_f32(&srckf->SY, SRCKF_MEASUREMENT_DIM, SRCKF_MEASUREMENT_DIM, srckf->SY_f32);
	arm_mat_init_f32(&srckf->SYI, SRCKF_MEASUREMENT_DIM, SRCKF_MEASUREMENT_DIM, srckf->SYI_f32);
	arm_mat_init_f32(&srckf->SYT, SRCKF_MEASUREMENT_DIM, SRCKF_MEASUREMENT_DIM, srckf->SYT_f32);
	arm_mat_init_f32(&srckf->SYTI, SRCKF_MEASUREMENT_DIM, SRCKF_MEASUREMENT_DIM, srckf->SYTI_f32);
	arm_mat_init_f32(&srckf->PXY, SRCKF_STATE_DIM, SRCKF_MEASUREMENT_DIM, srckf->PXY_f32);
	arm_mat_init_f32(&srckf->tmpPXY, SRCKF_STATE_DIM, SRCKF_MEASUREMENT_DIM, srckf->tmpPXY_f32);
	//initialise SQ
	arm_mat_init_f32(&srckf->SQ, SRCKF_STATE_DIM, SRCKF_STATE_DIM, srckf->SQ_f32);
	arm_mat_zero_f32(&srckf->SQ);
	SQ[0] = SQ[8] = SQ[16] = SQ[24] = SRCKF_QQ_INITIAL;
	SQ[32] = SQ[40] = SQ[48] = SRCKF_QW_INITIAL;
	//initialise SR
	arm_mat_init_f32(&srckf->SR, SRCKF_MEASUREMENT_DIM, SRCKF_MEASUREMENT_DIM, srckf->SR_f32);
	arm_mat_zero_f32(&srckf->SR);
	SR[0] = SR[7] = SR[14] = SRCKF_RA_INITIAL;
	SR[21] = SR[28] = SR[35] = SRCKF_RM_INITIAL;
	//other stuff
	//cubature points
	arm_mat_init_f32(&srckf->XCP, SRCKF_STATE_DIM, SRCKF_CP_POINTS, srckf->XCP_f32);
	//propagated cubature points
	arm_mat_init_f32(&srckf->XPCP, SRCKF_STATE_DIM, SRCKF_CP_POINTS, srckf->XPCP_f32);
	arm_mat_init_f32(&srckf->YPCP, SRCKF_MEASUREMENT_DIM, SRCKF_CP_POINTS, srckf->YPCP_f32);
	arm_mat_init_f32(&srckf->XCPCM, SRCKF_STATE_DIM, SRCKF_CP_POINTS, srckf->XCPCM_f32);
	arm_mat_init_f32(&srckf->tmpXCPCM, SRCKF_STATE_DIM, SRCKF_CP_POINTS, srckf->tmpXCPCM_f32);
	arm_mat_init_f32(&srckf->YCPCM, SRCKF_MEASUREMENT_DIM, SRCKF_CP_POINTS, srckf->YCPCM_f32);
	arm_mat_init_f32(&srckf->YCPCMT, SRCKF_CP_POINTS, SRCKF_MEASUREMENT_DIM, srckf->YCPCMT_f32);
	
	arm_mat_init_f32(&srckf->XCM, SRCKF_STATE_DIM, SRCKF_CP_POINTS + SRCKF_STATE_DIM, srckf->XCM_f32);
	//initialise fill SQ
	arm_mat_setsubmatrix_f32(&srckf->XCM, &srckf->SQ, 0, SRCKF_CP_POINTS);
	
	arm_mat_init_f32(&srckf->YCM, SRCKF_MEASUREMENT_DIM, SRCKF_CP_POINTS + SRCKF_MEASUREMENT_DIM, srckf->YCM_f32);
	//initialise fill SR
	arm_mat_setsubmatrix_f32(&srckf->YCM, &srckf->SR, 0, SRCKF_CP_POINTS);
	
	arm_mat_init_f32(&srckf->XYCM, SRCKF_STATE_DIM, SRCKF_CP_POINTS + SRCKF_MEASUREMENT_DIM, srckf->XYCM_f32);
	//Kalman gain
	arm_mat_init_f32(&srckf->K, SRCKF_STATE_DIM, SRCKF_MEASUREMENT_DIM, srckf->K_f32);
	//////////////////////////////////////////////////////////////////////////
	//state vector
	arm_mat_init_f32(&srckf->X, SRCKF_STATE_DIM, 1, srckf->X_f32);
	arm_mat_zero_f32(&srckf->X);
	//measurement vector
	arm_mat_init_f32(&srckf->Y, SRCKF_MEASUREMENT_DIM, 1, srckf->Y_f32);
	arm_mat_zero_f32(&srckf->Y);
	arm_mat_init_f32(&srckf->tmpY, SRCKF_MEASUREMENT_DIM, 1, srckf->tmpY_f32);
	arm_mat_zero_f32(&srckf->tmpY);
}
arm_matrix_instance_f32 c_rc_LQR2_errorStateVector_I(pv_type_datapr_attitude attitude,
													 pv_type_datapr_attitude attitude_reference,
													 pv_type_datapr_position position,
													 pv_type_datapr_position position_reference,
													 pv_type_datapr_servos servo,
													 pv_type_datapr_servos servo_reference,
													 float sample_time, bool stop){

	arm_matrix_instance_f32 c_rc_LQR2_error_state_vector, c_rc_LQR2_state_vector,  c_rc_LQR2_reference_state_vector;
	//Integradores
	//Vector integration of error(Trapezoidal method)
	if (stop){
		c_rc_LQR2_deltaxsi[0]=0;
		c_rc_LQR2_deltaxsiant[0]=0;
		c_rc_LQR2_xsi[0]=0;
		c_rc_LQR2_xsiant[0]=0;
		c_rc_LQR2_xsi[1]=0;
		c_rc_LQR2_xsiant[1]=0;
		c_rc_LQR2_deltaxsi[1]=0;
		c_rc_LQR2_deltaxsiant[1]=0;
	}else{
		c_rc_LQR2_deltaxsi[0]=position.z-position_reference.z;
		c_rc_LQR2_xsi[0]=c_rc_LQR2_xsiant[0]+(((float32_t)sample_time)*(c_rc_LQR2_deltaxsi[0]+c_rc_LQR2_deltaxsiant[0])*0.5);
		c_rc_LQR2_deltaxsi[1]=attitude.yaw-attitude_reference.yaw;
		c_rc_LQR2_xsi[1]=c_rc_LQR2_xsiant[1]+(((float32_t)sample_time)*(c_rc_LQR2_deltaxsi[1]+c_rc_LQR2_deltaxsiant[1])*0.5);
	}
	// anti_windup
	c_rc_LQR2_xsi[0]=c_rc_LQR2_saturation(c_rc_LQR2_xsi[0],-0.2,0.2);
	c_rc_LQR2_xsi[1]=c_rc_LQR2_saturation(c_rc_LQR2_xsi[1],-0.2,0.2);

	//update
	c_rc_LQR2_deltaxsiant[0]=c_rc_LQR2_deltaxsi[0]=0;
	c_rc_LQR2_deltaxsiant[1]=c_rc_LQR2_deltaxsi[1]=0;
	c_rc_LQR2_xsiant[1]=c_rc_LQR2_xsi[0];
	c_rc_LQR2_xsiant[1]=c_rc_LQR2_xsi[1];

	//State Vector
	c_rc_LQR2_state_vector_I_f32[STATE_X]=position.x;
	c_rc_LQR2_state_vector_I_f32[STATE_Y]=position.y;
	c_rc_LQR2_state_vector_I_f32[STATE_Z]=position.z;
	c_rc_LQR2_state_vector_I_f32[STATE_ROLL]=attitude.roll;
	c_rc_LQR2_state_vector_I_f32[STATE_PITCH]=attitude.pitch;
	c_rc_LQR2_state_vector_I_f32[STATE_YAW]=attitude.yaw;
	c_rc_LQR2_state_vector_I_f32[STATE_ALPHA_R]=servo.alphar;
	c_rc_LQR2_state_vector_I_f32[STATE_ALPHA_L]=servo.alphal;
	c_rc_LQR2_state_vector_I_f32[STATE_DX]=position.dotX;
	c_rc_LQR2_state_vector_I_f32[STATE_DY]=position.dotY;
	c_rc_LQR2_state_vector_I_f32[STATE_DZ]=position.dotZ;
	c_rc_LQR2_state_vector_I_f32[STATE_DROLL]=attitude.dotRoll;
	c_rc_LQR2_state_vector_I_f32[STATE_DPITCH]=attitude.dotPitch;
	c_rc_LQR2_state_vector_I_f32[STATE_DYAW]=attitude.dotYaw;
	c_rc_LQR2_state_vector_I_f32[STATE_DALPHA_R]=servo.dotAlphar;
	c_rc_LQR2_state_vector_I_f32[STATE_DALPHA_L]=servo.dotAlphal;
	c_rc_LQR2_state_vector_I_f32[STATE_INT_Z]=c_rc_LQR2_xsi[0];
	c_rc_LQR2_state_vector_I_f32[STATE_INT_YAW]=c_rc_LQR2_xsi[1];


	//Updates the height equilibrium point according to the reference
	c_rc_LQR2_state_vector_reference_I_f32[STATE_X]=position_reference.x;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_Y]=position_reference.y;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_Z]=position_reference.z;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_ROLL]=attitude_reference.roll;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_PITCH]=attitude_reference.pitch;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_YAW]=attitude_reference.yaw;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_ALPHA_R]=servo_reference.alphar;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_ALPHA_L]=servo_reference.alphal;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_DX]=position_reference.dotX;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_DY]=position_reference.dotY;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_DZ]=position_reference.dotZ;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_DROLL]=attitude_reference.dotRoll;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_DPITCH]=attitude_reference.dotPitch;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_DYAW]=attitude_reference.dotYaw;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_DALPHA_R]=servo_reference.dotAlphar;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_DALPHA_L]=servo_reference.dotAlphal;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_INT_Z]=0;
	c_rc_LQR2_state_vector_reference_I_f32[STATE_INT_YAW]=0;

	//Initializes the matrices
	arm_mat_init_f32(&c_rc_LQR2_state_vector, 18, 1, (float32_t *)c_rc_LQR2_state_vector_I_f32);
	arm_mat_init_f32(&c_rc_LQR2_reference_state_vector, 18, 1, (float32_t *)c_rc_LQR2_state_vector_reference_I_f32);
	arm_mat_init_f32(&c_rc_LQR2_error_state_vector, 18, 1, (float32_t *)c_rc_LQR2_error_state_vector_I_f32);
	//e(t)=x(k)- xr(k)
	arm_mat_sub_f32(&c_rc_LQR2_state_vector, &c_rc_LQR2_reference_state_vector, &c_rc_LQR2_error_state_vector);

	return c_rc_LQR2_error_state_vector;
}
Пример #16
0
void EKF_Attitude::innovate_priori(Quaternion& quaternion,
					float Gx,
					float Gy,
					float Gz){

	float quaternion_array[4] = {quaternion.w, quaternion.x, quaternion.y, quaternion.z};
	arm_matrix_instance_f32 q;
	arm_mat_init_f32(&q, 4, 1, quaternion_array);

	static uint32_t timestamp;
	static float 	dt;

	dt = Time.get_time_since_sec(timestamp);

	//---------------------- PREDICTION -----------------------------
	//1. Obtain the angular velocities:
	float wx = (Gx*2*PI)/360.0;
	float wy = (Gy*2*PI)/360.0;
	float wz = (Gz*2*PI)/360.0;

	//2. Calculate the discrete time state transition matrix:
	float32_t omega_f32[16] = {
			0, -wx, -wy, -wz,
			wx, 0,   wz, -wy,
			wy, -wz, 0,   wx,
			wz, wy, -wx,  0};

	arm_matrix_instance_f32 omega;      /* Matrix Omega Instance */
	arm_mat_init_f32(&omega, 4, 4, omega_f32);

	//Ak = I + 0.5*omega*T;
	arm_mat_scale_f32(&omega, 0.5*dt, &temp4x4);
	arm_mat_add_f32(&I, &temp4x4, &Ak);

	//3. Calculation of the a priori system state:
	// q = Ak*q
	arm_mat_mult_f32(&Ak, &q, &temp4x1);

	//memcpy((void*)quaternion, (void*)temp4x1_f32, 4);
	/*quaternion[0] = temp4x1_f32[0];
	quaternion[1] = temp4x1_f32[1];
	quaternion[2] = temp4x1_f32[2];
	quaternion[3] = temp4x1_f32[3];*/
	quaternion.w = temp4x1_f32[0];
	quaternion.x = temp4x1_f32[1];
	quaternion.y = temp4x1_f32[2];
	quaternion.z = temp4x1_f32[3];

	//4. Calculation of the a proiri noise covariance matrix:
	//   Pk = Ak*Pk*Ak.' + Qk;
	arm_mat_trans_f32(&Ak, &Ak_trans);

	//temp = Ak*Pk
	arm_mat_mult_f32(&Ak, &Pk, &temp4x4);
	//Pk = temp*Ak.'
	arm_mat_mult_f32(&temp4x4, &Ak_trans, &Pk);
	//temp = Pk + Qk:
	arm_mat_add_f32(&Pk, &Qk, &temp4x4);
	//Pk = temp;
	copy_matrix(&Pk, &temp4x4);

	timestamp = Time.get_timestamp();
}
Пример #17
0
EKF_Attitude::EKF_Attitude(){
	//Parameters
	arm_mat_init_f32(&Pk, 4, 4, Pk_f32);
	arm_mat_init_f32(&R,  3, 3, R_f32);
	arm_mat_init_f32(&Qk, 4, 4, Qk_f32);
	arm_mat_init_f32(&I,  4, 4, I_f32);
	arm_mat_init_f32(&x,  2, 1, x_f32);

	//Helpers:
	arm_mat_init_f32(&Ak,       4, 4, Ak_f32);
	arm_mat_init_f32(&Ak_trans, 4, 4, Ak_trans_f32);

	arm_mat_init_f32(&S,   	  3, 3, S_f32);
	arm_mat_init_f32(&K_k1,   4, 3, K_k1_f32);
	arm_mat_init_f32(&K_k2,   4, 3, K_k2_f32);
	arm_mat_init_f32(&h1_q,   3, 1, h1_q_f32);
	arm_mat_init_f32(&q_corr, 4, 1, q_corr_f32);
	arm_mat_init_f32(&q_corr_2, 4, 1, q_corr_2_f32);


	//Temps
	arm_mat_init_f32(&temp4x4,  4, 4, temp4x4_f32);
	arm_mat_init_f32(&temp4x4_2,  4, 4, temp4x4_2_f32);
	arm_mat_init_f32(&temp3x4,  3, 4, temp3x4_f32);
	arm_mat_init_f32(&temp4x3,  4, 3, temp4x3_f32);
	arm_mat_init_f32(&temp3x3,  3, 3, temp3x3_f32);
	arm_mat_init_f32(&temp3x1,  3, 1, temp3x1_f32);
	arm_mat_init_f32(&temp4x1,  4, 1, temp4x1_f32);
	arm_mat_init_f32(&null4x4,  4, 4, null4x4_f32);


	//arm_mat_scale_f32(&R, 0.0001, &temp3x3);
	//copy_matrix(&R, &temp3x3);

	arm_mat_scale_f32(&Qk, 0.0001, &temp4x4);
	copy_matrix(&Qk, &temp4x4);

}
Пример #18
0
void EKF_Attitude::innovate_stage2(Quaternion& quaternion,
							 float Mx,
							 float My,
							 float Mz){
	float quaternion_array[4] = {quaternion.w, quaternion.x, quaternion.y, quaternion.z};
	arm_matrix_instance_f32 q;
	arm_mat_init_f32(&q, 4, 1, quaternion_array);

	//----------------------   MEASUREMENT UPDATE   -----------------------------
	//1: Calculation of the Jacobian matrix:
		float32_t H_k2_f32[16] = {
				 2*quaternion.z,  2*quaternion.y,  2*quaternion.x,  2*quaternion.w,
				 2*quaternion.w, -2*quaternion.x, -2*quaternion.y, -2*quaternion.z,
				-2*quaternion.x, -2*quaternion.w,  2*quaternion.z,  2*quaternion.y
		};
		arm_matrix_instance_f32 H_k2;      /* Matrix Omega Instance */
		arm_mat_init_f32(&H_k2, 3, 4, H_k2_f32);

	//2: Calculate the Kalman Gain:
		/*    S = inv(H_k2 * Pk * H_k2.' + V_k2 * R_k2 * V_k2.');
			  K_k1 = Pk * H_k2.' * S;
		*/

		//temp3x3 = H_k2 * Pk * H_k2.'
		arm_mat_trans_f32(&H_k2, &temp4x3);
		arm_mat_mult_f32(&H_k2, &Pk, &temp3x4);
		arm_mat_mult_f32(&temp3x4, &temp4x3, &temp3x3);

		//temp3x3 = inv(temp3x3 + R)   ( = S!!)
		arm_mat_add_f32(&temp3x3, &R, &S);
		arm_mat_inverse_f32(&S, &temp3x3);

		//K_k2 = Pk * H_k2.'    (temp4x3 = H_k2.')
		arm_mat_mult_f32(&Pk, &temp4x3, &K_k2);
		arm_mat_mult_f32(&K_k2, &temp3x3, &temp4x3);

		copy_matrix(&K_k2, &temp4x3);

	//3: Reading of the magnetometer data:
		float32_t z_k2_f32[3] = {
				Mx,
				My,
				Mz,
		};
		arm_matrix_instance_f32 z_k2;      /* Matrix Omega Instance */
		arm_mat_init_f32(&z_k2, 3, 1, z_k2_f32);

   //4: Calculation of h2(q):
		float32_t h2_q_f32[3] = {
				2*quaternion.x*quaternion.y + 2*quaternion.w*quaternion.z,
				  quaternion.w*quaternion.w - quaternion.x*quaternion.x- quaternion.y*quaternion.y - quaternion.z*quaternion.z,
				2*quaternion.y*quaternion.z - 2*quaternion.w*quaternion.x
		};
		arm_matrix_instance_f32 h2_q;      /* Matrix Omega Instance */
		arm_mat_init_f32(&h2_q, 3, 1, h2_q_f32);

    //5: Calculation of the correction factor
    	//q_corr_2 = K_k2*(z_k2 - h2_q);
		arm_mat_sub_f32(&z_k2, &h2_q, &temp3x1);
		arm_mat_mult_f32(&K_k2, &temp3x1, &q_corr_2);
		q_corr_2.pData[1] = 0;
		q_corr_2.pData[2] = 0;

    //6: Calculation of the a posteriori state estimation
	    //q = q + q_2;
		arm_mat_add_f32(&q, &q_corr_2, &temp4x1);
		copy_matrix(&q, &temp4x1);

	//7: Calculation of a aposteriori error covariance matrix
	    //Pk = (I - K_k2 * H_k2)*Pk;
		arm_mat_mult_f32(&K_k2, &H_k2, &temp4x4);
		arm_mat_sub_f32(&I, &temp4x4, &temp4x4_2);

		arm_mat_mult_f32(&temp4x4_2, &Pk, &temp4x4);
		copy_matrix(&Pk, &temp4x4);

		quaternion.w = quaternion_array[0];
		quaternion.x = quaternion_array[1];
		quaternion.y = quaternion_array[2];
		quaternion.z = quaternion_array[3];
}
Пример #19
0
void EKF_Attitude::innovate_stage1(Quaternion& quaternion,
							 float Ax,
							 float Ay,
							 float Az){
	float quaternion_array[4] = {quaternion.w, quaternion.x, quaternion.y, quaternion.z};
	arm_matrix_instance_f32 q;
	arm_mat_init_f32(&q, 4, 1, quaternion_array);

	//----------------------   MEASUREMENT UPDATE   -----------------------------
	//1: Calculation of the Jacobian matrix:
		float32_t H_k1_f32[16] = {
				-2*quaternion.y,  2*quaternion.z, -2*quaternion.w, 2*quaternion.x,
				 2*quaternion.x,  2*quaternion.w,  2*quaternion.z, 2*quaternion.y,
				 2*quaternion.w, -2*quaternion.x, -2*quaternion.y, 2*quaternion.z
		};
		arm_matrix_instance_f32 H_k1;      /* Matrix Omega Instance */
		arm_mat_init_f32(&H_k1, 3, 4, H_k1_f32);

	//2: Calculate the Kalman Gain:
		/*    S = inv(H_k1 * Pk * H_k1.' + V_k1*R_k1*V_k1.');
			  K_k1 = Pk * H_k1.' * S;
		*/

		//temp3x3 = H_k1 * Pk * H_k1.'
		arm_mat_trans_f32(&H_k1, &temp4x3);
		arm_mat_mult_f32(&H_k1, &Pk, &temp3x4);
		arm_mat_mult_f32(&temp3x4, &temp4x3, &temp3x3);

		//temp3x3 = inv(temp3x3 + R)   ( = S!!)
		arm_mat_add_f32(&temp3x3, &R, &S);
		arm_mat_inverse_f32(&S, &temp3x3);

		//K_k1 = Pk * H_k1.'    (temp4x3 = H_k1.')
		arm_mat_mult_f32(&Pk, &temp4x3, &K_k1);
		arm_mat_mult_f32(&K_k1, &temp3x3, &temp4x3);

		copy_matrix(&K_k1, &temp4x3);

		//3: Reading of the accelerometer data:
		float32_t z_f32[3] = {
				Ax,
				Ay,
				Az,
		};
		arm_matrix_instance_f32 z;      /* Matrix Omega Instance */
		arm_mat_init_f32(&z, 3, 1, z_f32);

   //4: Calculation of h1(q):
		float32_t h1_q_f32[3] = {
				2*quaternion.x*quaternion.z-2*quaternion.w*quaternion.y,
				2*quaternion.w*quaternion.x+2*quaternion.y*quaternion.z,
				quaternion.w*quaternion.w - quaternion.x*quaternion.x- quaternion.y*quaternion.y + quaternion.z*quaternion.z
		};
		arm_matrix_instance_f32 h1_q;      /* Matrix Omega Instance */
		arm_mat_init_f32(&h1_q, 3, 1, h1_q_f32);

	//5: Calculation of the correction factor
		//q_corr = K_k1*(z - h1_q);
		arm_mat_sub_f32(&z, &h1_q, &temp3x1);
		arm_mat_mult_f32(&K_k1, &temp3x1, &q_corr);
		q_corr.pData[3] = 0;

	//6: Calculation of the a posteriori state estimation
		//q = q + q_1;
		arm_mat_add_f32(&q, &q_corr, &temp4x1);
		copy_matrix(&q, &temp4x1);

	//7: Calculation of a aposteriori error covariance matrix
		//Pk = (I - K_k1 * H_k1)*Pk;
		arm_mat_mult_f32(&K_k1, &H_k1, &temp4x4);
		arm_mat_sub_f32(&I, &temp4x4, &temp4x4_2);

		arm_mat_mult_f32(&temp4x4_2, &Pk, &temp4x4);
		copy_matrix(&Pk, &temp4x4);

		quaternion.w = quaternion_array[0];
		quaternion.x = quaternion_array[1];
		quaternion.y = quaternion_array[2];
		quaternion.z = quaternion_array[3];
}