Files
code-test-drone/docs/树莓派4B部署注意事项.md
T
keita e179aa322a 部署文档目标系统回改为Raspberry Pi OS官方镜像
用户在Ubuntu镜像上遇串口问题换回官方镜像: §1改Bookworm(3.11)/Trixie(3.13)
口径, §3补libstdc++符号说明(GCC12+官方镜像均满足), §4恢复raspi-config与
/dev/serial0指引, §7注明单测已与原生库脱钩
2026-09-23 18:00:30 +08:00

7.4 KiB

pod_bridge 移交树莓派 4B 部署注意事项

目标平台:树莓派 4B + Raspberry Pi OS 官方镜像(64 位,Bookworm / Trixie)。 (2026-09-23 由 Ubuntu 24.04 换回官方镜像:Ubuntu 镜像上串口配置与 libstdc++ 符号问题频出,官方镜像对 Pi 串口/固件支持最完整。) 范围:utils/pod_bridge(及其依赖的 visual_track_control 控制原语库)。 核对日期:2026-09-23,对照规格《光电吊舱控制协议G版-PB.docx》; 依赖轮子已按 PyPI 2026-09-23 上游信息复核。


1. 系统与 Python 版本(硬性)

  • 必须烧录 64 位镜像(Raspberry Pi Imager 里选 "Raspberry Pi OS (64-bit)"), 理由见 §3 MAVSDK 对 aarch64 的要求;32 位镜像不要碰。

  • 烧完先确认:cat /etc/os-release。Bookworm 自带 Python 3.11、 Trixie 自带 Python 3.13,均满足 PEP 604 标注(float | None / FrameParser | None)要求的 ≥3.10,直接用。

  • Bookworm 起系统 Python 受 PEP 668 保护,禁止 pip install 进系统环境 (报 externally-managed-environment),一律建 venv;venv 支持若缺失先 apt 补:

    sudo apt update && sudo apt install -y python3-venv python3-pip
    python3 -m venv ~/venv-pod
    ~/venv-pod/bin/pip install -r requirements-pod.txt
    

2. 依赖裁剪(树莓派上别全装)

requirements.txt 是全仓库清单,吊舱桥接只需要其中两个,务必裁剪, 否则 torch/cv2 在 Pi 4B 上是几百 MB 且毫无意义:

# requirements-pod.txt(桥接最小集)
mavsdk
pyserial
pytest    # 仅上机自测需要,部署运行可省
  • pod_bridge 本身纯 Python + 惰性导入:pyserial 只在 PodSerial 实例化时加载, mavsdk 只在 Px4Gateway.connect / 指令发送时加载——单测全绿不需要任何硬件库。
  • 不要在 Pi 上装 ultralytics/torch/opencv:那是 stereo_yolo 检测链的依赖, Pi 4B 跑不动实时 YOLO,检测应留在机载算力更强的平台或吊舱内部。
  • 若确实要装 opencv,用 opencv-python-headless(无 GUI 依赖), 并 sudo apt install libopenblas-dev libatlas-base-dev。

3. MAVSDK 在 ARM 上的坑

  • pip 的 mavsdk 包内嵌 mavsdk_server 二进制;aarch64 有官方 wheel (PyPI 核对:mavsdk 4.0.0 提供 cp38-abi3 manylinux2014_aarch64, abi3 兼容 Python 3.11/3.13,要求 glibc≥2.17)。32 位 armv7l 支持不稳定—— 这是必须 64 位镜像的主因。
  • libstdc++ 符号:wheel 内嵌库要求 GCC≥12 的运行时符号;官方镜像 Bookworm(GCC 12)/ Trixie(GCC 14)均满足,此前 Ubuntu 镜像上出现的 undefined symbol: ..._M_futex_wait_until... 不应复现。若仍报: ldd <libcmavsdk.so 路径> | grep stdc 确认链接对象,必要时用 LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libstdc++.so.6 兜底。
  • 安装后别只验证 import,要让内嵌二进制真跑一次: find ~/venv-pod -name mavsdk_server 找到路径后直接执行(无参数即起服务, Ctrl+C 退出),能打印启动信息说明架构匹配;Exec format error 则装错了架构。
  • 连接串写法(pod_bridge.json 的 px4.connection_string):
    • Pi 串口直连飞控 TELEM:serial:///dev/ttyUSB0:57600(波特率按飞控侧设置);
    • 经数传/仿真:udp://:14540。
  • PX4 侧需确认 TELEM 口已配 MAVLink 且 offboard 心跳未被占用。

4. 串口硬件(吊舱侧,最容易翻车)

  • 协议为 115200 8N1 无校验(规格 §2.1)。先确认吊舱串口电平:
    • RS232 → 必须加电平转换或直接用 USB 转串口模块(FTDI/CH340,推荐, 免折腾 GPIO UART,设备号 /dev/ttyUSB0);
    • TTL 3.3V → 可用 Pi GPIO14/15(/dev/serial0)。
  • 用 GPIO UART 时(官方镜像自带 raspi-config):
    • sudo raspi-config → Interface Options → Serial Port:控制台选 No、 串口硬件选 Yes(等价于 enable_uart=1 + 关闭 serial-getty 抢占);
    • Pi 4B 上 /dev/serial0 默认指向 mini-UART(ttyS0,波特率随主频漂移), 115200 下不稳——在 /boot/firmware/config.txt 加 dtoverlay=disable-bt 把 PL011(ttyAMA0)换回来,/dev/serial0 随之改指 ttyAMA0;
    • Pi 是 3.3V 电平,绝不直连 5V/RS232 电平,会烧 GPIO。
  • 接线三线:TX/RX 交叉、必须共地(GND),不共地是通讯乱码的第一大原因。
  • 用户权限:sudo usermod -aG dialout $USER,重登录生效,否则 open 串口 Permission denied。

5. 时钟同步(规格表3 依赖)

  • bridge._build_attitude 用宿主机 UTC 墙钟填表3 的年月日时分秒; Pi 4B 无 RTC,断电后时间是错的,吊舱会拿到错误时间戳。
  • 上机后确认 timedatectl 显示 System clock synchronized: yes; 无网环境考虑给 Pi 加 RTC 模块,或由飞控 GPS 授时(需改代码,见 §8 已知问题)。

6. 配置文件(utils/config/pod_bridge.json)上机必改两处

字段 改成
pod_serial.port 实际设备号,如 /dev/ttyUSB0(留空会 fail-fast 报错,这是刻意的)
px4.connection_string 实际飞控连接,如 serial:///dev/ttyUSB1:57600
  • 引导参数(guidance.*)全部是占位值,未经标定不得用于飞行决策; 首次实机只验证通讯收发,速度上限先调小。
  • 配置加载拒绝未知键——改 JSON 时注意拼写,多写的键会直接报错(防呆设计)。

7. 上机验证顺序(每步过了再下一步)

  1. 纯软件自测(无需任何接线): cd utils && ~/venv-pod/bin/python -m pytest tests/pod_bridge -q → 应 92 全绿 (单测已打桩 mavsdk 设定点类型,与 libcmavsdk 原生库健康状态无关)。
  2. 串口回环:USB 转串口模块 TX/RX 短接,跑一个 feed/echo 小脚本验证字节收发。
  3. 只接吊舱:观察能否解析出 表2-2(60Hz EE 16)帧;用 send_control(归中 0x2B) 验证下行。
  4. 只接飞控:Px4Gateway.connect 后确认 own_state().position_valid 为 True。
  5. 全链路地面联试:电机不装桨,观察 offboard 心跳与引导输出。
  6. 最后才考虑带动力测试。

8. 已知问题处置状态(2026-09-23 更新)

代码审查(2026-09-22)发现 4 项,其中 3 项安全相关缺陷已于 2026-09-23 修复, 新增回归测试 8 条(pod_bridge 测试 84 → 92,全量 348 条全绿):

  1. Px4Gateway 四路遥测共用 OwnState.time_ms → 已修:OwnState 拆出 position_time_ms(仅 position 流刷新),引导的位置超龄判定改用它;
  2. 表2-2 锁定状态(bit2)未参与引导门控 → 已修:PodBridge._pod_locked 要求遥测在 link.telemetry_timeout_ms 内且 bit2=锁定,表4 坐标才视为有效 (该配置项由此从死配置变为生效配置);
  3. PodBridge.run 主循环无异常护栏 → 已修:单周期异常按「第 1 次 + 每满 100 次」告警并补发零速刹车保 offboard 心跳,任务不终止;
  4. 表3 时间戳用宿主机墙钟而非 GPS 时间(见 §5)——仍未修,属可接受风险, 如需精确授时按 §5 对策处理。

9. 常驻运行(systemd 示例)

# /etc/systemd/system/pod-bridge.service
[Unit]
Description=Pod-PX4 Bridge
After=network.target

[Service]
ExecStart=/home/<user>/venv-pod/bin/python -m pod_bridge_app
WorkingDirectory=/home/<user>/code_drone-test/utils
Restart=always
RestartSec=3
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
  • 热路径不打日志是设计使然(告警走 WarnThrottle),现场排查用 journalctl -u pod-bridge -f。
  • 代码热路径按 10Hz 引导 + 20Hz 姿态下发,Pi 4B 单核占用可忽略,无需实时内核。