
先说结论这个项目值得每一个做移动机器人自主导航的人花时间跑一遍。它不是一个demo级的玩具而是一套完整的“未知环境自主探索”开发环境包含前端探索策略、后端路径规划与建图、仿真器、可视化闭环。标题里的CMU不是挂名这套环境确实出自CMU的机器人探索实验室在GitHub上以Autonomous Exploration Development Environment简称AEDE开源star量很高引用它的论文和衍生项目也不少。我自己从下载代码到把默认场景跑通大概花了一个下午真正把里面每个模块看懂、能改参数、能换场景用了差不多一周。这篇就把整个过程写下来包括环境搭建、框架拆解、多场景测试和一些你大概率会踩的坑。1. 项目到底在做什么三层架构拆解1.1 一个demo讲清楚完整闭环先想象一个场景你把一架无人机丢进一片完全未知的森林它没有任何先验地图也不知道边界在哪里唯一能做的就是不断飞、不断看、不断思考“哪里还没去过、怎么过去、路上会不会撞树”。AEDE解决的就是这件事。实际跑起来后你会在RViz里看到无人机自动起飞前端不断检测“边界点”Frontier也就是已探索区域和未探索区域交界处的候选点规划器从中挑一个最值得去的点生成一条无碰撞路径无人机沿路径飞行同时激光或视觉里程计把新看到的点云增量式地塞进地图地图更新后又产生新的边界点……如此循环直到找不到值得去的边界点任务自动结束。这个“探索-建图-规划”的循环是移动机器人领域很经典的问题。AEDE的价值在于它把这条链路完整实现并开源了而且仿真环境做得很真实你不需要有一台真机就能完整体验整个过程。1.2 核心模块与代码仓库结构从仓库结构来看AEDE主要分为这几大块exploration_manager探索管理节点负责边界点生成、选择、任务状态机是整个系统的“大脑”plan_env路径规划的地图与代价环境内部封装了八叉树地图和碰撞检测给规划器提供查询接口plan_manager路径规划器的调度与执行包含前端探索路径规划器参考RRT系列算法和后端安全轨迹优化vehicle_simulator无人机仿真器基于Gazebo负责模拟动力学、传感器、点云生成以及world场景的加载so3_disturbance施加外部扰动用来测试控制器鲁棒性odometry_visualization、pointgrey_camera_driver、realsense-ros视觉里程计与相机驱动相关用于真机和视觉方案。如果只想跑仿真核心只有前四个包。其它视觉相关的包大多只在切换到视觉里程计方案或者上真机时才需要。这个模块划分值得仔细看一遍尤其是exploration_manager和plan_env之间的调用关系理解了之后改参数才不会两眼一抹黑。我比较推荐第一次接触的人先不去读代码把项目原样跑起来然后在RViz里反复观察。看到无人机自己转弯、自己决定往哪飞、自己避开障碍物之后再回头看代码理解速度会快很多。2. 环境搭建从零开始把项目跑起来2.1 版本选择与依赖清单环境搭建是很多人卡住的第一关。AEDE对ROS版本有一定要求我实测下来比较稳的是Ubuntu 18.04 ROS MelodicUbuntu 20.04 ROS Noetic也能编译通过但Gazebo版本和PCL版本之间的组合更容易出幺蛾子建议新手直接上18.04 Melodic省心。依赖项方面除了ROS桌面完整版之外还有几个关键库必须提前装好Eigen 3.3PCL 1.8GTSAM 4.0.2探索前端和部分位姿优化会用到protobuf、yaml-cpp、google-glog 等基础库octomap注意版本后面单独讲安装命令大致如下sudo apt-get update sudo apt-get install ros-melodic-desktop-full sudo apt-get install libeigen3-dev libpcl-dev libgtsam-dev \ libgoogle-glog-dev libgflags-dev libprotobuf-dev protobuf-compiler \ libyaml-cpp-dev ros-melodic-octomap* ros-melodic-pcl-ros如果GTSAM没装成功也可以用源码编译注意版本选4.0.2而不是最新的4.1否则部分接口变化可能导致编不过。2.2 编译顺序与常见编译错误把这个仓库clone下来之后建议直接放到catkin工作空间的src目录下然后使用catkin build而不是catkin_make。原因是AEDE内部的包之间依赖关系比较复杂catkin_make对某些包的编译顺序处理得不好容易莫名失败。mkdir -p ~/aede_ws/src cd ~/aede_ws/src git clone https://github.com/HongbiaoZ/autonomous_exploration_development_environment.git cd ~/aede_ws catkin build如果只compile个别包也可以先cd到src目录用catkin build指定包名但强烈建议第一次全量编译确保依赖完整。编译过程中最常见的错误我整理一下第一个是找不到GTSAM。这个基本是版本问题先确认gtsam是否安装在/usr/local/lib/cmake/GTSAM下如果装的是系统源里的老版本路径可能不对。解决方法是源码编译GTSAM 4.0.2安装后重新build。第二个是octomap版本冲突。ROS Melodic自带的octomap 1.9和AEDE部分代码里默认的1.8接口会打架编译时报octomap::AbstractOcTree相关的类型错误。我当时的做法是手动指定octomap版本在plan_env的CMakeLists.txt里把octomap的find_package版本改成和系统一致或者干脆装1.8然后让ROS的octomap_server也用同一套库。这个问题比较隐蔽但遇到的人不少。第三个是缺少mav_msgs或mav_planning_msgs之类的消息包。AEDE的vehicle_simulator和exploration_manager之间会用一些自定义消息很多是从其它仓库引过来的如果clone时只拉主仓库而没拉子模块很容易缺消息定义。保险做法是clone时加--recursivegit clone --recursive https://github.com/HongbiaoZ/autonomous_exploration_development_environment.git如果已经clone了也可以用git submodule update --init --recursive补拉子模块。编译通过后建议先用roscore和rosnode list确认环境正常再进入下一步。3. 跑通一次自主探索启动流程与关键话题3.1 两步启动法AEDE的仿真启动不是一条launch全搞定而是分两步先启动Gazebo仿真器和无人机模型再启动探索管理节点。分开启动的好处是方便调试——你可以先确认地图和点云正常再启动探索逻辑出问题时定位更快。终端一启动仿真环境source ~/aede_ws/devel/setup.bash roslaunch vehicle_simulator system.launch这个launch会拉起Gazebo加载默认的随机森林场景同时启动无人机动力学仿真、点云生成和里程计节点。启动过程比较慢尤其是Gazebo第一次加载模型需要编译生成卡个一两分钟很正常。看到终端输出[ INFO] ... Ready并且RViz出现点云后才算成功。终端二启动探索管理节点source ~/aede_ws/devel/setup.bash roslaunch exploration_manager exploration.launch启动后无人机应该会在几秒内自动起飞然后开始在场景中自主探索。RViz里会逐渐看到地图边界向外扩张探索路径在持续更新。如果你看到无人机一直停在原地不动多半是探索管理器没收到有效的点云或里程计话题这个时候不要急着调参数先回头检查话题是否连通。3.2 观察运行状态话题、可视化与日志跑起来之后推荐用一组命令实时观察系统状态rosnode list rostopic list rostopic hz /cloud_registered rostopic echo /exploration_manager/exploration_status其中/cloud_registered是里程计配准后的点云话题频率一般在10Hz以上如果频率很低或者长时间没更新说明仿真的点云处理链路有问题探索必然卡住。RViz里推荐关注这几样东西全景点云代表无人机当前已经建好的地图观察它是否在持续增长边界点集合探索管理器发布的可选目标点一般以一簇点云或Marker形式显示看它们是否合理分布在已探索区域边缘全局路径和局部轨迹看规划器生成的路径是否平滑、是否绕开障碍物当前目标点无人机当前正在飞往的边界点观察它是否会频繁切换。日志方面exploration_manager运行时会输出[ExplorationManager]打头的状态信息包括当前阶段、候选点数量、目标点切换原因等。我建议跑的时候盯着这个输出看一段时间慢慢就能建立“状态-日志-行为”的对应关系。3.3 手动干预与目标点引导AEDE支持在探索过程中人为指定目标点这在测试和调试时非常有用。你可以用RViz的2D Nav Goal工具在地图上点一个位置探索管理器会临时把这个点当作高优先级目标规划器会给无人机重新规划路径。这个功能在调试路径规划时很宝贵。比如你怀疑某些狭窄区域规划不出来就可以手动把目标点丢进去看规划器怎么处理。我第一次用这个功能调试走廊场景时很快发现了局部路径避障参数太保守的问题手动干预比一遍遍重启探索要高效得多。需要注意的是手动目标点会打乱原来的探索策略所以调试完之后最好重启探索节点让它回到自主状态。4. 多场景测试换地图、调参数、验证泛化性4.1 随机森林场景与地图生成器AEDE默认的随机森林场景位于vehicle_simulator/worlds/目录下主体是一个.world文件里面通过Gazebo的模型标签放置大量树干模型模拟森林环境。这个场景的特点是障碍物细长、分布随机、视距有限非常适合测试探索算法的覆盖率。场景的随机性来自地图生成器map generator它在每次启动时会根据随机种子生成一批障碍物所以即使你重复跑同一个world每次的障碍物分布也可能不一样。这个特性在做统计测试时非常有用但也会给“复现实验”带来一点麻烦。如果需要固定场景可以修改world文件里随机种子的初始值或者干脆把生成器改为加载一个固定点云模型。在森林场景下我观察到AEDE的探索行为总体偏“保守稳健”无人机不会飞太快遇到树比较密集的区域会主动绕行探索路径的覆盖重叠比较多但安全性很高。对于第一次跑这个项目的人来说这个默认行为其实是最适合用来验证系统正常性的。4.2 自定义场景室内仓库、狭窄走廊与空旷大厅只跑自带的森林场景你会觉得这个项目“很能跑”但看不出它什么时候会失效。真正有价值的测试是换场景尤其是室内和半结构化环境。AEDE并不强制使用自己的world文件只要你把Gazebo场景切换成自定义的室内模型探索系统完全可以继续工作。我自己做了三类自定义场景来做压力测试第一类是室内仓库布局用一堆箱体和货架模型模拟货架通道通道宽度大概在无人机机身尺寸的1.5到2倍。这种场景对前端边界点检测是个考验因为货架之间的缝隙会产生大量看起来“能钻过去”但实际很危险的候选通道。第二类是狭窄走廊走廊宽度只比无人机机身宽一点点。AEDE的全局规划器在这种场景下会明显变保守候选点几乎都集中在走廊两端无人机转弯半径很大探索效率骤降。我通过放宽规划器的膨胀半径和安全距离参数勉强能让无人机通过走廊但速度会降到很低。这个现象说明它更适合中等密度障碍物环境极端狭窄环境不是它的主战场。第三类是空旷大厅只放几根独立柱子。这种场景下AEDE会暴露另一个问题因为边界点太远无人机倾向于飞非常长的直线一旦柱子在飞行途中进入传感器视野局部规划器的反应会稍微滞后导致路径出现明显的“先直行再急转弯”现象。这个可以通过提高局部规划器的重规划频率缓解。如果你没有现成的室内world文件最快的方式是直接用Gazebo自带的模型库搭几个基本形状或者从其它开源仓库比如TurtleBot的仿真场景里拿一个world文件出来改。AEDE对接的是ROS生态Gazebo场景对它是透明的只要能发布点云和里程计它就能跑。4.3 参数调整的思路与效果对照AEDE的主要参数集中在exploration_manager/config/exploration_params.yaml和plan_env/config两个地方。直接看参数名不一定能猜出作用我建议按照下面这个逻辑去调。先调地图分辨率与代价膨胀。plan_env里的地图体素分辨率决定了八叉树地图的精度默认值在0.1米到0.2米之间。分辨率越低碰撞检测越保守无人机离障碍物越远安全性越高但可通行区域变小探索效率下降。我实测在森林场景下把分辨率从0.2改到0.1无人机会在树之间明显绕得更远探索时间大概增加了20%到30%。再调边界点采样间隔与数量。exploration_manager里控制边界点检测频率和候选点数量的参数很关键。候选点越多目标选择越精细但计算量也越大。森林场景下我习惯把候选点数量限制在50个以内室内场景可以适当放宽到100个因为室内结构复杂少候选点容易漏掉一些“入口”。然后是速度与加速度限制。vehicle_simulator或者规划器参数里会有最大速度、最大加速度的限制。仿真环境下可以适当调高速度观察探索效率上限但真机上一定要保守。我试过把最大速度从默认值提高到1.5倍探索时间确实降了但路径曲率明显变大窄通道里差点撞上。调参的时候记住一个原则每次只改一个参数记录探索时间和覆盖率。不要一次性改三四个否则出问题你根本不知道是哪个参数引起的。我用一张表格记录了几组关键参数下的探索结果实测下来最有效的三组调整是适当降低地图分辨率、提高重规划频率、放宽候选点数量上限。这三项组合起来在复杂室内场景下能把探索时间降低30%左右同时不牺牲安全性。5. 常见问题与排查实录5.1 编译与启动故障速查表把我在不同机器上遇到的编译和启动问题整理成一张速查表直接照方抓药现象可能原因解决办法编译报找不到GTSAM版本不对或未安装源码编译GTSAM 4.0.2安装后重新catkin buildoctomap相关头文件报错octomap版本冲突将系统octomap与代码依赖版本对齐或修改CMakeLists指定版本缺少自定义消息包子模块未拉全用git submodule update --init --recursive补拉Gazebo启动后黑屏/卡住等待模型库下载Gazebo模型库缺失提前下载gazebo_models到~/.gazebo/models下或检查网络RViz里看不到点云frame_id不匹配或话题没发布检查TF树确认/cloud_registered话题有数据固定坐标系设为world5.2 探索卡死、震荡与效率低下的定位思路探索卡死和震荡是这个项目里最磨人的问题但绝大多数时候不是代码bug而是参数和环境不匹配。无人机飞到某个位置后长时间不动最常见的现象是边界点集合空了。这个不一定代表探索完成有可能是当前传感器视野内看不到任何边界点而探测范围又刚好被障碍物挡住。此时把探索完成判定阈值调大一点或者让无人机先做一次原地旋转往往就能恢复。还有些时候无人机会在两个目标点之间来回震荡飞一半突然掉头再飞回去。这个典型的根因是目标点切换过于频繁。探索管理器里对目标点有“最小更新间隔”和“当前目标点优先级”两个参数把它们调高一点震荡就会明显减少。另外如果局部规划器一直在重新规划且每次都因为代价过高放弃路径也会表现为原地打转这时需要检查代价地图的膨胀半径是否和无人机尺寸匹配。探索效率低、覆盖率重复高的另一个常见原因是传感器模型的视距太短。仿真器里点云发布的范围有限如果视距太小无人机每次只能看到面前一小块区域就会频繁地“近视眼式”决策飞出去没多久又掉头。我遇到过在Gazebo场景中视距300米和100米下的探索效率差别在一倍以上。所以先检查点云话题的范围再怀疑算法。5.3 折腾一周之后的实际体会跑完这个项目我最大的感受有两点。第一点是AEDE把“探索”这件事拆得很清楚。边界点检测是一层、目标选择是一层、路径规划是一层、建图优化又是一层。调试的时候你不需要同时盯所有东西只要按链路一层层看很快能定位到问题。这个模块化思维本身就是值得学习的比单纯会跑一个demo重要得多。第二点是仿真环境再怎么真实和真机之间的鸿沟依然很大。AEDE自带仿真器把点云和里程计都处理得相当“干净”到了真机上里程计漂移、点云噪声、传感器视场限制都会把探索质量往下拉。如果你后续打算用它做真机实验建议先在仿真里故意加入噪声、降低里程计更新频率提前适应“脏数据”下的表现。这个项目后续还可以往多机协同、语义探索、动态障碍物场景几个方向扩展。AEDE本身已经包含多无人机探索的接口在多台机器上各跑一个探索节点共用一张全局地图逻辑上很容易串起来。我自己的计划是先在仿真里把多机协同跑通再考虑往真机上迁移。这个坑已经挖好了后面有空再写一篇多机探索的实战记录。