제7부 미들웨어·데이터 계층
7.2 Zenoh 연동 — rmw_zenoh와 zenoh-pico
7.2.1 DDS만이 답은 아니다
ROS 2는 기본적으로 DDS(Data Distribution Service, 기본 구현체는 Fast DDS — rmw_fastrtps_cpp)를 통신 계층으로 쓴다. DDS는 성숙하고 검증됐지만 디스커버리 트래픽이 노드 수에 비례해 커지고, 임베디드·저대역폭·간헐 연결 네트워크에는 부담이 크다는 지적이 꾸준히 있어왔다. Eclipse Zenoh는 이 문제를 겨냥해 나온 pub/sub·query·compute 프로토콜로, ROS 2 진영은 rmw_zenoh(github.com/ros2/rmw_zenoh)라는 RMW(ROS Middleware) 구현체로 DDS를 완전히 대체할 수 있게 했다.
UNO Q 맥락에서 Zenoh가 흥미로운 이유는 두 가지다.
rmw_zenoh— MPU(Debian) 위 ROS 2 노드 간 통신을 DDS 대신 Zenoh로 운용할 수 있다. Wi-Fi 기반 원격 노드나 여러 UNO Q를 함께 묶는 구성에서 디스커버리 오버헤드를 줄이는 데 유리하다.zenoh-pico— Zenoh의 초경량 임베디드 구현체로, 8비트 AVR급에서도 동작할 만큼 경량이다. 이론적으로는 STM32U585(MCU) 쪽에도 탑재해 MPU와 별개로 pub/sub 노드를 만들 수 있다는 아이디어로 이어진다(7.2.4에서 다루되, 실험적·비공식 범주임을 계속 명시한다).
이 장은 rmw_zenoh(검증된 설치 경로가 있음)와 zenoh-pico(가능성은 있으나 UNO Q MCU 전용 검증 사례가 없음)를 구분해서 다룬다.
7.2.2 rmw_zenoh 설치와 기본 사용
7.2.2.1 설치
Jazzy용 바이너리가 공식 apt 저장소에 등록되어 있다(ROS 2 자체와 마찬가지로 Ubuntu Noble 기준 — UNO Q에서 쓰려면 7.1에서 구성한 Docker 컨테이너 안이나 소스 빌드 워크스페이스 위에서 설치한다).
sudo apt update
sudo apt install ros-jazzy-rmw-zenoh-cpp
소스에서 빌드하려면:
mkdir -p ~/ws_rmw_zenoh/src && cd ~/ws_rmw_zenoh/src
git clone https://github.com/ros2/rmw_zenoh.git -b jazzy
cd ~/ws_rmw_zenoh
rosdep install --from-paths src --ignore-src --rosdistro jazzy -y
colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release
7.2.2.2 RMW를 Zenoh로 전환
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
source /opt/ros/jazzy/setup.bash # 또는 소스 빌드 워크스페이스의 setup.bash
7.2.2.3 Zenoh 라우터가 필요하다
DDS는 멀티캐스트로 노드끼리 자동으로 서로를 찾지만, rmw_zenoh는 기본 설정에서 멀티캐스트 스카우팅이 꺼져 있다. 노드들이 서로를 발견하려면 디스커버리 정보를 중계할 Zenoh 라우터(zenohd)가 최소 하나 실행 중이어야 한다.
ros2 run rmw_zenoh_cpp rmw_zenohd
라우터를 계속 실행해 두기 번거롭다면 멀티캐스트 스카우팅을 켜서 라우터 없이(peer-to-peer) 동작하게 할 수도 있다.
export ZENOH_CONFIG_OVERRIDE='scouting/multicast/enabled=true'
⚠️ ROS 2가 원래 쓰는
ROS_DOMAIN_ID는 DDS 도메인 개념이다.rmw_zenoh는 이를 그대로 쓰지 않고 Zenoh 자체의 설정(라우터 연결 대상, 네임스페이스 등)으로 분리·통합 범위를 제어한다 — DDS 시절 방식대로ROS_DOMAIN_ID만 바꿔서 네트워크를 분리하려 하면 기대한 격리가 안 될 수 있으니 실제 동작을 확인하고 쓴다(검증 필요).
7.2.2.4 동작 확인
# 터미널 1 — 라우터
ros2 run rmw_zenoh_cpp rmw_zenohd
# 터미널 2
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
ros2 run demo_nodes_cpp talker
# 터미널 3
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
ros2 run demo_nodes_cpp listener
listener가 talker의 메시지를 받으면 성공이다.
7.2.2.5 여러 대의 기기를 묶기
UNO Q 여러 대, 또는 UNO Q와 PC를 같은 Zenoh 네트워크로 묶을 때는 라우터끼리 서로 연결하거나, 한쪽을 클라이언트 모드로 다른 쪽 라우터에 접속시킨다.
# 원격 라우터(예: 192.168.1.1)에 클라이언트로 접속
export ZENOH_CONFIG_OVERRIDE='mode="client";connect/endpoints=["tcp/192.168.1.1:7447"]'
7.2.3 zenoh-pico — 초경량 임베디드 Zenoh
eclipse-zenoh/zenoh-pico는 C로 작성된 Zenoh 클라이언트로, 마이크로컨트롤러를 겨냥한다. 확인된 수치:
- 최소 풋프린트: 8비트 Atmel AVR(Arduino Uno 등, 플래시 32KB급)에서 코어를 약 300바이트까지 줄인 구성이 가능하다고 공개돼 있다. 실용적인 구성(펌웨어 통신 기능 포함)은 약 15KB~50KB 플래시 수준.
- 전송 계층: UDP·TCP(유니캐스트/멀티캐스트) 외에 시리얼(UART) 링크를 지원한다 — Zephyr·Arduino·ESP-IDF·MbedOS 환경에서 시리얼 전송이 문서화돼 있다.
- Zephyr 지원: Zephyr 모듈로 통합 가능하며,
reel_board·nucleo-f767zi등에서 테스트가 보고돼 있다. STM32U585 또는 UNO Q 보드명으로 명시적으로 테스트된 사례는 확인하지 못했다 — Cortex-M33 계열 STM32라는 점에서 이식 가능성은 높아 보이지만 검증 필요로 표기한다.
이 수치는 8비트 AVR Uno를 기준으로 한 "얼마나 작게 줄일 수 있는가"의 하한선이다. UNO Q의 MCU인 STM32U585(Cortex-M33 @ 160MHz, 2MB 플래시, 786KB SRAM — 2.1)는 이 하한선에 비하면 자원이 압도적으로 충분하다. 즉 리소스 부족이 제약 요인은 아니다.
7.2.3.1 실제 제약 요인 — MCU에 이미 있는 통신 채널과의 경합
문제는 리소스가 아니라 STM32U585가 이미 App Lab의 Bridge(공식 명칭, arduino-router + Arduino_RouterBridge, 3.4)로 MPU와 시리얼 링크를 쓰고 있다는 점이다. 3.4가 확인한 바로는 이 링크는 구체적으로 LPUART1(MCU 측 Serial1) ↔ MPU 측 /dev/ttyHS1이며, User Manual이 이 인터페이스를 사용자 코드가 직접 열지 말라고 명시적으로 예약해 둔 자원이다. zenoh-pico를 MCU에 탑재해 MPU와 직접 pub/sub 하려면:
- 경로 A — Bridge와 별도 채널을 쓴다.
Serial1(LPUART1)이 아닌 다른 여분 UART가 있다면 zenoh-pico 전용 시리얼 링크로 분리해 Bridge와 충돌하지 않게 한다. Zephyr 기반 Arduino Core(3.2)에서 여분 UART를 어떻게 확보하는지는 핀아웃(2.2)을 먼저 확인해야 한다. - 경로 B — Bridge 위에 구축한다. 기존 Bridge 채널(MessagePack RPC)을 통해 zenoh-pico 프레임을 터널링하는 방법인데, Bridge의 프로토콜을 침범하는 구성이라 상당한 저수준 작업이 필요하고 공개된 참고 구현은 찾지 못했다.
- 경로 C — MCU가 아니라 별도의 Wi-Fi/이더넷 MCU 보드에서 zenoh-pico를 쓴다. 이쪽이 커뮤니티에서 실제로 훨씬 흔한 zenoh-pico 사용 패턴이다 — ESP32 등 자체 네트워크 인터페이스가 있는 별도 MCU가 zenoh 네트워크에 직접 참여해 UNO Q(또는 그 위 ROS 2 노드)와 pub/sub 한다. STM32U585 자체에는 Wi-Fi/이더넷이 없고(UNO Q의 무선은 MPU 쪽에만 연결되어 있다 — 2.1·4.4), 있는 것은 MPU로 가는 시리얼뿐이므로 이 경로에서는 STM32U585가 zenoh 네트워크의 직접 피어가 아니라 "MPU 뒤에 숨은 장치"로 남는다.
⚠️ 정리하면: STM32U585에 zenoh-pico를 직접 탑재해 자체 네트워크 노드로 만드는 아이디어는 하드웨어 스펙만 보면 무리가 없지만, UNO Q라는 보드 특유의 제약(시리얼 하나로 이미 Bridge가 점유) 때문에 실전 구성은 경로 A/B의 저수준 작업이 필요하다. 반대로 경로 C(별도 Wi-Fi MCU + zenoh-pico)는 자원·통신 모두 무난하지만 "UNO Q의 STM32U585 자체"를 zenoh 피어로 만드는 것은 아니다. 이 장에서 제시하는 것은 아이디어와 경로 구분까지이며, 어느 쪽도 UNO Q 전용으로 공개 검증된 사례는 확인하지 못했다. 실험적 영역으로 접근할 것.
7.2.4 ROS2 + Zenoh 통합 아키텍처
앞의 내용을 하나의 그림으로 정리하면, 현실적으로 안정적인 구성은 "MPU 쪽 ROS 2가 rmw_zenoh로 통신하고, 별도의 Wi-Fi 지원 MCU들이 zenoh-pico 피어로 같은 Zenoh 네트워크에 참여하는" 형태다. UNO Q 자신의 STM32U585는 여전히 Bridge를 통해서만 접근된다.
- 실선: 검증된 경로(
rmw_zenoh+ 라우터, zenoh-pico + Wi-Fi MCU는 zenoh 진영에서 일반적으로 쓰이는 패턴). - 점선: UNO Q 특유의 기존 경로(공식 Bridge,
arduino-router) — Zenoh와는 별개로 계속 존재한다.
7.2.5 언제 Zenoh를, 언제 기본 DDS를 쓸까
| 상황 | 권장 |
|---|---|
| UNO Q 한 대 안에서 ROS 2 노드끼리만 통신 | 기본 DDS(Fast DDS)로 충분 — 바꿀 이유가 적다 |
| UNO Q 여러 대 또는 UNO Q + PC를 Wi-Fi로 묶는 분산 구성 | Zenoh 검토 가치 있음 — 라우터 기반 디스커버리가 DDS 멀티캐스트보다 무선 환경에서 안정적이라는 보고가 많다 |
| 저대역폭·간헐 연결(예: 필드 로봇 원격 링크) | Zenoh 쪽이 설계 목적에 더 부합 |
| 이미 DDS 기반 도구체인(rosbag, 기존 DDS QoS 튜닝 등)에 깊이 의존 | 전환 비용을 고려해 신중히 — rmw_zenoh는 활발히 개발 중이지만 DDS만큼 오래 검증되진 않았다 |
견해: UNO Q를 단독으로 쓸 때는 기본 DDS를 유지하고, 여러 보드·PC를 묶는 순간부터 rmw_zenoh를 실험해 보는 편을 권한다. RMW_IMPLEMENTATION 환경변수 하나로 전환·롤백이 가능하므로 위험 부담이 크지 않다.
7.2.6 트러블슈팅
listener가 아무것도 못 받는다 →rmw_zenohd(라우터)가 실행 중인지, 양쪽 노드가 같은RMW_IMPLEMENTATION=rmw_zenoh_cpp를 export했는지 확인.- 다른 기기의 토픽이 안 보인다 → 멀티캐스트 스카우팅이 꺼져 있는 기본 상태에서는 라우터를 통하지 않으면 서로를 못 찾는다.
ZENOH_CONFIG_OVERRIDE로 라우터 주소를 명시하거나 멀티캐스트를 켠다. - DDS 시절
ROS_DOMAIN_ID로 네트워크를 분리하던 방식이 통하지 않는다 → Zenoh는 도메인 개념이 다르다. Zenoh 쪽 설정(네임스페이스·라우터 연결)으로 다시 설계한다.
7.2.7 다음 장으로
미들웨어를 구성했다면 다음은 데이터를 어디에 쌓을지다 — 7.3(PostgreSQL)과 7.4(SQLite)로 이어간다. MCU 통신 지연이 궁금하다면 8.3를 참조한다.
7.2.8 참고자료
- ros2/rmw_zenoh · jazzy 브랜치
- Discourse — rmw_zenoh binaries for Rolling, Jazzy and Humble
- eclipse-zenoh/zenoh-pico
- Zenoh 공식 블로그 — Zenoh-Pico: Above and Beyond
- Zenoh 공식 블로그 — Zenoh goes embedded with zenoh-pico
- eclipse-zenoh/zenoh-plugin-ros2dds —
rmw_zenoh와는 다른 접근(기존 DDS RMW 유지하며 Zenoh를 브리지로만 쓰는 방식)으로, 대규모 기존 DDS 배포에 Zenoh를 추가하고 싶을 때 대안으로 검토할 만하다