1. 为什么集群路径规划要从环境搭建开始啃搞集群路径规划的人十个里有八个卡在第一步——环境搭不起来。EGO-swarm 这套东西在学术圈和工程圈都挺火它解决的是多无人机在复杂三维环境里协同飞行、实时避障、保持队形的问题。听起来很酷对吧但如果你连编译都过不了后面那些花哨的集群编队、动态避障、轨迹优化全是空中楼阁。我自己第一次搭 EGO-swarm 的时候整整耗了三天。第一天卡在 ROS 版本不匹配第二天卡在 Eigen 和 PCL 的版本冲突第三天好不容易编译过了跑仿真的时候无人机直接原地抽搐。后来我才明白这个项目的环境依赖链条特别长从 ROS 的版本选择、C 编译器的版本、到各种数学库的精确版本任何一个环节出问题都会导致连锁反应。这篇文章适合谁看如果你正在做多机器人集群、无人机编队、或者任何涉及 EGO-planner 系列算法的项目而且你用的是 Ubuntu ROS 这套技术栈那这篇内容就是给你写的。我会把整个环境搭建过程拆开揉碎告诉你每一步为什么这么做、哪些地方容易翻车、以及翻车之后怎么救回来。不是那种复制粘贴命令的教程而是让你真正理解这套环境的内在逻辑。先说清楚 EGO-swarm 到底是什么。它是浙大 FAST 实验室开源的一套集群规划框架核心思想是把单机的 EGO-planner 扩展到多机场景。每架无人机独立规划自己的轨迹但通过一个轻量级的通信机制共享位置信息从而在局部避障的同时实现全局的集群行为。它的优势在于计算量小、实时性好单机规划器可以在几毫秒内完成轨迹重规划非常适合资源受限的机载平台。但正因为它是科研项目代码的工程化程度参差不齐依赖管理基本靠 README 里那几行说明。而 README 往往假设你已经是一个熟练的 ROS 开发者很多坑它默认你会自己填。这就是为什么很多人搭环境搭到怀疑人生。2. 系统版本与 ROS 发行版的选择逻辑2.1 Ubuntu 版本不是随便选的EGO-swarm 官方推荐的是 Ubuntu 18.04 ROS Melodic或者 Ubuntu 20.04 ROS Noetic。这两个组合有什么区别核心在于 C 标准库的版本和 PCL 的版本。Ubuntu 18.04 自带的是 GCC 7.5默认 C 标准是 C14。Ubuntu 20.04 自带 GCC 9.4默认 C 标准是 C17。EGO-swarm 的代码里用了一些 C14 的特性比如std::make_unique在 C17 下编译也没问题但有些第三方库在 C17 下会有警告甚至报错。我个人的建议是如果你是新装机直接上 Ubuntu 20.04 ROS Noetic。原因很简单Noetic 是 ROS 1 的最后一个版本社区支持到 2025 年各种依赖包的安装脚本最完善。Melodic 虽然也能用但很多 PPA 源已经停止维护了装个 PCL 都要折腾半天。但如果你实验室的机器全是 18.04那也别折腾重装系统Melodic 也能跑通只是后面装依赖的时候要多留个心眼。2.2 ROS 安装的两种路径ROS 的安装方式主要有两种apt 安装和源码编译。对于 EGO-swarm 来说必须用 apt 安装不要尝试源码编译 ROS。原因在于 EGO-swarm 依赖的很多 ROS 包比如cv_bridge、tf2在源码编译环境下容易出现 ABI 不兼容的问题而 apt 安装的二进制包是经过测试的稳定性有保障。安装 ROS Noetic 的标准流程sudo sh -c echo deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main /etc/apt/sources.list.d/ros-latest.list sudo apt install curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add - sudo apt update sudo apt install ros-noetic-desktop-full这里有个细节desktop-full包含了 Gazebo、RViz、以及各种感知和导航的包体积大概 2GB 左右。如果你磁盘空间紧张可以只装ros-noetic-desktop但后面跑仿真的时候还得补装 Gazebo 相关的包反而更麻烦。所以一步到位装desktop-full是最省事的。安装完之后别忘了初始化rosdepsudo rosdep init rosdep updaterosdep是 ROS 的依赖管理工具EGO-swarm 的很多依赖都是通过它来安装的。如果你在国内网络环境下rosdep update失败可以换用国内镜像源或者多试几次。这个命令失败是常态成功了才是意外。2.3 环境变量的配置陷阱很多教程会告诉你把source /opt/ros/noetic/setup.bash加到.bashrc里但没告诉你的是如果你同时有多个 ROS 工作空间.bashrc里的 source 顺序会影响环境变量的优先级。我的做法是在.bashrc里只 source 系统 ROS工作空间的 source 手动执行。这样每次打开终端环境是干净的不会因为某个工作空间的setup.bash覆盖了系统变量而导致奇怪的编译错误。echo source /opt/ros/noetic/setup.bash ~/.bashrc source ~/.bashrc验证 ROS 是否安装成功roscore如果能看到started core service [/rosout]说明 ROS 核心没问题。按CtrlC退出。3. EGO-swarm 的依赖链条与编译顺序3.1 核心依赖库的版本要求EGO-swarm 的依赖可以分为三类ROS 包、数学库、以及可视化工具。我把它们整理成了一张表方便你对照检查。依赖库版本要求作用安装方式Eigen3.3.7 以上线性代数运算apt 或源码PCL1.10 以上点云处理aptOpenCV4.2 以上图像处理与可视化aptArmadillo9.0 以上矩阵运算部分模块aptNLopt2.6 以上非线性优化aptROS Noetic完整版通信框架aptEigen 的版本特别关键。EGO-planner 的核心优化问题大量使用了 Eigen 的稀疏矩阵求解器如果版本低于 3.3.7某些 API 不存在编译会直接报错。Ubuntu 20.04 的 apt 源里 Eigen 版本是 3.3.7刚好满足要求。但如果你用的是 18.04apt 里的 Eigen 是 3.3.4需要手动升级。检查 Eigen 版本pkg-config --modversion eigen3如果输出小于 3.3.7就需要从源码安装wget https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz tar -xzvf eigen-3.4.0.tar.gz cd eigen-3.4.0 mkdir build cd build cmake .. sudo make install源码安装的 Eigen 会覆盖 apt 版本头文件安装在/usr/local/include/eigen3。这时候需要确保 CMake 能找到新版本可以在 CMakeLists.txt 里显式指定include_directories(/usr/local/include/eigen3)。3.2 创建工作空间与源码拉取EGO-swarm 的代码托管在 GitHub 上直接 clone 到工作空间的src目录mkdir -p ~/ego_swarm_ws/src cd ~/ego_swarm_ws/src git clone https://github.com/ZJU-FAST-Lab/ego-planner-swarm.gitclone 完成之后不要急着编译。先检查一下代码的分支和依赖声明。EGO-swarm 的主分支是master但有时候作者会推送一些实验性的分支这些分支的依赖可能不完整。建议 checkout 到最新的稳定 tag。查看可用 tagcd ego-planner-swarm git tag选择一个最近的 tag比如v1.0然后git checkout v1.0接下来安装rosdep依赖cd ~/ego_swarm_ws rosdep install --from-paths src --ignore-src -r -y这个命令会自动读取每个包的package.xml安装缺失的依赖。如果一切顺利你会看到一堆All required rosdeps installed successfully。但现实往往不顺利常见的报错是某些包找不到比如nlopt或者armadillo。这时候需要手动安装sudo apt install libnlopt-dev libarmadillo-dev3.3 编译过程中的典型报错与修复编译 EGO-swarm 用的是catkin_make但直接跑catkin_make大概率会失败。我总结了几种最常见的报错和对应的修复方法。报错一fatal error: Eigen/Dense: No such file or directory这说明编译器找不到 Eigen 的头文件。即使你装了 Eigen如果 CMake 没有正确配置 include 路径也会报这个错。解决方法是在工作空间的CMakeLists.txt里添加include_directories(/usr/include/eigen3)或者更通用的写法find_package(Eigen3 REQUIRED) include_directories(${EIGEN3_INCLUDE_DIR})报错二undefined reference to pcl::search::KdTree这是 PCL 链接错误通常是因为 PCL 的组件没有全部链接。在CMakeLists.txt里确保find_package(PCL REQUIRED)之后链接了所有需要的组件find_package(PCL REQUIRED COMPONENTS common io search kdtree) include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) target_link_libraries(your_target ${PCL_LIBRARIES})报错三error: make_unique is not a member of std这是 C 标准版本的问题。std::make_unique是 C14 引入的如果你的编译器默认用 C11就会报这个错。解决方法是在CMakeLists.txt里设置set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON)报错四内存不足导致编译中断EGO-swarm 的编译过程非常吃内存尤其是traj_utils和plan_manage这两个包单个编译单元可能占用 2GB 以上的内存。如果你的机器内存小于 8GB建议用catkin_make -j2限制并行编译的线程数或者增加 swap 空间。sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile编译成功后你会看到[100%] Built target的提示。这时候先别高兴太早编译通过只是第一步运行起来才是真正的考验。4. 仿真环境启动与常见运行问题4.1 启动脚本的调用顺序EGO-swarm 的仿真启动涉及多个 launch 文件调用顺序有讲究。正确的顺序是启动 Gazebo 仿真环境启动单机规划器启动集群通信节点启动 RViz 可视化对应的命令# 终端1启动 Gazebo roslaunch ego_planner swarm.launch # 终端2启动 RViz roslaunch ego_planner rviz.launchswarm.launch这个文件里其实已经包含了 Gazebo 的启动、无人机的 spawn、以及规划器的初始化。但如果你直接跑这个 launch 文件可能会遇到 Gazebo 卡在启动界面不动的情况。这通常是因为 Gazebo 在下载模型文件而国内网络访问 Gazebo 的模型库很慢。解决方法是在启动前设置 Gazebo 的模型路径为本地路径export GAZEBO_MODEL_PATH~/.gazebo/models:$GAZEBO_MODEL_PATH或者提前把需要的模型下载到本地。EGO-swarm 用到的模型主要是sun、ground_plane、以及一些简单的障碍物这些在 Gazebo 的默认模型库里都有。4.2 无人机原地抽搐的根因分析仿真跑起来之后最常见的问题是无人机在原地抖动或者直接飞不起来。这个问题我遇到过三次每次的原因都不一样。原因一控制频率不匹配EGO-swarm 的规划器输出的是位置指令而 Gazebo 里的无人机模型需要速度指令或者姿态指令。如果规划器的输出频率和控制器的工作频率不匹配就会出现指令堆积或者指令丢失导致无人机抖动。检查方法用rostopic hz /drone_0_planning/pos_cmd查看规划指令的发布频率。正常情况下应该是 100Hz 左右。如果频率忽高忽低说明规划器的计算时间不稳定可能是某个优化问题的求解时间过长。原因二坐标系变换错误EGO-swarm 涉及多个坐标系世界坐标系、无人机机体坐标系、相机坐标系、以及规划器的局部坐标系。如果某个坐标系变换写错了规划器算出来的轨迹在 Gazebo 里就会完全错位。排查方法在 RViz 里添加TF显示检查各个坐标系之间的变换关系是否正确。特别要注意world到drone_0的变换以及drone_0到drone_0_camera的变换。原因三物理引擎参数不合理Gazebo 的默认物理引擎参数比如max_step_size和real_time_update_rate可能不适合无人机仿真。如果max_step_size太大物理仿真会不稳定导致无人机抖动。调整方法在 Gazebo 的启动文件里修改物理引擎参数physics typeode max_step_size0.001/max_step_size real_time_update_rate1000/real_time_update_rate /physics4.3 集群通信的调试技巧EGO-swarm 的集群行为依赖于无人机之间的位置共享。如果通信出了问题每架无人机就会变成瞎子各自为战集群行为完全消失。调试通信的第一步是确认每架无人机都在发布自己的位置信息rostopic list | grep drone你应该能看到类似/drone_0_visual_slam/odom、/drone_1_visual_slam/odom这样的话题。然后用rostopic echo检查数据是否正常rostopic echo /drone_0_visual_slam/odom/pose/pose/position如果数据正常但集群行为还是不对那可能是通信的订阅关系有问题。EGO-swarm 用一个叫swarm_bridge的节点来转发无人机之间的位置信息。检查这个节点是否正常运行rosnode info /swarm_bridge如果swarm_bridge节点不存在说明 launch 文件里没有启动它或者启动失败了。查看 launch 文件里的相关配置确保swarm_bridge的launch-prefix没有设置成screen或者log否则你看不到它的输出。5. 从单机到集群的调试策略5.1 先用单机验证规划器在调试集群之前一定要先确保单机规划器能正常工作。EGO-swarm 的代码库里有一个单机的 launch 文件通常叫single_drone.launch或者run_in_sim.launch。先用这个文件跑通单机确认无人机能起飞、能避障、能到达目标点。单机调试的时候重点关注这几个话题/drone_0_planning/pos_cmd规划器输出的位置指令/drone_0_planning/bspline规划出的 B 样条轨迹/drone_0_planning/grid_map/occupancy局部占据栅格地图如果pos_cmd有输出但无人机不动检查 Gazebo 里的控制器是否订阅了正确的话题。如果bspline有输出但pos_cmd没有说明规划器的轨迹优化环节出了问题可能是优化问题的约束设置太严格导致求解失败。5.2 逐步增加无人机数量单机跑通之后不要一下子启动五架无人机。先启动两架确认它们能互相避让再增加到三架、四架。每增加一架都要重新检查通信和规划是否正常。两机调试的时候把两架无人机放在相邻的位置给它们设置交叉的飞行目标。观察它们在相遇时是否能互相避让。如果两架无人机直接撞上了说明通信没有生效或者避障的膨胀半径设置得太小。膨胀半径在advanced_param.xml里配置参数名通常是inflate_radius或者obstacle_inflate_size。默认值一般是 0.3 到 0.5 米对于室内仿真来说够用了。但如果你的无人机尺寸比较大或者飞行速度比较快需要适当增大这个值。5.3 日志分析与性能瓶颈定位EGO-swarm 的规划器会在终端输出大量的日志信息包括每次重规划的时间、优化问题的求解状态、以及轨迹的代价。这些日志是定位性能瓶颈的关键。如果你发现规划器的计算时间超过了控制周期通常是 10ms无人机就会出现明显的延迟和抖动。常见的原因包括局部地图的点云数量太多导致 KdTree 搜索变慢优化问题的维度太高求解器迭代次数过多代码里有不必要的拷贝操作增加了内存开销优化方法在grid_map模块里降低点云的分辨率或者限制局部地图的范围。在plan_manage模块里调整优化问题的权重参数减少迭代次数。我自己的经验是把局部地图的分辨率从 0.1 米降到 0.2 米规划时间能减少 30% 左右而避障效果几乎没有下降。这个取舍在实时性要求高的场景下非常值得。6. 环境搭建中的几个关键决策点6.1 用不用鱼香 ROS 一键安装网上有很多人推荐用鱼香 ROS 的一键安装脚本来装 ROS确实省事。但我的建议是如果你只是跑个简单的 demo用一键安装没问题但如果你要搭 EGO-swarm 这种依赖复杂的项目最好还是手动安装。原因在于一键安装脚本会修改系统的源列表和环境变量有时候会引入一些不必要的包或者覆盖掉你之前配置好的环境。EGO-swarm 对环境的纯净度有一定要求特别是 Eigen 和 PCL 的版本如果被脚本改乱了后面排查起来非常痛苦。6.2 源码编译还是二进制安装EGO-swarm 本身必须源码编译这个没得选。但它的依赖库比如 Eigen、PCL、OpenCV能用 apt 就用 apt不要源码编译。源码编译这些库不仅耗时而且容易和系统里的其他库产生冲突。唯一可能需要源码编译的是 NLopt因为 apt 里的版本有时候太旧。但 NLopt 的编译很简单依赖也少十分钟就能搞定。6.3 仿真环境用 Gazebo 还是 AirSimEGO-swarm 官方支持 Gazebo也有人在 AirSim 上跑通过。如果你只是做算法验证Gazebo 足够了而且配置简单。如果你需要更真实的视觉仿真比如跑 VINS 或者 ORB-SLAM那可以考虑 AirSim。但 AirSim 的配置复杂度比 Gazebo 高一个数量级而且和 ROS 的接口不如 Gazebo 成熟。我建议先用 Gazebo 把算法跑通等算法稳定了再考虑换仿真平台。7. 一些让我少走弯路的实操习惯搭环境这件事最怕的就是一次成功。因为一次成功意味着你没有踩过坑下次换个机器或者换个版本你还是不知道怎么处理。我现在的习惯是每搭一次环境就把所有的命令和报错记录下来形成一个自己的环境搭建日志。这个日志里不仅记录成功的命令更重要的是记录失败的尝试和失败的原因。比如尝试用 apt 安装 Eigen 3.4失败因为 Ubuntu 20.04 的源里只有 3.3.7这种信息比成功的命令更有价值。另外我强烈建议用 Docker 来管理 EGO-swarm 的环境。虽然 Docker 里的 GUI 显示需要额外配置但一旦配好环境就是可复现的。你可以在任何机器上拉取镜像几分钟就能跑起来不用再经历一遍编译的痛苦。Docker 的配置要点是把 X11 的 socket 挂载到容器里设置DISPLAY环境变量并且确保容器里的用户有权限访问 X11。具体的 Dockerfile 和运行脚本我下次再单独写一篇。还有一个习惯是在编译之前先用catkin_make -j1单线程编译一次。虽然慢但能确保每个编译单元的报错信息都能完整显示不会因为并行编译导致报错信息交错在一起。等单线程编译通过了再用-j4或者-j8加速。最后说一个关于调试的心态问题。EGO-swarm 的环境搭建确实麻烦但这个过程本身就是在帮你理解这套系统的架构。每解决一个依赖问题你就对这套系统的模块划分多了一分了解。等你把环境搭通了后面调算法的时候你会发现自己对代码的理解比那些直接用别人配好的环境的人深得多。这个系列后面还会写规划器的参数调优、集群编队的实现细节、以及如何把仿真里跑通的算法部署到真机上。环境搭建只是第一关但这一关过了后面的路就好走多了。