토픽 이해하기

목표: rqt_graph 및 명령줄 도구를 사용하여 ROS 2 토픽을 내부 조사합니다.

배경

ROS 2는 복잡한 시스템을 많은 모듈식 노드로 분해합니다. 토픽은 노드 간의 메시지 교환을 위한 버스로 작동하는 ROS 그래프의 중요한 요소입니다.

../../_images/Topic-SinglePublisherandSingleSubscriber.gif

노드는 여러 토픽에 데이터를 발행하고 동시에 여러 토픽을 구독할 수 있습니다.

../../_images/Topic-MultiplePublisherandMultipleSubscriber.gif

토픽은 데이터가 노드 간에 그리고 시스템의 다른 부분 사이에서 이동하는 주요 방법 중 하나입니다.

사전 준비

이전 튜토리얼 은 여기에서 확장되는 노드에 대한 유용한 배경 정보를 제공합니다.

항상, 새로운 터미널을 열 때마다 ROS 2를 소싱하는 것을 잊지 마세요.

작업

1 설정

이제 turtlesim을 시작하는 데 익숙해졌을 것입니다.

새 터미널을 열고 다음을 실행하세요:

ros2 run turtlesim turtlesim_node

다른 터미널을 열고 실행하세요:

ros2 run turtlesim turtle_teleop_key

이전 튜토리얼 에서 이 노드들의 기본 이름이 /turtlesim/teleop_turtle 임을 기억하세요.

2 rqt_graph

이 튜토리얼 전반에 걸쳐, 변화하는 노드와 토픽, 그리고 그들 사이의 연결을 시각화하기 위해 rqt_graph 를 사용할 것입니다.

turtlesim 튜토리얼 은 rqt와 모든 플러그인, rqt_graph 를 포함하여 설치하는 방법을 알려줍니다.

rqt_graph를 실행하려면, 새 터미널을 열고 다음 명령을 입력하세요:

rqt_graph

rqt 를 열고 플러그인 > 내부 조사 > 노드 그래프 를 선택하여 rqt_graph 를 열 수도 있습니다.

../../_images/rqt_graph.png

위 노드와 토픽, 그리고 그래프 주변의 두 액션(지금은 무시합시다)을 볼 수 있어야 합니다. 그래프는 /turtlesim 노드와 /teleop_turtle 노드가 토픽을 통해 서로 통신하는 방법을 묘사하고 있습니다. /teleop_turtle 노드는 데이터(거북이를 움직이기 위해 입력하는 키 입력)를 /turtle1/cmd_vel 토픽으로 발행하고, /turtlesim 노드는 그 토픽을 구독하여 데이터를 받습니다.

rqt_graph의 하이라이팅 기능은 많은 노드와 토픽이 다양한 방식으로 연결된 더 복잡한 시스템을 검사할 때 매우 유용합니다.

rqt_graph는 그래픽 내부 조사 도구입니다. 이제 토픽을 내부 조사하기 위한 몇 가지 명령줄 도구를 살펴보겠습니다.

3 ros2 topic list

새 터미널에서 ros2 topic list 명령을 실행하면 시스템에서 현재 활성화된 모든 토픽의 목록을 반환합니다:

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

ros2 topic list -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: 아래의 모든 상자의 선택을 취소할 수 있습니다.

../../_images/unhide.png

하지만 혼란을 피하기 위해 지금은 그 옵션을 선택한 상태로 두세요.

4 ros2 topic echo

토픽에서 발행되는 데이터를 보려면 다음을 사용하세요:

ros2 topic echo <topic_name>

/teleop_turtle/turtle1/cmd_vel 토픽을 통해 /turtlesim 에 데이터를 발행한다는 것을 알고 있으므로, 그 토픽을 조사하기 위해 echo 를 사용해봅시다:

ros2 topic echo /turtle1/cmd_vel

처음에는 이 명령이 데이터를 반환하지 않습니다. 그 이유는 /teleop_turtle 이 무언가를 발행하기를 기다리고 있기 때문입니다.

turtle_teleop_key 가 실행 중인 터미널로 돌아가서 화살표를 사용해 거북이를 움직이세요. 동시에 echo 가 실행 중인 터미널을 보면, 움직임을 만들 때마다 위치 데이터가 발행되는 것을 볼 수 있습니다:

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

이제 rqt_graph로 돌아가서 Debug 상자의 선택을 취소하세요.

../../_images/debug.png

/_ros2cli_26646 은 방금 실행한 echo 명령에 의해 생성된 노드입니다(숫자는 다를 수 있음). 이제 발행자가 cmd_vel 토픽을 통해 데이터를 발행하고 두 구독자가 그것을 구독하고 있음을 볼 수 있습니다.

5 ros2 topic info

토픽은 단일 대 단일 통신만을 의미하지 않으며, 하나 대 다수, 다수 대 하나, 또는 다수 대 다수의 통신도 가능합니다.

이를 확인하는 또 다른 방법은 다음을 실행하는 것입니다:

ros2 topic info /turtle1/cmd_vel

그러면 다음과 같은 결과가 반환됩니다:

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

6 ros2 interface show

노드는 메시지를 사용하여 토픽을 통해 데이터를 전송합니다. 발행자와 구독자는 통신을 위해 동일한 유형의 메시지를 보내고 받아야 합니다.

앞서 ros2 topic list -t 를 실행한 후 본 토픽 유형은 각 토픽에서 사용되는 메시지 유형이 무엇인지 알려줍니다. cmd_vel 토픽의 유형은 다음과 같습니다:

geometry_msgs/msg/Twist

이는 geometry_msgs 패키지에 Twist 라는 msg 가 있음을 의미합니다.

이제 이 유형에 대해 ros2 interface show <msg type> 를 실행하여 그 세부 사항을 알아볼 수 있습니다. 특히, 메시지가 예상하는 데이터 구조가 무엇인지에 대해 알 수 있습니다.

ros2 interface show geometry_msgs/msg/Twist

위 메시지 유형에 대해 다음을 반환합니다:

# 이것은 자유 공간에서의 속도를 선형  각속도 부분으로 나누어 표현합니다.

    Vector3  linear
            float64 x
            float64 y
            float64 z
    Vector3  angular
            float64 x
            float64 y
            float64 z

이것은 /turtlesim 노드가 세 요소 각각을 가진 두 벡터, linearangular 를 포함한 메시지를 기대하고 있음을 알려줍니다. echo 명령을 사용하여 /teleop_turtle/turtlesim 에 전달한 데이터를 기억한다면, 그것은 같은 구조입니다:

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

7 ros2 topic pub

이제 메시지 구조를 알았으니, 명령줄을 사용하여 직접 토픽에 데이터를 발행할 수 있습니다:

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

'<args>' 인자는 앞선 섹션에서 발견한 구조에 따라 토픽에 전달할 실제 데이터입니다.

이 인자는 YAML 구문으로 입력해야 한다는 점을 주목하세요. 전체 명령을 다음과 같이 입력하세요:

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 는 “한 번 메시지를 발행한 후 종료”를 의미하는 선택적 인자입니다.

터미널에는 다음과 같은 출력이 표시됩니다:

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))

그리고 거북이가 다음과 같이 움직이는 것을 볼 수 있습니다:

../../_images/pub_once.png

거북이(그리고 일반적으로 모방하려는 실제 로봇)는 지속적으로 작동하기 위해 안정적인 명령 스트림이 필요합니다. 따라서 거북이를 계속 움직이게 하려면 다음을 실행할 수 있습니다:

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 1 옵션을 추가한 것으로, ros2 topic pub 에게 1Hz에서 명령을 안정적으로 발행하도록 지시합니다.

../../_images/pub_stream.png

rqt_graph를 새로 고쳐 그래픽으로 무슨 일이 일어나고 있는지 볼 수 있습니다. 이제 ros2 topic pub ... 노드 (/_ros2cli_30358)가 /turtle1/cmd_vel 토픽을 통해 데이터를 발행하고 있으며, ros2 topic echo ... 노드 (/_ros2cli_26646)와 /turtlesim 노드가 이를 받고 있음을 볼 수 있습니다.

../../_images/rqt_graph2.png

마지막으로, pose 토픽에 대해 echo 를 실행하고 rqt_graph를 다시 확인할 수 있습니다:

ros2 topic echo /turtle1/pose
../../_images/rqt_graph3.png

새로운 echo 노드가 구독하고 있는 pose 토픽에도 /turtlesim 노드가 발행하고 있음을 볼 수 있습니다.

타임스탬프가 있는 메시지를 발행할 때, pub 은 현재 시간으로 자동으로 채워주는 두 가지 방법을 가지고 있습니다. std_msgs/msg/Header 를 가진 메시지의 경우, 헤더 필드를 auto 로 설정하여 stamp 필드를 채울 수 있습니다.

ros2 topic pub /pose geometry_msgs/msg/PoseStamped '{header: "auto", pose: {position: {x: 1.0, y: 2.0, z: 3.0}}}'

메시지가 전체 헤더를 사용하지 않고 builtin_interfaces/msg/Time 유형의 필드만 가지고 있는 경우, 그 값을 now 로 설정할 수 있습니다.

ros2 topic pub /reference sensor_msgs/msg/TimeReference '{header: "auto", time_ref: "now", source: "dumy"}'

8 ros2 topic hz

이 과정에 대한 마지막 내부 조사로, 데이터가 발행되는 속도를 보는 것입니다:

ros2 topic hz /turtle1/pose

/turtlesim 노드가 pose 토픽에 데이터를 발행하는 속도에 대한 데이터를 반환합니다.

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

turtle1/cmd_vel 의 속도를 안정적인 1Hz로 설정했음을 기억하세요. ros2 topic pub --rate 1 을 사용한 것입니다. 위 명령을 turtle1/cmd_vel 로 실행하면, 그 속도를 반영하는 평균을 볼 수 있습니다.

9 정리

이 시점에서 많은 노드가 실행 중일 것입니다. 각 터미널에서 Ctrl+C 를 입력하여 그들을 멈추는 것을 잊지 마세요.

요약

노드는 토픽을 통해 정보를 발행하며, 이를 통해 다른 노드가 그 정보를 구독하고 접근할 수 있습니다. 이 튜토리얼에서는 rqt_graph와 명령줄 도구를 사용하여 여러 노드 사이의 토픽을 통한 연결을 검사했습니다. 이제 ROS 2 시스템에서 데이터가 어떻게 이동하는지에 대해 좋은 이해를 가지고 있어야 합니다.

다음 단계

다음으로, ROS 그래프에서 다른 통신 유형에 대해 배우게 될 서비스 튜토리얼 로 넘어갑니다.