【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ÿ…...
企业级信息系统开发讲课笔记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…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...
Xcode 16 集成 cocoapods 报错
基于 Xcode 16 新建工程项目,集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...
简约商务通用宣传年终总结12套PPT模版分享
IOS风格企业宣传PPT模版,年终工作总结PPT模版,简约精致扁平化商务通用动画PPT模版,素雅商务PPT模版 简约商务通用宣传年终总结12套PPT模版分享:商务通用年终总结类PPT模版https://pan.quark.cn/s/ece1e252d7df...
