参考文章:
(31条消息) ROS导航小车1 teb_local_planner参数(仅作记录/收集)_teb local planner参数_Crush Mome的博客-CSDN博客
运行导航:
1. 启动底盘控制包 :
base_conctronl
2.启动键盘控制节点:
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
3.机器人端启动雷达扫描建图:
roslaunch robot_navigation robot_slam_laser.launch
4.PC端启动Rviz视图
roslaunch robot_navigation slam_rviz.launch
5. 进入地图包内保存包
roscd robot_navigation/maps #进包
rosrun map_server map_saver -f map #保存地图,命名为map
6. 启动雷达导航:
roslaunch robot_navigation robot_navigation.launch
7. Rviz导航视图:
roslaunch robot_navigation navigation_rviz.launch
一、move_base.launch
<launch>
<!-- Arguments -->
<arg name="cmd_vel_topic" default="cmd_vel" /> # 话题控制
<arg name="odom_topic" default="odom" /> # 里程计
<arg name="planner" default="dwa" doc="opt: dwa, teb"/> # 导航
<arg name="simulation" default= "false"/> # 仿真
<arg name="use_dijkstra" default= "true"/>
<arg name="base_type" default= "$(env BASE_TYPE)"/>
<arg name="move_forward_only" default="false"/>
<!-- move_base use DWA planner-->
<group if="$(eval planner == 'dwa')">
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<!-- use global_planner replace default navfn as global planner ,global_planner support A* and dijkstra algorithm-->
<param name="base_global_planner" value="global_planner/GlobalPlanner"/>
<param name="base_local_planner" value="dwa_local_planner/DWAPlannerROS" />
<!-- <rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/global_planner_params.yaml" command="load" /> -->
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/local_costmap_params.yaml" command="load" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/global_costmap_params.yaml" command="load" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/move_base_params.yaml" command="load" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/dwa_local_planner_params.yaml" command="load" />
<remap from="cmd_vel" to="$(arg cmd_vel_topic)"/>
<remap from="odom" to="$(arg odom_topic)"/>
<param name="DWAPlannerROS/min_vel_x" value="0.0" if="$(arg move_forward_only)" />
<!--default is True,use dijkstra algorithm;set to False,usd A* algorithm-->
<param name="GlobalPlanner/use_dijkstra " value="$(arg use_dijkstra)" />
</node>
</group>
<!-- move_base use TEB planner-->
<group if="$(eval planner == 'teb')">
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<!-- use global_planner replace default navfn as global planner ,global_planner support A* and dijkstra algorithm-->
<param name="base_global_planner" value="global_planner/GlobalPlanner"/>
<param name="base_local_planner" value="teb_local_planner/TebLocalPlannerROS" />
<!-- <rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/global_planner_params.yaml" command="load" /> -->
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/local_costmap_params.yaml" command="load" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/global_costmap_params.yaml" command="load" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/move_base_params.yaml" command="load" />
<rosparam file="$(find robot_navigation)/param/$(env BASE_TYPE)/teb_local_planner_params.yaml" command="load" />
<remap from="cmd_vel" to="$(arg cmd_vel_topic)"/>
<remap from="odom" to="$(arg odom_topic)"/>
<param name="TebLocalPlannerROS/max_vel_x_backwards" value="0.0" if="$(arg move_forward_only)" />
<!--default is True,use dijkstra algorithm;set to False,usd A* algorithm-->
<param name="GlobalPlanner/use_dijkstra " value="$(arg use_dijkstra)" />
<!--stage simulator takes the angle instead of the rotvel as input (twist message)-->
</node>
</group>
<!-- move_base -->
</launch>
1. teb_local_planner_params.yaml
此文件为TEB(NanoCar默认使用的路径规划算法)参数,参数详细如下:
TebLocalPlannerROS: # TEB局部路径规划
odom_topic: odom #使用里程计坐标
# Trajectory
teb_autosize: True #优化期间允许改变轨迹时域长度
dt_ref: 0.3 #局部路径规划解析度(0.01~1.0) 默认为0.3
dt_hysteresis: 0.1 #允许浮动范围
max_samples: 500
global_plan_overwrite_orientation: True #覆盖全局路径中局部路点朝向
allow_init_with_backwards_motion: True #允许开始后退回原来的执行的轨迹
max_global_plan_lookahead_dist: 3.0 #全局优化子集最大长度
global_plan_viapoint_sep: -1 #从全局计划中提取的每两个连续通过的点的最小间隔
global_plan_prune_distance: 1
exact_arc_length: False # ture则使用精确弧长
feasibility_check_no_poses: 2 # 检测位姿可达到的时间间隔
publish_feedback: False # 发布包含完整轨迹和障碍物
# Robotvb
max_vel_x: 0.8 # 最大前进速度 x
max_vel_x_backwards: 0.2 #最大后退速度 x
max_vel_y: 0.0 # y方向最大速度 阿克曼形是没有的
max_vel_theta: 0.53 # the angular velocity is also bounded by min_turning_radius in case of a carlike robot (r = v / omega) 最大转向角速度
acc_lim_x: 0.5 # 最大加速度
acc_lim_theta: 0.5 #最大角加速度
# ********************** Carlike robot parameters ********************
min_turning_radius: 0.375 # Min turning radius of the carlike robot (compute value using a model or adjust with rqt_reconfigure manually)——最小转弯半径
wheelbase: 0.145 # Wheelbase of our robot——驱动轴与转向轴之间的距离
cmd_angle_instead_rotvel: False # stage simulator takes the angle instead of the rotvel as input (twist message) —— 将收到的消息转化为操作
# ********************************************************************
footprint_model: # types: "point", "circular", "two_circles", "line", "polygon"
type: "line" # 设置机器人模型——可以为上面几种
line_start: [0.05, 0.0] # for type "line" #线的起点
line_end: [0.10, 0.0] # for type "line" #线的终点
# GoalTolerance
xy_goal_tolerance: 0.1 #xy目标偏移度
yaw_goal_tolerance: 0.2 #目标角度偏移容忍度
free_goal_vel: False #允许机器人以最大速度前往目的地,我们可以直接打开,然后设置一下我们上面的速度
complete_global_plan: True #完成目标点
# Obstacles
min_obstacle_dist: 0.12 # 与障碍物最小距离——与线
inflation_dist: 0.6 # 障碍物膨胀距离
include_costmap_obstacles: True # 局部地图中的障碍物是否考虑
costmap_obstacles_behind_robot_dist: 1.5
obstacle_poses_affected: 15
dynamic_obstacle_inflation_dist: 0.6 #动态障碍物膨胀范围
include_dynamic_obstacles: True #是否将为速度模型
costmap_converter_plugin: ""
costmap_converter_spin_thread: True
costmap_converter_rate: 5
# Optimization
no_inner_iterations: 5 # 被外循环调用后内循环执行次数
no_outer_iterations: 4 # 执行外循环优化次数
optimization_activate: True # 激活优化过程
optimization_verbose: False # 打印优化过程
penalty_epsilon: 0.1 # 对硬约束近似
obstacle_cost_exponent: 4
weight_max_vel_x: 2 # 最大速度权重
weight_max_vel_theta: 1 # 最大角速度权重
weight_acc_lim_x: 1 # 最大加速度权重
weight_acc_lim_theta: 1 # 最大角速度权重
weight_kinematics_nh: 1000
weight_kinematics_forward_drive: 1
weight_kinematics_turning_radius: 1
weight_optimaltime: 1 # must be > 0
weight_shortest_path: 0
weight_obstacle: 100 # 优化过程中和障碍物最小距离权重
weight_inflation: 0.2 # 膨胀区域权重
weight_dynamic_obstacle: 10 # 动态障碍物最小距离权重
weight_dynamic_obstacle_inflation: 0.2 # 动态障碍物膨胀区域权重
weight_viapoint: 1 #路径采样点距离权重
weight_adapt_factor: 2
# Homotopy Class Planner
enable_homotopy_class_planning: False
enable_multithreading: True # 允许多线程
max_number_classes: 4 # 允许线程数
selection_cost_hysteresis: 1.0 #
selection_prefer_initial_plan: 0.95
selection_obst_cost_scale: 1.0
selection_alternative_time_cost: False
roadmap_graph_no_samples: 15
roadmap_graph_area_width: 5
roadmap_graph_area_length_scale: 1.0
h_signature_prescaler: 0.5
h_signature_threshold: 0.1
obstacle_heading_threshold: 0.45
switching_blocking_period: 0.0
viapoints_all_candidates: True
delete_detours_backwards: True
max_ratio_detours_duration_best_duration: 3.0
visualize_hc_graph: False
visualize_with_time_as_z_axis_scale: False
# Recovery
shrink_horizon_backup: True # 规划检测系统异常,允许缩小时域规划范围
shrink_horizon_min_duration: 10
oscillation_recovery: False
oscillation_v_eps: 0.1
oscillation_omega_eps: 0.1
oscillation_recovery_min_duration: 10
oscillation_filter_duration: 10
2. move_base_params.yaml
此为 move_base 节点自身参数,也是控制其他参数的基本
controller_frequency: 2.0 # 底盘发送数据
controller_patience: 15.0 # 控制器有效控制下发时间
planner_frequency: 0.2 # 全局规划执行频率
planner_patience: 5.0 # 留给规划期寻找路径的时间
conservative_reset_dist: 3.0 #
oscillation_timeout: 10.0 # 允许震荡时间
oscillation_distance: 0.2 # 移动多远才能发送不摆动
clearing_rotation_allowed: false # 是否使用恢复模块
3. local_costmap_params.yaml
local_costmap: #局部代价地图
global_frame: map # 代价图的世界坐标系
robot_base_frame: base_footprint # 机器人局部坐标
update_frequency: 5.0 # 代价地图更新频率
publish_frequency: 5.0 # 代价地图发布频率
rolling_window: true # 是否使用动态窗口
width: 3 # 代价地图宽度
height: 3 # 代价地图宽度
resolution: 0.05 #精度
transform_tolerance: 0.5 #等待超时时间
plugins: # 固定使用,地图序列
- {name: static_layer, type: "costmap_2d::StaticLayer"}
- {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"}
4. global_costmap_params.yaml
global_costmap: # 全局代价地图
global_frame: map # 地图名
robot_base_frame: base_footprint #机器人底部坐标系
update_frequency: 1.0 # 代价地图更新频率
publish_frequency: 0.5 # 发布频率
# static_map: true #设置为静态地图
transform_tolerance: 0.5 #等待超时时间
plugins:
- {name: static_layer, type: "costmap_2d::StaticLayer"}
- {name: obstacle_layer, type: "costmap_2d::VoxelLayer"}
- {name: inflation_layer, type: "costmap_2d::InflationLayer"}
5. costmap_common_params.yaml
footprint: [ [-0.035,-0.1], [0.18,-0.1], [0.18,0.1], [-0.035,0.1] ] #机器人占有面积
transform_tolerance: 0.2 # 等待坐标发布超时时间
obstacle_layer: # 障碍层
enabled: true
obstacle_range: 2.5 #放入代价地图的距离
raytrace_range: 3.0 #清除代价地图的距离
inflation_radius: 0.05 #膨胀半径
track_unknown_space: false
combination_method: 1
observation_sources: laser_scan_sensor #传感器参数源:雷达
laser_scan_sensor: {data_type: LaserScan, topic: scan, marking: true, clearing: true}
#设置源消息 消息类型 发布话题 障碍物消息 是否清除障碍物消息
inflation_layer: #膨胀层
enabled: true #使能
cost_scaling_factor: 10.0 # 代价比例 越大价值越小(default: 10)
inflation_radius: 0.1 # 膨胀半径
static_layer: #静态层
enabled: true
map_topic: "/map" #话题名
关于参数的修改意见:
目前版本,我们使用的是Jetson nano阿克曼系列,我们使用的是基础版,所以我们测速时最大速度应该为1.5m,我们设置为0.8m进行测试。
TEB规划器的性能问题的总结参考
· 关闭多路径并行规划(效果非常显著)
· 使用Costmap Converter (非常显著)
· 降低迭代次数(no_inner/outer_iterations) (显著)
· 降低 max_lookahead_distance (一般)
· 减小局部耗费地图的大小 (显著)
· 增大规划周期和控制周期 (影响效果)
· 使用单点footprint,配合最小障碍物距离约束 (不太显著且影响效果)
我们主要参照的时teb.yaml这个参数表,可以直接影响我们的速度。
dt_ref 局部路径规划的解析度(默认0.3)
dt_hysteresis 允许改变的时域解析度的浮动范围, 一般为 dt_ref 的 10% 左右(默认0.1)
dt_ref和dt_hysteresis 最优路径上的两个相邻姿态(即位置、速度、航向信息,可通过TEB可视化在rivz中看到)的默认距离。
此距离不固定,规划器自动根据速度大小调整这一距离,速度越大,相邻距离自然越大。
global_plan_overwrite_orientation 覆盖全局路径中局部路径点的朝向,有些全局规划者在开始和全局目标之间没有考虑局部子目标的方向,因此自动确定
在我们的示例中,我们是开启的,为了寻找多条到达目的的路线,虽然这样可以减小我们的碰撞,但是会减小我们的速度,对于车辆的2D规划,可以设置为False,可实现对全局路径的更好跟踪。
max_global_plan_lookahead_dist
考虑优化的全局计划子集的最大长度(累积欧几里得距离)(如果为0或负数:禁用;长度也受本地Costmap大小的限制),默认3.0
该参数决定局部规划初始轨迹的最大长度,实际调试发现此参数无需过大,因为局部轨迹在每个控制周期都被更新,实际执行的指令仅是轨迹上第一个点的速度值,这里设置为1.5(默认3.0)即可,过长也可能导致优化结果无法有效收敛。 我们在示例中将他改小。
要求:1.应随车辆最大速度的增大而增大 2.不应超过激光雷达等传感器的可靠测量范围 3. 不应超过局部耗费地图的大小,即不能要求TEB对局部耗费地图以外的部分进行规划。
feasibility_check_no_poses 检测位姿可到达的时间间隔
在判断生成的轨迹是否冲突时使用,此时设置为3,即从轨迹起点开始逐个检查轨迹上的3个点,若3个点均不发生碰撞,则认为本次轨迹有效,由于teb优化并非硬约束,这里相当于是轨迹生成之后的一层保障,这个参数因根据机器人的速度和环境复杂程度调整,否则极有可能出现在狭窄环境中走走停停的情况。
max_vel_x acc_lim_x x轴方向速度与加速度约束
max_vel_y acc_lim_y y轴方向速度与加速度约束
max_vel_x_backwards 最大倒车速度
阿克曼的y是为0的,x的最大速度我们上面说过,设置为1,加速度我们可以设置为0.3.
注意加速度同样约束减速过程。若电机性能良好且速度不快可以立即刹车,可直接将acc_lim_x设置为0,表示没有约束。若电机不能承受阶跃输入或者响应时间很长,则应当设置加速度限制.
禁止倒车应在penalty部分将前向行驶的权重设置得极高,但是我们是不需要禁止的。
GoalTolerance 参数设置机器人停止运行的容差
xy_goal_tolerance和yaw_goal_tolerance 目标跟踪误差
根据车辆运行精度设置。例如,笔者使用一台攀爬RC车构建导航系统,这种车辆转向间隙特性很大,则不应设置严格的航向限制
free_goal_vel 自由目标速度
在竞速的部分,我们可以在参数里直接置为True,让小车全速前进
Obstacles 参数用于对环境中障碍物的处理方式,体现在轨迹优化阶段
costmap_converter_plugin 是否使用costmap_converter插件 若设置为空字符,则视为禁用转换
costmap_converter插件的作用是将障碍物预先表示成线段或多边形的形式,可以在一定程度上减轻后续计算距离的压力,具体见costmap_converter - ROS Wiki
include_costmap_obstacles 必须设置为True后才能规避实时探测到的、建图时不存在的障碍物。
这个是我们必须要打开的
min_obstacle_dist 最小障碍物距离
增大min_obstacle_dist可以防止机器人离墙太近,但是对于狭窄通道的情况,反而应该设置的很小。这三个参数的设置非常重要,需要根据机器人的外形尺寸小心调整,否则极易出现狭窄空间机器人无法通过或优化不收敛的情况。
inflation_dist 障碍物膨胀距离
默认0.0 障碍物膨胀距离。这个值必须大于min_obstacle_dist才有效。源码在AddEdgesObstacles. 此膨胀只是降低通过这些区域的优先级,不应当用此距离迫使车辆远离障碍物。障碍物周边的缓冲区,零惩罚代价,缓冲区会导致规划器减速,我们设置为0.6
costmap_obstacles_behind_robot_dist double 限制在机器人后面规划时考虑到的占用的本地成本图障碍(指定距离,单位为米)
obstacle_poses_affected int 障碍物位置与轨迹上最接近的姿态相连,以减少计算量,但同时也考虑了许多相邻的障碍物
https://www.jianshu.com/p/a0f1d93f5179
Optimization 参数主要是设置优化框架中各部分的权重大小
我们在这给出参考链接
no_inner_iterations int 被外循环调用后内循环执行优化次数 1 5 100
no_outer_iterations int 执行的外循环的优化次数 1 4 100
optimization_activate bool 激活优化 False True True
optimization_verbose bool 打印优化过程详情 False False True
penalty_epsilon double 对于硬约束近似,在惩罚函数中添加安全范围 0.0 0.1 1.0
weight_max_vel_x double 最大x速度权重 0.0 2.0 1000.0
weight_max_vel_y double 最大y速度权重 0.0 2.0 1000.0
weight_max_vel_theta double 最大加速度权重 0.0 1.0 1000.0
weight_acc_lim_x double 最大x 加速度权重 0.0 1.0 1000.0
weight_acc_lim_y double 最大y 加速度权重 0.0 1.0 1000.0
weight_acc_lim_theta double 最大角速度权重 0.0 1.0 1000.0
weight_kinematics_nh double 满足非完整运动学的优化权值 0.0 1000.0 10000.0
weight_kinematics_forward_drive double 优化过程中,迫使机器人只选择前进方向,差速轮适用 0.0 1.0 1000.0
weight_kinematics_turning_radius double 优化过程中,车型机器人的最小转弯半径的权重 0.0 1.0 1000.0
weight_optimaltime double 优化过程中,基于轨迹的时间上的权重 0.0 1.0 1000.0
weight_obstacle double 优化过程中,和障碍物最小距离的权重 0.0 50.0 1000.0
no_inner_iterations: 5 图优化optimizer的迭代次数
no_outer_iterations: 4 每次外部循环迭代都会根据所需的时间分辨率dt_ref自动调整轨迹的大小,并调用内部优化器
penalty_epsilon 0.1 一次性改变所有的惩罚项,为惩罚函数增加一个小的安全余量,以实现硬约束近似. 例如为速度的约束提供一个缓冲的效果,在到达速度限制前会产生一定的惩罚,让其提前减速达到缓冲的效果
weight_obstacle 默认值:50.0. 优化权重以保持与障碍物的最小距离。可以增大至几百,让机器人提前转向,避免卡死
obstacle_cost_exponent 无默认值,目前设置为0.65. 源码在EdgeObstacle::computeError和EdgeInflatedObstacle::computeError,判断是否为1,同时min_obstacle_dist > 0才有效。用于更新g2o的误差函数
weight_kinematics_nh 默认值:1000. 用于满足非完整运动学的优化权重. 该参数必须很高,因为运动学方程构成了一个等式约束,即使值1000也不意味着由于与其他成本相比较小的“原始”成本值而导致的矩阵条件不佳