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. 爬虫2.3-scrapy框架-post、shell、验证码

    目录 scrapy框架-post请求和shell 1. post请求 2. scrapy shell 3. 验证码识别 scrapy框架-post请求和shell 1. post请求 scrapy框架 ...

  2. PytorchZerotoAll学习笔记(二)--梯度下降之手动求导

    梯度下降算法:    待优化的损失值为 loss,那么我们希望预测的值能够很接近真实的值 y_pred ≍ y_label      我们的样本有n个,那么损失值可以由一下公式计算得出: 要使得los ...

  3. PReLU——Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification

    1. 摘要 在 \(ReLU\) 的基础上作者提出了 \(PReLU\),在几乎没有增加额外参数的前提下既可以提升模型的拟合能力,又能减小过拟合风险. 针对 \(ReLU/PReLU\) 的矫正非线性 ...

  4. Pyhone学习之环境搭建

    一.python 环境搭建 本章节我们将向大家介绍如何在本地搭建Python开发环境.Python可应用于多平台包括 Linux 和 Mac OS X.你可以通过终端窗口输入 "python ...

  5. 第九次ScrumMeeting博客

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

  6. Python:迭代器的简单理解

    一.什么是迭代器 迭代,顾名思义就是重复做一些事很多次(就现在循环中做的那样).迭代器是实现了__next__()方法的对象(这个方法在调用时不需要任何参数),它是访问可迭代序列的一种方式,通常其从序 ...

  7. mysql---时间类型详解

    mysql 日期类型 mysql 日期类型    ·  DATE (适用于"出生日期"等只需要年月日数据的日期字段) 日期.支持的范围为'1000-01-01'到'9999-12- ...

  8. CoordinatdBolt原理分析

    参考链接:http://xumingming.sinaapp.com/811/twitter-storm-code-analysis-coordinated-bolt/ CoordinatedBolt ...

  9. 各种GIT代码托管工具比较

    bitbucket免费支持5个开发成员的团队创建无限私有代码托管库. GOES是一个由GO语音编写的自组GIT托管服务. gitorious 是一个基于GIT版本控制系统的WEB项目托管平台,基于RU ...

  10. bootstrap心得

    最近在弄个人的博客,之前对bootstrap的使用老是感觉使用的一般 幸好在看了慕课网的一个老师的实例教程之后,才感觉是真正对前端使用bootstrap有了一点理解 首先就是. 这些标签,其实都是相当 ...