简介本资源是面向Robomaster智能无人机赛的自主控制框架基于Ego-planner实现路径规划与决策适合具备ROS与C基础、希望深入无人机算法与自主飞行开发的参赛者与研究者。压缩包共994个文件约96.35MB以cpp、hpp、h等C源码为主体配合launch、xacro、yaml等ROS配置以及png、svg、rviz等可视化资源另有py脚本、msg消息定义与cmake构建文件覆盖感知、状态估计、路径规划、控制与通信等模块。已有414人学习下载。通过该框架可系统理解Ego-planner的避障与轨迹规划思路掌握从传感器处理到决策执行的完整链路并借助可部署源码快速验证与改进算法提升无人机自主控制与竞赛实战能力。1. 从 Robomaster 飞控到 Ego-planner这套框架到底能跑出什么如果你正在准备 Robomaster 智能无人机赛道的飞控代码大概率会遇到一个尴尬感知模块能识别目标控制模块能输出姿态但中间那条「从当前位置到目标点、还要绕开对手和场地障碍」的轨迹始终调不顺。这份「使用 Ego-planner 的 Robomaster 智能无人机赛框架」压缩包解决的就是这一段——它把 Ego-planner 作为局部轨迹规划器嵌进 Robomaster 的决策链路让无人机在高速机动中依然能生成平滑、可跟踪、避障的轨迹。压缩包里能看到solar_system.agr、brief_k10L6.bin、Chessboard.cc、CostFunctionFactory.cc、PinholeFullCamera.cc、CataCamera.cc、ScaramuzzaCamera.cc、gpl.cc、PinholeCamera.cc、EquidistantCamera.cc这些文件覆盖了相机模型、代价函数工厂、棋盘格标定和规划器主体。它适合已经能跑通基础飞控、想补齐「自主避障 动态目标追踪」这一环的参赛队也适合想把 Ego-planner 从仿真搬到实机的开发者。2. Ego-planner 在 Robomaster 里的角色拆解为什么不是全局规划器2.1 局部规划与全局规划的边界Robomaster 赛场是一个 8 米见方、有遮挡、有高速移动对手的动态环境。全局规划器比如 A*、Dijkstra算出来的路径在对手突然横穿、场地道具被撞歪之后基本就废了。Ego-planner 的定位是局部规划器它不关心「从起点到终点的完整拓扑」只关心「未来 1 到 2 秒内我该怎么走才不撞、还能逼近目标」。这个时间窗口对应到 Robomaster 无人机上大约是 3 到 6 米的前向距离刚好覆盖一次急停或一次绕障的机动范围。Ego-planner 的核心思路是把轨迹表示成一串带时间戳的 B 样条控制点然后用梯度下降去优化控制点位置代价函数里同时塞进平滑项、障碍物项、目标项和动力学可行性项。CostFunctionFactory.cc这个文件就是干这个的——它根据配置生成不同的代价函数组合。你改一个权重轨迹的「激进程度」就变了。常见做法是平滑项权重调高轨迹更圆润但绕障反应慢障碍物项权重调高贴障更紧但容易抖动。2.2 从传感器到轨迹的完整数据流一份能跑的 Ego-planner 链路数据流是这样的相机驱动PinholeFullCamera.cc/EquidistantCamera.cc/CataCamera.cc/ScaramuzzaCamera.cc输出图像和相机内参。标定模块Chessboard.cc用棋盘格算外参和畸变系数把像素坐标转成无人机机体坐标系下的障碍物位置。状态估计模块融合 IMU 和视觉输出无人机当前位姿和速度。Ego-planner 主体gpl.cc接收目标点、当前状态、障碍物点云输出一条 B 样条轨迹。控制模块把轨迹离散成位置 速度 加速度指令发给飞控。brief_k10L6.bin这个文件从命名看是一个二进制数据文件常见做法是存标定参数或预训练的障碍物检测权重。solar_system.agr是 Agisoft 的工程文件格式可能用于场地三维重建或相机标定参考。这两个文件不是代码但它们是让规划器「知道自己在哪、障碍物在哪」的前提。2.3 为什么 Robomaster 场景特别适合 Ego-plannerRobomaster 无人机的飞行时间通常只有 3 到 5 分钟算力平台多是 Jetson Nano 或 Xavier NX 级别。Ego-planner 的计算量集中在 B 样条优化上一次规划迭代在 Jetson 上大约 5 到 15 毫秒1 秒能跑 60 到 200 次重规划。这个频率足够跟上对手的移动。相比之下基于采样的 RRT* 在同样算力下重规划频率会掉到 10 赫兹以下轨迹跟踪就会明显滞后。另一个原因是 Ego-planner 对障碍物点云的容错性。它不需要完整的障碍物边界只需要一堆离散的障碍物点就能通过距离场梯度把轨迹推开。Robomaster 场地上对手的装甲板、场地边缘的围挡、甚至飞过的弹丸都可以作为障碍物点输入。这种「点云即障碍」的接口比需要精确建模的规划器省掉了大量预处理。3. 把压缩包跑起来编译、标定与第一个避障轨迹3.1 环境依赖与编译顺序这套代码依赖 ROS常见做法是 Melodic 或 Noetic、Eigen3、PCL 和 Ceres Solver。编译顺序不能乱因为CostFunctionFactory.cc依赖 Ceres 的自动求导gpl.cc依赖 PCL 的点云类型。# 安装核心依赖Ubuntu 18.04 ROS Melodic 为例 sudo apt-get install -y ros-melodic-pcl-ros ros-melodic-cv-bridge \ libeigen3-dev libceres-dev libpcl-dev # 创建工作空间 mkdir -p ~/rm_ego_ws/src cd ~/rm_ego_ws/src # 把压缩包解压后的源码目录放进来假设目录名为 rm_ego_planner cp -r /path/to/rm_ego_planner . # 编译注意先编译相机模型和标定模块再编译规划器 cd ~/rm_ego_ws catkin_make -DCMAKE_BUILD_TYPERelease -j4这里-DCMAKE_BUILD_TYPERelease必须加Ego-planner 的优化在 Debug 模式下会慢 5 到 10 倍实机上根本跑不动。-j4根据你的 CPU 核数调整Jetson 上建议-j2否则编译时内存容易爆。编译过程中如果报Ceres not found检查libceres-dev是否装对版本。Ceres 2.0 以上和 1.14 的 API 有差异CostFunctionFactory.cc里如果用了AutoDiffCostFunction的旧写法需要把模板参数从CostFunctor, 1, 1改成CostFunctor, 1, 1的新形式。这个坑我后面还会细说。3.2 相机标定Chessboard.cc 怎么用Chessboard.cc是棋盘格标定模块。Robomaster 无人机上常用的相机是鱼眼或广角畸变很大不标定的话障碍物位置会偏出半米以上。# 启动标定节点假设相机话题是 /camera/image_raw rosrun rm_ego_planner chessboard_calib \ _image_topic:/camera/image_raw \ _pattern_size:9x6 \ _square_size:0.025 # 在另一个终端里播放录好的棋盘格视频或实时对准棋盘 rosbag play calib_board.bag_pattern_size:9x6表示棋盘格内角点数是 9 列 6 行不是格子数。_square_size:0.025是每个格子的实际边长单位米。标定完成后会生成一个 YAML 文件里面包含相机内参矩阵和畸变系数。把这个文件路径填到PinholeFullCamera.cc或EquidistantCamera.cc的配置里。常见错误是棋盘格没铺平或者拍摄时棋盘格只出现在图像边缘。标定算法对边缘畸变最敏感但边缘角点检测也最容易失败。我一般会录一段棋盘格从画面中心缓慢移到边缘的视频确保每个区域都有 10 帧以上清晰图像。3.3 配置 Ego-planner 参数并跑通第一条轨迹gpl.cc是规划器入口它的参数通过 ROS 参数服务器加载。一个能用的最小配置如下# config/ego_planner.yaml planner: max_vel: 3.0 # 最大速度Robomaster 场地建议 2.5-3.5 max_acc: 6.0 # 最大加速度太高会触发飞控保护 planning_horizon: 5.0 # 规划视野单位米 obstacle_inflation: 0.3 # 障碍物膨胀半径按无人机轴距一半加余量 smooth_weight: 1.0 # 平滑项权重 obstacle_weight: 2.0 # 障碍物项权重越高越贴障 goal_weight: 1.5 # 目标项权重 control_points: 8 # B 样条控制点数量越多轨迹越灵活但越慢# 启动规划器 roslaunch rm_ego_planner ego_planner.launch \ config_file:$(rospack find rm_ego_planner)/config/ego_planner.yaml # 在 RViz 里给一个目标点观察轨迹生成 rosrun rviz rviz -d $(rospack find rm_ego_planner)/rviz/planner.rvizmax_vel和max_acc不是随便填的。Robomaster 无人机的飞控通常有自己的速度环如果 Ego-planner 输出的速度指令超过飞控能跟踪的范围轨迹跟踪就会发散。常见做法是先设max_vel: 1.5跑通后再逐步加到 3.0。obstacle_inflation要大于无人机实际半径否则规划出的轨迹会擦着障碍物过实机上因为控制误差就撞了。control_points这个参数很关键。8 个控制点对应大约 1.5 秒的轨迹时长在 3 米每秒的速度下覆盖 4.5 米。如果你把planning_horizon设成 5 米控制点至少要 8 个否则轨迹表达不出绕障的曲率。4. 避坑与排查标定、编译和轨迹抖动4.1 标定结果偏差大障碍物位置飘现象RViz 里障碍物点云和实际场地对不上偏了 0.3 到 0.5 米。原因棋盘格标定时用了错误的square_size或者相机和 IMU 的外参没标。Chessboard.cc只标相机内参相机到机体的外参需要另外的标定流程。解决用卷尺量棋盘格实际边长精确到毫米。外参标定常见做法是让无人机对准一个已知位置的标志物手动调整外参直到点云对齐。如果用了CataCamera.cc或ScaramuzzaCamera.cc的鱼眼模型畸变系数要单独验证可以用cv::fisheye::undistortImage做一次去畸变可视化。4.2 编译报错 CostFunctionFactory 模板参数不匹配现象error: wrong number of template arguments指向CostFunctionFactory.cc里的AutoDiffCostFunction。原因Ceres Solver 2.0 之后AutoDiffCostFunction的模板参数从(CostFunctor, 1, 1)变成了(CostFunctor, 1, 1)但要求 CostFunctor 的operator()是const的旧代码可能没加const。解决打开CostFunctionFactory.cc找到报错行把operator()改成const修饰或者把 Ceres 降级到 1.14。我一般会先试改const因为降级可能影响其他模块。4.3 轨迹抖动无人机在空中画波浪现象Ego-planner 输出的轨迹在 RViz 里看起来平滑但实机上无人机上下抖动。原因smooth_weight太低或者max_acc设得超过了飞控的实际加速度能力。另一个可能是状态估计的延迟Ego-planner 用的当前位姿是 50 毫秒前的导致轨迹起点和实际位置有偏差。解决先把smooth_weight从 1.0 提到 2.0观察抖动是否减轻。如果没改善把max_acc降到 4.0。状态估计延迟需要检查 IMU 和视觉的时间戳同步常见做法是在gpl.cc里加一个 20 毫秒的预测补偿。4.4 规划器输出空轨迹无人机悬停不动现象给了目标点但gpl.cc没有输出轨迹无人机原地悬停。原因障碍物点云太密把目标点也包进去了规划器认为目标不可达。或者planning_horizon设得太小目标点在视野外。解决检查 RViz 里目标点是否在障碍物膨胀范围内。如果是把obstacle_inflation从 0.3 降到 0.2或者把目标点往障碍物外侧挪 0.5 米。planning_horizon至少要是目标距离的 1.2 倍否则规划器看不到目标。4.5 实机飞行时轨迹跟踪滞后转弯切内道现象无人机在转弯时没有按规划轨迹走而是切了内道差点撞障碍物。原因控制模块的 PID 参数太软或者轨迹的时间分配不合理。Ego-planner 输出的 B 样条自带时间戳但如果控制模块没有按时间戳做前馈就会滞后。解决在控制模块里加前馈项把轨迹的速度和加速度直接叠加到 PID 输出上。常见做法是用traj.getVel(t)和traj.getAcc(t)取当前时刻的期望速度和加速度乘以一个前馈系数0.5 到 0.8加到控制量里。5. 进阶技巧用 CostFunctionFactory 定制 Robomaster 专属代价CostFunctionFactory.cc是这套框架里最值得深挖的文件。它把平滑、避障、目标逼近、动力学可行性拆成独立的代价项你可以按 Robomaster 的规则加自己的项。比如 Robomaster 无人机赛里攻击对方装甲板有角度要求你可以在代价函数里加一项「接近目标时的朝向惩罚」让无人机在逼近过程中自动调整机头方向。// 在 CostFunctionFactory.cc 里新增一个朝向代价项 class OrientationCost { public: OrientationCost(const Eigen::Vector3d target_dir, double weight) : target_dir_(target_dir), weight_(weight) {} template typename T bool operator()(const T* const pos, const T* const yaw, T* residual) const { // pos 是控制点位置yaw 是控制点对应的偏航角 T dx pos[0] - T(target_dir_.x()); T dy pos[1] - T(target_dir_.y()); T desired_yaw atan2(dy, dx); residual[0] T(weight_) * (yaw[0] - desired_yaw); return true; } private: Eigen::Vector3d target_dir_; double weight_; };这个代价项的逻辑是计算控制点到目标的方向角然后惩罚当前偏航角和期望方向角的差值。weight_控制朝向对齐的优先级Robomaster 里建议设 0.5 到 1.0太高会导致无人机为了对准目标而放弃避障。加完代价项后需要在CostFunctionFactory::createCostFunction里注册它并把yaw作为优化变量传进去。注意 Ego-planner 默认只优化位置控制点偏航角是单独规划的所以你要么把偏航角也加入 B 样条要么在轨迹后处理里单独算偏航。另一个进阶用法是动态调整obstacle_weight。当无人机距离目标小于 1 米时把obstacle_weight从 2.0 降到 1.0让无人机更激进地逼近目标当距离大于 3 米时恢复到 2.0 保证安全。这个逻辑可以写在gpl.cc的规划循环里每帧根据距离改参数。验证定制代价项是否生效最直接的方法是在 RViz 里看轨迹的朝向箭头。如果箭头在接近目标时逐渐转向目标方向说明代价项起作用了。另一个方法是录 bag用rqt_plot画yaw_error曲线看它是否收敛。从那以后我每次改CostFunctionFactory.cc都会先跑一遍仿真确认轨迹不撞、不抖、朝向对再上实机。实机第一次飞新代价项时一定把max_vel降到 1.0手动切一次紧急悬停确认遥控器能接管。希望帮到你。本文还有配套的精品资源点击获取