摘自: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