4. 航空软件SIL仿真平台选型与搭建
飞控软件的SIL(Software-in-the-Loop)仿真,是把经过编译的飞控应用代码与飞控模型、被控对象模型、传感器/执行机构模型一起放在宿主机上运行,用虚拟时间推进闭环,从而在没有真实硬件的情况下验证控制律、模式切换和故障逻辑。本节的目标不是罗列所有工具,而是完成一个“最小可用”的SIL环境:能编译、能集成、能跑通一个定高或姿态保持的闭环用例,并能看到可判读的结果。
一、主流SIL工具链的取舍
工程上常见的组合有三类。第一类是MATLAB/Simulink + Embedded Coder + Simulink Test:模型即环境,自动生成被测代码,适合控制律早期验证,但飞控软件的真实C代码往往需要额外封装成S-Function或通过FMU接入。第二类是开源栈,如PX4/ArduPilot的jMAVSim、Gazebo、FlightGear组合,飞控代码直接编译为原生可执行文件,通过MAVLink与仿真器交互,最接近真实软件形态,适合回归测试。第三类是商业工具链,如SCALEXIO、dSPACE VEOS、Vector CANoe的SIL选项,接口规范、可追溯性好,但成本高、依赖授权。
对于“最小可用搭建”,推荐以PX4 SITL + Gazebo(或jMAVSim)为骨架,因为它天然满足三个条件:飞控代码是真实C/C++工程、编译产物就是被测对象、接口(MAVLink/uORB)与实机一致。若团队已有Simulink资产,则用FMU把模型作为被控对象接入,飞控代码仍走原生编译,避免“模型里跑模型”导致的可信度下降。
二、模型编译与集成
以PX4为例,编译命令本身很简单,但“最小可用”的关键在于确认产物和启动脚本正确:
cd ~/PX4-Autopilot
make px4_sitl_default gazebo
# 或仅编译不启动仿真
make px4_sitl_default
编译完成后,build/px4_sitl_default/bin/px4 就是被测飞控可执行文件,etc/init.d-posix/rcS 决定启动时加载哪些模块。集成时要注意两点:一是控制律参数(如 MPC_XY_P、MPC_Z_P)应通过参数文件或 param set 注入,而不是硬编码,便于回归时批量替换;二是若用Simulink模型作为被控对象,应导出FMU并让仿真器加载,飞控侧仍通过MAVLink收发,避免把控制律也放进Simulink导致“测的不是真实代码”。
三、接口适配
SIL的接口适配核心是“消息映射”和“时间同步”。飞控内部用uORB传递 sensor_combined、vehicle_attitude、actuator_controls 等主题;仿真器需要的是物理量(角速度、加速度、位置、电机转速)。桥接模块 simulator_mavlink 负责把仿真器的 HIL_SENSOR、HIL_GPS 消息转成uORB,再把 actuator_controls 转成 HIL_ACTUATOR_CONTROLS 发回仿真器。若使用lockstep模式,仿真器每推进一步都等待飞控完成一次控制周期,保证时序一致;若用实时模式,则需关注仿真步长与飞控主循环周期的匹配,避免积分漂移。
接口适配中常见的坑是坐标系和单位:MAVLink的 HIL_SENSOR 使用NED(北-东-地)坐标系,加速度单位m/s²,角速度rad/s;而部分模型输出的是ENU或机体轴,必须在桥接层显式转换。建议在桥接代码中集中定义转换函数,并在日志中打印原始值与转换值,便于排障。
四、环境配置脚本
为了让环境可复现,应把依赖安装、编译、启动、参数注入写成脚本。下面是一个最小示例,假设已安装ROS 2和Gazebo:
#!/usr/bin/env bash
set -e
export PX4_HOME=$HOME/PX4-Autopilot
export GAZEBO_MODEL_PATH=$PX4_HOME/Tools/sitl_gazebo/models
# 1. 编译
cd $PX4_HOME
make px4_sitl_default
# 2. 启动仿真器(后台)
gazebo --verbose Tools/sitl_gazebo/worlds/iris.world &
GAZEBO_PID=$!
sleep 3
# 3. 启动飞控并加载参数
build/px4_sitl_default/bin/px4 -d \
-s etc/init.d-posix/rcS \
-p 4560 &
PX4_PID=$!
# 4. 注入回归参数
sleep 5
param set MPC_Z_P 1.2
param set MPC_Z_VEL_P 0.8
param set MPC_ALT_MODE 2
# 5. 运行用例(示例:起飞到2m并悬停)
mavsdk_takeoff --alt 2.0
sleep 20
# 6. 收尾
kill $PX4_PID $GAZEBO_PID
脚本中 -d 表示后台运行,-s 指定启动脚本,-p 4560 是MAVLink端口。参数注入放在飞控启动之后、用例执行之前,确保生效。若需要批量回归,可把参数和用例写成CSV,由脚本循环读取并替换。
五、最小可用验证
环境搭好后,用一个定高悬停用例验证闭环是否真正跑通。操作上:启动仿真,发送起飞指令到2 m,等待20 s,观察高度曲线。判读依据可以设为:上升时间小于5 s、超调不超过10%(即峰值不超过2.2 m)、稳态误差在±0.5 m以内、姿态角波动小于3°。若高度持续发散或模式自动切回手动,优先检查 actuator_controls 是否被仿真器接收、HIL_SENSOR 时间戳是否单调递增、以及参数是否被正确加载。日志用 ulog2csv 导出后,重点看 vehicle_local_position.z 和 vehicle_attitude 两条曲线。