mini光流使用说明

摘自:https://blog.csdn.net/u011913159/article/details/79616492

迷你光流使用说明

 

u011913159 2018-03-19 20:07:01 14750 收藏 23

版权

为了让你有兴趣往下学习,先上个定点悬停效果视频给你欣赏一下吧!

点击打开视频链接

首先,简单介绍一下我使用的这款光流传感器。长宽高:14x11x5mm,重量约0.6克,工作电流小于10ma。先来一睹它的芳容:

实物测量图:

 

然后,简单介绍一下它的通信接口和协议:

废话不多说,先把它接到飞控上吧。我是这样接的,用电烙铁把三根杜邦线焊到模块上,然后直接插到飞控的串口即可。注意:输入电压是2.0~3.6V,电压低了模块不能正常工作,高了可能会损坏模块。

一、数据的接收和解析,这点就不详解了,根据通信协议编写代码就行,比较简单直接上代码吧。


void Mini_Flow_Receive(u8 data)
{
	static u8 RxBuffer[32];
	static u8 _data_cnt = 0;
	static u8 state = 0;
	
	static u8 fault_cnt;
	u8 sum = 0;
	
	switch(state)
	{
		case 0:
			if(data==0xFE)
			{
				state=1;
				RxBuffer[_data_cnt++]=data;
			}else state = 0;
		break;
			
		case 1:
			if(data==0x04)
			{
				state=2;
				RxBuffer[_data_cnt++]=data;
			}else state = 0;
		break;
			
		case 2:
			RxBuffer[_data_cnt++]=data;
		
			if(_data_cnt==9)
			{
				state = 0;
				_data_cnt = 0;
				
				sum =  (RxBuffer[2] + RxBuffer[3] + RxBuffer[4] + RxBuffer[5]);
				
				if(sum == RxBuffer[6]) //和校验
				{
					mini.ssi_cnt++;
					
					//读取原始数据
					mini.flow_x = ( (s16)(*(RxBuffer+3)<<8)|*(RxBuffer+2) );
					mini.flow_y = ( (s16)(*(RxBuffer+5)<<8)|*(RxBuffer+4) );
					mini.qual   = *(RxBuffer+7);
					
					//累加求位移
					mini.flow_x_i += mini.flow_x;
					mini.flow_y_i += mini.flow_y;
					
				}
			}
		break;
			
		default:
			state = 0;
			_data_cnt = 0;
		break;
	}
}

先来看看光流输出的原始数据曲线吧,测试条件:模块离桌面20厘米左右,镜头正对着桌面,手持来回平移,数据输出范围大概在+-30:

二、光流数据的处理(由于这个光流输出的数据是没有经过惯性融合的,所以必须进行处理才能使用)。

第1步,对积分位移进行一个简单的低通滤波。

        pixel_flow.fix_x_i += (mini.flow_x_i - pixel_flow.fix_x_i) *0.2;
        pixel_flow.fix_y_i += (mini.flow_y_i - pixel_flow.fix_y_i) *0.2;

第2步,用姿态角去补偿积分位移(#define  angle_to_rad  0.0174f  //角度转弧度)。

	pixel_flow.ang_x += (600.0f*tan(imu_data.rol*angle_to_rad) - pixel_flow.ang_x) *0.2;
	pixel_flow.ang_y += (600.0f*tan(imu_data.pit*angle_to_rad) - pixel_flow.ang_y) *0.2;
	
	pixel_flow.out_x_i = pixel_flow.fix_x_i - pixel_flow.ang_x;
	pixel_flow.out_y_i = pixel_flow.fix_y_i - pixel_flow.ang_y;

注意:600.0f是一个重要参数!需要慢慢调,调到怎么样才算合格呢?

当飞机在原地摇晃时,pixel_flow.fix_x_i 和 pixel_flow.ang_x 的曲线变化幅度几乎一样即可,两者相减互相抵消,达到补偿的作用。或者这么说:pixel_flow.fix_y_i 和 pixel_flow.ang_y 的曲线变化幅度几乎一样即可(特别注意,飞机在原地晃时积分位移数据会缓慢地增大或者减小,这是积分飘移现象,是正常的)。

飞机在原地摇晃时,pixel_flow.fix_x_i 和 pixel_flow.ang_x 的曲线图:

用姿态角去补偿积分位移的作用是:当飞机在原地摇晃时,使积分位移尽量保持不变。为什么要使积分位移尽量保持不变呢?很简单,因为飞机在在原地摇晃,位移没变。

飞机在原地摇晃时,姿态角补偿后的积分位移曲线图:

第3步,对积分位移进行微分处理,得到速度。

	//求微分速度
	pixel_flow.x = (pixel_flow.out_x_i - pixel_flow.out_x_i_o)/dT;	pixel_flow.out_x_i_o = pixel_flow.out_x_i;
	pixel_flow.y = (pixel_flow.out_y_i - pixel_flow.out_y_i_o)/dT;	pixel_flow.out_y_i_o = pixel_flow.out_y_i;
	
	//低通滤波
	pixel_flow.fix_x += ( pixel_flow.x - pixel_flow.fix_x ) * 0.1f;
	pixel_flow.fix_y += ( pixel_flow.y - pixel_flow.fix_y ) * 0.1f;

 

有的人看到这里可能会迷惑了,为什么要微分求速度而不是直接使用光流的输出作为速度呢?原因是:这个光流模块的输出的数据严格的说不是速度,而是连续两帧画面的相对位移,单位是像素。

飞机在一个水平面内来回平移的速度曲线图:

第4步,把数据单位转换为厘米。

//式中HIGH为实际高度,单位:米
float cpi = (HIGH / 11.914f) *2.54f ;

//积分位移单位转换为:厘米
loc_x = pixel_flow.out_x_i * cpi;
loc_y = pixel_flow.out_y_i * cpi;

//微分速度单位转换为:厘米/秒
loc_xs = pixel_flow.fix_x * cpi;
loc_ys = pixel_flow.fix_y * cpi;

至此,光流数据的处理算是基本完成了,有了积分位移和微分速度这两个参数,就可以进行水平面内的位置环和速度环的串级PID控制了。


最后给大家提供一个光流调试助手,把迷你光流模块通过串口模块连接到电脑上面后,打开这个上位机即可查看光流模块数据,还有动态显示的功能,非常方便!通信协议与本文所述一致。

光流调试助手下载地址:https://download.csdn.net/download/u011913159/12236283

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值