构建与运行
环境与构建
环境:Ubuntu 20.04、ROS2 Foxy、Python 3.8。实际飞行测试使用 Windows OpenHUTB Air 场景与 WSL2。
在仓库根目录执行:
source /opt/ros/foxy/setup.bash
rosdep install --from-paths src/air/uav_mission_interfaces src/air/uav_mission_safety_manager --ignore-src --rosdistro foxy -r -y
colcon build --symlink-install --packages-up-to uav_mission_safety_manager
source install/setup.bash
AirSim 模式另需安装包内 requirements.txt 中的 Python 依赖。AirSim 的安装脚本会提前导入 NumPy 和 RPC 客户端,首次安装需先准备构建工具和这两项,并关闭隔离构建:
python3 -m pip install --user "setuptools>=45.2.0,<76" "wheel<0.46" numpy==1.17.4 msgpack-rpc-python==0.4.1
python3 -m pip install --user --no-build-isolation -r src/air/uav_mission_safety_manager/requirements.txt
依赖版本面向 Python 3.8;OpenCV 使用兼容该环境的 4.5.5.64。rclpy、消息类型和 launch 等 ROS 依赖由 package.xml 声明,通过上述 rosdep 安装,不从 pip 安装。仅运行离线状态机时无需安装 AirSim 依赖。
启动节点
先启动 OpenHUTB 并选择 Air 模式,等待无人机落地停稳。确认 Windows 的 AirSim TCP 端口 41451 对 WSL 可达。
# WSL2 NAT 模式下获取 Windows 主机地址;其他网络配置请填写实际地址。
AIRSIM_HOST=$(ip route | awk '/default/ {print $3; exit}')
ros2 launch uav_mission_safety_manager main.launch.py \
use_airsim:=true airsim_host:="$AIRSIM_HOST" airsim_port:=41451
只运行一个飞行控制节点。每个新终端均需加载 ROS 和工作空间环境:
source /opt/ros/foxy/setup.bash
source install/setup.bash
在独立终端查看状态:
ros2 topic echo /uav_mission_safety_manager/status
状态包含 state、reason、position_ned、target_ned、target_speed、takeoff_rpc_result、command_pending 和 last_error。
连接与起飞
在命令终端逐条执行,确认状态后再进行下一步。启动节点本身不会连接、解锁或起飞。
# 连接并记录起点,等待 ARMING。
ros2 topic pub --once /uav_mission_safety_manager/command std_msgs/msg/String '{data: "{\"event\":\"connect\"}"}'
# 解锁,等待 TAKEOFF;此时尚未请求起飞。
ros2 topic pub --once /uav_mission_safety_manager/command std_msgs/msg/String '{data: "{\"event\":\"armed\"}"}'
# 请求起飞,遥测确认离地后进入 EXECUTING。
ros2 topic pub --once /uav_mission_safety_manager/command std_msgs/msg/String '{data: "{\"event\":\"airborne\"}"}'
takeoff_rpc_result 为 null 表示暂无结果。实测存在返回 false 但无人机已升空的情况,进入 EXECUTING 不代表起飞 RPC 返回成功。
航点与服务
航点使用 AirSim 本地 NED 绝对坐标,单位为米:x 向北、y 向东、z 向下。它不是相对位移,也不会自动转换为 ROS ENU。请根据起点坐标及场景障碍物修改以下示例:
ros2 topic pub --once /uav_mission_safety_manager/command std_msgs/msg/String '{data: "{\"event\":\"goto\",\"x\":3,\"y\":0,\"z\":-5,\"speed\":0.5}"}'
| 服务 | 功能 |
|---|---|
/uav_mission_safety_manager/pause |
取消当前飞行任务并请求悬停,保留目标和速度 |
/uav_mission_safety_manager/resume |
恢复原目标及指令速度 |
/uav_mission_safety_manager/return_home |
返回连接时记录的起点上方并自动降落 |
/uav_mission_safety_manager/land |
显式请求降落 |
调用格式:
ros2 service call /uav_mission_safety_manager/pause std_srvs/srv/Trigger '{}'
ros2 service call /uav_mission_safety_manager/resume std_srvs/srv/Trigger '{}'
ros2 service call /uav_mission_safety_manager/return_home std_srvs/srv/Trigger '{}'
# 需要显式降落时单独调用:
ros2 service call /uav_mission_safety_manager/land std_srvs/srv/Trigger '{}'
服务成功表示本地接受请求。若 command_pending=true 导致拒绝,等待派发完成再重试。返航完成应观察到 RETURNING → LANDING → LANDED。降落服务可在 TAKEOFF、EXECUTING、PAUSED、RETURNING、LANDING 或 FAILSAFE 请求。
落地后可发送 reset 回到 IDLE,下一轮重新连接记录起点。AirSim 模式禁止手动注入 connected、at_home 和 landed 事件。
控制参数与安全边界
| 参数或条件 | 默认值 |
|---|---|
max_altitude |
相对起点最大高度 50 m |
telemetry_timeout |
遥测超时 2 s |
operation_timeout |
飞行阶段超时 120 s |
| 普通航点到达容差 | 1 m |
| 返航速度 | 0.5 m/s |
| 返航转降落条件 | 位置误差 ≤ 0.08 m、合速度 ≤ 0.05 m/s,持续 1 s |
前三项在 config/mission.yaml 中配置,其余为当前控制实现中的固定值。返航保持当前高度或至少起点上方 5 m,受高度上限约束;末段使用低速修正,无避障能力。
屋顶落地兼容逻辑仅在降落 RPC 成功、距起点 ≤ 0.15 m、合速度 ≤ 0.1 m/s 持续 3 s 后尝试解除解锁,之后仍需新遥测确认落地。
FAILSAFE 不保证自动悬停或降落;停止节点不会中止模拟器中的飞行任务。关闭节点前应确认无人机已落地。
测试命令
离线检查
python3 -m unittest discover -s src/air/uav_mission_safety_manager/tests -v
ROS_DOMAIN_ID=87 python3 src/air/uav_mission_safety_manager/tests/ros_smoke.py
离线节点使用 use_airsim:=false,不计为实际模拟器验证。
实际 AirSim 复测
以下脚本会重置并起飞模拟无人机,自行启动 ROS 节点。先停止其他飞行控制节点,每条命令完成并确认落地后再运行下一条:
ROS_DOMAIN_ID=93 python3 src/air/uav_mission_safety_manager/tests/ros_airsim_validation.py \
--host "$AIRSIM_HOST" --case mission --log /tmp/uav_mission.jsonl --fly
ROS_DOMAIN_ID=93 python3 src/air/uav_mission_safety_manager/tests/ros_airsim_validation.py \
--host "$AIRSIM_HOST" --case return_land --log /tmp/uav_return_land.jsonl --fly
ROS_DOMAIN_ID=93 python3 src/air/uav_mission_safety_manager/tests/ros_airsim_validation.py \
--host "$AIRSIM_HOST" --case disconnect --log /tmp/uav_disconnect.jsonl --fly
mission 验证航点、暂停/继续及返航自动降落;return_land 验证起点上方返航中显式降落;disconnect 切断节点专用 TCP 转发,验证遥测超时。测试输出留在 /tmp,不提交仓库。断线后的独立恢复降落不计入自动故障恢复能力。
已有结果见测试结果与已知限制。