当前位置: 首页 > article >正文

PX4飞控自定义Mavlink消息:实现UART传感器数据在QGC地面站的可视化

1. 为什么需要自定义Mavlink消息在无人机开发中我们经常需要将各种传感器数据实时传输到地面站进行监控和分析。PX4飞控虽然内置了丰富的标准Mavlink消息但当我们接入一些特殊传感器时标准消息往往无法满足需求。比如你想通过UART串口接入一个电池管理系统(BMS)实时监测电压、电流、温度等参数这时候就需要自定义Mavlink消息了。我去年做过一个农业植保机项目需要实时监测药箱剩余药量和喷洒流量。标准Mavlink消息里没有这些字段当时就是通过自定义消息解决的。实测下来这种方案非常稳定可靠飞行2小时没出现过数据丢失。自定义Mavlink消息的核心优势在于可以自由定义数据结构完全适配你的传感器数据传输效率高一条消息就能打包所有相关参数QGC地面站可以原生支持不需要额外插件与标准消息使用相同的通信机制稳定性有保障2. 准备工作与环境搭建2.1 硬件准备首先确保你有这些硬件搭载PX4飞控的无人机Pixhawk系列或兼容硬件待接入的UART传感器如电压电流传感器调试用的电脑和USB数据线数传电台或WiFi链路用于地面站通信我推荐使用Pixhawk 4硬件它的UART接口丰富而且社区支持最好。传感器方面我用过Hobbywing的PL8电量计通过串口输出数据很稳定。2.2 软件环境需要准备这些软件工具PX4固件开发环境建议Ubuntu 18.04/20.04QGroundControl地面站版本3.5代码编辑器VS Code或Qt Creator串口调试工具如cutecom安装PX4开发环境时建议直接用官方提供的脚本bash ./Tools/setup/ubuntu.sh这个脚本会自动安装所有依赖项包括编译器、调试工具等。我第一次手动安装时漏了几个包编译老是报错后来用脚本一次就搞定了。3. 定义Mavlink消息结构3.1 创建消息定义文件在mavlink/message_definitions/v1.0/目录下新建read_sensor.xml文件?xml version1.0? mavlink version3/version messages message id223 nameREAD_UART_SENSOR descriptionBMS sensor data from UART/description field typefloat namevoltageVoltage in volts/field field typefloat namecurrentCurrent in amps/field field typefloat nametemperatureTemperature in °C/field field typeuint8_t namequantityRemaining percentage/field field typeuint8_t nameremainingRemaining minutes/field /message /messages /mavlink几个注意事项消息ID要避开标准消息范围建议200-300字段类型要匹配传感器数据类型字段名称要有意义方便后续使用记得添加单位说明我曾经因为字段类型用错该用float用了int导致数据精度丢失调试了半天才发现问题。3.2 生成消息头文件执行以下命令生成C语言头文件python3 -m pymavlink.tools.mavgen --langC --wire-protocol2.0 --outputgenerated/include/mavlink/v2.0 message_definitions/v1.0/read_sensor.xml生成的文件会放在generated/include/mavlink/v2.0目录下。把这个目录下的相关文件复制到PX4固件的mavlink/include/mavlink/v2.0/common目录中。4. PX4飞控端实现4.1 创建uORB消息在Firmware/msg/目录下创建read_uart_sensor.msg文件uint64 timestamp # 时间戳 float32 voltage # 电压值 float32 current # 电流值 float32 temperature # 温度值 uint8 quantity # 剩余电量百分比 uint8 remaining # 剩余飞行时间(分钟)然后在CMakeLists.txt中添加这个msg文件set(msg_files ... read_uart_sensor.msg )4.2 实现串口读取模块在src/modules/下新建read_uart_sensor目录创建主程序文件#include px4_platform_common/module.h #include drivers/drv_hrt.h #include uORB/uORB.h #include uORB/topics/read_uart_sensor.h // UART初始化 int uart_init(const char *device) { int fd open(device, O_RDWR | O_NOCTTY); // 配置串口参数... return fd; } // 主线程函数 int read_uart_thread(int argc, char *argv[]) { int uart_fd uart_init(/dev/ttyS3); struct read_uart_sensor_s sensor_data {}; orb_advert_t pub orb_advertise(ORB_ID(read_uart_sensor), sensor_data); while(!thread_should_exit) { // 读取串口数据并解析 char buffer[64]; read(uart_fd, buffer, sizeof(buffer)); // 示例数据格式: 15.4,2.1,25,80,30 sscanf(buffer, %f,%f,%f,%hhu,%hhu, sensor_data.voltage, sensor_data.current, sensor_data.temperature, sensor_data.quantity, sensor_data.remaining); sensor_data.timestamp hrt_absolute_time(); orb_publish(ORB_ID(read_uart_sensor), pub, sensor_data); usleep(100000); // 10Hz更新 } close(uart_fd); return 0; }4.3 配置Mavlink消息流在mavlink_messages.cpp中添加消息流类class MavlinkStreamReadUartSensor : public MavlinkStream { public: const char *get_name() const override { return READ_UART_SENSOR; } uint16_t get_id() override { return MAVLINK_MSG_ID_READ_UART_SENSOR; } bool send(const hrt_abstime t) override { read_uart_sensor_s data; if(_sub.update(data)) { mavlink_read_uart_sensor_t msg {}; msg.voltage data.voltage; msg.current data.current; msg.temperature data.temperature; msg.quantity data.quantity; msg.remaining data.remaining; mavlink_msg_read_uart_sensor_send_struct(_mavlink-get_channel(), msg); return true; } return false; } private: uORB::Subscription _sub{ORB_ID(read_uart_sensor)}; };然后在mavlink_main.cpp中设置发送频率configure_stream(READ_UART_SENSOR, 10.0f); // 10Hz5. QGC地面站端实现5.1 添加消息解析将生成的mavlink_msg_read_uart_sensor.h复制到QGC的libs/mavlink/include/mavlink/v2.0/common目录。在Vehicle.cc中添加消息处理函数void Vehicle::_handleReadUartSensor(mavlink_message_t message) { mavlink_read_uart_sensor_t sensor; mavlink_msg_read_uart_sensor_decode(message, sensor); _batteryFactGroup.voltage()-setRawValue(sensor.voltage); _batteryFactGroup.current()-setRawValue(sensor.current); _batteryFactGroup.temperature()-setRawValue(sensor.temperature); _batteryFactGroup.percentRemaining()-setRawValue(sensor.quantity); _batteryFactGroup.timeRemaining()-setRawValue(sensor.remaining); }5.2 修改UI界面在BatteryIndicator.qml中添加显示控件Column { spacing: 2 QGCLabel { text: 电压: _activeVehicle.battery.voltage.value.toFixed(1) V } QGCLabel { text: 电流: _activeVehicle.battery.current.value.toFixed(1) A } QGCLabel { text: 温度: _activeVehicle.battery.temperature.value.toFixed(0) °C } QGCLabel { text: 电量: _activeVehicle.battery.percentRemaining.value % } QGCLabel { text: 剩余时间: _activeVehicle.battery.timeRemaining.value 分钟 } }6. 调试与优化技巧6.1 常见问题排查数据不更新检查串口配置波特率、数据位、停止位数据错误验证消息ID在飞控和地面站端是否一致数据延迟调整Mavlink消息发送频率内存不足优化消息结构减少不必要字段我遇到过一个坑地面站收不到数据最后发现是消息ID在飞控和地面站版本不一致。建议在消息定义稳定前两边同时更新。6.2 性能优化建议合理设置消息频率关键数据10-20Hz足够使用适当的数据类型能用uint8就不要用float启用数据压缩对浮点数设置合理的精度使用多消息分流大数据量时分多个消息发送在植保机项目中我把所有喷洒数据打包到一个消息里结果导致通信延迟。后来拆分成两个消息问题就解决了。7. 扩展应用场景这种自定义消息的方案不仅适用于电池监测还可以用于农业植保机的药量监测物流无人机的货舱状态监控巡检无人机的专用传感器数据实验性传感器的快速集成去年给某科研团队做水下无人机时就用类似方案传输了水深、水温和水质数据。他们后来发论文时还特别感谢了这个数据采集方案。

相关文章:

PX4飞控自定义Mavlink消息:实现UART传感器数据在QGC地面站的可视化

1. 为什么需要自定义Mavlink消息 在无人机开发中,我们经常需要将各种传感器数据实时传输到地面站进行监控和分析。PX4飞控虽然内置了丰富的标准Mavlink消息,但当我们接入一些特殊传感器时,标准消息往往无法满足需求。比如你想通过UART串口接入…...

Gumbo-parser内存管理终极指南:7个简单步骤避免常见陷阱

Gumbo-parser内存管理终极指南:7个简单步骤避免常见陷阱 【免费下载链接】gumbo-parser An HTML5 parsing library in pure C99 项目地址: https://gitcode.com/gh_mirrors/gu/gumbo-parser Gumbo-parser是一个纯C99编写的HTML5解析库,高效的内存…...

React Native Interactable跨平台开发终极指南:iOS与Android差异处理技巧

React Native Interactable跨平台开发终极指南:iOS与Android差异处理技巧 【免费下载链接】react-native-interactable Experimental implementation of high performance interactable views in React Native 项目地址: https://gitcode.com/gh_mirrors/re/react…...

ai域名后缀注册对SEO有影响吗

ai域名后缀注册对SEO有影响吗 在当今互联网时代,域名选择对于一个网站的成功至关重要。尤其是对于那些在科技、人工智能(AI)等前沿领域的企业和个人来说,ai域名后缀注册的问题更是备受关注。本文将从多个角度探讨ai域名后缀注册对…...

wx-dump-4j前端架构解析:React+Ant Design构建现代化管理界面

wx-dump-4j前端架构解析:ReactAnt Design构建现代化管理界面 【免费下载链接】wx-dump-4j 一款基于Java开发的微信数据分析工具。 项目地址: https://gitcode.com/gh_mirrors/wx/wx-dump-4j wx-dump-4j是一款基于Java开发的微信数据分析工具,其前…...

jsTree状态管理插件终极指南:实现用户界面的持久化状态保存

jsTree状态管理插件终极指南:实现用户界面的持久化状态保存 【免费下载链接】jstree jquery tree plugin 项目地址: https://gitcode.com/gh_mirrors/js/jstree jsTree状态管理插件是提升用户体验的关键组件,能够自动保存和恢复树形结构的展开状态…...

深入解析C语言malloc(0)的内存分配机制

1. 深入解析 malloc(0) 的行为机制在 C 语言编程中,内存管理是一个基础但极其重要的话题。malloc 函数作为动态内存分配的核心工具,其行为规范在 C 标准中有明确定义。然而,当我们遇到像 malloc(0) 这样的边界情况时,事情就变得有…...

escodegen浏览器端使用教程:在Web环境中实现代码生成

escodegen浏览器端使用教程:在Web环境中实现代码生成 【免费下载链接】escodegen ECMAScript code generator 项目地址: https://gitcode.com/gh_mirrors/es/escodegen escodegen是一个强大的ECMAScript代码生成器,它能够将抽象语法树(AST)转换回…...

React Native Interactable终极指南:TouchesInside与静态交互对比详解

React Native Interactable终极指南:TouchesInside与静态交互对比详解 【免费下载链接】react-native-interactable Experimental implementation of high performance interactable views in React Native 项目地址: https://gitcode.com/gh_mirrors/re/react-na…...

snabbt.js与Hammer.js集成终极指南:打造流畅触摸手势动画的10个技巧

snabbt.js与Hammer.js集成终极指南:打造流畅触摸手势动画的10个技巧 【免费下载链接】snabbt.js Fast animations with javascript and CSS transforms 项目地址: https://gitcode.com/gh_mirrors/sn/snabbt.js snabbt.js是一个轻量级JavaScript动画库&#…...

开源模型性价比之选:Gemma-3-12b-it在OpenClaw中的实战表现

开源模型性价比之选:Gemma-3-12b-it在OpenClaw中的实战表现 1. 为什么选择Gemma-3-12b-it作为OpenClaw的推理引擎 上个月在优化个人自动化工作流时,我面临一个关键决策:该为OpenClaw选择什么样的大模型作为"大脑"?经过…...

5分钟上手Velocity动态主题动画:让界面动效随用户偏好智能切换

5分钟上手Velocity动态主题动画:让界面动效随用户偏好智能切换 【免费下载链接】velocity Accelerated JavaScript animation. 项目地址: https://gitcode.com/gh_mirrors/ve/velocity Velocity是一款高性能的JavaScript动画库,专注于提供流畅、高…...

Jasny Bootstrap按钮标签组件详解:如何优雅地添加图标标签

Jasny Bootstrap按钮标签组件详解:如何优雅地添加图标标签 【免费下载链接】bootstrap The missing components for your favorite front-end framework. 项目地址: https://gitcode.com/gh_mirrors/boots/bootstrap Jasny Bootstrap作为Bootstrap的扩展组件…...

Vivado报错[Opt 31-430]?别慌,手把手教你从网表里揪出那个‘没爹妈’的FDCE

Vivado报错[Opt 31-430]全流程诊断手册:从网表逆向追踪到代码修复 当Vivado在opt_design阶段抛出[Opt 31-430] Found a FDCE that its data pin is undriven时,多数FPGA开发者的第一反应是检查代码中的寄存器定义。但真实情况往往更复杂——这个报错可能…...

Decision Transformer与行为克隆对比分析:何时选择哪种方法

Decision Transformer与行为克隆对比分析:何时选择哪种方法 【免费下载链接】decision-transformer Official codebase for Decision Transformer: Reinforcement Learning via Sequence Modeling. 项目地址: https://gitcode.com/gh_mirrors/de/decision-transfo…...

ShareList插件开发全攻略:从零开始打造专属网盘工具

ShareList插件开发全攻略:从零开始打造专属网盘工具 【免费下载链接】sharelist 快速分享 GoogleDrive OneDrive 项目地址: https://gitcode.com/gh_mirrors/sh/sharelist ShareList是一款强大的开源网盘工具,支持快速挂载Google Drive、OneDriv…...

跨平台文件同步:OpenClaw+百川2-13B-4bits量化模型智能归档方案

跨平台文件同步:OpenClaw百川2-13B-4bits量化模型智能归档方案 1. 为什么需要智能文件归档 作为一个长期在多台设备间切换工作的开发者,我的文件管理一直处于混乱状态。同一份文档可能同时存在于Mac的Downloads文件夹、Windows桌面的"临时"目…...

高级应用:将Decision Transformer部署到生产环境的完整流程

高级应用:将Decision Transformer部署到生产环境的完整流程 【免费下载链接】decision-transformer Official codebase for Decision Transformer: Reinforcement Learning via Sequence Modeling. 项目地址: https://gitcode.com/gh_mirrors/de/decision-transfo…...

EasyPhoto与ControlNet深度集成:实现精准肖像控制的终极指南

EasyPhoto与ControlNet深度集成:实现精准肖像控制的终极指南 【免费下载链接】sd-webui-EasyPhoto 📷 EasyPhoto | Your Smart AI Photo Generator. 项目地址: https://gitcode.com/gh_mirrors/sd/sd-webui-EasyPhoto 在AI肖像生成领域&#xff0…...

别再死记硬背了!用Wireshark抓包实战,5分钟搞懂TCP三次握手和HTTP请求全过程

用Wireshark抓包实战:5分钟可视化TCP三次握手与HTTP请求 刚接触计算机网络时,那些抽象的三次握手、滑动窗口、HTTP报文总让人头晕。直到我第一次用Wireshark看到真实的数据包在屏幕上跳动——原来教科书上的每个概念都能在抓包结果中找到对应的"证…...

5分钟快速上手MUNIT:从零开始构建你的第一个图像翻译模型

5分钟快速上手MUNIT:从零开始构建你的第一个图像翻译模型 【免费下载链接】MUNIT Multimodal Unsupervised Image-to-Image Translation 项目地址: https://gitcode.com/gh_mirrors/mu/MUNIT MUNIT(Multimodal Unsupervised Image-to-Image Trans…...

OpenClaw+gemma-3-12b-it:学术论文自动摘要与分类系统

OpenClawgemma-3-12b-it:学术论文自动摘要与分类系统 1. 为什么需要自动化论文处理 作为一名经常需要阅读大量文献的研究者,我深刻体会到手动处理论文的痛点。每周需要从arXiv、PubMed等平台下载数十篇论文,然后逐篇阅读摘要、分类归档。这…...

技术面试终极指南:10个反向面试技巧助你问对公司问题

技术面试终极指南:10个反向面试技巧助你问对公司问题 【免费下载链接】reverse-interview Questions to ask the company during your interview 项目地址: https://gitcode.com/gh_mirrors/re/reverse-interview 在技术面试中,反向面试&#xff…...

Uppy与MongoDB Atlas集成指南:云数据库中的文件元数据存储解决方案

Uppy与MongoDB Atlas集成指南:云数据库中的文件元数据存储解决方案 【免费下载链接】uppy The next open source file uploader for web browsers :dog: 项目地址: https://gitcode.com/gh_mirrors/up/uppy Uppy作为现代Web应用的文件上传解决方案&#xff…...

C++与C混合编程:extern ‘C‘原理与实践指南

1. 揭开extern C的神秘面纱第一次看到extern C这个语法时,我和大多数C新手一样感到困惑。它看起来像是一个可有可无的修饰符,直到我在实际项目中踩了坑才明白它的重要性。记得那是一个跨平台的网络库项目,当我们尝试在C代码中调用一个C语言编…...

避开Arduino PID编程的3个常见坑:为什么你的控制总是不稳?

Arduino PID控制实战:避开3个致命陷阱实现精准调节 当你在深夜盯着反复震荡的电机转速曲线,或是加热棒温度始终无法稳定的数据时,是否怀疑过自己复制的PID代码有问题?这不是你的错觉——大多数Arduino PID控制问题都源于三个容易被…...

如何利用社交平台快速提升gallery本地AI平台影响力:5个实战推广策略

如何利用社交平台快速提升gallery本地AI平台影响力:5个实战推广策略 【免费下载链接】gallery A gallery that showcases on-device ML/GenAI use cases and allows people to try and use models locally. 项目地址: https://gitcode.com/GitHub_Trending/galler…...

本地AI模型开发终极指南:从零开始构建智能应用社区

本地AI模型开发终极指南:从零开始构建智能应用社区 【免费下载链接】gallery A gallery that showcases on-device ML/GenAI use cases and allows people to try and use models locally. 项目地址: https://gitcode.com/GitHub_Trending/gallery44/gallery …...

gallery用户留存技巧:提高本地AI平台用户的活跃度

gallery用户留存技巧:提高本地AI平台用户的活跃度 【免费下载链接】gallery A gallery that showcases on-device ML/GenAI use cases and allows people to try and use models locally. 项目地址: https://gitcode.com/GitHub_Trending/gallery44/gallery …...

gallery应用商店优化:提升本地AI平台的发现率与下载量

gallery应用商店优化:提升本地AI平台的发现率与下载量 【免费下载链接】gallery A gallery that showcases on-device ML/GenAI use cases and allows people to try and use models locally. 项目地址: https://gitcode.com/GitHub_Trending/gallery44/gallery …...