跨进程通信使用 Zenoh中间件 进行高效数据传输的测试和分析

news2024/9/20 22:34:08

文章目录

    • 1. 引言
    • 2. Zenoh C++ 使用指南
      • 2.1 安装 Zenoh C++ 库
      • 2.2 编写基本的 Zenoh C++ 程序
        • 订阅示例
        • 发布示例
      • 2.3 编译和运行程序
    • 3. Zenoh 与 ROS2 集成
      • 3.1 安装 Zenoh
      • 3.2 安装 ROS2 的 Zenoh RMW 实现
      • 3.3 设置 RMW 实现为 Zenoh
      • 3.4 验证配置
    • 4. 编写基于 Zenoh 的 ROS2 应用程序
      • 4.1 发布者节点
      • 4.2 订阅者节点
    • 5. ROS2跨进程通信性能测试
      • 5.1 吞吐量测试 (throughput_in_message_per_second)
      • 5.2 延迟测试 (us)
    • 6. 参考文章

1. 引言

Zenoh 是一个高效的数据传输框架,核心由 Rust 编写,同时提供了 C++、Python 等多种语言绑定。支持多种部署环境和跨网络通信,实现了去中心化的自适应网络发现,最小的协议网络开销,能够满足低延迟和高吞吐量的要求,甚至它内部也实现了IPC(zero copy)。
本文将探讨如何在 C++ 环境下使用 Zenoh 进行数据传输,并讨论 Zenoh 与 ROS2 的集成方式。
在这里插入图片描述

2. Zenoh C++ 使用指南

2.1 安装 Zenoh C++ 库

首先,获取并安装 Zenoh C++ 库:

# 获取 zenoh-cpp 库
git clone https://github.com/eclipse-zenoh/zenoh-cpp.git
cd zenoh-cpp

# 安装依赖并构建
mkdir build && cd build
cmake ..
make
sudo make install

2.2 编写基本的 Zenoh C++ 程序

一个基本的 Zenoh C++ 程序包括以下步骤:

  1. 初始化 Zenoh 会话。
  2. 发布或订阅数据。
  3. 处理数据。
订阅示例
#include <iostream>
#include <zenoh/zenoh.hpp>

int main(int argc, char *argv[]) {
    // 初始化 Zenoh session
    auto config = zenoh::Config();
    auto z = zenoh::open(config).res();
    
    // 订阅数据
    auto sub = z->subscribe("/example/key", [](const zenoh::Sample& sample) {
        std::cout << "Received data: " << sample.payload.data() << std::endl;
    });

    // 等待数据
    std::cout << "Waiting for data..." << std::endl;
    std::this_thread::sleep_for(std::chrono::minutes(10)); // 保持运行
    return 0;
}
发布示例
#include <iostream>
#include <zenoh/zenoh.hpp>

int main(int argc, char *argv[]) {
    // 初始化 Zenoh session
    auto config = zenoh::Config();
    auto z = zenoh::open(config).res();

    // 发布数据
    for (int i = 0; i < 10; ++i) {
        std::string message = "Hello Zenoh: " + std::to_string(i);
        z->put("/example/key", message);
        std::cout << "Published: " << message << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}

2.3 编译和运行程序

编译时需要链接 Zenoh 库:

g++ -std=c++17 -o zenoh_example zenoh_example.cpp -lzenoh

然后运行程序:

./zenoh_example

3. Zenoh 与 ROS2 集成

Zenoh 提供了一个轻量级且高效的消息传输机制,能够满足低延迟、高吞吐量的要求。通过 Zenoh 作为 ROS2 的 RMW (ROS Middleware) 实现,开发者可以实现跨网络的高效通信。Zenoh 的架构分为核心通信引擎和不同语言的绑定接口,其中核心由 Rust 编写,C++ 和 Python 绑定则为主流语言提供支持。

在 ROS2 中,使用 Zenoh 的典型步骤包括:

  1. 安装 Zenoh 和 ROS2 的 Zenoh RMW 实现。
  2. 配置 ROS2 使用 Zenoh 作为默认中间件。
  3. 编写基于 Zenoh 的 ROS2 应用程序。

要实现 Zenoh 与 ROS2 的集成,可以按照以下步骤进行详细配置和开发:

3.1 安装 Zenoh

Zenoh 的核心库可以通过以下命令安装:

git clone https://github.com/eclipse-zenoh/zenoh.git
cd zenoh
cargo build --release

Zenoh 的核心是用 Rust 编写的,因此需要安装 Rust 和 Cargo。如果还未安装,可以通过以下命令安装:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

3.2 安装 ROS2 的 Zenoh RMW 实现

ROS2 默认支持多种 RMW(ROS Middleware)实现,Zenoh 也可以作为其中之一使用。你需要安装 rmw_zenohrmw_zenoh_cpp

git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git
cd zenoh-plugin-dds
cargo build --release

然后,可以将编译好的库添加到 ROS2 的路径中。

3.3 设置 RMW 实现为 Zenoh

在运行 ROS2 节点时,可以通过以下命令将 RMW_IMPLEMENTATION 设置为 rmw_zenoh_cpp

export RMW_IMPLEMENTATION=rmw_zenoh_cpp

也可以在 .bashrc 文件中添加此命令,以便每次启动终端时自动配置。

3.4 验证配置

通过以下命令验证 Zenoh 是否已作为 ROS2 的默认中间件:

ros2 doctor --report

输出中应显示 RMW_IMPLEMENTATION: rmw_zenoh_cpp

4. 编写基于 Zenoh 的 ROS2 应用程序

在 ROS2 中,你可以按照常规方式编写节点,Zenoh 的集成是透明的。以下是一个使用 Zenoh 的发布者和订阅者示例:

4.1 发布者节点

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

int main(int argc, char *argv[]) {
    rclcpp::init(argc, argv);
    auto node = rclcpp::Node::make_shared("zenoh_publisher");
    auto publisher = node->create_publisher<std_msgs::msg::String>("zenoh_topic", 10);

    rclcpp::WallRate loop_rate(1);
    while (rclcpp::ok()) {
        auto message = std_msgs::msg::String();
        message.data = "Hello from Zenoh Publisher!";
        RCLCPP_INFO(node->get_logger(), "Publishing: '%s'", message.data.c_str());
        publisher->publish(message);
        rclcpp::spin_some(node);
        loop_rate.sleep();
    }
    rclcpp::shutdown();
    return 0;
}

4.2 订阅者节点

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

void topic_callback(const std_msgs::msg::String::SharedPtr msg) {
    RCLCPP_INFO(rclcpp::get_logger("zenoh_subscriber"), "I heard: '%s'", msg->data.c_str());
}

int main(int argc, char *argv[]) {
    rclcpp::init(argc, argv);
    auto node = rclcpp::Node::make_shared("zenoh_subscriber");
    auto subscription = node->create_subscription<std_msgs::msg::String>(
        "zenoh_topic", 10, topic_callback);
    
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

这些节点编写完成后,使用常规的 ROS2 编译工具如 colcon 进行编译:

colcon build

确保在运行时,环境变量 RMW_IMPLEMENTATION 设置为 rmw_zenoh_cpp,然后可以启动发布者和订阅者:

ros2 run <package_name> zenoh_publisher
ros2 run <package_name> zenoh_subscriber

5. ROS2跨进程通信性能测试

为了评估 Zenoh 的性能,我们按照以上方法进行了ROS2跨进程通信的吞吐量和延迟测试,测试数据如下:

5.1 吞吐量测试 (throughput_in_message_per_second)

count1kb (bytes)2kb(bytes)4kb(bytes)8kb(bytes)16kb(bytes)
1258643.170172798.709119124.43590914.27279555.248
2261220.364166884.978112133.02987834.26479053.264
3252042.470157376.734111920.86296717.97278143.373
4276926.169156251.875110722.08189124.87075229.330
5261305.844164742.864118617.88498019.08176151.792
  • 随着消息大小增加,吞吐量逐渐降低。小消息(如1KB)的传输速率最高,约为25万条/秒,而大消息(如16KB)的吞吐量则降至约7.5万条/秒。
  • 消息大小对吞吐量影响显著,较大消息由于传输开销增加,导致吞吐能力下降。

5.2 延迟测试 (us)

count1kb (us)2kb(us)4kb(us)8kb(us)16kb(us)
16758656497
29669587176
38262656386
46866587180
510460646289
  • 不同消息大小的延迟相对稳定。小消息(如1KB)的延迟在 67-104 微秒之间,而大消息(如16KB)的延迟在 76-97 微秒之间。
  • 延迟随消息大小略有波动,但整体表现较好,能够满足大多数低延迟应用场景的需求。

结论:Zenoh 在跨进程通信中表现出较高的吞吐量和低延迟特性。对于小消息,Zenoh 可以在确保低延迟的同时实现高吞吐量。虽然大消息的吞吐量有所降低,但仍保持了较低的延迟,展示出良好的通信性能。这使得 Zenoh 适合在低延迟和高性能要求的应用中使用,尤其是在分布式系统中。

6. 参考文章

eclipse zenoh 助力雾计算和边缘计算

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2051949.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统编程 --- 多线程

线程&#xff1a;是进程内的一个执行分支&#xff0c;线程的执行粒度&#xff0c;要比进程要细。 一、线程的概念 1、Linux中线程该如何理解 地址空间就是进程的资源窗口。 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1…

浏览器遇到的问题

下载的时候遇到&#xff0c;需要授权&#xff0c;无法下下载 将隐私里面的全部关掉

虚幻5|AI巡逻宠物伴随及定点巡逻—初步篇

一.建立AI基本三件套 1.建立AI基本三件套 二.使用AI的基本设置 1.打开我们想要用的AI宠物的蓝图&#xff0c;选中自我Actor,右侧细节处找到AI&#xff0c;选中对应的AI控制器 三.打开AI控制器 写如下 四&#xff0c;AI行为树 1.新建一个任务&#xff0c;命名含巡逻二字即可…

BigInteger与BigDecimal

BigInteger BigInteger构造方法 public BigInteger(int num, Random rnd) 获取随机大整数&#xff0c;范围&#xff1a;[0 ~ 2的num次方-1] public BigInteger(String val) 获取指定的大整数 public BigInteger(String val, int radix) 获取指定进制的大整数 构造方法小结…

Power Query抓取多页数据导入到Excel

原文链接 举例网站&#xff1a;http://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/ggtj/index.phtml?last5&p1 操作步骤 &#xff08;版本为&#xff1a;Excel2010&#xff09;&#xff1a; Step-01&#xff1a;单击【Power Query】-【从Web】&#xff0c;…

Java之文件操作和IO

目录 File类 属性 构造方法 方法 文件内容的读写 InputStream OutputStream File类 属性 修饰符及类型属性说明static StringpathSeparator依赖于系统的路径分隔符&#xff0c;String类型的表示static charpathSeparator依赖于系统的路径分隔符&#xff0c;char类型的…

ps磨皮滤镜插件Imagenomic Portraiture 4.5 Build 4501中文版

PS磨皮神器更新为Portraiture 中文汉化版&#xff08;支持PS 2024&#xff09; 。Portraiture 4.5 Build 4501中文绿色破解版是一款非常强大的适用于Photoshop&#xff0c;Lightroom&#xff0c;Aperture的人物磨皮&#xff08;人物润色&#xff09;插件。Portraiture插件被经常…

基于eBPF的procstat软件追踪C++ STL容器扩容

在性能敏感的C程序中&#xff0c;标准模板库&#xff08;STL&#xff09;容器的扩容操作往往是导致性能抖动的原因之一。扩容操作可能会引发内存重新分配和数据迁移&#xff0c;从而导致性能不稳定。然而&#xff0c;由于C标准库的扩容函数通常被内联化&#xff0c;传统的方法难…

Geekbench AI 1.0正式发布:AI性能评估

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

STM32标准库学习笔记-4.定时器中断

参考教程&#xff1a;【STM32入门教程-2023版 细致讲解 中文字幕】 定时器简介 TIM&#xff08;Timer&#xff09;定时器。定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断。16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计…

vue3响应式工具 toRefs() 和 toRef()

前言 直接解构响应式对象的属性进行赋值给新的变量&#xff0c;会导致新变量失去响应式。 当修改新变量的值时&#xff0c;不会触发原始响应式对象的更新&#xff0c;从而在模板中也不会有相应的视图更新。 示例&#xff1a; <template><div><p>姓名: {{ …

垂直行业数字化表现抢眼 亚信科技全年利润展望乐观

大数据产业创新服务媒体 ——聚焦数据 改变商业 2024年8月14日&#xff0c;亚信科技控股有限公司&#xff08;股票代码&#xff1a;01675.HK&#xff09;公布了公司截至2024年6月30日的中期业绩。 财报数据显示&#xff0c;2024年上半年&#xff0c;亚信科技的营业收入为人民币…

Java巅峰之路---进阶篇---面向对象(一)

static关键字 介绍 static表示静态&#xff0c;是java中的一个修饰符&#xff0c;可以修饰成员方法&#xff0c;成员变量。 其中&#xff0c;被static修饰的成员变量&#xff0c;叫做静态变量&#xff1b;被static修饰的成员方法&#xff0c;叫做静态方法。 静态变量 调用…

水凝胶和皮肤再生有关系?那它是什么玩意儿?

大家好&#xff0c;今天我们来聊聊皮肤再生与水凝胶的关系。这篇《Hydrogel-Based Skin Regeneration》是发表于《International Journal of Molecular Sciences》上的一篇文章。皮肤作为人体最大的器官&#xff0c;其伤口愈合至关重要&#xff0c;但传统治疗方法有局限性。组织…

数据结构(Java):揭开二叉搜索树删除机制的奥秘

目录 1、二叉搜索树 1.1 概念 2、代码模拟实现 2.1 插入操作 2.2 查找操作 2.3 &#x1f31f;删除操作&#x1f31f;&#xff08;难点&#xff09; 2.3.1 要删除节点的左子树为空 2.3.2 要删除节点的右子树为空 2.3.3 要删除节点的左右子树均不为空 2.3.4 删除操作代码…

认知杂谈17

今天分享 有人说的一段争议性的话 I I 男人撑起一片天&#xff0c;背后是默默的坚守与承担 说起生孩子这事儿啊&#xff0c;对大多数男同胞来讲&#xff0c;那真是又温馨又充满挑战。要当爸爸了&#xff0c;这意味着责任重大&#xff0c;心里期待满满&#xff0c;一方面得…

函数图像绘制小工具

函数图像绘制小工具 文章说明核心代码效果展示源码下载 文章说明 方便绘制一些数学的基础图象&#xff0c;制作该款小工具&#xff0c;不过尚为雏形阶段&#xff0c;等待后续逐步完善 核心代码 采用canvas绘图实现&#xff0c;核心代码如下 <script setup> import {onMou…

公开数据库汇总及下载(1)-TCGA

文章目录 1. 常用数据库2. TCGA数据下载2.1 TCGA介绍2.2 数据类型详解2.3 TCGA数据等级2.4 TCGA网页筛选页面介绍2.5 各文件每个字段的含义2.6 biospecimen IDs介绍(样本ID)2.7 下载代码 参考文件 本文的内容介绍、代码下载主要参考了网上多个文件汇总而成&#xff0c;本文仅作…

深度学习基础—Dropout正则化(随机失活正则化)

1.Dropout正则化 Dropout正则化&#xff1a;网络中每一个神经元节点都有一定概率保留或消除&#xff0c;从而下较小规模的网络。 假设上图网络存在过拟合&#xff0c;Dropout正则化的做法就是遍历每一个节点&#xff0c;对该节点以一定的概率保留或删除&#xff0c;从而简化网络…

C语言 | Leetcode C语言题解之第347题前K个高频元素

题目&#xff1a; 题解&#xff1a; struct hash_table {int key;int val;// 查看 https://troydhanson.github.io/uthash/ 了解更多UT_hash_handle hh; };typedef struct hash_table* hash_ptr;struct pair {int first;int second; };void swap(struct pair* a, struct pair*…