토픽 이해하기
목표: rqt_graph 및 명령줄 도구를 사용하여 ROS 2 토픽을 내부 조사합니다.
배경
ROS 2는 복잡한 시스템을 많은 모듈식 노드로 분해합니다. 토픽은 노드 간의 메시지 교환을 위한 버스로 작동하는 ROS 그래프의 중요한 요소입니다.
노드는 여러 토픽에 데이터를 발행하고 동시에 여러 토픽을 구독할 수 있습니다.
토픽은 데이터가 노드 간에 그리고 시스템의 다른 부분 사이에서 이동하는 주요 방법 중 하나입니다.
작업
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 를 열 수도 있습니다.
위 노드와 토픽, 그리고 그래프 주변의 두 액션(지금은 무시합시다)을 볼 수 있어야 합니다.
그래프는 /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: 아래의 모든 상자의 선택을 취소할 수 있습니다.
하지만 혼란을 피하기 위해 지금은 그 옵션을 선택한 상태로 두세요.
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 상자의 선택을 취소하세요.
/_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 노드가 세 요소 각각을 가진 두 벡터, linear 과 angular 를 포함한 메시지를 기대하고 있음을 알려줍니다.
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))
그리고 거북이가 다음과 같이 움직이는 것을 볼 수 있습니다:
거북이(그리고 일반적으로 모방하려는 실제 로봇)는 지속적으로 작동하기 위해 안정적인 명령 스트림이 필요합니다. 따라서 거북이를 계속 움직이게 하려면 다음을 실행할 수 있습니다:
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에서 명령을 안정적으로 발행하도록 지시합니다.
rqt_graph를 새로 고쳐 그래픽으로 무슨 일이 일어나고 있는지 볼 수 있습니다.
이제 ros2 topic pub ... 노드 (/_ros2cli_30358)가 /turtle1/cmd_vel 토픽을 통해 데이터를 발행하고 있으며, ros2 topic echo ... 노드 (/_ros2cli_26646)와 /turtlesim 노드가 이를 받고 있음을 볼 수 있습니다.
마지막으로, pose 토픽에 대해 echo 를 실행하고 rqt_graph를 다시 확인할 수 있습니다:
ros2 topic echo /turtle1/pose
새로운 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 시스템에서 데이터가 어떻게 이동하는지에 대해 좋은 이해를 가지고 있어야 합니다.