3.6 ROS2에서 Zenoh 통신 환경 구축
자율주행 자동차부터 협동 로봇(Cobot)에 이르기까지, 현대 로보틱스 산업의 절대적인 표준 운영체제는 바로 **ROS2(Robot Operating System 2)**이다. ROS2는 기본 통신 미들웨어로 DDS(Data Distribution Service)를 채택하여 실시간성을 확보했지만, 아이러니하게도 이 DDS의 무거운 UDP 멀티캐스트 기반 디스커버리(Discovery) 방식과 와이파이(Wi-Fi) 등 불안정한 무선 네트워크에서의 취약성이 수많은 로봇 엔지니어들을 절망에 빠뜨렸다.
Eclipse Zenoh는 바로 이 ROS2/DDS 생태계가 가진 태생적 한계를 타파하기 위해 등장한 구원 투수이다. Zenoh는 인터넷 규모(Internet-scale)의 라우팅 기술을 ROS2에 주입하여, 로컬 네트워크에 갇혀 있던 로봇들을 지구 반대편의 클라우드 관제 센터와 밀리초(ms) 단위의 지연만으로 매끄럽게 연결해 낸다.
이 장에서는 기존 ROS2 시스템의 코드 수정 없이 외부 네트워크와 통신을 열어주는 브릿지(Bridge) 방식과, 아예 ROS2의 기본 신경망(RMW)을 통째로 걷어내고 Zenoh 코어를 이식하는 네이티브(Native) 방식 두 가지 환경 구축 파이프라인을 가장 실전적인 관점에서 해부하여 서술한다. 거추장스러운 DDS 데몬들을 걷어내고, 깃털처럼 가볍고 빛처럼 빠른 Zenoh의 날개를 당신의 ROS2 워크스페이스에 당장 달아보자.
1. ROS2 배포판(Humble, Iron, Jazzy 등) 작업 공간(Workspace) 준비
Zenoh를 ROS2 통신의 척추로 이식하기 위해서는 먼저 기반이 되는 대상 ROS2 플랫폼의 버전을 명확히 정의하고, 표준적인 Colcon 방식의 빌드 작업 공간(Workspace)을 무균실처럼 철저하게 준비해야 한다.
1.1 ROS2 대상 배포판(Distribution) 호환성 확인
Zenoh-ROS2 생태계 통합 도구들은 기본적으로 최신 안정화(LTS) 버전과 최신 비장기 지원 릴리스를 모두 포괄하여 지원한다.
- Humble Hawksbill (Ubuntu 22.04 LTS): 현재 산업 현장의 주력 배포판.
- Iron Irwini (Ubuntu 22.04): 중간 브릿지 개발을 위한 배포판.
- Jazzy Jalisco (Ubuntu 24.04 LTS): 향후 5년을 책임질 차세대 배포판.
빌드 오류를 미연에 방지하기 위해, 사용자 터미널 환경이 자신이 목표로 하는 ROS2 배포판의 환경 변수로 정확히 오버레이(Overlay) 되어 있는지 매번 확인하는 습관을 들여야 한다.
## 예시: ROS2 Humble 환경 글로벌 로우딩
source /opt/ros/humble/setup.bash
## 환경 변수가 제대로 물렸는지 디버깅 확인
printenv ROS_DISTRO
## 출력 결과: humble
1.2 프로젝트 전용 Colcon 워크스페이스 루트 생성
ROS2의 rmw_zenoh 패키지나 zenoh-bridge-dds를 소스 코드 레벨에서 직접 엮어서(Link) 커스텀 빌드해야 할 상황에 대비해, 글로벌 환경을 오염시키지 않는 격리된 디렉터리를 생성한다.
## 홈 디렉터리 하위에 zenoh_ws라는 이름의 작업 공간 창설
mkdir -p ~/zenoh_ws/src
cd ~/zenoh_ws
## 초기 워크스페이스 빌드를 통해 Colcon 메타데이터 구조 강제 생성
colcon build --symlink-install
이 기초 공사가 성공했다면 zenoh_ws 내부에 build, install, log 디렉터리가 생성된다. 향후 서술될 브릿지 컴파일이나 네이티브 RMW 소스 빌드 작업은 철저하게 이 경로에 위치한 src 폴더 안에서 깃 클론(Git Clone)을 수행하여 격리된 생태계를 유지하도록 한다.
2. 브릿지 방식 통신: zenoh-bridge-dds 패키지 설치 및 빌드
이미 수십 대의 노드로 구성되어 쌩쌩하게 굴러가고 있는 레거시(Legacy) ROS2 시스템 전체를 하루아침에 뜯어고치는 것은 자살 행위다.
기존의 노드(Node) 소스코드나 RMW(ROS Middleware) 설정, DDS 환경을 단 1비트도 건드리지 않고, 외부 네트워크(VPN, 5G망 등)와 ROS2 시스템을 매끄럽게 관통시키는 방법이 바로 zenoh-bridge-dds 데몬을 활용한 브릿징 전략이다. 이 브릿지는 내부망에서는 표준 DDS 프로토콜로 로봇들과 대화하고, 외부 플랜트망으로는 데이터를 가공하여 Zenoh 프로토콜 위로 쏜다.
2.1 운영체제 패키지 매니저를 통한 쾌속 설치 (가장 권장됨)
Ubuntu 기반의 ROS2 개발 환경(Humble, Jazzy 등)을 사용 중이라면 apt 저장소 추가를 통해 바이너리를 직접 꽂아 넣는 것이 빌드 오류를 원천 차단하는 지름길이다.
## Eclipse Zenoh 저장소 인증 키 획득
echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list.d/zenoh.list
sudo apt update
## 브릿지 바이너리 호쾌하게 설치 완료
sudo apt install zenoh-bridge-dds
2.2 Rust Cargo를 활용한 소스코드 빌드 및 최적화
최신 기능이 필요하거나 기본 패키지가 제공되지 않는 ARM/임베디드 타겟이라면 앞선 3.3절에서 구성한 Rust 툴체인을 꺼내 들어 소스 빌드를 감행해야 한다. DDS 코어 라이브러리와 엮여야 하므로 C++ 빌드 필수 도구(cmake, clang 등) 준비가 선행되어야 한다.
## 필수 시스템 헤더파일(Clang 의존성) 준비
sudo apt install -y build-essential cmake libclang-dev
## crates.io 레지스트리에서 소스코드를 인출 후 즉석에서 릴리즈 바이너리로 타설
cargo install zenoh-bridge-dds
바이너리가 ~/.cargo/bin/ 디렉터리에 놓이게 되므로 해당 경로가 PATH에 삽입되어 있는지 재차 확인하자.
2.3 브릿지 활성화 및 동작 검증 테스트
설치가 완료되었다면 기존의 ROS2 DDS 트래픽을 가로채서 Zenoh 네트워크로 쏘아 올릴 데몬을 백그라운드로 띄워 둔다.
## 로컬 ROS2 네트워크 전체를 스푸핑하여 기본 Zenoh 라우터로 넘김
zenoh-bridge-dds -d 0
브릿지가 구동되면 터미널에 [zenoh_bridge_dds] - Zeno-DDS Bridge successfully started 라는 메시지가 위풍당당하게 찍힌다. 이제부터 브릿지가 띄워진 이 PC는 거대한 ROS2 로컬 무리(Swarm)와 전 세계 인터넷을 잇는 단 하나의 스타게이트(Stargate) 역할을 수행할 것이다.
3. 네이티브 방식 통신: rmw_zenoh 미들웨어 컴파일 및 설치
앞 절에서 다룬 zenoh-bridge-dds가 기존 레거시 시스템을 위한 회유책이었다면, rmw_zenoh 네이티브 방식은 ROS2의 근간을 이루는 미들웨어(RMW) 레이어 자체를 통째로 이식 수술하여 DDS를 완전히 축출하는 혁명적 방법이다.
중간에 DDS 프로토콜을 거치거나 변환할 필요가 없으므로 네트워크 효율이 비약적으로 상승하며, 드론이나 마이크로 로봇 등 컴퓨팅 파워가 극히 제한된 에지(Edge) 환경에서 진가를 발휘한다.
3.1 사전 의존성(Dependencies) 설치
이 방식은 수동으로 소스코드를 내려받아 ROS2의 툴체인(Colcon)과 엮어서 완전히 새로운 rmw 라이브러리를 빌드해야 하므로, 철저한 빌드 환경 세팅이 필수적이다.
sudo apt update
sudo apt install -y python3-vcstool python3-colcon-common-extensions git wget
python3-vcstool:.repos파일 등 여러 깃(Git) 저장소를 일괄 관리하는 필수 도구python3-colcon-common-extensions: ROS2 메타 빌드 시스템 코어
3.2 rmw_zenoh 소스코드 인출(Fetch)
앞선 3.6.1절에서 정갈하게 확보해 둔 ~/zenoh_ws/src 디렉터리로 들어간다. 여기서 rmw_zenoh의 심장부 소스코드와 그 C++ 래퍼(Wrapper) 짝꿍인 zenoh-cpp 코드를 함께 다운로드해야 한다. 편의성을 위해 Eclipse 팀에서 제공하는 .repos 리스트 파일을 활용한다.
cd ~/zenoh_ws/src
## ROS2 배포판 버전에 맞는(humbel, jazzy 등) 최신 릴리스 리스트 파일 다운로드
wget https://raw.githubusercontent.com/ros2/rmw_zenoh/rolling/rmw_zenoh.repos
## vcs 도구를 사용해 리스트에 명시된 모든 저장소를 병렬 병합
vcs import < rmw_zenoh.repos
3.3 의존성 자동 리졸브(Resolve) 및 커스텀 Colcon 빌드
소스 트리가 구성되었다면, rosdep 도구를 돌려 Ubuntu 시스템 레벨에서 누락된 패키지가 없는지 스캔하고 모두 설치한다.
cd ~/zenoh_ws
## 전체 src 디렉터리를 훑으며 모자란 시스템 라이브러리 자동 확충
rosdep install --from-paths src --ignore-src --rosdistro $ROS_DISTRO -y
드디어 결전의 빌드 타임이다. C++ 링킹 과정에서 많은 램(RAM)을 소비하므로 만약 라즈베리 파이 같은 장비라면 스왑(Swap) 메모리를 켜 두길 권장한다.
## 전체 작업 공간에 대해 의존성 분석을 거친 안전한 빌드 호출
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release
Summary: X packages finished 메시지와 정상 종료가 떨어지면 성공이다. 이제 남은 것은 이 새롭게 이식된 심장(rmw)을 ROS2 운영체제가 실제로 꺼내 쓰도록 명시적으로 명령을 내리는 일꾼 노릇뿐이다. 다음 절에서 환경 변수를 조작하여 이식된 장기를 구동시켜 보자.
4. RMW_IMPLEMENTATION 환경 변수 설정 및 기본 노드 동작 검증
앞 절에서 온갖 고난을 이겨내고 rmw_zenoh 라이브러리를 빌드했다면, 이제 ROS2 애플리케이션들에게 **“앞으로 모든 통신은 기본값인 DDS(rmw_fastrtps_cpp 등)를 버리고, 우리가 갓 구워낸 Zenoh(rmw_zenoh_cpp)를 타라”**고 명시적으로 강제해야 한다.
이 전환 스위치 역할을 하는 것이 바로 ROS2 코어의 심장 격인 RMW_IMPLEMENTATION 환경 변수이다.
4.1 커스텀 워크스페이스 로드 및 환경 변수 장착
터미널을 열고 가장 먼저 로컬 시스템의 글로벌 ROS 환경과 우리가 새롭게 빌드한 zenoh_ws의 로컬 오버레이를 순차적으로 로드(source)해야 한다. 이것은 의사와 간호사가 이식 수술 전에 오염되지 않은 무결점 도구를 순서대로 정렬하는 과정과 같다.
## 1단계: ROS2 기본 환경 (예: Humble) 덮어씌우기
source /opt/ros/humble/setup.bash
## 2단계: 우리가 컴파일한 rmw_zenoh가 담긴 로컬 작업 공간 오버레이
source ~/zenoh_ws/install/setup.bash
이제 RMW 구현체를 Zenoh로 전격 교체하는 핵심 환경 파라미터를 선언한다. 이 변수가 살아있는 터미널 창에서만 Zenoh 기반으로 노드가 뜬다는 사실을 유념하라. (컴퓨터 부팅 시마다 영구 적용을 원하면 ~/.bashrc 하단에 기입해야 한다.)
## 통신 미들웨어를 독점적으로 Zenoh 커스텀 라이브러리로 지정
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
4.2 노드 기반 토픽(Topic) 루프백 핑퐁(Ping-pong) 테스트
장기가 제대로 뛰는지 청진기를 댈 시간이다. ROS2에 내장된 가장 원초적인 테스트 애플리케이션인 demo_nodes_cpp의 퍼블리셔(Talker)와 서브스크라이버(Listener)를 구동하여 패킷이 오가는지 확인한다.
이 테스트는 반드시 동일한 환경 변수가 적용된 2개의 독립된 터미널에서 진행되어야 한다.
터미널 #1 (송신단 - Talker):
## 첫 번째 터미널 환경 설정 복습
source /opt/ros/humble/setup.bash
source ~/zenoh_ws/install/setup.bash
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
## 1초 주기로 "Hello World: N" 토픽을 퍼블리시
ros2 run demo_nodes_cpp talker
터미널 #2 (수신단 - Listener):
## 두 번째 터미널 역시 완벽히 동일한 환경 세팅 후 구동
source /opt/ros/humble/setup.bash
source ~/zenoh_ws/install/setup.bash
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
## Talker 토픽 구독 대기
ros2 run demo_nodes_cpp listener
두 번째 터미널 창에 [INFO] [listener]: I heard: [Hello World: 1] 같은 로그가 미친 듯이 올라오고 있다면 완벽하게 성공이다. 이 패킷들은 지루한 DDS 프로토콜의 오버헤드를 완전히 집어던진 채, 초경량 Zenoh 런타임 위에서 가장 빠르고 간결하게 전달된 결정체이다. 축하한다. 이제 당신의 ROS 시스템은 클라우드의 한계를 뛰어넘을 모든 준비를 마쳤다.