Study/[ROS] Navigation

ROS Navigation(1. Basic Concept)

soohwan_justin 2021. 1. 5. 21:44

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

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

  • ROS Navigation Stack이란 무엇인가?
  • Navigation Stack을 위해 필요한 것은  무엇인가?
  • move_base node는 무엇이며 왜 중요한 것인가?
  • move_base node에서 무슨 part가 발생하는가?

 

이번 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 를 추가합니다.

 

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

 

 

 

 

ROS로 내비게이션은 실행하기 위해 필요한것은 무엇인가?

1. 지도

내비게이션을 위해 가장 먼저 필요한 것은 로봇이 길을 찾을 환경의 지도입니다. 이 지도를 획득하는 방법은 로봇을 사용하는 것입니다. 지도는 단지 로봇의 센서 데이터로부터 로봇 주변의 환경을 나타내는 것입니다. 우리는 그냥 로봇을 어떤 환경 주변에서 움직이도록 조작하여 지도를 만들 수 있습니다. 이를 ROS Navigation의 용어로, 맵핑(Mapping)이라고 합니다. 이 것이 어떻게 동작하는지 예시를 보겠습니다.

 

 


- 예제 1.

 

 

먼저, 우리는 map builder 프로그램을 launch해야합니다. 다음 명령으로 이를 실행합니다

 

$ roslaunch turtlebot3_gazebo turtlebot3_house.launch

 

해당 launch파일 실행 시, 아래와 같은 시뮬레이션 환경이 보입니다.

 

 

다음 launch 파일을 실행하여 로봇을 움직일 수 있습니다.

 

$ roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch

 

다음 launch 파일을 실행하면, 아래와 같이 맵을 만드는 모습을 볼 수 있습니다.

 

$ roslaunch turtlroslaunch turtlebot3_slam turtlebot3_gmapping.launch

 

 

 

이전에 실행했던 turtlebot3_teleop_key 패키지로 로봇를 움직이면, 이에 따라 맵을 추가적으로 만드는 모습을 볼 수 있습니다.

 

어느정도 지도를 만들고 나면, 다음 명령으로 해당 지도를 저장합니다. 실행한 가제보 환경 전체의 지도를 만들어도 되지만, 일단 위 그림 정도의 지도만 저장하여 사용하겠습니다.

 

$ rosrun map_server map_saver

 

 위 패키지를 실행하면  map.png, map.yaml 파일이 생기는데, 이 파일들을 내비게이션에 이용하게 됩니다. 이 두 파일은 같은 디렉토리에 있어야 합니다.

 

 

- 예제 1.1 끝

 


 

이 전체 과정에 대해 궁금하실 수 있는데, 이번 포스트는 단지 basic concept 입니다. 더 자세한 내용은 이후 포스트에 설명하겠습니다. 지금은 단지 이 과정의 일반적인 사진만 있어도 됩니다.

 

 

2. 만들어진 지도에서의 위치추정

이전에, 로봇이 내비게이션을 수행하기 위해서는 지도가 필요하다고 했습니다만, 이것으로 충분할까요? 물론 아닙니다. 아무리 정확한 지도가 있다고 해도, 이 지도에서 로봇이 자신이 어디있는지 모른다면 이는 전혀 필요가 없습니다. 즉, 적절한 내비게이션의 수행을 위해서는 매 순간 우리 로봇이 맵에서 어떤 위치에 있는지, 그리고 어떤 방향을 향하는지를 알아야 합니다. ROS Navigation의 용어로는 이를 위치추정(Localization)이라고 합니다.

 

이제, turtlebot3가 어떻게 자신의 위치를 추정하는지 보겠습니다.

 


- 예제 1.2

 

이전에 만들었던 지도를 사용하여 내비게이션을 실행하도록 합니다. turtlebot3의 navigation패키지의 launch파일을 수정하여 아까 만들었던 맵을 사용하도록 합니다.

 

$ atom /home/<user_name>/catkin_ws/src/turtlebot3/turtlebot3_navigation/launch/turtlebot3_navigation.launch

 

 

수정했으면, 다음 명령을 실행합니다. (이전에 실행했던 SLAM 패키지는 종료하세요)

 

$ roslaunch turtlebot3_navigation turtlebot3_navigation.launch

 

 

이와 같이 작은 초록색 화살표들이 많이 나타난 모습을 보게 될텐데, 이 화살표들은 현재 추정되는 로봇의 위치와 방향을 나타냅니다. 즉, 로봇은 저 모든 화살표들 중 하나일 것이라고 추정하는 것입니다. 하지만, 현재는 로봇의 위치가 제대로 나타나지 않은 것을 볼 수 있습니다.  따라서 현재 로봇의 위치와 방향에 맞게 지도에서의 로봇의 위치를 바꿔줘야 합니다. 이는 상단 UI의 2D Pose Estimate를 사용하여 로봇의 위치를 바꿔줄 수 있습니다.

 

 

이렇게 로봇의 위치를 조절하고, 키보드를 사용하여 움직여보세요. 로봇의 초기 위치를 현재 위치와 정확하게 맞출 필요는 없습니다. 적당히 비슷하게만 맞춰주면, 로봇이 움직임에 따라 자신의 위치를 추정하게 되며, 자신의 위치로 추정되는 곳으로 화살표들이 점차 모이게 됩니다.

 

 

최종적으로, 위와 같이 로봇의 위치를 나타내게 됩니다.

 

- 예제 1.2. 끝


위에서 말했듯이, 위치 추정에 대한 자세한 내용은 나중에 설명하겠습니다.

 

3. 이제 로봇에게 목표 지점의 위치를 보낼 수 있습니다.

이제 로봇이 환경에 대한 지도를 만들고, 위치를 찾을 수 있도록 하는 첫 번째 단계인 지도 작성을 끝냈습니다. 이제 다음 단계는 내비게이션입니다.

 

이를 위해서는, 먼저 로봇이 어디로 가야할지 말해주고, 다음으로 어떻게 가야할지 알려주는 시스템이 필요합니다. ROS에서는, 이를 경로 계획(Path Planning)이라고 합니다. 이 경로 계획은 기본적으로 현재 로봇의 위치와 목표 위치를 입력으로 받고, 해당 목표 위치로 가는 가장 빠르고 좋은 경로를 출력으로 합니다. 다음으로, 이게 어떻게 동작하는지 보겠습니다.

 


- 예제 1.3.

 

예제 1.2과 같은 상태에서 시작합니다. 이번에는 2D Pose Estimate 옆에 있는 2D Navi Goal을 사용하여 목표 지점을 선택하면, 로봇이 자동으로 주행하는 모습을 볼 수 있습니다.

 

 

- 예제 1.3. 끝


그런데, 로봇은 어떻게 최적의 경로를 알까요? 이 경로를 계산하기 위해 기존에 만들었던 지도를 사용해서 그럴까요? 다음 포스트에서는 이에 대해 알아볼 것입니다.


4. 장애물을 피해야 합니다.

ROS는 예를 들어 탁자같은 장애물을 어떻게 피하도록 할까요? 만약 누군가 로봇의 진행 경로 앞에 갑자기 나타난다면 어떻게 될까요? 로봇이 그 사람을 알아챌까요? 로봇이 장애물을 피할 수 있을까요? 이 모든 질문들은 장애물 회피(Obstacle Avoidance)라고 하는 하나의 topic에 관계되어 있습니다.

 

기본적으로, 장애물 회피 시스템은 큰 그림(지도)를 작은 조각들로 나누는데, 이 작은 조각들은 센서로부터 오는 데이터를 사용하여 업데이트합니다. 이 방법으로, 로봇은 갑작스러운 환경의 변화, 즉 장애물이 나타난다고 해도 이를 감지하게 됩니다.

 

이에 대한 내용은 나중에 더 자세하게 설명할 것입니다.

 

 

 

지금까지의 예제는 그냥 실행해보았지만, 사실 이런 시스템이 동작하기 위해서, 즉 ROS Navigation Stack이 적절하게 동작하기 위해서는 어떤 로봇을 사용하려고 하는지, 이 시스템이 어떻게 만들어졌는지에 따라 그 시스템에 데이터를 제공해야 합니다. 로봇을 적절하게 설정(configure)해야 한다는 것입니다.

 

로봇 설정(Robot Configuration)은 모든 내비게이션 모듈에 있어서 매우 중요합니다. 예를 들어, 맵핑 시스템에서 만약 레이저 센서의 방향이나 이런 것을 시스템에 제대로 알려주지 않는다면, 정확한 지도를 만들 수 없습니다. 이전에서 보았다시피, ROS Navigatoin에서는 좋은 지도를 가지고 있지 않다면 이는 아무 의미가 없습니다. 다음 그림은 로봇의 레이저가 제대로 설정되지 않은 경우의 예시입니다.

 

 

 

 

 

로봇을 어떻게 설정하는가?

로봇의 설정과 정의는 로봇의  URDF파일을 사용합니다. URDF(Unified Robot Description Format)은 로봇 모델을 묘사하기 위해 XML포맷을 사용합니다. 이는 로봇의 각 부분, 차원,  기구학, 역학, 센서 등등을 정의합니다. 우리가 ROS에서 3D로봇을 볼 때마다, URDF파일을 사용하게 됩니다. turtlebot3에서 레이저 센서 부분은 어떻게 되어있는지 확인해보겠습니다.

 

  <joint name="scan_joint" type="fixed">
    <parent link="base_link"/>
    <child link="base_scan"/>
    <origin xyz="-0.064 0 0.122" rpy="0 0 0"/>
  </joint>

  <link name="base_scan">
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <mesh filename="package://turtlebot3_description/meshes/sensors/lds.stl" scale="0.001 0.001 0.001"/>
      </geometry>
      <material name="dark"/>
    </visual>

    <collision>
      <origin xyz="0.015 0 -0.0065" rpy="0 0 0"/>
      <geometry>
        <cylinder length="0.0315" radius="0.055"/>
      </geometry>
    </collision>

    <inertial>
      <mass value="0.114" />
      <origin xyz="0 0 0" />
      <inertia ixx="0.001" ixy="0.0" ixz="0.0"
               iyy="0.001" iyz="0.0"
               izz="0.001" />
    </inertial>
  </link>

 

보시다시피, 레이저에 관련하여 몇 가지가 정의되었습니다.

 

  • 로봇의 베이스(base_link)에 대한 레이저의 위치와 방향을 정의
  • 관성 값 정의
  • 충돌에 관련된 값 정의. 이 값은 레이저의 실제 물리적 값(충돌 범위 등)을 제공
  • 시각적인 값을 정의. 이는 단순히 시각화 목적이며, RVIZ등에서 이 소자를 시각화 하기 위해 사용

이 파일은 보통 패키지 내부의 yourrobot_description 디렉토리에 저장합니다.

 

이번 Course에서는 URDF를 다루지는 않을것인데, 시간이 되면 나중에 이 부분에 대해 따로 포스팅 하겠습니다.

 

이렇게 URDF 말고도, 내비게이션 프로세싱을 위해서는 많은 파라미터들을 설정해야합니다. 이 파라미터들은 내비게이션 처리(맵핑이나 위치추정 등)에 포함된 다른 페이즈들의 행동(behavior)들을 수정할 수 있도록 해줍니다.

 

 

The Navigation Stack

이전의 예제들을 통해, 우리는 ROS node들을 launch했습니다. 각각의 node들은 다른 작업을 위해 ROS 프로그램들을 launch했습니다. 그런데 이 패키지들은 어디서 온 것이며, 이 패키지들은 무엇이며, 각각이 연결되어있을까요 아니면 완전히 독립적일까요?

 

우리는 ROS에서 Navigation Stack이라고 알려진 것을 실행했습니다. 이 Navigation Stack은 자동으로 로봇이 다른 지점으로 움직일 수 있게 해주고, 장애물을 피하게 해주는 모든 알고리즘과 ROS의 node들의 집합입니다.

 

Navigation Stack은 로봇의 현재 위치, 목표 위치, 오도메트리(Odometry) 데이터, 레이저 같은 센서로부터의 데이터를 입력으로 받으며, 출력은 목표지점으로 로봇을 보내기 위한 속도 명령값입니다.

 

요약하자면, Navigation Stack의 주된 목표는 로봇이 확실하게 장애물과 부딪치지 않고, 길을 잃지 않게 하며 위치 A로부터 B로 이동하도록 하는 것입니다.

 

 

 

하드웨어 요구사항

ROS Navigation Stack은 일반적입니다. 즉, 어떤 형태의 움직이는 로봇에도 사용될 수 있다는 것인데, 전체 시스템이 더 잘 작동하도록 하기 위해 하드웨어에 관련하여 고려해야 할 사항들이 있습니다. 이는 다음과 같습니다.

  • 내비게이션 패키지는 차동 구동 로봇(differential drive) 그리고 홀로노믹 로봇(holonomic robot)에서 더 잘 작동합니다. 또한, 로봇은 다음 형식의 속도 명령으로 제어되어야 합니다.
    x, y (선 속도, linear velocity)
    z (각 속도, angular velocity)
  • 로봇은 로봇 어딘가에 평면 레이저 센서를 장착해야 합니다. 이는 위치 추정과 지도 작성에 사용됩니다.
  • 사각형 또는 원형의 로봇의 경우에 더 잘 작동합니다.

아래에 나올 그림이 지금은 정확하게 이해가 되지는 않을 것이지만, 나중에는 이해가 될 것입니다. 일단은 전체적인 아이디어를 알아본다는 정도로 보겠습니다.

 

 

위의 다이어그램에 따르면, 우리는 Navigation Stack과 통신하고, 작동하기 위해  functional 블록들이 반드시 필요합니다. ROS Navigation Stack의 입력으로 사용되는 블록들은 다음과 같습니다.

 

  • Odometry source: 로봇의 오도메트리 데이터는 출발 위치에 대한 로봇의 위치를 제공해줍니다. 메인 오도메트리는 엔코더, IMU, 2D/3D카메라(visual odometry의 경우)를 사용하여 계산합니다. 오도메트리 값은 nav_msgs/Odometry 형식의 메시지를 사용하여 Navigation Stacks로 publish해야하니다. 오도메트리 메시지는 로봇의 위치와 속도값을 가질 수 있습니다.
  • Sensor source: 센서들은 내비게이션에서 두 개의 작업에 사용됩니다. 하나는 지도에서 로봇의 위치를 찾는데 쓰이고(레이저 데이터), 하나는 로봇의 경로에서 장애물을 감지(레이저, 초음파, point cloud 데이터)하는데 쓰입니다.
  • sensor transforms/tf: 로봇에 있는 각각 다른 센서들에 의해 수집된 데이터 그 데이터들을 구별할 수 있도록 반드시 common frame또는 reference frame(일반적으로 base_link)에 대한 값으로 나타내어야 합니다. 로봇은 ROS 좌표변환(transform)을 사용하여 로봇의 메인 좌표계와 센서 프레임 사이의 관계를 반드시 publish해야합니다.
  • base_controller: base controller의 메인 기능은 Navigation stack의 출력인 Twist(geometry_msgs/Twist) 메시지를 이에 대응하는 로봇의 모터의 속도로 변환하는 것입니다.

 


- 연습 1.1

 

위에서 언급했던 node들에서 사용하는 메시지를 확인해봅니다.

 

turtlebot3 시뮬레이션을 실행하고, rostopic list명령으로 topic들을 확인해봅니다.

 

$ roslaunch turtlebot3_gazebo turtlebot3_house.launch

$ rostopic list

 

 

 

 위의 topic들 중, cmd_vel, scan, odom, tf 의 정보를 확인해봅니다.

 

$ rostopic info /cmd_vel
$ rostopic info /odom
$ rostopic info /scan
$ rostopic info /tf

 

$ rosmsg show geometry_msgs/Twist
$ rosmsg show nav_msgs/Odometry
$ rosmsg show sensor_msgs/LaserScan
$ rosmsg show tf2_msgs/TFMessage

 

 

 

 

- 연습 1.1 끝

 


 

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

ROS Navigation(4. Path Planning 2)  (0) 2021.01.12
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