base_local_planner

ROS wiki

Given a plan to follow and a costmap, the controller produces velocity commands to send to a mobile base.

他的功能是给一个global plan和local costmap,局部路径规划器计算出可行的速度发送给机器人

base_local_planner::TrajectoryPlanner provides implementations of the DWA and Trajectory Rollout

It should be possible to create custom local planners using the dwa_local_planner as template and just adding own cost functions or trajectory generators.

你可以参照DWA实现自己的局部规路径算法

算法主要是在局部的costmap中模拟计算沿着不同的方向进行定义的cost函数的大小,选择一个cost小的正的的方向前进。

主要是进行计算cost函数,每个cost可以有weight参数调整,这个可以算是灵活和也可以说是不稳定的因素(要自己调试)

  • ObstacleCostFunction
  • MapGridCostFunction
  • OscillationCostFunction
  • PreferForwardCostFunction

teb_local_planner

ROS wiki

优化轨迹执行的时间,与障碍物的距离,满足最大的速度与加速度的要求

Support of holonomic robots is included since Kinetic

parameter

参数分为一下几类(记住有些参数他在ros wiki里面是没有说明的,在代码里面有的,不是所有的参数都可以通过rqt_reconfigure配置的,有很少的一部分是不行的):

所有的参数你都可以在teb_config.h中找到初始值和含义

  • robot configuration

    跟机器人底盘是圆形,多边形,car-like有关,在后面的优化有用到,要设置正确

~<name>/max_vel_x_backwards (double, default: 0.2)
Maximum absolute translational velocity of the robot while driving backwards in meters/sec. See optimization parameter weight_kinematics_forward_drive
  • goal tolerance
~<name>/xy_goal_tolerance (double, default: 0.2) 

~<name>/yaw_goal_tolerance (double, default: 0.2)
#Remove the goal velocity constraint such that the robot can arrive at the goal with maximum speed
~<name>/free_goal_vel (bool, default: false)
  • trajectory configuration

# 轨迹的空间分辨率,只是一个参考值,真实的分辨率跟别的还有关
~<name>/dt_ref (double, default: 0.3)
  • obstacles
#距离障碍物的最短距离
~<name>/min_obstacle_dist (double, default: 0.5)
#Limit the occupied local costmap obstacles taken into account for planning behind the robot (specify distance in meters).
~<name>/costmap_obstacles_behind_robot_dist (double, default: 1.0) #障碍物会影响的pose的个数,
#bool legacy_obstacle_association; //!< If true, the old association strategy is used (for each obstacle, find the nearest TEB pose), otherwise the new one (for each teb pose, find only "relevant" obstacles).
~<name>/obstacle_poses_affected (int, default: 30)
  • optimization
#只允许前进的权重
~<name>/weight_kinematics_forward_drive (double, default: 1.0)
#远离障碍物至少min_obstacle_dist的权重
~<name>/weight_obstacle (double, default: 50.0)
#紧跟global plan的权重
~<name>/weight_viapoint (double, default: 1.0)
  • parallel planning in distinctive topologies
#允许并进计算,消耗更多的计算资源
~<name>/enable_homotopy_class_planning (bool, default: true)
~<name>/enable_multithreading (bool, default: true) #Specify how much trajectory cost must a new candidate have w.r.t. a previously selected trajectory in order to be selected (selection if new_cost < old_cost*factor).
~<name>/selection_cost_hysteresis (double, default: 1.0)
#Extra scaling of obstacle cost terms just for selecting the 'best' candidate.
~<name>/selection_obst_cost_scale (double, default: 100.0)
#Extra scaling of via-point cost terms just for selecting the 'best' candidate. New in version 0.4
~<name>/selection_viapoint_cost_scale (double, default: 1.0)
  • miscellaneous parameters

code


void TebLocalPlannerROS::initialize(std::string name, tf::TransformListener* tf, costmap_2d::Costmap2DROS* costmap_ros)
{
// create the planner instance
if (cfg_.hcp.enable_homotopy_class_planning)
{
planner_ = PlannerInterfacePtr(new HomotopyClassPlanner(cfg_, &obstacles_, robot_model, visualization_, &via_points_));
ROS_INFO("Parallel planning in distinctive topologies enabled.");
}
else
{
planner_ = PlannerInterfacePtr(new TebOptimalPlanner(cfg_, &obstacles_, robot_model, visualization_, &via_points_));
ROS_INFO("Parallel planning in distinctive topologies disabled.");
}
} bool TebLocalPlannerROS::computeVelocityCommands(geometry_msgs::Twist& cmd_vel)
{
// prune global plan to cut off parts of the past (spatially before the robot)
pruneGlobalPlan(*tf_, robot_pose, global_plan_); // Transform global plan to the frame of interest (w.r.t. the local costmap)
if (!transformGlobalPlan(*tf_, global_plan_, robot_pose, *costmap_, global_frame_, cfg_.trajectory.max_global_plan_lookahead_dist,
transformed_plan, &goal_idx, &tf_plan_to_global))
{
ROS_WARN("Could not transform the global plan to the frame of the controller");
return false;
} // check if we should enter any backup mode and apply settings
configureBackupModes(transformed_plan, goal_idx); updateObstacleContainerWithCostmap(); // Now perform the actual planning
bool success = planner_->plan(transformed_plan, &robot_vel_, cfg_.goal_tolerance.free_goal_vel); bool feasible = planner_->isTrajectoryFeasible(costmap_model_.get(), footprint_spec_, robot_inscribed_radius_, robot_circumscribed_radius, cfg_.trajectory.feasibility_check_no_poses); if (!planner_->getVelocityCommand(cmd_vel.linear.x, cmd_vel.linear.y, cmd_vel.angular.z)){ }
}
bool TebOptimalPlanner::plan(const std::vector<geometry_msgs::PoseStamped>& initial_plan, const geometry_msgs::Twist* start_vel, bool free_goal_vel)
{
if (!teb_.isInit()){
// init trajectory
teb_.initTEBtoGoal(initial_plan, cfg_->trajectory.dt_ref, cfg_->trajectory.global_plan_overwrite_orientation, cfg_->trajectory.min_samples, cfg_->trajectory.allow_init_with_backwards_motion);
}
else{
PoseSE2 start_(initial_plan.front().pose);
PoseSE2 goal_(initial_plan.back().pose);
if (teb_.sizePoses()>0 && (goal_.position() - teb_.BackPose().position()).norm() < cfg_->trajectory.force_reinit_new_goal_dist) // actual warm start!
teb_.updateAndPruneTEB(start_, goal_, cfg_->trajectory.min_samples); // update TEB
else // goal too far away -> reinit
{
ROS_DEBUG("New goal: distance to existing goal is higher than the specified threshold. Reinitalizing trajectories.");
teb_.clearTimedElasticBand();
teb_.initTEBtoGoal(initial_plan, cfg_->trajectory.dt_ref, true, cfg_->trajectory.min_samples, cfg_->trajectory.allow_init_with_backwards_motion);
}
} // now optimize
return optimizeTEB(cfg_->optim.no_inner_iterations, cfg_->optim.no_outer_iterations); } bool TebOptimalPlanner::optimizeTEB(int iterations_innerloop, int iterations_outerloop, bool compute_cost_afterwards,
double obst_cost_scale, double viapoint_cost_scale, bool alternative_time_cost)
{
for(int i=0; i<iterations_outerloop; ++i)
{
if (cfg_->trajectory.teb_autosize)
teb_.autoResize(cfg_->trajectory.dt_ref, cfg_->trajectory.dt_hysteresis, cfg_->trajectory.min_samples, cfg_->trajectory.max_samples); //构建图
success = buildGraph(weight_multiplier);
if (!success)
{
clearGraph();
return false;
}
//优化图
success = optimizeGraph(iterations_innerloop, false);
if (!success)
{
clearGraph();
return false;
} if (compute_cost_afterwards && i==iterations_outerloop-1) // compute cost vec only in the last iteration
computeCurrentCost(obst_cost_scale, viapoint_cost_scale, alternative_time_cost); clearGraph(); weight_multiplier *= cfg_->optim.weight_adapt_factor; }
} bool TebOptimalPlanner::buildGraph(double weight_multiplier)
{
// add TEB vertices
AddTEBVertices(); // add Edges (local cost functions)
if (cfg_->obstacles.legacy_obstacle_association)
AddEdgesObstaclesLegacy(weight_multiplier);
else
AddEdgesObstacles(weight_multiplier); //AddEdgesDynamicObstacles(); AddEdgesViaPoints(); AddEdgesVelocity(); AddEdgesAcceleration(); AddEdgesTimeOptimal(); if (cfg_->robot.min_turning_radius == 0 || cfg_->optim.weight_kinematics_turning_radius == 0)
AddEdgesKinematicsDiffDrive(); // we have a differential drive robot
else
AddEdgesKinematicsCarlike(); // we have a carlike robot since the turning radius is bounded from below. AddEdgesPreferRotDir(); } bool TebOptimalPlanner::optimizeGraph(int no_iterations,bool clear_after)
{
if (cfg_->robot.max_vel_x<0.01)
{
ROS_WARN("optimizeGraph(): Robot Max Velocity is smaller than 0.01m/s. Optimizing aborted...");
if (clear_after) clearGraph();
return false;
} if (!teb_.isInit() || teb_.sizePoses() < cfg_->trajectory.min_samples)
{
ROS_WARN("optimizeGraph(): TEB is empty or has too less elements. Skipping optimization.");
if (clear_after) clearGraph();
return false;
} // boost::shared_ptr<g2o::SparseOptimizer> optimizer_; //!< g2o optimizer for trajectory optimization
optimizer_->setVerbose(cfg_->optim.optimization_verbose);
optimizer_->initializeOptimization(); int iter = optimizer_->optimize(no_iterations); if(!iter)
{
ROS_ERROR("optimizeGraph(): Optimization failed! iter=%i", iter);
return false;
} if (clear_after) clearGraph();
}

g2o

boost::shared_ptr<g2o::SparseOptimizer> TebOptimalPlanner::initOptimizer()
{
// Call register_g2o_types once, even for multiple TebOptimalPlanner instances (thread-safe)
static boost::once_flag flag = BOOST_ONCE_INIT;
boost::call_once(&registerG2OTypes, flag); // allocating the optimizer
boost::shared_ptr<g2o::SparseOptimizer> optimizer = boost::make_shared<g2o::SparseOptimizer>();
//typedef g2o::LinearSolverCSparse<TEBBlockSolver::PoseMatrixType> TEBLinearSolver;
TEBLinearSolver* linearSolver = new TEBLinearSolver(); // see typedef in optimization.h
linearSolver->setBlockOrdering(true);
//typedef g2o::BlockSolver< g2o::BlockSolverTraits<-1, -1> > TEBBlockSolver;
TEBBlockSolver* blockSolver = new TEBBlockSolver(linearSolver);
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(blockSolver); optimizer->setAlgorithm(solver); optimizer->initMultiThreading(); // required for >Eigen 3.1 return optimizer;
}

move_base的 局部路径规划代码研究的更多相关文章

  1. move_base的全局路径规划代码研究

    algorithmn parameter code 主要是以下三个函数 计算所有的可行点 怎么计算一个点的可行点 从可行点中计算路径path todo algorithmn 算法的解释 Dijkstr ...

  2. DWA局部路径规划算法论文阅读:The Dynamic Window Approach to Collision Avoidance。

    DWA(动态窗口)算法是用于局部路径规划的算法,已经在ROS中实现,在move_base堆栈中:http://wiki.ros.org/dwa_local_planner DWA算法第一次提出应该是1 ...

  3. ros局部路径规划-DWA学习

    ROS的路径规划器分为全局路径和局部路径规划,其中局部路径规划器使用的最广的为dwa,个人理解为: 首先全局路径规划会生成一条大致的全局路径,局部路径规划器会把全局路径给分段,然后根据分段的全局路径的 ...

  4. ROS源码解读(一)--局部路径规划

    博客转载自:https://blog.csdn.net/xmy306538517/article/details/78772066 ROS局部路径导航包括Trajectory Rollout 和 Dy ...

  5. ROS机器人路径规划介绍--全局规划

    ROS机器人路径规划算法主要包括2个部分:1)全局路径规划算法:2)局部路径规划算法: 一.全局路径规划 global planner ROS 的navigation官方功能包提供了三种全局路径规划器 ...

  6. 路径规划: PRM 路径规划算法 (Probabilistic Roadmaps 随机路标图)

    随机路标图-Probabilistic Roadmaps (路径规划算法) 路径规划作为机器人完成各种任务的基础,一直是研究的热点.研究人员提出了许多规划方法如: 1. A* 2. Djstar 3. ...

  7. ROS探索总结(十四)——move_base(路径规划)

    在上一篇的博客中,我们一起学习了ROS定位于导航的总体框架,这一篇我们主要研究其中最重要的move_base包. 在总体框架图中可以看到,move_base提供了ROS导航的配置.运行.交互接口,它主 ...

  8. 【路径规划】 Optimal Trajectory Generation for Dynamic Street Scenarios in a Frenet Frame (附python代码实例)

    参考与前言 2010年,论文 Optimal Trajectory Generation for Dynamic Street Scenarios in a Frenet Frame 地址:https ...

  9. V-rep学习笔记:机器人路径规划1

     Motion Planning Library V-REP 从3.3.0开始,使用运动规划库OMPL作为插件,通过调用API的方式代替以前的方法进行运动规划(The old path/motion ...

随机推荐

  1. JSP整理

    JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%>结束. JSP是一种Java servlet ...

  2. CSP201609-2:火车购票

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  3. JAVA学习笔记--组合与继承

    JAVA一个很重要的功能就是代码的可复用性,代码复用可以大大提升编程效率.这里主要介绍两种代码复用方式:组合和继承. 一.组合 组合比较直观,只需在新的类中产生现有类的对象,新的类由现有类的对象组成, ...

  4. 第九次ScrumMeeting博客

    第九次ScrumMeeting博客 本次会议于11月4日(六)22时整在3公寓725房间召开,持续20分钟. 与会人员:刘畅.辛德泰.窦鑫泽.张安澜.赵奕.方科栋. 1. 每个人的工作(有Issue的 ...

  5. USACO 1.3.3 Calf Flac(Manacher算法)

    Description 据说如果你给无限只母牛和无限台巨型便携式电脑(有非常大的键盘),那么母牛们会制造出世上最棒的回文.你的工作就是去寻找这些牛制造的奇观(最棒的回文). 在寻找回文时不用理睬那些标 ...

  6. Alpha发布用户使用报告

    此作业要求参见:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2325] 组名:可以低头,但没必要 组长:付佳 组员:张俊余 李文涛 孙 ...

  7. 冲刺ing-2

    第二次Scrum冲刺 队员完成的任务 队员 完成任务 吴伟华 分配任务 蔺皓雯 编写博客,查阅资料 蔡晨旸 查阅资料 曾茜 暂无 鲁婧楠 暂无 杨池宇 暂无 成员遇到的问题 队员 问题 吴伟华 暂无 ...

  8. YQCB冲刺周第一天

    团队讨论的照片 任务看板为 今天小组成员讨论了每个页面的排版,每个页面的跳转,以及页面的排版. 今天准备编写登录界面的.注册界面的代码. 遇到的困难是用户记账时选择的分类标准很多,最后将其整合,删减.

  9. 关于cnblog.com的用户体验

    首先我自己目前是一个学生党,每天在博客园上就上发布一些自己做的东西以及老师布置的作业,还能在上面学习很多别人的一些好的列子,我就希望博客园能够很好地为我们这些学生服务,当我们用它时能够很好地达到我们的 ...

  10. python 动态获取当前运行的类名和函数名的方法

    一.使用内置方法和修饰器方法获取类名.函数名 python中获取函数名的情况分为内部.外部,从外部的情况好获取,使用指向函数的对象,然后用__name__属性 复制代码代码如下: def a():pa ...