资讯动态

基于 Renode 的 ArduPilot 物理飞行测试:CI 集成、场景原理与本地复现完整指南

发布时间:2026/9/14 8:09:08 来源:尧图企业网站定制
基于 Renode 的 ArduPilot 物理飞行测试CI 集成、场景原理与本地复现完整指南【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilotArduPilot 仓库通过 Renode 仿真器在 CI 中运行未修改的真实 ChibiOS 固件完成整架飞机的物理飞行任务其中 IMU、罗盘与气压计型号均按真实 CubeOrangePlus 硬件选配。本指南以 Tools/renode/tests/README.md 为主线逐条讲解测试的获取、运行、校验与调试手段并结合源码说明每条命令背后的实现机制帮助你在本地复现 CI 级别的仿真飞行验证。一、这套测试解决什么问题嵌入式飞控开发最痛苦的一环是改一行代码必须上真机验证而 Renode 飞行测试提供了一条折中路径把真实编译产物ArduPlane / ArduCopter 固件放进指令级仿真器运行再通过独立的物理引擎让它在虚拟世界里完成起飞、巡航、降落。它既保留了接近硬件的行为寄存器、DMA、外设时序又能跑在普通 Linux 服务器上因此可以作为 CI 的常驻回归手段。从仓库结构看测试基础设施集中在 Tools/renode/tests 目录下文件职责fetch_renode.sh下载并校验 Renode 运行时test_physics_flight.py三个物理飞行场景plane / copter / quadplanetest_mission.pyCubeOrange SITL-on-hardware 四航点任务test_physics_flight_helpers.py物理飞行公共工具函数test_mission_helpers.py任务测试公共工具函数其余test_*.py面向底层模块DFU、FAT 镜像、启动脚本、外设模型等的单元测试二、快速开始两条命令跑起来文档给出的标准入口在仓库根目录执行Tools/renode/tests/fetch_renode.sh Tools/renode/tests/test_physics_flight.py quadplane --renode build/renode/renode第一步把 Renode 可执行包下载到build/renode/第二步以quadplane场景执行物理飞行测试。此外 CI 还会跑整个 Python 测试目录python3 -m pytest -q Tools/renode/tests2.1 未提供 Renode 时的行为reset与 flash-model 类测试使用build/renode/renode或读取环境变量RENODE指定的可执行文件两者都不可用时这些测试会自动跳过skip不会报错中断。这一点在两个测试入口的 argparse 逻辑中也有体现test_physics_flight.py与test_mission.py都会在未显式传--renode时探测build/renode/renode是否存在存在才将其作为默认值。2.2 不在 CI 中、但本地可用的场景plane、copter两个物理场景以及 CubeOrange SITL-on-hardware 任务测试不在 CI 执行范围内但官方保留供本地使用Tools/renode/tests/test_physics_flight.py plane --renode build/renode/renode Tools/renode/tests/test_physics_flight.py copter --renode build/renode/renode Tools/renode/tests/test_mission.py三、Renode 与 SVD 数据获取机制含校验3.1 fetch_renode.sh按架构下载并三重校验fetch_renode.sh 从官方固件服务器RENODE_PACKAGE_BASE_URL默认指向https://firmware.ardupilot.org/Tools/Renode/下载当前主机架构的最新包。脚本内部逻辑如下平台限制仅支持 Linuxuname -s非 Linux 直接报错退出架构仅接受x86_64/amd64与aarch64/arm64分别对应renode-linux-x86_64与renode-linux-aarch64两个制品名清单校验先下载latest.json清单用内嵌 Python 脚本校验schema_version、制品目标architecture/platform/runtime_identifier、文件名合法性仅允许[A-Za-z0-9._-]\.tar\.gz、SHA-256 格式64 位十六进制与源码修订号格式40 位十六进制包校验下载后先比对stat --format%s的文件大小再用sha256sum --check校验校验和原子安装先解压到临时目录并确认存在可执行的renode才整体mv到目标目录目标已存在时直接报错退出避免覆盖。3.2 三个关键环境变量环境变量作用RENODE_PACKAGE_BASE_URL更换 Renode 包镜像源RENODE_SOURCE_REVISION要求特定的 40 位源码修订号不匹配即失败RENODE_PACKAGE_SHA256额外要求包校验和与受信任值一致CI 在 .github/workflows/test_renode.yml 中同时固定后两者- name: Fetch Renode env: RENODE_SOURCE_REVISION: 2a060779f4e2b87d1ae7238a041d858369818805 RENODE_PACKAGE_SHA256: 0f090820a222acbef7e80168c955feccf1759b69bc891b2ad821bacc19c4bcae run: Tools/renode/tests/fetch_renode.sh文档明确提醒更换 Renode 包时这两个值必须同步更新否则供应链校验会直接失败。3.3 run.py 的 SVD 下载与缓存测试运行的核心启动器是 Tools/renode/run.py。它每次运行时读取编译产物hwdef.dat中的精确 MCU 型号从RENODE_DATA_BASE_URL默认官方固件服务器的data/SVD/目录下载匹配的 SVD 文件校验大小与 SHA-256 后缓存到~/.cache/ardupilot/renode/data/SVD/默认目录。两个相关环境变量RENODE_DATA_CACHE更换缓存目录RENODE_DATA_BASE_URL更换 SVD 镜像源。SVDSystem View Description提供了外设寄存器布局描述是 Renode 精确建模 STM32 外设的基础数据因此它和 Renode 本体一样需要校验与缓存。四、物理飞行场景深入plane / copter / quadplanetest_physics_flight.py 的入口main()只接受三个场景名choices(plane, copter, quadplane)。下表汇总三者的配置差异均来自源码中的run_plane/run_copter/run_quadplane函数项目planecopterquadplaneCI 主场景板卡MatekH743KakuteF4CubeOrangePlus固件arduino plane./waf planearducopter./waf copterarduino plane./waf plane默认参数MatekH743-plane.parmKakuteF4-copter.parmCubeOrangePlus-quadplane.parm物理模型planebfxquadplane物理交换速率400 HzPHYSICS_RATE_HZ125 HzF405_PHYSICS_RATE_HZ400 Hz起始经纬高堪培拉 (-35.363261, 149.165230, 584.0, 353.0)同上同上外设u-blox GPSSERIAL3、IST8310 罗盘I2C1、MS4525 空速I2C1u-blox GPSSERIAL3、IST8310 罗盘I2C0三颗 IMUicm42688_ext/icm20948_ext/icm20649、u-blox GPSSERIAL2、MS4525 空速I2C14.1 运行时拓扑Renode 主进程 物理 sidecar每个场景都启动两个进程物理 sidecarbuild/sitl/tool/renode-physics由./waf configure --board sitl ./waf --targets tool/renode-physics构建带--physics-port与--model参数Renode 主进程由run.py启动通过--exec sysbus.physics Connect port model lat lon alt hdg rate把仿真器与 sidecar 连接起来。两者通过 localhost 上的锁步协议lockstep protocol交换带时间戳的执行器/传感器状态。源码中wait_for_sidecar()会轮询 sidecar 日志直到出现PHYSICS_PORT port标记确认监听就绪后才启动 Renode。4.2 传感器身份校验让仿真对齐真机quadplane 场景在起飞前会做一步关键校验——check_sensor_ids()通过 MAVLink 逐个读取INS_ACC_ID、INS_GYR_ID、COMPASS_DEV_ID、BARO1_DEVID等参数与真实 CubeOrangePlus 板卡采集到的 ID 逐一比对源码 test_physics_flight.py 中CUBEORANGEPLUS_SENSOR_IDS常量参数期望值对应真机传感器INS_ACC_ID / INS_GYR_ID3408930ICM42688SPI4 CS4INS_ACC2_ID / INS_GYR2_ID2883874ICM20948SPI4 CS1INS_ACC3_ID / INS_GYR3_ID3015690ICM20649SPI1 CS4COMPASS_DEV_ID590114ICM20948 内置 AK09916BARO1_DEVID721442MS5611SPI4 CS2BARO2_DEVID721674MS5611SPI1 CS3任何一项不匹配都会以sensor IDs differ from real hardware报错。这意味着仿真模型必须精确复现 SPI 总线、片选、设备类型编码等底层细节测试才可能通过。4.3 三个场景的飞行任务与判据planeMatekH743 固定翼TAKEOFF 模式爬升到相对高度 38 m → LOITER 模式绕圈累计 ≥350°用 VFR_HUD 航向增量累加判断→ AUTOLAND 模式着陆并自动解锁。着陆要求距 home ≤125 m、相对高度 ≤3 m、地速 ≤2 m/s。任务完成后从虚拟 SD 卡镜像state/sdcard.img用fat_image.extract_files()提取唯一的*.BIN日志再用 pymavlink 的DFReader_binary校验模式序列必须包含 TAKEOFF(13) → LOITER(12) → AUTOLAND(26) 子序列必须出现 3 个 IMU 实例每实例 ≥500 条记录且全程健康与 2 个气压计各 ≥100 条、≥20 个不同压力读数证明气压在动态变化空速健康且最大值 ≥20 m/s、结尾 ≤3 m/s最大高度 ≥38 m、离 home 最大距离 ≥50 m、最终相对高度 ±3 m 内姿态稳定|pitch| ≤35°、|roll| ≤70°日志无丢帧DSF 最大值 0、无 ERR/IREG 错误。copterKakuteF4 四旋翼上传四航点任务起飞 10 m 4 个航点 降落由common.mission_items()生成切 AUTO 后强制解锁FORCE_ARM_MAGIC 2989飞行。落回地面解锁后校验SYS_STATUS中 gyro/accel/mag/气压/GPS 传感器全程健康最大高度与最大距离均 ≥8 m着陆精度相对高度 ±1 m、距 home ≤3 m姿态稳定roll/pitch ≤35°。quadplaneCubeOrangePlusCI 主场景任务由quadplane_mission_items()生成——NAV_VTOL_TAKEOFF垂直起飞至 20 m随后 3 个航点(120,0,40)、(120,100,40)、(-300,60,25)再经一段长距离低空进场DO_LAND_START后NAV_VTOL_LAND垂直降落。通过EXTENDED_SYS_STATE的vtol_state与 STATUSTEXT 中的Transition started/Land descend started判断任务确实经历了多旋翼与固定翼两种飞行状态。判据最大高度 ≥28 m、最大距离 ≥100 m、最大空速 ≥11 m/s着陆精度±1 m 高、≤10 m 距离姿态上限 roll ≤60°、pitch ≤40°。五、SITL-on-hardware 任务测试test_mission.pytest_mission.py 走的是另一条构建链路——它用 Tools/scripts/sitl-on-hardware/sitl-on-hw.py 构建 CubeOrange 的 SITL-on-hardware Copter 固件--frame quad默认参数 CubeOrange.parm随后通过 MAVLink 连接tcp:127.0.0.1:port校验POWER_STATUSVcc 必须在 4900–5100 mV 之间且只带MAV_POWER_STATUS_USB_CONNECTED标志验证仿真电源建模设置AUTO_OPTIONS3、上传 4 航点任务、切 AUTO、强制解锁等待起飞、巡航、降落并自动解锁通过MAV_CMD_LOG_REQUEST_LIST/LOG_REQUEST_DATA走 MAVLink 协议下载 DataFlash 日志为flight.BIN用DFReader校验日志POS 记录 ≥50 条、包含 AUTO 模式、最大高度/距离 ≥8 m、最终相对高度 ±1 m、无丢帧DSF 最大值 0。默认超时 300 秒--timeout所有状态、Renode 输出与下载的flight.BIN保留在build/renode-test/下。该测试同样复用run.py并设置XDG_CONFIG_HOME与TMPDIR指向 state 目录把仿真产生的临时文件隔离在测试产物目录内。六、开发期调试复用构建与自定义固件6.1 复用已有构建--skip-build物理飞行测试每次默认会重新构建固件与物理 sidecar。开发迭代时可用--skip-build跳过构建直接复用build/board/bin/下已有的产物Tools/renode/tests/test_physics_flight.py quadplane --interactive --skip-build6.2 直接喂固件--firmware--firmware接受APJ、BIN、HEX、ELF四种格式源码中FIRMWARE_SUFFIXES。提供固件后会跳过板卡固件构建但仍会构建物理 sidecar除非同时使用--skip-build。从源码看main()会在解析时校验文件存在与后缀合法性。6.3 交互模式--interactiveTools/renode/tests/test_physics_flight.py quadplane --interactive --skip-build该模式不执行任务校验而是把 Renode 与物理 sidecar 保持运行供地面站GCS人工接管。命令会打印 MAVLink TCP 端点MAVLink: tcp:127.0.0.1:port以实时速度paced运行——对比之下自动化模式会附加--unthrottled让仿真尽可能快保持进程存活直到按下 Ctrl-C源码中wait_interactive()循环监听 KeyboardInterrupt。6.4 导出 USB 设备--usb--usb会把仿真飞控的 USB 控制器通过 USB/IP 导出到 Linux VHCI 控制器。首次使用需一次性安装 udev 规则sudo Tools/renode/usbip_attach.py --install-rules测试内部通过 Tools/renode/usbip_attach.py 以--port 3240启动辅助进程附着状态记录在测试产物目录的usbip.log中源码start_usb_helper()。这允许你在宿主机上以真实 USB 设备的方式枚举、上传固件、验证 USB 重枚举行为。6.5 GDB 调试--gdb--gdb会打开一个运行 GDB 的 xterm固件停在 reset 处直到在 GDB 里输入continue才继续执行。两个要点必须使用 ELF 固件APJ、BIN、HEX 镜像不含调试器需要的 ELF 符号main()中会显式校验--gdb与 ELF 的组合非 ELF 直接报错由 harness 构建固件时--gdb会自动给 waf configure 加上-g参数而使用--skip-build时所选 ELF 必须已经包含调试符号。七、测试产物与常见问题排查7.1 产物目录结构所有测试默认输出到build/renode-test/下按场景与时间戳命名的子目录如CubeOrangePlus-quadplane-20260913-...包含文件/目录内容renode.logRenode 进程输出physics.log物理 sidecar 输出flight.BIN从虚拟 SD 卡 / MAVLink 下载的 DataFlash 日志flight.tlogCopter / QuadPlane 场景的 MAVLink 遥测记录usbip.logUSB/IP 附着状态使用--usb时state/仿真状态目录虚拟 flash、SD 卡镜像、XDG 配置等--output-dir可指定自定义目录且要求目标目录不存在防止覆盖历史结果。7.2 常见失败信号sensor IDs differ from real hardware仿真外设模型与真机传感器身份不一致检查 hwdef 的传感器声明与--imu选择timed out waiting for ...默认 600 秒超时CI 中 quadplane 场景用--timeout 900不足以完成任务或仿真卡死——排查时先看renode.log尾部Renode stopped with status N/physics sidecar stopped with status N任一子进程异常退出都会导致测试失败日志尾部各 100 行会附加在异常信息中expected one DataFlash log, found Nplane 场景要求 SD 卡中恰好一份日志。7.3 供应链与一致性提醒文档最后强调了两个易错点一是RENODE_SOURCE_REVISION与RENODE_PACKAGE_SHA256必须与 Renode 包同步更新CI 中两者在 .github/workflows/test_renode.yml 显式固定二是测试行为依赖build/renode/renode或RENODE本地复现请先执行fetch_renode.sh确保版本与 CI 一致。八、总结从 CI 到本地的工作流综合文档与源码这套测试体系的完整工作流可以归纳为准备环境fetch_renode.sh或自行指定RENODE/RENODE_PACKAGE_BASE_URL镜像单元级回归python3 -m pytest -q Tools/renode/tests覆盖 DFU、FAT 镜像、启动脚本、数据获取等基础模块物理级回归test_physics_flight.py quadplane复现 CI 的 CubeOrangePlus 垂直起降固定翼巡航垂直降落全流程含传感器身份校验与飞行日志校验任务级回归test_mission.py验证 SITL-on-hardware 构建链路上的航点任务与 MAVLink 日志下载调试--interactive 地面站、--usb 真实 USB 枚举、--gdb ELF 符号级断点覆盖从自动化回归到人工诊断的全过程。通过把真实固件、精确外设模型与独立物理引擎三者缝合在一起这套测试让飞行质量回归在 CI 中成为日常动作也为本地开发提供了一个无需硬件的可信验证环境。【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价