# ros2 param 명령어를 통한 파라미터 조정

#### Parameter의 개념과 활용

ROS2에서 노드(Node)는 내부적으로 다양한 설정값들을 파라미터(Parameter)로 관리한다. 예를 들어, 카메라 해상도 설정, 센서 주기, 필터 계수 등은 각 노드에서 파라미터로 등록해 놓고 필요할 때 값을 읽거나 쓸 수 있다. 이러한 파라미터는 실행 중에 동적으로 변경할 수 있으며, 이에 따라 노드의 동작 방식이 달라진다.

ROS1에서 동적 재구성(dynamic reconfigure)을 활용해 런타임에 파라미터를 조정하던 방식을, ROS2에서는 `ros2 param` 명령어나 파라미터 클라이언트(Parameter Client) 노드를 통해 수행한다. 특히 `ros2 param` 명령어는 터미널에서 간단히 파라미터를 조회하고 설정하기에 편리하다.

ROS2의 파라미터는 다음과 같은 특징을 가진다.

* 노드 이름을 기준으로 파라미터가 식별된다.
* 파라미터의 자료형(Type)은 `bool`, `int`, `double`, `string` 등이 지원된다.
* 파라미터를 지원하지 않는 노드에서는 `ros2 param` 명령을 사용해도 동작하지 않는다.
* 파라미터가 변경될 때마다 해당 노드에서 파라미터 콜백 함수를 정의해 두었다면 즉시 반영할 수도 있다.

#### ros2 param 명령어의 구조

`ros2 param`은 ROS2의 명령줄 인터페이스(ROS2 CLI) 중 하나로, 노드의 파라미터를 조회하거나 변경할 수 있도록 지원한다. 기본적인 사용법은 다음과 같다.

```
ros2 param <subcommand> <node_name> <arguments...>
```

여기서 `<subcommand>`에는 대표적으로 `list`, `get`, `set`, `describe`, `dump` 등이 있으며, `<node_name>`은 파라미터를 조회하고자 하는 노드의 이름이다.

이때 노드가 현재 실행 중이어야 파라미터 조정이 가능하다. 또한 노드가 파라미터를 명시적으로 선언했는지도 확인해야 한다(언디클레어(undeclare)된 파라미터를 다루는 것은 별도 옵션을 사용해야 할 수도 있음).

#### ros2 param list

`ros2 param`의 `list` 서브커맨드는 특정 노드가 보유하고 있는 파라미터 목록을 확인할 때 사용한다.

```
ros2 param list /my_node
```

위와 같이 실행하면 `/my_node` 노드에 선언된 파라미터 이름들이 나열된다. 만약 어떤 노드가 파라미터를 하나도 가지고 있지 않거나, 노드 이름이 잘못되었다면 빈 목록을 반환하거나 에러가 발생할 수 있다.

#### ros2 param get

특정 파라미터의 값을 확인하고자 할 때는 `get`을 사용한다.

```
ros2 param get /my_node camera_fps
```

위 명령은 `/my_node` 노드에 선언된 `camera_fps`라는 파라미터 값을 터미널에 출력한다. 반환되는 형태는 다음과 유사하다.

```
Name: camera_fps
Type: int
Value: 30
```

파라미터가 실제로 존재하지 않거나, 노드가 실행 중이 아니면 에러가 발생한다.

#### ros2 param set

런타임에 파라미터 값을 변경하고자 할 때 `set`을 활용한다.

```
ros2 param set /my_node camera_fps 60
```

이렇게 하면 `camera_fps` 파라미터가 60으로 변경된다. 노드 내에서 파라미터 변경 콜백 함수를 등록해 두었다면, 새로운 값(60)에 대한 처리 로직이 즉시 반영될 수 있다.

자료형에 따라 인자 전달 방식이 달라질 수 있다. 예를 들어 bool 형 파라미터를 `true` 또는 `false`로 설정하거나, string 형 파라미터를 설정할 때는 반드시 따옴표를 넣어주는 등 신경 쓸 점이 있다.

#### ros2 param describe

특정 파라미터에 대해 보다 자세한 정보를 확인하고자 할 때는 `describe` 서브커맨드를 사용할 수 있다.

```
ros2 param describe /my_node camera_fps
```

위와 같이 실행하면 노드에 선언된 해당 파라미터의 자료형(type), 읽기/쓰기가 허용되는지, 기본값(default value), 설명(description) 등이 표시된다. 다만, 파라미터 선언 시에 개발자가 메타데이터(설명, 최소/최대 범위 등)를 충분히 설정해 두어야 의미 있는 정보를 얻을 수 있다.

#### ros2 param dump

`dump` 서브커맨드는 노드에 등록된 모든 파라미터의 현재 상태를 YAML(YAML Ain’t Markup Language) 포맷으로 파일에 저장할 때 사용한다. 예를 들어,

```
ros2 param dump /my_node --output my_node_params.yaml
```

위 명령을 수행하면 `/my_node`의 모든 파라미터를 `my_node_params.yaml` 파일에 기록한다. 생성된 YAML 파일을 열어보면 다음과 같은 형태로 저장되어 있을 수 있다.

```yaml
my_node:
  ros__parameters:
    camera_fps: 30
    camera_resolution: "HD"
    use_color: true
```

이처럼 `dump`를 통해 나중에 재사용이 가능한 파라미터 세트 파일을 만들 수 있다.

#### 파라미터 파일을 통한 자동 로딩

ROS2 노드를 실행할 때 특정 파라미터 파일을 로딩하여 노드에 설정될 파라미터를 자동으로 적용할 수도 있다. 일반적으로 아래처럼 `--ros-args --params-file` 옵션을 활용한다.

```
ros2 run my_package my_node_executable \
  --ros-args --params-file my_node_params.yaml
```

여기서 `my_node_params.yaml` 파일에 있는 파라미터들이 노드 실행 시점에 로딩된다. 이러한 방식을 활용하면 여러 노드들의 파라미터를 YAML 파일 형태로 관리함으로써, 시스템 전체 파라미터를 일괄적으로 구성하거나 버전관리를 수행하기가 용이하다.

#### 파라미터 자료형 처리

`ros2 param set`이나 YAML 파일을 통해 파라미터를 등록하거나 수정할 때, 자료형을 명확히 구분해야 한다. 예를 들어 정수형(int)을 실수형(double)로 바꿀 수 없도록 노드에서 제한을 두었을 수 있다. 또한 bool 형은 `true/false`로, 문자열은 따옴표로 감싸서 사용해야 한다.

* **bool**: `true` 또는 `false`
* **int**: `42`, `-1`, `100` 등
* **double**: `3.14`, `-2.7` 등
* **string**: `"camera_name"`, `"HD"` 등

#### 파라미터 콜백 함수

C++ 또는 Python으로 작성된 ROS2 노드 코드에서 파라미터 변경 콜백 함수를 정의해 두면, 노드 실행 중에 파라미터가 변경될 때마다 해당 콜백에서 새로운 값에 대한 로직을 구현할 수 있다. 예시 구조는 대략 아래와 같다(C++의 경우).

```cpp
// 예시: rclcpp::Node를 상속받은 클래스 내부
this->set_on_parameters_changed_callback(
  [this](const std::vector<rclcpp::Parameter> &params) {
    for (const auto &param : params) {
      if (param.get_name() == "camera_fps") {
        RCLCPP_INFO(this->get_logger(), "camera_fps has changed to %d", param.as_int());
        // 변경된 파라미터 값에 따라 처리할 로직...
      }
    }
    return rcl_interfaces::msg::SetParametersResult().successful = true;
  }
);
```

이렇듯 콜백을 통해 동적으로 파라미터 값을 받아서, 센서 주기를 재설정하거나 필터 계수를 변경하는 등의 기능을 구현할 수 있다.

#### 파라미터 이벤트(Events) 토픽

ROS2에서는 파라미터의 변경 이력을 추적할 수 있도록 “Parameter Events”라는 전용 토픽을 제공한다. 노드가 어떤 파라미터를 변경하거나 새로운 파라미터를 선언 및 삭제할 때, 자동으로 이벤트가 발행(publish)된다. 이를 통해 시스템 전역에서 파라미터 변경 사항을 추적할 수 있으며, 별도의 디버깅 노드를 두어 이벤트를 모니터링하기도 편리하다.

아래 명령은 파라미터 이벤트 토픽을 구독(subscribe)하여 실시간으로 변경 사항을 확인하는 예시이다.

```
ros2 topic echo /parameter_events
```

해당 토픽을 모니터링하면, 어느 노드가 어떤 파라미터를 어떻게 변경했는지에 대한 정보를 받을 수 있다. 예시 메시지 구조는 다음과 비슷하다.

```plaintext
stamp:
  sec: 123456789
  nanosec: 987654321
node: "/my_node"
new_parameters:
  - name: "camera_fps"
    value:
      type: 2
      integer_value: 60
changed_parameters:
  - ...
deleted_parameters:
  - ...
```

* **new\_parameters**: 새롭게 선언된 파라미터 목록
* **changed\_parameters**: 기존 파라미터가 변경된 목록
* **deleted\_parameters**: 제거된 파라미터 목록

이를 활용하면 어느 시점에 누가 어떤 파라미터를 바꿨는지, 어떤 값으로 바뀌었는지를 손쉽게 로깅하거나 디버깅할 수 있다.

#### Lifecycle 노드에서 파라미터 다루기

ROS2에는 노드가 특정 상태들(UNCONFIGURED, INACTIVE, ACTIVE 등)을 가지며, 상태 전이를 제어할 수 있는 Lifecycle Node 개념이 있다. 이러한 Lifecycle Node에서도 파라미터를 활용할 수 있는데, 일반 노드와는 조금 다른 과정을 밟아야 할 수 있다.

1. **파라미터 선언 시점**: 노드가 UNCONFIGURED 상태에서 파라미터를 선언한다.
2. **CONFIGURE 단계**: 노드를 INACTIVE 상태로 전환하면서, 선언된 파라미터 값이 유효한지 검사하거나 초기화 과정을 진행한다.
3. **ACTIVATE 단계**: 본격적으로 노드 동작을 시작한다. 이때 파라미터 변경이 들어오면, INACTIVE 상태로 돌아간 뒤 재설정하는 방식을 취할 수도 있다. (구현 방법에 따라 다름)

Lifecycle Node에서 파라미터를 조정하려면 노드가 적절한 콜백을 제공해야 하고, 상태 전이에 따른 파라미터 유효성 검증 로직을 잘 구성해야 한다. 일반 노드와 마찬가지로 `ros2 param` 명령어를 사용할 수 있지만, 노드 상태에 따라 파라미터 변경이 제한되거나, 특정 단계에서만 반영될 수도 있다.

#### 파라미터 Server Node(전용 노드) 활용

ROS2에서는 별도의 ‘Parameter Server Node’를 두어 전역 파라미터를 관리하는 방식은 권장되지 않는다(ROS1의 파라미터 서버와 개념적으로 유사). 대신 각 노드가 스스로 파라미터를 관리하고, 필요한 경우 인터페이스를 통해 해당 노드의 파라미터에 접근하는 구조가 기본이다.

다만, 특정 상황(예: 여러 노드들이 동일한 설정값을 공유해야 하는 경우)에서 전용 노드를 두고, 그 노드에 파라미터를 선언해두며 각 노드가 이를 조회하는 형태로 구성할 수도 있다. 이 경우에도 `ros2 param` 명령어로 이 ‘Parameter Server Node’의 파라미터를 읽거나 쓸 수 있으며, 파라미터 이벤트 토픽을 통해 변경 상황을 전파할 수 있다.

#### 파라미터 최적화 및 베스트 프랙티스

* **필요한 파라미터만 선언**: 사용하지 않을 파라미터를 무작정 선언하면, 유지보수가 어려워지고 혼란이 생긴다.
* **이름 규칙 통일**: 여러 노드에서 동일한 역할을 하는 파라미터는 통일된 이름 규칙을 사용한다. 예: `camera_fps`, `camera_resolution`, `sensor_update_rate` 등
* **파라미터 콜백 함수에서 유효성 검증**: 파라미터가 0 이하로 설정되면 에러를 발생시키거나 기본값으로 되돌리는 등, 노드 내부에서 안전장치를 마련한다.
* **YAML 파일로 관리**: 여러 노드가 동시에 사용할 파라미터값을 버전 관리하기 위해 YAML 파일을 적극 활용한다.
* **Lifecycle Node 고려**: 노드가 ACTIVE 상태에서 파라미터를 수정해야 한다면, 상태 전이 로직을 신중히 설계한다.
