ROS学习记录17SLAM仿真学习6完结—— 无人驾驶

Posted 康娜喵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ROS学习记录17SLAM仿真学习6完结—— 无人驾驶相关的知识,希望对你有一定的参考价值。

零.前言

这次使用Move_Base框架配置配置,就能实现自主导航了。仿真篇结束,后面找机会拿个实物来玩儿。
在整理包,后面会传到githubgitee

一.安装与介绍

1.1 move_base

安装sudo apt-get install ros-noetic-move-base

框架是这样,我们只需要配置

  • 定位: amcl
  • 路径规划:局部与全局。其中,局部我们使用符合阿克曼模型的teb_local_planner
  • 地图:map_server,来创建代价地图
  • 里程计:odom已经配置

1.2 amcl

安装:sudo apt-get install ros-noetic-move-base
amcl是adaptive Monte Carlo Localization,即适应蒙特卡洛定位,也就是我们概率论学的那个思想一样。就不多解释了,因为解释起来篇幅太长。
具体可看:http://wiki.ros.org/amcl?distro=noetic

1.3 teb_local_planner

安装sudo apt-get install ros-noetic-teb_local_planner
对于这个路径规划的原理可以看:http://wiki.ros.org/teb_local_planner

二.配置

先创建一个包:catkin_create_pkg slam_nav roscpp
然后在下面创建ros_ws/src/slam_nav/param文件夹,并写入以下配置

2.1 costmap_common_params.yaml

只需要改一处,雷达的话题即可

obstacle_range: 2.5 #只有障碍物在这个范围内才会被标记
raytrace_range: 3.0 ##只有在这个范围内不存在的才会被消除
robot_radius: 0.2
inflation_radius: 0.2 #膨胀半径

transform_tolerance: 0.5

observation_sources: scan

scan: 
  data_type: LaserScan 
  topic: /ackman/laser/scan #改为你的雷达发布话题
  marking: true 
  clearing: true

map_type: costmap

2.2 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
  cost_scaling_factor: 10.0
  inflation_radius: 0.25  

2.3 local_costmap_params.yaml

local_costmap:
  global_frame: map
  robot_base_frame: base_footprint
  update_frequency: 5.0
  publish_frequency: 2.0
  static_map: false
  rolling_window: true
  width: 5
  height: 5
  resolution: 0.05
  transform_tolerance: 0.5
  cost_scaling_factor: 5
  inflation_radius: 0.25

2.4 move_base_params.yaml

shutdown_costmaps: false #当move_base在不活动状态时,是否关掉costmap

controller_frequency: 5.0 #向底盘控制移动话题cmd_vel发送命令的频率.
controller_patience: 3.0

planner_frequency: 0.5
planner_patience: 5.0

#机器人必须移动多远(以米计)才能被视为不摆动。
#如果出现摆动则说明全局规划失败,那么将在超时后执行恢复模块
oscillation_timeout: 10.0
oscillation_distance: 0.1

conservative_reset_dist: 0.1

2.5 teb_local_planner_params.yaml

必须修改的地方:

  • min_turning_radius: # 最小转弯半径 注意车辆运动学中心是后轮中点

  • wheelbase: # 即前后轮距离

  • line_start、line_end # 此处用把小车抽象为一个线段模型,具体可参考:http://wiki.ros.org/teb_local_planner/Tutorials/Obstacle%20Avoidance%20and%20Robot%20Footprint%20Model

TebLocalPlannerROS:

  odom_topic: odom
  map_frame: /odom
      
  # Trajectoty 这部分主要是用于调整轨迹

  teb_autosize: True #优化期间允许改变轨迹的时域长度
  dt_ref: 0.3 #期望的轨迹时间分辨率
  dt_hysteresis: 0.03 #根据当前时间分辨率自动调整大小的滞后现象,通常约为。建议使用dt ref的10%
  
  #覆盖全局规划器提供的局部子目标的方向;规划局部路径时会覆盖掉全局路径点的方位角,
  #对于车辆的2D规划,可以设置为False,可实现对全局路径的更好跟踪。
  global_plan_overwrite_orientation: True

#指定考虑优化的全局计划子集的最大长度,如果为0或负数:禁用;长度也受本地Costmap大小的限制
  max_global_plan_lookahead_dist: 3.0 

  feasibility_check_no_poses: 1 #检测位姿可到达的时间间隔,default:4
    
  #如果为true,则在目标落后于起点的情况下,可以使用向后运动来初始化基础轨迹
  #(仅在机器人配备了后部传感器的情况下才建议这样做)
  allow_init_with_backwards_motion: False

  global_plan_viapoint_sep: -1

  #参数在TebLocalPlannerROS::pruneGlobalPlan()函数中被使用
  #该参数决定了从机器人当前位置的后面一定距离开始裁剪
  #就是把机器人走过的全局路线给裁剪掉,因为已经过去了没有比较再参与计算后面的局部规划
  global_plan_prune_distance: 1

  exact_arc_length: False
  publish_feedback: False

  # Robot
  max_vel_x: 10
  max_vel_x_backwards: 1
  max_vel_theta: 5
  acc_lim_x: 10
  acc_lim_theta: 5

  #仅适用于全向轮
  # max_vel_y (double, default: 0.0)  
  # acc_lim_y (double, default: 0.5)

  # ********************** Carlike robot parameters ********************
  min_turning_radius: 0.9       # 最小转弯半径 注意车辆运动学中心是后轮中点
  wheelbase: 0.6               # 即前后轮距离

#设置为true时,ROS话题(rostopic) cmd_vel/angular/z 内的数据是舵机角度,
  cmd_angle_instead_rotvel: True 
  # ********************************************************************

  footprint_model: # types: "point", "circular", "two_circles", "line", "polygon" 多边形勿重复第一个顶点,会自动闭合
    type: "line"
    # radius: 0.2 # for type "circular"
    line_start: [-0.3, 0.0] # for type "line"
    line_end: [0.3, 0.0] # for type "line"
    # front_offset: 0.2 # for type "two_circles"
    # front_radius: 0.2 # for type "two_circles"
    # rear_offset: 0.2 # for type "two_circles"
    # rear_radius: 0.2 # for type "two_circles"
    # vertices: [ [0.25, -0.05], [0.18, -0.05], [0.18, -0.18], [-0.19, -0.18], [-0.25, 0], [-0.19, 0.18], [0.18, 0.18], [0.18, 0.05], [0.25, 0.05] ] # for type "polygon"

  # GoalTolerance
      
  xy_goal_tolerance: 0.2
  yaw_goal_tolerance: 0.1
  #自由目标速度。设为False时,车辆到达终点时的目标速度为0。
  #TEB是时间最优规划器。缺少目标速度约束将导致车辆“全速冲线”
  free_goal_vel: False
  
  # complete_global_plan: True   
  # Obstacles
      
  min_obstacle_dist: 0.3 # 与障碍的最小期望距离,
  include_costmap_obstacles: True #应否考虑到局部costmap的障碍设置为True后才能规避实时探测到的、建图时不存在的障碍物。
  costmap_obstacles_behind_robot_dist: 2.0 #考虑后面n米内的障碍物
  obstacle_poses_affected: 30 #为了保持距离,每个障碍物位置都与轨道上最近的位置相连。
  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
  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
  weight_obstacle: 50
  weight_dynamic_obstacle: 10 # not in use yet
  alternative_time_cost: False # not in use yet
  selection_alternative_time_cost: False
  # Homotopy Class Planner

  enable_homotopy_class_planning: False
  enable_multithreading: False
  simple_exploration: False
  max_number_classes: 4
  roadmap_graph_no_samples: 15
  roadmap_graph_area_width: 5
  h_signature_prescaler: 0.5
  h_signature_threshold: 0.1
  obstacle_keypoint_offset: 0.1
  obstacle_heading_threshold: 0.45
  visualize_hc_graph: False

  # # Recovery

  # shrink_horizon_backup: True
  # shrink_horizon_min_duration: 10
  # oscillation_recovery: True
  # oscillation_v_eps: 0.1
  # oscillation_omega_eps: 0.1
  # oscillation_recovery_min_duration: 10
  # oscillation_filter_duration: 10

三.启动

编写launch,修改map_serveramcl的部分话题信息

<launch>

   <node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
    <rosparam file="$(find slam_nav)/param/costmap_common_params.yaml" command="load" ns="global_costmap" /> 
    <rosparam file="$(find slam_nav)/param/costmap_common_params.yaml" command="load" ns="local_costmap" />
    <rosparam file="$(find slam_nav)/param/local_costmap_params.yaml" command="load" />
    <rosparam file="$(find slam_nav)/param/global_costmap_params.yaml" command="load" /> 
    <rosparam file="$(find slam_nav)/param/teb_local_planner_params.yaml" command="load" />
    <rosparam file="$(find slam_nav)/param/move_base_params.yaml" command="load" />
    
    <param name="base_local_planner" value="teb_local_planner/TebLocalPlannerROS" />
   </node>

   	<node name="map_server" pkg="map_server" type="map_server" args="$(find slam_model)/map/ackman_wall.yaml" output="screen">
                <param name="frame_id" value="map"/>
    </node>
   <arg name="use_map_topic"   default="True"/>
    <arg name="scan_topic"      default="/ackman/laser/scan"/> 
    <arg name="initial_pose_x"  default="0.0"/>
    <arg name="initial_pose_y"  default="0.0"/>
    <arg name="initial_pose_a"  default="0.0"/>
    <arg name="odom_frame_id"   default="odom"/>
    <arg name="base_frame_id"   default="base_footprint"/>
    <arg name="global_frame_id" default="map"/>
  <node pkg="amcl" type="amcl" name="amcl">
      <param name="use_map_topic"             value="$(arg use_map_topic)"/>
      <!-- Publish scans from best pose at a max of 10 Hz -->
      <param name="odom_model_type"           value="diff"/>
      <param name="odom_alpha5"               value="0.1"/>
      <param name="gui_publish_rate"          value="10.0"/>
      <param name="laser_max_beams"           value="810"/>
      <param name="laser_max_range"           value="-1"/>
      <param name="min_particles"             value="500"/>
      <param name="max_particles"             value="5000"/>
      <param name="kld_err"                   value="0.05"/>
      <param name="kld_z"                     value="0.99"/>
      <param name="odom_alpha1"               value="0.2"/>
      <param name="odom_alpha2"               value="0.2"/>
      <!-- translation std dev, m -->
      <param name="odom_alpha3"               value="0.2"/>
      <param name="odom_alpha4"               value="0.2"/>
      <param name="laser_z_hit"               value="0.5"/>
      <param name="laser_z_short"             value="0.05"/>
      <param name="laser_z_max"               value="0.05"/>
      <param name="laser_z_rand"              value="0.5"/>
      <param name="laser_sigma_hit"           value="0.2"/>
      <param name="laser_lambda_short"        value="0.1"/>
      <param name="laser_model_type"          value="likelihood_field"/>
      <!-- <param name="laser_model_type" value="beam"/> -->
      <param name="laser_likelihood_max_dist" value="2.0"/>
      <param name="update_min_d"              value="0.1"/>
      <param name="update_min_a"              value="0.2"/>
      <param name="odom_frame_id"             value="$(arg odom_frame_id)"/> 
      <param name="base_frame_id"             value="$(arg base_frame_id)"/> 
      <param name="global_frame_id"           value="$(arg global_frame_id)"/>
      <param name="resample_interval"         value="1"/>
      <!-- Increase tolerance because the computer can get quite busy -->
      <param name="transform_tolerance"       value="1.0"/>
      <param name="recovery_alpha_slow"       value="0.0"/>
      <param name="recovery_alpha_fast"       value="0.0"/>
      <param name="initial_pose_x"            value="$(arg initial_pose_x)"/>
      <param name="initial_pose_y"            value="$(arg initial_pose_y)"/>
      <param name="initial_pose_a"            value="$(arg initial_pose_a)"/>
      <remap from="/scan"                     to="$(arg scan_topic)"/>
      <remap from="/tf_static"                to="/tf_static"/>
    </node>

   </launch> 

然后先启动ackman_show.launch再启动这个move_base.launch
rivz里订阅几个话题:

2D Nav Goal即可让小车导航

你甚至可以挡它的路:

四.完结后记

目前实现了整个从模型创建到导航的整体功能的实现,代码里还是含有很多bug,而且很多参数的影响也没有量化的考虑清楚。后面用实际模型的时候再针对性的解决这部分问题,现在已经熟悉整个流程了。

以上是关于ROS学习记录17SLAM仿真学习6完结—— 无人驾驶的主要内容,如果未能解决你的问题,请参考以下文章

ROS学习记录13SLAM仿真学习2——创建一个包含LidarCameraIMU的Ackman小车

ROS学习记录12SLAM仿真学习1——ROS Control

ROS学习记录12SLAM仿真学习1——ROS Control

ROS学习记录14SLAM仿真学习3——开车,并发布坐标信息

ROS学习记录14SLAM仿真学习3——开车,并发布坐标信息

ROS学习记录15SLAM仿真学习4——使用gmapping建图与保存地图