iT邦幫忙

2025 iThome 鐵人賽

DAY 24
0
Rust

30 天玩轉 Zenoh:Rust 助力物聯網、機器人與自駕的高速通訊系列 第 24

Day 24: Zenoh 在機器人系統的應用全景 Part 1 - ROS1 與 zenoh-plugin-ros1:傳統機器人網路的新橋梁

  • 分享至 

  • xImage
  •  

Zenoh 在機器人系統的應用全景 Part 1 - ROS1 與 zenoh-plugin-ros1:傳統機器人網路的新橋梁

本系列探討 Zenoh 在機器人領域的變革潛力,本文作爲開頭,我們將檢視 zenoh-plugin-ros1 如何通過先進網路架構與尖端的 Rust 實作,橋接傳統機器人系統與現代資料導向通訊範式。

ROS 1 的起源與演進

開放機器人革命

2007 年,Willow Garage 推出 ROS 1,徹底改變機器人軟體的構思、開發與共享方式。它不僅是一套中介軟體,而是一場開放協作的宣言,串連全球研究者、工程師和愛好者。

ROS 1 的巧妙之處在於其開源社群的開發方式。廣泛套件生態系允許研究生寫的導航演算法無縫被工業機器人使用。發布/訂閱的通訊模式直覺易用,中央 Master 協調服務讓系統“即插即用”。

可惜的是,ROS 1 如今已經不再維護,官方最新版本 ROS 1 Noetic 已於 2025 年 5 月 31 日達生命週期終點。

機器人生態爆炸

ROS 1 影響廣泛且。從全球大學普遍使用的標誌性 PR2 研究平台,到教導新一代的 TurtleBots,ROS 1 成為機器人社群的通用語言。其影響跨足:

  • 工業自動化:靈活製造使用 ROS 1
  • 服務機器人:清潔、運輸、款待腳色大量應用
  • 研究平台標準:全球高校加速協同合作
  • 開源文化:促進分享,推動快速創新

ROS 1 社群是機器人史上首度出現的全球性合作共生。

網路架構限制

當年革命設計,今則成瓶頸。ROS 1 網路架構基於關鍵假設,隨機器人發展成為限制:

  • 中心化發現:ROS Master 以 XML-RPC 運行於單節點,全網註冊,一旦故障,網路全崩潰。
  • 點對點連線:發現後節點直連 TCP 傳輸,但導致
    • NAT 穿越困難
    • 網路拓撲死板
    • 連線數量指數成長瓶頸
  • 無網路層安全:數據明文,無認證加密,不適合產線
  • 平台綁定:依賴 POSIX 與特定網路堆疊,限制彈性部署

zenoh-plugin-ros1

分散式發現協定

zenoh-plugin-ros1 實作分散式發現系統,消除 ROS 1 的單點故障。發現協定運行於層級化 key-value namespace:

// discovery.rs
kedefine!(
    pub discovery_format: "ros1_discovery_info/${discovery_namespace:*}/${resource_class:*}/${data_type:*}/${md5:*}/${bridge_namespace:*}/${topic:**}",
);

產生類似

ros1_discovery_info/*/pub/std_msgs%2FString/hash123/*/robot1/sensors/camera

的探測鍵。

多層級發現架構

  1. 命名空間隔離:多機隊共存同網路不干擾
  2. 資源分類:分 Publisher、Subscriber、Service、Client 獨立追蹤
  3. 型別安全:數據類型與 MD5 檢驗確保端點相容
  4. 橋接命名空間映射:支持複雜路由與網路分段策略

類 ALOHA 網路協調

採用啟發自 ALOHA 協定 的廣播協調,避免大規模部署時beancon風暴:

// aloha_declaration.rs
while monitor_running.load(std::sync::atomic::Ordering::Relaxed) {
    match remote_beacons.fetch_and(0, std::sync::atomic::Ordering::SeqCst) {
        0 => {
            if !sending_beacons {
                // Exponential backoff with randomization
                let period_ns = beacon_period.as_nanos();
                let aloha_wait: u128 = rand::random::<u128>() % period_ns;
                tokio::time::sleep(Duration::from_nanos(aloha_wait.try_into().unwrap())).await;

ALOHA 優勢

  • 碰撞避免:隨機beancon時序防洪
  • 自組網:無中心控制自動調協
  • 頻寬高效:每段網路僅一節點beancon
  • 容錯:節點故障自動接手

品質服務網路策略 (QoS Policy)

ZenohClient 實作高度 QoS 控制,ROS 1 難以達成:

// zenoh_client.rs
self.session
    .declare_publisher(key_expr)
    .reliability(Reliability::Reliable)
    .allowed_destination(Locality::Remote)
    .congestion_control(CongestionControl::Block)
    .await

QoS 高階功能

  • 可靠性保障:頻繁傳感資料用 best-effort,安全指令用可靠傳輸
  • 擁塞控制:動態背壓防止淹沒
  • 本地政策:精細控管本地與遠端路由
  • 優先級類別:關鍵訊息優先傳遞

Rust 實作亮點

先進 Async 執行緒管理

// lib.rs
static ref TOKIO_RUNTIME: tokio::runtime::Runtime = tokio::runtime::Builder::new_multi_thread()
    .worker_threads(WORK_THREAD_NUM.load(Ordering::SeqCst))
    .max_blocking_threads(MAX_BLOCK_THREAD_NUM.load(Ordering::SeqCst))
    .enable_all()
    .build()
    .expect("Unable to create runtime");

執行架構特色

  • 可調執行緒池:不同硬體優化性能
  • 阻塞執行緒管理:防止阻塞搶占異步任務
  • 情境感知執行:無縫介入現有執行緒或獨立建立

錯誤處理與韌性

// abstract_bridge.rs
match zenoh_client.make_query_sync(key, query.0).await {
    Ok(reply) => match reply.recv_async().await {
        Ok(r) => match r.result() {
            Ok(sample) => {
                let data = sample.payload().to_bytes().into_owned();
                Ok(rosrust::RawMessage(data))
            }
            Err(e) => {
                error!("ROS1 -> Zenoh Client: received Zenoh Query with error: {:?}", e);
                Err(format!("{:?}", e))
            }
        },
        Err(e) => Err(e.to_string())
    },
    Err(e) => Err(e.to_string())
}

錯誤處理優點

  • 所有失敗型態明確
  • 使用 ? 操作符鏈式傳播錯誤
  • 無隱藏例外,函式簽名一目了然

無鎖程式與原子操作

// aloha_subscription.rs
struct AlohaResource {
    activity: AtomicBool,
}

impl AlohaResource {
    pub fn update(&mut self) {
        self.activity.store(true, Relaxed);
    }

    pub fn is_active(&self) -> bool {
        self.activity.load(Relaxed)
    }
}

無鎖好處

  • 實時效能優異,避免互斥資源爭用
  • 防死鎖,結構簡潔
  • 隨著核心數量線性擴展性能

巨集驅動程式碼生成

// discovery.rs:36-38
kedefine!(
    pub discovery_format: "ros1_discovery_info/${discovery_namespace:*}/${resource_class:*}/${data_type:*}/${md5:*}/${bridge_namespace:*}/${topic:**}",
);

巨集於編譯期產生類型安全的 key 處理代碼,杜絕大量執行時字串錯誤。

實務操作教學:搭建 ROS 1 與 Zenoh 橋接

理解橋接架構

zenoh-plugin-ros1 建立無縫橋接,讓 ROS 1 生態系統透過 Zenoh 網路互連。橋接保留 ROS 1 通訊的語意完整性:

Zenoh ROS1 Bridge Architecture

  1. 持續監控本地 ROS Master,使用 ROS XML-RPC API
  2. 嚴格保留資料型別和 MD5 簽章
  3. 雙向映射 ROS1 網路元件與 Zenoh 實體
  4. 遠端 ROS1 主題如本地主題般透明呈現

安裝與設置

前置條件

安裝必要依賴:

# 安裝 Rust 開發環境
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup update

# 安裝 ROS 1(Ubuntu/Debian)
sudo apt update
sudo apt install ros-noetic-desktop-full

# 安裝開發工具
sudo apt install llvm-dev libclang-dev build-essential

方式一:從原始碼建置

# Clone the repository
git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git
cd zenoh-plugin-ros1

# Build the bridge
cargo build --release

# The binaries will be available in target/release/
ls target/release/zenoh-bridge-ros1

方式二:套件管理安裝

Debian/Ubuntu:

# Add Eclipse Zenoh repository
echo "deb [trusted=yes] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list
sudo apt update

# Install the bridge
sudo apt install zenoh-bridge-ros1

Docker 部署:

# Pull the latest image
docker pull eclipse/zenoh-bridge-ros1:latest

# Run with host networking
docker run --init --net host eclipse/zenoh-bridge-ros1

基本使用範例

單橋接設置範例

# Terminal 1: Start ROS Master
roscore

# Terminal 2: Start the bridge
zenoh-bridge-ros1

# Terminal 3: Publish to a topic
rostopic pub /test_topic std_msgs/String "data: 'Hello Zenoh!'" -r 1

# Terminal 4: Subscribe to the topic
rostopic echo /test_topic

多主控橋接網路

# Terminal 1: Start first ROS Master
rosmaster -p 10000

# Terminal 2: Start second ROS Master
rosmaster -p 10001

# Terminal 3: Bridge first ROS system
zenoh-bridge-ros1 --ros_master_uri http://localhost:10000

# Terminal 4: Bridge second ROS system
zenoh-bridge-ros1 --ros_master_uri http://localhost:10001

# Terminal 5: Publish from first system
ROS_MASTER_URI=http://localhost:10000 rostopic pub /shared_topic std_msgs/String "data: 'From System 1'" -r 1

# Terminal 6: Subscribe from second system
ROS_MASTER_URI=http://localhost:10001 rostopic echo /shared_topic

幕後發生了什麼事情呢

  1. 每個橋接點都會連線到其對應的 ROS Master
  2. 系統會自動發現主題並將其映射到 Zenoh 的關鍵字表達式
  3. 數據透過 Zenoh 的網狀網路在系統間透明流動

展望未來

Zenoh 與 ROS1 的整合是機器人發展的新里程碑,讓舊系統注入現代分散式通訊技術。Rust 不僅帶來系統程式設計的可靠性,Zenoh 更提供彈性、性能与擴展性兼備的資料層。

下一篇我們將探索下一代 ROS 2,以及 Zenoh 在 ROS 2 的應用,敬請期待!


上一篇
Day 23: 認識 Zenoh Protocol的架構與實作
系列文
30 天玩轉 Zenoh:Rust 助力物聯網、機器人與自駕的高速通訊24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言