[ROS2] (15)-Python으로 퍼블리셔와 서브스크라이버 만들기
퍼블리셔와 서브스크라이버 만들기
이번 포스팅에서는 [ROS2] (14)-C++로 퍼블리셔와 서브스크라이버 만들기 에서 만들었던 퍼블리셔와 서브스크라이버 노드를 python으로 만들어볼 것이다.
패키지 생성하기
dev_ws/src
폴더에 py_pubsub
이라는 패키지를 만들어보자.
$ cd ~/dev_ws/src
$ ros2 pkg create --build-type ament_python py_pubsub
퍼블리셔 노드 작성하기
dev_ws/src/py_pubsub/py_pubsub
폴더에 아래와 같이 파일을 다운로드 하자.
$ cd ~/dev_ws/src/py_pubsub/py_pubsub
$ wget https://raw.githubusercontent.com/ros2/examples/foxy/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_member_function.py
다운로드한 파일을 열어서 코드를 확인해보자.
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
가장 먼저 필요한 모듈들을 import 해주고 있다. rclpy
는 Node
클래스를 사용할 수 있게 해주고, std_msgs.msg
를 통해 문자열 메시지 타입을 사용할 수 있다. 위 코드에 있는 모듈들은 dependency에 추가되어야 한다.
class MinimalPublisher(Node):
다음으로 MinimalPublisher
클래스를 만들면서 Node
로부터 상속을 받는다.
def __init__(self):
super().__init__('minimal_publisher')
self.publisher_ = self.create_publisher(String, 'topic', 10)
timer_period = 0.5 # seconds
self.timer = self.create_timer(timer_period, self.timer_callback)
self.i = 0
생성자를 정의하고 있다. super().__init__
을 통해 Node
클래스의 생성자를 불러오면서 노드 이름을 minimal_publisher
로 정의한다. create_publisher
를 통해 String
타입의 topic
이라는 이름을 갖고, queue 사이즈는 10
인 퍼블리셔를 정의한다. 다음으로 0.5초마다 callback 하는 타이머를 정의한다.
def timer_callback(self):
msg = String()
msg.data = 'Hello World: %d' % self.i
self.publisher_.publish(msg)
self.get_logger().info('Publishing: "%s"' % msg.data)
self.i += 1
timer_callback
함수는 counter를 붙인 문자열을 만든다. 그리고 get_logger().info
를 통해 콘솔 창에 출력한다.
def main(args=None):
rclpy.init(args=args)
minimal_publisher = MinimalPublisher()
rclpy.spin(minimal_publisher)
# Destroy the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
minimal_publisher.destroy_node()
rclpy.shutdown()
마지막으로 main
함수를 정의하고 있다. rclpy
라이브러리를 시작시키고, 노드를 만들고 spin 시킨다.
퍼블리셔 노드 dependency 추가하기
먼저, package.xml
파일을 열어서 아래와 같이 2개의 dependency를 추가한다.
<exec_depend>rclpy</exec_depend>
<exec_depend>std_msgs</exec_depend>
다음으로 entry point를 추가한다. setup.py
파일을 열어서 아래와 같이 entry_points
영역에 console_scripts
괄호 안에 내용을 추가한다.
entry_points={
'console_scripts': [
'talker = py_pubsub.publisher_member_function:main',
],
},
setup.cfg
파일은 자동으로 덧붙여지므로 별도로 수정할 것은 없다.
서브스크라이브 노드 작성하기
마찬가지로 예제 코드를 다운로드한다.
$ cd ~/dev_ws/src/py_pubsub/py_pubsub
$ wget https://raw.githubusercontent.com/ros2/examples/foxy/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_member_function.py
코드는 퍼블리셔와 거의 유사하다. 토픽의 이름과 메시지 타입이 같아야 수신할 수 있으므로, 퍼블리셔 노드와 같은 값을 갖는다. 그리고 서브스크라이브 노드는 타이머가 필요없으므로 타이머를 포함하지 않는다.
dependency도 퍼블리셔 노드와 같으므로 package.xml
파일은 수정할 것이 없다. setup.py
파일에 listenter
부분만 추가해주자.
entry_points={
'console_scripts': [
'talker = py_pubsub.publisher_member_function:main',
'listener = py_pubsub.subscriber_member_function:main',
],
},
노드 빌드 및 실행하기
먼저, dependency를 먼저 설치해주자.
$ cd ~/dev_ws
$ rosdep install -i --from-path src --rosdistro foxy -y
py_pubsub
패키지만 빌드해주자.
$ cd ~/dev_ws
$ colcon build --packages-select py_pubsub
2개의 터미널 창에서 각각 설정파일을 source 해주고 talker
와 listener
를 실행해주자. 정상적으로 토픽을 퍼블리시하고 수신하는 것을 확인할 수 있다.
실행 중인 listener
노드를 ctrl + c로 중지해주고, cpp_pubsub
패키지에 있는 listener
를 실행해도 정상적으로 동작하는 것을 확인할 수 있다.
댓글남기기