Robotics DocsV1.0
返回 Diff_Planner Simulation Testing 系列

04 / Diff_Planner Simulation Testing

机器狗&无人机测试

无人机仿真 / 系列文档 04

空中具身智能挑战赛官方提供的仿真环境

#2026中国高校智能机器人创意大赛-空中具身智能挑战赛官方提供的仿真环境 # Aerial Autonomy Challenge:ROS1 + Unity 仿真环境安装、使用与开发指南

更新于 2026-08-0510:07

    本文面向第一次接触 ROS、Docker 和无人机仿真的用户。目标是让用户能够:

    1. 根据自己的电脑选择“本机 ROS1”或“ROS1 Docker”运行方式。
    2. 编译并启动 ROS Noetic + Unity 仿真。
    3. 在 RViz 和 Unity 中观察无人机、地图和轨迹。
    4. 修改参数或 C++/Python 代码,并在仿真中验证结果。

    本文基于官方 2026robotics 分支和本项目当前可运行的工作区整理。官方链接:

    https://github.com/DifferentialRobotics/Aerial_Autonomy_Challenge/tree/2026robotics

    官方仿真器下载链接(官方 README 提供):

    https://pan.baidu.com/s/1rCioYJQSKhKqadkiC0CGdA?pwd=hs5p

    本文优先支持 Ubuntu/Linux。电脑已经安装 ROS Noetic 时,可以完全不使用 Docker;没有 ROS1 时,再使用 ROS1 Docker。Windows 或 macOS 上使用 Docker Desktop 需要额外的图形转发配置,本文不作为主要支持路径。

    1. 先理解这套系统

    这不是一个只运行 Unity 的程序,而是多个 ROS 节点共同组成的闭环:

    Unity 仿真器
      ├── 目标点列表 /publish_point (PoseArray)
      │             ↓
      │   sequential_waypoint_bridge.sh
      │             ↓ /goal (PoseStamped)
      │        Diff-Planner 规划器
      │             ↓ /drone_0_planning/trajectory
      │        traj_server 轨迹采样
      │             ↓ /drone_0_planning/pos_cmd
      │        cascadePID 控制器
      │             ↓ /quad_0/cmdRPM
      │        quadrotor_dynamics 动力学仿真
      │             ↓ /quad_0/lidar_slam/odom
      │        Unity 和航点到达判断
      │
      └── 点云 /drone_0_pcl_render_node/cloud
                    ↓
              GridMap 障碍物地图
    

    启动脚本是 sh_files/run_unity.sh,它按顺序启动:

    1. ROS-TCP-Endpoint:让 Unity 通过 TCP 连接 ROS,默认端口为 10000。
    2. Unity 可执行仿真器。
    3. ROS 仿真节点、规划器、控制器和动力学。
    4. 多航点桥接脚本。
    5. RViz 可视化。

    2. 安装前检查

    2.1 宿主机建议配置

    官方验证环境为 Ubuntu 20.04、ROS Noetic、NVIDIA RTX 4060。其他配置也可能运行,但图形驱动和编译时间会不同。

    建议准备:

    • 64 位 Linux,建议 Ubuntu 20.04。
    • 支持 OpenGL 的显卡;推荐 NVIDIA 显卡和已安装的 NVIDIA 驱动。
    • 至少 16 GB 内存;编译时使用 -j1 可以降低内存压力。
    • 至少 30 GB 可用磁盘空间。
    • Docker Engine(仅在选择 Docker 路径时需要)。
    • ROS Noetic(仅在选择本机 ROS1 路径时需要)。
    • 能够显示 X11 图形窗口的桌面环境。

    在宿主机执行以下检查:

    uname -m
    lsb_release -a
    echo "$DISPLAY"
    

    如果使用 NVIDIA 显卡,再执行 nvidia-smi 检查驱动。DISPLAY 通常类似 :0 或 :1;Docker 图形配置必须使用实际输出的显示编号,不能盲目写成 :0。

    2.2 选择运行路径

    请先在准备运行仿真的环境中执行:

    source /opt/ros/noetic/setup.bash
    rosversion -d
    

    如果输出 noetic,说明该环境已经有 ROS1,可以直接使用本机 ROS1 路径,不需要 Docker。

    如果提示文件不存在,或者电脑没有 ROS1,则使用 Docker 路径。Docker 只是在一个隔离环境中提供 Ubuntu 20.04 和 ROS Noetic,项目代码仍然可以挂载在宿主机上保存。

    两条路径后面的代码下载、Unity 仿真器放置、catkin 编译和运行逻辑相同,主要区别是命令在哪个环境执行:

    情况 代码和编译位置 是否需要 Docker 图形配置
    本机已安装 ROS Noetic 宿主机工作区 不需要 X11 socket 挂载
    本机没有 ROS1 ROS1 Docker 容器内 需要 DISPLAY、X11 socket 和 GPU 转发

    2.3 安装 Docker(仅 Docker 路径需要)

    如果宿主机还没有 Docker,可以先安装 Ubuntu 软件源中的版本:

    sudo apt update
    sudo apt install -y docker.io
    sudo systemctl enable --now docker
    sudo usermod -aG docker "$USER"
    

    执行 usermod 后需要重新登录,或者临时执行:

    newgrp docker
    docker run --rm hello-world
    

    2.4 NVIDIA Docker 支持(仅 Docker 路径需要)

    想让 Unity 使用显卡,需要在宿主机安装 NVIDIA Container Toolkit,并保证以下命令能工作:

    docker run --rm --gpus all nvidia/cuda:12.0.0-base-ubuntu20.04 nvidia-smi
    

    如果该命令报 could not select device driver,说明 Docker 还没有配置 GPU 运行时。先根据 NVIDIA 官方文档安装 Container Toolkit,再继续本指南。没有 GPU 时可以尝试软件渲染,但 Unity 和 RViz 可能无法正常显示或性能很差。

    3. 获取代码和 Unity 仿真器

    3.1 获取代码

    mkdir -p ~/aerial_ws
    cd ~/aerial_ws
    git clone --branch 2026robotics https://github.com/DifferentialRobotics/Aerial_Autonomy_Challenge.git
    cd Aerial_Autonomy_Challenge
    

    如果代码已经存在,只需要确认分支:

    git branch --show-current
    git status --short
    

    3.2 放置 Unity 仿真器

    从官方网盘下载并解压仿真器,将整个目录放到:

    Aerial_Autonomy_Challenge/src/AerialAutonomyChallenge-Simulator/
    

    必须能看到以下文件:

    ls -l src/AerialAutonomyChallenge-Simulator/AerialAutonomyChallenge-Simulator.x86_64
    

    赋予执行权限:

    chmod +x src/AerialAutonomyChallenge-Simulator/AerialAutonomyChallenge-Simulator.x86_64
    

    如果文件不存在,ROS 节点可以编译成功,但 Unity 场景不会启动。

    4. 根据环境继续安装

    4.1 电脑已经安装 ROS1:直接使用本机环境

    这是最简单的路径。所有 ROS 节点、Unity 和 RViz 都直接运行在宿主机上,不需要创建 Docker 容器,也不需要挂载 X11 socket。

    在宿主机打开一个终端,执行:

    source /opt/ros/noetic/setup.bash
    rosversion -d
    which roscore
    which roslaunch
    which rviz
    

    rosversion -d 应输出 noetic。本项目官方环境是 ROS Noetic;如果是 ROS Melodic 或其他 ROS1 版本,不能保证所有依赖和 C++ ABI 兼容,建议使用 Noetic。

    如果 ROS 已安装但缺少编译工具或常用依赖,可以在宿主机补齐:

    sudo apt update
    sudo apt install -y ros-noetic-desktop-full zsh git build-essential python3-rosdep \
      python3-catkin-tools libeigen3-dev libpcl-dev
    

    ros-noetic-desktop-full 用于补齐 RViz、常用消息和桌面工具;如果已经完整安装,apt 会直接跳过已存在的包。每个新终端都要 source ROS 环境,也可以将下面一行加入 ~/.bashrc

    source /opt/ros/noetic/setup.bash
    

    首次使用 rosdep 时初始化并安装工作区依赖:

    sudo rosdep init 2>/dev/null || true
    rosdep update
    cd ~/aerial_ws/Aerial_Autonomy_Challenge
    rosdep install --from-paths src --ignore-src --rosdistro noetic -r -y
    

    如果代码放在其他目录,将上面的工作区路径替换为实际路径。然后编译:

    cd ~/aerial_ws/Aerial_Autonomy_Challenge
    source /opt/ros/noetic/setup.bash
    catkin_make -j1
    source devel/setup.bash
    

    本机运行 Unity 时,通常不需要执行 xhost,因为 Unity 和 RViz 与当前桌面用户使用同一个显示会话。确认显示变量存在:

    echo "$DISPLAY"
    echo "$XDG_RUNTIME_DIR"
    

    如果 DISPLAY 为空,说明当前终端不是图形桌面会话,应在桌面终端中运行。若 XDG_RUNTIME_DIR 为空,可临时设置:

    mkdir -p /tmp/xdg-runtime-$(id -u)
    chmod 700 /tmp/xdg-runtime-$(id -u)
    export XDG_RUNTIME_DIR=/tmp/xdg-runtime-$(id -u)
    

    最后在工作区根目录运行:

    cd ~/aerial_ws/Aerial_Autonomy_Challenge
    chmod +x src/AerialAutonomyChallenge-Simulator/AerialAutonomyChallenge-Simulator.x86_64
    ./sh_files/run_unity.sh
    

    脚本第一行使用 /bin/zsh。即使本机已经安装 ROS,也需要确认本机有 zsh;没有时执行 sudo apt install -y zsh

    4.2 电脑没有 ROS1:使用 Docker

    4.2.1 推荐的容器启动方式

    先在宿主机授权当前图形显示。下面的 root 是因为示例容器以 root 用户运行;如果容器使用普通用户,需要授权对应用户名。

    xhost +SI:localuser:root
    

    在包含工作区的父目录执行:

    cd ~/aerial_ws
    docker run --name aerial_ros1 \
      --gpus all \
      --net=host \
      --ipc=host \
      -e DISPLAY="$DISPLAY" \
      -e QT_X11_NO_MITSHM=1 \
      -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
      -v "$PWD/Aerial_Autonomy_Challenge":/workspace/Aerial_Autonomy_Challenge \
      -it osrf/ros:noetic-desktop-full bash
    

    说明:

    • --gpus all 把 NVIDIA GPU 交给容器。
    • --net=host 让 Unity、ROS TCP endpoint 和宿主机更容易互通。
    • -e DISPLAY 和 /tmp/.X11-unix 是显示 Unity/RViz 窗口所需的 X11 配置。
    • 工作区挂载到 /workspace/Aerial_Autonomy_Challenge,容器删除后代码仍保留在宿主机。

    如果已经有可以使用的 ROS1 容器,不需要重新创建,只要确认它具有 ROS Noetic、zsh、RViz、X11 socket 和 GPU 权限即可。

    4.2.2 容器内安装工具和依赖

    进入容器后执行:

    apt update
    apt install -y zsh git build-essential python3-pip python3-rosdep \
      python3-catkin-tools libeigen3-dev libpcl-dev
    

    检查 ROS 和 zsh:

    source /opt/ros/noetic/setup.bash
    rosversion -d
    which zsh
    ls -l /bin/zsh
    

    预期 ROS 版本为 noetic,并且 /bin/zsh 存在。

    4.2.3 使用 rosdep 安装 ROS 依赖

    在容器内的工作区根目录执行:

    cd /workspace/Aerial_Autonomy_Challenge
    rosdep init 2>/dev/null || true
    rosdep update
    rosdep install --from-paths src --ignore-src --rosdistro noetic -r -y
    

    rosdep 会根据每个 ROS 包的 package.xml 安装消息、PCL、OpenCV、Eigen、RViz 等依赖。网络受限时,rosdep update 可能失败;此时需要在可联网环境执行,或使用已经准备好依赖的 ROS 镜像。

    5. 编译工作区

    选择与自己环境对应的工作区路径:

    # 本机 ROS1 路径
    cd ~/aerial_ws/Aerial_Autonomy_Challenge
    
    # Docker 路径
    cd /workspace/Aerial_Autonomy_Challenge
    

    进入工作区后编译:

    source /opt/ros/noetic/setup.bash
    catkin_make -j1
    source devel/setup.bash
    

    官方使用 -j1 是为了降低并行编译的内存占用。确认关键程序已经生成:

    test -x devel/lib/diff_planner/diff_planner_node && echo planner_ok
    test -x devel/lib/diff_planner/traj_server && echo traj_server_ok
    test -x devel/lib/cascadePID/cascadePID_node && echo pid_ok
    test -x devel/lib/mars_drone_sim/quadrotor_dynamics_node && echo dynamics_ok
    

    编译常见问题:

    现象 处理方式
    Eigen3Config.cmake 找不到 安装 libeigen3-dev,重新执行 catkin_make -j1
    PCL/OpenCV 头文件找不到 重新执行 rosdep install,确认使用 ROS Noetic 镜像
    Permission denied 执行 Unity 对 .x86_64 执行 chmod +x
    编译中途被系统杀掉 使用 catkin_make -j1,增加 Docker 内存或宿主机交换空间
    修改了 C++ 但运行行为没变化 重新编译并重新 source devel/setup.bash

    当前工作区的 src/user_command/multipoint/CMakeLists.txt 已包含 Eigen3 查找配置。如果从干净仓库重新构建时该包报 Eigen 错误,应保留该配置或安装 libeigen3-dev。

    6. 配置图形显示

    本机 ROS1 路径通常不需要额外配置:在 Ubuntu 桌面终端中运行即可。下面的 X11 授权和 socket 挂载只针对 Docker 路径,也是本项目实际遇到过的重点问题。

    6.1 本机 ROS1 路径

    echo "$DISPLAY"
    echo "$XDG_RUNTIME_DIR"
    

    DISPLAY 有值时直接启动即可,不要执行 Docker 的 socket 挂载命令。如果从 SSH 远程登录,需要配置 ssh -X/ssh -Y 或远程桌面;仅设置 DISPLAY 并不能凭空创建图形会话。

    6.2 Docker 路径:宿主机操作

    在宿主机执行:

    echo "$DISPLAY"
    xhost +SI:localuser:root
    

    例如输出为 :1,容器内就应使用 DISPLAY=:1。如果容器启动时没有挂载 X11 socket,需要重新创建容器并加入:

    -e DISPLAY=:1 \
    -v /tmp/.X11-unix:/tmp/.X11-unix:rw
    

    6.3 Docker 路径:容器内操作

    export DISPLAY=:1
    test -S /tmp/.X11-unix/X1 && echo x11_socket_ok
    
    mkdir -p /tmp/xdg-runtime-root
    chmod 700 /tmp/xdg-runtime-root
    export XDG_RUNTIME_DIR=/tmp/xdg-runtime-root
    export QT_X11_NO_MITSHM=1
    

    将 :1 替换成宿主机 echo "$DISPLAY" 的真实结果。如果 X1 不存在,不能只设置环境变量,必须重新挂载 socket。

    运行成功后,可以在宿主机撤销授权:

    xhost -SI:localuser:root
    

    7. 启动仿真

    7.1 一键启动

    本机 ROS1 用户在宿主机执行:

    cd ~/aerial_ws/Aerial_Autonomy_Challenge
    source /opt/ros/noetic/setup.bash
    source devel/setup.bash
    ./sh_files/run_unity.sh
    

    Docker 用户在容器内执行:

    cd /workspace/Aerial_Autonomy_Challenge
    source /opt/ros/noetic/setup.bash
    source devel/setup.bash
    ./sh_files/run_unity.sh
    

    终端通常是 Bash,因此手动准备环境使用 setup.bash;run_unity.sh 自身会用 zsh 启动,并 source setup.zsh。实际运行脚本的环境中必须存在 /bin/zsh。正常情况下可以看到:

    • ros_tcp_endpoint 在 0.0.0.0:10000 启动。
    • Unity 出现仿真窗口。
    • 规划器输出 FSM ... WAIT_TARGET。
    • 轨迹服务器输出 [Traj server]: ready.。
    • 航点桥输出 [WaypointBridge] 启动成功。
    • RViz 窗口出现。

    7.2 分窗口启动(调试推荐)

    一键脚本会同时启动多个后台进程,出错时日志不容易区分。调试时可以打开多个终端;本机 ROS1 用户直接打开桌面终端,Docker 用户可用 docker exec -it aerial_ros1 bash 打开多个容器终端。

    每个终端先进入实际工作区并加载环境。本机 ROS1 用户执行:

    cd ~/aerial_ws/Aerial_Autonomy_Challenge
    source /opt/ros/noetic/setup.bash
    source devel/setup.bash
    

    Docker 用户执行:

    cd /workspace/Aerial_Autonomy_Challenge
    source /opt/ros/noetic/setup.bash
    source devel/setup.bash
    

    然后分别运行:

    # 终端 1:TCP endpoint
    roslaunch ros_tcp_endpoint endpoint.launch
    
    # 终端 2:Unity
    ./src/AerialAutonomyChallenge-Simulator/AerialAutonomyChallenge-Simulator.x86_64
    
    # 终端 3:ROS 仿真、规划器和控制器
    roslaunch diff_planner run_sim_unity.launch
    
    # 终端 4:多航点桥
    ./sh_files/sequential_waypoint_bridge.sh
    
    # 终端 5:RViz
    roslaunch diff_planner exp_rviz.launch
    

    停止仿真时优先在启动窗口按 Ctrl-C,然后检查:

    rosnode list
    

    如果旧节点仍然存在,先停止旧容器或结束对应 ROS launch,再启动下一轮测试,避免多个 ROS master 或重复节点互相干扰。

    8. 用话题确认系统是否正常

    rostopic list
    rostopic hz /quad_0/lidar_slam/odom
    rostopic hz /drone_0_pcl_render_node/cloud
    rostopic hz /drone_0_planning/pos_cmd
    rostopic info /goal
    rosnode list
    rqt_graph
    

    关键话题:

    话题 类型 作用
    /publish_point geometry_msgs/PoseArray Unity 发布一组目标点
    /goal geometry_msgs/PoseStamped 当前目标点,规划器的输入
    /drone_0_pcl_render_node/cloud sensor_msgs/PointCloud2 障碍物点云
    /quad_0/lidar_slam/odom nav_msgs/Odometry 动力学仿真的真实状态
    /drone_0_quad_0/lidar_slam/odom nav_msgs/Odometry poscmd_2_odom 生成的理想状态
    /drone_0_planning/trajectory traj_utils/PolyTraj 规划器生成的轨迹
    /drone_0_planning/pos_cmd quadrotor_msgs/PositionCommand 轨迹服务器采样后的位置指令
    /quad_0/cmdRPM std_msgs/Float32MultiArray PID 输出的电机转速
    /drone_0_traj_server/heartbeat std_msgs/Empty 规划器和轨迹服务器的存活信号

    直接测试单个目标点:

    rostopic pub -1 /goal geometry_msgs/PoseStamped \
    "{header: {frame_id: world}, pose: {position: {x: 2.0, y: 0.0, z: 1.0}, orientation: {w: 1.0}}}"
    

    9. 代码包说明

    src/
    ├── AerialAutonomyChallenge-Simulator/   Unity 二进制仿真器
    ├── Simulator-bridge/                    Unity ↔ ROS TCP 桥
    ├── diff_planner/                        主要规划与控制代码
    │   ├── plan_env/                        点云和占据栅格地图
    │   ├── path_searching/                  动态 A* 初始路径搜索
    │   ├── traj_opt/                        多项式轨迹优化
    │   ├── plan_manage/                     FSM、规划管理、轨迹服务器
    │   ├── cascadePID/                      位置/姿态 PID 和电机控制
    │   └── mars_drone_sim/                  四旋翼动力学和风场
    ├── uav_simulator/                       通用模拟器和局部感知节点
    ├── Utils/                               消息、RViz 工具、可视化工具
    └── user_command/multipoint/             YAML 航点工具
    

    9.1 修改参数:最快的实验方式

    先修改 src/diff_planner/plan_manage/launch/include/advanced_param_sim.xml:

    • manager/max_vel:最大速度。
    • manager/max_acc:最大加速度。
    • planning_horizon:规划时域。
    • grid_map/obstacles_inflation:障碍物膨胀距离。
    • optimization/obstacle_clearance:轨迹与障碍物的安全距离。
    • optimization/weight_obstacle:避障代价权重。
    • use_multitopology_trajs:是否尝试多种拓扑轨迹。

    这些是 launch 参数,修改后不需要编译,但需要停止并重新启动 roslaunch diff_planner run_sim_unity.launch。

    9.2 修改规划算法

    建议按以下顺序阅读:

    1. src/diff_planner/plan_manage/src/diff_planner_node.cpp:程序入口,只负责初始化 FSM。
    2. src/diff_planner/plan_manage/src/diff_replan_fsm.cpp:处理目标、里程计、碰撞检查、重规划和紧急停止。
    3. src/diff_planner/plan_manage/src/planner_manager.cpp:组织初始路径、轨迹候选和优化结果。
    4. src/diff_planner/path_searching/src/dyn_a_star.cpp:搜索无碰路径。
    5. src/diff_planner/traj_opt/src/poly_traj_optimizer.cpp:根据地图和约束优化轨迹。

    修改这些 C++ 文件后:

    catkin_make -j1
    source devel/setup.bash
    

    推荐一次只改一个变量或一个逻辑块,先记录基线,再比较修改前后的规划时间、轨迹长度、最小障碍距离和实际跟踪误差。

    9.3 修改控制器或动力学

    • 修改 src/diff_planner/cascadePID/src/cascadePID_node.cpp:改变位置误差到姿态/电机转速的控制逻辑。
    • 修改 src/diff_planner/mars_drone_sim/src/quadrotor_dynamics_node.cpp:改变质量、动力学、风力模型和传感器输出。
    • 修改 src/uav_simulator/fake_drone/src/poscmd_2_odom.cpp:改变规划器使用的理想状态模型。

    这些模块都会影响闭环行为,修改后必须重新编译并重新启动完整仿真。

    9.4 修改航点逻辑

    sh_files/sequential_waypoint_bridge.sh 内嵌了一段 Python:

    • 订阅 Unity 的 /publish_point。
    • 将每个点转换为 /goal。
    • 通过真实里程计判断是否到达。
    • 到达后发送下一个点。
    • 新任务开始前可先返回原点。

    修改默认高度、到达距离或离开距离时,不需要编译;重新运行脚本即可。当前脚本默认 DEFAULT_Z=0.0,如果目标点没有有效高度,可能把目标发到地面,建议根据任务设为飞行高度,例如 1.0。

    9.5 Unity 的修改边界

    仓库中只有 Unity 的 Linux 可执行文件,没有 Unity 工程和场景源码。因此可以通过 ROS 话题和参数改变算法行为,但不能直接修改 Unity 界面、障碍物生成逻辑或场景资源。若要修改 Unity 本身,需要向仿真器提供方索取 Unity 工程。

    10. 建议的开发和测试流程

    10.1 保留基线

    开始实验前:

    git switch -c experiment/my-first-change
    git status --short
    

    运行产生的 pycache 和 cascadePID/data/log_0.txt 属于生成文件,不要混入功能提交。当前工作区已有 src/user_command/multipoint/CMakeLists.txt 的 Eigen3 修改,保留或单独记录它,不要误删用户自己的改动。

    10.2 做一组可比较的实验

    每次实验固定:

    • Unity 场景和障碍物布局。
    • 起始位置和目标点。
    • 仿真时长。
    • ROS 参数和版本。

    记录基线数据:

    rosbag record -O baseline.bag \
      /goal \
      /quad_0/lidar_slam/odom \
      /drone_0_planning/pos_cmd \
      /drone_0_planning/trajectory \
      /drone_0_pcl_render_node/cloud
    

    停止录包后,可以使用 rqt_plot 对比指令位置和动力学实际位置:

    /drone_0_planning/pos_cmd/position/x
    /quad_0/lidar_slam/odom/pose/pose/position/x
    

    10.3 安全检查

    任何控制器、动力学或目标判断修改,都要先在低速、小范围、无障碍场景测试。确认以下条件后再使用复杂场景:

    • 目标超出地图时会被拒绝。
    • 轨迹碰撞时会触发重规划或紧急停止。
    • 丢失规划器 heartbeat 时轨迹服务器会停止继续发送旧轨迹。
    • 无人机不会因为目标高度为 0 而撞地。

    11. 本项目已发现的已知问题

    这些问题不一定阻止启动,但会影响实验结果,建议在正式交付前修正并重新编译/测试:

    1. src/diff_planner/plan_manage/launch/sim/run_sim_unity.launch 第 43 行的风区 max_x 为 11.68.0,应改成合法数字。
    2. 风区 min_y=-2.88、max_y=-4.14 的边界顺序相反;当前 isInWindZone 使用“位置大于等于 min 且小于等于 max”的判断,风区可能永远不成立。
    3. src/diff_planner/plan_manage/launch/include/advanced_param_sim.xml 没有设置 waypoint1_y。
    4. 航点桥订阅 /drone_0_planning/fsm_state,但当前规划器没有发布这个话题;实际到达判断主要依赖 /quad_0/lidar_slam/odom。
    5. 日志中的 Package name "cascadePID" does not follow the naming conventions 是 ROS 包命名警告,不是启动失败原因。
    6. 规划器使用 poscmd_2_odom 生成的理想里程计,而 PID、Unity 和航点桥使用动力学真实里程计。测试控制效果时应比较这两条状态链。

    12. 实际遇到过的报错和解决办法

    12.1 /bin/zsh: bad interpreter: No such file or directory

    报错示例:

    ./sh_files/run_unity.sh: /bin/zsh: bad interpreter: No such file or directory
    

    原因是脚本第一行是 #!/bin/zsh,但实际运行脚本的环境中没有这个文件。本机 ROS1 路径需要在宿主机安装;Docker 路径需要在容器内安装。宿主机安装 zsh 不会自动安装到容器内。

    本机 ROS1 用户在宿主机执行:

    sudo apt update
    sudo apt install -y zsh
    ls -l /bin/zsh
    

    Docker 用户在容器内执行:

    apt update
    apt install -y zsh
    ls -l /bin/zsh
    

    如果文件已经存在但仍报错,检查脚本是否是 Windows 换行符:

    head -n 1 sh_files/run_unity.sh | od -An -t x1
    

    首行结尾应为 0a,不能有 0d 0a。有 0d 时执行:

    sed -i 's/\r$//' sh_files/*.sh
    

    12.2 Authorization required、could not connect to display

    报错示例:

    Authorization required, but no authorization protocol specified
    qt.qpa.xcb: could not connect to display unix:1
    

    这个问题主要出现在 Docker 路径中:容器可以找到显示编号,但没有得到宿主机 X11 授权,或没有挂载 X11 socket。本机 ROS1 用户在桌面终端运行时通常不会遇到它。

    宿主机执行:

    echo "$DISPLAY"
    xhost +SI:localuser:root
    

    创建容器时包含:

    -e DISPLAY="$DISPLAY" \
    -e QT_X11_NO_MITSHM=1 \
    -v /tmp/.X11-unix:/tmp/.X11-unix:rw
    

    容器内执行:

    export DISPLAY=:1
    test -S /tmp/.X11-unix/X1
    mkdir -p /tmp/xdg-runtime-root
    chmod 700 /tmp/xdg-runtime-root
    export XDG_RUNTIME_DIR=/tmp/xdg-runtime-root
    

    如果 X1 不存在,需要重新创建容器并挂载 socket。测试结束后,宿主机可以撤销授权:

    xhost -SI:localuser:root
    

    12.3 RViz 退出,但 ROS 节点已启动

    如果日志显示规划器和动力学都启动,只有 RViz 出现 process has died,通常仍是 X11 或 OpenGL 配置问题,不是规划算法错误。先检查 DISPLAY、XDG_RUNTIME_DIR、X11 socket 和 GPU,再重新启动。

    12.4 ROS 找不到包或可执行文件

    确保每个新终端都执行:

    source /opt/ros/noetic/setup.bash
    
    # 本机 ROS1 路径
    cd ~/aerial_ws/Aerial_Autonomy_Challenge
    
    # 或 Docker 路径
    cd /workspace/Aerial_Autonomy_Challenge
    
    source devel/setup.bash
    rospack find diff_planner
    

    如果 rospack find 失败,说明工作区没有成功编译,或当前终端没有 source 正确的 devel/setup。

    13. 交付给客户前的检查清单

    建议先完成“固定场景 + 单个目标点”的基线测试,再逐步修改参数、规划器、控制器和动力学。这样客户可以清楚区分“环境没有配置好”和“代码修改改变了飞行结果”这两类问题。