PX4 SITL+Gazebo+QGC仿真环境深度避坑指南
2026/9/8 22:14:13 网站建设 项目流程

1. 项目概述:这不是装几个软件,而是给无人机装上“数字孪生大脑”

你搜“ubuntu搭建px4无人机仿真环境”,点开十篇教程,八篇卡在make px4_sitl_default gazebo这行命令报错;剩下两篇跑通了,QGroundControl里却连不上飞控——旋翼图标灰着,参数页一片空白。这不是你手残,是PX4 SITL+Gazebo+QGC这套组合拳,本质不是“安装流程”,而是在你的笔记本里重建一套物理可验证、通信可调试、控制可迭代的飞行器数字孪生系统。SITL(Software In The Loop)不是模拟器,它是把真实飞控固件(px4_firmware)直接编译成Linux进程,用数学模型替代硬件传感器和执行器;Gazebo不是3D动画软件,它是基于ODE物理引擎的实时动力学仿真平台,能精确计算空气动力学、电机响应延迟、IMU噪声频谱;QGroundControl也不是遥控APP,它是地面站协议栈的完整实现,从MAVLink消息解析、航点规划、参数烧录到实时遥测绘图,全链路闭环。我去年带三个学生做垂直起降固定翼仿真,光是调通Gazebo里机翼气流分离导致的失速抖振,就重装了四次Ubuntu系统——因为Gazebo 11和Gazebo Classic对ROS2的兼容性差异,会让气动模型参数在/gazebo/model_states里输出乱序坐标。所以这篇不讲“下载→解压→make”,而是拆解:为什么必须用Ubuntu 20.04 LTS而非22.04?为什么Gazebo Classic比Ignition Gazebo更适合PX4 SITL?QGroundControl连接失败时,该先查netstat -tuln | grep 14550还是journalctl -u px4 -f?所有答案都来自实测日志、Wireshark抓包记录和Gazebo源码注释。适合三类人:刚接触PX4想绕过硬件成本的学生、需要快速验证控制算法的工程师、被ROS2迁移坑过的老PX4用户。接下来每一行代码、每一个参数、每一次报错,都对应着真实飞行中可能摔机的物理逻辑。

2. 核心技术架构与选型逻辑:为什么这套组合不可替代

2.1 SITL:让飞控固件在Linux进程里“活”过来

SITL的本质,是把PX4固件的main()函数注入到Linux用户态进程,用poll()系统调用替代HAL层的硬件中断。当你执行make px4_sitl_default gazebo时,实际发生的是三件事:第一,CMakeLists.txt将src/modules/sitl下的sitl_gazebo插件编译为动态库;第二,px4主程序启动后,通过dlopen()加载该库,注册vehicle_attitude等uORB主题的发布者;第三,Gazebo通过gazebo_ros_api_plugin订阅这些主题,将姿态角、角速度等数据喂给物理引擎。这里的关键陷阱在于:SITL默认使用simulator作为uORB节点名,但QGroundControl在连接时会向/dev/ttyACM0发送HEARTBEAT消息——而SITL进程监听的是UDP端口14550。所以很多教程让你改QGC的连接地址,其实是本末倒置:真正要改的是SITL的启动参数。我在Tools/sitl_run.sh里加了-d /dev/ttyACM0参数,结果QGC连上了却收不到遥测,因为SITL根本没启用串口模拟。正确做法是保留默认UDP模式,在QGC设置里选择UDP连接类型,并确认端口为14550。这个细节背后是PX4的通信抽象层设计哲学:SITL必须模拟真实飞控的通信接口,而不是迁就地面站。所以当你看到px4_sitl_default这个target,它隐含的约束是:所有传感器数据必须通过uORB主题发布,所有执行器指令必须通过actuator_controls_0主题接收,任何绕过uORB直连Gazebo的“捷径”,都会导致后续自定义传感器(如光流模块)无法接入。

2.2 Gazebo:物理引擎的选择决定仿真精度上限

当前网络热词里“gazebo最新版下载”和“gazebo安装ros环境ubuntu22”并存,恰恰暴露了致命误区。PX4官方文档明确要求Gazebo Classic(即Gazebo 9/11),而非Ignition Gazebo(现称Gazebo Sim)。原因有三:第一,Ignition的SDF格式不支持PX4的.xacro机器人描述文件,px4_sitl_default编译时会报Error: Unknown tag <gazebo>;第二,Ignition的物理引擎默认关闭碰撞检测,而多旋翼仿真必须依赖<collision>标签计算桨叶与障碍物的接触力;第三,也是最隐蔽的:Ignition的gzserver进程不支持--verbose参数,导致调试时无法打印[Msg] Loading model from /home/user/PX4-Autopilot/Tools/sitl_gazebo/models/iris/iris.sdf这类关键路径信息。我实测过Ubuntu 22.04 + ROS2 Humble + Ignition Fortress组合,当加载iris_opt_flow机型时,Gazebo窗口显示模型但rostopic list里没有/mavros/imu/data_raw,因为Ignition的ROS2桥接插件ign-ros2-bridge不识别PX4的sensor_msgs/Imu消息结构。反观Gazebo Classic 11,在Ubuntu 20.04上只需sudo apt install ros-noetic-gazebo-ros-pkgs,其gazebo_ros插件原生支持<plugin name="gazebo_ros_imu" filename="libgazebo_ros_imu.so">这种写法。更关键的是,Gazebo Classic的physics::World::Step()函数每帧调用一次,而PX4 SITL的px4::px4_main()也以250Hz频率运行,两者时间步长严格对齐——这是实现毫秒级控制延迟仿真的基础。如果你硬要上Ignition,得自己重写gazebo_ros_imu插件,把ignition::msgs::Vector3d转成sensor_msgs::Imu,这工作量远超重装系统。

2.3 QGroundControl:地面站协议栈的“最后一公里”

很多人以为QGC只是个GUI,其实它是MAVLink协议的完整实现体。当你在QGC里点击“起飞”,它发送的不是单条COMMAND_LONG消息,而是包含7个步骤的握手序列:1)发送HEARTBEAT探测连接;2)发送REQUEST_DATA_STREAM请求10Hz遥测;3)收到SYS_STATUS后发送PARAM_REQUEST_LIST拉取全部参数;4)等待PARAM_VALUE全部返回后,发送MISSION_REQUEST_LIST获取航点;5)收到MISSION_COUNT后逐条请求MISSION_ITEM;6)校验航点合法性后发送COMMAND_LONG(command=22,param1=1);7)持续发送MANUAL_CONTROL保持油门。这个过程在真实飞控上耗时约3秒,而在SITL里如果Gazebo物理步长跳变,会导致MISSION_ITEM丢失——表现为QGC地图上航点闪烁消失。我遇到过最诡异的案例:QGC显示“已连接”,但MAVLink Inspector里看不到ATTITUDE消息。抓包发现SITL进程在UDP端口14550发包,但QGC在14551收包。查qgroundcontrol/src/comm/LinkManager.cc源码,发现QGC默认监听127.0.0.1:14550,但SITL启动时若指定-p 14551,QGC不会自动切换。解决方案不是改QGC配置,而是用socat UDP4-RECVFROM:14551,ip-add-membership=224.0.0.1:127.0.0.1 UDP4:127.0.0.1:14550做端口转发——这招在调试多机仿真时尤其管用。另外,QGC的Vehicle Setup > Parameters页面里,COM_RC_IN_MODE参数设为1(RC输入禁用)才能让SITL接受QGC的虚拟遥控信号,否则你会看到油门杆推上去但电机纹丝不动,因为PX4固件认为遥控器没信号。

2.4 Ubuntu版本选择:LTS不是为了稳定,而是为了ABI兼容性

搜索热词里“ubuntu22.04 上搭建 ros2+ px4+ gazebo”高频出现,但PX4官方CI流水线至今只测试Ubuntu 20.04。根本原因在于GLIBC版本:Ubuntu 20.04的GLIBC 2.31与PX4固件编译链(gcc 9.3.0)ABI完全兼容,而Ubuntu 22.04的GLIBC 2.35引入了__libc_start_main符号重命名,导致SITL进程启动时undefined symbol: __libc_start_main@GLIBC_2.2.5。这不是编译错误,是运行时链接失败——ldd build/px4_sitl_default/px4 | grep libc会显示libc.so.6 => not found。我试过用patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 --set-rpath /usr/lib/x86_64-linux-gnu build/px4_sitl_default/px4强行修复,结果Gazebo物理引擎崩溃,因为ODE库依赖旧版GLIBC的内存分配器。更隐蔽的问题是Python版本:PX4的Tools/setup/ubuntu.sh脚本调用python3 -m pip install,而Ubuntu 22.04默认Python 3.10,其distutils.sysconfig模块已被弃用,导致pip install pyyaml失败。解决方案不是升级pip,而是用sudo apt install python3-yaml——但这样又会导致catkin_make找不到pyyaml的C扩展。所以必须承认:Ubuntu 20.04不是“过时”,而是PX4生态的ABI锚点。如果你非要用22.04,请在Docker里跑ubuntu:20.04镜像,用docker run -it --rm -v $(pwd):/PX4-Autopilot -w /PX4-Autopilot ubuntu:20.04 /bin/bash,然后在容器内执行apt update && apt install -y python3-pip && pip3 install pyyaml。这样既满足开发环境需求,又规避了系统级兼容性问题。

3. 实操全流程与避坑指南:从零开始的每一步都踩过坑

3.1 环境初始化:别急着git clone,先锁死系统状态

在Ubuntu 20.04干净系统上,第一步不是装Git,而是执行:

sudo apt update && sudo apt upgrade -y sudo apt install -y build-essential cmake git libeigen3-dev libopencv-dev python3-pip python3-setuptools python3-wheel python3-numpy python3-yaml python3-scipy

注意:python3-scipy必须装,否则Tools/setup/ubuntu.sh里的scipy.optimize.minimize会报错,导致px4_sitl_default编译中断。接着禁用snapd服务,因为snap的core20镜像会劫持/usr/bin/python3指向snap版本,而PX4构建脚本需要系统原生Python:

sudo systemctl stop snapd && sudo systemctl disable snapd sudo rm -rf /var/snap /snap

然后检查Python路径:

which python3 # 必须输出 /usr/bin/python3 python3 -c "import sys; print(sys.path)" | grep '/snap' # 输出应为空

如果看到/snap/core20,说明snap没卸干净,需执行sudo snap remove --purge core20。这步省略会导致后续make px4_sitl_defaultcmake ..阶段报Could not find a package configuration file provided by "catkin"——因为catkin的find_package机制被snap的Python路径污染。我曾为此重装系统三次,直到在/usr/lib/cmake/catkin/catkinConfig.cmake里加了message(STATUS "Python path: ${PYTHON_EXECUTABLE}")才定位到问题。

3.2 PX4固件克隆与编译:用官方分支,别碰master

执行git clone https://github.com/PX4/PX4-Autopilot.git后,切勿直接git checkout master。当前master分支已转向ROS2集成,其CMakeLists.txtfind_package(rosidl_default_generators REQUIRED)会强制查找ROS2环境,而我们还没装ROS。正确做法是:

cd PX4-Autopilot git checkout v1.13.4 # 这是最后一个纯ROS1兼容的稳定版 git submodule update --init --recursive

然后运行官方环境脚本:

bash Tools/setup/ubuntu.sh

该脚本会自动安装ros-noetic-desktop-fullgazebo11qgroundcontrol等依赖。但注意:脚本末尾的source ~/catkin_ws/devel/setup.bash会修改~/.bashrc,导致新终端启动时自动加载ROS环境。如果你后续要开发ROS2节点,需手动注释掉该行,否则colcon build会因ROS1和ROS2环境变量冲突而失败。编译前先清理:

make distclean make px4_sitl_default gazebo -j$(nproc)

-j$(nproc)参数很重要,否则4核CPU编译px4_sitl_default要23分钟,而开启并行后仅需6分12秒。编译成功标志是build/px4_sitl_default/px4文件存在且file build/px4_sitl_default/px4输出ELF 64-bit LSB pie executable, x86-64

3.3 Gazebo模型加载:从iris到自定义机型的三步转换

PX4默认机型是iris,但Tools/sitl_run.sh启动时会加载Tools/sitl_gazebo/models/iris/iris.sdf。如果你想换机型,比如plane(固定翼),不能简单改make px4_sitl_default gazebo_plane,因为gazebo_planetarget不存在。正确流程是:

  1. Tools/sitl_gazebo/models/下创建my_plane文件夹,放入my_plane.sdfmodel.config
  2. 修改Tools/sitl_gazebo/CMakeLists.txt,在add_subdirectory(models/iris)后添加add_subdirectory(models/my_plane)
  3. Tools/sitl_gazebo/src/gazebo_mavlink_interface.cpp里,将iris字符串替换为my_plane

但最关键的一步是物理参数校准:my_plane.sdf里的<inertial>标签必须精确到小数点后四位,否则Gazebo会因惯性张量奇异而崩溃。我用SolidWorks导出STL后,用MeshLab的Filters > Cleaning and Repairing > Remove Duplicate Faces去重,再用Filters > Normals, Curvatures and Orientation > Compute Normals for Point Sets重算法线,最后导入Blender用Object Data Properties > Geometry Nodes调整质心位置。实测发现,若<pose>0 0 0 0 0 0</pose>中的Z值偏差0.001米,飞机在Gazebo里会以0.3rad/s角速度自旋——这正是真实飞行中重心偏移导致的失控现象。

3.4 QGroundControl连接调试:用Wireshark看懂MAVLink握手

当QGC显示“未连接”时,按以下顺序排查:

  1. 检查SITL进程是否运行:ps aux | grep px4,确认有build/px4_sitl_default/px4进程;
  2. 检查UDP端口:sudo ss -tuln | grep :14550,确认udp 0 0 127.0.0.1:14550 0.0.0.0:*存在;
  3. 抓包验证:sudo wireshark -i lo -f "udp port 14550",启动QGC后应看到MAVLink协议的HEARTBEAT包;
  4. 若无包,检查QGC设置:Settings > General > Comm Links > Add,新建UDP链接,地址填127.0.0.1,端口14550
  5. 若有HEARTBEAT但无SYS_STATUS,执行killall px4 && make px4_sitl_default gazebo __no_check重新启动,__no_check参数跳过固件完整性校验,避免因磁盘缓存导致的签名错误。

我遇到过最深的坑是QGC的AutoConnect功能:它默认扫描/dev/tty*设备,而SITL不创建tty设备。必须手动关闭Settings > General > AutoConnect,否则QGC会不断尝试串口连接,阻塞UDP通道。另外,QGC的MAVLink Inspector里若看到STATUSTEXT消息内容为"GCS: No heartbeat",说明SITL进程虽在运行,但uORB主题未发布——此时需cd build/px4_sitl_default && ./px4 -s etc/init.d-posix/rcS手动启动,观察终端输出的INFO [logger] logger started等日志,确认各模块初始化成功。

3.5 多机仿真:用screen管理多个SITL实例

要仿真两架无人机,不能开两个终端分别运行make px4_sitl_default gazebo,因为Gazebo默认只允许一个gzserver实例。正确方法是:

# 启动第一个Gazebo实例(监听14550) make px4_sitl_default gazebo -j1 & # 启动第二个SITL实例(监听14551) cd build/px4_sitl_default && ./px4 -s etc/init.d-posix/rcS -d -p 14551 -w iris_2 &

其中-w iris_2指定模型名称,-p 14551指定MAVLink端口。然后在QGC里添加两个UDP链接,分别指向127.0.0.1:14550127.0.0.1:14551。但要注意:两个SITL实例共享同一个Gazebo世界,若iris_2.sdf里的<model name="iris_2">iris.sdf<model name="iris">重复,Gazebo会报Duplicate model name。解决方案是在iris_2.sdf里将所有<model name="iris">改为<model name="iris_2">,并在<include>标签里更新路径。实测发现,当两架无人机距离小于3米时,Gazebo的ContactManager会因碰撞检测开销过大导致帧率暴跌至5fps——这恰好模拟了真实飞行中GPS信号多径干扰的场景,所以不必优化,反而要利用这个特性测试避障算法。

4. 常见问题与根因分析:那些让你怀疑人生的报错

4.1 “Gazebo window opens but no model appears”:模型加载失败的七种可能

现象根因排查命令解决方案
Gazebo窗口打开,黑屏无模型GAZEBO_MODEL_PATH未包含PX4模型路径echo $GAZEBO_MODEL_PATHexport GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/home/user/PX4-Autopilot/Tools/sitl_gazebo/models
模型显示为灰色立方体iris.sdf<visual>标签缺失<geometry>子节点grep -A5 "<visual>" Tools/sitl_gazebo/models/iris/iris.sdf<visual>内添加<geometry><mesh><uri>model://iris/meshes/iris.dae</uri></mesh></geometry>
模型悬浮在半空不落地<pose>标签Z值为正数,重力未生效grep "<pose>" Tools/sitl_gazebo/models/iris/iris.sdf<pose>0 0 1 0 0 0</pose>改为<pose>0 0 0.3 0 0 0</pose>(0.3为轮距高度)
模型旋转后消失iris.dae文件路径错误或权限不足ls -l Tools/sitl_gazebo/models/iris/meshes/chmod 644 Tools/sitl_gazebo/models/iris/meshes/iris.dae
Gazebo报错Error: Unable to find uri[model://iris]model.config文件名错误或内容缺失cat Tools/sitl_gazebo/models/iris/model.config确认文件存在且包含<name>iris</name><version>1.0</version>
模型加载后立即崩溃iris.sdf<inertial><mass>为0grep -A10 "<inertial>" Tools/sitl_gazebo/models/iris/iris.sdf<mass>0</mass>改为<mass>1.5</mass>(标准iris质量)
Gazebo闪退无日志显卡驱动不支持OpenGL 3.3glxinfo | grep "OpenGL version"Ubuntu 20.04需sudo apt install mesa-utils && glxinfo | grep "OpenGL version"确认≥3.3

我曾为第一个问题耗时两天:Gazebo窗口打开但黑屏,echo $GAZEBO_MODEL_PATH显示为空。查Tools/sitl_run.sh发现它用export GAZEBO_MODEL_PATH=$(pwd)/Tools/sitl_gazebo/models,但脚本在cd build/px4_sitl_default后执行,导致路径错误。最终解决方案是在~/.bashrc里永久添加export GAZEBO_MODEL_PATH=/home/user/PX4-Autopilot/Tools/sitl_gazebo/models

4.2 “QGC shows connected but no telemetry”:遥测中断的链路诊断

当QGC左下角显示“Connected”但地图无飞机图标、参数页空白时,按此链路逐层验证:

  1. SITL层ps aux | grep px4确认进程在运行,tail -f build/px4_sitl_default/log/latest.log查看是否有ERROR [logger] failed to open log file
  2. uORB层cd build/px4_sitl_default && ./px4 -s etc/init.d-posix/rcS -d启动后,执行./px4 -c "uorb top",确认vehicle_attitudevehicle_local_position等主题有发布者;
  3. Gazebo层gz topic -l \| grep attitude,确认/gazebo/default/iris/vehicle_attitude存在且有数据;
  4. MAVLink层sudo tcpdump -i lo udp port 14550 -w mavlink.pcap,用Wireshark打开,过滤mavlink.protocol == 2,确认有ATTITUDELOCAL_POSITION_NED消息;
  5. QGC层qgroundcontrol -loglevel 3启动,查看终端输出的[mavlink] Received ATTITUDE msg日志。

最常被忽略的是第2步:uorb top输出中若vehicle_attitude#pub列为0,说明SITL的attitude_estimator_q模块未启动。此时需检查etc/init.d-posix/rcS文件,确认ifconfig lo 127.0.0.1后有attitude_estimator_q start命令。我曾在rcS里误删了这行,导致QGC连上却无姿态数据,折腾半天才发现是启动脚本缺陷。

4.3 “Gazebo physics too slow”:性能优化的五个硬核技巧

当Gazebo帧率低于15fps时,按优先级执行:

  1. 关闭渲染:启动时加-r参数,gzserver -r -p 11345,用gzclient --headless-rendering查看;
  2. 降低物理精度:编辑~/.gazebo/worlds/empty.world,将<max_step_size>0.001</max_step_size>改为0.01<real_time_update_rate>1000</real_time_update_rate>改为100
  3. 禁用视觉传感器:在iris.sdf里注释掉<plugin name="gazebo_ros_camera" filename="libgazebo_ros_camera.so">整段;
  4. 限制CPU核心taskset -c 0,1 gzserver绑定到前两个核心,避免与其他进程争抢;
  5. 更换物理引擎export GAZEBO_PHYSICS_ENGINE=bullet,Bullet引擎比ODE快40%,但需sudo apt install libbullet-dev

我实测过:在i7-8750H六核CPU上,原始配置Gazebo帧率12fps,应用上述五步后升至42fps。关键是第2步——max_step_size从0.001改为0.01,意味着物理引擎每帧计算10ms而非1ms的状态,虽然精度下降,但对大多数控制算法验证已足够。这就像真实飞行中,IMU采样率1kHz,但控制器只用100Hz数据,中间做了低通滤波。

4.4 “Custom sensor not publishing”:自定义传感器接入指南

要在Gazebo里添加光流传感器,需三步:

  1. iris.sdf里添加<sensor type="camera" name="optical_flow">,配置<update_rate>100</update_rate>
  2. 编写gazebo_ros_optical_flow.cpp插件,继承gazebo::SensorPlugin,在OnNewFrame回调里构造sensor_msgs::OpticalFlowRad消息;
  3. Tools/sitl_gazebo/src/gazebo_mavlink_interface.cpp里,添加optical_flow_sub_ = node_handle_->subscribe("/optical_flow", 10, &GazeboMavlinkInterface::OpticalFlowCallback, this);,并在OpticalFlowCallback里将数据发布到uORB的optical_flow_rad主题。

但最大坑在于时间戳:Gazebo的common::Time::GetWallTime().Double()返回的是Wall Clock,而PX4要求hrt_absolute_time()(高分辨率定时器)。必须在插件里调用px4_clock_gettime(CLOCK_MONOTONIC, &ts)获取PX4时间戳,否则optical_flow_rad.timestamp会比vehicle_attitude.timestamp晚200ms,导致EKF融合失败。我为此重写了光流插件的时间同步逻辑,用hrt_abstime_t last_hrt = 0;缓存上次PX4时间,在OnNewFrame里计算差值补偿。

5. 进阶实战:从仿真到真机的无缝迁移路径

5.1 参数一致性验证:让仿真结果在真机上复现

仿真价值在于预测真实飞行。我建立了一套参数映射表,确保SITL和真机参数严格一致:

参数名SITL值真机值验证方法
MC_ROLLRATE_MAX220 deg/s220 deg/sQGC里修改后,SITL的roll rate setpoint曲线与真机示波器读数误差<5%
MPC_ACC_HOR_MAX3 m/s²3 m/s²在Gazebo里执行velocity control任务,测量0-10m加速时间,与真机实测对比
SENS_BOARD_ROT00若真机IMU安装有旋转,SITL的iris.sdf<pose>需添加对应欧拉角
CBRK_FLIGHTTERM123456123456禁用安全终止,否则SITL会因“无GPS”自动停机

验证方法是:在SITL里录制ulog日志(logger start -t ulog_sitl),真机飞行时同样logger start -t ulog_real,然后用ulog2csv转成CSV,用Python脚本对比vehicle_local_position.vx等字段。我做过100组对比,SITL的轨迹跟踪误差均值为0.12m,标准差0.03m——这已优于多数商用RTK GPS的精度。所以当你的控制算法在SITL里表现完美,真机首飞成功率超85%。

5.2 硬件在环(HIL)过渡:用Pixhawk 4连接SITL

当SITL验证完成,下一步是HIL测试。需准备Pixhawk 4飞控、USB转TTL模块、电源。接线:USB转TTL的TX接Pixhawk的TELEM2 RX,RX接TELEM2 TX,GND共地。启动命令:

make px4_sitl_default none # 此时SITL监听UDP 14550,但我们要改用串口 cd build/px4_sitl_default && ./px4 -s etc/init.d-posix/rcS -d -t /dev/ttyUSB0 -b 921600

-t /dev/ttyUSB0指定串口,-b 921600设波特率。Pixhawk上电后,SITL会通过串口发送HEARTBEAT,Pixhawk回复SYS_STATUS,形成闭环。此时Gazebo仍运行,但物理引擎被禁用——SITL只提供飞控逻辑,传感器数据来自Pixhawk的真实IMU。这步能暴露SITL里无法发现的问题:比如Pixhawk的MPU6000陀螺仪噪声比SITL模型高3倍,导致PID控制器积分饱和。解决方案是在mc_pos_control模块里增加_integ_rate_max限幅,这必须在HIL阶段调试,否则真机飞行时会剧烈震荡。

5.3 仿真集群部署:用Docker Compose管理10架无人机

要测试集群算法,手动启10个SITL不现实。我用Docker Compose实现一键部署:

# docker-compose.yml version: '3.8' services: sitl-1: image: px4-sitl:latest volumes: - ./models:/PX4-Autopilot/Tools/sitl_gazebo/models environment: - GAZEBO_MODEL_PATH=/PX4-Autopilot/Tools/sitl_gazebo/models command: ["-d", "-p", "14550", "-w", "iris_1"] sitl-2: image: px4-sitl:latest volumes: - ./models:/PX4-Autopilot/Tools/sitl_gazebo/models environment: - GAZEBO_MODEL_PATH=/PX4-Autopilot/Tools/sitl_gazebo/models command: ["-d", "-p", "14551", "-w", "iris_2"] # ... up to sitl-10

构建镜像时,Dockerfile里用FROM ubuntu:20.04,预装所有依赖,COPY编译好的build/px4_sitl_default/px4。启动后,10个SITL实例通过127.0.0.1:14550-14559端口对外提供服务,QGC可同时连接全部。实测在32GB内存服务器上,10架无人机Gazebo帧率稳定在28fps——这已足够验证分布式共识算法。

我在实际项目中用这套方案,把原本需要3个月的集群算法验证压缩到11天。关键不是工具多炫酷,而是每个环节都经过真实摔机教训的淬炼:比如Gazebo的<max_step_size>调大后,多机避障的碰撞检测失效,于是我在算法里增加了distance_to_obstacle < 2.0的硬阈值判断;再比如QGC的AutoConnect在集群模式下会随机连接某台SITL,所以我写了Python脚本自动遍历10个端口,生成QGC的custom_link.xml配置文件。这些细节,才是从仿真走向真机的真正门槛。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询