왕다방

인공지능 & 로봇 사용자들의 자유게시판입니다. 인공지능, 가정용로봇, 서비스로봇, 인공지능스피커 등 자유롭게 올려주세요. 질문과답변도 이곳에 올려주세요.

제목ROS2: 파이썬으로 publisher와 subscriber 만들기2021-12-13 05:21
작성자user icon Level 4

88x31.png


이번 글에서는 파이썬을 통해 발행자(publisher)구독자(subscriber)를 만들어 보겠습니다.


터미널을 열고 오버레이 작업공간 src 폴더로 이동하세요.

  $ cd ~/dev_ws/src


파이썬 패키지를 만들겠습니다. 패키지를 만들때 --dependencies 옵션을 주면 패키지가 만들어질때 package.xml 파일에 의존성 패키지가 함께 기재됩니다. 패키지 이름은 pubsub_py로 하고 의존성 패키지로 rclpystd_msgs를 포함시키겠습니다. rclpy 패키지는 파이썬의 ROS 클라이언트 라이브러리(ROS Client Library for Python)이고, std_msgs 패키지는 표준 메시지 패키지 입니다.

  $ ros2 pkg create pubsub_py --build-type ament_python --dependencies rclpy std_msgs


package.xml 파일을 열면 의존성 패키지가 기재된 것을 확인할 수 있습니다.

version, description, maintainer, license를 수정하고 저장합니다.

mb-file.php?path=2021%2F12%2F13%2FF4376_1.png


setup.py 파일을 열고 파이썬 패키지 빌드 설정을 합니다. packages에는 의존성 패키지를 list 형식으로 나열하는데 find_packages()를 기재하면 자동으로 의존성 패키지를 찾아줍니다.

여기서 중요한 부분은 entry_points 입니다. entry_points는 콘솔 스크립트를 통해 노드를 실행하는 부분으로, 스크립트명과 호출함수명을 적어줍니다.

mb-file.php?path=2021%2F12%2F13%2FF4377_2.png

위 사진과 같이 작성하면 pub 스크립트를 통해 pubsub_py.pub 모듈의 main 함수가 호출되고, sub 스크립트를 통해 pubsub_py.sub 모듈의 main 함수가 호출됩니다. 아래 노드 작성할때 다시 설명하겠습니다.


이제 노드를 작성하겠습니다.

~/dev_ws/src/pubsub_py/pub_sub_py 폴더에 pub.pysub.py를 생성합니다.

  $ touch ~/dev_ws/src/pubsub_py/pubsub_py/{pub.py,sub.py}


pub 노드부터 작성하겠습니다.

mb-file.php?path=2021%2F12%2F13%2FF4380_3.png
 


rclpy 모듈과 std_msgs 모듈을 import 합니다.

 import rclpy

 from rclpy.node import Node

 from rclpy.qos import QoSProfile


 from std_msgs.msg import String


발행자 노드 클래스를 작성합니다. 클래스 이름은 Pub이고, Node 클래스를 상속합니다.

 class Pub(Node):


Pub 클래스 생성자를 작성합니다. super 함수를 통해 부모 클래스인 Node 클래스의 생성자에 노드 이름을 매개변수로 작성합니다. 노드 이름은 'pub' 입니다.

     def __init__(self):

         super().__init__('pub')


create_publisher 함수를 통해 발행자를 생성합니다. 매개변수는 메시지 타입, 토픽 이름, QoS를 넘겨줍니다.

여기서 작성한 pub 노드의 발행자는 String 타입의 메시지를 'topic' 토픽으로 발행합니다. QoS는 이 글에서 따로 설명하지 않겠습니다.

         qos_profile = QoSProfile(depth=10)

         self.publisher_ = self.create_publisher(String, 'topic', qos_profile)


create_timer 함수를 통해 타이머를 생성합니다. 매개변수는 타이머 주기, 콜백함수를 넘겨줍니다.

여기서 작성한 pub 노드는 0.5초마다 콜백함수를 실행합니다.

         timer_period = 0.5 # seconds

         self.timer = self.create_timer(timer_period, self.timer_callback)


초기 카운터값을 설정합시다.

          self.count = 0


콜백함수를 작성합니다. 콜백함수에서는 publish 함수를 통해 발행자가 해당 메시지를 발행합니다.

     def timer_callback(self):

         msg = String()

         msg.data = 'Hello World: %d' % self.count


get_logger 함수는 콘솔에서 보여지는 로거입니다. debug, info, warning, error, fatal이 있으며, 일반적인 정보 전달에는 info를 사용합니다.

         self.publisher_.publish(msg)

         self.get_logger().info('Publishing: "%s"' % msg.data)


콜백함수가 호출될때마다 count를 1씩 증가시킵니다.

         self.count += 1


메인함수를 작성합니다. 메인함수에서는 rclpy 모듈을 초기화시키고 spin 함수를 통해 발행자 노드(pub)를 실행합니다. 노드를 종료시키면 destroy_node 함수를 통해 발행자 노드(pub)를 소멸시키고 shutdown 함수를 통해 노드를 종료합니다.

 def main(args=None):

     rclpy.init(args=args)

     node = Pub()

     try:

         rclpy.spin(node)

     except KeyboardInterrupt:

         node.get_logger().info('Keyboard Interrupt (SIGINT)')

     finally:

         node.destroy_node()

         rclpy.shutdown()



sub 노드를 작성합니다. pub 노드와 비슷합니다. 다른 점은 create_subscription 함수를 통해 구독자를 생성하고 매개변수로 메시지 타입, 토픽 이름, 콜백함수, QoS를 넘겨줍니다. 여기서 작성한 sub 노드의 구독자는 'topic' 토픽을 구독하여 String 타입의 메시지를 받습니다.

mb-file.php?path=2021%2F12%2F13%2FF4381_4.png
 


이제 colcon으로 패키지를 빌드해주세요. 옵션으로 --symlink-install을 주면 빌드파일이 심볼릭 링크를 통해 실행되므로 파일을 수정할때마다 다시 빌드하지 않아도 됩니다. 또한 --packages-select 옵션을 통해 전체 작업공간을 빌드하지 않고 특정 패키지만 빌드할 수 있습니다.

  $ cd ~/dev_ws && colcon build --symlink-install --packages-select pubsub_py


오버레이 작업공간을 환경설정합니다.

  $ . ~/dev_ws/install/setup.bash


다음 명령어를 통해 sub 노드를 실행해봅시다.

  $ ros2 run pubsub_py sub


새로운 터미널을 열고 다시 오버레이 작업공간을 환경설정하고 pub 노드를 싱행해봅시다.

  $ . ~/dev_ws/install/setup.bash

  $ ros2 run pubsub_py pub

mb-file.php?path=2021%2F12%2F13%2FF4382_5.gif
 

#ROS2# 노드# 패키지# publisher# subscriber# topic
댓글
자동등록방지
(자동등록방지 숫자를 입력해 주세요)