# QoS 튜닝을 통한 트래픽 제어 기초

#### QoS 정의

QoS(Quality of Service)는 네트워크나 분산 환경에서 데이터를 안정적이고 목적에 맞게 전송하기 위한 일련의 설정을 의미한다. ROS2 환경에서도 노드 간 통신 시 다양한 QoS 프로필을 제공하여, 특정 상황(실시간 요구, 신뢰성 우선 등)에 맞추어 메시지 전송 및 수신 동작을 최적화할 수 있다. QoS 튜닝은 단순히 신뢰성을 높이는 것에 그치지 않고, 시스템에서 발생하는 트래픽을 제어하여 대역폭 사용률을 효율적으로 관리하는 측면에서도 중요하다.

#### ROS2에서의 QoS 요소

ROS2의 QoS 설정은 DDS(Data Distribution Service) 계층에서 제공되는 여러 정책(Policy)을 기반으로 한다. 대표적인 QoS 파라미터는 아래와 같다.

* Reliability: 메시지 전송 방식을 결정한다.
  * Reliable: 수신 노드가 메시지를 누락 없이 받도록 보장한다.
  * Best Effort: 메시지 누락이 발생할 수 있지만, 대역폭이나 전송 지연 측면에서 부담이 적다.
* Durability: 노드가 구독을 시작하기 전에 발행된 메시지의 보존 여부를 결정한다.
  * Volatile: 이전에 발행된 메시지는 필요 시 재전송되지 않는다.
  * Transient Local: 발행자가 메시지를 보존하며, 구독자가 뒤늦게 구독해도 최근 메시지를 일부(또는 전부) 받을 수 있다.
* **Deadline**: 메시지 전달 주기에 대한 제약을 설정한다. 주어진 시간 안에 메시지가 전달되지 않으면 QoS 위반으로 간주한다.
* **Liveliness**: 노드나 토픽의 활성화 상태를 모니터링하고, 비정상 종료 등의 이슈를 조기에 감지할 수 있게 해준다.
* **History**: 메시지를 어느 시점까지 보관할 것인지 결정한다. Depth와 함께 설정하며, 캐시 메모리를 통해 메시지가 누적된다.
* **Depth**: 메시지 히스토리에서 보관할 수 있는 메시지의 개수이다.

위 QoS 정책들은 설정 값에 따라 서로 다른 트래픽 특성을 만들어낸다. 예를 들어 Reliability를 Best Effort로 설정하면 전송 누락 가능성이 있지만 트래픽이 줄어들고, Reliable로 설정하면 어느 정도 네트워크 부하가 커지는 대신 메시지 유실을 줄일 수 있다.

#### 트래픽 제어 관점에서의 QoS 파라미터 분석

ROS2 애플리케이션에서 QoS를 튜닝할 때, 가장 먼저 고려해야 할 것은 메시지의 중요도와 허용 가능한 지연 시간(또는 손실) 간의 균형이다. 이를 정량적으로 판단하기 위해 네트워크 트래픽 분석이 필요할 수 있다.

**트래픽 부하와 대역폭**

* 메시지 발행 주기를 $T\_p$라 하고, 각 메시지의 평균 크기를 $S\_m$이라 하자.
* 네트워크에서 해당 노드가 차지하는 평균 대역폭 $\eta$는 $\eta = \frac{S\_m}{T\_p}$ 로 단순화할 수 있다. 단위 시간당 전송되는 데이터의 양이므로, 여기서 $S\_m$이 크거나 $T\_p$가 작아지면 네트워크 부하가 커진다.
* Reliability를 Reliable로 설정하면, 누락된 메시지의 재전송(ACK/NACK 기법 등)이 추가되어 실제 트래픽은 $\eta$ 이상의 값을 갖게 된다.

**메시지 누적과 지연**

* History와 Depth 설정은 메시지가 누적되어 버퍼링되는 수준을 결정한다. 즉, 발행자가 한꺼번에 여러 메시지를 송신할 때, 구독자가 일정 부분 데이터를 빠르게 처리하지 못하면 메시지가 계속 쌓이게 된다.
* 메시지 누적 때문에 발생할 수 있는 지연(latency)을 추정하기 위해서는 시스템에 배치된 각 노드의 처리속도와 네트워크 지연을 함께 고려해야 한다.

#### QoS 정책 간 상호작용

QoS 파라미터는 서로 독립적이기보다는 상호 밀접하게 연결되어 있다. 예를 들어 Reliability를 Reliable로 설정하면서 History와 Depth를 적절히 설정하지 않으면, 버퍼 오버플로가 발생하여 오히려 전송 실패율이 높아질 수도 있다. 반면 Best Effort로 설정하여 History Depth를 크게 잡으면, 메시지 유실이 발생해도 빠르게 재시도하지 않기 때문에 전체 트래픽은 줄어들지만, 실시간 모니터링 등의 용도로는 부적절해질 수 있다.

ROS2 노드 간 통신에서 트래픽을 제어하기 위해서는 다음과 같은 절차가 도움이 된다.

1. **목표 정의**: 트래픽 사용량을 특정 임계값 이하로 유지하거나, 지연 시간을 특정 값 이하로 제한하고자 하는 등, 시스템 요구사항을 명확히 정의한다.
2. **QoS 정책 조합 설정**: Reliability, Durability, Deadline, Liveliness 등의 파라미터를 상황에 맞추어 조합하고, History와 Depth 설정으로 메시지 버퍼링 규모를 조절한다.
3. **측정 및 모니터링**: 실제 트래픽과 지연을 측정하여, 설정한 QoS 값이 목표 요구사항을 만족하는지 확인한다.
4. **재조정**: 요구사항과 실제 성능 간의 괴리가 있으면 QoS 정책을 재조정하거나, 노드 설계 방식을 변경한다.

#### 동적 QoS 튜닝

ROS2에서는 노드 실행 중에도 QoS 파라미터를 일부 동적으로 변경할 수 있는 기법을 제공한다. 그러나 모든 QoS가 동적으로 수정 가능한 것은 아니며, 주로 아래 항목들이 적용 가능하다.

* **Publisher/Subscriber 동적 생성**: 기존 노드를 종료하고 새 QoS 프로파일을 사용한 노드를 다시 실행할 수 있다.
* **Dynamic Reconfigure**: rclcpp, rclpy 등 상위 레벨 API를 활용하여 파라미터 변경을 시도할 수 있다.
* **비즈니스 로직 기반 변경**: 애플리케이션 로직 상에서 특정 이벤트(예: 네트워크 부하가 갑자기 상승) 발생 시 QoS 설정을 자동으로 변경한다.

이러한 기법으로 시스템이 동작 중에도 트래픽 제어 정책을 유연하게 적용할 수 있다.

#### QoS별 트래픽 제어 시나리오

ROS2 애플리케이션에서 트래픽을 제어해야 하는 상황은 매우 다양하다. 본 장에서는 특정 QoS 정책을 적용했을 때 어떤 트래픽 특성이 나타나는지 시나리오 기반으로 살펴본다.

**1. Best Effort + Volatile 시나리오**

* **주요 특성**: 최소한의 트래픽 오버헤드, 메시지 유실 가능성 존재
* **적용 예시**: 센서 데이터 중 일부 누락이 허용되고, 빠른 전송이 필요한 경우(예: 끊임없이 변화하는 무손실 압축 영상 데이터)
* 트래픽 분석:
  * Best Effort 방식은 추가 재전송이나 ACK/NACK 트래픽이 거의 없다.
  * 단, 수신 측에서 메시지 누락이 발생해도 재전송 요청이 없으므로, 실제 수신 주기 간격이 발행 주기보다 커질 수 있다.
  * Volatile 정책으로 이전 메시지를 전혀 보관하지 않으므로, 늦게 구독 시작한 노드는 과거 데이터를 받을 수 없다.

**2. Reliable + Volatile 시나리오**

* **주요 특성**: 메시지 유실 최소화, 트래픽 증가 가능성
* **적용 예시**: 중요한 이벤트 로그, ROS2 기반 제어 명령(저속이지만 100% 전달이 중요한 경우)
* 트래픽 분석:
  * 신뢰성 보장을 위해 수신 측에서 ACK를 보내거나 재전송이 발생할 수 있으므로, 전체 트래픽이 증가한다.
  * Volatile 정책으로 인해, 과거 데이터가 필요한 경우에는 구독 시점 이후부터의 데이터만 수신 가능하다.

**3. Best Effort + Transient Local 시나리오**

* **주요 특성**: 중간 정도의 트래픽 오버헤드, 과거 메시지 일부 확보 가능
* **적용 예시**: 센서 중 일부분은 어느 정도 신뢰도가 필요하고, 구독자 간 새로 유입되는 구독자가 일정 데이터는 받고자 할 때
* 트래픽 분석:
  * Best Effort로 인해 ACK/NACK 기반의 재전송은 최소화된다.
  * Transient Local 정책이므로 발행자는 최근 메시지를 일정 수량 보존한다. 새로운 구독자가 생길 때 과거 데이터를 전송하는 트래픽이 순간적으로 증가한다.

**4. Reliable + Transient Local 시나리오**

* **주요 특성**: 메시지 유실 방지, 과거 메시지도 전달 가능, 상당한 트래픽 증가 가능성
* **적용 예시**: 실시간성이 최우선은 아니지만, 데이터 유실 없이 과거 정보도 필요로 하는 시스템(예: 로깅, 맵핑)
* 트래픽 분석:
  * Reliable 정책에 따른 재전송 및 ACK 트래픽과, Transient Local로 인한 과거 데이터 전송이 함께 발생한다.
  * 시스템 규모가 커질수록 트래픽 부담도 가중되므로, History Depth 설정이 매우 중요하다.

#### 성능 모니터링 및 튜닝 방법론

QoS 설정은 이론적으로만 설계해서는 실제 시스템 요구사항을 충족하지 못할 수 있다. 따라서 다음 과정을 통해 실제 운영 환경에서의 튜닝을 수행해야 한다.

**측정 지표**

1. 메시지 손실률(Loss Rate):
   * $\text{Loss Rate} = \frac{\text{발행 메시지 수} - \text{수신 메시지 수}}{\text{발행 메시지 수}}$
   * Reliable 모드에서도 일시적으로 네트워크 대역폭 부족 등으로 메시지 유실이 발생할 수 있다.
2. 평균 지연시간(Average Latency):
   * $\text{Avg. Latency} = \frac{1}{N} \sum\_{i=1}^{N} (t\_{\text{수신}, i} - t\_{\text{발행}, i})$
   * QoS 정책 중 Deadline이 지켜지는지 파악할 때 참고한다.
3. Jitter(지연 변동폭):
   * 개별 지연시간 편차를 관찰하여, 실시간성이 요구되는 경우 유용하다.
4. CPU/메모리 사용량:
   * Reliable 모드에서 History Depth가 클수록 메모리 사용량이 증가하며, 재전송 메커니즘으로 CPU 부하도 높아질 수 있다.
5. 네트워크 대역폭 사용률:
   * $\eta = \frac{S\_m}{T\_p}$ (단순모델)
   * 실제 환경에서는 ACK/NACK 등으로 인해 더 복잡한 형태를 띠므로, 트래픽 모니터링 툴을 통해 정밀 측정할 수 있다.

**트레이싱 및 로깅 툴 활용**

* **ros2 tracing**: ros2\_tracing 패키지를 이용해 노드 실행 흐름과 메시지 수신/전송 타이밍을 추적 가능하다.
* **DDS 벤더 툴**: 사용 중인 DDS 벤더마다 제공하는 모니터링 툴을 통해 지연, 메시지 손실, 네트워크 사용률 등을 분석할 수 있다.

**튜닝 순서 제안**

1. **초기 설정**: 시스템 요구사항에 맞추어 Reliability, Durability, History, Depth를 우선 설정한다.
2. **성능 측정**: 위에서 언급한 측정 지표를 수집한다.
3. **병목 지점 파악**: 특정 노드의 처리 능력 부족, 네트워크 대역폭 한계, QoS 정책 충돌 등 병목이 어디에서 주로 발생하는지 분석한다.
4. **미세 조정**: 문제가 되는 지점(버퍼 오버플로, 지연 등)에 맞추어 QoS 정책을 세분화한다.
5. **반복**: 최종적으로 목표 지표를 만족할 때까지 2\~4 단계를 반복한다.

#### 네트워크 레벨에서의 QoS 영향

QoS 정책이 노드 간 메시지 교환에만 영향을 미치는 것은 아니다. DDS를 기반으로 동작하는 ROS2는 네트워크 계층(UDP, Multicast, Unicast 등)과 밀접하게 연관되어 있으므로, QoS 정책에 따라 네트워크 트래픽 패턴도 달라진다.

* **Multicast 사용**: 다수의 구독자가 같은 토픽을 수신할 때, DDS 벤더 구현에서 멀티캐스트 그룹을 통해 데이터를 전송하는 방식을 사용할 수 있다. 이 경우, **Reliable** 모드에서 단일 스트림에 대한 재전송이 필요할 수 있으므로, 전체 트래픽이 다소 복잡해질 수 있다.
* **Unicast 사용**: 특정 구독자만 존재하는 토픽은 자동으로 유니캐스트를 통해 전송될 수 있다. **Best Effort** 모드에서는 일반 UDP 트래픽처럼 동작하며, 오버헤드가 크지 않다.
* **네트워크 토폴로지 고려**: QoS 정책이 동일하더라도, 네트워크의 구조(스위치나 라우터 구성, VLAN, VPN 등)에 따라 실제 지연과 손실 특성이 달라진다.

#### QoS 오버헤드 분해

트래픽 제어 관점에서 QoS 오버헤드를 더 세분화하여 살펴보자.

1. 재전송 오버헤드
   * Reliable 모드에서 수신자가 패킷 누락을 감지할 경우, 발행자에게 재전송 요청을 보낸다.
   * 재전송 요청 자체도 트래픽을 발생시키며, 발행자는 누락된 패킷을 다시 전송해야 한다.
2. Keep Alive/Heartbeat 오버헤드
   * DDS 네트워크 통신에서 수신자 또는 발행자가 주기적으로 자신의 상태(Alive 상태)를 알리는 패킷을 전송한다.
   * 이러한 Heartbeat 메시지를 통해 상대방이 여전히 활성화되어 있음을 확인하고, 필요한 경우 재전송을 유도한다.
3. Discovery 오버헤드
   * ROS2는 DDS Discovery 메커니즘을 사용해 노드끼리 서로 인지한다. QoS 매개변수는 Discovery 단계에서 교환되는 데이터에도 영향을 주며, 그 과정에서 트래픽이 추가된다.
4. Metadata(헤더) 오버헤드
   * 메시지에 DDS/ROS2가 관리하는 헤더나 시퀀스 번호, QoS 관련 정보 등이 포함된다. 메시지 크기가 작을수록 상대적으로 헤더 오버헤드가 비중이 커진다.

#### QoS 프로파일 활용 예시

ROS2에서는 자주 사용되는 QoS 설정을 **Sensor Data**, **Services**, **Parameters** 등 특정 use-case에 맞춰 정의해둔 프로파일로 제공하는 경우가 많다. 예컨대, $rclcpp::SensorDataQoS$는 주로 빠른 주기의 센서 데이터를 신속하게 처리하기 위해 Best Effort를 사용하는 등, 상황에 맞는 적절한 QoS 파라미터를 미리 설정해두었다.

* **SensorDataQoS**: 보통 Best Effort + Volatile
* **ServicesQoS**: 메시지 유실이 없는 Reliable + Volatile (서비스 요청-응답 구조)
* **ParametersQoS**: 파라미터 동기화에 주로 Reliable 사용

이러한 기본 프로파일을 시작점으로 삼아, 필요한 곳에 한해 History Depth, Durability 등을 추가로 조정하는 식으로 트래픽 제어 목표를 달성할 수 있다.

#### QoS 정책 충돌과 호환성

ROS2 DDS 계층에서 QoS 설정이 상호 호환되지 않을 경우, 발행자와 구독자가 연결(Matching)되지 않을 수도 있다. 예를 들어 다음과 같은 경우 문제를 일으킬 수 있다.

* 발행자는 Reliable로 설정하고, 구독자는 Best Effort로 설정한 경우
  * DDS 표준에서 Reliability가 서로 다르면 호환이 안 될 수 있다(일반적으로 구독자가 더 엄격한 신뢰성을 요구하면 매칭이 실패).
* 발행자와 구독자 모두 Deadline을 다르게 설정했을 때
  * 서로 맞추지 못하면 Deadline QoS가 충돌할 수 있다.

이러한 상황을 방지하려면, **QoS 호환성**(Compatibility) 개념을 이해해야 한다.

* DDS 스펙 상에서 “필수적으로 일치해야 하는 QoS”와 “상호 조정 가능한 QoS”가 구분되어 있다.
* ROS2 문서나 DDS 벤더 문서를 통해 해당 부분을 미리 확인하고, 발행/구독 노드가 일관된 설정을 갖도록 해야 한다.

#### 간단한 QoS 튜닝 실습 예시

아래는 ROS2에서 발행자(Publisher)와 구독자(Subscriber) 각각의 QoS를 설정하는 간단한 예시이다. (C++ 기준)

```cpp
// 발행자 예시
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_ = 
  this->create_publisher<std_msgs::msg::String>(
    "example_topic", 
    rclcpp::QoS(rclcpp::KeepLast(10)).reliable().transient_local()
  );

// 구독자 예시
auto subscription_ = 
  this->create_subscription<std_msgs::msg::String>(
    "example_topic",
    rclcpp::QoS(rclcpp::KeepLast(10)).reliable().transient_local(),
    [this](std_msgs::msg::String::SharedPtr msg) {
      // 콜백 처리
    });
```

* **reliable()**: 신뢰성 보장 (메시지 유실 최소화)
* **transient\_local()**: 과거 메시지(최대 Depth 10개)를 일정 시간 보관
* **rclcpp::KeepLast(10)**: History Depth를 10으로 설정

위와 같이 발행자와 구독자가 동일한 QoS 설정을 사용하면, 메시지 유실 없이(네트워크 사정이 크게 나쁘지 않은 이상) 과거 메시지까지 보장되는 안정적인 통신이 가능하다. 그러나 재전송 트래픽이 증가할 수 있고, 새로운 구독자가 추가될 때 과거 데이터를 전송해야 하므로 일시적 트래픽 스파이크가 발생할 수 있다.

#### 실시간성(Real-Time) 고려와 QoS

ROS2 Humble 버전에서 실시간성(Real-Time)을 달성하고자 할 때, QoS 설정이 중요한 역할을 한다. 특히, 하드 실시간(Hard Real-Time)을 요구하는 경우에는 메시지 손실률보다 **지연시간 예측 가능성**과 **지연 편차(Jitter)의 최소화**가 우선시된다.

* **미션 크리티컬(Mission Critical) 환경**: 드론 제어, 자율주행 차량 등에서 특정 주기마다 들어오는 센서 데이터를 놓치지 않아야 하며, 메시지 전달 지연이 누적되지 않도록 주의해야 한다.
* **DDS 실시간 Extension**: 일부 DDS 벤더는 실시간 확장 기능(예: RTPS 2.3, 마이크로 DDS 구현 등)을 제공하여, 스케줄링이나 메모리 할당 방식을 제어할 수 있다.
* **Reliable vs Best Effort 선택**: 실시간 환경에서는 재전송으로 인해 지연이 늘어날 위험이 있기 때문에, 상황에 따라 Best Effort를 사용해 지연을 줄이기도 한다. 단, 중요한 제어 신호는 Reliable가 권장되기도 하므로, 시스템 특성에 따라 적절한 절충이 필요하다.
* **Liveliness 관리**: 발행자나 구독자의 활성 상태를 주기적으로 파악하여, 비정상 종료 시 빠르게 대응해야 하는 경우(분산 제어 시스템)에 특히 유용하다.

#### Time-Based Filter 정책

DDS 레벨에서 제공하는 Time-Based Filter 정책은 **구독자가 수신할 메시지의 빈도를 일정 주기로 제한**하는 기능이다. ROS2 자체에서는 아직 폭넓게 노출되지 않았지만, DDS 벤더에 따라 세부 파라미터를 조정할 수 있다.

* $\text{Minimum Separation} = \Delta t$ 이라고 할 때, 구독자는 $\Delta t$ 이내에 들어오는 메시지 중 최근 메시지만 수신하도록 설정할 수 있다.
* 센서 데이터가 매우 빠른 속도로 들어오지만, 실제로는 초당 10Hz만 처리해도 충분한 상황이라면 Time-Based Filter로 트래픽을 줄일 수 있다.
* 다만, ROS2에서 이를 직접 사용하는 경우는 많지 않으며, **자체적으로 발행주기를 제한**하거나, **Throttle** 노드를 두어 메시지 레이트를 낮추는 방식을 주로 쓴다.

#### Resource Limits 설정

QoS에서 History, Depth 등의 설정과 더불어 Resource Limits(자원 제한) 정책을 통해 노드가 사용할 수 있는 버퍼나 큐의 크기를 제한할 수 있다.

* **Max Samples**, **Max Instances**, **Max Samples per Instance** 등의 파라미터를 통해 메시지 캐시나 인스턴스 관리 제한을 둘 수 있다.
* 시스템 자원(메모리, CPU)이 한정되어 있는 임베디드 환경에서는 너무 많은 메시지를 버퍼링하지 못하도록 방어 기제를 마련해야 한다.
* ROS2 API 레벨에서는 History와 Depth 외의 Resource Limits를 세밀하게 지정하기가 다소 제한적이나, DDS 벤더별 설정 파일(예: XML 형태)을 통해 세부 조정을 적용할 수 있다.

#### QoS 미스매치(Mismatch) 디버깅

노드 간 통신에서 발행자와 구독자가 연결되지 않는 문제가 발생할 때, 가장 먼저 의심해봐야 하는 것이 QoS 미스매치다.

**ros2 topic list / ros2 topic info**:

* 노드들이 사용하는 QoS 설정을 확인할 수 있다.
* 예:

```bash
ros2 topic info /example_topic
```

**DDS 벤더 로깅**:

* QoS 미스매치가 발생하면 DDS 쪽에서 경고나 오류 메시지가 남을 수 있다.
* 벤더별 로깅 레벨을 높여서 확인하면, “QoS profiles are incompatible” 같은 메시지가 나타날 수도 있다.

**rqt\_graph / ros2 doctor**:

* ROS2 네트워크 트포그래피(토폴로지)가 비정상적으로 구성되어 있지 않은지 점검한다.

#### QoS 튜닝 시 고려해야 할 상위 계층 이슈

QoS만으로 모든 트래픽 문제를 해결할 수 있는 것은 아니다. 아래와 같은 상위 계층 이슈를 함께 고려해야 한다.

* **Node/Executor 설계**: 다수의 Subscriber 콜백이 하나의 Executor에 몰리면, 콜백 처리 지연이 발생해 통신 지연으로 이어질 수 있다.
* **콜백 콜 완화 기법**: 주기적 타이머 콜백과 Subscribe 콜백을 병행해서 쓸 때, 처리량 제한을 위해 레이트 제한(Throttle), QoS + Timer 조합 같은 구조를 활용할 수 있다.
* **메시지 데이터 구조 최적화**: 메시지 구조가 지나치게 크면, 불필요한 필드를 줄이고 직렬화 방식을 개선해 전송 효율을 높여야 한다.
* **네트워크 하위 계층 품질**: QoS를 튜닝해도 물리적 네트워크 품질(라우팅, 스위칭, 채널 혼잡 등) 문제나 RTOS 스케줄링 이슈가 있으면 실질적 개선이 어려울 수 있다.

#### 대규모 시스템에서의 QoS 스케일업

ROS2는 소규모 로컬 시스템부터 수십\~수백 개 이상의 노드가 상호 통신하는 대규모 분산 시스템까지 확장 가능하다. 노드 수가 늘어날수록 다음과 같은 현상이 나타날 수 있다.

* **Discovery 트래픽 폭증**: 노드가 많아질수록 DDS Discovery 프로세스에서 멀티캐스트/브로드캐스트 트래픽이 증가한다.
* **네트워크 분할(Segment)**: VLAN, 서브넷 등을 통해 네트워크를 분리하고, DDS Router나 브리지 노드를 활용해 트래픽을 일정 부분 격리할 필요가 있다.
* **QoS 커스터마이징**: 모든 노드에 동일한 QoS 설정을 적용하지 않고, 중요 노드와 부차적 노드의 QoS 전략을 구분하여 효율을 높일 수 있다.

#### mermaid를 이용한 QoS 아키텍처 예시

아래 mermaid 예시에서는 ROS2 네트워크 내부에서 **Publisher**, **Subscriber**, **QoS 브로커(가칭)** 등이 상호작용하며 트래픽을 제어하는 모습을 도식화해볼 수 있다.

{% @mermaid/diagram content="flowchart LR
A\["Publisher Node<br>(Reliable, Volatile)"] -->|메시지 발행| B\["QoS Broker<br>(Policy Manager)"]
B --> C\["Subscriber Node1<br>(Best Effort, Volatile)"]
B --> D\["Subscriber Node2<br>(Reliable, Transient Local)"]
C -->|에이전트 보고| B
D -->|에이전트 보고| B" %}

* **QoS Broker(가칭)**: 실제 ROS2에서 제공되는 컴포넌트는 아니지만, 여러 노드의 QoS 정책을 중개하거나 실시간 모니터링을 담당하는 별도 노드를 구성해볼 수 있음을 시각적으로 표현했다.
* **Publisher -> Subscriber1(Best Effort)**: 트래픽 최소화를 우선시한다.
* **Publisher -> Subscriber2(Reliable)**: 중요한 구독자에게는 신뢰성을 높인다.

#### DDS 벤더별 QoS 최적화 팁

ROS2의 QoS 설정은 DDS 계층에 의존하므로, 사용 중인 DDS 벤더(Opensplice, RTI Connext, Fast-DDS, Cyclone DDS 등)에 따라 세부 동작이 달라질 수 있다. 벤더별로 제공하는 설정 파일(XML, YAML 등)을 통해 ROS2에서 노출되지 않는 파라미터까지 미세 조정이 가능하다.

1. **Transport 설정**: UDP나 TCP, Multicast, Zero-Copy Transport 등을 선택 가능하다. 특정 벤더는 Zero-Copy 전송으로 지연을 줄이는 기능을 제공한다.
2. Discovery 방식 최적화:
   * **Simple** vs **Enhanced** Discovery 모드, Participant-level Discovery 제한, Peer 리스트 지정 등을 통해 초기에 불필요한 브로드캐스트 트래픽을 줄일 수 있다.
3. **Thread Pool / Task Priority**: DDS 스레드의 우선순위를 높이거나, 실시간 스케줄러(예: SCHED\_FIFO) 적용을 지원하는 벤더가 있다. 이를 통해 실시간성을 강화할 수 있다.
4. **자원 제한(Resource Limits) 세분화**: ROS2 레이어에서 History와 Depth만 설정하기보다는, DDS XML 설정을 통해 Sample 관리, 인스턴스 관리, Publisher/Subscriber마다 별도 버퍼 크기 등 복잡한 튜닝이 가능하다.

#### QoS 실전 운영 사례

ROS2를 적용하는 프로젝트에서 트래픽 제어가 중요한 실제 사례들을 간단히 살펴보자.

**자율주행 로봇 센서 융합**

* **카메라, LiDAR, IMU 등 복합 센서**에서 빠른 속도로 방대한 데이터를 발행할 때, 네트워크 용량이 부족해 지연이나 손실이 발생한다.
* 1차적으로 Best Effort로 전송하되, 중요한 감지 이벤트는 Reliable Topic으로 별도 전송하는 하이브리드 방식이 자주 쓰인다.
* 오버헤드를 줄이기 위해 일부 센서는 메시지 크기를 줄이거나(압축, 다운샘플링), 필요 시 **Time-Based Filter**로 구독자가 원하는 데이터만 간헐적으로 받아볼 수 있게 한다.

**분산 로봇 군집 제어(Swarm)**

* 다수의 로봇이 서로의 위치나 상태를 공유할 때, 트래픽 폭증을 막기 위해 중계 노드(브로커 역할)를 두어 QoS 정책을 다르게 적용한다.
* 예: 각 로봇이 높은 빈도로 센서데이터를 발행하되, 중앙 브로커가 “중요 이벤트”만 Reliable로 재발행하고, 나머지는 Best Effort 토픽으로 단순 브로드캐스트한다.

**원격 작업(텔레오퍼레이션)**

* 네트워크 지연이 큰 WAN 환경에서 ROS2 노드를 연결해 텔레오퍼레이션을 수행할 때, Reliable 모드로 인한 재전송 지연이 위험을 초래할 수 있다.
* 제어 명령은 Best Effort로 빠르게 전달하며, 시스템 상태 피드백이나 오류 로그는 Reliable로 보완한다.

#### QoS 튜닝의 계층적 접근

아래는 QoS 튜닝 과정을 계층적으로 나타낸 간단한 개념도이다.

{% @mermaid/diagram content="flowchart LR
A\[네트워크<br>물리/링크 계층] --> B\[ROS2 DDS<br>QoS 세부 설정]
B --> C\["ROS2 애플리케이션<br>(rclcpp, rclpy)"]
C --> D\[상위 로직<br>제어/결정]" %}

1. **네트워크 물리/링크 계층**: 실제 대역폭, 지연, 패킷 손실 상황을 모니터링하고, 라우팅/스위칭 장비의 QoS(802.1p, DSCP 등)를 조정한다.
2. **ROS2 DDS QoS 세부 설정**: Reliability, Durability, History, Depth, Resource Limits 등 최적화.
3. **ROS2 애플리케이션**: 콜백 구조, Executor 설정, 메시지 주기/크기 제어, 노드 분할/통합 여부 결정.
4. **상위 로직**: 각 노드 간 통신 내용(주제), 우선순위 설정, 이벤트 중심 QoS 전환 전략 마련 등.

#### 추가 점검 사항

* **상황별 프로파일화**: 개발 과정에서 요구사항별(실시간, 높은 신뢰도, 대규모 브로드캐스트 등) QoS 프로파일을 몇 가지 정의해두면, 새 노드 개발 시 재사용이 용이하다.
* **테스트 자동화**: CI(Continuous Integration) 환경에서 QoS 설정이 제대로 적용되었는지, 메시지 손실률/지연이 임계값 내인지 자동으로 검증하는 테스트 스크립트를 마련한다.
* **장애 상황 시뮬레이션**: 패킷 손실율이 인위적으로 높은 환경(예: tc, netem 등으로 에뮬레이션)에서 QoS 정책이 어떻게 작동하는지 사전에 확인한다.
