gazebo/Nav2

nav2 - (STVL) Using an External Costmap Plugin

정지홍 2025. 4. 3. 15:40

https://docs.nav2.org/tutorials/docs/navigation2_with_stvl.html

 

(STVL) Using an External Costmap Plugin — Nav2 1.0.0 documentation

0- Setup Follow the same process as in Getting Started for installing and setting up a robot for hardware testing or simulation, as applicable. Ensure ROS 2, Navigation2, and Gazebo are installed. 1- Modify Navigation2 Parameter STVL is an optional plugin,

docs.nav2.org

 

 

overview

  • 해당되는 튜토리얼은 external plugin을 어떻게 load하는지 보여줄것이다.
    • 하나의 예시로는 STVL plugin을 사용할것이다.
      여기에서 방식대로 한다면 planner , controller , behavior에 대한 plugin도 적용하는 것이 가능할것이다.

 

 

Costmap2D and STVL

  • Costmap 2D는 sensor data를 저장하고, 전역적으로 robot이 planning과 control에 사용할수 있도록 구성된 data structure이다.
    • 이 안에는 여러 pluginlib기반의 costmap plugins이 존재하며, runtime에 load가 가능하다.
      • ex) obstacle payer와 voxel layer와 static layer등을 런타임에 로드하는 것이 가능.
  • STVL은 3D 인식용 costmap plugin이다.
    • STVL은 depth camera , lidar 등의 3D sensor data를 희소한 3d voxel형태로 저장하여 , 시간에 따라서 장애물을 자동으로 사라지게한다.
    • 이는 복잡하고 동적인 환경에서 유용하며, 3d sensor data 처리를 기존보다 최대 2배 효율적으로 할 수 있다.

 

 

0. setup

sudo apt install ros-<ros2-distro>-spatio-temporal-voxel-layer

 

 

1. modify navigation2 parameter

  • 기존의 parameter를 봐볼건데, 예제를 적용시킬 global costmap에 대해서 살펴보자.
# global costmap이 2번 중첩되는 이유는, launchg 파일내에서 global_costmap 실행시 namespace를 동일하게 설정했기 때문
global_costmap:
  global_costmap:
    ros__parameters:
      update_frequency: 1.0 # costmap을 초당 몇 번(Hz) 업데이트 할지. 1.0은 1초에 한번 갱신
      publish_frequency: 1.0 # topic을 몇 Hz로 publish할지. 
      global_frame: map # costmap이 기준으로 삼는 전역 프레임이다. 
      robot_base_frame: base_link # 로봇의 기준 프레임이다. 여기서는 로봇의 중심이다.(base_link)
      # 로봇의 반지름이다. 미터 단위 ( m ) . 장애물 회피 계산 등에 사용. 이는 꼭 시뮬레이션 할때, gazebo와 일치시켜야한다. collsion블럭과...
      robot_radius: 0.22
      resolution: 0.05 # costmap의 격자 해상도를 의미. m단위이며, 0.05는 5cm이다.
      track_unknown_space: true # 미탐색 영역을 no information으로 표시할지 
      # 레이어 플러그인 설정. 해당 할목은 costmap에 사용할 레이어들을 정의한다. 각 이름은 아래 정의된 설정 블록의 키와 매칭됨
      plugins: ["static_layer", "obstacle_layer", "inflation_layer"]
      # lidar나 sensor data로부터 실시간 장애물을 costmap에 반영하는 역할을 하는 레이어다.
      obstacle_layer:
        plugin: "nav2_costmap_2d::ObstacleLayer"
        enabled: True
        observation_sources: scan # 사용할 센서 소스이다. 이름은 아래의 블록과 동일해야함.
        scan:
          topic: /scan # 센서 데이터가 들어오는 Ros 2의 토픽이름 
          max_obstacle_height: 2.0 # 특정 높이 이상이면 무시됨
          clearing: True # 센서로 free space를 감지해서 제거 가능하게함. 이를 ray tracing이라 함.
          marking: True # 감지된 장애물을 costmap에 표지할지 안할지 정함. true면  표시함.
          data_type: "LaserScan" # 수신되는 sensor 메시지의 타입.
          raytrace_max_range: 3.0 # clearing 범위의 최대거리
          raytrace_min_range: 0.0
          obstacle_max_range: 2.5 # 장애물로 인식할 최대 거리
          obstacle_min_range: 0.0
      # slam이나 map server에서 제공하는 정적 맵을 반영. 보통은 pgm지도이다. 맵은 대부분은 occupancy grid(nav_msgs/OccupancyGrid)
      static_layer:
        plugin: "nav2_costmap_2d::StaticLayer"
        # Ros의 qos를 설정하는 부분. 여기서는 transient local로 설정했다. 즉, /map 토픽을 transient local모드로 구독을 의미
        # transient local은 과거에 publisher가 보낸 마지막 message를 cache에 저장해두다가, 나중에 subscribe한 node에게 보내주는것
        map_subscribe_transient_local: True
      inflation_layer: # 장애물 주변을 cost로 퍼뜨려서 경로 생성 시에 간접 회피가 가능하게 한다.
        plugin: "nav2_costmap_2d::InflationLayer" 
        cost_scaling_factor: 3.0 # 거리 대비 비용 감소 속도. (급할수록 크게 감소 )
        inflation_radius: 0.7 # 장애물 주변 0.7m범위까지 퍼진다.
      always_send_full_costmap: True # 항상 전체 costmap을 publish할지 여부. false라면 부분만 보내서 대역폭 절약. 대신에 시각화에 문제가 생길수있으니 비추

 


 

  • 그리고 한번 stvl을 적용시키기 위해서 nav2_params.yaml을 수정해보자.
# global costmap이 2번 중첩되는 이유는, launchg 파일내에서 global_costmap 실행시 namespace를 동일하게 설정했기 때문
global_costmap:
  global_costmap:
    ros__parameters:
      update_frequency: 1.0 # costmap을 초당 몇 번(Hz) 업데이트 할지. 1.0은 1초에 한번 갱신
      publish_frequency: 1.0 # topic을 몇 Hz로 publish할지. 
      global_frame: map # costmap이 기준으로 삼는 전역 프레임이다. 
      robot_base_frame: base_link # 로봇의 기준 프레임이다. 여기서는 로봇의 중심이다.(base_link)
      # 로봇의 반지름이다. 미터 단위 ( m ) . 장애물 회피 계산 등에 사용. 이는 꼭 시뮬레이션 할때, gazebo와 일치시켜야한다. collsion블럭과...
      robot_radius: 0.22
      resolution: 0.05 # costmap의 격자 해상도를 의미. m단위이며, 0.05는 5cm이다.
      track_unknown_space: true # 미탐색 영역을 no information으로 표시할지 
      # 레이어 플러그인 설정. 해당 할목은 costmap에 사용할 레이어들을 정의한다. 각 이름은 아래 정의된 설정 블록의 키와 매칭됨
      plugins: ["static_layer", "obstacle_layer", "inflation_layer","stvl_layer"]
      # lidar나 sensor data로부터 실시간 장애물을 costmap에 반영하는 역할을 하는 레이어다.
      obstacle_layer:
        plugin: "nav2_costmap_2d::ObstacleLayer"
        enabled: True
        observation_sources: scan # 사용할 센서 소스이다. 이름은 아래의 블록과 동일해야함.
        scan:
          topic: /scan # 센서 데이터가 들어오는 Ros 2의 토픽이름 
          max_obstacle_height: 2.0 # 특정 높이 이상이면 무시됨
          clearing: True # 센서로 free space를 감지해서 제거 가능하게함. 이를 ray tracing이라 함.
          marking: True # 감지된 장애물을 costmap에 표지할지 안할지 정함. true면  표시함.
          data_type: "LaserScan" # 수신되는 sensor 메시지의 타입.
          raytrace_max_range: 3.0 # clearing 범위의 최대거리
          raytrace_min_range: 0.0
          obstacle_max_range: 2.5 # 장애물로 인식할 최대 거리
          obstacle_min_range: 0.0
      # slam이나 map server에서 제공하는 정적 맵을 반영. 보통은 pgm지도이다. 맵은 대부분은 occupancy grid(nav_msgs/OccupancyGrid)
      static_layer:
        plugin: "nav2_costmap_2d::StaticLayer"
        # Ros의 qos를 설정하는 부분. 여기서는 transient local로 설정했다. 즉, /map 토픽을 transient local모드로 구독을 의미
        # transient local은 과거에 publisher가 보낸 마지막 message를 cache에 저장해두다가, 나중에 subscribe한 node에게 보내주는것
        map_subscribe_transient_local: True
      inflation_layer: # 장애물 주변을 cost로 퍼뜨려서 경로 생성 시에 간접 회피가 가능하게 한다.
        plugin: "nav2_costmap_2d::InflationLayer" 
        cost_scaling_factor: 3.0 # 거리 대비 비용 감소 속도. (급할수록 크게 감소 )
        inflation_radius: 0.7 # 장애물 주변 0.7m범위까지 퍼진다.
      always_send_full_costmap: True # 항상 전체 costmap을 publish할지 여부. false라면 부분만 보내서 대역폭 절약. 대신에 시각화에 문제가 생길수있으니 비추
      stvl_layer:
        plugin: "spatio_temporal_voxel_layer/SpatioTemporalVoxelLayer"
        enabled: true # 레이어의 활성화 여부 
        voxel_decay: 15. # 각 voxel의 수명이 감소되는 속도. 클수록 빨리 사라짐. 단위는 decay_model에 따라서 달라짐.
        decay_model: 0 # 0은 linear , 1은 지수 , 2는 센서 거리 기반 모델
        voxel_size: 0.05 # voxel 격자의 크기. m단위 . 여기서는 0.05이니 5cm이다. 작을수록 더 정밀한 3D 모델 생성
        track_unknown_space: true # 센서가 아직 비추지 않은 공간을 unknown으로 추적할지 여부.
        unknown_threshold: 15 # unknown으로 간주되기 위한 voxel의 계수. 이 값보다 작으면 known공간으로 간주.
        mark_threshold: 0 # 장애물로 간주하기 위한 voxel의 최소 갯수. 0이라면 voxel이 하나만 존재해도 marking됨
        update_footprint_enabled: true # robot의 footprint영역을 실시간 업데이트 할지의 여부. 
        combination_method: 1 # 여러 레이어를 합칠때 사용하는 방법. 1=max , 0=overwrite
        origin_z: 0.0 # costmap의 z축 기준 원점.
        publish_voxel_map: true # /voxel_grid 토픽에 3d voxel 맵을 publish할지 여부
        transform_tolerance: 0.2 # tf transform이 약간 늦어져도 허용할 시간이며 '초 단위' 이다.
        mapping_mode: false # true이면 slam이나 정적 맵 생성 모드로 동작하며, false라면 장애물 탐지를 위한 costmap모드
        map_save_duration: 60.0 # mapping mode가 true일때, 맵 저장 주기 ( 초 단위 )
        observation_sources: pointcloud # 관찰할 소스이름이며, 여러개가 가능하다.
        pointcloud: # 관찰 소스에 대한 설정. 여기는 pointcloud이다.
          data_type: PointCloud2 # 들어오는 데이터 타입. 여기서는 아마도 sensor_msg/msg/pointcloud2 일거임
          topic: /oakd/rgb/preview/depth/points # 실제로 받아오는 센서의 토픽 이름 
          marking: true # 해당 센서를 통해서 인식한 장애물을 costmap에 추가할지의 여부
          clearing: true # 해당 센서를 통해서 공간을 비어있음으로 표시할지 여부 
          obstacle_range: 3.0 # 장애물로 인식할 최대 거리. m단위이며 이보다 멀면 무시 
          min_obstacle_height: 0.0 # 장애물로 인식할 최소 높이.  m단위
          max_obstacle_height: 2.0 # 장애물로 인식할 최대 높이. m단위
          expected_update_rate: 0.0 
          observation_persistence: 0.0
          inf_is_valid: false
          filter: "voxel"
          voxel_min_points: 0
          clear_after_reading: true # 센서 데이터를 처리후 내부 버퍼에서 제거할지 여부이며, true이면 메모리를 절약 가능
          max_z: 7.0
          min_z: 0.1
          vertical_fov_angle: 0.8745 # 센서의 수직 FOV 각도
          horizontal_fov_angle: 1.048
          decay_acceleration: 15.0 # decay 속도를 가속 시키는 계수이며, 움직이는 장애물을 빨리 지우고 싶을때 사용 
          model_type: 0 # stvl 내부 모델. 0은 기본이며, 1은 거리 기반 모델