1. Ardupilot多机SITL仿真概述
作为一名无人机开发者,我经常需要在仿真环境中测试多机协同飞行。Ardupilot的SITL(Software In The Loop)仿真功能非常强大,但配置多机仿真时却遇到了不少坑。经过多次尝试,我终于找到了稳定可靠的多机仿真方案。
多机仿真的核心在于为每架无人机分配独立的通信端口和系统ID。这就像给每个学生分配不同的学号和座位,避免点名时出现混乱。在Ardupilot中,我们需要通过端口隔离确保每架无人机的数据不会互相干扰。
2. 常见错误与排查
2.1 插件调用方式错误
最初我按照网上教程修改iris_runway.sdf文件,直接替换无人机加载代码:
xml复制<plugin name="ardupilot_plugin_1" filename="libArduPilotPlugin.so">
<fdm_addr>127.0.0.1</fdm_addr>
<fdm_port_in>9002</fdm_port_in>
<fdm_port_out>9003</fdm_port_out>
<mavlink_port>5760</mavlink_port>
<model_name>iris_1</model_name>
<sysid>1</sysid>
</plugin>
这种配置在Gazebo 8.10.0版本会导致第二个无人机无法连接,因为插件调用方式已经更新。错误表现为:
code复制Waiting for heartbeat from tcp:127.0.0.1:5770
MAV> link 1 down
关键发现:不同版本的Gazebo对插件调用语法有差异,直接复制旧教程代码往往不适用。
2.2 端口冲突分析
多机仿真失败的主要原因包括:
- 端口号重复使用(如两个实例都尝试绑定5760端口)
- 系统ID未正确设置
- 模型名称冲突
- 插件版本不兼容
通过netstat -tulnp命令可以检查端口占用情况,这是排查连接问题的第一步。
3. 正确配置步骤详解
3.1 创建独立无人机模型
- 复制原始模型文件:
bash复制cp -r ~/ardupilot_gazebo/models/iris_with_gimbal ~/ardupilot_gazebo/models/iris_with_gimbal_2
- 修改模型配置文件:
xml复制<!-- ~/ardupilot_gazebo/models/iris_with_gimbal_2/model.sdf -->
<model name="iris_with_gimbal_2">
...
<plugin filename="gz-sim-user-ardupilot-system" name="gz::sim::systems::ArduPilotPlugin">
<fdm_port_in>9012</fdm_port_in>
<fdm_port_out>9013</fdm_port_out>
</plugin>
</model>
3.2 场景文件配置
创建multi_iris_runway.sdf:
xml复制<include>
<uri>model://iris_with_gimbal</uri>
<name>iris_1</name>
<pose>0 0 0.195 0 0 1.57</pose>
</include>
<include>
<uri>model://iris_with_gimbal_2</uri>
<name>iris_2</name>
<pose>3 0 0.195 0 0 1.57</pose>
</include>
注意:pose中的角度单位为弧度,90度=1.57弧度。位置坐标(x,y,z)单位为米。
3.3 启动仿真环境
- 启动Gazebo仿真:
bash复制gz sim -v4 -r multi_iris_runway.sdf
- 在两个终端分别启动SITL实例:
bash复制# 终端1
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON -I 0 --sysid 1 --console --map --out=127.0.0.1:14550
# 终端2
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON -I 1 --sysid 2 --console --map --out=127.0.0.1:14560
参数说明:
-I:实例索引号--sysid:MAVLink系统ID--out:设置MAVLink输出端口
4. 地面站连接配置
4.1 QGroundControl设置
- 主连接自动使用14550端口
- 添加次级连接:
- 协议:UDP
- 端口:14560
4.2 连接验证
成功连接后,QGC会显示两架无人机:
- 载具1(系统ID 1)
- 载具2(系统ID 2)
可以通过下拉菜单切换控制的无人机。
5. 高级配置技巧
5.1 参数文件分离
为每架无人机创建独立的参数文件:
bash复制# 生成初始参数文件
sim_vehicle.py -v ArduCopter --model JSON -I 0 --sysid 1 --console --map --out=127.0.0.1:14550 --add-param-file=vehicle1.param
5.2 自动化脚本
创建启动脚本start_sim.sh:
bash复制#!/bin/bash
# 启动Gazebo
gz sim -v4 -r multi_iris_runway.sdf &
# 启动SITL实例
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON -I 0 --sysid 1 --console --map --out=127.0.0.1:14550 &
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON -I 1 --sysid 2 --console --map --out=127.0.0.1:14560 &
5.3 网络延迟模拟
测试网络延迟对编队的影响:
bash复制# 添加100ms延迟和1%丢包
sudo tc qdisc add dev lo root netem delay 100ms loss 1%
6. 常见问题解决
6.1 连接超时问题
症状:Waiting for heartbeat长时间无响应
解决方案:
- 检查Gazebo是否正常加载模型
- 确认端口未被其他程序占用
- 验证模型文件中的插件配置
6.2 控制信号混乱
症状:操作一架无人机时另一架也有反应
原因:系统ID设置重复
解决方法:
- 确保每个
--sysid参数唯一 - 检查地面站连接配置
6.3 位置漂移问题
症状:无人机在仿真中不稳定
调试方法:
- 检查IMU和GPS数据
- 调整仿真频率参数
- 验证物理引擎设置
7. 性能优化建议
- 降低图形质量提升性能:
bash复制gz sim -v4 -r multi_iris_runway.sdf --render-engine ogre2
- 使用无头模式:
bash复制gz sim -v4 -r -s multi_iris_runway.sdf
- 调整仿真速度:
bash复制gz sim -v4 -r --iterations 1 multi_iris_runway.sdf
经过多次实践,我发现最稳定的配置是为每架无人机创建完全独立的模型文件。虽然初期设置稍复杂,但能避免后期各种奇怪的兼容性问题。在团队协作时,建议将完整的仿真环境打包成Docker镜像,确保所有成员使用完全一致的配置。