본문 바로가기
ROBOTICS/Turtlebot3 - Noetic

ROS Noetic : Concept of ROS Topic (Publisher, Subscriber)

by 누워있는말티즈 2022. 8. 6.

Concept of ROS Topic (Publisher, Subscriber)

ROS 환경에서 2개 이상의 node는 topic을 통해 통신을 하게 된다. 이때 Topic을 발행하는 쪽이publisher, 이를 수령하는 쪽이 Subscriber의 역할을 한다. 간단하게 tutorial로 준 talker, listener node의 동작을 본다.

좌측 상단이 talker, 우측 상단이 listener

위 화면을 보면 talker node에서 listener node로 /chatter라는 이름의 topic을 전달하는 것을 확인할 수 있다. 현재 시행되는 node, topic은 아래 명령들로 확인이 가능하다.

rosnode list # node
rostopic list # topic
rostopic info *topic_name* #t opic and node info
rqt_graph # graphical analysis

rostopic echo *topic_name* # display topic contents on terminal

같은 방식으로 turtlesim에서 시도해본다.

위에서 볼 수 있듯이 node는 turtlesimdraw_square 두 개가 켜져있다.

turtlesim node는 graphical interface를 표출해주는 node이며 draw_square는 turtlesim node를 실제적으로 움직이는 node이다. 서로 주고받는 topic은 아래와 같다.

turtlesim에서 draw_square에 보내는 topic /turtle1/pose는 turtlesim/Pose

draw_square에서 turtlesim에 보내는 topic /turtle1/cmd_vel는 geometry_msgs/Twist

draw_square는 turtlesim의 현재 위치와 orientation에 대한 정보를 받아와서 turtlesim에 다음 방향의 각도와 속도 정보를 발행한다.


Custom Publisher & Subscriber

Publisher
turtlesim의 거북이가 원형으로 돌게 만드는 node를 만들어본다.
다시 my_robot_pkg/scripts에 새로운 python 파일을 생성하고 아래와 같은 코드를 작성한다.

#!/usr/bin/env python3
import rospy
from geometry_msgs.msg import Twist

def main():
    # pub = rospy.Publisher("name_of_topic", type of data, queue size) 
    pub = rospy.Publisher("/turtle1/cmd_vel", Twist, queue_size=10) 
    rate = rospy.Rate(5)

    while not rospy.is_shutdown():
        # write message to publish
        msg = Twist() # this is a Twist object
        msg.linear.x = 2.0
        msg.angular.z = 1.0

        # publish the message
        pub.publish(msg)

        rate.sleep()


if __name__=='__main__':
    rospy.init_node("draw_circle")
    rospy.loginfo("circle node init")  

    main()

여기서 주목할 부분이 몇 가지 있다.
line 7: Publisher에서 발행하는 topic의 이름을 정확히 맞춰주어야 한다. turtlesim 노드는 /turtle1/cmd_vel을 받으므로 이와 동일하게 설정한다.

추가적으로 이 topic의 type은 /geometry_msgs_Twist이므로 이도 지정해준다.
line 3: 위 내용과 연관되어 message의 형식을 정할 때는 그 형식의 라이브러리를 불러줘야 하며 이렇게 import한 package는 package.xml에 바로 추가해준다.

위 node를 turtlesim과 함께 실행하면 다음과 같은 결과를 볼 수 있다.

rqt graph로 봐도 이제 앞에서 draw circle node가 cmd_vel을 보내주는 것을 알 수 있다.


Subscriber
이제 Subscriber를 만들 것이다. 동일하게 turtlesim을 이용할건데 아무도 subscribe 하지 않고 있는 /turtle1/pose를 사용해본다. 확인하는 김에 데이터 모양도 같이 살펴봤다.

이제 subscriber 코드를 작성한다. 동일한 폴더에 새로 파일을 만든다.

#!/usr/bin/env python3  
from math import sqrt  
import rospy  
from turtlesim.msg import Pose

def pose\_callback(msg: Pose):  
rospy.loginfo(msg)  
sum = msg.x + msg.y  
rospy.loginfo("sum : "+ str(sum))

def main():  
\# we need callback function!!!  
sub = rospy.Subscriber("/turtle1/pose", Pose, callback = pose\_callback)

if **name**\=='**main**':  
rospy.init\_node("turtle\_subscriber")  
rospy.loginfo("subscriber node init")

main()
rospy.spin() # kind of infinite loop
# more passive than actual loop

line 7 : Publisher 때와 동일하게 읽을 topic의 이름을 정확히 일치시키고 읽은 message의 type도 맞춰줘야 한다.
*callback : 매우 중요하다!

line 21 : rospy.spin()은 callback 루프를 시행시켜주는 아주 중요한 아이이다.
실행 결과와 rqt 화면은 아래와 같다.


그렇다면 turtlesim 노드를 사이에 turtlesim에 publish하고 turtlesim이 쏘는걸 subscribe하는걸 만들었다. 둘을 동시에 시행하면 rqt graph는 아래와 같은 모양을 보인다!

반응형

'ROBOTICS > Turtlebot3 - Noetic' 카테고리의 다른 글

ROS Noetic : Server & Client  (0) 2022.08.11
ROS Noetic : ROS service  (0) 2022.08.10
ROS Noetic : Closed Loop system with Turtlesim  (0) 2022.08.09
ROS Noetic : Create Package and Node  (0) 2022.08.05
ROS Noetic : Setup and Workspace  (0) 2022.08.05

댓글