在智能云服务机器人的研究中,结合DOCKER容器技术是一个研究方向之一,本文阐述了利用容器技术进行一个线下机器人的基本控制方法。
阅读本文之前,建议先阅读之前在仿真条件下做的turtlebot_sim的控制,本文的工作是基于仿真工作的基础进行的。之前,实体的turtlebot机器人未成功,主要是因为相应的package缺少,在docker的镜像这并未给出。
package(功能包)是ROS中软件组织的基本形式,一个功能包具有最小的结构和最小的内容,用于创建ROS程序。它可以运行包含RIS运行的进程(节点)、配置文件等。
实际上,完整版的ROS系统大概 341 个package,详见“/opt/ros/indigo/share/“,但是ROS镜像中只包含了150左右的package,因此有很多的功能仅仅用DOCKER官方给的简单版的镜像是不能实现的。
为了解决这个问题,尝试过以下几个觉得可行性方法:
(1)直接在容器内部进行package的安装,failed。因为,在进行ROS容器的启用之前就改变了ROS容器的网络结构,不是用的默认docker0网桥,而是自定义的网桥,并且对自定义的网桥进行了配置,详细见:在仿真条件下做了turtlebot_sim的控制
(2)利用Docker的Volume数据卷共享机制,使ROS容器与本地共享package,failed。因为,虽然可以在容器内部“发现“这些共享包,单与本地共享的package功能包是由本地编译生成的,依赖的还是本地环境,即使重新编译,重新编译的命令比如catkin_make在容器内部也缺失。
(3)在Docker hub 官网给的简单版的ROS镜像基础上,重新制作包含完整版的功能包package的ROS的镜像,并用制作的镜像进行实验,Succeed。
如概述中所说,本文所提出的办法是在之前仿真办法的基础上,建议连着看。
根据之前未能在容器内部控制的原因,主要就是要重新build的镜像中需要加入完整的功能包,与完整版相比,大概还少200个功能包左右。
其实就是在原来的build镜像的Dockerfile里多加上这些功能包即可,但是我们又不太好一次性区分哪些在简单版的镜像中有哪些没有,所以直接把所有的功能包安装341个命令都写入,一个个写虽然二三十分钟就可以弄完,但总觉得这种方式太过蛮力,还好只有几百个,如果是上千上万个就显得不太好。
于是,写了一小段python代码进行处理生成需要的几百条命令:
python代码:
import os
def GetDirList(dir, dirlist):
newDir=dir
number=0
from string import maketrans
#定义转化表,下载的命令包和读取的本地的包文件名需要把'_'转为'-'
table =maketrans('_','-')
if os.path.isdir(dir):
for s in os.listdir(dir): #遍历指定目录
# 生成添加到Dockerfile的命令
newDir=' ros-indigo-'+s.translate(table)+' \\'
number=number+1
dirlist.append(newDir)
print number
return dirlist
#指定从本地目录'/opt/ros/indigo/share/',功能包都在这个目录
list = GetDirList('/opt/ros/indigo/share/', [])
for e in list:
print e #把需要添加到Dockerfile的命令打印到控制台,直接拷贝
原Dockerfile:
注:
此处原Dockerfile的基础镜像指定的是“ros:indigo-robot“,对于此镜像的描述,可以看看官网描述。
FROM ros:indigo-robot
WORKDIR /notebooks
RUN sed -i "s|http://archive.ubuntu.com|http://mirrors.163.com|g" /etc/apt/sources.list && rm -Rf /var/lib/apt/lists/* && apt-get -y update && apt-get install -y \
pkg-config \
python-dev \
python-opencv \
libopencv-dev \
libav-tools \
libjpeg-dev \
libpng-dev \
libtiff-dev \
libjasper-dev \
python-numpy \
python-pycurl \
python-opencv \
#在这里把上面由python代码生成的341条命令拷贝到这里
使用基于新镜像生成的容器。
$ sudo docker run -idt --name=<指定容器名> --net=none <新镜像的名称> /bin/bash
接下来的操作把这里在仿真的操作完成一遍即可,
http://blog.csdn.net/chenming_hnu/article/details/61648071
实操运行步骤参考官网:
http://wiki.ros.org/Robots/TurtleBot/
$ source /etc/profile
$ source /opt/ros/indigo/setup.bash
开启另外的新容器窗口时,不要用attach命令,用exec命令。
root@50ed97b4ce5c:/notebooks# roslaunch turtlebot_teleop keyboard_teleop.launch
电脑屏幕的左边命令框为开启Turtlebot, Kinect的命令;右边为Kinect采集的图像,黄圈为图像特征点。
目前这种办法对于多个容器的配置是有问题的。当前的方式是通过用容器借用主机网卡eth0的方式进行通讯,但是当需要类似的多个容器的时候,就会遇到问题了。
当前的 Docker容器的宿主机与Turtlebot机器是特意配置在同一个局域网 192.168.1.1/24内。但是,要使云机器人的研究具有普适性,是要扩展到更大范围的网络。并且,Docker容器宿主机应该由专业服务器进行承担,这样才可以处理大规模的分布式机器人的复杂任务的处理。