本文整理 PX4 + Gazebo + MAVROS + Onboard 控制程序的四种启动场景:单机仿真、多机仿真、单机实测和多机实测。多机时最容易出错的是实例编号、系统 ID 和端口的对应关系,文中单独列了一张对照表。

环境说明

项目 说明
PX4 SITL,使用 px4_sitl_default 构建
Gazebo PX4 官方支持的 Gazebo,命令中使用 gz_x500 模型
ROS ROS 2,配合 MAVROS2 与 onboard 控制程序
地面站 QGroundControl(QGC),用于设置真实飞控的 MAV_SYS_ID

多实例仿真中,PX4 用 -i 指定实例编号,这个编号会映射为 MAV 系统 ID;MAVROS 通过 fcu_url 指定与 PX4 通信的 UDP 端口或串口。端口必须与实例一一对应。

情况 1:单机仿真

启动 PX4 + Gazebo:

1
PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 -i 0

启动 MAVROS + Onboard 控制:

1
ros2 launch onboard_control mainTree.launch.py uav_id:=1 fcu_url:="udp://:14540@127.0.0.1:14557"

情况 2:多机仿真

启动多个 PX4 SITL 实例,为每架无人机分配不同的初始位置和系统 ID:

1
2
3
4
5
6
# 实例 0
PX4_SYS_AUTOSTART=4001 PX4_SIM_MODEL=gz_x500 PX4_GZ_MODEL_POSE="0,0" ./build/px4_sitl_default/bin/px4 -i 0
# 实例 1
PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_POSE="1,0" PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 -i 1
# 实例 2
PX4_GZ_STANDALONE=1 PX4_SYS_AUTOSTART=4001 PX4_GZ_MODEL_POSE="0,1" PX4_SIM_MODEL=gz_x500 ./build/px4_sitl_default/bin/px4 -i 2

PX4_GZ_MODEL_POSE 指定模型在 Gazebo 中的初始位置 (x, y)。第二及后续实例加上 PX4_GZ_STANDALONE=1,避免与第一个实例的 Gazebo 插件冲突。

为每架无人机启动各自的 MAVROS + Onboard 控制:

1
2
3
ros2 launch onboard_control mainTree.launch.py uav_id:=1 fcu_url:="udp://:14540@127.0.0.1:14557"
ros2 launch onboard_control mainTree.launch.py uav_id:=2 fcu_url:="udp://:14541@127.0.0.1:14558"
ros2 launch onboard_control mainTree.launch.py uav_id:=3 fcu_url:="udp://:14542@127.0.0.1:14559"

实例、系统 ID 和端口的对应关系:

实例 -i MAV_SYS_ID PX4 UDP 输入端口 MAVROS fcu_url tgt_system
0 1 14540 udp://:14540@127.0.0.1:14557 1
1 2 14541 udp://:14541@127.0.0.1:14558 2
2 3 14542 udp://:14542@127.0.0.1:14559 3

建议给每架无人机使用不同的 ROS 2 命名空间(如 /uav1、/uav2、/uav3),避免话题和 TF 树冲突。

情况 3:单机实测

连接真实飞控的串口(示例为 /dev/ttyACM0,波特率 57600):

1
ros2 launch onboard_control mainTree.launch.py uav_id:=1 fcu_url:="serial:///dev/ttyACM0:57600"

使用其他接口(如 /dev/ttyUSB0)时,替换设备路径即可。

情况 4:多机实测

多块飞控对应多台机载电脑,或同一台机载电脑的多个串口:

1
2
3
ros2 launch onboard_control mainTree.launch.py uav_id:=1 fcu_url:="serial:///dev/ttyACM0:57600"
ros2 launch onboard_control mainTree.launch.py uav_id:=2 fcu_url:="serial:///dev/ttyACM1:57600"
ros2 launch onboard_control mainTree.launch.py uav_id:=3 fcu_url:="serial:///dev/ttyACM2:57600"

实测前,先用 QGC 逐块设置飞控的 MAV_SYS_ID:与启动命令中的 uav_id 一致,并且在集群内不重复。

注意事项与排查

多机时需要保证三件事:每个 PX4 实例的 -i 唯一(对应不同的 MAV_SYS_ID);MAVROS 的 fcu_url 端口与对应 PX4 实例匹配;不同无人机使用不同的 ROS 命名空间。

问题 可能原因 排查建议
无法连接 MAVROS 端口号或串口不对 确认 fcu_url 与实际端口,检查 UDP 是否被防火墙拦截
多机互相干扰、心跳冲突 系统 ID 重复或端口占用 检查 -i、MAV_SYS_ID 以及 QGC 中的参数
话题混杂 没有使用命名空间 在 launch 文件中增加 namespace 参数
模型位置重叠 初始位姿相同 为各实例设置不同的 PX4_GZ_MODEL_POSE