泊志bzuav pixhawk飞控笔记,px4,pix v2.4.6 最终版飞控 集成了哪些传感器

四轴多轴Pixhawk2.4.6PX4PIX32位APM飞控自动定点巡航失控返航
查看数: 487|
评论数: 0|
厂家直销航模电池1300容量22000容量 AT9遥控器&&乐迪充电器 450飞机
... umber_id=
(68.26 KB, 下载次数: 3)
16:38 上传
Powered byPIXHAWK飞控概览
我的图书馆
PIXHAWK飞控概览
Pixhawk飞控的技术规格、接口分配、PWM,PPM-SUM和SBUS模式下的舵机与电调的连接方法、接口图,和与其他常见飞控的区别与选择。
32位 STM32F427 ARM Cortex M4 核心外加 FPU(浮点运算单元)
168 Mhz/256 KB RAM/2 MB 闪存
32位 STM32F103 故障保护协处理器
Invensense MPU6000 三轴加速度计/陀螺仪
ST Micro L3GD20 16位陀螺仪
ST Micro LSM303D 14位加速度计/磁力计
MS5611 MEAS 气压计
良好的二极管控制器,带有自动故障切换
舵机端口7V高压与高电流输出
所有的外围设备输出都有过流保护,所有的输入都有防静电保护
5个UART串口,1个支持大功率,两个有硬件流量控制
Spektrum DSM/DSM2/DSM-X 卫星输入
Futaba SBUS输入(输出正在完善中)
PPM sum 信号
RSSI(PWM或者电压)输入
I2C, SPI, 2个CAN, USB
3.3 与 6.6 ADC 输入
高 15.5 mm
长 81.5 mm
Pixhawk 的接口分配
PWM,PPM-SUM和SBUS模式下的舵机与电调的连接方法
Pixhawk 接口图
上图中针脚1在右边
串口 1 (Telem 1),串口 2 (Telem 2) ,串口 (GPS) 针脚: 6 = GND, 5 = RTS, 4 = CTS, 3 = RX, 2 = TX, 1 = 5V.
选择哪款飞控? APM 、PX4,还是 PIXHAWK
APM2.5与2.6是传统ardupilot飞控的最新(也是最终)版本: APM25 与 26 概览
PX4FMU与PX4IO 是这个新飞控家族的最初两个版本: Px4FMU 概览 与 Px4IO 概览
Pixhawk是根据我们的需要,结合 PX4FMU / PX4IO改进而开发出的PX4飞控的单块电路板版本。
APM是一款非常可靠的成功产品,它的潜力被充分挖掘,给我们带来了丰富的功能。
但是APM的8位CPU在储存和CPU计算能力上已经不能满足未来的需求了。
虽然最近取得的一些进展让我们对APM更加留恋,但是事实已经非常明显,发展的趋势不可逆转。
尽管目前尚未到时候,但是APM系列产品马上就要终结了。
PX4FMU / PX4IO 是由一个Lorenz Meier所在的瑞士小组所开发的学校项目。
PX4拥有一个32位处理器,提供更多内存、运用分布处理方式并且包含一个浮点运算协处理器。
与APM相比,PX4 / Pixhawk具有其10倍以上的CPU性能和更多其他方面的改进。
Diydrones和3DRobotics把PX4系统视作他们下一代飞控的基础。
Pixhawk是由DIYDrones、3DR和最初的瑞士PX4团队联合开发的下一代飞控。
DIYDrones和3DR认为下一代飞控应该具备的特征,Pixhawk全部都符合。
目前Pixhawk的固件正在进行最终的调试,而且它在未来将会有更大的发展空间。
以后开发的重点将是Pixkawk,所以PX4系统的开发可能会滞后并且某些问题可能很久都不会得到解决。
APM系统已经走到了它的终点,PX4FMU/IO系统只是开发Pixhawk的过渡。所以如果你需要一款飞控的话,请果断选择Pixhawk吧!
PIXHAWK 系统特性
Pixhawk飞控是PX4飞控系统的进一步发展。
Pixhawk将PX4-FMU控制器与PX4-IO集成到了一块电路板上,除此之外还有额外的IO、内存和其他特性。
Pixhawk是一款货真价实的第三代飞行控制系统(APM -& PX4 -& Pixhawk)。
它针对我们的飞行导航软件做了高度优化以实现对飞行器的控制与自动飞行。
它的性能目前有充足的富余,因此在未来的几年内Pixhawk系统都可以继续有效使用。
Nuttx实时操作系统对各种自主模型都可以实现高性能、高灵活性与高可靠性的控制。
类似于Unix/Linux,集成了多线程和Lua 任务脚本与飞行行为的编程环境提供了强大的开发潜力。
有一个定制的PX4驱动层确保所有进程密集运行。
目前的APM和PX4用户可以无缝切换至Pixhawk系统,这大大降低了新用户的入门门槛。
新的外围设备,将会有:数码空速计,外接彩色LED指示灯与外接磁力计。
所有的外围设备都可以自动检测和配置。
Pixhawk飞控系统的组成部分:
一颗性能强劲的32位处理器,还有一颗附加故障保护备用控制器,外加超大的储存空间。
主控制器STM32F427 32位微处理器: 168 MHz,252 MIPS,Cortex M4核心与浮点单元。
2M闪存储存程序和256K运行内存。
独立供电的32位STM32F103备用故障保护协处理器,在主处理器失效时可实现手动恢复。
micro SD储存卡槽,用于数据日志和其他用途。
各种恰到好处的传感器。
三轴16位ST Micro L3GD20H陀螺仪,用于测量旋转速度。
三轴14位加速度计和磁力计,用于确认外部影响和罗盘指向。
可选择外部磁力计,在需要的时候可以自动切换。
MEAS MS5611气压计,用来测量高度。
内置电压电流传感器,用于确认电池状况。
可外接UBLOX LEA GPS,用于确认飞机的绝对位置。
各种可扩展I/O接口和专用接口。
14个PWM舵机或电调输出。
5个UART(串口),一个支持大功率,2个有硬件流量控制。
两个CAN I/O接口(一个有内部3.3V收发,一个在扩充接口上)。
兼容Spektrum DSM / DSM2 / DSM-X?? 卫星接收机输入: 允许使用Specktrum遥控接收机。
兼容Futaba S.BUS??输入和输出。
PPM sum 信号输入。
RSSI(PWM或电压)输入。
I2C和SPI串口。
两个3.3V和一个6.6V电压模拟信号输入。
内置microUSB接口以及外置microUSB接口扩展。
包含它自己的板载微控制器和FMU栈。
具有冗余设计和扩展保护的综合供电系统。
Pixhawk是由一个集成有电压电流传感器输出的协同系统供电。
良好的二极管控制器,提供自动故障切换和冗余供电输入。
可支持高压(最高10V)大电流(10A+)舵机。
所有的外接输出都有过流保护,所有的输入都有防静电保护。
其他特性。
提供额外的安全按钮可以实现安全的马达激活/关闭。
LED状态指示器与驱动可以支持高亮度外接彩色LED指示灯表明飞行状态。
通过高能多种提示音的压电声音指示器可以得知实时飞行状态。
可支持带外壳与内置磁力计的高性能UBLOX GPS。
重量: 38g,宽度: 50mm,厚度: 15.5mm,长度: 81.5mm
PX4FMU / PX4IO与PIXHAWK的比较
新的PX4 Pixhawk模块是目前FMU和IO模块的升级,并且与两者完全兼容。
主要区别是目标用户群不同:
PX4FMU和IO的元件封装地非常密集,所以板子比较小(一个8通道接收机的尺寸)。Pixhawk有更多的空间、更多的接口和更多的PWM输出。
一共有两组舵机接口,主要的一组8个接口是通过备用处理器连接,另外一组辅助的6个通道则直接连在主处理器上。
标有“RC”的接口适用于普通PPM信号或者futaba SBUS信号的输入,标有“SB”的接口则用于读取RSSI信号,输出SBUS信号至舵机。
顶上有一个Spektrum 卫星接收机兼容接口(标有SPKT/DSM)。
二者的基本操作方式是相同的,并且软件也是通用的。
在Pixhawk中,FMUv2与IOv2在同一块电路板上工作(并且开发者会发现软件将适用于FMUv2和IOv2)
PX4FMU / PX4IO与Pixhawk的主要区别
14个PWM输出(Pixhawk)vs. 12个PWM输出(PX4)
所有的Pixhawk PWM输出都是在舵机输出端口(PX4: 8个在舵机输出端口,4个在15pin DF13端口)
5个串行端口 vs. 4个 (因为某些有双重功能,所以旧版本在某些配置下只有3个)
256 KB RAM 与 2 MB 闪存 vs 192 KB RAM 与 1 MB 闪存(旧版)
更先进的传感器模块 (最新一代)
大功率蜂鸣器驱动 (旧版: VBAT驱动,不如新的响)
大功率彩色LED(旧版:仅支持外接BlinkM)
支持装在面板上的USB外接模块 (旧版:无此功能)
重新改进与设计的供电结构
更好的输入输出针脚的短路与高压保护
更好的检测供电电压 (内置的或者外接的,例如:舵机电压)
支持Spektrum卫星接收机对频 (在v1版本里需要手动接线才能实现,但是软件支持)
v2版本里没有再使用固态继电器
外壳的结构可以帮助正确的放置插头,使得接头更容易插拔(在另一帖里,这个部分有更详细的说明)
外壳可以防止舵机接头的脱落
新的模块跟原来相比高度相同,体积会稍稍大一些,但是操作起来更方便。
外置供电模块与现有的3DR供电模块类似 (每个Pixhawk都带有一个免费的供电模块)。
每一代产品都有一个备用处理器,如果在固定翼飞行时自动驾驶失效,故障切换机制将会启动,协处理器将接替主处理器工作。
对于软件开发者,区别在于PX4中间软件有良好的抽象,可以在运行时中找到或构建。
TA的最新馆藏[转]&[转]&[转]&
喜欢该文的人也喜欢查看: 26944|回复: 154
PX4 FLOW光流 应用关键问题讲解
本帖最后由 golaced 于
09:09 编辑
最近在做新的迷你8轴 ,想往里面加上光流传感器,淘宝上有许多价格不等有的500多 有的800多非常的坑,贵的主要原因就是超声波传感器,但是有些店光传感器就500非常坑和其他店区别就是提供技术支持,但我怀疑估计他们也搞不懂光流算法是什么并且PX4 FLOW光流不直接提供stm32工程文件需要用PX4 console 编译无法在线调试,有时间的人可以把开源文件用keil新建个工程编译下载试试还行不行,楼主暂时还不打算研究光流算法所有就不就行这个工作了。
我买的光流传感器为X宝上最便宜的大概280左右,同时也买了那个很贵的超声波传感器所以也花了500多,但是比那些800,1000的可便宜了不少如果有兴趣可以买网上10元左右的那种超声波传感器更改开源程序,但我觉得还不如用另外的stm32来完成超声波的采集,PX4 FLOW光流中貌似只是多了个卡尔曼滤波器而已,网上那些超声定高的四轴不是也挺好的而且能查到的资料也很多。
刚买来的PX4 FLOW光流自带的是官方程序,效果不怎么好,原来没用过PX4 的产品一开始一头雾水,上网查阅了很多帖子都说效果不好,无意中在某论坛上发现一个人用PX4 FLOW光流定点的视频效果不错还提供固件,于是满怀激动的下载并烧入传感器中实验了一下效果比自带的好了很多这个附件就是网上找到的那个。
第二天再测试就发现坑爹了这个固件测出来的x,y轴数居然一样,我以为是传感器坏了又重新烧了官方程序发现虽然效果不好但是x,y方向是分离的,上网找到了这个提供这个固件的淘宝店询问了回答是要用他们生产的传感器,我就纳闷了本来就是用别人开源的资料,原理图 代码都是别人提供的结果自己赚那么多钱,跑到论坛上上传固件吸引了那么多人,我以为是大神造福我们这些菜鸟结果还只适用自己的板子。
我虽然做的东西不多但是在别人东西上改改还是可以的,再次浏览PX4 FLOW光流的资料我认为上面固件好使只不过是调整了一些参数而已,而其他店的传感器输出数据x,y轴一样估计是店主动了点小手脚,PX4 FLOW光流可以调整的参数如下:
Name& & & &&&Default& & & &&&Access& & & &&&Comment
BFLOW_F_THLD& & & &&&5000& & & &&&RW& & & &&&This parameter is a feature threashold and limits the quality of patterns that are used to calculate the bottom flow. For low values (e.g. 10) almost every pattern is taken, for higher values (e.g. 100) only significant patters are taken.
BFLOW_V_THLD& & & &&&30& & & &&&RW& & & &&&This is a pattern correlation threashold for filtering bad matches. Lower means only strong correlations are accepted.
BFLOW_HIST_FIL& & & &&&0& & & &&&RW& & & &&&1: Flow histogram filter is ON, 0: OFF
BFLOW_GYRO_COM& & & &&&1& & & &&&RW& & & &&&1: Gyro compensation is ON, 0: OFF
BFLOW_LP_FIL& & & &&&0& & & &&&RW& & & &&&1: Lowpass filter on flow output is ON, 0: OFF
BFLOW_W_NEW& & & &&&0.3& & & &&&RW& & & &&&Flow lowpass filter gain
DEBUG& & & &&&1& & & &&&RW& & & &&&1: Debug messages ON, 0: OFF
GYRO_SENS_DPS& & & &&&250& & & &&&RW& & & &&&Gyroscope sensitivity: 250, 500, 2000 (dps)
GYRO_COMP_THR& & & &&&0.01& & & &&&RW& & & &&&Gyro compensation threshold (dps): Gyro data lower than this threshold is not compensated to prevent drift
IMAGE_WIDTH& & & &&&64& & & &&&R& & & &&&Image width (pixels)
IMAGE_HEIGHT& & & &&&64& & & &&&R& & & &&&Image height (pixels)
IMAGE_L_LIGHT& & & &&&0& & & &&&RW& & & &&&1: Image sensor low light mode ON, 0: OFF
IMAGE_NOISE_C& & & &&&1& & & &&&RW& & & &&&1: Image sensor noise correction ON, 0: OFF
IMAGE_TEST_PAT& & & &&&0& & & &&&RW& & & &&&1: Gray-shaded test pattern mode ON, 0: OFF
LENS_FOCAL_LEN& & & &&&16& & & &&&RW& & & &&&Focal length of lens (mm)
POSITION& & & &&&0& & & &&&RW& & & &&&0: Only position 0 is used (Bottom: 0, Front: 1, Top: 2, Back: 3, Right: 4, Left: 5)
SONAR_FILTERED& & & &&&0& & & &&&RW& & & &&&1: Kalman filter on sonar output is ON, 0: OFF
SONAR_KAL_L1& & & &&&0.8461& & & &&&RW& & & &&&Sonar Kalman gain L1
SONAR_KAL_L2& & & &&&6.2034& & & &&&RW& & & &&&Sonar Kalman gain L2
SYS_ID& & & &&&81& & & &&&RW& & & & MAVLink System ID
SYS_COMP_ID& & & &&&50& & & &&&RW& & & & MAVLink Component ID
SYS_SENSOR_ID& & & &&&77& & & &&&RW& & & & MAVLink Sensor ID
SYS_TYPE& & & &&&0& & & &&&RW& & & & MAVLink System Type
SYS_AP_TYPE& & & &&&1& & & &&&RW& & & & MAVLink Autopilot Type
SYS_SW_VER& & & &&&13XX& & & &&&R& & & &&&Software Version
SYS_SEND_STATE& & & &&&1& & & &&&RW& & & &&&1: Send MAVLink Heartbeat, 0: Not
USART_2_BAUD& & & &&&115200& & & &&&R& & & &&&Baudrate USART 2
USART_3_BAUD& & & &&&115200& & & &&&R& & & &&&Baudrate USART 3 (Data Output)
USB_SEND_VIDEO& & & &&&1& & & &&&RW& & & &&&1: Send video over USB, 0: Not
USB_SEND_FLOW& & & &&&1& & & &&&RW& & & &&&1: Send flow over USB, 0: Not
USB_SEND_GYRO& & & &&&1& & & &&&RW& & & &&&1: Send gyro data over USB, 0: Not
USB_SEND_FWD& & & &&&0& & & &&&RW& & & &&&1: Send forwarded flow over USB, 0: Not
USB_SEND_DEBUG& & & &&&1& & & &&&RW& & & &&&1: Send debug msgs over USB, 0: Not
VIDEO_RATE& & & &&&150& & & &&&RW& & & &&&Time in milliseconds between images of video transmission
VIDEO_ONLY& & & &&&0& & & &&&RW& & & &&&1: High resolution video mode is ON, 0: OFF
其中BFLOW_F_THLD& &BFLOW_V_THLD&&BFLOW_W_NEW三个参数对定位效果影响较大,经过楼主尝试得出三个参数为19& &20&&0.1时对我的传感器效果较好下面是几个波形:
左右周期运动
上下运动高度波形
这个参数的效果和上面固件的结果基本差不多,如果在经过滤波和加速度融合处理效果估计会更好,当然你也可以自己调整其他参数方法如下pdf所示
我调试出的固件如下:
该固件效果和上面的差不多而且xy分离测量。还有在调整传感器参数是在qground中使用set貌似无法把参数写入rom中,我使用的方法是直接在源码中修改其文件为src/settings.c 每次调试时先连上USB在线修改参数比较结果,满意后就到settings.c中修改对应参数,然后按照上面pdf中方法编译获得固件下载即可。
对于传感器数据接收来说,新手对mavlink那坑爹的协议估计都一头雾水,而且在提供的顺序并不是传感器发送帧的顺序,楼主一开始也被这个误导,导致接收到数据缺无法正确解码,正确的顺序应该是:
楼主的接收程序是:
&&typedef struct
& & & & uint64_t&&time_
& & & & u8& &
& & & & int16_t flow_x;
& & & & int16_t flow_y;
& & & & float flow_comp_x;//Flow in m in x-sensor direction, angular-speed compensated
& & & & float flow_comp_y;
& & & & u8 //Optical flow quality / confidence. 0: bad, 255: maximum quality
& & & &//ground_distance& & & & float& & & & Ground distance in m. Positive value: distance known. Negative value: Unknown distance& && &
& && && && &
& &float ByteToFloat(unsigned char* byteArry)
&&return *((float*)byteArry);
u8 FLOW_STATE[4];
u8 flow_buf[30];
void FLOW_MAVLINK(unsigned char data)
红色的是起始标志位(stx),在v1.0版本中以“FE”作为起始标志。这个标志位在mavlink消息帧接收端进行消息解码时有用处。
第二个格子代表的是灰色部分(payload,称作有效载荷,要用的数据在有效载荷里面)的字节长度(len),范围从0到255之间。在mavlink消息帧接收端可以用它和实际收到的有效载荷的长度比较,以验证有效载荷的长度是否正确。
第三个格子代表的是本次消息帧的序号(seq),每次发完一个消息,这个字节的内容会加1,加到255后会从0重新开始。这个序号用于mavlink消息帧接收端计算消息丢失比例用的,相当于是信号强度。
第四个格子代表了发送本条消息帧的设备的系统编号(sys),使用PIXHAWK刷PX4固件时默认的系统编号为1,用于mavlink消息帧接收端识别是哪个设备发来的消息。
第五个格子代表了发送本条消息帧的设备的单元编号(comp),使用PIXHAWK刷PX4固件时默认的单元编号为50,用于mavlink消息帧接收端识别是设备的哪个单元发来的消息(暂时没什么用) 。
第六个格子代表了有效载荷中消息包的编号(msg),注意它和序号是不同的,这个字节很重要,mavlink消息帧接收端要根据这个编号来确定有效载荷里到底放了什么消息包并根据编号选择对应的方式来处理有效载荷里的信息包。
& && &26*/& & & & & & & &&&
// FE 1A| A2 X X| 64
static u8 s_flow=0,data_cnt=0;
u8 cnt_offset=0;& & & &
u8 get_one_fame=0;
char floattobyte[4];
& & & & & & & & switch(s_flow)
& & & &&&{
& & case 0: if(data==0xFE)
& & & & & & & & & & & & s_flow=1;
& & & & & & & & & & & &
& & & & & & & & case 1: if(data==0x1A)
& & & & & & & & & & & & & & & & { s_flow=2;}
& & & & & & & & & & & & else
& & & & & & & & & & & & s_flow=0;
& & & & & & & & & & & &
& & & && &case 2:
& & & & & & & & & & & & if(data_cnt&4)
& & & & & & & & & & & & {s_flow=2; FLOW_STATE[data_cnt++]=}
& & & & & & & && &else
& & & & & & & & & & & & {data_cnt=0;s_flow=3;flow_buf[data_cnt++]=}
& & & & & & & &&&
& & & & & & & & case 3:
& & & & & & & &&&if(FLOW_STATE[3]=100){
& & & & & & & & & & & & if(data_cnt&26)
& & & & & & & & & & & & {s_flow=3; flow_buf[data_cnt++]=}
& & & & & & & && &else
& & & & & & & & & & & & {data_cnt=0;s_flow=4;}
& & & & & & & & }
& & & & & & & & else
& & & & & & & & & & & & {data_cnt=0;s_flow=0;}
& & & & & & & & & & & &&&
& & & & & & & & case 4:get_one_fame=1;s_flow=0;data_cnt=0;
& & & & & & & & default:s_flow=0;data_cnt=0;
& & & &&&}//--end of s_uart
& & & & & & & &
& & & &&&if(get_one_fame)
& & & &&&{
& & & & & & & & flow.time_sec=(flow_buf[7]&&64)|(flow_buf[6]&&56)|(flow_buf[5]&&48)|(flow_buf[4]&&40)
& & & & & & & &&&|(flow_buf[3]&&32)|(flow_buf[2]&&16)|(flow_buf[1]&&8)|(flow_buf[0]);
&&& & & &&&floattobyte[0]=flow_buf[8];
& & & & & & & &&&floattobyte[1]=flow_buf[9];
& & & & & & & &&&floattobyte[2]=flow_buf[10];
& & & & & & & &&&floattobyte[3]=flow_buf[11];
& & & & & & & & flow.flow_comp_x =ByteToFloat(floattobyte);
& & & & & & & &&&floattobyte[0]=flow_buf[12];
& & & & & & & &&&floattobyte[1]=flow_buf[13];
& & & & & & & &&&floattobyte[2]=flow_buf[14];
& & & & & & & &&&floattobyte[3]=flow_buf[15];
& & & & & & & & flow.flow_comp_y =ByteToFloat(floattobyte);
& & & & & & & &&&floattobyte[0]=flow_buf[16];
& & & & & & & &&&floattobyte[1]=flow_buf[17];
& & & & & & & &&&floattobyte[2]=flow_buf[18];
& & & & & & & &&&floattobyte[3]=flow_buf[19];
& & & && & flow.hight=ByteToFloat(floattobyte);//ground_distance& & & & float& & & & Ground distance in m. Positive value: distance known. Negative value: Unknown distance& &&&
& & & && & flow.flow_x=(int16_t)((flow_buf[20])|(flow_buf[21]&&8));
& & & && & flow.flow_y=(int16_t)((flow_buf[22])|(flow_buf[23]&&8));
& & & & & & & &&&flow.id=flow_buf[24];
& & & && & flow.quality=flow_buf[25]; //Optical flow quality / confidence. 0: bad, 255: maximum quality
& & & & & & & & }
写的不好,也没有校验,不过结果正确,代码里面也包括了串口接收四位数据转换单精度浮点的部分(估计很多新手也很头疼的部分)。
以上内容不敢说全部原创,如有问题望指正。
本帖子中包含更多资源
才可以下载或查看,没有帐号?
成功读取..楼主能解释一下 flow_x,flow_y, flow_comp_x,flow_comp_y具体含义么怎么融合到定点PID里 ...
前两个貌似是像素位移速度&&后面是融合高度后的真实速度& & 定点apm里貌似用光流输出速度积分换算成了GPS坐标 然后给到导航里了你可以看下firmware-master里例子中flow_postion_estimator 那个
/****************************************************************************
*& &Copyright (C)
PX4 Development Team. All rights reserved.
*& &Author: Samuel Zihlmann &&
*& && & & & & & & &&&Lorenz Meier &&
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*& & notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*& & notice, this list of conditions and the following disclaimer in
*& & the documentation and/or other materials provided with the
*& & distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
*& & used to endorse or promote products derived from this software
*& & without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* &AS IS& AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
****************************************************************************/
* @file flow_position_estimator_main.c
* Optical flow position estimator
#include &px4_config.h&
#include &unistd.h&
#include &stdlib.h&
#include &stdio.h&
#include &string.h&
#include &stdbool.h&
#include &fcntl.h&
#include &float.h&
#include &nuttx/sched.h&
#include &sys/prctl.h&
#include &drivers/drv_hrt.h&
#include &termios.h&
#include &errno.h&
#include &limits.h&
#include &math.h&
#include &uORB/uORB.h&
#include &uORB/topics/parameter_update.h&
#include &uORB/topics/actuator_armed.h&
#include &uORB/topics/vehicle_control_mode.h&
#include &uORB/topics/vehicle_attitude.h&
#include &uORB/topics/vehicle_attitude_setpoint.h&
#include &uORB/topics/vehicle_local_position.h&
#include &uORB/topics/sensor_combined.h&
#include &uORB/topics/optical_flow.h&
#include &uORB/topics/filtered_bottom_flow.h&
#include &systemlib/perf_counter.h&
#include &systemlib/systemlib.h&
#include &poll.h&
#include &platforms/px4_defines.h&
#include &flow_position_estimator_params.h&
__EXPORT int flow_position_estimator_main(int argc, char *argv[]);
static bool thread_should_exit =& & & & & & & & /**& Daemon exit flag */
static bool thread_running =& & & & & & & & /**& Daemon status flag */
static int daemon_& & & & & & & & & & & & & & & & /**& Handle of daemon task / thread */
int flow_position_estimator_thread_main(int argc, char *argv[]);
static void usage(const char *reason);
static void usage(const char *reason)
& & & & if (reason) {
& & & & & & & & fprintf(stderr, &%s\n&, reason);
& & & & fprintf(stderr, &usage: daemon {start|stop|status} [-p &additional params&]\n\n&);
& & & & exit(1);
* The daemon app only briefly exists to start
* the background job. The stack size assigned in the
* Makefile does only apply to this management task.
* The actual stack size should be set in the call
* to px4_task_spawn_cmd().
int flow_position_estimator_main(int argc, char *argv[])
& & & & if (argc & 2) {
& & & & & & & & usage(&missing command&);
& & & & if (!strcmp(argv[1], &start&)) {
& & & & & & & & if (thread_running) {
& & & & & & & & & & & & printf(&flow position estimator already running\n&);
& & & & & & & & & & & & /* this is not an error */
& & & & & & & & & & & & exit(0);
& & & & & & & & }
& & & & & & & & thread_should_exit =
& & & & & & & & daemon_task = px4_task_spawn_cmd(&flow_position_estimator&,
& & & & & & & & & & & & & & & & & & & && && &SCHED_DEFAULT,
& & & & & & & & & & & & & & & & & & & && && &SCHED_PRIORITY_MAX - 5,
& & & & & & & & & & & & & & & & & & & && && &4000,
& & & & & & & & & & & & & & & & & & & && && &flow_position_estimator_thread_main,
& & & & & & & & & & & & & & & & & & & && && &(argv) ? (char * const *)&argv[2] : (char * const *)NULL);
& & & & & & & & exit(0);
& & & & if (!strcmp(argv[1], &stop&)) {
& & & & & & & & thread_should_exit =
& & & & & & & & exit(0);
& & & & if (!strcmp(argv[1], &status&)) {
& & & & & & & & if (thread_running) {
& & & & & & & & & & & & printf(&\tflow position estimator is running\n&);
& & & & & & & & } else {
& & & & & & & & & & & & printf(&\tflow position estimator not started\n&);
& & & & & & & & }
& & & & & & & & exit(0);
& & & & usage(&unrecognized command&);
& & & & exit(1);
int flow_position_estimator_thread_main(int argc, char *argv[])
& & & & /* welcome user */
& & & & thread_running =
& & & & printf(&[flow position estimator] starting\n&);
& & & & /* rotation matrix for transformation of optical flow speed vectors */
& & & & static const int8_t rotM_flow_sensor[3][3] =& &{{&&0, -1, 0 },
& & & & & & & & { 1, 0, 0 },
& & & & & & & & {&&0, 0, 1 }
& & & & }; // 90deg rotated
& & & & const float time_scale = powf(10.0f, -6.0f);
& & & & static float speed[3] = {0.0f, 0.0f, 0.0f};
& & & & static float flow_speed[3] = {0.0f, 0.0f, 0.0f};
& & & & static float global_speed[3] = {0.0f, 0.0f, 0.0f};
& & & & static uint32_t counter = 0;
& & & & static uint64_t time_last_flow = 0; // in ms
& & & & static float dt = 0.0f; // seconds
& & & & static float sonar_last = 0.0f;
& & & & static bool sonar_valid =
& & & & static float sonar_lp = 0.0f;
& & & & /* subscribe to vehicle status, attitude, sensors and flow*/
& & & & struct actuator_armed_
& & & & memset(&armed, 0, sizeof(armed));
& & & & struct vehicle_control_mode_s control_
& & & & memset(&control_mode, 0, sizeof(control_mode));
& & & & struct vehicle_attitude_
& & & & memset(&att, 0, sizeof(att));
& & & & struct vehicle_attitude_setpoint_s att_
& & & & memset(&att_sp, 0, sizeof(att_sp));
& & & & struct optical_flow_
& & & & memset(&flow, 0, sizeof(flow));
& & & & /* subscribe to parameter changes */
& & & & int parameter_update_sub = orb_subscribe(ORB_ID(parameter_update));
& & & & /* subscribe to armed topic */
& & & & int armed_sub = orb_subscribe(ORB_ID(actuator_armed));
& & & & /* subscribe to safety topic */
& & & & int control_mode_sub = orb_subscribe(ORB_ID(vehicle_control_mode));
& & & & /* subscribe to attitude */
& & & & int vehicle_attitude_sub = orb_subscribe(ORB_ID(vehicle_attitude));
& & & & /* subscribe to attitude setpoint */
& & & & int vehicle_attitude_setpoint_sub = orb_subscribe(ORB_ID(vehicle_attitude_setpoint));
& & & & /* subscribe to optical flow*/
& & & & int optical_flow_sub = orb_subscribe(ORB_ID(optical_flow));
& & & & /* init local position and filtered flow struct */
& & & & struct vehicle_local_position_s local_pos = {
& & & & & & & & .x = 0.0f,
& & & & & & & & .y = 0.0f,
& & & & & & & & .z = 0.0f,
& & & & & & & & .vx = 0.0f,
& & & & & & & & .vy = 0.0f,
& & & & & & & & .vz = 0.0f
& & & & };
& & & & struct filtered_bottom_flow_s filtered_flow = {
& & & & & & & & .sumx = 0.0f,
& & & & & & & & .sumy = 0.0f,
& & & & & & & & .vx = 0.0f,
& & & & & & & & .vy = 0.0f
& & & & };
& & & & /* advert pub messages */
& & & & orb_advert_t local_pos_pub = orb_advertise(ORB_ID(vehicle_local_position), &local_pos);
& & & & orb_advert_t filtered_flow_pub = orb_advertise(ORB_ID(filtered_bottom_flow), &filtered_flow);
& & & & /* vehicle flying status parameters */
& & & & bool vehicle_liftoff =
& & & & bool sensors_ready =
& & & & /* parameters init*/
& & & & struct flow_position_estimator_
& & & & struct flow_position_estimator_param_handles param_
& & & & parameters_init(&param_handles);
& & & & parameters_update(&param_handles, &params);
& & & & perf_counter_t mc_loop_perf = perf_alloc(PC_ELAPSED, &flow_position_estimator_runtime&);
& & & & perf_counter_t mc_interval_perf = perf_alloc(PC_INTERVAL, &flow_position_estimator_interval&);
& & & & perf_counter_t mc_err_perf = perf_alloc(PC_COUNT, &flow_position_estimator_err&);
& & & & while (!thread_should_exit) {
& & & & & & & & if (sensors_ready) {
& & & & & & & & & & & & /*This runs at the rate of the sensors */
& & & & & & & & & & & & struct pollfd fds[2] = {
& & & & & & & & & & & & & & & & { .fd = optical_flow_sub, .events = POLLIN },
& & & & & & & & & & & & & & & & { .fd = parameter_update_sub,& &.events = POLLIN }
& & & & & & & & & & & & };
& & & & & & & & & & & & /* wait for a sensor update, check for exit condition every 500 ms */
& & & & & & & & & & & & int ret = poll(fds, 2, 500);
& & & & & & & & & & & & if (ret & 0) {
& & & & & & & & & & & & & & & & /* poll error, count it in perf */
& & & & & & & & & & & & & & & & perf_count(mc_err_perf);
& & & & & & & & & & & & } else if (ret == 0) {
& & & & & & & & & & & & & & & & /* no return value, ignore */
//& & & & & & & & & & & & & & & & printf(&[flow position estimator] no bottom flow.\n&);
& & & & & & & & & & & & } else {
& & & & & & & & & & & & & & & & /* parameter update available? */
& & & & & & & & & & & & & & & & if (fds[1].revents & POLLIN) {
& & & & & & & & & & & & & & & & & & & & /* read from param to clear updated flag */
& & & & & & & & & & & & & & & & & & & & struct parameter_update_
& & & & & & & & & & & & & & & & & & & & orb_copy(ORB_ID(parameter_update), parameter_update_sub, &update);
& & & & & & & & & & & & & & & & & & & & parameters_update(&param_handles, &params);
& & & & & & & & & & & & & & & & & & & & printf(&[flow position estimator] parameters updated.\n&);
& & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & /* only if flow data changed */
& & & & & & & & & & & & & & & & if (fds[0].revents & POLLIN) {
& & & & & & & & & & & & & & & & & & & & perf_begin(mc_loop_perf);
& & & & & & & & & & & & & & & & & & & & orb_copy(ORB_ID(optical_flow), optical_flow_sub, &flow);
& & & & & & & & & & & & & & & & & & & & /* got flow, updating attitude and status as well */
& & & & & & & & & & & & & & & & & & & & orb_copy(ORB_ID(vehicle_attitude), vehicle_attitude_sub, &att);
& & & & & & & & & & & & & & & & & & & & orb_copy(ORB_ID(vehicle_attitude_setpoint), vehicle_attitude_setpoint_sub, &att_sp);
& & & & & & & & & & & & & & & & & & & & orb_copy(ORB_ID(actuator_armed), armed_sub, &armed);
& & & & & & & & & & & & & & & & & & & & orb_copy(ORB_ID(vehicle_control_mode), control_mode_sub, &control_mode);
& & & & & & & & & & & & & & & & & & & & /* vehicle state estimation */
& & & & & & & & & & & & & & & & & & & & float sonar_new = flow.ground_distance_m;
& & & & & & & & & & & & & & & & & & & & /* set liftoff boolean
& & & & & & & & & & & & & & & & & & & &&&* -& at bottom sonar sometimes does not work correctly, and has to be calibrated (distance higher than 0.3m)
& & & & & & & & & & & & & & & & & & & &&&* -& accept sonar measurements after reaching calibration distance (values between 0.3m and 1.0m for some time)
& & & & & & & & & & & & & & & & & & & &&&* -& minimum sonar value 0.3m
& & & & & & & & & & & & & & & & & & & &&&*/
& & & & & & & & & & & & & & & & & & & & if (!vehicle_liftoff) {
& & & & & & & & & & & & & & & & & & & & & & & & if (armed.armed && att_sp.thrust & params.minimum_liftoff_thrust && sonar_new & 0.3f && sonar_new & 1.0f) {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & vehicle_liftoff =
& & & & & & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & } else {
& & & & & & & & & & & & & & & & & & & & & & & & if (!armed.armed || (att_sp.thrust & params.minimum_liftoff_thrust && sonar_new &= 0.3f)) {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & vehicle_liftoff =
& & & & & & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & /* calc dt between flow timestamps */
& & & & & & & & & & & & & & & & & & & & /* ignore first flow msg */
& & & & & & & & & & & & & & & & & & & & if (time_last_flow == 0) {
& & & & & & & & & & & & & & & & & & & & & & & & time_last_flow = flow.
& & & & & & & & & & & & & & & & & & & & & & & &
& & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & dt = (float)(flow.timestamp - time_last_flow) * time_
& & & & & & & & & & & & & & & & & & & & time_last_flow = flow.
& & & & & & & & & & & & & & & & & & & & /* only make position update if vehicle is lift off or DEBUG is activated*/
& & & & & & & & & & & & & & & & & & & & if (vehicle_liftoff || params.debug) {
& & & & & & & & & & & & & & & & & & & & & & & & /* copy flow */
& & & & & & & & & & & & & & & & & & & & & & & & if (flow.integration_timespan & 0) {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & flow_speed[0] = flow.pixel_flow_x_integral / (flow.integration_timespan / 1e6f) * flow.ground_distance_m;
& & & & & & & & & & & & & & & & & & & & & & & & & & & & flow_speed[1] = flow.pixel_flow_y_integral / (flow.integration_timespan / 1e6f) * flow.ground_distance_m;
& & & & & & & & & & & & & & & & & & & & & & & & } else {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & flow_speed[0] = 0;
& & & & & & & & & & & & & & & & & & & & & & & & & & & & flow_speed[1] = 0;
& & & & & & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & & & & & flow_speed[2] = 0.0f;
& & & & & & & & & & & & & & & & & & & & & & & & /* convert to bodyframe velocity */
& & & & & & & & & & & & & & & & & & & & & & & & for (uint8_t i = 0; i & 3; i++) {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & float sum = 0.0f;
& & & & & & & & & & & & & & & & & & & & & & & & & & & & for (uint8_t j = 0; j & 3; j++) {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & sum = sum + flow_speed[j] * rotM_flow_sensor[j];
& & & & & & & & & & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & & & & & & & & & speed =
& & & & & & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & & & & & /* update filtered flow */
& & & & & & & & & & & & & & & & & & & & & & & & filtered_flow.sumx = filtered_flow.sumx + speed[0] *
& & & & & & & & & & & & & & & & & & & & & & & & filtered_flow.sumy = filtered_flow.sumy + speed[1] *
& & & & & & & & & & & & & & & & & & & & & & & & filtered_flow.vx = speed[0];
& & & & & & & & & & & & & & & & & & & & & & & & filtered_flow.vy = speed[1];
& & & & & & & & & & & & & & & & & & & & & & & & // TODO add yaw rotation correction (with distance to vehicle zero)
& & & & & & & & & & & & & & & & & & & & & & & & /* convert to globalframe velocity
& & & & & & & & & & & & & & & & & & & & & & & &&&* -& local position is currently not used for position control
& & & & & & & & & & & & & & & & & & & & & & & &&&*/
& & & & & & & & & & & & & & & & & & & & & & & & for (uint8_t i = 0; i & 3; i++) {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & float sum = 0.0f;
& & & & & & & & & & & & & & & & & & & & & & & & & & & & for (uint8_t j = 0; j & 3; j++) {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & sum = sum + speed[j] * PX4_R(att.R, i, j);
& & & & & & & & & & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & & & & & & & & & global_speed =
& & & & & & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.x = local_pos.x + global_speed[0] *
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.y = local_pos.y + global_speed[1] *
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.vx = global_speed[0];
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.vy = global_speed[1];
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.xy_valid =
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.v_xy_valid =
& & & & & & & & & & & & & & & & & & & & } else {
& & & & & & & & & & & & & & & & & & & & & & & & /* set speed to zero and let position as it is */
& & & & & & & & & & & & & & & & & & & & & & & & filtered_flow.vx = 0;
& & & & & & & & & & & & & & & & & & & & & & & & filtered_flow.vy = 0;
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.vx = 0;
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.vy = 0;
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.xy_valid =
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.v_xy_valid =
& & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & /* filtering ground distance */
& & & & & & & & & & & & & & & & & & & & if (!vehicle_liftoff || !armed.armed) {
& & & & & & & & & & & & & & & & & & & & & & & & /* not possible to fly */
& & & & & & & & & & & & & & & & & & & & & & & & sonar_valid =
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.z = 0.0f;
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.z_valid =
& & & & & & & & & & & & & & & & & & & & } else {
& & & & & & & & & & & & & & & & & & & & & & & & sonar_valid =
& & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & if (sonar_valid || params.debug) {
& & & & & & & & & & & & & & & & & & & & & & & & /* simple lowpass sonar filtering */
& & & & & & & & & & & & & & & & & & & & & & & & /* if new value or with sonar update frequency */
& & & & & & & & & & & & & & & & & & & & & & & & if (sonar_new != sonar_last || counter % 10 == 0) {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & sonar_lp = 0.05f * sonar_new + 0.95f * sonar_
& & & & & & & & & & & & & & & & & & & & & & & & & & & & sonar_last = sonar_
& & & & & & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & & & & & float height_diff = sonar_new - sonar_
& & & & & & & & & & & & & & & & & & & & & & & & /* if over 1/2m spike follow lowpass */
& & & & & & & & & & & & & & & & & & & & & & & & if (height_diff & -params.sonar_lower_lp_threshold || height_diff & params.sonar_upper_lp_threshold) {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & local_pos.z = -sonar_
& & & & & & & & & & & & & & & & & & & & & & & & } else {
& & & & & & & & & & & & & & & & & & & & & & & & & & & & local_pos.z = -sonar_
& & & & & & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & & & & & local_pos.z_valid =
& & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & filtered_flow.timestamp = hrt_absolute_time();
& & & & & & & & & & & & & & & & & & & & local_pos.timestamp = hrt_absolute_time();
& & & & & & & & & & & & & & & & & & & & /* publish local position */
& & & & & & & & & & & & & & & & & & & & if (isfinite(local_pos.x) && isfinite(local_pos.y) && isfinite(local_pos.z)
& & & & & & & & & & & & & & & & & & & && &&&&& isfinite(local_pos.vx) && isfinite(local_pos.vy)) {
& & & & & & & & & & & & & & & & & & & & & & & & orb_publish(ORB_ID(vehicle_local_position), local_pos_pub, &local_pos);
& & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & /* publish filtered flow */
& & & & & & & & & & & & & & & & & & & & if (isfinite(filtered_flow.sumx) && isfinite(filtered_flow.sumy) && isfinite(filtered_flow.vx)
& & & & & & & & & & & & & & & & & & & && &&&&& isfinite(filtered_flow.vy)) {
& & & & & & & & & & & & & & & & & & & & & & & & orb_publish(ORB_ID(filtered_bottom_flow), filtered_flow_pub, &filtered_flow);
& & & & & & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & & /* measure in what intervals the position estimator runs */
& & & & & & & & & & & & & & & & & & & & perf_count(mc_interval_perf);
& & & & & & & & & & & & & & & & & & & & perf_end(mc_loop_perf);
& & & & & & & & & & & & & & & & }
& & & & & & & & & & & & }
& & & & & & & & } else {
& & & & & & & & & & & & /* sensors not ready waiting for first attitude msg */
& & & & & & & & & & & & /* polling */
& & & & & & & & & & & & struct pollfd fds[1] = {
& & & & & & & & & & & & & & & & { .fd = vehicle_attitude_sub, .events = POLLIN },
& & & & & & & & & & & & };
& & & & & & & & & & & & /* wait for a attitude message, check for exit condition every 5 s */
& & & & & & & & & & & & int ret = poll(fds, 1, 5000);
& & & & & & & & & & & & if (ret & 0) {
& & & & & & & & & & & & & & & & /* poll error, count it in perf */
& & & & & & & & & & & & & & & & perf_count(mc_err_perf);
& & & & & & & & & & & & } else if (ret == 0) {
& & & & & & & & & & & & & & & & /* no return value, ignore */
& & & & & & & & & & & & & & & & printf(&[flow position estimator] no attitude received.\n&);
& & & & & & & & & & & & } else {
& & & & & & & & & & & & & & & & if (fds[0].revents & POLLIN) {
& & & & & & & & & & & & & & & & & & & & sensors_ready =
& & & & & & & & & & & & & & & & & & & & printf(&[flow position estimator] initialized.\n&);
& & & & & & & & & & & & & & & & }
& & & & & & & & & & & & }
& & & & & & & & }
& & & & & & & & counter++;
& & & & printf(&[flow position estimator] exiting.\n&);
& & & & thread_running =
& & & & close(vehicle_attitude_setpoint_sub);
& & & & close(vehicle_attitude_sub);
& & & & close(armed_sub);
& & & & close(control_mode_sub);
& & & & close(parameter_update_sub);
& & & & close(optical_flow_sub);
& & & & perf_print_counter(mc_loop_perf);
& & & & perf_free(mc_loop_perf);
& & & & fflush(stdout);
& & & & return 0;
更新RAD帧读取:
FLOW_RAD flow_
FLOW_FIX flow_
u8 FLOW_STATE[4];
u8 flow_buf[27];
u8 flow_buf_rad[45];
& &float ByteToFloat(unsigned char* byteArry)
&&return *((float*)byteArry);
#define&&IIR_ORDER& &&&4& && &//使用IIR滤波器的阶数
static double b_IIR[IIR_ORDER+1] ={0.0008f, 0.0032f, 0.0048f, 0.0032f, 0.0008f};&&//系数b
static double a_IIR[IIR_ORDER+1] ={1.0000f, -3.0176f, 3.5072f, -1.8476f, 0.3708f};//系数a
static double InPut_IIR[4][IIR_ORDER+1] = {0};
static double OutPut_IIR[4][IIR_ORDER+1] = {0};
void FLOW_MAVLINK(unsigned char data)
红色的是起始标志位(stx),在v1.0版本中以“FE”作为起始标志。这个标志位在mavlink消息帧接收端进行消息解码时有用处。
第二个格子代表的是灰色部分(payload,称作有效载荷,要用的数据在有效载荷里面)的字节长度(len),范围从0到255之间。在mavlink消息帧接收端可以用它和实际收到的有效载荷的长度比较,以验证有效载荷的长度是否正确。
第三个格子代表的是本次消息帧的序号(seq),每次发完一个消息,这个字节的内容会加1,加到255后会从0重新开始。这个序号用于mavlink消息帧接收端计算消息丢失比例用的,相当于是信号强度。
第四个格子代表了发送本条消息帧的设备的系统编号(sys),使用PIXHAWK刷PX4固件时默认的系统编号为1,用于mavlink消息帧接收端识别是哪个设备发来的消息。
第五个格子代表了发送本条消息帧的设备的单元编号(comp),使用PIXHAWK刷PX4固件时默认的单元编号为50,用于mavlink消息帧接收端识别是设备的哪个单元发来的消息(暂时没什么用) 。
第六个格子代表了有效载荷中消息包的编号(msg),注意它和序号是不同的,这个字节很重要,mavlink消息帧接收端要根据这个编号来确定有效载荷里到底放了什么消息包并根据编号选择对应的方式来处理有效载荷里的信息包。
& && &26*/& & & & & & & &&&
// FE 1A| A2 X X| 64
static u8 s_flow=0,data_cnt=0;
u8 cnt_offset=0;& & & &
u8 get_one_fame=0;
char floattobyte[4];
& & & & & & & & switch(s_flow)
& & & &&&{
& & case 0: if(data==0xFE)
& & & & & & & & & & & & s_flow=1;
& & & & & & & & & & & &
& & & & & & & & case 1: if(data==0x1A||data==0x2C)
& & & & & & & & & & & & & & & & { s_flow=2;}
& & & & & & & & & & & & else
& & & & & & & & & & & & s_flow=0;
& & & & & & & & & & & &
& & & && &case 2:
& & & & & & & & & & & & if(data_cnt&4)
& & & & & & & & & & & & {s_flow=2; FLOW_STATE[data_cnt++]=}
& & & & & & & && &else
& & & & & & & & & & & & {data_cnt=0;s_flow=3;flow_buf[data_cnt++]=}
& & & & & & & &&&
& & & & & & & & case 3:
& & & & & & & &&&if(FLOW_STATE[3]==100){
& & & & & & & & & & & & if(data_cnt&26)
& & & & & & & & & & & & {s_flow=3; flow_buf[data_cnt++]=}
& & & & & & & && &else
& & & & & & & & & & & & {data_cnt=0;s_flow=4;}
& & & & & & & & }
& & & & & & & & else if(FLOW_STATE[3]==106){
& & & & & & & & & & & & if(data_cnt&44)
& & & & & & & & & & & & {s_flow=3; flow_buf_rad[data_cnt++]=}
& & & & & & & && &else
& & & & & & & & & & & & {data_cnt=0;s_flow=4;}
& & & & & & & & }
& & & & & & & & else
& & & & & & & & & & & & {data_cnt=0;s_flow=0;}
& & & & & & & & & & & &&&
& & & & & & & & case 4:get_one_fame=1;s_flow=0;data_cnt=0;
& & & & & & & & default:s_flow=0;data_cnt=0;
& & & &&&}//--end of s_uart
& & & & & & & &
& & & &&&if(get_one_fame)
& & & &&&{
& & & & & & & &&&if(FLOW_STATE[3]==100){
& & & & & & & & flow.time_sec=(flow_buf[7]&&64)|(flow_buf[6]&&56)|(flow_buf[5]&&48)|(flow_buf[4]&&40)
& & & & & & & &&&|(flow_buf[3]&&32)|(flow_buf[2]&&16)|(flow_buf[1]&&8)|(flow_buf[0]);
&&& & & &&&floattobyte[0]=flow_buf[8];
& & & & & & & &&&floattobyte[1]=flow_buf[9];
& & & & & & & &&&floattobyte[2]=flow_buf[10];
& & & & & & & &&&floattobyte[3]=flow_buf[11];
& & & & & & & & flow.flow_comp_x.originf =ByteToFloat(floattobyte);
& & & & & & & &&&floattobyte[0]=flow_buf[12];
& & & & & & & &&&floattobyte[1]=flow_buf[13];
& & & & & & & &&&floattobyte[2]=flow_buf[14];
& & & & & & & &&&floattobyte[3]=flow_buf[15];
& & & & & & & & flow.flow_comp_y.originf =ByteToFloat(floattobyte);
& & & & & & & &&&floattobyte[0]=flow_buf[16];
& & & & & & & &&&floattobyte[1]=flow_buf[17];
& & & & & & & &&&floattobyte[2]=flow_buf[18];
& & & & & & & &&&floattobyte[3]=flow_buf[19];
& & & && & flow.hight.originf=ByteToFloat(floattobyte);//ground_distance& & & & float& & & & Ground distance in m. Positive value: distance known. Negative value: Unknown distance& &&&
& & & && & flow.flow_x.origin=(int16_t)((flow_buf[20])|(flow_buf[21]&&8));
& & & && & flow.flow_y.origin=(int16_t)((flow_buf[22])|(flow_buf[23]&&8));
& & & & & & & &&&flow.id=flow_buf[24];
& & & && & flow.quality=flow_buf[25]; //Optical flow quality / confidence. 0: bad, 255: maximum quality
& & & & & & & & flow_fix.flow_x.average & & & & & & & &&&= IIR_I_Filter(flow_fix.flow_x.origin , InPut_IIR[0], OutPut_IIR[0], b_IIR, IIR_ORDER+1, a_IIR, IIR_ORDER+1);
& & & & & & & & flow.flow_y.average & & & & & & & &&&= IIR_I_Filter(flow.flow_y.origin , InPut_IIR[1], OutPut_IIR[1], b_IIR, IIR_ORDER+1, a_IIR, IIR_ORDER+1);
& & & & & & & & flow.flow_comp_x.average = IIR_I_Filter(flow.flow_comp_x.originf , InPut_IIR[2], OutPut_IIR[2], b_IIR, IIR_ORDER+1, a_IIR, IIR_ORDER+1);
& & & & & & & & flow.flow_comp_y.average = IIR_I_Filter(flow.flow_comp_y.originf , InPut_IIR[3], OutPut_IIR[3], b_IIR, IIR_ORDER+1, a_IIR, IIR_ORDER+1);
& & & & & & & & }
& & & &&&else if(FLOW_STATE[3]==106)
& & & &&&{
& & & &&&& & & & flow_rad.time_usec=(flow_buf_rad[7]&&64)|(flow_buf_rad[6]&&56)|(flow_buf_rad[5]&&48)|(flow_buf_rad[4]&&40)
& & & & & & & &&&|(flow_buf_rad[3]&&32)|(flow_buf_rad[2]&&16)|(flow_buf_rad[1]&&8)|(flow_buf_rad[0]);
&&& & & &&&flow_rad.integration_time_us=(flow_buf_rad[11]&&32)|(flow_buf_rad[10]&&16)|(flow_buf_rad[9]&&8)|(flow_buf_rad[8]);
& & & & & & & &&&floattobyte[0]=flow_buf_rad[12];
& & & & & & & &&&floattobyte[1]=flow_buf_rad[13];
& & & & & & & &&&floattobyte[2]=flow_buf_rad[14];
& & & & & & & &&&floattobyte[3]=flow_buf_rad[15];
& & & & & & & &&&flow_rad.integrated_x=ByteToFloat(floattobyte);
& & & & & & & &&&floattobyte[0]=flow_buf_rad[16];
& & & & & & & &&&floattobyte[1]=flow_buf_rad[17];
& & & & & & & &&&floattobyte[2]=flow_buf_rad[18];
& & & & & & & &&&floattobyte[3]=flow_buf_rad[19];
& & & & & & & &&&flow_rad.integrated_y=ByteToFloat(floattobyte);
& & & & & & & &&&floattobyte[0]=flow_buf_rad[20];
& & & & & & & &&&floattobyte[1]=flow_buf_rad[21];
& & & & & & & &&&floattobyte[2]=flow_buf_rad[22];
& & & & & & & &&&floattobyte[3]=flow_buf_rad[23];
& & & & & & & &&&flow_rad.integrated_xgyro=ByteToFloat(floattobyte);
& & & & & & & &&&floattobyte[0]=flow_buf_rad[24];
& & & & & & & &&&floattobyte[1]=flow_buf_rad[25];
& & & & & & & &&&floattobyte[2]=flow_buf_rad[26];
& & & & & & & &&&floattobyte[3]=flow_buf_rad[27];
& & & & & & & &&&flow_rad.integrated_ygyro=ByteToFloat(floattobyte);
& & & & & & & &&&floattobyte[0]=flow_buf_rad[28];
& & & & & & & &&&floattobyte[1]=flow_buf_rad[29];
& & & & & & & &&&floattobyte[2]=flow_buf_rad[30];
& & & & & & & &&&floattobyte[3]=flow_buf_rad[31];
& & & & & & & &&&flow_rad.integrated_zgyro=ByteToFloat(floattobyte);
& & & & & & & &&&flow_rad.time_delta_distance_us=(flow_buf_rad[35]&&32)|(flow_buf_rad[34]&&16)|(flow_buf_rad[33]&&8)|(flow_buf_rad[32]);
& & & & & & & &&&floattobyte[0]=flow_buf_rad[36];
& & & & & & & &&&floattobyte[1]=flow_buf_rad[37];
& & & & & & & &&&floattobyte[2]=flow_buf_rad[38];
& & & & & & & &&&floattobyte[3]=flow_buf_rad[39];
& & & & & & & &&&flow_rad.distance=ByteToFloat(floattobyte);
& & & & & & & &&&flow_rad.temperature=(flow_buf_rad[41]&&8)|(flow_buf_rad[40]);
& & & & & & & &&&flow_rad.sensor_id=(flow_buf_rad[42]);
& & & & & & & &&&flow_rad.quality==(flow_buf_rad[43]);
& & & & & & & &&&
& & & & & & & &&&flow_fix.flow_x.origin =flow.flow_x.origin + flow_rad.integrated_ygyro*flow_fix.scale_rad_
& & & & & & & &&&flow_fix.flow_y.origin =flow.flow_y.origin - flow_rad.integrated_xgyro*flow_fix.scale_rad_
& & & & & & & &&&flow_fix.flow_comp_x.originf =flow.flow_comp_x.originf - flow_rad.integrated_ygyro*flow_fix.scale_rad_fix_
& & & & & & & &&&flow_fix.flow_comp_y.originf =flow.flow_comp_y.originf + flow_rad.integrated_xgyro*flow_fix.scale_rad_fix_
& & & &&&}& & & &
& & & &&&}
&&typedef struct
& & & &//Flow in m in x-sensor direction, angular-speed compensated
& & & & int16_
}FLOW_DATA;
&&typedef struct
& & & & uint64_t&&time_
& & & & u8& &
& & & & FLOW_DATA flow_x;
& & & & FLOW_DATA flow_y;
& & & & FLOW_DATA flow_comp_x;//Flow in m in x-sensor direction, angular-speed compensated
& & & & FLOW_DATA flow_comp_y;
& & & & u8 //Optical flow quality / confidence. 0: bad, 255: maximum quality
& & & & FLOW_DATA//ground_distance& & & & float& & & & Ground distance in m. Positive value: distance known. Negative value: Unknown distance& && && && && &
typedef struct
uint64_t time_ ///& Timestamp (microseconds, synced to UNIX time or since system boot)
uint32_t integration_time_ ///& Integration time in microseconds. Divide integrated_x and integrated_y by the integration time to obtain average flow. The integration time also indicates the.
float integrated_x; ///& Flow in radians around X axis (Sensor RH rotation about the X axis induces a positive flow. Sensor linear motion along the positive Y axis induces a negative flow.)
float integrated_y; ///& Flow in radians around Y axis (Sensor RH rotation about the Y axis induces a positive flow. Sensor linear motion along the positive X axis induces a positive flow.)
float integrated_ ///& RH rotation around X axis (rad)
float integrated_ ///& RH rotation around Y axis (rad)
float integrated_ ///& RH rotation around Z axis (rad)
uint32_t time_delta_distance_ ///& Time in microseconds since the distance was sampled.
///& Distance to the center of the flow field in meters. Positive value (including zero): distance known. Negative value: Unknown distance.
int16_ ///& Temperature * 100 in centi-degrees Celsius
uint8_t sensor_ ///& Sensor ID
uint8_ ///& Optical flow quality / confidence. 0: no valid flow, 255: maximum quality
}FLOW_RAD;
&&typedef struct
& & & & FLOW_DATA flow_x;
& & & & FLOW_DATA flow_y;
& & & & FLOW_DATA flow_comp_x;//Flow in m in x-sensor direction, angular-speed compensated
& & & & FLOW_DATA flow_comp_y;
& & & & float scale_rad_
& & & & float scale_rad_fix_
& & & & FLOW_DATA//ground_distance& & & & float& & & & Ground distance in m. Positive value: distance known. Negative value: Unknown distance& && && && && &
}FLOW_FIX;
新贴连接& &提供px4flow 光流串口接受和预处理库函数 头文件里有调用方法
赞一个,支持
写的不错,就是字体太大了!
楼主牛人,支持楼主,打击JS!
自己赶紧改一下吧,看起来太费劲了。
不错的帖子
字体太大,改改吧
我已经移植到MDK下了
我也在入门,你是用PX4带的eclipse开发的吗
我也在入门,你是用PX4带的eclipse开发的吗
没有 我还没对那个有接触
PX4FLOW-FX版光流传感器,好像很不错,就是不知道有多精准
正准备用PX4 FLOW,好东西
楼主研究的很深入了,我一开始买了个开源固件的光流,但是效果真的好差,后来又买了一个应该是你说的那家动了手脚的,主要是急着用就没有研究,现在是用串口接收,楼主用I2C实现了吗?我看I2C很简单,但是不行,不就是先写地址0X42,再写0,再读数据吗?
楼主研究PixHawk飞控吗?&&看了好久现在还没太整明白飞控的程序架构& &想做二次开发,可迟迟不能上手
我估计是固件的问题,刷了继续
楼主研究的很深入了,我一开始买了个开源固件的光流,但是效果真的好差,后来又买了一个应该是你说的那家动 ...
0X42是读的地址,他是7位地址。末尾代表读或者写。 给0X43那就是向SLAVE(从)里面写数据了。 表示没弄出来
&&if(FLOW_STATE[3]=100){
& && && && && && && && &if(data_cnt&26)&&这里是写错了吧。。。&&该是&&if(FLOW_STATE[3]==100)吧。。。
楼主研究PixHawk飞控吗?&&看了好久现在还没太整明白飞控的程序架构& &想做二次开发,可迟迟不能上手 ...
我没用过 都是自己尝试开发&&但是做的也不好
楼主研究的很深入了,我一开始买了个开源固件的光流,但是效果真的好差,后来又买了一个应该是你说的那家动 ...
没用i2c 板子上串口多 用起来方便
if(FLOW_STATE[3]=100){
& && && && && && && && &if(data_cnt
是的是的是的是的是的是的是的是的是的
楼主好人,有时间看看
楼主绝对是牛人
好帖留名。
通过光流测试波形可以看到,光流传感器非常容易受外界干扰,传感器上下移动,倾斜和左右旋转都会造成读数大幅移动,原因第一是本身图形的变化第二是光流算法中用到了陀螺仪读数和高度对图像光流的变化进行的修正,因此我感觉光流传感器只能用于定点悬停,想超过惯性导航无GPS下自主巡航貌似不太靠谱,需要一套非常完整的机制来确定什么时候该用光流传感器输出的速度和对特殊情况下的(光流数据容易受干扰)的滤波
楼主威武!!!正在调
楼主 我用你的固件和官方的固件没有 FLOW_m_COMP_x, 和 FLOW_m_COMP_x输出&&只有FLOW_X 和FLOW_y输出。 不知道是哪里没有使能还是怎么的。& &楼主的光流能给个图片看看吗
楼主 我用你的固件和官方的固件没有 FLOW_m_COMP_x, 和 FLOW_m_COMP_x输出&&只有FLOW_X 和FLOW_y输出。 不 ...
你如果没装超声模块 没有那个数据是正常的 因为光流算法中用到高度值来计算位移速度&&没有高度值 只能输出图形中光流像素的位移量 你可以参考源码在主控制器外围添加淘宝上便宜的传感器 计算出速度
楼主的固件刷新率只有10到20HZ&&完全不能满足需要啊&&
刷官方固件,用楼主参数,不行呀
感谢楼主分享啊,本来都快对光流放弃了,现在感觉又有阳光了
还有我想问下楼主这个px4flow怎么下程序那,用串口的mcuisp下吗
呵呵,找到哦怎么修改了,跟改apm参数差不多,逗比了。
请问左右周期运动是指左右平移还是原地左右转动?我尝试了下左右平移时波形变化不大,左右转动倒是波形和楼主差不多
我已经把光流的代码移植到MDK下面了,并做了优化
请问左右周期运动是指左右平移还是原地左右转动?我尝试了下左右平移时波形变化不大,左右转动倒是波形和楼 ...
平移平移平移平移
我已经把光流的代码移植到MDK下面了,并做了优化
能分享下工程吗
虽然看不懂。但是觉得很厉害。。
楼主,刚上手这个模块想请问下光流用作定点悬浮应该大概是一个怎么样的思路?能从里面读出flow_x和flow_y的读数,但从qground看波形扰动太大了…真的能做定点悬浮吗?那个平移距离应该怎么算?谢谢赐教!
楼主,刚上手这个模块想请问下光流用作定点悬浮应该大概是一个怎么样的思路?能从里面读出flow_x和flow_y的 ...
我还没弄 ,要悬停先要消除左右倾斜时也会输出速度,我开启了模块里的角度修正但是没什么卵子用,如果你给角度控制量限幅的很小然后只在悬停状态来使用应该直接用光流输出速度做反馈加上一个速度闭环就行,但是我想还是把光流像素位移量读出来自己做修正计算速度具体方法可以参照:
楼主你好,我是新手刚学习px4flow模块,用你的固件可以读出flow_x和flow_y,可以分享下楼主的工程吗?想修改一下固件代码
楼主你好,我用你的px4flow接收程序可以读出你的固件里面flow_x和flow_y的值但是却读不出官方固件的值,想问一下楼主是改了源程序里面的发送格式吗,可是我对着看的官方程序的发送格式和你的接收程序是对应的啊,谢谢楼主指点
楼主你好,我用你的px4flow接收程序可以读出你的固件里面flow_x和flow_y的值但是却读不出官方固件的值,想 ...
没改&&读不出哪个值
没改&&读不出哪个值
就是用你的px4flow接收程序读不出官方固件的flow_x和flow_y值,但是可以读出你的固件里面flow_x和flow_y的值,是因为传感器参数的原因吗
就是用你的px4flow接收程序读不出官方固件的flow_x和flow_y值,但是可以读出你的固件里面flow_x和flow_y ...
在v1.0版本中以“FE”作为起始标志&&不知道你的版本是什么的V0.9&&是0x55
在v1.0版本中以“FE”作为起始标志&&不知道你的版本是什么的V0.9&&是0x55
谢谢楼主了,我们找到原因了,是因为参数给的不对导致接收的数据有问题,换了楼主的参数就可以接收数据了,现在正在修改超声波代码,准备装一个廉价超声波上去。
楼主的飞控板是什么芯片《光流和飞控是用串口通信么?
楼主的飞控板是什么芯片《光流和飞控是用串口通信么?
我的飞控是stm32f407Vgt 是串口通信
我的飞控是stm32f407Vgt 是串口通信
串口通信的.c文件能给我参考一下么 本人学生
up!!!!
串口通信的.c文件能给我参考一下么 本人学生
前面有代码
成功读取..楼主能解释一下 flow_x,flow_y, flow_comp_x,flow_comp_y具体含义么怎么融合到定点PID里
楼主试过用I2C读取数据吗?还有就是我买的不带超声波的版本,我准备外接一个便宜超声波传感器。然后再飞控里面来计算真是移动速度。摄像头焦距是16mm吧,我看到一个文献说的,真实移动速度=光流像素速度X(高度/焦距)。具体算法是什么呢
楼主你好,我用的这个软件V2.60的,怎么把你的固件刷进去看看效果呀
本帖子中包含更多资源
才可以下载或查看,没有帐号?
学习了,谢谢楼主
楼主你好,我用的这个软件V2.60的,怎么把你的固件刷进去看看效果呀
setup里的固件更新
楼主,你编译px4flow代码的环境是什么?
楼主,你编译px4flow代码的环境是什么?
我还没编译过&&只是那模块直接用
楼主试过用I2C读取数据吗?还有就是我买的不带超声波的版本,我准备外接一个便宜超声波传感器。然后再飞控 ...
FLOW&&src 文件下 main。c里有像素换算速度的部分
const float focal_length_px = (12) / (4.0f * 6.0f) * 1000.0f; //original focal lenght: 12mm pixelsize: 6um, binning 4 enabled
& & & &&&flow_compx = flow_fix.flow_x.origin / focal_length_px / (flow_rad.integration_time_us / f);
楼主的滤波处理函数IIR_I_Filter可以参考一下吗,谢谢
楼主的滤波处理函数IIR_I_Filter可以参考一下吗,谢谢
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: IIR_I_Filter
** 功能描述: IIR直接I型滤波器
** 输& & 入: InData 为当前数据
**& && && &&&*x& &&&储存未滤波的数据
**& && && &&&*y& &&&储存滤波后的数据
**& && && &&&*b& &&&储存系数b
**& && && &&&*a& &&&储存系数a
**& && && &&&nb& &&&数组*b的长度
**& && && &&&na& &&&数组*a的长度
**& && && &&&LpfFactor
** 输& & 出: OutData& && && &
** 说& & 明: 无
** 函数原型: y(n) = b0*x(n) + b1*x(n-1) + b2*x(n-2) -
& && && && && && &&&a1*y(n-1) - a2*y(n-2)
**====================================================================================================*/
/*====================================================================================================*/
double IIR_I_Filter(double InData, double *x, double *y, double *b, short nb, double *a, short na)
&&double z1,z2;
&&double OutD
&&for(i=nb-1; i&0; i--)
& & x=x[i-1];
&&x[0] = InD
&&for(z1=0,i=0; i& i++)
& & z1 += x*b;
&&for(i=na-1; i&0; i--)
& & y=y[i-1];
&&for(z2=0,i=1; i& i++)
& & z2 += y*a;
&&y[0] = z1 - z2;
&&OutData = y[0];
&&return OutD
楼主的光流固件效果不错
楼主,刚上手这个模块想请问下光流用作定点悬浮应该大概是一个怎么样的思路?能从里面读出flow_x和flow_y的 ...
你好,请问你的光流能实现悬停了么?效果怎么样呢?
楼主的光流固件效果不错
你好,能交流一下光流使用心得么?刚上手,望指导,感谢!
楼主,你好,请问参考手册中的《PX4、
PIXhawk(PIXRaptor)编译环境的建立及源码的下载编译》一文,百度了,没找到,在哪可以找到啊?如何打开源代码进行编译啊?
楼主,你好,请问参考手册中的《PX4、
PIXhawk(PIXRaptor)编译环境的建立及源码的下载编译》一文,百度了 ...
我还没试过
不知道发送出去的数据是什么数据,i2c读取的地址不知道怎么写
我还没试过
楼主,请问你程序里面的32的采样频率和CMOS的刷新频率是多少啊?
我还没试过
还有7天前更新的更新RAD帧读取里,关于IIR滤波的程序,固件里面是没有的吧?还有那个超声波与PX4FLOW是怎么连接的啊?感谢楼主,不吝赐教!
楼主,你更新的RAD帧读取的那段代码,后半段的代码程序里面读不出任何值。。。只有你最开始的代码读出了和你一样的值。。。但是看波形。。左右平移的时候波形变化好像没有啊。。。只有左右晃动才有波形。。。请问楼主这是何原因
好贴,感谢楼主,收藏了。
怎么我用console 老是编译出错了
你好,用了你的固件,顶不住啊。ps:我没用超声波,只用了一个光流模块。
你好,请问你的光流能实现悬停了么?效果怎么样呢?
你好,请问你现在实现光流定点了吗?有没有结合超声波使用?
好东西,mark了!
支持一个,收藏了
我已经移植到MDK下了
能把你的工程分享下吗?谢谢啦
顶一个,楼主研究的很认真,看似花了不少时间和心思
通过光流测试波形可以看到,光流传感器非常容易受外界干扰,传感器上下移动,倾斜和左右旋转都会造成读数大 ...
这个数据本身就容易收到干扰,确实需要外围的传感器数据用来纠正,不过相对就复杂了很多
我已经移植到MDK下了
漂亮,对pix家的那种指令行的make方式确实反感,移植都需要哪些注意的呢,复杂程度如何,一直想移植,但是代码比较大,想找一个相对小一点的工程移植试试
问问十几块的那种能装到pix上用吗
意义不大用GPS就可以定的很稳
更新 光流定位测试视频 ,死区有点大定位调整不足
光棍节更新 光流定点视频
光流悬停的飞控用的啥?apm吗
光流悬停的飞控用的啥?apm吗
自己的飞控 OLD-X
光棍节更新 光流定点视频 /s/15bO2E
楼主,可以发最新的Flow固件测试吗?飞控代码flow_postion_estimat.c有修改吗?我室内测试过你的 “px4flow.zip (43.96 KB, 下载次数: 110) ”,在Loiter模式与STABILIZE模式差不多,定位效果不是很好,比室外GPS模式的(Loiter)模式差。
楼主,可以发最新的Flow固件测试吗?飞控代码flow_postion_estimat.c有修改吗?我室内测试过你的 “px4fl ...
你试试这个行不行
本帖子中包含更多资源
才可以下载或查看,没有帐号?
你试试这个行不行
谢谢楼主!我先测试过,体验体验,再与你分享!
楼主,比以前改善了很多的,可以共享一下源代码?
你试试这个行不行
楼主,新的固件,室内定位效果不错,请教楼主你在Flow-master 代码修改了哪些东西,可以详细说说吗?正在做课题报告,过几天上交;请楼主帮帮忙,我的邮箱
楼主,新的固件,室内定位效果不错,请教楼主你在Flow-master 代码修改了哪些东西,可以详细说说吗?正在 ...
我也是在网上下的 你可以看看国外的论坛有没有人改过
我也是在网上下的 你可以看看国外的论坛有没有人改过
无人机大神,请教大神国外哪一个网站,麻烦指点迷津!
我也是在网上下的 你可以看看国外的论坛有没有人改过
楼主,新的固件,室内定位Loiter模式还是会漂,Loiter模式没有GPGS稳定。
楼主,新的固件,室内定位Loiter模式还是会漂,Loiter模式没有GPGS稳定。
zzzzzzzzzzzzzzzzzzzzzzzzzzz
本帖子中包含更多资源
才可以下载或查看,没有帐号?
zzzzzzzzzzzzzzzzzzzzzzzzzzz
楼主,你好!你的这个固件将Flow-master的I2C关掉了吗?怎么I2C无数据出来呢?
zzzzzzzzzzzzzzzzzzzzzzzzzzz
楼主,麻烦你不要关掉I2C通信,我的飞控板与flow-master是I2C通信的,飞控板测不了光流数据
本帖最后由 molys 于
16:17 编辑
zzzzzzzzzzzzzzzzzzzzzzzzzzz
楼主,在QGC上看图像质量,固件px4flow_hao1比固件pxflow_hao12好一些,但固件px4flow_hao1没有I2C通信,PIXHAWK 飞控光流通信是I2C,无法测试到实际结果,请不要屏蔽I2C.谢谢楼主,谢谢大神!
楼主,是加了如下文件吗:
同学&&抱歉我也不怎么清楚光流的程序 那个hao1是飞行试验室的但是不用他们的光流硬件xy读数只是反了下向&&你可以试试加上滤波会不会好一点,欢迎交流飞控其他方面的知识
阿莫电子论坛, 原"中国电子开发网"}

我要回帖

更多关于 pixhawk飞控板原理图 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信