ros分布式多机通信完整教程

ros多机通信完整试坑教程

文章目录

  • ros多机通信完整试坑教程
    • 前言:
      • 系统介绍:
    • 1、设置IP和~/.bashrc文件:
    • 列一波搜到的有用的教程:
    • 接着上面的来
    • 第二个bug——图像话题会丢包、延迟等问题

前言:

  1. 老规矩,先讲讲为啥要做这个项目。因为机器人上的工控机没有办法加显卡,所以无法跑TensorFlow-GPU,如果用CPU的话,一个是时间太长,二是消耗资源太多。
    所以必须得将图像处理模块,放到笔记本上。刚好看到古月居大佬的书《ros机器人开发实践》中,介绍了如何设置。emmm,下面会介绍书上的一些bug。。。。
  2. 感觉现在的时间越来越不够用了,连写博客的时间都不想花了。今天抽一个小时简单记录一下吧,希望我走过的坑,能够给大家节约一些时间。
  3. 遇到的坑有:
    1 . 根据古月大佬书上的教程,只能实现从机的订阅,从机并不能发布topic到主机(host)上
    2 . 我用的是路由器无线通信,通信速度有问题,订阅的话题是Kinect V2相机的数据,数据量大,频率高,通过这种通信方式,经常会丢包
    3 . 订阅压缩话题:/kinect2/hd/image_color_rect/compressed

系统介绍:

  1. 主机:移动机器人,控制主机是工控机,CPU是i5 6200U
  2. 从机:笔记本,CPU是i7 6500 ,GPU GT960M
  3. 相机:Kinect V2,连接在工控机上。
  4. 软件包:基本的Kinect V2的库函数,具体安装,可以参考这个教程:ubuntu16.04+ros kinetic+kinect2.0错误解决方案+小技巧
  5. 工控机连的是一个无线路由,然后让笔记本也连上,使二者处于同一个局域网
  6. 都需要安装openssh,这个直接 sudo apt-get install openssh 就好了
  7. 在笔记本上远程操作工控机(主机),需要这样:
  8. ssh [email protected]
  9. 上面的iim是你被远程操作的工控机的用户名,换成你自己的就好了,后面的IP是工控机在局域网中的IP
  10. 登录后,就可以操作launch 相机了——
  • roslaunch kinect2_bridge kinect2_bridge.launch
  • 就可以拿到话题了。接下来就可以想办法做你需要做的事儿了

1、设置IP和~/.bashrc文件:

  1. 先找两台机子的IP地址:
    ifconfig

根据这篇教程的介绍,可以知道这些东西的含义:

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

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

  1. 分别了解了之后,需要在两台机子上的/etc/hosts文件加入对方的IP地址和对应的计算机名字
    举例如下:
    在工控机上终端操作,或者远程操工控机(计算机名为iim):
sudo vim /etc/hosts

这里的笔记本(计算机名为 lyl )的IP地址是192.168.199.124,其实连到局域网的时候不是这个,因为编辑博客,所以连的是外网。假设就是上面的那个。
然后加上这段:

192.168.199.124  lyl

前面的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

可以发现,咦,一个东西都打印不出来!
遇到这个问题,我搜了很多教程,我刚开始都以为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个案例,用于深度图的解压缩还是比较合适的,底下我还是会将我自己是成功的贴出来。

接着上面的来

  1. 从机-笔记本上需要设置的内容,可以看看:
    把这段加到笔记本中的 ~/.bashrc 文件中
export ROS_HOSTNAME=lyl
export ROS_MASTER_URI=http://iim:11311

同理在主机-工控机上这个文件中加上这段:

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')

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

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

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

你可能感兴趣的:(ros,ubuntu,kinect2,错误解决,教程,faster_rcnn,rospy,远程登录,topic)