ros分佈式多機通信完整教程

ros多機通信完整試坑教程

前言:

  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,我才知道被坑了。

列一波搜到的有用的教程:

接着上面的來

  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的頻率,所以完全可以等得起這個。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章