전공/컴퓨터 코딩 데이터
ROS2 파이썬을 이용한 topic subscribe, publish
흔한 학생
2024. 11. 7. 23:39
터틀심 pose 구독하기 subscribe
ros2 run to
import rclpy as rp
from turtlesim.msg import Pose
rp.init()
test_node = rp.create_node('sub_test')
def callback(data):
print("--->")
print("/turtle/pose: ",data)
test_node.create_subscription(Pose, '/turtle1/pose', callback, 10)
rp.spin_once(test_node)
코드 해석
더보기
<주피터 노트북에서 실행>
rp.init() 으로 초기화
rp.create_node 로 노드 생성
.create_subscription 으로 메세지 구독
- .create_subscription(데이터 타입, 토픽 이름, 실행할 함수, 10)
- 처음에 import한 데이터 타입의 /turtle1/pose 토픽
- create_subscription 함수는 토픽이 들어올때마다 실행할 함수를 넣어줘야 함
rp.spin_once(test_node)
- 만들었던 노드를 실행
- 일반적으로 rp.spin()으로 노드를 계속 실행하여 토픽을 받음
topic 횟수 제한하기
횟수를 정해서 실행하고 싶을 때는 카운터 변수를 이용하면 좋음
카운터 변수를 만들고 callback 함수 안에서 전역(global)로 선언한 후
일정 횟수 이상 callback 하면 Exception이 일어나도록 하여 제한함
cnt =0 def callback(data): global cnt cnt+=1 print("--->") print("/turtle/pose: ",data) if cnt>3: raise Exception("Subsription stop")
이처럼 콜백 함수를 수정할 수 있음
cmd_vel 토픽 발행하기 publish
import rclpy as rp
from geometry_msgs.msg import Twist
rp.init()
test_node=rp.create_node('pub_test')
msg = Twist()
msg.linear.x=2.0
pub = test_node.create_publisher(Twist, '/turtle1/cmd_vel', 10)
pub.publish(msg)
코드해석
Twist() 클래스의 객체를 만듦
노드에서 publisher를 만드는 함수로 cmd_vel 토픽을 발행하는 pub을 만들고
pub.publish로 발행할 수 있다.
여러 번 publish하기 위한 방법
일반적으로 여러번 발행하기 위해서는 callback 함수를 만들고
해당 함수에서 pub.publish(msg) 를 수행하도록 한다.
그리고 create_timer 함수를 이용해 일정 주기로 callback 함수를 실행하도록 한다.
cnt = 0
def timer_callback():
global cnt
cnt += 1
pub.publish(msg)
if cnt > 3:
raise Exception("publish stop")
timer_period = 0.1
timer = test_node.create_timer(timer_period, timer_callback)
rp.spin(test_node)
구독 sub 과 발행 pub 비교
똑같이 rp.create_node('노드이름') 으로 노드를 만들고 시작 test_node=rp.create_node('test') |
|
sub | pub |
만든 노드에 있는 .create_subscription 함수로 토픽을 구독하고 callback 함수를 호출 test_node.create_subscription(~, ~, ~, ~) |
만든 노드에 있는 .create_publisher 함수로 새로운 변수 선언 pub = test_node.create_publisher(~, ~, ~) |
발행할 메세지 클래스의 객체 선언 msg=Twist() | |
만든 변수에 있는 .publish() 함수로 토픽 발행 pub.publish(msg) |
|
만든 노드에 있는 .create_timer 함수로 callback 함수 호출 일반적으로 callback 함수에서 publish 하도록 설정 timer = test_node.create_timer(~,~) |
|
rp.spin(test_node) | |
구독은 노드에서 바로 구독함과 동시에 콜백함수 실행하기 때문에 .create_subscription 하고 바로 노드 spin 하면 됨 |
발행은 노드에서 발행할 토픽 설정하고 바로 발행되지 않음 때문에 .create_publisher 하고 publish 해야 토픽이 발행됨 또 여러 번 발행하기 위해선 추가적인 함수에 publish를 해야하기에 조금 더 복잡함 |