匿名四轴【 任务一(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;

如有错误希望在评论区指出
排版不佳

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值