使用 ROS Melodic 运行 Python 代码
机器人操作系统 (Robot Operating System,ROS) 在机器人技术中得到广泛应用。但是,不同的可用 ROS 发行版可能会导致软件版本冲突。
每个 Ubuntu 版本都附带不同的 ROS 发行版。例如,Ubuntu 18.04 使用基于 Python 2.7 的 ROS Melodic。Ubuntu 20.04 使用基于 Python 3 的 ROS Noetic。
通常,我们的ROS主机需要是较旧的ROS版本,以获得特定的硬件驱动程序支持。在这种情况下,使用基于Python3的现代软件库(如OpenCV 4、Tensorflow和PyTorch)会导致问题。
在本文中,我将向你展示如何将 ROS Melodic master 与更新的 ROS 发行版放在同一台机器上。我们可以通过使用 Docker 将我们的软件模块容器化来做到这一点。
什么是Docker?
Docker 目前是容器化软件的行业标准。它有点像虚拟机,但更轻量,因为每个容器都使用主机的操作系统。
“Docker 容器镜像是一个轻量级的、独立的、可执行的软件包,其中包括运行应用程序所需的一切:代码、运行时、系统工具、系统库和设置。” [1]
在 Docker 容器中,我们可以安装任何我们想要使用的 ROS 发行版和软件库——而不会对我们的主机系统造成问题。
作为本文中的示例用例,我们将使用带有 ROS Melodic 的 Ubuntu 18.04 作为我们的系统。出于演示目的,我们将发布一个网络摄像头图像主题。使用 Docker,我们将使用 ROS Noetic 和 OpenCV 4 创建并运行用于计算机视觉任务的容器。
通过下图所示的设置,ROS Melodic 节点可以使用 Docker 的--network host设置与 ROS Noetic 节点共存并进行通信。
如何在同一台计算机上针对不同的 ROS 版本使用 Docker。
使用 ROS Melodic 发布网络摄像头流
如果你的计算机上还没有 catkin 工作区,请使用以下命令创建一个:
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make
首先,我们必须在主机系统上启动 ROS Melodic master。为此,请在一个新终端中输入roscore。
接下来,我们使用 ROS 包cv_camera 发布网络摄像头流。要从 GitHub 克隆包,需要使用 catkin_make 构建包,然后运行cv_camera_node,执行以下命令:
cd ~/catkin_ws/src
git clone https://github.com/OTL/cv_camera.git
cd ..
catkin_make
source devel/setup.bash
rosrun cv_camera cv_camera_node
你现在应该能够看到图像主题/cv_camera/image_raw。
使用 ROS Noetic 运行 Docker 容器
对于我们的模型计算机视觉节点,我们将在ROS_Docker文件夹中创建以下三个文件:
/home/username/ROS_Docker/
|-- Dockerfile
|-- cv_node.py
|-- start_ros_node.sh
Dockerfile
要创建和运行 Docker 容器,我们必须编写一个 Dockerfile。Dockerfile 就像一个蓝图,它告诉 Docker 如何构建镜像。Docker 使用映像来创建和运行容器。
在 Dockerfile 中,我们使用FROM从基础映像开始,然后使用RUN apt-get update && apt-get install.
对于我们的 ROS 应用程序,我们必须创建一个 catkin 工作区。然后,我们需要使用RUN git clone.
FROM ros:noetic
# install packages with apt-get
RUN apt-get update && apt-get install -y --no-install-recommends
git
libopencv-dev python3-opencv
&& rm -rf /var/lib/apt/lists
# create and build a catkin_ws
SHELL ["/bin/bash", "-c", "-l"]
WORKDIR /home/catkin_ws
RUN mkdir src && source "/opt/ros/$ROS_DISTRO/setup.bash" && catkin_make
# get ROS packages from github
WORKDIR /home/catkin_ws/src
RUN git clone -b noetic https://github.com/ros-perception/vision_opencv.git
WORKDIR /home/catkin_ws/
RUN source /home/catkin_ws/devel/setup.bash && catkin_make
# copy our scripts
WORKDIR /home
COPY ./cv_node.py .
COPY ./start_ros_node.sh .
ENTRYPOINT ["/home/start_ros_node.sh"]
cv_node.py
cv_node目的是订阅我们的网络摄像头主题,对图像做一些处理,然后发布一个新的图像主题。为了在 ROS 图像和 OpenCV 图像之间进行转换,我们使用 cv_bridge。
以下代码将订阅网络摄像头主题,使用 OpenCV 4 添加文本并在新主题上发布新图像。
#!/usr/bin/env python3
import rospy
import cv2
from sensor_msgs.msg import Image, CompressedImage
from cv_bridge import CvBridge
class cv_node:
def __init__(self):
self.bridge = CvBridge()
image_sub = rospy.Subscriber("/cv_camera/image_raw", Image, self.callback, queue_size=1)
self.image_pub = rospy.Publisher("/cv_camera/image_out/compressed", CompressedImage, queue_size=1)
def callback(self, data):
cv_img = self.bridge.imgmsg_to_cv2(data)
cv_img = cv2.putText(cv_img, "Published with ROS Noetic", (30,30), cv2.FONT_HERSHEY_SIMPLEX, 1.1, (255,0,0), 2)
cv_img = self.bridge.cv2_to_compressed_imgmsg(cv_img)
self.image_pub.publish(cv_img)
def main():
rospy.init_node('cv_node')
node = cv_node()
rate = rospy.Rate(30) # frequency in Hz
while not rospy.is_shutdown():
rate.sleep()
if __name__ == '__main__':
main()
该节点可以适应执行更高级的任务。例如,我们可以使用深度神经网络在cv_img 上进行对象检测。
如果你想导入其他库——例如 PyTorch 或 Tensorflow——确保使用RUN pip install [...]将它们安装在 Dockerfile 中
start_ros_node.sh
这个脚本是我们的 Docker 容器的入口点。它用来启动我们的 ROS 节点cv_node.py。
#!/bin/bash
source /home/catkin_ws/devel/setup.bash
python3 cv_node.py
构建并运行容器
要构建 docker 镜像,请在终端中执行以下命令:docker build -t medium .
这将在当前目录中运行Dockerfile,并使用medium标记创建Docker映像。
构建过程完成后,在终端中运行以下命令:
docker run -it --network host medium:latest
这将以交互模式运行带有medium标签的最新容器。此外,它将使用主机的网络,以便 Docker 容器和我们的 ROS master 可以通信。
你现在应该在主机系统上看到新主题 /cv_camera/image_out/compressed。你可以使用命令rosnode info cv_node检查cv_node。
使用 Docker,我们可以容器化不同的 ROS 发行版并安装额外的软件库。因为它们是封装好的,不会对我们的主机系统造成问题。
可以使用 Docker 的--network host设置来建立 Docker 容器和主机之间的通信。