# pod_bridge 移交树莓派 4B 部署注意事项 > 目标平台:树莓派 4B + **Ubuntu 24.04(aarch64)**。 > 范围:`utils/pod_bridge`(及其依赖的 `visual_track_control` 控制原语库)。 > 核对日期:2026-09-23,对照规格《光电吊舱控制协议G版-PB.docx》; > 依赖轮子已按 PyPI 2026-09-23 上游信息复核。 --- ## 1. 系统与 Python 版本(硬性) - **Ubuntu 24.04(aarch64)**:Ubuntu 的 Pi 镜像只有 64 位,天然满足 MAVSDK 对 aarch64 的要求(见 §3);不要自行改装任何 32 位系统。 - **Python 3.12**(Ubuntu 24.04 自带)满足 PEP 604 标注(`float | None` / `FrameParser | None`)要求的 ≥3.10,直接用,无需另装。 - Ubuntu 24.04 系统 Python 受 PEP 668 保护,**禁止 `pip install` 进系统环境** (报 externally-managed-environment),一律建 venv。注意 Ubuntu 默认 **不带 venv 支持**,先 apt 补齐: ```bash 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 且毫无意义: ```text # 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.12,要求 glibc≥2.17,Ubuntu 24.04 为 2.39 ✅)。 32 位 armv7l 支持不稳定——Ubuntu 24.04 Pi 镜像只有 64 位,无此问题。 - 安装后别只验证 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 时(**Ubuntu 没有 raspi-config**,手工配置): - `/boot/firmware/config.txt` 确认有 `enable_uart=1`;若控制台占着串口, 关掉:`sudo systemctl disable --now serial-getty@ttyAMA0.service`; - Pi 4B 上 GPIO UART 默认是 mini-UART(ttyS0,波特率随主频漂移),115200 下 不稳——同一文件加 `dtoverlay=disable-bt` 把 PL011(ttyAMA0)换回来 (设备树 overlay 由固件加载,与发行版无关,Ubuntu 同样生效); - **Ubuntu 没有 Raspberry Pi OS 的 `/dev/serial0` 软链**,设备名直接写 `/dev/ttyAMA0`(或 ttyS0); - **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 全绿。 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 示例) ```ini # /etc/systemd/system/pod-bridge.service [Unit] Description=Pod-PX4 Bridge After=network.target [Service] ExecStart=/home//venv-pod/bin/python -m pod_bridge_app WorkingDirectory=/home//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 单核占用可忽略,无需实时内核。