아마 ROS2를 사용해서 인공지능/로봇을 개발하다보면 가장 많이 접하는 용어중에 하나가 topic, node일 것이다.
이번 글에서는 그 중 하나인 topic 개념에 대해서 배워볼 예정이다.
준비되었는가?
그럼 Let's go!!
목표
대상
예상 소요시간
약 20분
로봇 내부에서는 수많은 데이터와 신호들이 오가는데, 이때 이 정보들을 message로 만들어 topic이라는 공간을 통해 message를 발행하고 구독한다.
사람을 예로 들면 "이 공간(Topic)에서는 이 message로만 이야기 할 수 있어" 로 이해하면 쉽다.
저번 시간에 배운 node는 하단의 그림 처럼 여러 topic에 message를 발행하거나 여러 topic을 구독할 수 있다.
이렇듯 topic를 이용하면 node간 데이터 교환이 정말 수월하기 때문에 로봇개발시 자주 사용된다.
이전 포스트를 통해 node라는 개념을 익혔을 것!
개발자와 함께하는 ROS2 Humble Node 이해하기, ROS2 명령어-2 바로가기
먼저 turtlesim을 실행하도록 하자
ros2 run turtlesim turtlesim_node
터미널을 하나 더 열어 teleop_key도 같이 실행해주자
ros2 run turtlesim turtle_teleop_key
이제 rqt_graph라는 것을 실행해보자.
rqt_graph는 간단히 말해 node와 topic간에 연결 상태를 시각화해주는 툴이라 생각하면 되겠다.
실행하는 방법은 다음 명령어를 터미널에 입력한다.
rqt_graph
그럼 다음과 같은 창이 보일 것이다.
*참고로 rqt를 실행해 Plugins -> Instropection -> Node Graph를 선택해도 rqt_graph를 실행한 것과 같은 효과를 볼 것이다.
이 이미지에는 /teleop_turtle, /turtlesim이라는 node와 /turtle/cmd_vel이라는 topic이 존재 하는 것을 볼 수 있다. /turtle1/rotate_absolute/_action/status, /turtle1/rotate_absolute/_action/feedback이라는 action도 보이지만 오늘의 주제는 아니므로 잠시 신경끄도록 하자!
또한 마우스를 topic 이름, /turtle1/cmd_vel 위에 올리면 위의 그림과 같이 색이 보이는 것(highlighting기능)을 확인할 수 있다.
이 그림에서 /turtlesim node와 /teleop_turtle이 /turtle1/cmd_vel이라는 topic을 통해서 메세지 전송이 일어남을 시각화하고 있다.
즉, /teleop_turtle은 /turtle1/cmd_vel토픽에 message를 발행(publish)하고 /turtlesim은 이 topic을 구독(subscribe)함으로써 message를 획득한다.
앞서 언급한 highlighting 기능은 복잡한 시스템의 rqt_graph를 살펴볼 때 어떤 node와 topic들이 연결되있는지 볼 때 유용하다.
rqt_graph가 시각화 도구라면 terminal에서 메세지를 출력하는 방식의 도구도 있다.
터미널에 다음 명령어를 실행해보자
ros2 topic list
이 명령어는 현재 존재하는 모든 topic이름들을 나열해준다.
예시) /turtlesim, /teleop_turtle node에 있는 topic들
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
추가로 -t라는(message type의 t) 명령어를 추가로 입력하면 topic에 발행되는 message의 type도 출력해준다.
/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]
그런데 잠깐 이상한걸 눈치챈 독자들이 있는가?
ros2 topic list에 출력된 목록과 rqt_graph에 나왔던 topic들이 다르다.
그렇다. 사실 아까 rqt_graph에서 Hide라는 checkbox가 선택되어 있어서 일부 존재하지만 딱히 사용되지 않고 있은 topic들을 보이지 않았다.
너무 많으면 오히려 헷갈리니 다시 Hide를 체크해두자
topic에 발행되는 message를 확인하기 위해 다음과 같은 명령어를 사용한다.
ros2 topic echo <topic 이름>
앞서 rqt_graph에서 /teleop_turtle node가 /turtlesim node에 /turtle1/cmd_vel topic을 통해 message를 발행한다는 것을 알았다.
한 번 어떤 message인지 봐볼까?
터미널에 다음과 같은 명령어를 실행한다.
ros2 topic echo /turtle1/cmd_vel
?? 아무 message도 뜨질 않는다.
3초 생각해보자
1
2
3
!
그렇다 지금 우리는 속도를 나타내는 message를 보내고 있지 않기 때문이다.
echo 한 터미널이 잘 보이게 위치 시킨 후
turtle_teleop_key를 실행한 터미널로가서 방향키를 눌러 속도를 나타내는 message를 보내보자!
이제 다음과 같은 메세지가 echo 명령어를 실행한 터미널에 출력되는 것을 볼 수 있을 것이다.
Hurray!!!
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
rqt_graph로 가서 Debug라 적인 box를 클릭하여 uncheck해보자
echo도 사실 고유 이름을 갖는 임의의 node를 생성하여 /turtle1/cmd_vel topic을 구독하고 여기에 들어온 message를 출력해준다.
topic이 용이한 이유는 일대일 통신일 필요가 없어서 이다.
즉, 일대다, 다대일, 다대다 통신이 가능하다는 것이다. wow
이걸 어떻게 아냐고?
새 터미널을 열어서 다음 명령어를 입력해보자.
이 명령어는 관심 topic의 정보를 제공한다.
ros2 topic info /turtle1/cmd_vel
Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 2
이는 즉 /turtle1/cmd_vel라는 topic에 message를 발행하는 자(Publisher count)는 1명, 구독하는자는 2명임을 말해준다.
topic을 통해 node가 데이터를 주고 받는 다는 것을 확인했다.
그런데 아까 데이터를 주고 받는 node 속에는 발행자(이하 publisher)와 구독자(이하 subscriber)가 있다고 했는데 이들이 정상적으로 데이터를 주고 받으려면 같은 message type을 사용해야한다.
/turtle1/cmd_vel의 message type은 다음과 같았다.
geometry_msgs/msg/Twist
이 type의 의미를 풀이해보면 geometry_msgs 패키지 안에 msg 중 Twist라는 type이 있다는 이야기다.
그렇다 패키지는 excutable, node뿐만 아니라 message(또는 msg)도 갖고 있을 수 있다.
또한, ros2 interface show <message 타입> 이라는 명령어로 message에 어떤 정보가 있는지 알 수 있다.
ros2 interface show geometry_msgs/msg/Twist
위의 명령어를 입력했다면 다음과 같은 정보가 출력될 것이다.
# This expresses velocity in free space broken into its linear and angular parts.
Vector3 linear
float64 x
float64 y
float64 z
Vector3 angular
float64 x
float64 y
float64 z
의미를 살펴보자면 linear는 선속도(x,y,z축 방향으로), 그리고 angular는 각속도(각을 나타내는 축 또한 x,y,z축을 정의할 수 있다)를 의미한다.
그리고 각각의 속도는 Vector3라는 데이터 타입을 갖는데 이때 숫자 3은 성분이 x,y,z로써 3개라서 그렇다.
이 선속도, 각속도는 추후 자세하게 배울 것이니 그냥 로봇의 속도를 나타내는 message구나 라고 생각하면 된다.
topic 이름과 message type을 알고 있으면
다음 명령어를 사용하여 터미널에서 해당 topic에 message를 임의로 발행(이하 publish)해줄 수 있다.
ros2 topic pub <topic 이름> <message 타입> '<message 내용(데이터)>'
그렇다면 아까 확인한 Twist라는 message를 다음과 같이 publish해보자
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}}"
명령어의 의미를 살펴보자면 /turtle1/cmd_vel 이라는 topic에 geometry_mags 패키지 안 msg 폴더에 있는 Twist message를 x축 선속도는 2.0, y축, z축 선속도는 0.0, x,y축 각속도는 0.0, z축 각속도는 1.8로 설정해서 publish해줘 라는 말이 된다.
이때 once는 딱 한번만 message를 publish하라는 말이다.
명령어를 입력했다면 다음과 같이 터미널에 표시될 것이다.
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))
그렇다면 TurtleSim 창에 있는 turtle을 다음과 같이 움직였을 것이다.
메세지를 한번만 publish했기 때문에 일정 거리를 움직이고 멈추는 것을 관찰 할 수 있다.
계속적으로 움직이게 하고 싶다면 --once 대신 --rate라는 인자를 사용하면 된다. rate는 Hz(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 1 로 대체됐는데 이는 1Hz로 Twist message를 publish 계속 해줘 라는 말이다.
아래와 같이 로봇이 원형의 궤적을 그렸다면 성공!
이제 rqt_graph창으로가서 refresh 버튼을 눌러보면(파란색 원형 화살표) 새로운 publisher가 생긴 것을 확인 할 수 있다.
하단의 이미지는 /_ros2cli_30358이라는 node가 ros2 topic pub 명령어에 의해 생성되 /turtle1/cmd_vel topic에 publish하고 있는 모습을 보여준다.
topic이 존재하지만 다른 node와 연결되지 않아 숨어있는 topic이있는데 그 중 하나가 /turtle1/pose 이다. 이는 turtle1의 자세 정보를 전달 및 수신하는데 사용된다.
그러면 ros2 topic echo를 이용해 새롭게 node를 만들어주면 rqt_graph에서는 다음과 같이 /_ros2cli_1682라는 node에 /turtle1/pose가 연결된 것을 확인 할 수 있다.
ros2 topic echo /turtle1/pose
마지막으로 ros2 topic hz라는 명령어가 있다.
hz라는게 무슨 의미일까? 2초간 생각해보자.
1
2
그렇다 Hz(1초당 몇회)라는 단위에서 나온 것인데
다음과 같은 명령어를 사용하면 1초당 해당 topic이 몇 번 publish되는지 알 수 있다.
ros2 topic hz <topic 이름>
그렇다면 /turtle1/pose에 얼마나 message가 publish되는지 알기위해선 다음과 같은 명령어를 실행하면 된다.
ros2 topic hz /turtle1/pose
그러면 터미널에 다음과 같이 평균적으로 몇번이나 1초에 message가 publish되는지 알려준다.
참고로 min max std dev 등은 message가 publish되는데 걸린 최소, 최대, 표준편차 시간을 의미한다.
average rate: 59.354
min: 0.005s max: 0.027s std dev: 0.00284s window: 58
여태까지 topic의 개념과 관련된 명령어 도구들을 엄청 배웠다.
ROS2로 인공지능/로봇 개발 하다보면 유용한 개념이라 엄청 사용하게 될 것이다.
그렇기 때문에 관련 도구들도 다양했다.
아직 낯설더라도 자주쓰다보면 손에 익혀지는 부분이니 너무 걱정하지 않아도 된다.
일단 여기까지 온 스스로에게 엄지척 해주자 ㅎㅎ
질문하고 싶거나 인공지능 & 로봇 개발에 대해 다뤄줬으면 하는 주제를 댓글로 남겨주세요!
문의메일: irobou0915@gmail.com
오픈톡 문의: https://open.kakao.com/o/sXMqcQAf
IRoboU 유튜브 채널: https://www.youtube.com/channel/UC2-d99PrBwJy15MjPa32zYg