无人机飞控之光流知识小结

要完成飞行器的定位,则必须要有位置的反馈数据。在户外,我们一般使用GPS作为位置传感器,然而,在室内,GPS无法使用,要完成定位功能,可以选用光流传感器。

本讲主要介绍如何通过下视摄像头估计飞行器的平移速度,即光流传感器。

光流传感器输出什么?

首先要知道光流传感器的输出是什么?光流传感器输出的是xy两个轴向的速度数据,注意,没有位置数据,而位置反馈可以通过速度积分获得,不可避免会产生漂移,但实际通过组合导航算法的处理,也可获得较为满意的使用效果。

光流算法的原理?

总体来看,光流算法分为两步:

  1. 通过下视摄像头获得图像数据,分析图像的不同时刻的帧数据,得到像素的移动速度;

  2. 将像素的移动速度转换成飞行器的移动速度;

那如何判定图像的运动?

选择对应的特征点,通过特征点的运动来判定图像的运动。

### STM32 平台下无人机悬停功能实现方案 #### 1. 系统架构概述 基于 STM32 的无人机悬停功能主要依赖于传感器和高度测量模块(如超声波或ToF)。通过采集地面纹理变化的数据并结合陀螺仪信息,计算无人机相对于地面的位置偏移量。随后利用闭环控制系统调整电机转速,使无人机保持在目标位置上[^1]。 #### 2. 关键硬件组件选型 - **核心处理器**: 使用高性能的 STM32 微控制器作为主控单元。 - **模块**: 推荐采用 PV3953L1 模块 (集成 PMW3901 和 VL53L1X),能够提供高精度的速度矢量以及距离检测数据[^2]。 - **其他外设**: 配置气压计用于辅助定高等操作;加速度计/陀螺仪组合完成姿态解算。 #### 3. 软件设计思路 ##### 数据处理部分 定义了一个名为 `flow_integral_frame` 的结构体来存储每次读取到的积分结果,其中包括像素动方向上的累积位移以及其他相关信息[^4]: ```c typedef struct { uint16_t frame_count_since_last_readout; int16_t pixel_flow_x_integral; int16_t pixel_flow_y_integral; int16_t gyro_x_rate_integral; int16_t gyro_y_rate_integral; int16_t gyro_z_rate_integral; uint32_t integration_timespan; uint32_t sonar_timestamp; uint16_t ground_distance; int16_t gyro_temperature; uint8_t qual; } flow_integral_frame_t; ``` 当接收到新的串口数据包时调用函数 `Flow_Receive()` 进行解析,并更新上述变量值[^3]: ```c void Flow_Receive(uint8_t data){ static uint8_t rx_buf[PACKET_SIZE]; static uint8_t index=0; if(index<PACKET_SIZE){ rx_buf[index++]=data; if(index==PACKET_SIZE && CheckSum(rx_buf)){ ParsePacket(rx_buf,&currentFrame); index=0; } }else{ index=0;//丢弃错误帧重新同步 } } ``` ##### 控制算法实现 为了提高系统的鲁棒性和抗干扰能力,在实际应用过程中还需要加入必要的补偿机制比如重力影响修正等。具体来说就是通过对时间间隔内的平均移动速率乘以相应的时间长度得到最终估计出来的水平位移差值: ```c void Pixel_Flow_Fix(float dT){ float dx,dy,dz; currentPos.x += ((float)(currentFrame.pixel_flow_x_integral)*FLOW_SCALE_FACTOR*dT)/PIXEL_PER_METER; currentPos.y -= ((float)(currentFrame.pixel_flow_y_integral)*FLOW_SCALE_FACTOR*dT)/PIXEL_PER_METER; dz=(float)((int16_t)currentFrame.gyro_z_rate_integral)*(GYRO_Z_SENSITIVITY*PI_OVER_180)*dT; RotateVector(&dx,&dy,dz); targetSpeed.vx=-Kp*(dx-currentVel.vx); targetSpeed.vy=-Kp*(dy-currentVel.vy); } // 定义旋转向量方法简化表述逻辑复杂度 void RotateVector(float *px,float *py,float angle_rad){ float temp=*px*cosf(angle_rad)-(*py)*sinf(angle_rad); *py=*px*sinf(angle_rad)+(*py)*cosf(angle_rad); *px=temp; } ``` 最后一步则是编写 PID 或者更高级别的控制律去驱动四个无刷直电动机达到预期效果即维持当前位置不变的同时抵抗外界扰动因素的影响. --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值