ROS2 DDS — 미들웨어 구조와 QoS 설정

ROS2DDSProtocol

ROS2는 노드 간 통신에 DDS(Data Distribution Service)를 사용한다. ROS1의 roscore 중앙 브로커 방식을 버리고, 분산 Discovery와 QoS 기반 통신을 도입한 것이다.

ROS1의 문제 — 왜 DDS인가

ROS1은 roscore가 모든 노드의 등록과 토픽 매칭을 담당한다. roscore가 죽으면 새 노드 등록이 불가능하고, 네트워크 분리 환경에서는 동작하지 않는다. 또한 통신 품질(손실 허용, 지연 제한 등)을 제어할 방법이 없다.

DDS는 이 세 가지를 해결한다:

  • 중앙 브로커 없이 노드끼리 직접 Discovery
  • QoS 정책으로 통신 품질 제어
  • OMG 표준 기반으로 벤더 간 호환

ROS2 — DDS 통합 구조

Application (rclcpp / rclpy)
        |
    RCL (ROS Client Library)
        |
    RMW (ROS MiddleWare interface)
        |
  +-----------+-----------+
  |           |           |
Fast DDS  Cyclone DDS  Connext DDS

RMW 레이어가 DDS 벤더를 추상화한다. 애플리케이션 코드를 바꾸지 않고 DDS 구현체를 교체할 수 있다.

# DDS 벤더 변경
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp    # Fast DDS (기본)
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp  # Cyclone DDS

주요 DDS 벤더

벤더패키지특징
eProsima Fast DDSrmw_fastrtps_cppROS2 기본값. Discovery Server 지원
Eclipse Cyclone DDSrmw_cyclonedds_cpp경량. 실시간 결정론적 통신에 최적화
RTI Connext DDSrmw_connextdds상용. 대규모 시스템, 보안 기능

Discovery — 노드를 어떻게 찾는가

Simple Discovery (기본)

모든 노드가 멀티캐스트로 자신을 알린다. 설정 없이 같은 네트워크의 모든 ROS2 노드가 서로를 찾는다.

Node A ---multicast---> 네트워크
Node B ---multicast---> 네트워크
Node C ---multicast---> 네트워크
         (모두가 모두를 발견)

한계: 노드 수가 늘면 Discovery 패킷이 로 증가한다. WiFi 환경에서는 멀티캐스트가 불안정하다.

Discovery Server (Fast DDS 전용)

중앙 서버가 Discovery 정보를 관리한다. 노드는 서버에만 등록하고, 관련 토픽이 있는 노드 정보만 받는다.

# 서버 실행
fastdds discovery --server-id 0 --ip-address 192.168.1.100 --port 11811

# 클라이언트 노드
export ROS_DISCOVERY_SERVER=192.168.1.100:11811
ros2 run demo_nodes_cpp talker

Discovery Server v2는 같은 토픽을 구독하지 않는 노드 간에는 Discovery 데이터를 교환하지 않는다. 대규모 시스템(수십~수백 노드)에서 네트워크 부하가 크게 줄어든다.

Domain ID — 네트워크 격리

같은 네트워크에서 여러 로봇이나 팀이 ROS2를 사용할 때, Domain ID로 통신을 격리한다.

# 로봇 A 그룹
export ROS_DOMAIN_ID=1
ros2 run my_pkg node_a

# 로봇 B 그룹 — A와 통신 불가
export ROS_DOMAIN_ID=2
ros2 run my_pkg node_b
  • 기본값: 0
  • 안전 범위: 0 ~ 101
  • Domain ID가 다르면 서로 Discovery 자체가 되지 않는다

Domain ID vs Namespace: Domain ID는 네트워크 수준에서 완전 격리한다. Namespace(/robot1/cmd_vel)는 같은 네트워크 안에서 토픽 이름만 분리한다.

QoS — 통신 품질 제어

DDS의 핵심 가치는 QoS(Quality of Service)다. Publisher와 Subscriber가 각각 QoS를 선언하고, 호환되는 경우에만 연결된다.

주요 QoS 정책

정책옵션설명
ReliabilityRELIABLE / BEST_EFFORT메시지 전달 보장 여부
DurabilityTRANSIENT_LOCAL / VOLATILE늦게 참여한 구독자에게 기존 데이터 전달 여부
HistoryKEEP_LAST(N) / KEEP_ALL보관할 메시지 수
DeadlineDuration메시지 간 최대 허용 간격
LivelinessAUTOMATIC / MANUAL_BY_TOPIC노드 생존 확인 방식
LifespanDuration메시지 유효 기간

호환 규칙

QoS는 “Offered vs Requested” 모델이다. Publisher가 제공(Offer)하고, Subscriber가 요구(Request)한다. Subscriber의 요구가 Publisher의 제공보다 엄격하면 연결되지 않는다.

Publisher (Offer)Subscriber (Request)연결
ReliableReliableO
ReliableBest EffortO
Best EffortBest EffortO
Best EffortReliableX
Transient LocalTransient LocalO
Transient LocalVolatileO
VolatileVolatileO
VolatileTransient LocalX

규칙: Publisher가 더 높은 품질을 제공하면 낮은 요구에도 연결된다. 반대는 불가.

QoS 프리셋

// Sensor Data — 최신 값만 중요, 손실 허용
auto qos = rclcpp::SensorDataQoS();
// History: KEEP_LAST(5), Reliability: BEST_EFFORT, Durability: VOLATILE

// Default — 일반 토픽
auto qos = rclcpp::QoS(10);
// History: KEEP_LAST(10), Reliability: RELIABLE, Durability: VOLATILE

// 맵 데이터 — 늦게 참여해도 마지막 맵을 받아야 함
auto qos = rclcpp::QoS(rclcpp::KeepLast(1))
    .reliable()
    .transient_local();

실전 QoS 선택

상황ReliabilityDurabilityHistory
센서 데이터 (IMU, LiDAR)Best EffortVolatileKeep Last(5~10)
제어 명령 (cmd_vel)ReliableVolatileKeep Last(1)
맵 (map, costmap)ReliableTransient LocalKeep Last(1)
TFReliableVolatileKeep Last(100)
원격 조종 (teleop)Best EffortVolatileKeep Last(1)

QoS 불일치 디버깅

ros2 topic echo로 데이터가 안 보이면 QoS 불일치를 의심한다.

# 토픽의 QoS 확인
ros2 topic info /map --verbose
# Publisher와 Subscriber의 QoS 정책이 각각 표시된다

# QoS를 맞춰서 echo
ros2 topic echo /map --qos-reliability reliable --qos-durability transient_local

QoS가 불일치하면 에러 메시지 없이 데이터가 안 온다. ros2 topic info --verbose로 양쪽 QoS를 반드시 확인한다.

Zenoh — DDS 대안

ROS2 Kilted(2025)부터 Zenoh가 공식 대안 미들웨어로 추가되었다.

sudo apt install ros-jazzy-rmw-zenoh-cpp
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
항목DDSZenoh
Discovery멀티캐스트 기반Router 기반
네트워크LAN 최적화WAN/클라우드 친화적
오버헤드상대적으로 무거움경량 와이어 프로토콜
WiFi 환경멀티캐스트 불안정안정적

WiFi나 클라우드 연동이 필요한 환경에서 DDS 대신 고려할 수 있다.

메모

  • QoS 불일치는 에러가 아니라 “무응답”으로 나타난다. 토픽이 보이는데 데이터가 안 오면 QoS부터 확인한다
  • ROS_DOMAIN_ID는 같은 물리 네트워크에서 ROS2 시스템을 격리하는 가장 간단한 방법이다. 별도 설정 없이 환경변수 하나로 동작한다
  • Discovery Server는 Fast DDS 전용이다. Cyclone DDS에서는 사용할 수 없다
  • DDS 벤더를 바꿔도 애플리케이션 코드는 수정할 필요 없다. 단, 벤더별 성능 특성과 설정 방식은 다르다
  • 센서 데이터에 RELIABLE을 쓰면 네트워크 지연 시 데이터가 쌓여서 지연이 누적된다. 최신 값만 필요하면 BEST_EFFORT를 쓴다