ros多机通信完整教程

系统介绍:
注意:下面的export 只需要export ROS_MASTER_URI 不要export ROS_HOSTNAME 不然你在本机roscore或者roslaunch就会报错

1、设置IP和~/.bashrc文件:
列一波搜到的有用的教程:
接着上面的来
第二个bug——图像话题会丢包、延迟等问题
前言:
老规矩,先讲讲为啥要做这个项目。因为机器人上的工控机没有办法加显卡,所以无法跑TensorFlow-GPU,如果用CPU的话,一个是时间太长,二是消耗资源太多。
所以必须得将图像处理模块,放到笔记本上。刚好看到古月居大佬的书《ros机器人开发实践》中,介绍了如何设置。emmm,下面会介绍书上的一些bug。。。。
感觉现在的时间越来越不够用了,连写博客的时间都不想花了。今天抽一个小时简单记录一下吧,希望我走过的坑,能够给大家节约一些时间。
遇到的坑有:
1 . 根据古月大佬书上的教程,只能实现从机的订阅,从机并不能发布topic到主机(host)上
2 . 我用的是路由器无线通信,通信速度有问题,订阅的话题是Kinect V2相机的数据,数据量大,频率高,通过这种通信方式,经常会丢包
3 . 订阅压缩话题:/kinect2/hd/image_color_rect/compressed
系统介绍:
主机:移动机器人,控制主机是工控机,CPU是i5 6200U
从机:笔记本,CPU是i7 6500 ,GPU GT960M
相机:Kinect V2,连接在工控机上。
软件包:基本的Kinect V2的库函数,具体安装,可以参考这个教程:ubuntu16.04+ros kinetic+kinect2.0错误解决方案+小技巧
工控机连的是一个无线路由,然后让笔记本也连上,使二者处于同一个局域网
都需要安装openssh,这个直接 sudo apt-get install openssh 就好了
在笔记本上远程操作工控机(主机),需要这样:
ssh [email protected]
上面的iim是你被远程操作的工控机的用户名,换成你自己的就好了,后面的IP是工控机在局域网中的IP
登录后,就可以操作launch 相机了——
roslaunch kinect2_bridge kinect2_bridge.launch
就可以拿到话题了。接下来就可以想办法做你需要做的事儿了
1、设置IP和~/.bashrc文件:
先找两台机子的IP地址:
ifconfig
根据这篇教程的介绍,可以知道这些东西的含义:

如果电脑连接的时有线网,则显示结果中,etho 部分的 inet addr 后面就是该电脑的 IP 地址;

如果电脑连接的是无线,则 wlan0 部分的 inet addr 后就是 IP 地址。

在这里插入图片描述

分别了解了之后,需要在两台机子上的/etc/hosts文件加入对方的IP地址和对应的计算机名字
举例如下:
在工控机上终端操作,或者远程操工控机(计算机名为iim):
sudo vim /etc/hosts
1
这里的笔记本(计算机名为 lyl )的IP地址是192.168.199.124,其实连到局域网的时候不是这个,因为编辑博客,所以连的是外网。假设就是上面的那个。
然后加上这段:

192.168.199.124 lyl
1
前面的IP,后面的是名字,尽量对齐

之后的笔记本端的文件整体如下:

127.0.0.1 localhost
127.0.1.1 lyl
192.168.31.124 lyl
192.168.31.182 iim

The following lines are desirable for IPv6 capable hosts

::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

工控机的就不放了,差不多。
古月大佬说,最好ping一下,看看通信是否正常:
在笔记本上

ping iim
1
正常就好了

设置ROS_MASTER_URI,这里的就比较复杂。
我刚开始按照古月的教程,首先文件就写错了一个:bashrc 写成了 bzshrc
更重要的是,他只是在从机,也就是我这里的笔记本上设置了这个参数,这样的话,只能保证笔记本可以订阅主机(工控机)的话题,但是无法发布话题出去!
具体的表现,可以用这个显示:
rostopic echo /yourtopic_name
1
可以发现,咦,一个东西都打印不出来!
遇到这个问题,我搜了很多教程,我刚开始都以为ros不支持从机发布话题,后来直接看了官方教程,提到了双方都得设置ROS_MASTER_URI,我才知道被坑了。

列一波搜到的有用的教程:
在多台机器上运行ROS
ROS网络设置
-这俩都是wiki上的教程
多台机器之间的通信问题
这没啥用
网络上的ROS很慢
这个是一样遇到话题传递速度过慢的问题,贴过来,是帮助大家自己搜索类似的关键词。
Kinect订阅点云代码(point)
这大概是我这几天所做的工作的笔记了,对以后有用的都贴上来了
在ros中python订阅压缩图片话题的教程
不完全适合Kinect V2的包,我后来发现,完全可以用更简洁的。这里得注意OpenCV2和OpenCV3是不一样的
rospy订阅压缩图片采用CvBridge().compressed_imgmsg_to_cv2(ros_img)
第45个案例,用于深度图的解压缩还是比较合适的,底下我还是会将我自己是成功的贴出来。
接着上面的来
从机-笔记本上需要设置的内容,可以看看:
把这段加到笔记本中的 ~/.bashrc 文件中
export ROS_HOSTNAME=lyl
export ROS_MASTER_URI=http://iim:11311
1
2
同理在主机-工控机上这个文件中加上这段:
这里只需要export ROS_MASTER_URI

export ROS_HOSTNAME=iim
export ROS_MASTER_URI=http://iim:11311

设置好IP后,最好 source ~/.bashrc 刷新一下,就可以通信了。

第二个bug——图像话题会丢包、延迟等问题
主要原因,可能是因为用的是WiFi无线网络,带宽有限,视频流数据庞大,所以经常会丢包。获取不到话题。
所以没办法,我只能订阅压缩过的话题——
/kinect2/hd/image_depth_rect/compressed
整体思路大致如下,分析直接看注释吧,要吃饭了,我不想继续写了

#导入消息类型,压缩的和未压缩的
from sensor_msgs.msg import CompressedImage
from cv_bridge import CvBridge, CvBridgeError
from sensor_msgs.msg import Image
import rospy
import numpy as np
import cv2

class Detect(object):
    def __init__(self):
        self.start_time = time.time()
        #订阅网络压缩话题,并且,消息类型换成压缩的
        self.image_sub = rospy.Subscriber("/kinect2/hd/image_color_rect/compressed",CompressedImage, self.rgb_callback,queue_size=1)
        self.depth_sub = rospy.Subscriber("/kinect2/hd/image_depth_rect/compressed",CompressedImage, self.depth_callback,queue_size=1)
        self.bridge = CvBridge()

    def rgb_callback(self,image):
        try:
        #尝试转换压缩图片信息到CV2可以直接用的格式。后面加不加bgr8好像都行。
            self.rgb_image = self.bridge.compressed_imgmsg_to_cv2(image, "bgr8")
            #用上面的和下面的都行,都是会转成rgb的图,但是对于第二个深度图就不合适了,只能用上面的
#            np_arr = np.fromstring(image.data,np.uint8)
# opencv3 is this ,and opencv2 is cv2.CV_LOAD_IMAGE_COLOR
#            self.rgb_image = cv2.imdecode(np_arr,cv2.IMREAD_COLOR)
        except CvBridgeError as e:
            print(e)
            rospy.loginfo('convert rgb image error')

    def depth_callback(self,depth):
        try:
            print("depth_start:")
            self.depth_image = self.bridge.compressed_imgmsg_to_cv2(depth)
            print(self.depth_image.shape)
        except CvBridgeError as e:
            print(e)
            rospy.loginfo('convert depth image image error')

这里的代码,只提供参考,应该是很难直接运行的,具体直接运行的代码有机会再贴出来吧。

反正通过这样,基本上可以实现少丢包,低延迟的效果。
具体的数字,可以看看:

在工控机本地,rostopic hz /kinect2/hd/image_color_rect/compressed
大概是30Hz
在笔记本上我订阅的频率大概是14Hz,然后订阅两个的话,应该会降低一些。
而我的识别模块,大概是3Hz的频率,所以完全可以等得起这个。

你可能感兴趣的:(ros)