해당 실습 자료는 한양대학교 Road Balance - ROS 2 for G Camp와 ROS 2 Documentation: Foxy, 표윤석, 임태훈 <ROS 2로 시작하는 로봇 프로그래밍> 루피페이퍼(2022) 를 참고하여 작성하였습니다.
이번 장에서는
Publisher Node
와Subscriber Node
간의 메세지 통신Topic
을 구현해볼 예정입니다. 해당 예제에서는 ROS 프로그래밍: Package - Python 에서 제작한 Package를 활용하여 아주 간단한 예제인 ROS2 판 ‘Hello World’를 제작해볼 예정입니다.
$ cd ~/ros2_ws/src
$ ros2 pkg create topic_helloworld --build-type ament_python --dependencies rclpy std_msgs
~/ros2_ws/src/topic_helloworld/topic_helloworld/
폴더에 helloworld_publisher.py
라는 이름으로 소스 코드 파일을 저장하시면 됩니다.$ cd ~/ros2_ws/src/topic_helloworld/topic_helloworld
$ gedit helloworld_publisher.py
import rclpy
from rclpy.node import Node
from rclpy.qos import QoSProfile # QoS 설정을 위해
from std_msgs.msg import String # String 메시지 인터페이스를 사용하기 위해 import
class HelloworldPublisher(Node): # Node 클래스를 상속
def __init__(self):
super().__init__('helloworld_publisher') # 부모 클래스(Node)의 생성자를 호출하고 이름을 helloworld_publisher로 지정
qos_profile = QoSProfile(depth=10) # 통신상태가 원활하지 못할 경우 퍼블리시 할 데이터를 버퍼에 10개까지 저장하라는 설정
self.helloworld_publisher = self.create_publisher(# create_publisher함수를 이용해 helloworld_publisher 설정
String, # 토픽 메시지 타입: String,
'helloworld', # 토픽 이름: helloworld
qos_profile)#, QoS설정
self.timer = self.create_timer(1, **self.publish_helloworld_msg**) # 콜백 함수를 실행. 1초마다 publish_helloworld_msg 함수 실행
self.count = 0
def **publish_helloworld_msg**(self): # 앞서 지정한 콜백 합수
msg = String() # 메시지 타입 String으로 지정
msg.data = 'Hello World: {0}'.format(self.count) # 표준 문자열 메세지 구조에 따라 해당 문자열을 msg.data에 담아줌
self.helloworld_publisher.publish(msg) # __init__ 에서 정의한 helloworld_publisher 퍼블리시!
self.get_logger().info('Published message: {0}'.format(msg.data)) # 터미널 창에 출력하며 로그 기록됨 (python의 print도 가능)
self.count += 1
def main(args=None):
rclpy.init(args=args) # 초기화
node = HelloworldPublisher() # HelloworldPublisher를 node라는 이름으로 생성
try:
rclpy.spin(node) # rclpy에게 이 Node를 반복해서 실행 (=spin) 하라고 전달
except KeyboardInterrupt: # `Ctrl + c`가 동작했을 때
node.get_logger().info('Keyboard Interrupt (SIGINT)')
finally:
node.destroy_node() # 노드 소멸
rclpy.shutdown() # rclpy.shutdown 함수로 노드 종료
if __name__ == '__main__':
main()
코드 내용에 대해서는 하나씩 알아보도록 하겠습니다.
Python ROS2 프로그래밍을 위한 rclpy
rclpy
의 Node
클래스