通过单个Python脚本执行Docker容器启动与ROS roslaunch命令是否可行?
实现方案说明
可以通过单个Python脚本实现你需要的完整流程,你现有代码的核心问题是client.containers.run()默认会阻塞运行,也没有配置容器环境、执行/run.sh的相关逻辑,下面给出两种可行的实现方案:
方案一:所有命令在Docker容器内执行(更推荐)
不需要宿主机安装ROS环境,一致性更高,完整示例代码如下:
#!/usr/bin/env python3 import docker # 初始化Docker客户端 client = docker.from_env() # 私有镜像需补充登录逻辑,公开镜像可跳过 # client.login(username="你的账号", password="你的密码") # 后台启动容器,使用host网络模式简化ROS通信配置 container = client.containers.run( image="替换为你的ROS镜像地址", detach=True, network_mode="host", # 如需挂载本地代码可取消注释下方配置 # volumes={"/本地工作空间路径": {"bind": "/容器内工作空间路径", "mode": "rw"}} ) # 执行容器内的/run.sh脚本 run_sh_result = container.exec_run("/bin/bash /run.sh") print("run.sh执行输出:\n", run_sh_result.output.decode("utf-8")) # 执行失败直接清理容器退出 if run_sh_result.exit_code != 0: print("run.sh执行失败,正在清理容器") container.stop() container.remove() exit(1) # 执行roslaunch命令,注意需要先source ROS和工作空间的环境变量 roslaunch_cmd = "/bin/bash -c 'source /opt/ros/$ROS_DISTRO/setup.bash && source 替换为容器内工作空间的devel/setup.bash && roslaunch 替换为你的功能包名 替换为你的启动文件.launch'" roslaunch_result = container.exec_run(roslaunch_cmd, stream=True) # 实时打印roslaunch运行日志 for log in roslaunch_result.output: print(log.decode("utf-8"), end="") # 脚本退出前清理容器 container.stop() container.remove()
方案二:roslaunch在宿主机执行
需要宿主机安装对应版本的ROS,且和容器内的ROS Master正常通信,核心调整点如下:
- 容器启动时暴露11311端口,配置ROS相关环境变量
- 增加等待逻辑,确认容器内ROS Master完全启动后再初始化roslaunch
示例代码片段:
import docker import time import roslaunch import rospy client = docker.from_env() # 启动容器时配置端口和环境变量 container = client.containers.run( image="替换为你的ROS镜像地址", detach=True, ports={"11311/tcp": 11311}, environment={ "ROS_MASTER_URI": "http://localhost:11311", "ROS_HOSTNAME": "localhost" } ) # 执行/run.sh run_sh_result = container.exec_run("/bin/bash /run.sh") print(run_sh_result.output.decode("utf-8")) if run_sh_result.exit_code != 0: container.stop() container.remove() exit(1) # 等待ROS Master启动完成 time.sleep(3) # 初始化并启动roslaunch rospy.init_node("docker_launch_starter", anonymous=True) launch = roslaunch.scriptapi.ROSLaunch() launch.start() # 后续按需添加需要启动的节点配置
注意事项
- 若/run.sh负责启动ROS Master,建议增加端口监听检测逻辑替代固定时长等待,避免连接失败
- 使用host网络模式时,需确保宿主机11311端口未被其他进程占用
- 脚本异常退出时建议增加异常捕获逻辑,自动清理残留容器
内容的提问来源于stack exchange,提问作者Vlad Paskevits
相关产品推荐
相关产品推荐

