Study/[ROS] Navigation

ROS Navigation(4. Path Planning 2)

soohwan_justin 2021. 1. 12. 10:23

이 포스트는 theconstructsim.com의 ROS Navigation in 5 Days 를 참고하였습니다.

이번 포스트에서 다룰 내용은

  • 장애물 회피는 어떻게 작동하는가?
  • local planner란?
  • local costmap이란?
  • path planning recap
  • dynamic reconfigure과 다른 RViz tools의 사용법

이번 course에서는 turtlebot simulation package를 사용합니다. 아래 링크를 참조하세요

emanual.robotis.com/docs/en/platform/turtlebot3/simulation/

시뮬레이션 모델은 Waffle 모델을 사용합니다.

waffle 모델을 사용하기 위해서는 환경 변수를 추가하거나, bash shell에 해당 명령을 입력하면 됩니다.

 

$ export TURTLEBOT3_MODEL=waffle

 

또는, ~/.bashrc 를 수정하여 맨 밑에 export TURTLEBOT3_MODEL=waffle 를 추가합니다.

 

여기서 말하는 내비게이션이란, 우리가 일반적으로 차를 운전하면서 사용하는 내비게이션처럼 단순히 길만 찾는것이 아닌, 해당 경로를 따라 주행까지 하는 것을 말합니다.

 

 

The Local Planner

global planner가 경로를 계산하면, 이 경로는 local planner로 보내집니다. 그 다음엔, local planner가 그 global plan을 분할한 각각의 부분들을 실행할 것입니다(local plan을 global plan의 작은 부분들이라고 생각하세요). 따라서, 주어진 경로와 지도, local planner는 로봇을 움직이도록 하기 위해 속도 명령을 제공할 것입니다.

 

global planner와 다르게, local planner는 오도메트리와 레이저 데이터를 계속 확인하고, 충돌이 없는 local plan을 선택합니다. 따라서, local planner는 로봇의 충돌을 방지하며 목적지에 도달하기 위해 로봇의 경로를 즉시 재계산할 수 있습니다. local plan이 계산되면, 이는 /local_plan topic으로 publish됩니다.

 

global planner처럼 local planner도 여러 종류가 있습니다. 다음으로, 그것들 중 하나를 알아보겠습니다.

base_local_planner

base local planner는 global plan을 계산하고, 실행하기 위해 Trajectory Rollout과 Dynamic Window Approach(DWA)알고리즘을 제공합니다. 이 알고리즘이 어떻게 동작하는지를 요약하자면, 다음과 같습니다.

  • 로봇의 control spalce로부터 불연속적으로 샘플링합니다.
  • Discretely sample from the robot's control space
  • 각각의 샘플링된 속도에 대해, 현재 로봇의 상태에서 시뮬레이션을 수행합니다. 즉, 현재 상태에서 샘플된 각각의 속도를 적용하면 로봇이 어떻게 움직일지를 예측하는 것입니다.
  • 시뮬레이션의 결과로 나온 경로들을 평가합니다.
  • 부적절한 경로들을 제거합니다.
  • 가장 점수가 높은 경로를 선택하고, 이에 관련된 속도 값을 mobile base로 보냅니다.
  • 위 과정을 반복합니다.

이와 같이 시뮬레이션으로 경로를 생성해보고, 가장 적절한 경로를 선택합니다.  https://www.semanticscholar.org/paper/Improved-dynamic-window-approach-by-using-Lyapunov-Berti-Sappa/0bbf0d455775564347a5548d9fab10a7ed60ccec

DWA와 Trajectory Rollout의 차이점은 로봇의 공간을 샘플링하는 방법입니다. Trajectory Rollout 샘플들은 로봇의 가속도 제한 내에서 주어진 모든 시뮬레이션에 걸친 속도의 집합이지만, DWA는 단지 한 스텝의 시뮬레이션만을 사용합니다.

dwa_local_planner

DWA local planner는 Dynamic Window Approach 알고리즘을 적용한 방법입니다. 이는 기본적으로 base local planner의 DWA (Dynamic Window Approach) 옵션을 다시 작성했지만 코드는 특히 궤적을 시뮬레이션하는 방식에서 훨씬 더 깔끔하고 이해하기 쉽습니다. 일반적으로 거의 이 옵션을 사용한다고 보시면 됩니다.

 

eband_local_planner

local plan을 계산하기 위해 Elastic Band method를 적용하는 planner 입니다.

teb_local_planner

local plan을 계산하기 위해 Timed Elastic Band method를 적용하는 planner 입니다.

 

 

local planner도 global planner처럼 파라미터들이 있습니다. 이 파라미터들은 우리가 사용하는 planner에 따라 값이 달라질것입니다. 우리는 DWA local planner 파라미터에 대해서만 집중적으로 알아볼 것입니다. 각각의 planner에 대한 정보는 다음 링크를 참조하세요

base_local_planner: http://wiki.ros.org/base_local_planner

eband_local_planner: http://wiki.ros.org/eband_local_planner

teb_local_planner: http://wiki.ros.org/teb_local_planner

dwa local planner Parameters

local planner에서 사용하는 파라미터들은 YAML파일에 정의되어있습니다. DWA local planner에서 중요한 파라미터들은 다음과 같습니다.

 

Robot Configuration Parameters

  • /acc_lim_x (default: 2.5): 로봇의 x방향 가속도 제한 (meters/s^2)
  • /acc_lim_th (default: 3.2): 로봇의 각 가속도 제한(radians/s^2)
  • /max_trans_vel (default: 0.55): 로봇의 최대 병진속도(translational velocity)의 절대값(m/s)
  • /min_trans_vel (default: 0.1): 로봇의 최소 병진속도(translational velocity)의 절대값(m/s)
  • /max_vel_x (default: 0.55): 로봇의 x방향 최대속도(m/s)
  • /min_vel_x (default: 0.0): 로봇의 x방향 최소속도. 후진이 가능하게 하려면 음수 값을 설정(m/s)
  • /max_rot_vel (default: 1.0): 로봇의 최대 회전속도의 절대값(rad/s)
  • /min_rot_vel (default: 0.4): 로봇의 최소 회전속도의 절대값(rad/s)

Goal Tolerance Parameters

  • /yaw_goal_tolerance (double, default: 0.05): 목표 자세와 로봇의 실제 자세와의 각도 오차(rad)
  • /xy_goal_tolerance (double, default: 0.10): 목표 자세와 로봇의 실제 자세와의 x,y 위치 오차(meter)
  • /latch_xy_goal_tolerance (bool, default: false): 만약 goal_tolerance가 latch되면, 로봇이 목표 xy위치에 도달했을 때 goal tolerance를 벗어나더라도 회전을 합니다.

 

Forward Simulation Parameters

  • /sim_time (default: 1.7): 해당 값의 시간동안의 시뮬레이션 계산. 예를 들어, 해당 값에 2를 설정하면 앞으로 2초간의 시뮬레이션 계산(초 단위)
  • /sim_granularity (default: 0.025): 주어진 궤적의 포인트 사이의 스텝 사이즈(미터 단위)
  • /vx_samples (default: 3): x 속도 공간에서의 샘플 수
  • /vy_samples (default: 10): y 속도 공간에서의 샘플 수
  • /vtheta_samples (default: 20): theta 속도(각속도) 공간에서의 샘플 수

 

Trajectory Scoring Parameters

  • /path_distance_bias (default: 32.0): 컨트롤러가 주어진 경로(global plan)에 가깝게 유지하도록 하는 가중치
  • /goal_distance_bias (default: 24.0): 컨트롤러가 local goal에 도달하도록 하는 가중치 
  • /occdist_scale (default: 0.01): 컨트롤러가 장애물을 피하도록 하는 가중치

즉, 경로에 대해 점수를 매길 때, 어떤 부분에 대해 더 점수를 줄 것이냐 하는 것입니다. 위 파라미터들의 경우, 주어진 경로를 잘 따라가는가? local goal에 잘 도착하는가? 장애물을 잘 피하는가?  입니다.


연습 5.1.

 

이전 포스트에서 만들었던 my_amcl_launch 패키지를 그대로 사용합니다.

해당 패키지에 param 디렉토리를 만들고, 다음 5개의 파일을 만들고, 편집합니다.

 

costmap_common_params.yaml

dwa_local_planner_params.yaml

global_costmap_params.yaml

local_costmap_params.yaml

move_base_params.yaml

 

 

costmap_common_params.yaml

ax_obstacle_height: 0.60  # assume something like an arm is mounted on top of the robot

# Obstacle Cost Shaping (http://wiki.ros.org/costmap_2d/hydro/inflation)
robot_radius: 0.17  # distance a circular robot should be clear of the obstacle
# footprint: [[x0, y0], [x1, y1], ... [xn, yn]]  # if the robot is not circular

map_type: voxel

obstacle_layer:
  enabled:              true
  max_obstacle_height:  0.6
  origin_z:             0.0
  z_resolution:         0.2
  z_voxels:             10
  unknown_threshold:    15
  mark_threshold:       0
  combination_method:   1
  track_unknown_space:  true    #true needed for disabling global path planning through unknown space
  obstacle_range: 3.0
  raytrace_range: 3.5
  origin_z: 0.0
  publish_voxel_map: false
  observation_sources:  scan #bump
  scan: {sensor_frame: base_scan, data_type: LaserScan, topic: /scan, marking: true, clearing: true, inf_is_valid: true}

#cost_scaling_factor and inflation_radius were now moved to the inflation_layer ns
inflation_layer:
  enabled:              true
  cost_scaling_factor:  3.0  # exponential rate at which the obstacle cost drops off (default: 10)
  inflation_radius:     1.0  # max. distance from an obstacle at which costs are incurred for planning paths.

static_layer:
  enabled:              true

 

 

dwa_local_planner_params.yaml

DWAPlannerROS:

# Robot Configuration Parameters
  max_vel_x: 0.26
  min_vel_x: -0.26

  max_vel_y: 0.0
  min_vel_y: 0.0

# The velocity when robot is moving in a straight line
  max_vel_trans:  0.26
  min_vel_trans:  0.13

  max_vel_theta: 1.82
  min_vel_theta: 0.9

  acc_lim_x: 2.5
  acc_lim_y: 0.0
  acc_lim_theta: 3.2

# Goal Tolerance Parametes
  xy_goal_tolerance: 0.05
  yaw_goal_tolerance: 0.17
  latch_xy_goal_tolerance: false

# Forward Simulation Parameters
  sim_time: 2.0
  vx_samples: 20
  vy_samples: 0
  vth_samples: 40
  controller_frequency: 10.0

# Trajectory Scoring Parameters
  path_distance_bias: 32.0
  goal_distance_bias: 20.0
  occdist_scale: 0.02
  forward_point_distance: 0.325
  stop_time_buffer: 0.2
  scaling_speed: 0.25
  max_scaling_factor: 0.2

# Oscillation Prevention Parameters
  oscillation_reset_dist: 0.05

# Debugging
  publish_traj_pc : true
  publish_cost_grid_pc: true

 

global_costmap_params.yaml

global_costmap:
   global_frame: map
   robot_base_frame: base_footprint
   update_frequency: 10.0
   publish_frequency: 10.0
   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"}

 

 

local_costmap_params.yaml

local_costmap:
   global_frame: odom
   robot_base_frame: base_footprint
   update_frequency: 10.0
   publish_frequency: 10.0
   static_map: false
   rolling_window: true
   width: 4.0
   height: 4.0
   resolution: 0.05
   transform_tolerance: 0.5
   plugins:
    - {name: obstacle_layer,      type: "costmap_2d::VoxelLayer"}
    - {name: inflation_layer,     type: "costmap_2d::InflationLayer"}

 

 

move_base_params.yaml

shutdown_costmaps: false
controller_frequency: 10.0
planner_patience: 5.0
controller_patience: 15.0
conservative_reset_dist: 3.0
planner_frequency: 5.0
oscillation_timeout: 10.0
oscillation_distance: 0.2

 

 

해당 패키지의 launch 디렉토리에 다음과 같이 move_base.launch 파일을 만듭니다.

<launch>
  <!-- Arguments -->
  <arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/>
  <arg name="cmd_vel_topic" default="/cmd_vel" />
  <arg name="odom_topic" default="odom" />
  <arg name="move_forward_only" default="false"/>

  <!-- move_base -->
  <node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
    <param name="base_local_planner" value="dwa_local_planner/DWAPlannerROS" />
    <rosparam file="$(find my_amcl_launcher)/param/costmap_common_params.yaml" command="load" ns="global_costmap" />
    <rosparam file="$(find my_amcl_launcher)/param/costmap_common_params.yaml" command="load" ns="local_costmap" />
    <rosparam file="$(find my_amcl_launcher)/param/local_costmap_params.yaml" command="load" />
    <rosparam file="$(find my_amcl_launcher)/param/global_costmap_params.yaml" command="load" />
    <rosparam file="$(find my_amcl_launcher)/param/move_base_params.yaml" command="load" />
    <rosparam file="$(find my_amcl_launcher)/param/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)" />
  </node>
</launch>

 

내비게이션 node를 실행하는 change_map.launch파일을 다음과 같이 수정하고, 해당 파일의 이름을 my_navigation.launch로 변경해줍니다.

<launch>
  <!-- Arguments -->
  <arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/>
  <arg name="map_file" default="$(find turtlebot3_navigation)/maps/map2/map.yaml"/>
  <arg name="open_rviz" default="true"/>
  <arg name="move_forward_only" default="false"/>

  <!-- Turtlebot3 -->
  <include file="$(find turtlebot3_bringup)/launch/turtlebot3_remote.launch">
    <arg name="model" value="$(arg model)" />
  </include>

  <!-- Map server -->
  <node pkg="map_server" name="map_server" type="map_server" args="$(arg map_file)"/>

  <!-- AMCL -->
  <include file="$(find my_amcl_launcher)/launch/my_amcl.launch"/>

  <!-- move_base -->
  <include file="$(find my_amcl_launcher)/launch/move_base.launch">
    <arg name="model" value="$(arg model)" />
    <arg name="move_forward_only" value="$(arg move_forward_only)"/>
  </include>

  <!-- rviz -->
  <group if="$(arg open_rviz)">
    <node pkg="rviz" type="rviz" name="rviz" required="true"
          args="-d $(find my_amcl_launcher)/rviz/my_amcl.rviz"/>
  </group>
</launch>

 

 

이제부터, 위에서 작성한 파라미터들을 수정하여 내비게이션의 성능을 조절하면 됩니다.


Local Costmap

local planner는 local plan을 계산하기 위해 local costmap을 사용합니다. global costmap과는 다르게, local costmap은 로봇의 센서 데이터로부터 직접적으로 만들어집니다. 사용자에 의해 정의된 크기의 costmap의 중앙에 로봇이 있게 되고, 로봇이 움직임에 따라 이 지도 또한 같이 움직이게되며, 실시간으로 장애물에 대한 정보를 얻게됩니다.

 

즉, 새로운 물체가 나타나면 이 물체는 global costmap에는 반영이 되지 않고, local costmap에만 반영된다는 것입니다. 이전에 설정했듯이 global costmap은 static map으로부터 만들어졌으며, 이는 환경이 바뀌더라도 costmap이 바뀌지 않을 것이라는 뜻입니다. 하지만, local costmap은 그 대신 센서 데이터로부터 만들어졌기 때문에 이는 센서의 데이터로부터 항상 업데이트가 가능합니다. 

Local Costmap Parameters

  • global_frame: costmap이 작동하는 global frame의 이름입니다. local costmap에서는 반드시 오도메트리 데이터, /odom으로 설정해야합니다.
  • *static_map *: costmap을 초기화하기 위해 static map을 사용할지의 여부를 결정합니다. local costmap에서는 반드시 false로 설정되어야합니다. 
  • rolling_window: costmap의 rolling window version 사용 여부를 정합니다. local costmap에서는 반드시 true로 설정되어야합니다.
  • width: costmap의 넓이(가로 길이)입니다.
  • heigth: costmap의 높이(세로 길이)입니다.
  • update_frequency: 맵 업데이트의 주기를 설정합니다.
  • plugins: global map의 plugins와 동일합니다.

 

global costmap에서 보았듯이, local costmap에도 layers가 추가될 수 있습니다. local costmap의 경우, 일반적으로 다음 2개의 layers를 사용합니다. 연습 5.1에서 작성했던 local_costmap_params.yaml을 확인해보세요

 

  • costmap_2d::ObstacleLayer: 장애물 회피를 위해 사용
  • costmap_2d::InflationLayer: 장애물을 팽창시키기(inflate)위해 사용

주의!: local costmap과 global costmap의  obstacle layer는 다른 plugins를 사용합니다. local costmap은 costmap_2d::ObstacleLayer를 사용하고, global costmap은 costmap_2d::VoxelLayer를 사용합니다. 이 둘을 헷갈리는 것은 매우 자주일어나는 실수입니다.

 

local costmap이 지도를 업데이트하는 과정은 다음과 같습니다. 해당 업데이트 사이클의 속도는 update_frequency 파라미터로 설정할 수 있습니다.

  • 센서 데이터를 읽습니다
  • Marking 및 clearing 작업이 수행됩니다.
  • 각각의 셀에 적절한 cost values가 할당됩니다.
  • 장애물이 있는 각각의 cell에 Obstacle inflation이 수행됩니다. 이는 점유된 각각의 셀로부터 정의된 inflation radius만큼, 바깥쪽으로 퍼져나갑니다.

local costmap은 자동으로 센서의 topics을 subscribe하고, 그 데이터에 따라서  스스로 업데이트를 합니다. 각각의 센서는 mark(costmap에 장애물의 정보를 추가하는 것), clear(costmap에서 장애물의 정보를 없애는 것)에 사용됩니다. marking과 clearing 작업은 obstacle layer에 정의될 수 있습니다.

 

이제 우리는 common costmap parameters file에 정의된 파라미터들을 확인해봐야 하는데, 이 파라미터들은 global costmap, local costmap 모두에게 영향을 미칩니다.

 

  • footprint: mobile base의 윤곽선(contour)입니다. ROS에서, 이는 2차원 배열 형태 [x0, y0], [x1, y1], [x2, y2], ...] 로 나타냅니다. 이 footprint는  내접원과 외접원의 반지름을 계산하기 위해 사용되는데, 이 내접원과 외접원은 로봇에 맞게 장애물을 팽창시키는데 사용됩니다. 일반적으로, 안전을 위해 footprint를 로봇의 실제 윤곽보다 좀 더 크게 정의하는 것이 좋습니다.
  • robot_radius: 로봇이 원형인 경우, footprint 대신 사용합니다.
  • layers parameters: 각각의 layer를 정의합니다

 

Obstacle Layer

obstacle layer는 marking, clearing operations를 담당합니다. 이들은 obstacle layer에 정의될 수 있습니다.

  • max_obstacle_height (default: 2.0): costmap에 반영될 수 있는 장애물의 최대 높이입니다. 이 값은 로봇의 높이보다 조금 크게 정의되어야 하며, 단위는 미터입니다.
  • obstacle range (default: 2.5): costmap에 반영될 거리 입니다. 로봇과의 거리가 해당 값 보다 작을 경우, costmap에 반영되며, 단위는 미터입니다. 이는 센서마다 재정의할 수 있습니다.
  • raytrace_range (default: 3.0): 센서 데이터를 사용하여 장애물을 ray trace하는 거리를 정의하며, 단위는 미터입니다. 이는 센서마다 재정의할 수 있습니다.
  • observation_sources (default: ""): 공간에 의해 분리된 observation source names의 리스트입니다. 이는 밑에 정의된 각각의 source_name 네임스페이스를 정의합니다.

observation_sources의 각각의 source_name은 파라미터를 정의할 수 있는 네임스페이스를 정의합니다.

  • /source_name/topic (default: source_name): 이 source에 대한 센서 데이터의 topic입니다. 기본값은 source의 이름입니다.
  • /source_name/data_type (default: "PointCloud"): 그 topic에 관련된 데이터 타입입니다. 지금은 "PointCloud," "PointCloud2,"  "LaserScan" 만 지원됩니다.
  • /source_name/clearing (default: false): 이 관측값이 자유 공간을 clear하는데에 사용될지의 여부를 정합니다.
  • /source_name/marking (default: true): 이 관측값이 장애물을 mark하는데에 사용될지의 여부를 정합니다.
  • /source_name/inf_is_valid (default: false): "LaserScan" 데이터 메시지에서 Inf값을 받을지를 정합니다. Inf값은 레이저 센서가 측정할 수 있는 최대값으로 변환됩니다.

Inflation Layer

inflation layer는 장애물의 각각의 셀의 팽창에 대한 설정을 합니다.

  • inflation_radius (default: 0.55): 장애물 cost value를 팽창시킬 반지름 크기입니다.(미터 단위)
  • cost_scaling_factor (default: 10.0): 팽창시키는 동안 적용할 scalling factor입니다.

cost_scaling_factor란, 다음 그림에서 거리에 따른 cell cost 그래프가 지수함수적으로 감소하는데, 이 지수함수의 감소 비율을 정합니다. 

 

 

다음은 inflation layer의 파라미터를 바꾼 결과입니다.

 

inflation_radius = 1.0

cost_scaling_factor = 3.0

 

inflation_radius = 1.0

cost_scaling_factor = 3.0

 

 

inflation_radius = 1.0

cost_scaling_factor = 10.0

 

 

즉, 해당 값들이 크면 로봇이 장애물로부터 멀리 떨어져서 진행하려고 하기 때문에 안전하지만, 장애물을 빙 돌아가려고 하기 때문에 최적화 된 경로를 찾기가 더 어려워집니다.

 

 

Static Layer

staric layer는 costmap이 필요로 하는 경우 static map을 제공합니다(global costmap의 경우).

  • map_topic (string, default: "map"): costmap이 해당 topic의 static map 데이터를 subscribe합니다.

 

Recovery Behaviors

recovery behavior는 로봇이 경로를 따라가는 중, 어떤 이유로 인해 진행이 막혔을 때 수행됩니다. ROS에서는 이 경우, 로봇이 막힌 상황을 풀어주고 다시 내비게이션을 진행하도록 recovery behavior를 수행합니다.

 

ROS Navigation Stack은 clear costmap과 rotate recovery라는 recovery behaviors를 제공합니다. 이를 활성화 하기 위해서는, move_base 파라미터 파일에서 다음 옵션을 활성화해야 합니다.

 

  • recovery_behavior_enabled (default: true): recovery behavior를 활성화할지의 여부를 설정합니다.

Rotate Recovery

기본적으로, rotate recovery behavior는 로봇이 360도로 회전하면서 공간을 clear하려고 하는 시도입니다. 이 방법으로, 로봇은 계속 내비게이션을 진행하기 위한 장애물이 없는 경로를 찾을 수도 있습니다. 이 behavior를 커스터마이징 하기 위한 파라미터는 다음과 같습니다.

Rotate Recovery Parameters

  • /sim_granularity (double, default: 0.017): 회전할 때, 현재 환경이 안전한지를 확인합니다. 해당 각도 이내에 장애물이 있는지를 확인합니다. 단위는 라디안이며, 기본값은 1도 입니다.
  • /frequency (double, default: 20.0): mobile base로 보내는 속도 명령 주기입니다. 단위는 Hz입니다.

Clear Costmap

clear costmap recovery는 로봇의 특정한 지역의 바깥쪽에 있는 장애물들을 모두 clear합니다. 기본적으로, local costmap은 global map과 비슷하게 생겨야 합니다. move_base node는 /move_base/clear_costmaps 라는 service를 사용하여 costmap을 clear할 수 있습니다.

 

다음 명령으로 해당 service를 호출하면, 아래와 같은 결과를 볼 수 있습니다.

 

 

service 호출 이전

 

service호출 후

$ rosservice call /move_base/clear_costmaps "{}" 

 

 

Oscillation Supression

Oscillation(진동)은 x, y, theta 중 어떤 것이든 간에 음수와 양수 값이 연속해서 선택될 때 발생합니다. 이를 방지하기 위해서는, 로봇이 어떤 방향으로 움직일 때, 반대쪽 방향은 다음 cycle에서 갈 수 없는 방향이라고 표시를 하고, 로봇이 그 flag가 설정된 위치에서 어느정도 거리를 진행하기 전까지는 그 쪽으로 가지 못하게 하면 됩니다. 이에 관련된 move_base 파라미터는 다음과 같습니다.

  • oscillation_timeout (double, default: 0.0): recovery behaviors가 실행되기 전에 얼마나 오래 oscillation을 허용할 것인가를 설정합니다. 단위는 초이며, 값이 0.0일 경우 무한대로 대기, 즉 recovery behaviors가 발생하지 않습니다.
  • oscillation_distance (double, default: 0.5): oscillating이 아니라고 여겨지는 움직임을 위해서 로봇이 얼마나 멀리 움직여야 하는지를 설정합니다. 단위는 미터이며, 이 값보다 멀리 움직이는 경우 oscillation_timeout값을 초기화하여 다시 카운트합니다.

 

 

 

Dynamic Reconfigure

지금까지, 파라미터 값을 파일에서 직접 수정하였지만, rqt_reconfigure를 사용하여 편하게 조절할 수 있으며, 실시간으로 성능 변화를 관찰할 수 있습니다.

 

$ rosrun rqt_reconfigure rqt_reconfigure

'Study > [ROS] Navigation' 카테고리의 다른 글

ROS Navigation(4. Path Planning 1)  (0) 2021.01.10
ROS Navigation(3. Localization)  (0) 2021.01.10
ROS Navigation(2. Map Creation)  (1) 2021.01.10
ROS Navigation(1. Basic Concept)  (0) 2021.01.05