TIKI-MINI로 시작하는 ROS2 실무
목차

1. 이론

1.5파라미터 (Parameter)

파라미터란?

로봇의 최대 속도, 센서 주소, 로봇 이름 같은 설정값을 코드에 직접 적어 두면 값을 바꿀 때마다 코드를 고치고 다시 빌드해야 합니다. 파라미터(Parameter) 는 이런 값을 노드 밖에서 정하게 해 주는 장치입니다.

  • 파라미터는 노드마다 따로 가지고 있습니다. 노드 이름과 파라미터 이름의 조합으로 구분합니다 (예: /driver의 speed).
  • 노드가 선언(declare) 한 파라미터만 존재합니다. 선언할 때 기본값을 줍니다.
  • 실행할 때 명령행이나 YAML 파일로 기본값을 덮어씁니다.
  • 실행 중에도 ros2 param set으로 바꿀 수 있습니다 (노드가 이를 처리하도록 만들어 둔 경우).
구분토픽서비스파라미터
용도계속 흐르는 데이터한 번의 요청과 응답노드의 설정값
예/cmd_vel, /scan주행 켜기/끄기최대 속도, 로봇 이름
값이 바뀌는 빈도계속요청할 때가끔 (설정할 때)

파라미터 타입

파라미터에는 타입이 있고 한 번 선언하면 그 타입이 고정됩니다. 기본값을 보고 타입이 정해집니다.

Python 값ROS2 타입예
True / FalseboolTrue
정수integer (int64)3
실수double0.5
문자열string'tiki'
리스트각각 배열 타입[1, 2, 3]

기본값을 0.5(double)로 선언했다면 나중에 1(정수)이나 'fast'(문자열)로 바꾸려는 시도는 거부됩니다. 실수 파라미터에는 1이 아니라 1.0처럼 소수점을 붙여 쓰는 습관이 안전합니다.

해보기 1: 선언하고 읽기

다음 순서가 기본입니다.

  1. declare_parameter(이름, 기본값) 으로 선언한다.
  2. get_parameter(이름).value 로 값을 읽는다.
LIVE

1) 파라미터 선언과 읽기

파라미터 (실행할 때 --ros-args -p 이름:=값 으로 넘긴 것과 같습니다)

직접 바꿔 보기

  • 위쪽 입력 칸에서 robot_name을 mini로, speed를 0.8로 바꾸고 실행해 보세요. 코드는 그대로인데 출력이 바뀝니다.
  • loud를 체크하면 대문자로 출력됩니다.
  • 파라미터 탭에서 선언된 파라미터와 --ros-args -p 로 재정의됨 표시를 확인하세요.
  • speed 칸에 1을 입력해도 동작합니다. 에뮬레이터는 정수를 실수 파라미터에 자동으로 맞춰 주기 때문입니다. 입력 칸이 값을 JSON 숫자로 넘기는 한계 탓인데, 실제 명령행에서는 speed:=1.0 처럼 쓰는 것이 안전합니다.
  • 코드에서 self.declare_parameter('speed', 0.5) 줄을 지우고 실행해 보세요. 어떤 오류가 날까요?

해보기 2: /cmd_vel 드라이버를 파라미터로 조절하기

1.3장의 드라이버는 속도가 코드에 박혀 있었습니다. 이제 speed와 turn을 파라미터로 만들어, 코드는 그대로 두고 값만 바꿔서 로봇의 움직임을 바꿔 봅니다.

LIVE

2) 파라미터로 속도 조절하기

파라미터 (실행할 때 --ros-args -p 이름:=값 으로 넘긴 것과 같습니다)

직접 바꿔 보기

  • turn을 0으로 바꾸면 직진합니다.
  • turn을 음수로 바꾸면 반대로 돕니다.
  • 반지름 1m인 원을 그리려면 speed와 turn을 어떻게 정해야 할까요? (1.3장의 힌트: 반지름은 speed / turn)
  • speed를 2.0으로 키우면 벽에 닿는 시간이 어떻게 달라지나요?

실행할 때 값 바꾸기 (참고)

개발환경을 구축한 뒤에는 --ros-args -p 로 파라미터를 넘겨 노드를 실행합니다. 위 1, 2번 예제의 입력 칸이 이것과 같은 효과입니다.

ros2 run <패키지> <실행파일> --ros-args -p speed:=0.8 -p turn:=0.2
# 노드 이름을 바꿔 실행하면서 파라미터 지정
ros2 run <패키지> <실행파일> --ros-args -r __node:=my_driver -p speed:=0.8

파라미터가 많으면 YAML 파일에 모아 두고 한 번에 넘깁니다.

# driver_params.yaml
driver:                # 노드 이름
  ros__parameters:     # 이 이름은 고정입니다 (밑줄 두 개)
    speed: 0.8
    turn: 0.2
ros2 run <패키지> <실행파일> --ros-args --params-file driver_params.yaml

실행 중인 노드의 파라미터는 ros2 param 명령으로 조회하고 바꿉니다.

ros2 param list                       # 모든 노드의 파라미터 이름
ros2 param get /driver speed          # 값 하나 읽기
ros2 param set /driver speed 0.8      # 값 바꾸기
ros2 param dump /driver               # 현재 값을 YAML로 출력
ros2 param describe /driver speed     # 타입, 설명, 범위

해보기 3: 잘못된 값 거부하기

노드가 실행 중에 ros2 param set으로 값이 바뀌어도, 최대 속도를 넘는 값처럼 위험한 값은 받으면 안 됩니다. 두 가지 방법이 있습니다.

  • 파라미터 콜백(add_on_set_parameters_callback): 값이 바뀌기 직전에 호출되어 SetParametersResult(successful=True/False)로 승인하거나 거부합니다. 거부 사유(reason)도 돌려줄 수 있습니다.
  • 디스크립터(ParameterDescriptor): 선언할 때 설명과 허용 범위를 붙입니다. 범위를 벗어난 값은 자동으로 거부됩니다.

아래 노드는 1초마다 speed를 바꿔 보고 마지막에 범위를 벗어난 turn을 시도합니다. 실제 ros2 param set을 누가 실행하는 대신 노드가 스스로 set_parameters를 호출합니다.

LIVE

3) 파라미터 콜백과 범위 검사

결과 읽는 법

  • 파라미터 탭: 변경 시도가 승인(흰색)되었는지 거부(붉은색)되었는지와 사유가 보입니다.
  • set_parameters는 예외를 던지는 대신 결과 목록을 돌려줍니다. successful을 꼭 확인하세요.

직접 바꿔 보기

  • 콜백의 허용 범위를 0.0 이상 0.5 이하로 바꾸면 어떤 시도가 거부될까요?
  • self.tries에 -0.1을 추가해 보세요.
  • 콜백에서 return SetParametersResult(successful=True)만 남기고 검사를 지우면 speed=2.0도 승인됩니다. 검사 코드가 없으면 값이 그대로 들어간다는 것을 확인하세요.

연습: 선언하지 않은 파라미터

아래 코드는 시작하자마자 오류로 종료됩니다. 오류 메시지를 읽고 고쳐 보세요. 고친 뒤에는 min_speed를 0.1에서 1.0 사이로 바꿔 가며 실행해 보세요.

LIVE

연습: 선언하지 않으면?

파라미터 (실행할 때 --ros-args -p 이름:=값 으로 넘긴 것과 같습니다)

힌트

  • 오류 메시지에 어떤 파라미터 이름이 나오는지 확인하세요.
  • max_speed는 어떻게 선언했나요? min_speed도 같은 방식으로 선언해야 합니다.

한눈에 정리

  1. 파라미터는 노드마다 가진 설정값이고 코드를 고치지 않고 실행할 때 바꿀 수 있다.
  2. declare_parameter(이름, 기본값)으로 선언하고 get_parameter(이름).value로 읽는다. 선언하지 않으면 오류가 난다.
  3. 타입은 선언할 때 고정된다. 다른 타입으로 바꾸려는 시도는 거부된다.
  4. 실행할 때는 --ros-args -p 이름:=값 이나 --params-file 파일.yaml, 실행 중에는 ros2 param get/set/dump를 쓴다.
  5. 실행 중 변경을 반영하려면 매번 다시 읽거나 파라미터 콜백에서 갱신한다. 잘못된 값은 콜백 또는 ParameterDescriptor의 범위로 거부한다.

확인 문제

Q1. get_parameter('speed')를 호출했더니 ParameterNotDeclaredException 오류가 납니다. 원인과 해결 방법은?

speed를 선언하지 않았기 때문입니다. 노드를 만들 때(보통 __init__) self.declare_parameter('speed', 0.5) 처럼 먼저 선언해야 합니다. 이름의 오타도 같은 오류를 만들므로 선언한 이름과 읽는 이름이 똑같은지도 확인하세요.

Q2. 최대 속도 파라미터를 declare_parameter('max_speed', 0.5)로 선언했습니다. 이후 ros2 param set /driver max_speed 1 처럼 정수 1을 보내면 어떻게 되나요?

파라미터는 실수(double)로 선언됐는데 정수 값을 넣으려 하므로 타입이 달라 거부될 수 있습니다. 실수 파라미터에는 1.0처럼 소수점을 붙여 씁니다. 정확히는 ros2 param set 명령이 값 모양을 보고 타입을 정하기 때문에 1은 정수로 해석됩니다.

Q3. 노드 시작 시 get_parameter('speed').value를 self.speed에 저장해 두고 타이머에서 self.speed만 씁니다. 실행 중에 ros2 param set으로 speed를 바꾸면 로봇의 속도가 바뀔까요?

바뀌지 않습니다. self.speed는 시작할 때 복사해 둔 값이라 파라미터가 바뀌어도 갱신되지 않습니다. 타이머 안에서 매번 get_parameter('speed').value를 읽거나, add_on_set_parameters_callback에서 self.speed를 갱신해야 합니다.

다음 장

1.6장에서는 오래 걸리는 작업을 목표, 피드백, 결과로 주고받는 액션을 다룹니다. 그다음 1.7장의 런치 파일에서는 이 장에서 배운 파라미터도 파일 하나로 함께 넘깁니다.