ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

机载电脑与PIX6C飞控UART串口通信:三平台读取IMU数据实战

机载电脑与PIX6C飞控UART串口通信:三平台读取IMU数据实战 第一次把香橙派5 Max和PIX6C用三根杜邦线连在一起的那个晚上我盯着屏幕上的空输出看了很久。USB转串口的TX灯明明在闪飞控的心跳理论上已经在这根线上跑了可终端里就是什么都读不到。后来发现原因简单得让人脸红——板子默认启用的根本不是我以为的那个设备节点。机载电脑与飞控之间最常用、也最容易被“想当然”拖进坑里的通道就是UART串口而串口这条链路上最典型的实战目标就是读取飞控的IMU数据流。这篇内容把三篇实测串成一条线香橙派5 Max启动UART与飞控直连、Allspark1与PIX6C的通信踩坑出坑、Orin NX载板与飞控通信最后落到一个可复现的结果上——稳定读到IMU数据并且知道接下来能拿它做什么。1. 为什么飞控的真实数据都在串口里先搞清楚MAVLink从哪根线出来1.1 飞控串口输出的不是“裸体”IMU而是MAVLink消息流很多人以为飞控串口吐出来的东西就是类似GPS坐标或者原始传感器读数那样一段段独立的数据。其实PX4/ArduPilot上电后TELEM串口会主动向外发送MAVLink协议消息。MAVLink 2以二进制帧为单位一帧数据里有magic字节、length、seq序号、sysid/compid、message id、payload和checksum。你想读IMU实际上就是在这一帧一帧的二进制流里找message id为27RAW_IMU、26SCALED_IMU、105HIGHRES_IMU、30ATTITUDE等消息。这个区别很重要。因为如果你不知道MAVLink帧结构直接拿串口调试工具看满屏都是乱码你根本不知道通信是否成功。但只要知道“飞控串口输出的是MAVLink协议流”整套排查逻辑就清晰了先确认物理层能收到字节流再用能解析MAVLink的工具去验证协议层。物理层通、协议层通、数据字段能用这三步是递进关系缺一不可。1.2 TELEM口、GPS口与DEBUG口的区别插错口是最常见的伪故障PIX6C这类飞控上接口非常多而跟机载电脑通信首推TELEM1或TELEM2。GPS口虽然也是UART但默认是给GPS模块使用的输出的是NMEA或其他GPS协议DEBUG口主要是飞控系统调试控制台不是给你传业务数据用的I2C、CAN、SBUS也都是各自的专用总线根本不是标准UART。所以“我把线接到GPS口上为什么读不到MAVLink”这种问题我见过太多次多数时候不是接线或参数的问题纯粹是接口选错了。TELEM口的物理形态一般是JST-GH 4芯或6芯其中4芯分别是TX、RX、VCC、GND6芯会多出RTS/CTS流控信号。这里特别提醒一句不要给飞控的VCC口随便灌电。飞控本身有自己的电源管理机载电脑这边只需要接三根线VCC悬空不接即可。两边电源如果直接联通可能形成地环路严重时会导致飞控供电异常。message id消息名内容与用途27RAW_IMU三轴加速度、陀螺、磁力原始测量值适合算法自己处理噪声与偏置26SCALED_IMU标定后的加速度、陀螺、磁力单位多为mG和mrad/s105HIGHRES_IMU浮点高精度IMU单位是标准国际单位解析最方便30ATTITUDE飞控解算后的欧拉角与四元数单位是弧度1.3 电平匹配第一课3.3V TTL不是RS232飞控的TELEM口是3.3V TTL电平。香橙派5 Max的UART引脚、Orin NX载板的UART引脚也基本都是3.3V TTL所以这些平台之间可以直接连。但如果你手里拿的是USB转RS232线或者把TX/RX接到了某个5V电平的调试串口上轻则收不到数据重则烧掉串口引脚。我踩过一次用一根5V输出的PL2303模块去连飞控虽然侥幸没烧但那次通信就从来没稳定过飞控偶尔能收到数据偶尔什么都收不到。后来换了个CP2102模块把电平调到3.3V输出问题瞬间消失。所以无论你用什么USB转串口芯片一定要买支持3.3V电平、且能切换到3.3V TTL输出的版本。FT232、CP2102、CH340这些常见芯片里前两者驱动支持和稳定性明显更好做机载通信我会优先选。2. 香橙派5 Max起步把UART从“隐藏模式”里拉出来2.1 香橙派镜像里UART默认没启用设备节点存在但引脚没复用香橙派5 Max用的是瑞芯微RK3588系列平台官方Ubuntu/Debian镜像里40pin排针上的UART很多默认没有开放。我在系统里执行ls /dev/ttyS*能看到ttyS0、ttyS1、ttyS7等一系列设备节点但这不代表40pin上的UART_RX和UART_TX引脚已经被复用成串口功能了。板子出厂时这些引脚可能被配置成GPIO、I2C或者SPI功能你在对应的ttyS节点上read要么永远阻塞要么读到的是固定高电平什么都没变化。启用方式现在主要有两种一是香橙派系统里的rsetup工具里面有硬件/overlay菜单把对应UART打开后重启二是直接改/boot/orangepiEnv.txt在overlays字段后面追加你需要的UART序号。不同发行版路径可能不一样但底层思路都是通过设备树overlay把引脚复用成UART功能。这一步不做后面所有操作都白搭。2.2 找到自己的UART设备名不靠猜很多人上来就写/dev/ttyS0大概率不行。建议用sudo dmesg | grep -i tty查看串口注册情况同时打开香橙派5 Max的原理图或者40pin手册看清你用的那组UART编号对应哪个ttyS节点。以我常用的组合为例我在rsetup里开启了UART7之后设备节点出现在/dev/ttyS7引脚在40pin上。每个板子的映射不一定相同所以我每次换板子都会先做一次环回测试# 先把串口TX和RX用杜邦线短接 stty -F /dev/ttyS7 115200 raw -echo echo hello mavlink /dev/ttyS7 cat /dev/ttyS7如果cat能收到自己刚发出去的字符串说明从内核设备节点到引脚物理输出这条链路都是好的。这一步非常值得做因为它把“板子配置问题”和“飞控连接问题”一刀切开。环回测试过了后面接飞控时如果还没数据那就是接线或飞控侧的事不需要再怀疑板子。2.3 连接飞控和香橙派三根线一个坑飞控TELEM2的TX接香橙派的RX飞控的RX接香橙派的TXGND接GND。VCC不接。第一次测试低速近距离下用杜邦线没问题但最好控制在10cm以内并远离电调和电源线。我遇到过一根40cm的飞线绕在电调信号线旁边造成串口时通时断换成短飞线后立刻稳定。这种问题很难用软件排查因为示波器看波形是有的但误码率就是高罪魁祸首往往是电磁干扰。平台常见原生串口节点使能方式我推荐的首接方案香橙派5 Max/dev/ttyS7等rsetup或设备树overlay40pin直连TTLAllspark1/dev/ttyUSB0/ttyUSB1USB驱动即插即用USB转TTL模块Orin NX载板/dev/ttyTHS1需设备树使能设备树overlay较折腾USB转TTL模块优先物理连接完成后用stty把串口设置为115200、raw模式然后直接cat /dev/ttyS7屏幕上应该出现稳定的二进制乱码。看到乱码别慌那大概率就是MAVLink流。再用mavproxy做协议验证mavproxy.py --master/dev/ttyS7 --baud115200 --outudp:127.0.0.1:14550能等到heartbeat香橙派这边就算真正跑通了。按这个顺序来做香橙派5 Max这一Part确实能做到一次必通。3. Allspark1与PIX6C连续踩坑从权限到接线再到波特率的完整排查链路3.1 第一座山ttyUSB0打开就报I/O error多半是ModemManager在抢设备Allspark1这类ARM机载电脑最容易的接法不是直接引原生UART而是插一个USB转串口模块。插上后ls /dev/ttyUSB*能看到设备但用Python的serial库打开时报错或者cat直接提示I/O error这是我第一次在这个平台上踩的坑。原因是Ubuntu的ModemManager服务会把USB串口设备当成潜在的拨号modem时不时自动去操作它导致设备被占用。排查方法是在另一个终端里持续执行dmesg -w同时去打开设备大概率能看到“Device or resource busy”之类的字样。解决办法很直接关掉ModemManager并禁用sudo systemctl stop ModemManager sudo systemctl disable ModemManager这步做完很多看似玄学的“串口打不开”问题就消失了。如果你不想整体禁用ModemManager也可以写udev规则把特定的USB转串口设备标记为不要被它接管但对机载电脑这种专用设备来说直接禁用更省心。3.2 第二座山用户权限不够以及ttyUSB设备号漂移打开不报busy了但提示Permission denied那就是当前用户不在dialout组里。解决办法sudo usermod -aG dialout $USER然后重新登录一次。有朋友改完组不重新登录就过来问为什么还是没权限其实一组group刷新就解决了。ttyUSB序号漂移是Allspark1这种多USB设备平台的常态。你同时插了U盘、数传、USB转串口重启后同一个模块可能从ttyUSB0变成ttyUSB1。代码里硬编码设备名过两天就可能因为插入顺序变化而找不到设备。最靠谱的对策是写udev规则按USB转串口芯片的idVendor和idProduct固定一个符号链接。echo SUBSYSTEMtty, ATTRS{idVendor}0403, ATTRS{idProduct}6001, SYMLINKfcu, MODE0666 | sudo tee /etc/udev/rules.d/99-fcu.rules sudo udevadm control --reload-rules sudo udevadm triggerFT232的vendor/product是0403:6001CP2102是10C4:EA60。规则生效后代码里直接写/dev/fcu不管ttyUSB编号怎么变都能找到。这个习惯我在所有机载电脑上都会保留值得推广。3.3 第三座山TX/RX接反和PIX6C的TELEM2波特率到了“能打开串口但一点数据都没有”的阶段90%是TX/RX接反。这里记住一句话飞控的TX必须进板子的RX飞控的RX必须进板子的TX。USB转串口模块上丝印一般标得很清楚但个别模块丝印不准所以不要迷信实测没数据就交叉换一下再测。PIX6C的TELEM2默认波特率我记得是115200但如果你拿到手的飞控被其他人刷过参数说不定是57600或者921600。正确做法是到QGC的参数表里查看SER_TEL2_BAUD这个参数它写多少串口这边就设多少。不要想当然地认为一定是115200我见过好几个案例都是上一手改过参数导致后面的人一直怀疑线坏了。所有参数都对之后用minicom或直接cat看字节如果满屏纯净乱码且节奏稳定说明链路正常。如果完全0字节回去查线序如果乱码中夹杂可读的“”这类字符往往是波特率不匹配。这个观察经验比任何调试工具都直接。3.4 避干扰短飞线、Mavlink Router中转Allspark1这个平台给我最深的教训是用长飞线把USB转串口模块拉到PIX6C旁边结果IMU数据在飞行测试时出现毛刺。后来我把飞线换成10cm以内的双绞杜邦线并把模块固定在机架远离电调的位置现象才消失。USB转串口模块这种小东西很多人不重视摆放位置但它在机架上的位置直接决定串口信噪比。软件层面如果你要在机载电脑上同时跑多个程序读同一个串口千万不要直接开两个进程抢同一个tty。用mavlink-router把串口转成UDP/TCP再分发给ROS、地面站和其他程序是最稳的做法mavlink-routerd -e 127.0.0.1:14550 /dev/fcu:115200这样MAVLink消息就成了“可多人订阅”网络资源谁想读IMU都来UDP端口拿串口侧只保留一个读进程彻底避免资源竞争。4. Orin NX载板别硬刚原生UARTUSB转串口其实是更稳的通道4.1 Jetson平台的串口命名与常规Linux差异很大Orin NX载板跑JetPack系统底层虽然是Ubuntu但Tegra系列SoC的原生串口设备名往往叫ttyTHS0、ttyTHS1而不是我们更熟悉的ttyS0。网上大量Linux串口教程里写的/dev/ttyS0在Jetson上很可能对应不到实际硬件。建议先执行这条命令看看当前板子有哪些串口设备ls /dev/ttyTHS* /dev/ttyUSB* /dev/ttyACM* 2/dev/null如果什么都看不到就先插USB转串口再执行一次。Jetson上很多板级UART是默认关闭的光看设备列表你就会发现USB转串口可能是你唯一能立刻用上的串口通道。4.2 40pin上那个UART默认未必真的能用Orin NX载板上最常被想当然使用的一组引脚是40pin中的UART_TX和UART_RX。问题在于很多载板默认把这组引脚分配给了系统调试串口或者UART功能根本没有在设备树里使能。我最初在Orin NX上硬刚原生UART编译设备树、改extlinux.conf、反复重启折腾了很长时间才让Pin8/Pin10输出数据。如果你确实想用原生UART方向是找到载板型号对应的设备树overlay在/boot/extlinux/extlinux.conf里追加FDT overlays重启后检查对应ttyTHS节点是否出现。但这个流程在不同JetPack版本和不同载板之间差异很大。如果你手头任务比较急在飞行现场搞设备树并不划算我后来基本不再走这条路。4.3 Orin NX载板的最佳姿势CP2102/FT232 USB转串口直连我的建议是用CP2102或FT232芯片的USB转串口模块接在Orin NX载板的USB-A口上另一端接PIX6C的TELEM2。Jetson Linux自带这些常见USB串口芯片的驱动插上就能看到/dev/ttyUSB0部分CDC设备显示为ttyACM0。接线和前面完全一样TX-RX交叉、RX-TX交叉、GND共地、VCC悬空。这个方案稳是因为它把“板级UART是否被复用”这个复杂问题从系统层面绕开了。USB协议栈由内核接管我们只需要关心USB转串口芯片到飞控这一小段TTL链路。对机载电脑来说少折腾一层板级配置就少一个故障点。5. 实测IMU数据读取把飞控的“身体姿态”从字节流里捞出来5.1 安装pymavlink先等一个心跳无论你用的是香橙派、Allspark1还是Orin NX只要串口节点能稳定读到字节流剩下就交给pymavlink。安装很简单pip install pymavlink下面这段代码我在机载电脑上跑过很多次作用是等待飞控心跳然后按类型轮询IMU消息from pymavlink import mavutil master mavutil.mavlink_connection(/dev/fcu, baud115200) print(等待飞控心跳...) master.wait_heartbeat(timeout10) if master.target_system 0: print(没有收到心跳检查接线/波特率/设备节点) else: print(f收到心跳 system{master.target_system} component{master.target_component}) while True: msg master.recv_match(type[RAW_IMU, SCALED_IMU2, ATTITUDE], blockingTrue) if not msg: continue t msg.get_type() if t RAW_IMU: print(fRAW_IMU acc: {msg.xacc} {msg.yacc} {msg.zacc} fgyr: {msg.xgyro} {msg.ygyro} {msg.zgyro} fmag: {msg.xmag} {msg.ymag} {msg.zmag}) elif t SCALED_IMU2: print(fSCALED_IMU2 acc: {msg.xacc} {msg.yacc} {msg.zacc} fgyr: {msg.xgyro} {msg.ygyro} {msg.zgyro}) elif t ATTITUDE: print(fATTITUDE roll{msg.roll:.3f} pitch{msg.pitch:.3f} yaw{msg.yaw:.3f})这条链路通说明你已经从串口通信进入飞行数据管道阶段。心跳信号是第一步IMU消息就是下一步。5.2 IMU消息字段意味着什么别只会打印RAW_IMU和SCALED_IMU都包含三轴加速度计、三轴陀螺仪、三轴磁力计区别在于原始值和标定后的值单位也不同。ATTITUDE则直接给你飞控解算后的欧拉角单位是弧度。如果你后续要做VIO、LIO或者IMU标定通常更关心RAW_IMU或者HIGHRES_IMU因为你需要高频原始测量然后自己处理偏置与噪声。如果只是验证通信链路ATTITUDE就够了。顺手可以验证一下数据频率。例如统计10秒内RAW_IMU的数量import time start time.time() count 0 while time.time() - start 10: msg master.recv_match(typeRAW_IMU, blockingTrue) count 1 print(fRAW_IMU rate: {count / 10:.1f} Hz)如果频率和飞控参数配置一致说明链路带宽、波特率、串口中断都处于健康状态。如果明显偏低多半是串口丢包或者USB转串口芯片不稳定。这个健康度检查比单纯“能打印数据”要重要得多。5.3 串口测出来没问题之后别急着挂算法我试过直接拿串口IMU数据喂给VINS-Fusion做初始化结果前几秒姿态就飘了。后来发现是两个问题叠加一是串口到算法的时间戳没对齐我拿到的是数据到达机载电脑的时刻不是飞控采样时刻二是USB转串口本身存在几毫秒到几十毫秒的抖动对视觉惯性里程计这种对时间戳敏感的系统影响非常大。正确做法是使用RAW_IMU消息里的time_usec字段把数据重新对齐到飞控时间基准。读到IMU只是第一步IMU数据的时间可信度才是决定你拿它做什么的关键。这也是为什么很多开源方案里会专门做时间同步而不是简单从串口读浮点数。5.4 一个更省事的备选直接订阅HIGHRES_IMU如果只是做平台自检不涉及精确时间同步直接订阅HIGHRES_IMUmessage id 105也很好。它的字段已经是浮点数单位是标准国际单位省去mG到m/s²、mrad/s到rad/s的人工换算。但消息体更大115200波特率下如果频率开得很高会挤占其他MAVLink消息的带宽。所以选择哪种IMU消息本质是在解析方便、时间精度、带宽占用三者之间做取舍。6. 三个平台都用得上的收尾经验接线顺序、排查顺序和长期部署改进6.1 我一直在用的“串口黄金排查顺序”从香橙派到Allspark1再到Orin NX绕了一大圈我发现真正麻烦的从来不是协议而是能不能按顺序排除掉物理层故障。我给自己定了一条排查链每次串口不通就按这个顺序走先做串口环回测试确认板子这端的串口软件链路没坏用万用表量一下飞控TELEM口TX/RX对GND的电压正常会在3.3V附近跳动接上飞控先看字节静态时应该能持续读到节奏均匀的乱码如果0字节优先交叉TX/RX如果乱码夹杂可读字符优先检查波特率确认字节流稳定后再上pymavlink、mavproxy等协议层工具。这个顺序能覆盖我见过的95%“串口不通”问题。很多朋友一上来就怀疑飞控参数、怀疑固件、怀疑电平其实先跑一遍这个排查链大多数人能省下一晚上。6.2 长期部署的三点建议长期在机载电脑上做无人机开发我不会再用散乱杜邦线。第一换成带屏蔽的短串口线或者在三根线上套磁环第二把飞控端和机载电脑端做成可插拔的JST-GH接口避免每次拆装重新认线序第三代码里统一用udev固定设备名比如/dev/fcu不让设备号漂移成为定时炸弹。还有一个容易被忽略的点如果机载电脑和飞控共用一个电池电源注意地环路。串口GND已经两边共地这时候如果USB转串口模块又从外部取电就可能形成地环路干扰。尽量让USB转串口模块由机载电脑USB口供电不要在别处再额外给它供一次电。6.3 数据层面最后想提醒的后面如果你继续做lidar-imu标定、camera-imu联合标定会发现串口IMU数据的质量和时间同步直接决定标定结果。串口通信本身不难难的是在复杂电磁环境和多任务并发时还能让IMU数据流稳定、低延迟、带准确时间戳。这也是我倾向于把IMU数据通道单独划开的原因——比如PIX6C的TELEM2只跑IMU和心跳TELEM1留给地面站遥控避免大包消息把IMU挤到一边。按这条思路部署完机载电脑与飞控之间的UART链路就是一块真正可信的地基上面再叠VIO、导航、控制这些算法我心里才有底。
返回列表