Exemple #1
0
void run_ekf(struct tilt_data* td) {
  /* model noise covariance matrix       */
  double Q[4]={0.001, 0.0,
	       0.0,   0.003};
  /* measurement noise covariance matrix */
  double R[1]={1.7};
  /* initial x */
  double X0[2] = {0.0, 0.0};
  /* initial state covariance matrix */
  double P0[4] = {1.0, 0.0,
		  0.0, 1.0};
  /* measure */
  double y[1];
  /* command */
  double u[1];

  struct ekf_filter* filter;
  filter = ekf_filter_new(2, 1, Q, R, linear_filter, linear_measure);
  tilt_init(td, 150, X0);
  ekf_filter_reset(filter, X0, P0);

  /* filter run */
  for (iter=0; iter<td->nb_samples; iter++) {
    u[0] = td->gyro[iter];
    y[0] = td->m_angle[iter];
    ekf_filter_predict(filter, u);
    ekf_filter_update(filter, y);
    ekf_filter_get_state(filter, X0, P0);
    tilt_data_save_state(td, iter, X0, P0);
  }
}
Exemple #2
0
/*
 *perform kalman filter at time K, estimate best navigation parameter error at time K
 *estimate navigation parameters at current time when acc bias estimation is stable
 */
void vIEKFProcessTask(void* pvParameters)
{
	u8 i,j;
	u8 acc_bias_stable = 0;	//indicate whether acc bias is stably estimated
	char logData[100]={0};
	
	ekf_filter filter;	
	float dt;
	
	float measure[5]={0};
	float insBufferK[INS_FRAME_LEN];
	float insBufferCur[INS_FRAME_LEN];
	float *p_insBuffer;

	float direction;
	u8 temp;
	GPSDataType gdt={0.0,0.0,0.0,0.0,0.0};
	portBASE_TYPE xstatus;
	
	PosConDataType pcdt;	//position message send to flight control task

	/*initial filter*/
	filter=ekf_filter_new(9,5,(float *)iQ,(float *)iR,INS_GetA,INS_GetH,INS_aFunc,INS_hFunc);
	memcpy(filter->x,x,filter->state_dim*sizeof(float));
	memcpy(filter->P,iP,filter->state_dim*filter->state_dim*sizeof(float));

	/*capture an INS frame*/
	xQueueReceive(AHRSToINSQueue,&p_insBuffer,portMAX_DELAY);
	/*last number in buffer represent time interval, not time */
	p_insBuffer[INDEX_DT]=0.0;
	
	Blinks(LED1,4);
	
	for(;;)
	{
		/*capture an INS frame*/
		xQueueReceive(AHRSToINSQueue,&p_insBuffer,portMAX_DELAY);
		PutToBuffer(p_insBuffer);
		p_insBuffer[INDEX_DT]=0.0;
		
		ReadBufferBack(insBufferK);
		dt=insBufferK[INDEX_DT];
		
		/*do INS integration at time K*/
		INS_Update(navParamK, insBufferK);
		
		/*do INS integration at current time*/
		if(acc_bias_stable)
		{
			ReadBufferFront(insBufferCur);
			INS_Update(navParamCur,insBufferCur);
		}
		
		/*predict navigation error at time K*/
		EKF_predict(filter
					, (void *)(insBufferK+3)
					, NULL
					, (void *)(&dt)
					, (void *)(filter->A)
					, NULL);
			
		xstatus=xQueueReceive(xUartGPSQueue,&gdt,0);	//get measurement data
		if(xstatus == pdPASS)
		{
			float meas_Err[5]={0.0};
			
			direction = gdt.COG*0.0174533;

			temp=(u8)(gdt.Lati*0.01);
			measure[0]=(0.01745329*(temp+(gdt.Lati-temp*100.0)*0.0166667)-initPos[0])*6371004;
			
			temp=(u8)(gdt.Long*0.01);
			measure[1]=(0.01745329*(temp+(gdt.Long-temp*100.0)*0.0166667)-initPos[1])*4887077;
			
			measure[2]=gdt.Alti-initPos[2];
			measure[3]=gdt.SPD*0.51444*arm_cos_f32(direction);
			measure[4]=gdt.SPD*0.51444*arm_sin_f32(direction);
			
			for(i=0;i<5;i++)
			{
				meas_Err[i] = navParamK[i] - measure[i];
			}
			
			/*data record*/
			/*uncomment this to record data for matlab simulation*/
//			sprintf(logData,"%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\r\n",
//											insBufferK[0],insBufferK[1],insBufferK[2],
//											insBufferK[3],insBufferK[4],insBufferK[5],
//											insBufferK[6],insBufferK[7],
//											measure[0],measure[1],measure[2],measure[3],measure[4],
//											navParamK[3],navParamK[4]);
//			xQueueSend(xDiskLogQueue,logData,0);
			
			sprintf(logData, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\r\n",
							measure[0],measure[1],measure[3],measure[4],
							navParamK[0],navParamK[1],navParamK[3],navParamK[4],
							navParamCur[0],navParamCur[1],navParamCur[3],navParamCur[4]);
			xQueueSend(xDiskLogQueue,logData,0);
			/*update*/
			EKF_update(filter
						, (void *)meas_Err
						, NULL
						, NULL
						, (void *)(filter->x)
						, NULL);		
//			printf("%.2f %.2f %.4f %.4f %.4f\r\n",meas_Err[0],meas_Err[1],filter->x[6],filter->x[7],filter->x[8]);
			/*
			 *correct navParamCur
			 */
			if(acc_bias_stable)
			{
				for(i=0;i<6;i++)
					navParamCur[i] -= filter->x[i];
				navParamCur[6] = filter->x[6];
				navParamCur[7] = filter->x[7];
				navParamCur[8] = filter->x[8];
				
				pcdt.posX = navParamCur[0];
				pcdt.posY = navParamCur[1];
				pcdt.posZ = navParamCur[2];
				
				pcdt.veloX = navParamCur[3];
				pcdt.veloY = navParamCur[4];
				pcdt.veloZ = navParamCur[5];
				
				/*put to queue*/
				xQueueSend(INSToFlightConQueue,&pcdt,0);
			}
			
			/*correct navParameters at time K
			 *reset error state x*/			
			for(i=0;i<6;i++)
			{
				navParamK[i] -= filter->x[i];
				filter->x[i] = 0.0;
			}
			navParamK[6] = filter->x[6];
			navParamK[7] = filter->x[7];
			navParamK[8] = filter->x[8];			
			
			/*when acc bias stable, 
			 *calculate current navigation parameters*/
			if(!acc_bias_stable && filter->P[60]<0.007)
			{
				acc_bias_stable = 1;
				//set init value
				for(i=0;i<filter->state_dim;i++)
				{
					navParamCur[i] = navParamK[i];
				}
				//extrapolate current navigation parameters from time K
				for(i=0;i<GPS_DELAY_CNT;i++) 
				{
					if(i+buffer_header >= GPS_DELAY_CNT)
					{
						for(j=0;j<INS_FRAME_LEN;j++)
							insBufferCur[j] = IMU_delay_buffer[(i+buffer_header-GPS_DELAY_CNT)*INS_FRAME_LEN+j];
					}
					else
					{
						for(j=0;j<INS_FRAME_LEN;j++)
							insBufferCur[j] = IMU_delay_buffer[(i+buffer_header)*INS_FRAME_LEN+j];
					}
					insBufferCur[0] -= navParamK[6];
					insBufferCur[1] -= navParamK[7];
					insBufferCur[2] -= navParamK[8];
					
					INS_Update(navParamCur,insBufferCur);
				}
				Blinks(LED1,1);
			}
//			printf("%.1f %.1f %.1f %.1f %.1f\r\n",navParamK[0],navParamK[1],navParamK[2],navParamK[3],navParamK[4]);
		}
		else
		{
			/*data record*/
			sprintf(logData,"%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\r\n",
											insBufferK[0],insBufferK[1],insBufferK[2],
											insBufferK[3],insBufferK[4],insBufferK[5],
											insBufferK[6],insBufferK[7],
											0.0,0.0,0.0,0.0,0.0,
											navParamK[3],navParamK[4]);
			xQueueSend(xDiskLogQueue,logData,0);
		}
	}
}
void run_ekf (void) {
  /* initial state covariance matrix */
  double P[7*7] = {P0Q,   0.0,   0.0,   0.0,   0.0,   0.0,   0.0,
		   0.0,   P0Q,   0.0,   0.0,   0.0,   0.0,   0.0,
		   0.0,   0.0,   P0Q,   0.0,   0.0,   0.0,   0.0,
		   0.0,   0.0,   0.0,   P0Q,   0.0,   0.0,   0.0,
		   0.0,   0.0,   0.0,   0.0,   P0B,   0.0,   0.0,
		   0.0,   0.0,   0.0,   0.0,   0.0,   P0B,   0.0,
		   0.0,   0.0,   0.0,   0.0,   0.0,   0.0,   P0B };
  /* model noise covariance matrix */
  double Q[7*7] = {Q0G,   0.0,   0.0,   0.0,   0.0,   0.0,   0.0,
		   0.0,   Q0G,   0.0,   0.0,   0.0,   0.0,   0.0,
		   0.0,   0.0,   Q0G,   0.0,   0.0,   0.0,   0.0,
		   0.0,   0.0,   0.0,   Q0G,   0.0,   0.0,   0.0,
		   0.0,   0.0,   0.0,   0.0,   Q0B,   0.0,   0.0,
		   0.0,   0.0,   0.0,   0.0,   0.0,   Q0B,   0.0,
		   0.0,   0.0,   0.0,   0.0,   0.0,   0.0,   Q0B };
  /* measurement noise covariance matrix */
  double R[1]={1.7};
  /* state [q0, q1, q2, q3, bp, bq, br] */
  double X[7];
  /* measure */
  double Y[1];
  /* command */
  double U[3] = {0.0, 0.0, 0.0};

  struct ekf_filter* ekf;
  ekf = ekf_filter_new(7, 1, Q, R, linear_filter, linear_measure);
  ahrs_quat_init(ad, 150, X);
  ekf_filter_reset(ekf, X, P);

  /* filter run */
  int iter;
  for (iter=0; iter < ad->nb_samples; iter++) {
    U[0] = ad->gyro_p[iter];// - X[4];
    U[1] = ad->gyro_q[iter];// - X[5];
    U[2] = ad->gyro_r[iter];// - X[6];
    ekf_filter_predict(ekf, U);
    norm_quat(X);
    ahrs_state = iter%3;
    switch (ahrs_state) {
    case UPDATE_PHI:
      Y[0] = phi_of_accel(ad->accel_x[iter], ad->accel_y[iter], ad->accel_z[iter]);
      break;
    case UPDATE_THETA:
      Y[0] = theta_of_accel(ad->accel_x[iter], ad->accel_y[iter], ad->accel_z[iter]);
      break;
    case UPDATE_PSI: {
      double eulers[3];
      eulers_of_quat(eulers, X);
      Y[0] = psi_of_mag(eulers[0], eulers[1], ad->mag_x[iter], ad->mag_y[iter], ad->mag_z[iter]);
      break;
    }
    }
    ekf_filter_update(ekf, Y);
    norm_quat(X);
    //    printf("P66 %f\n", P[6*7 + 6]);
    ekf_filter_get_state(ekf, X, P);
    ahrs_data_save_state_quat(ad, iter, X, P);
    ahrs_data_save_measure(ad, iter);
  }
}