当前位置: 首页 > news >正文

【dockerros2】ROS2节点通信:docker容器之间/docker容器与宿主机之间

🌀 一个中大型ROS项目常需要各个人员分别完成特定的功能,而后再组合部署,而各人员完成的功能常常依赖于一定的环境,而我们很难确保这些环境之间不会相互冲突,特别是涉及深度学习环境时。这就给团队项目的部署落地带来了极大的困难。虽然类似于conda这样的工具可以弥补一部分的不足,但是对于项目部署而言,还是不足的。

🚀现在就针对上述的问题,提出一种基于docker的ROS2通信解决方案,其中会涉及docker network和docker compose等内容。容器与宿主机的ROS2版本,LTS版(foxy/humble/…)都行。
在这里插入图片描述


🌔01
前情说明

首先有以下几点说明

(1) 宿主系统是基于ubuntu系统,系统的架构x86_64或arm均可,使用的是NVIDIA显卡,且系统内已安装相应的显卡驱动。
(2) 宿主机和容器的架构(x86_64/arm64)保持一致。
(3) 如果宿主机开了VPN,先关掉,避免干扰。

为了讲解的方便,假设我们有以下环境:

(1) 宿主系统是ubuntu20.04,架构是x86_64,安装了ros foxy,显卡是NVIDIA GTX 1650,且显卡驱动可用。
(2) 宿主系统内docker和docker compose都可以正常使用。
(3) 有一个docker镜像(假设叫做image:latest),镜像环境是ubuntu22.04,架构也是x86_64,安装了ros humble。


🌔02
创建docker compose文件

第一步编写一个docker compose文件,用以从镜像创建容器。这种方式会比使用docker run好些,因为它能够把容器的参数写到文件里,还能联调多个容器的关系,对于多容器组合的项目开发比较友好。并且我建议,如果你只有一个docker容器,那也使用docker compose,这样相对于docker run的命令行方式更容易维护。

mkdir project && cd project
touch project.yml

然后编写project.yml的内容,示例如下。这里之所有没用device:来挂载摄像头、激光雷达等外设,那是因为这些外设的驱动节点(传感器数据发布节点)放在宿主机中更好,容器只要订阅这些节点发布的话题进行处理即可。另外,ROS_DOMAIN_ID要一样才能通信,默认为0。

# 多对多,自由
services:c1:  # 服务名称(一个服务对应一个容器),自己取名即可container_name: c1  # 容器名称image: image:latest # 镜像名称working_dir: [your_workdir_path1]  # 工作目录,比如/home/zhangsanshm_size: [your_share_memory_size]  # 共享内存大小,比如4Gruntime: nvidia  environment:- NVIDIA_VISIBLE_DEVICES=all- DISPLAY=${DISPLAY}  # 设置DISPLAY环境变量 volumes:- [your_source_path1]:[your_target_path1]  # 挂载项目目录- /dev/dri:/dev/dri  # 挂载 GPU 设备- /tmp/.X11-unix:/tmp/.X11-unix:rw  # 挂载 X11 Unix 套接字- ${HOME}/.Xauthority:/root/.Xauthority:rw  # 挂载 X11 认证文件networks:- [network_name] # 共享网络名称,比如ros_networkstdin_open: true  # 相当于 -itty: true  # 相当于 -tc2:  # 服务名称(一个服务对应一个容器),自己取名即可container_name: c2  # 容器名称image: image:latest # 镜像名称working_dir: [your_workdir_path2]  # 工作目录,比如/home/lisishm_size: [your_share_memory_size]   # 共享内存大小,比如4Gruntime: nvidia  environment:- NVIDIA_VISIBLE_DEVICES=all- DISPLAY=${DISPLAY}  # 设置DISPLAY环境变量 volumes:- [your_source_path2]:[your_target_path2]  # 挂载项目目录- /dev/dri:/dev/dri  # 挂载 GPU 设备- /tmp/.X11-unix:/tmp/.X11-unix:rw  # 挂载 X11 Unix 套接字- ${HOME}/.Xauthority:/root/.Xauthority:rw  # 挂载 X11 认证文件networks:- [network_name] # 共享网络名称,比如ros_networkstdin_open: true  # 相当于 -itty: true  # 相当于 -tnetworks: # 如果没有名称为ros_network的网络,会自己创建一个。[network_name]:name: [network_name]driver: bridge

🌔03
启动docker compose服务

开放X11服务(这样容器中的窗口就可以显示出来),并从project.yml文件启动docker容器。

xhost +
docker-compose -f project.yml up

接着你可以查看网络信息,确认是否共享上了:

docker network ls

你会看这样的信息:

NETWORK ID     NAME                          DRIVER    SCOPE
ecb8bca83c79   bridge                        bridge    local
0e489127c701   host                          host      local  #这个是你宿主机的网络
fad86f998533   none                          null      local
65b64309ebc2   ros_network                   bridge    local   #这个是你刚才创建的共享网络

进一步查看共享网络信息:

docker network inspect ros_network  

你会看到这样的输出:

# c1和c2之间的ROS2节点在ros_network子网中通信
# 容器ROS2节点通过把数据转发给ros_network网关,网关再转接给host,实现与宿主机ROS2节点通信
[{"Name": "ros_network","Id": "65b64309ebc2df88cd05c3a1fb33635ab4818fd6d2022ce028ad25ef22f2e0ef","Created": "2025-01-11T20:20:06.632800735+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": {},"Config": [{"Subnet": "172.18.0.0/16", # 子网"Gateway": "172.18.0.1" # 网关}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {"79ba2ce2e7914e02e9c36828eb40c343c5abe5f3ca43f2c61b304b91f8cd8de6": {"Name": "c1","EndpointID": "f3956bf172423f84b4e2bf0d55d9c1149b9135dcc32cfc6d01c6770b86a0015d","MacAddress": "02:42:ac:12:00:03","IPv4Address": "172.18.0.3/16", # c1的ip"IPv6Address": ""},"d02027c00ae82e6589dd4690fb7f69974de9d867958f17ced17f3babe0c7527b": {"Name": "c2","EndpointID": "50b4abf51ee3f4b118b99813b061830a2cf2858ecffa4b2c6147849e378fe8b7","MacAddress": "02:42:ac:12:00:02","IPv4Address": "172.18.0.2/16", #c2的ip"IPv6Address": ""}},"Options": {},"Labels": {}}
]

🌔04
ROS2通信测试

另开两个终端,分别在终端内运行以下命令进入容器(你可以开多个):

docker exec -it c1 /bin/bash # 第一个终端(可以开多个)
docker exec -it c2 /bin/bash # 第二个终端(可以开多个)

启动以下节点:

# 在宿主机中
ros2 run turtlesim turtlesim_node
# 在c1容器中
ros2 run demo_nodes_cpp talker # [INFO] [1736647116.948458682] [talker]: Publishing: 'Hello World: 1'
# 在c2容器中
ros2 run demo_nodes_cpp listener  # [INFO] [1736647126.948946624] [listener]: I heard: [Hello World: 1]

并分别在各环境中运行:

ros2 node list

如果所有环境中都输出了以下内容,那就说明成功了。

/listener
/talker
/turtlesim

🌔05
附录

5.1 安装docker compose

# 从官方下载软件包(确保和自己机器的架构一致):https://github.com/docker/compose/releases
# 假设下载了docker-compose-linux-x86_64到~/Downloads
cd ~/Downloads
# 改名
mv docker-compose-linux-x86_64 docker-compose
# 移动到指定位置
sudo mv docker-compose /usr/local/bin
# 赋予权限
sudo chmod +x /usr/local/bin/docker-compose

相关文章:

【dockerros2】ROS2节点通信:docker容器之间/docker容器与宿主机之间

🌀 一个中大型ROS项目常需要各个人员分别完成特定的功能,而后再组合部署,而各人员完成的功能常常依赖于一定的环境,而我们很难确保这些环境之间不会相互冲突,特别是涉及深度学习环境时。这就给团队项目的部署落地带来了…...

使用外网访问在群晖中搭建思源docker

还是要折腾,之前发现用公网IP可以访问就没有折腾,今天ip变了,用不了了,一搜,发现有方法可以用域名访问,哎,太好了! 原文:分享我在 群晖 docker 部署 思源笔记 步骤 - 链…...

深度学习中的EMA技术:原理、实现与实验分析

深度学习中的EMA技术:原理、实现与实验分析 1. 引言 指数移动平均(Exponential Moving Average, EMA)是深度学习中一种重要的模型参数平滑技术。本文将通过理论分析和实验结果,深入探讨EMA的实现和效果。 深度学习中的EMA技术:原理、实现与…...

win32汇编环境,窗口程序中对按钮控件常用操作的示例

;运行效果 ;win32汇编环境,窗口程序中对按钮控件常用操作的示例 ;常用的操作,例如创建按钮控件,使其无效,改变文本,得到文本等。 ;将代码复制进radasm软件里,直接就可以编译运行。重点部分加备注。 ;>&g…...

CentOS 7.9 通过 yum 安装 Docker

文章目录 前言一、删除已安装的 Docker二、网络设置三、设置 yum 源,并安装依赖四、设置 Docker 仓库五、安装及使用 Docker六、镜像仓库总结 前言 CentOS 7.9 过了维护期,Docker 官方文档没有了相关的安装文档。记录一下,备用! …...

【开源免费】基于Vue和SpringBoot的英语知识应用网站(附论文)

本文项目编号 T 138 ,文末自助获取源码 \color{red}{T138,文末自助获取源码} T138,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

工具推荐:PDFgear——免费且强大的PDF编辑工具 v2.1.12

PDFgear——免费且强大的PDF编辑工具 v2.1.12 软件简介 PDFgear 是一款 完全免费的 PDF 软件,支持 阅读、编辑、转换、合并 以及 跨设备签署 PDF 文件,无需注册即可使用。它提供了丰富的 PDF 处理功能,极大提升了 PDF 文件管理的便捷性和效…...

Web渗透测试之XSS跨站脚本 防御[WAF]绕过手法

目录 XSS防御绕过汇总 参考这篇文章绕过 XSS payload XSS防御绕过汇总 服务端知道有网络攻击或者xss攻 Html...

MMDetection框架下的常见目标检测与分割模型综述与实践指南

目录 综述与实践指南 SSD (Single Shot MultiBox Detector) 基本配置和使用代码 RetinaNet 基本配置和使用代码 Faster R-CNN 基本配置和使用代码 Mask R-CNN 基本配置和使用代码 Cascade R-CNN 基本配置和使用代码 总结 综述与实践指南 MMDetection是一个基于Py…...

怎么实现Redis的高可用?

大家好,我是锋哥。今天分享关于【怎么实现Redis的高可用?】面试题。希望对大家有帮助; 怎么实现Redis的高可用? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 为了实现 Redis 的高可用性,我们需要保证在发…...

OpenCV实现Kuwahara滤波

Kuwahara滤波是一种非线性的平滑滤波技术,其基本原理在于通过计算图像模板中邻域内的均值和方差,选择图像灰度值较为均匀的区域的均值来替代模板中心像素的灰度值。以下是Kuwahara滤波的详细原理说明: 一、基本思想 Kuwahara滤波的基本思想…...

WINFORM - DevExpress -> DevExpress总结[安装、案例]

安装devexpress软件 路径尽量不换,后面破解不容易出问题 vs工具箱添加控件例如: ①使用控制台进入DevExpress安装目录: cd C:\Program Files (x86)\DevExpress 20.1\Components\Tools ②添加DevExpress控件: ToolboxCreator.exe/ini:toolboxcreator…...

Golang学习笔记_22——Reader示例

Golang学习笔记_19——Stringer Golang学习笔记_20——error Golang学习笔记_21——Reader 文章目录 io.Reader 示例从字符串中读取从文件中读取从HTTP响应中读取从内存的字节切片中读取自定义io.Reader实现 源码 io.Reader 示例 从字符串中读取 func ReadFromStrDemo() {str…...

【2024年华为OD机试】(A卷,100分)- 猜字谜(Java JS PythonC/C++)

一、问题描述 小王设计了一个简单的猜字谜游戏,游戏的谜面是一个错误的单词,比如 nesw,玩家需要猜出谜底库中正确的单词。猜中的要求如下: 对于某个谜面和谜底单词,满足下面任一条件都表示猜中: 变换顺序…...

iostat命令详解

iostat 命令是 I/O statistics(输入/输出统计)的缩写,用来报告系统的 CPU 统计信息和块设备及其分区的 IO 统计信息。iostat 是 sysstat 工具集的一个工具,在 Ubuntu 系统中默认是不带 iostat 命令的,需要自行安装: $ sudo apt in…...

Linux:操作系统简介

前言: 在本片文章,小编将带大家理解冯诺依曼体系以及简单理解操作喜欢,并且本篇文章将围绕什么以及为什么两个话题进行展开说明。 冯诺依曼体系: 是什么: 冯诺依曼体系(Von Neumann architecture&#xff…...

企业级信息系统开发讲课笔记4.12 Spring Boot默认缓存管理

文章目录 1. Spring Boot默认缓存管理2. Spring的缓存机制2.1 缓存机制概述2.2 缓存接口和缓存管理接口3. 声明式缓存注解3.1 @EnableCaching注解3.2 @Cacheable注解3.2.1 value/cacheNames属性3.2.2 key属性3.2.3 keyGenerator属性3.2.4 cacheManager/cacheResolver属性3.2.5 …...

2025制定一个高级java开发路线:分布式系统、多线程编程、高并发经验

1-熟悉分布式系统的设计和应用,熟悉分布式、缓存、消息、负载均衡等机制和实现者优先。 2-熟悉多线程编程,具备高并发经验优先。 技术学习规划:熟悉分布式系统和高并发技术 以下是针对目标要求的系统性学习规划,分为 阶段目标 和…...

20250110_ PyTorch中的张量操作

文章目录 前言1、torch.cat 函数2、索引、维度扩展和张量的广播3、切片操作3.1、 encoded_first_node3.2、probs 4、长难代码分析4.1、selected4.1.1、multinomial(1)工作原理: 总结 前言 1、torch.cat 函数 torch.cat 函数将两个张量拼接起来,具体地是…...

hadoop-yarn常用命令

一、YARN命令介绍 1. YARN命令简介 YARN提供了一组命令行工具,用于管理和监控YARN应用程序和集群。 2. yarn application命令 (1) yarn application命令的基本语法 yarn application命令的基本语法如下: yarn application [genericOptions] [comma…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...