匿名四軸【 任務一(1000Hz)慣性傳感器數據讀取一】

上一篇說了傳感器數據讀取,接下來來看慣性傳感器數據讀取
//我們來看這個函數現在到了第二部分慣性傳感器數據讀取
u32 test_dT_1000hz[3],test_rT[6];
static void Loop_1000Hz(void)	//1ms執行一次
{
	test_dT_1000hz[0] = test_dT_1000hz[1];
	test_rT[3] = test_dT_1000hz[1] = GetSysTime_us ();
    //記錄當前的時間,並將存儲的時間存儲在test_rT[3],
    //test_dT_1000hz[1]中
    //這樣我們再看上面就是把上次存儲的時間存儲在test_dT_1000hz[0]
    //總的來說
    //test_dT_1000hz[0]上一次時間
    //test_dT_1000hz[1]這次的時間
	test_dT_1000hz[2] = (u32)(test_dT_1000hz[1] - test_dT_1000hz[0]) ;
    //test_dT_1000hz[2]記錄這次時間與上一次時間的差值
    

	/*傳感器數據讀取*/
	Fc_Sensor_Get();
	
	/*慣性傳感器數據準備*/
	Sensor_Data_Prepare(1);
	
	/*姿態解算更新*/
	IMU_Update_Task(1);
	
	/*獲取WC_Z加速度*/
	WCZ_Acc_Get_Task();
	WCXY_Acc_Get_Task();
	
	/*飛行狀態任務*/
	Flight_State_Task(1,CH_N);
	
	/*開關狀態任務*/
	Swtich_State_Task(1);
	
	/*光流融合數據準備任務*/
	ANO_OF_Data_Prepare_Task(0.001f);


	/*數傳數據交換*/
	ANO_DT_Data_Exchange();
	
	test_rT[4]= GetSysTime_us ();
	test_rT[5] = (u32)(test_rT[4] - test_rT[3]) ;	

}

我們來看具體的傳感器數據準備

//慣性傳感器數據準備
void Sensor_Data_Prepare(u8 dT_ms)
//在上面函數中這邊的dT_ms爲1,
//還記得我們前面談到的1000Hz是1ms執行一次,
//這邊的dT_ms指的應該就是兩次之間相隔的時間,
{	
 	//定義頻率,如果前後執行任務之間間距是1ms則可以看到頻率爲1000HZ
	float hz = 0 ;
	if(dT_ms != 0) hz = 1000/dT_ms;//判斷dT_ms是否爲0,否則不能作爲除數,避免錯誤
    
//	MPU6050_Read();
//	sensor_rotate_func(dT);
	
	/*靜止檢測*/
	motionless_check(dT_ms);
    //在後面我們會講到,可以先去看一下下面的講解,再回來看剩下的代碼
			
	MPU6050_Data_Offset(); //校準函數


	/*得出校準後的數據*/
	for(u8 i=0;i<3;i++)
	{ 
		
		sensor_val[A_X+i] = sensor.Acc_Original[i] ;

		sensor_val[G_X+i] = sensor.Gyro_Original[i] - save.gyro_offset[i] ;
		//sensor_val[G_X+i] = (sensor_val[G_X+i] >>2) <<2;
	}
	
	/*可將整個傳感器座標進行旋轉*/
//	for(u8 j=0;j<3;j++)
//	{
//		float t = 0;
//		
//		for(u8 i=0;i<3;i++)
//		{
//			
//			t += sensor_val[A_X + i] *wh_matrix[j][i]; 
//		}
//		
//		sensor_val_rot[A_X + j] = t;
//	}

//	for(u8 j=0;j<3;j++)
//	{
//		float t = 0;
//		
//		for(u8 i=0;i<3;i++)
//		{
//			
//			t += sensor_val[G_X + i] *wh_matrix[j][i]; 
//		}
//		
//		sensor_val_rot[G_X + j] = t;
//	}	

	/*賦值*/
	for(u8 i = 0;i<6;i++)
	{
		sensor_val_rot[i] = sensor_val[i];
	}

	/*數據座標轉90度*/
	sensor_val_ref[G_X] =  sensor_val_rot[G_Y] ;
	sensor_val_ref[G_Y] = -sensor_val_rot[G_X] ;
	sensor_val_ref[G_Z] =  sensor_val_rot[G_Z];

	
	sensor_val_ref[A_X] =  (sensor_val_rot[A_Y] - save.acc_offset[Y] ) ;
	sensor_val_ref[A_Y] = -(sensor_val_rot[A_X] - save.acc_offset[X] ) ;
	sensor_val_ref[A_Z] =  (sensor_val_rot[A_Z] - save.acc_offset[Z] ) ;
	
	/*單獨校準z軸模長*/
	mpu_auto_az();

//======================================================================
	
	/*軟件低通濾波*/
	for(u8 i=0;i<3;i++)
	{	
		//
		gyr_f[4][X +i] = (sensor_val_ref[G_X + i] );
		acc_f[4][X +i] = (sensor_val_ref[A_X + i] );
		//
		for(u8 j=4;j>0;j--)
		{
			//
			gyr_f[j-1][X +i] += GYR_ACC_FILTER *(gyr_f[j][X +i] - gyr_f[j-1][X +i]);
			acc_f[j-1][X +i] += GYR_ACC_FILTER *(acc_f[j][X +i] - acc_f[j-1][X +i]);
		}
		
//		LPF_1_(100,dT_ms*1e-3f,sensor_val_ref[G_X + i],sensor.Gyro[X +i]);
//		LPF_1_(100,dT_ms*1e-3f,sensor_val_ref[A_X + i],sensor.Acc[X +i]);
				
	}
	
			/*旋轉加速度補償*/
//======================================================================
	
	for(u8 i=0;i<3;i++)
	{	
		center_pos.gyro_rad_old[i] = center_pos.gyro_rad[i];
		center_pos.gyro_rad[i] =  gyr_f[0][X + i] *RANGE_PN2000_TO_RAD;//0.001065f;
		center_pos.gyro_rad_acc[i] = hz *(center_pos.gyro_rad[i] - center_pos.gyro_rad_old[i]);
	}
	
	center_pos.linear_acc[X] = +center_pos.gyro_rad_acc[Z] *center_pos.center_pos_cm[Y] - center_pos.gyro_rad_acc[Y] *center_pos.center_pos_cm[Z];
	center_pos.linear_acc[Y] = -center_pos.gyro_rad_acc[Z] *center_pos.center_pos_cm[X] + center_pos.gyro_rad_acc[X] *center_pos.center_pos_cm[Z];
	center_pos.linear_acc[Z] = +center_pos.gyro_rad_acc[Y] *center_pos.center_pos_cm[X] - center_pos.gyro_rad_acc[X] *center_pos.center_pos_cm[Y];
	
//======================================================================
	/*賦值*/
	for(u8 i=0;i<3;i++)
	{

		
		sensor.Gyro[X+i] = gyr_f[0][i];//sensor_val_ref[G_X + i];
		
		sensor.Acc[X+i] = acc_f[0][i] - center_pos.linear_acc[i]/RANGE_PN16G_TO_CMSS;//sensor_val_ref[A_X+i];//
	}
	
	/*轉換單位*/
		for(u8 i =0 ;i<3;i++)
		{
			/*陀螺儀轉換到度每秒,量程+-2000度*/
			sensor.Gyro_deg[i] = sensor.Gyro[i] *0.061036f ;//  /65535 * 4000; +-2000度 0.061

			/*陀螺儀轉換到弧度度每秒,量程+-2000度*/
			sensor.Gyro_rad[i] = sensor.Gyro_deg[i] *0.01745f;//sensor.Gyro[i] *RANGE_PN2000_TO_RAD ;//  0.001065264436f //微調值 0.0010652f
		
			/*加速度計轉換到釐米每平方秒,量程+-8G*/
			sensor.Acc_cmss[i] = (sensor.Acc[i] *RANGE_PN16G_TO_CMSS );//   /65535 * 16*981; +-8G
		
		}

}


motionless_check函數

//靜止檢測,motionless英文的意思就是靜止的,不運動的
enum
{
	X = 0,
	Y = 1,
	Z = 2,
	VEC_XYZ,
    //這裏放一個數是爲了說明這個枚舉已經有3個值了,所以VEC爲3
};
//首先我們看一下這個枚舉,如果看不懂建議先去看一下我前面寫的
//這裏是一個枚舉類型前面有講過,這裏的VEC_XYZ爲3,因爲枚舉遞增
float g_d_sum[VEC_XYZ] = {500,500,500};
s16 g_old[VEC_XYZ];//s16就是int16_t
//這邊我們還看不出這個變量有什麼用,
//不過關於這個變量的運用基本上就是下面這個函數
//所以只要看懂下面這個函數,就可以知道這個變量是用來幹什麼的
void motionless_check(u8 dT_ms)
{
	u8 t = 0;
	for(u8 i = 0;i<3;i++)
	{
     //#define ABS(x) ( (x)>0?(x):-(x) )----ABS就是取絕對值
		g_d_sum[i] += 3*ABS(sensor.Gyro_Original[i] - g_old[i]) ;
	//看到sensor.Gyro_Original[i] 不要慌,看一下我們前面有沒講過
    //果然在前面讀取傳感器數據我們曾講過這個東西,來看一下代碼
    /*
        這裏的Gyro應該是角速度
        sensor.Gyro_Original[X] = temp[1][X];
        sensor.Gyro_Original[Y] = temp[1][Y];
        sensor.Gyro_Original[Z] = temp[1][Z];
    */
    //而前面我們分析過temp中記錄中的20602傳感器的數據,
    //就相當於Gyro_Original存儲的是從20602讀出的角速度數據
    //那麼現在這行代碼這剩下g_old沒解決,g_old引用地方只有下面那句話
    //g_old[i] = sensor.Gyro_Original[i];
    //很顯然了存儲的也是角速度,那只有可能是過去的角速度,
    //想象一下,我們上面提到的幾行代碼是在下面哪一行代碼執行
    //的那麼我們下次執行到這裏時那麼Gyro_Original的值已經更新了,
    //但是g_old存儲的還是原來的,
    //那這裏g_de_sum存儲的就是原來的舊的數據
    //那麼這行代碼的意思就是(這次的值與上一次值的偏差)的絕對值*3,
    //這邊*3是什麼意思就是放大3倍的意思
		g_d_sum[i] -= dT_ms ;	
    //看到這裏需要講解一下匿名代碼是怎麼檢測靜止的
    //把前面說到的角速度差值放大3倍然後累加起來,
    //每毫秒-1,如果這個值大於10說明飛機還沒實現自穩
    //如果小於10說明飛機已經基本實現自穩
		g_d_sum[i] = LIMIT(g_d_sum[i],0,200);
    //把這個值限定在0-200之間
		if( g_d_sum[i] > 10)
		{
			t++;
		}
		
		g_old[i] = sensor.Gyro_Original[i];
	}

	if(t>=2)
	{
		flag.motionless = 0;	
		//如果出現3次大於0則可判定飛機未自穩
	}
	else
	{
		flag.motionless = 1;
	}

}
//我們看完這個函數發現這個函數最主要作用就是返回一個自穩係數
//flag.motionless,如果motionless=1則可認爲實現了自穩,
//如果爲0則可認爲沒有實現自穩。
//flag是匿名代碼貫穿始終的一個結構體所以最好遇到的時候最好注意點,
//方便之後理解代碼
typedef struct
{
	//基本狀態/傳感器
	u8 start_ok;//初始化All_Init()這個值就爲恆定的1
	u8 sensor_imu_ok;
	u8 mems_temperature_ok;
	
	u8 motionless;//自穩係數,如果爲1,實現自穩,如果爲0,則沒有實行自穩
	u8 power_state;
	u8 wifi_ch_en;
	u8 chn_failsafe;
	u8 rc_loss;	
	u8 rc_loss_back_home;
	u8 gps_ok;	

	
	//控制狀態
	u8 manual_locked;
	u8 unlock_err;
	u8 unlock_cmd;
	u8 unlock_sta;//unlocked
	u8 thr_low;
	u8 locking;
	u8 taking_off; //起飛
	u8 set_yaw;
	u8 ct_loc_hold;
	u8 ct_alt_hold;

	
	//飛行狀態
	u8 flying;
	u8 auto_take_off_land;
	u8 home_location_ok;	
	u8 speed_mode;
	u8 thr_mode;	
	u8 flight_mode;
	u8 flight_mode2;
	u8 gps_mode_en;
	u8 motor_preparation;
	u8 locked_rotor;
}_flag;

如有錯誤希望在評論區指出
排版不佳

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章