Knowhow/ROS2

[ROS2 Foxy Tutorial 한글 번역] 4. Understanding topics

침닦는수건 2023. 2. 1. 01:34
반응형

Link

https://docs.ros.org/en/foxy/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Topics/Understanding-ROS2-Topics.html

 

Understanding topics — ROS 2 Documentation: Foxy documentation

You're reading the documentation for an older, but still supported, version of ROS 2. For information on the latest version, please have a look at Humble. Understanding topics Goal: Use rqt_graph and command line tools to introspect ROS 2 topics. Tutorial

docs.ros.org

 

Background

ROS 2는 복잡한 로봇 시스템을 작은 기능 단위의 노드로 쪼갠다. Topic은 노드 간의 메세지를 주고 받는 버스와 같은 역할을 하므로 ROS graph의 핵심적인 요소 중 하나라고 할 수 있다.

(위 그림에서 topic이 흘러가는 줄 알았는데 메시지가 흘러가는 모습을 보고 혼동이 되었다. 내가 이해한 바는 topic은 버스와 같고 메시지는 그 안에 타있는 사람과 같다. 버스 노선이 먼저 깔려 어디서 어디로 이동할지 정해진 뒤에야 사람이 그 버스를 타고 흐를 수 있음과 비슷하다. topic을 버스 노선이자 버스라고 이해하는게 좋을 듯 하다.)

 

노드는 데이터를 수많은 topic으로 publish함과 동시에 수많은 topic을 subscription하기도 한다.

노드 간 데이터 이동의 주된 방식인 topic은 1대1, 1대多, 多대1 로도 만들 수 있다. 

 

Prerequisites

2023.01.31 - [Develop/ROS2] - [ROS2 Foxy Tutorial 한글 번역] 3. Understanding nodes 이전 글의 연장선 상에 있으므로 잘 숙지하면 도움이 된다. 

 

당연하게도, ROS2 sourcing하는 것은 잊지 말자. 

 

Tasks

1. Setup

지금까지 튜토리얼을 잘 따라왔다면 turtlesim 사용은 조금 편해졌을 것이다. 

 

새 터미널을 열고 다음 커맨드를 실행한다.

ros2 run turtlesim turtlesim_node

역시 새 터미널을 열고 다음 커맨드를 실행한다.

ros2 run turtlesim turtle_teleop_key

이전 글에서도 봤듯이 위에 실행된 두 노드의 이름이 각각 /turtlesim과 /teleop_turtle 이라는 점을 기억하자.

 

2. rqt_graph

이번 튜토리얼을 통해서 노드와 토픽 변화, 그리고 그 사이 연결 관계를 시각화해주는 rqt_graph 를 사용하게 된다.

 

2023.01.31 - [Develop/ROS2] - [ROS2 Foxy Tutorial 한글 번역] 2. Using turtlesim and rqt 이전 글에서 rqt와 관련 plugin 들을 어떻게 설치하는지 언급한 바 있으니 참고하면 되겠다.

 

rqt_graph를 실행하기 위해 새로운 터미널을 열고 다음 커맨드를 입력한다.

rqt_graph

직접 rqt_graph를 입력하지 않고 rqt를 먼저 실행한 뒤에 Plugins > Introspection > Node Graph 순서대로 클릭해도 같은 결과를 얻을 수 있다. 

위와 같이 노드, 토픽 그리고 (아직은 몰라도 되는) 액션들이 각각 다른 도형으로 표현되어 있는 것을 볼 수 있다. 마우스를 각 도형 위에 올려보면 타겟의 색깔이 변하는 것을 볼 수 있다. 

 

그래프는 어떻게 /turtlesim 노드와 /teleop_turtle 노드가 토픽을 통해 소통하는지 그림으로 보여준다. /teleop_turtle 노드가 (사용자가 키보드 입력으로 거북이를 이동시키면) 데이터를 /turtle1/cmd_vel 토픽으로 publish하고 /turtlesim 노드는 해당 토픽을 통해 데이터를 subscribe한다. 

 

하이라이트 되는 rqt_graph의 시각적 효과는 보다 많은 노드와 토픽이 연결되어 있어 복잡한 시스템을 분석할 때 도움이 된다. 

 

rqt_graph는 시각적으로 시스템을 파악하는 것을 도와주는 도구였고 다음은 커맨드 라인 도구를 소개하겠다.

 

(그림이 위 예시와 다를 수 있다. 마치 아래 그림과 같을 수 있다. 이는 Group: 의 수가 달라 시각화가 달라졌을 뿐이다.)

3. ros2 topic list

"ros2 topic list" 커맨드를 새 터미널에서 실행하면 다음과 같이 현 시스템에서 활성화되어 있는 모든 토픽들이 나열된다.

/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

"ros2 topic list -t"와 같이 -t 태그를 추가하면 토픽 유형이 []안에 추가 표시 된다. 

/parameter_events [rcl_interfaces/msg/ParameterEvent]
/rosout [rcl_interfaces/msg/Log]
/turtle1/cmd_vel [geometry_msgs/msg/Twist]
/turtle1/color_sensor [turtlesim/msg/Color]
/turtle1/pose [turtlesim/msg/Pose]

이러한 내용들, 특히 토픽 유형은 노드가 어떻게 토픽 안의 데이터를 같은 정보로 인식하며 서로 소통하는지를 보여준다. 

 

만약 rqt_graph 상에서 위에 출력된 결과가 어딨는지 보고 싶다면 Hide: 옆에 있는 check box들을 전부 해제하면 보인다.

혼란을 방지하기 위해선 그대로 check해둔 상태로 넘어가도록 하자.

 

4. ros2 topic echo

토픽으로 publish되는 데이터를 보고 싶으면 다음 커맨드를 사용해라.

ros2 topic echo <topic_name>

우리 예제에서는 /teleop_turtle이 /turtle1/cmd_vel 토픽을 통해 데이터를 /turtle_sim으로 publish하고 있다는 것을 알고 있으니 다음과 같이 쓰면 되겠다.

ros2 topic echo /turtle1/cmd_vel

맨 처음엔 입력을 해도 아무런 내용도 터미널에 출력되지 않을 것이다. 이는 /teleop_turtle이 뭔가를 publish할 때까지 무한 대기 중이기 때문이다. 

 

turtle_teleop_key 노드가 실행된 터미널로 돌아와 키보드 화살표를 이용해 거북이를 이동시켜 보라. 그리고 echo를 실행했던 터미널에 동시에 무엇이 출력되는지 봐라. 실시간으로 거북이의 움직임에 대한 데이터가 publish되고 있음을 확인할 수 있다. 

linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
  ---

이제 rqt_graph로 돌아와 Debug box를 체크해제 해봐라.

/_ros2cli_26646 이라는 노드가 echo에 의해 생성되었다. publisher가 publish한 데이터를 이젠 cmd_vel과 더불어 총 2개의 subscriber가 subcribe하고 있다는 것을 확인할 수 있다. 

 

(거북이 회전은 왜 출력 안되냐고 질문할 수 있을 것 같은데 튜토리얼 상 거북이 회전은 action으로 구현되어 있다. 따라서 topic 관련 커맨드가 먹히지 않는 것이다. )

 

5. ros2 topic info

토픽은 1대1 소통 방식만 지원하지 않는다. 1대多, 多대1, 多대多도 지원한다. 

 

이를 직접 관찰할 수 있는 방법은 다음 커맨드이다. 

ros2 topic info /turtle1/cmd_vel

다음과 같이 확인할 수 있다.

Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 2

 

6. ros2 interface show

노드는 메시지 형태로 토픽을 통해 데이터를 전송한다. publisher와 subcriber는 반드시 같은 타입의 메시지를 서로 주고 받으며 소통해야 한다. 

 

"ros2 topic list -t"를 입력해서 볼 수 있었던 토픽 타입은 어떤 메시지 타입이 사용되었는지를 같이 갖고 있다. cmd_vel 토픽의 타입을 다시 한 번 보자.

geometry_msgs/msg/Twist

이는 geometry_msgs 패키지 내에 Twist라고 불리는 메시지가 있다는 뜻이다. 

 

관련 세부 내용을 확인하기 위해 "ros2 interface show <msg type>" 커맨드를 사용할 수 있다. 이는 메시지가 기대하는 데이터의 구조를 잘 보여준다.

ros2 interface show geometry_msgs/msg/Twist

출력 결과는 다음과 같다.

This expresses velocity in free space broken into its linear and angular parts.

    Vector3  linear
    Vector3  angular

이는 /turtlesim 노드는 두가지 벡터(linear, angular)를 포함하고 있는 메시지를 기본으로 한다는 것을 알 수 있다. 이는 아까 /teleop_turtle이 /turtle_sim으로 보내는 토픽을 echo해봤을 때 출력된 결과와 동일한 구조다. 

linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
  ---

 

7. ros2 topic pub

이제 메시지 구조를 알 수 있기 때문에 직접적으로 토픽을 통해 데이터를 publish할 수도 있다. 

ros2 topic pub <topic_name> <msg_type> '<args>'

'<args>' 가 실제 토픽을 통해 이동할 데이터이며 이전 6. 에서 발견한 메시지 구조를 만족하는 형태다. 

 

이 값은 반드시 YAML syntax로 표현되어 있어야 한다. 최종 예제 커맨드는 다음과 같다.

ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"

--once 는 추가 argument인데  단 한 번만 수행하고 종료하라는 뜻이다. 

 

다음과 같은 출력 결과를 얻을 수 있다.

publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

윈도우에 보이는 결과는 다음과 같다.

거북이(혹은 실제 사용할 로봇)는 보통 연속적으로 움직이는 것이 당연하다고 생각해서 연속 실행을 원할 경우, 다음과 같이 커맨드를 변경해서 1회 실행이 아닌 연속 움직임을 수행하도록 할 수도 있다. 

ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"

--once 옵션과 다른 점은 --rate N 옵션은 ros2 topic pub 커맨드를 N Hz 주기로 계속 호출하는 것과 같은 효과다. 

'

rqt_graph로 돌아와 시각적으로 어떤 변화가 있었는지 보자. ros2 topic pub ... 노드(/_ros2cli_30358)이 /turtle1/cmd_vel 토픽을 통해 데이터를 publish하고 있다는 것을 볼 수 있고 이 데이터는 ros2 topic echo ... 노드(/_ros2cli_26646)와 /turtlesim 노드가 subscribe하고 있다는 것도 볼 수 있다.

최종적으로 pose 토픽을 echo하고 rqt_graph를 확인해보자.

ros2 topic echo /turtle1/pose

/turtlesim 노드가 pose 토픽을 통해 데이터를 publish하고 있고, echo 노드가 subcribe하고 있음을 볼 수 있다.

 

8. ros2 topic hz

마지막 남은 커맨드는 데이터가 publish되고 있는 주기를 알아보는 커맨드다.

ros2 topic hz /turtle1/pose

이는 /turtlesim 노드가 pose 토픽을 통해 얼마나 잦은 주기로 데이터를 publish하고 있는지 알 수 있다.

average rate: 59.354
  min: 0.005s max: 0.027s std dev: 0.00284s window: 58

위 결과는 pose 토픽 publish 평균 주기를 보여준다. 

 

아까 ros2 topic pub --rate 1 커맨드를 통해 turtle1/cmd_vel 토픽의 주기를 1로 바꾸어 두었기 때문에 만약 cmd_vel 토픽을의 hz를 확인했다면 정확히 1.0이 나왔을 것이다. 

 

9. Clean up

지금까지 열었던 많은 터미널을 전부 Ctrl+C로 꺼주자.

 

Summary

노드는 토픽을 통해서 데이터를 publish하며 이는 또 다른 다수의 노드가 subscribe할 수 있다. 이번 튜토리얼에서는 노드 간의 토픽을 통한 연결을 rqt_graph와 command line tool을 이용하여 관찰해보았다. 이제 데이터가 ROS2 시스템에서 어떻게 이동하는지 감을 조금 잡았으면 좋겠다.

반응형