天天看點

踩坑之旅:配置 ROS 環境

最近在學習機器人相關的導航算法,為了友善于驗證算法的效果,需要搭一個 ROS(Robot Operate System) 環境。特地寫點筆記,這是這個機器人系列的首篇筆記。

以下内容為本人的著作,如需要轉載,請聲明原文連結 微信公衆号「englyf」https://www.cnblogs.com/englyf/p/16660252.html

最近在學習機器人相關的導航算法,為了友善于驗證算法的效果,需要搭一個 ROS(Robot Operate System) 環境。特地寫點筆記,這是這個機器人系列的首篇筆記。

雖然在網絡上有很詳細的教程,不過在對着教程一步步安裝的過程中還是踩了不少坑。因為在牆内(你懂的),會導緻聯網下載下傳檔案的時候老是失敗。可能你會說不可以指定牆内的安裝源嗎?可以是可以,不過在安裝完 ROS 包後還需要初始化一些環境,比如 rosdep 的初始化,這時候還是需要從 github 聯網下載下傳檔案的,這時就算指定了牆内的安裝源也不管事,因為這個 github 的域名被污染了。下面就記錄一下解決的過程吧,回首往事真的一把心酸。。。

基礎環境:

Ubuntu 18.04

ROS Melodic

VMware® Workstation 14 Pro

1.配置軟體倉庫

確定軟體倉庫裡允許下載下傳的資源類型包括

main

,

universe

,

restricted

,

multiverse

。如下面圖所示,

踩坑之旅:配置 ROS 環境

2.指定牆内的安裝源

國内的安裝源有好幾個,還是覺得阿裡的安裝源比較快一些,直接拷貝下面的内容到

/etc/apt/sources.list

檔案中替換原來的内容并且儲存

deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse

# deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
           

單獨指定 ROS 包的安裝源

sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.aliyun.com/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'
           

3.指定密鑰

sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
           

到目前為止,以上的設定都很順利。如果這一步你剛好出錯了,可以到這裡去看看處理方法。

4.安裝 ROS 包

更新一下安裝索引

sudo apt update
           

安裝完整的桌面版

sudo apt install ros-melodic-desktop-full
           

中間會出現提示

Do you want to continue? [Y/n]
           

輸入 Y 然後回車繼續安裝過程,花點時間休息一下再回來。。。

回來一看

E: Failed to fetch http://mirrors.aliyun.com/ros/ubuntu/pool/main/r/ros-melodic-rqt-moveit/ros-melodic-rqt-moveit_0.5.10-1bionic.20210505.031448_amd64.deb  Undetermined Error [IP: 120.241.234.99 80]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
           

出現了這一坨失敗提示,後邊還建議加個參數

--fix-missing

下載下傳補漏,好的再來一次

sudo apt install ros-melodic-desktop-full --fix-missing
           

好了,安裝完成

5.配置 ROS 環境變量

為了在每次啟動 bash 時都自動載入 ROS 的環境變量,輸入

echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc
           

配置完,重新開機一下 Terminal 視窗

6.安裝一些關鍵的依賴包

sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential
           

中間又會出現提示

Do you want to continue? [Y/n]
           

輸入 Y 然後回車繼續安裝過程

7.初始化 ROS 的依賴安裝管理包 rosdep

rosdep 是 ROS 安裝管理包。使用 ROS 過程中如果需要安裝被 ROS 要編譯的源代碼,或被某些 ROS 核心元件依賴的包,那麼就可以用 rosdep 來安裝。使用前,這個包需要被初始化一次

sudo rosdep init
           

但是,很多情況下你會碰到下面這些錯誤提示

ERROR: cannot download default sources list from:
https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/sources.list.d/20-default.list
Website may be down.
           

報錯内容的意思說白了就是說域名

raw.githubusercontent.com/ros/rosdistro/master/rosdep/sources.list.d/20-default.list

的頁面找不到了。真實情況其實是這個位址的域名因為衆所周知的原因被污染了,并不是頁面已經下架。

我是這麼處理的,在網上搜一下關鍵詞

域名查IP

找到可以查域名對應 IP 的網站,然後根據查到的 IP 來修改

主機名靜态查詢表

檔案。如果網站告訴你

禁止查詢該域名

,那就再換一個網站再查,多大點事!

我這裡頁面傳回的結果是

實體位址 IP位址 數字位址
美國加利福尼亞舊金山 185.199.108.133 3116854405
美國加利福尼亞舊金山 185.199.111.133 3116855173
美國加利福尼亞舊金山 185.199.110.133 3116854917
美國加利福尼亞舊金山 185.199.109.133 3116854661
打開

/etc/hosts

檔案,這個就是

主機名靜态查詢表

sudo gedit /etc/hosts
           

對應上邊查到的 IP 位址,把下面的内容拷貝追加到

/etc/hosts

的尾部并儲存

185.199.108.133 raw.githubusercontent.com
185.199.111.133 raw.githubusercontent.com
185.199.110.133 raw.githubusercontent.com
185.199.109.133 raw.githubusercontent.com
           

然後,再試一次

~$ sudo rosdep init
Wrote /etc/ros/rosdep/sources.list.d/20-default.list
Recommended: please run

	rosdep update
           

成功通過這一關,接着執行更新一下

~$ rosdep update
reading in sources list data from /etc/ros/rosdep/sources.list.d
Hit https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/osx-homebrew.yaml
ERROR: error loading sources list:
	('The read operation timed out',)
           

可惜又通路失敗了,這會兒報的是讀操作逾時。重試了好幾回,沒辦法了,看來要動用大招~

上面說白了就是讀 github 網站的資源不穩定,那麼我們就找一個 github 的代理資源吧。剛好我這認識一個

https://ghproxy.com/

支援對 github 資源代理加速,速度非常好,目前是的。

下面是應用加速代理

打開檔案,這裡注意一下 ROS Melodic 用的是 python2

sudo gedit /usr/lib/python2.7/dist-packages/rosdep2/sources_list.py
           

找到函數

download_rosdep_data

,把變量 url 指派成

url = "https://ghproxy.com/" + url
           

修改後效果

def download_rosdep_data(url):
    """
    :raises: :exc:`DownloadFailure` If data cannot be
        retrieved (e.g. 404, bad YAML format, server down).
    """
    try:
        # http/https URLs need custom requests to specify the user-agent, since some repositories reject
        # requests from the default user-agent.
	    url = "https://ghproxy.com/" + url
        if url.startswith("http://") or url.startswith("https://"):
            url_request = request.Request(url, headers={'User-Agent': 'rosdep/{version}'.format(version=__version__)})
        else:
            url_request = url
        f = urlopen(url_request, timeout=DOWNLOAD_TIMEOUT)
        text = f.read()
        f.close()
        data = yaml.safe_load(text)
        if type(data) != dict:
            raise DownloadFailure('rosdep data from [%s] is not a YAML dictionary' % (url))
        return data
    except (URLError, httplib.HTTPException) as e:
        raise DownloadFailure(str(e) + ' (%s)' % url)
    except yaml.YAMLError as e:
        raise DownloadFailure(str(e))
           

打開下面的幾個檔案,在所有找到的

https://raw.githubusercontent.com

字元串前添加上

https://ghproxy.com/

儲存即可。

/usr/lib/python2.7/dist-packages/rosdistro/__init__.py
/usr/lib/python2.7/dist-packages/rosdep2/gbpdistro_support.py
/usr/lib/python2.7/dist-packages/rosdep2/sources_list.py
/usr/lib/python2.7/dist-packages/rosdep2/rep3.py
/usr/lib/python2.7/dist-packages/rosdistro/manifest_provider/github.py
           

不過,對于檔案

/usr/lib/python2.7/dist-packages/rosdep2/gbpdistro_support.py

裡函數 download_gbpdistro_as_rosdep_data 的輸入參數 gbpdistro_url 在應用前也需要補上加速位址

def download_gbpdistro_as_rosdep_data(gbpdistro_url, targets_url=None):
    """
    Download gbpdistro file from web and convert format to rosdep distro data.

    DEPRECATED: see REP137. This function will output
                (at least) one deprecation warning

    :param gbpdistro_url: url of gbpdistro file, ``str``
    :param target_url: override URL of platform targets file
    :raises: :exc:`DownloadFailure`
    :raises: :exc:`InvalidData` If targets file does not pass cursory
     validation checks.
    """
    # we can convert a gbpdistro file into rosdep data by following a
    # couple rules
    # will output a warning
    targets_data = download_targets_data(targets_url=targets_url)
    gbpdistro_url = "https://ghproxy.com/" + gbpdistro_url
    try:
        f = urlopen(gbpdistro_url, timeout=DOWNLOAD_TIMEOUT)
        text = f.read()
        f.close()
        gbpdistro_data = yaml.safe_load(text)
        # will output a warning
        return gbprepo_to_rosdep_data(gbpdistro_data,
                                      targets_data,
                                      gbpdistro_url)
    except Exception as e:
        raise DownloadFailure('Failed to download target platform data '
                              'for gbpdistro:\n\t' + str(e))
           

好了,大招都使完了,看看效果

~$ rosdep update
reading in sources list data from /etc/ros/rosdep/sources.list.d
Hit https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/osx-homebrew.yaml
Hit https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml
Hit https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/python.yaml
Hit https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/ruby.yaml
Hit https://raw.githubusercontent.com/ros/rosdistro/master/releases/fuerte.yaml
Query rosdistro index https://ghproxy.com/https://raw.githubusercontent.com/ros/rosdistro/master/index-v4.yaml
Skip end-of-life distro "ardent"
Skip end-of-life distro "bouncy"
Skip end-of-life distro "crystal"
Skip end-of-life distro "dashing"
Skip end-of-life distro "eloquent"
Add distro "foxy"
Add distro "galactic"
Skip end-of-life distro "groovy"
Add distro "humble"
Skip end-of-life distro "hydro"
Skip end-of-life distro "indigo"
Skip end-of-life distro "jade"
Skip end-of-life distro "kinetic"
Skip end-of-life distro "lunar"
Add distro "melodic"
Add distro "noetic"
Add distro "rolling"
updated cache in /home/if/.ros/rosdep/sources.cache
           

8.測試一下環境

分别按順序獨立在各自的終端裡執行下邊的這幾個指令

// 啟動 ROS 核心
roscore

// 啟動 ROS 仿真平台
rosrun turtlesim turtlesim_node

// 接收方向鍵按鍵資訊
rosrun turtlesim turtle_teleop_key
           

在最後的終端裡按着鍵盤方向鍵就可以控制仿真視窗裡的小烏龜動起來了

踩坑之旅:配置 ROS 環境

如果你能順利走到這裡,說明 ROS 環境可以正常跑了。

後記:

其實寫這篇筆記的過程中,除了首次配置環境,還穿插了很多任務,導緻配置的過程一直停滞不前,筆記也落下那麼久才發出來。如果你在對照這篇筆記來配置 ROS 環境的時候也碰到了其它的問題,歡迎留言提出來,或者添加我的微信公衆号englyf給我留言?畢竟部落格不一定一直線上。