| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Operating System
- DFS
- Linux
- ubuntu 22.04
- SQLD
- computer vision
- Python
- Humble
- CPP
- Optimization
- 밑바닥부터 시작하는 딥러닝2
- C++
- Process
- file system
- CNN
- On-memory file system
- assignment2
- assignment1
- do it! 알고리즘 코딩테스트: c++편
- Gentoo2
- cs231n
- Machine Learning
- ROS2
- Baekjoon
- deep learning
- BFS
- System Call
- Seoul National University
- Data Science
- RNN
- Today
- Total
newhaneul
[ROS2 Humble] Python으로 ROS2 토픽 다루기 본문
본 포스팅은 '민형기 저자의 'ROS2 Humble 혼자 공부하는 로봇SW 직접 만들고 코딩하자'를 읽고 공부한 내용을 정리하기 위한 포스팅입니다.
1. rclpy의 초기화 및 노드 생성
ROS Client Library for Pyhon은 파이썬을 위한 ROS 클라이언트 라이브러리, 즉 Python 유저들을 위한 ROS 라이브러리이다.

Jupyter notebook을 통해 위와 같이 실행했다면, 실행한 /turtlesim과 작성한 /sub_test라는 노드가 실행된 것이다. 이 두 노드가 실행되었는지 확인하기 위해 아래 명령어를 사용해 확인한다.
ros2 node lsit

2. Subscription에서 실행할 callback 함수 작성
만약 어떤 노가 토픽을 발행하면, Python으로 노드를 구독하는 subscriber가 동작한다. 이때 토픽은 일정 주기로 발행되는데, 토픽을 받을 때마다 실행하게 하는 함수를 callback 함수라고 부른다. 즉 토픽을 받을 때마다 어떤 일을 수행하게 하는 함수를 callback 함수라고 하며 그 함수를 미리 작성해 두어야 한다.

3. 토픽 subscriber 만들기
create_subscription은 아래의 형식으로 호출하면 된다. 데이터 타입은 앞에서 import 한 turtlesim의 Pose이다. 그리고 토픽의 이름은 '/turtle1/pose'이다. 또한, callback 함수는 토픽이 들어오면 실행할 함수를 지정하면 된다.
test_node.create_subscription(<data_type>, '<topic_name>'. <callback>, <QoS History>)

터미널에서 rqt_graph를 실행하면 아래 결과를 볼 수 있다. 작성한 create_subscription 명령에 의해 '/turtlesim' 노드에서 '/turtle1/pose'라는 토픽이, 만들어 낸 '/sub_test'라는 노드로 지나가고 있음을 확인할 수 있다.

이제 rclpy의 spin_once라는 명령에서 앞서 선언한 test_node를 지정해주면 해당 노드를 구독할 수 있다. 여기서 사용한 spin_once는 토픽을 한 번만 받아들이는 명령이다. 토픽을 계속 무한히 구독하게 하는 명령어는 spin이다.
spin_once가 한 번 실행되면 토픽이 들어올 때까지 기다렸다가, 토픽이 들어오면 지정된 callback 함수가 아래처럼 실행되는 것을 알 수 있다.
rp.spin_once(test_node)
rp.spin(test_node)

4. 토픽을 받는 횟수 제한해보기
함수 안에서 함수 외부의 변수를 다루기 위해 cnt를 global로 선언해주고, callback 함수가 한 번 실행될 때마다 cnt를 1씩 증가시키는 코드를 만들었다. 그러고 cnt가 3보다 큰 경우에는 raise가 발동되어 에러가 발생된다.

5. python으로 토픽 발행하기
간단히 필요한 모듈을 import 하고 노드를 초기화하는 코드를 아래처럼 작성한다. 'from geometry_msgs.msg import Twist'는 발행하든 구독하든 다루려고 하는 토픽의 데이터 타입에 따라 import 하는 것이다. 현재 cmd_vel이라는 토픽을 발행하려고 하므로, cmd_vel 토픽의 데이터 타입에 대해 알아야 한다.

'ros2 topic list -t'를 통해 '/turtle1/cmd_vel' 토픽의 데이터 타입이 Twist에 해당함을 확인할 수 있다.
ros2 topic list -t

6. cmd_vel 토픽의 데이터 타입인 Twist 선언
구독할 때는 callback 함수에서 data를 다루도록 create_subscription이 신경 쓰이지 않도록 해주었다면, 토픽을 발행하는 것은 메시지의 타입을 알고 그 타입에 맞도록 발행할 내용을 저장하는 것이 먼저이다.
Twist 데이터 타입을 import 했으니 먼저 해당 메시지를 msg라는 변수에 다음과 같이 저장한다. 그 후 msg 변수를 출력하여 msg에 어떤 내용이 있는지 확인한다.
msg = Twist()

실행 결과를 보면 3차원 벡터 linear와 angular 두 개로 되어 있고 두 벡터 모두 x, y, z 값을 가지고 있다. 해당 코드는 속도 명령이므로 msg라는 변수를 만들 때 내부값들은 모두 0으로 초기화된다는 것을 알 수 있다.
7. python으로 cmd_vel 토픽 간단히 발행해보기
간단히 linear의 x 값을 수정하는 코드를 아래와 같이 작성한다. 그리고 해당 결과가 잘 변경되었는지 확인하기 위해 print 문으로 msg 변수를 출력해본다.
msg.linear.x = 2.0
print(msg)

이제 앞서 선언해 둔 test_node라는 변수에서 지정한 pub_test라는 노드가 create_publisher로 토픽을 발행하게 한다. 아래처럼 데이터 타입과 토픽 이름을 지정하고 QoS 설정을 해주면 된다.
pub = test_node.create_publisher(<data_type>, '<topic_name>', QoS)
pub = test_node.create_publisher(Twist, '/turtle1/cmd_vel', 10)

저장해둔 Twist 데이터 타입의 msg를 발행하기 위해 아래 명령어를 작성한다.
pub.publish(msg)

만약 지금까지 실행한 상태에서 추가로 또 움직이게 하고 싶다면 msg를 변경하면 된다. 그리고 이미 create_publisher 명령으로 publisher를 생성했으므로 publish 명령만 인가하면 된다.


8. ROS에서 timer를 이용해서 토픽 발행하기
일정 주기로 토픽을 발행하기 위해서는 일정 시간을 유지할 필요가 있다. 예를 들어 1Hz로 토픽을 발행하고 싶다면 1Hz, 즉 초당 한 번 토픽을 발행하는 것으로 만들어내야 한다. 해당 기능은 create_timer라는 명령어를 사용하여 구현할 수 있다.
test_node.create_timer(timer_period, timer_callback)
먼저 타이머의 주기와 해당 시간에 어떤 걸 할 지 callback function을 지정해주어야 한다. 지금 예시로 callback function은 timer가 호출될 때마다 cnt를 1씩 증가시키는 코드를 def 안에 넣어 두었다. 그리고 timer_callback 함수가 호출될 때마다 msg를 publish 하도록 했다.

이제 작성한 timer_callback과 0.1로 지정한 timer_period를 가지고 test_node가 제공하는 create_timer를 만든다. 그러면 0.1초에 한 번씩 timer_callback 함수를 실행하게 되고, 작성한 대로 cmd_vel 토픽을 0.1초에 한 번씩 발행하게 된다. 그리고 타이머가 동작할 때까지 기다리도록 spin 명령어를 사용하였다.
9. 노드의 종료
test_node.destroy_node()'1. Programming > ROS' 카테고리의 다른 글
| [ROS2 Humble] Python으로 서비스 클라이언트 다루기 (0) | 2026.01.04 |
|---|---|
| [ROS2 Humble] ROS2 기본 명령어 (1) | 2026.01.01 |
| [ROS2 Humble] 터미널과 bashrc 설정 (0) | 2026.01.01 |
