클래스에서 매개변수 사용하기 (Python)

목표: Python을 사용하여 ROS 매개변수를 사용하는 클래스를 생성하고 실행합니다.

배경

Nodes 를 만들 때 런치 파일에서 설정할 수 있는 매개변수를 추가해야 할 때가 있습니다.

이 튜토리얼에서는 C++ 클래스에서 이러한 매개변수를 생성하고 런치 파일에서 설정하는 방법을 보여줍니다.

전제 조건

이전 튜토리얼에서는 작업 공간을 만드는 방법패키지를 만드는 방법 을 배웠습니다. 또한 ROS 2 시스템에서 매개변수 에 대한 기능을 배웠습니다.

작업

1 패키지 생성

새 터미널을 열고 ROS 2 설치를 소스로 지정 하여 ros2 명령이 작동하도록합니다.

이전 튜토리얼에서 만든 이전 디렉토리 에서 생성한 ros2_ws 디렉토리로 이동합니다.

패키지는 워크스페이스의 루트가 아닌 src 디렉토리에서 생성해야 합니다. ros2_ws/src 로 이동하고 새로운 패키지를 만듭니다.

ros2 pkg create --build-type ament_python --license Apache-2.0 python_parameters --dependencies rclpy

터미널에서 패키지 python_parameters 와 해당 필요한 파일 및 폴더를 확인하는 메시지가 반환됩니다.

--dependencies 인수는 package.xmlCMakeLists.txt 에 필요한 종속성 라인을 자동으로 추가합니다.

1.1 package.xml 업데이트

패키지 생성 중에 --dependencies 옵션을 사용했으므로 package.xml 또는 CMakeLists.txt 에 종속성을 수동으로 추가할 필요가 없습니다.

그러나 항상 package.xml 에 설명, 유지 관리자 이메일 및 이름, 라이센스 정보를 추가하는 것을 잊지 마세요.

<description>Python parameter tutorial</description>
<maintainer email="you@email.com">Your Name</maintainer>
<license>Apache License 2.0</license>

2. 파이썬 노드 작성

ros2_ws/src/python_parameters/python_parameters 디렉토리 안에 새 파일 python_parameters_node.py 를 만들고 다음 코드를 붙여넣습니다.

import rclpy
import rclpy.node

class MinimalParam(rclpy.node.Node):
    def __init__(self):
        super().__init__('minimal_param_node')

        self.declare_parameter('my_parameter', 'world')

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

    def timer_callback(self):
        my_param = self.get_parameter('my_parameter').get_parameter_value().string_value

        self.get_logger().info('Hello %s!' % my_param)

        my_new_param = rclpy.parameter.Parameter(
            'my_parameter',
            rclpy.Parameter.Type.STRING,
            'world'
        )
        all_new_parameters = [my_new_param]
        self.set_parameters(all_new_parameters)

def main():
    rclpy.init()
    node = MinimalParam()
    rclpy.spin(node)

if __name__ == '__main__':
    main()

2.1 코드 검토

맨 위의 import 문은 패키지 종속성을 가져오기 위해 사용됩니다.

다음 코드 부분은 클래스와 생성자를 만듭니다. 생성자의 줄 self.declare_parameter('my_parameter', 'world') 은 이름이 my_parameter 이고 기본값이 world 인 매개 변수를 생성합니다. 매개 변수 유형은 기본값에서 추론되므로 이 경우 문자열 유형으로 설정됩니다. 그 다음으로 timer 가 1의 주기로 초기화되어 timer_callback 함수가 1초에 한 번 실행되도록합니다.

class MinimalParam(rclpy.node.Node):
    def __init__(self):
        super().__init__('minimal_param_node')

        self.declare_parameter('my_parameter', 'world')

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

timer_callback 함수의 첫 번째 줄은 노드에서 매개변수 my_parameter 를 가져와 my_param 에 저장합니다. 다음으로 get_logger 함수를 사용하여 이벤트가 로그에 기록되도록 합니다. 그런 다음 set_parameters 함수를 사용하여 매개변수 my_parameter 를 기본 문자열 값 world 로 다시 설정합니다. 사용자가 매개변수를 외부에서 변경한 경우에도 항상 기본값으로 재설정되도록 합니다.

def timer_callback(self):
    my_param = self.get_parameter('my_parameter').get_parameter_value().string_value

    self.get_logger().info('Hello %s!' % my_param)

    my_new_param = rclpy.parameter.Parameter(
        'my_parameter',
        rclpy.Parameter.Type.STRING,
        'world'
    )
    all_new_parameters = [my_new_param]
    self.set_parameters(all_new_parameters)

timer_callback 다음으로 메인 함수가 나옵니다. 이곳에서 ROS 2가 초기화되고 MinimalParam 클래스의 인스턴스가 생성되며 rclpy.spin 이 노드에서 데이터를 처리하기 시작합니다.

def main():
    rclpy.init()
    node = MinimalParam()
    rclpy.spin(node)

if __name__ == '__main__':
    main()
2.1.1 (선택 사항) 매개변수 기술자 추가

선택적으로 매개변수에 대한 기술자를 설정할 수 있습니다. 기술자를 사용하면 매개변수와 해당 제약 조건에 대한 텍스트 설명을 지정할 수 있으며 읽기 전용으로 만들거나 범위를 지정하는 등의 제약 조건을 지정할 수 있습니다. 이를 위해 __init__ 코드를 다음과 같이 변경해야 합니다.

# ...

class MinimalParam(rclpy.node.Node):
    def __init__(self):
        super().__init__('minimal_param_node')

        from rcl_interfaces.msg import ParameterDescriptor
        my_parameter_descriptor = ParameterDescriptor(description='This parameter is mine!')

        self.declare_parameter('my_parameter', 'world', my_parameter_descriptor)

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

나머지 코드는 동일합니다. 노드를 실행한 후 ros2 param describe /minimal_param_node my_parameter 를 실행하여 유형 및 설명을 볼 수 있습니다.

2.2 엔트리 포인트 추가

setup.py 파일을 엽니다. 다시 한 번 maintainer, maintainer_email, descriptionlicense 필드를 package.xml 에 맞게 설정합니다.

maintainer='YourName',
maintainer_email='you@email.com',
description='Python parameter tutorial',
license='Apache License 2.0',

entry_points 필드의 console_scripts 괄호 내에 다음 줄을 추가합니다.

entry_points={
    'console_scripts': [
        'minimal_param_node = python_parameters.python_parameters_node:main',
    ],
},

저장하지 않으면 안 됩니다.

3 빌드 및 실행

빌드하기 전에 작업 공간 루트 (ros2_ws)에서 빠진 종속성을 확인하기 위해 rosdep 를 실행하는 것이 좋습니다.

rosdep install -i --from-path src --rosdistro humble -y

다음으로 작업 공간 루트인 ros2_ws 로 이동하고 새 패키지를 빌드합니다.

colcon build --packages-select python_parameters

새 터미널에서 ros2_ws 로 이동하고 설정 파일을 다시 소스화합니다.

source install/setup.bash

이제 노드를 실행합니다.

ros2 run python_parameters minimal_param_node

터미널은 다음과 같은 메시지를 1초에 한 번씩 반환해야 합니다:

[INFO] [parameter_node]: Hello world!

이제 매개변수의 기본값을 볼 수 있지만 직접 설정할 수 있어야 합니다. 이를 위한 두 가지 방법이 있습니다.

3.1 콘솔을 통한 변경

이 부분은 매개변수에 대한 튜토리얼 에서 얻은 지식을 사용하여 방금 만든 노드에 적용합니다.

노드가 실행 중인지 확인합니다.

ros2 run python_parameters minimal_param_node

다른 터미널을 열고 다시 ros2_ws 내에서 설정 파일을 소스화하고 다음 줄을 입력합니다.

ros2 param list

거기에서 사용자 지정 매개변수 my_parameter 를 볼 수 있습니다. 변경하려면 콘솔에서 다음 줄을 실행하면 됩니다.

ros2 param set /minimal_param_node my_parameter earth

Set parameter successful 출력을 받았다면 변경이 잘 이루어진 것입니다. 다른 터미널을 확인하면 출력이 INFO [minimal_param_node]: Hello earth! 로 변경되었음을 볼 수 있습니다.

노드는 그 후에 매개변수를 world 로 다시 설정하므로 노드에서 항상 기본값으로 다시 설정됩니다.

3.2 런치 파일을 통한 변경

매개변수를 런치 파일에서 설정할 수도 있습니다. 먼저 런치 디렉토리를 추가해야 합니다. ros2_ws/src/python_parameters/ 디렉토리 안에 launch 라는 새 디렉토리를 만듭니다. 그 안에 python_parameters_launch.py 라는 새 파일을 만듭니다.

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='python_parameters',
            executable='minimal_param_node',
            name='custom_minimal_param_node',
            output='screen',
            emulate_tty=True,
            parameters=[
                {'my_parameter': 'earth'}
            ]
        )
    ])

여기서 우리는 my_parameterparameter_node 를 실행할 때 earth 로 설정합니다. 아래의 두 줄을 추가하여 출력이 콘솔에 인쇄되도록했습니다.

output="screen",
emulate_tty=True,

이제 setup.py 파일을 엽니다. 상단에 import 문을 추가하고 data_files 매개변수에 모든 런치 파일을 포함하도록 다음 새 문을 추가합니다.

import os
from glob import glob
# ...

setup(
  # ...
  data_files=[
      # ...
      (os.path.join('share', package_name), glob('launch/*launch.[pxy][yma]*')),
    ]
  )

변경 사항을 저장하지 않으면 안 됩니다.

다음으로 작업 공간 루트인 ros2_ws 로 이동하고 새 패키지를 빌드합니다.

colcon build --packages-select python_parameters

그런 다음 새 터미널에서 설정 파일을 다시 소스화합니다.

source install/setup.bash

이제 방금 만든 런치 파일을 사용하여 노드를 실행합니다.

ros2 launch python_parameters python_parameters_launch.py

터미널은 다음과 같은 메시지를 반환해야 합니다:

[INFO] [custom_minimal_param_node]: Hello earth!

요약

매개변수를 설정할 수 있는 사용자 지정 매개변수를 가진 노드를 만들어 보았습니다. 이 매개변수는 런치 파일이나 명령 행에서 설정할 수 있습니다. 종속성, 실행 파일 및 런치 파일을 패키지 구성 파일에 추가하여 빌드 및 실행하고 매개변수를 확인하는 방법을 살펴보았습니다.

다음 단계

자신만의 패키지와 ROS 2 시스템을 보유한 상태에서 다음 튜토리얼 에서 환경 및 시스템에서 문제가 발생한 경우 이를 조사하는 방법을 배울 것입니다.