move_base源码没有获取机器人当前位姿的地方,这属于局部路径算法的范畴。只能获得全局目标的位姿
bool MoveBase::makePlan(const geometry_msgs::PoseStamped& goal, vector& plan)
此函数只在一个地方被调用,就是planThread()
线程被唤醒之后开始规划路径1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22boost::unique_lock<costmap_2d::Costmap2D::mutex_t> lock(*(planner_costmap_ros_->getCostmap()->getMutex() ));
plan.clear();
if(planner_costmap_ros_ == NULL) {
log.error("Planner costmap ROS is NULL, unable to create global plan");
return false;
}
//get the starting pose of the robot
tf::Stamped<tf::Pose> global_pose;
if(!planner_costmap_ros_->getRobotPose(global_pose)) {
log.warn("Unable to get starting pose of robot, unable to create global plan");
return false;
}
geometry_msgs::PoseStamped start;
tf::poseStampedTFToMsg(global_pose, start);
// 这里就是 GlobalPlanner::makePlan 了
if(!planner_->makePlan(start, goal, plan) || plan.empty()){
ROS_WARN("[move_base] Failed to find a plan to point (%.2f, %.2f)",
goal.pose.position.x, goal.pose.position.y);
return false;
}
return true;
代码并不复杂, 最后实际就进入bool GlobalPlanner::makePlan(const geometry_msgs::PoseStamped& start, const geometry_msgs::PoseStamped& goal, double tolerance, std::vector<geometry_msgs::PoseStamped>& plan)
这里要参考全局路径规划(二) makePlan
MoveBase::planService(nav_msgs::GetPlan::Request &req, nav_msgs::GetPlan::Response &resp)
req参数包含了起点和目标信息,这个服务回调函数的的核心是planner_->makePlan
move_base server必须在inactive状态,否则不向下执行
判断
global planner
的costmap是否存在;若req给定机器人初始位姿则使用,否则使用getRobotPose
获得机器人所在位置做初始位姿调用
clearCostmapWindows
完成对机器人区域的clear, clear_radius由参数设置调用
if(!planner_->makePlan(start, req.goal, global_plan) || global_plan.empty())
这是完成plan计算的核心部分。判断这个调用是否成功,如果失败,则在目标区域附近搜索,多次更改req.goal的值,并重新调用makePlan;新的goal如下图:
各个可能位置之间的水平和竖直间距和req.tolerance
正相关
如果还是失败,则此次路径规划无解。如果成功,直接break循环,把原来无法达到的目标点插入global_plan
容器的最后,local planner
一般会从新的目标点导航到原目标点.
- 将
global_plan
拷贝到resp.plan
MoveBase::clearCostmapWindows(double size_x, double size_y)
planService·
用到了clearCostmapWindows
函数,它只被调用了这一次,过程如下:
- 通过
planner_costmap_ros_->getRobotPose(global_pose);
获取在全局地图的global_pose 以这个点为中心,找到以size_x和size_y为边长的矩形的四个顶点
调用planner_costmap_ros_->getCostmap()->setConvexPolygonCost(clear_poly, costmap_2d::FREE_SPACE);
完成对机器人所在区域的clear工作以上同样的操作在
controller_costmap_ros
上也操作一遍,这样globa costmap 和local costmap都已经在机器人所在的区域完成clear工作