
self.declare_parameter('parameter_name', default_value)
parameter_name = self.get_parameter('parameter_name').value
self.add_on_set_parameters_callback(self.callback_function)
# ROS2 노드의 파라미터를 동적으로 변경 시, 그 결과를 나타내는 메시지 타입 호출 --> successful/reason
from rcl_interfaces.msg import SetParametersResult
class Argument(Node):
def __init__(self):
super().__init__('argument')
self.declare_parameter('qos_depth', 10)
qos_depth = self.get_parameter('qos_depth').value
self.declare_parameter('min_random_num', 0)
self.min_random_num = self.get_parameter('min_random_num').value
self.declare_parameter('max_random_num', 9)
self.max_random_num = self.get_parameter('max_random_num').value
self.add_on_set_parameters_callback(self.update_parameter)
def update_parameter(self, params):
for param in params:
if param.name == 'min_random_num' and param.type_ == Parameter.Type.INTEGER:
self.min_random_num = param.value
elif param.name == 'max_random_num' and param.type_ == Parameter.Type.INTEGER:
self.max_random_num = param.value
return SetParametersResult(successful=True)
argument:
ros__parameters:
qos_depth: 10 # 메시지 버퍼 크기
min_random_num: 0 # 무작위 숫자의 최소값
max_random_num: 9 # 무작위 숫자의 최대값
$ ros2 run ex_calculator argument
$ ros2 param list
$ ros2 param get /argument <parameter_name>
$ ros2 param set /argument <parameter_name>

서비스 클라이언트로 서비스 요청을 통해 파라미터 변경
Parameter 클래스를 선언하여 매개변수(name, type, integer_value) 등을 설정
이를 이용하여 a노드에서 b노드의 파라미터를 변경 가능
data_files=[
('share/ament_index/resource_index/packages', ['resource/' + package_name]),
(share_dir, ['package.xml']),
(share_dir + '/launch', glob.glob(os.path.join('launch', '*.launch.py'))),
(share_dir + '/param', glob.glob(os.path.join('param', '*.yaml'))),
위 코드를 추가하여 launch, yaml 파일을 사용하여 빌드하도록 설정
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
def generate_launch_description():
param_dir = LaunchConfiguration(
'param_dir',
default=os.path.join(
get_package_share_directory('ex_calculator'),
'param',
'arithmetic_config.yaml'))
return LaunchDescription([
DeclareLaunchArgument(
'param_dir',
default_value=param_dir,
description='Full path of parameter file'),
Node(
package='ex_calculator',
executable='argument',
name='argument',
parameters=[param_dir],
output='screen'),
Node(
package='ex_calculator',
executable='calculator',
name='calculator',
parameters=[param_dir],
output='screen'),
])
위 코드를 통해 해당 함수는 calculator, argument 두 노드를 파라미터 파일을 실행하도록 한다
param_dir: 패키지의 공유 디렉토리 경로와 설정된 yaml 파일의 경로를 지정
$ ros2 run ex_calculator checker -g 100
-g 100 : 실행 인자, -g는 옵션 또는 플래그로 해당 옵션에 100에 해당하는 값을 전달
import argparse
import sys
import rclpy
from ex_calculator.checker.checker import Checker
def main(argv=sys.argv[1:]):
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'-g',
'--goal_total_sum',
type=int,
default=50,
help='Target goal value of total sum')
parser.add_argument(
'argv', nargs=argparse.REMAINDER,
help='Pass arbitrary arguments to the executable')
args = parser.parse_args()
rclpy.init(args=args.argv)
try:
checker = Checker()
checker.send_goal_total_sum(args.goal_total_sum)
try:
rclpy.spin(checker)
except KeyboardInterrupt:
checker.get_logger().info('Keyboard Interrupt (SIGINT)')
finally:
checker.arithmetic_action_client.destroy()
checker.destroy_node()
finally:
rclpy.shutdown()
if __name__ == '__main__':
main()
parser=argparse.ArgumentParser: 명령줄 인자를 처리하기 위한 도구, 실행 시 인자를 정의하고 해석, 파서 만들기
parser.add_argument(): 명령줄에서 사용할 수 있는 옵션을 정의, 인자 추가
args = parser.parse_args(): 인자 파싱하기
args.xxx): 인자사용하기
-g, --goal_total_sum: 옵션이름 설정type=int: 옵션의 타입 설정default=50: 사용자가 인자 제공하지 않을 경우 기본값 설정help: --help입력시 설명 확인 가능 --> formatter_class=argparse.ArgumentDefaultsHelpFormatter: --help를 실행할 때 기본값을 포함한 설명을 출력할 수 있게 해줍니다.int main(int argc, char*argv[])
{
rclcpp::init(argc, argv):
...
def main(argv=sys.arbv[1:]:
(argparse 구문 추가)
rclpy.init(args=argv)
| name | explanation |
|---|---|
| argc | argument count |
| argv | argument vector or value |
| args | arguments |
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
def generate_launch_description():
param_dir = LaunchConfiguration(
'param_dir',
default=os.path.join(
get_package_share_directory('ex_calculator'),
'param',
'arithmetic_config.yaml'))
return LaunchDescription([
DeclareLaunchArgument(
'param_dir',
default_value=param_dir,
description='Full path of parameter file'),
Node(
package='ex_calculator',
executable='argument',
name='argument',
parameters=[param_dir],
output='screen'),
Node(
package='ex_calculator',
executable='calculator',
name='calculator',
parameters=[param_dir],
output='screen'),
])
# 필요시 실행 관련 설정을 선언하고 메소드의 리턴값으로 'LaunchDescription` 클래스로 반환함
def generate_launch_description():
xxx = LaunchConfiguration(yyy)
return LaunchDescription(yyy)
DeClareLaunchArgument(aaa),
Node(bbb),
Node(ccc),
])
param_dir: 파라미터 디렉토리를 설정하는 부분Node(
package=''
executable = ''
name=''
parameters=[param_dir]
output='screen'),
remappings: 특정 이름을 변경할 수 있는것, 내부 코드 변경없이 토픽, 서비스, 액션 등의 고유 이름을 변경할 수 있는 유용한 기능
namespace: 고유의 이름을 바꾸어 독립적인 네트워크 그룹핑이 가능
LaunchDescription.add_action: return값이 많은 경우 사용가능