[ROS2] ROS2 프로그래밍 기초 - 파이썬

HY K·2024년 9월 20일

ROS2

목록 보기
11/18

이번 포스팅에서는 ROS2의 파이썬 프로그래밍 기초에 대해서 알아보자.
참고한 링크는 다음과 같다.
https://cafe.naver.com/openrt/24450


패키지 생성

$ cd robot_ws/src
$ ros2 pkg create my_first_ros_rclpy_pkg --build-type ament_python --dependencies rclpy std_msgs

그리고 package.xml과 setup.py, setup.cfg 파일을 수정해야 한다.

package.xml

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>my_first_ros_rclpy_pkg</name>
  <version>0.0.0</version>
  <description>basic ROS python programming pkg</description>
  <maintainer email="alpha12334@naver.com">kimhoyun</maintainer>
  <license>Apache 2.0</license>

  <depend>rclpy</depend>
  <depend>std_msgs</depend>

  <test_depend>ament_copyright</test_depend>
  <test_depend>ament_flake8</test_depend>
  <test_depend>ament_pep257</test_depend>
  <test_depend>python3-pytest</test_depend>

  <export>
    <build_type>ament_python</build_type>
  </export>
</package>

setup.py

entry_points 옵션의 console_scripts를 사용해서 실행 파일을 설정하는 것이 setup.py에서 가장 핵심이다. 여기에 내가 실행하고자 하는 파이썬 노드 이름을 입력하면 된다.

from setuptools import find_packages, setup
from setuptools import setup

package_name = 'my_first_ros_rclpy_pkg'

setup(
    name=package_name,
    version='0.1.0',
    packages=find_packages(exclude=['test']),
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='kimhoyun',
    maintainer_email='kimhoyun@todo.todo',
    description='TODO: Package description',
    license='Apache License 2.0',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            "helloworld_publisher = my_first_ros_rclpy_pkg.helloworld_publisher:main",
            "helloworld_subscriber = my_first_ros_rclpy_pkg.helloworld_subscriber:main",
        ],
    },
)

setup.cfg

기본적으로 작성이 되어있으며,
1. 패키지 이름을 기재해야 하는 것
2. 지정 폴더에 실행 파일이 생성된다는 점
이 2가지만 기억하면 된다.

[develop]
script_dir=$base/lib/my_first_ros_rclpy_pkg
[install]
install_scripts=$base/lib/my_first_ros_rclpy_pkg

퍼블리셔 노드 작성

import rclpy
from rclpy.node import Node # rclpy로부터 Node 클래스를 사용
from rclpy.qos import QoSProfile # QoS 설정
from std_msgs.msg import String # std_msgs의 String 인터페이스 사용

class HelloworldPublisher(Node): # 노드 클래스 상속
    def __init__(self):
        super().__init__("helloworld_publisher") # 부모 클래스 생성자 호출 -> 노드 이름 지정
        qos_profile = QoSProfile(depth=10) # qos 설정 커스텀
        self.helloworld_publisher = self.create_publisher(String, "helloworld", qos_profile)
        # 토픽 퍼블리셔 설정 -> String 타입의 helloworld 토픽을 qos_profile 따라 발행
        self.timer = self.create_timer(1, self.publish_helloworld_msg)
        # 타이머 함수를 통해서 콜백 함수를 지속적으로 실행, 1초마다 실행을 의미
        self.count = 0

    def publish_helloword_msg(self): # 콜백 함수
        msg = String() # string 타입 지정
        msg.data = "Hello world : {0}".format(self.count) # 원하는 메시지 넣기
        self.helloworld_publisher.publish(msg) # 토픽 발행
        self.get_logger().info("Published Message : {0}".format(msg.data))
        # ROS2의 로깅 방식
        self.count += 1

def main(args=None):
    rclpy.init(args=args) # rclpy.init 함수를 통해서 초기화
    node = HelloworldPublisher() # node 변수를 통해서 Node 생성
    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        node.get_logger().info("Keyboard Interrupt (SIGINT)")
        # Ctrl + C 입력 등에서는 노드가 종료하게 만듦
    finally:
        node.destroy_node()
        rclpy.shutdown()

if __name__=="__main__":
    main()

서브스크라이버 노드

import rclpy
from rclpy.node import Node
from rclpy.qos import QoSProfile
from std_msgs.msg import String # 퍼블리셔 노드와 동일

class HelloworldSubscirber(Node):
    def __init__(self):
        super().__init__("Helloworld_subscriber")
        qos_profile = QoSProfile(depth=10)
        self.helloworld_subscriber = self.create_subscription(
            # 토픽 서브스크라이브 정의
            String,
            "helloworld",
            self.subscirbe_topic_message, # 콜백 함수 실행
            qos_profile
        )

    def subscirbe_topic_message(self, msg): # 콜백 함수 선언 및 구현
        self.get_logger().info("Received Message : {0}".format(msg.data))

def main(args=None):
    rclpy.init(args=args)
    node = HelloworldSubscirber()

    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        node.get_logger().info("Keyboard Interrupt (SIGINT)")
    finally:
        node.destroy_node()
        rclpy.shutdown()

if __name__ == "__main__":
    main()

빌드하기

$ cd robot_ws
$ colcon build --symlink-install --packages-select my_first_ros_rclpy_pkg

실행하기

$ source install/local_setup.bash
// 혹은
$ source install/setup.bash
// 그 다음에
$ ros2 run my_first_ros_rclpy_pkg hellworld_publisher

// 다른 터미널에서는
$ cd robot_ws && source install/setup.bash
$ ros2 run my_first_ros_rclpy_pkg helloworld_subscirber

이상으로 가장 기초적인 ROS2 파이썬 프로그래밍에 대해서 알아보았다.

profile
로봇, 드론, SLAM, 제어 공학 초보

0개의 댓글