ROS課程講義--2 Catkin工作空間和Package
2.2 Catkin工作空間
Catkin工作空間是建立、修改、編譯catkin軟體包的目錄。catkin的工作空間,直觀的形容就是一個倉庫,裡面裝載著ROS的各種專案工程,便於系統組織管理呼叫。在視覺化圖形介面裡是一個資料夾。我們自己寫的ROS程式碼通常就放在工作空間中,本節就來介紹catkin工作空間的結構。
2.2.1 初始化catkin工作空間
介紹完catkin編譯系統,我們來建立一個catkin的工作空間。首先我們要在計算機上建立一個初始的catkin_ws/
路徑,這也是catkin工作空間結構的最高層級。輸入下列指令,完成初始建立。
$ mkdir -p ~/catkin_ws/src $ cd ~/catkin_ws/ $ catkin_make #初始化工作空間
第一行程式碼直接建立了第二層級的資料夾src,這也是我們放ROS軟體包的地方。第二行程式碼使得程序進入工作空間,然後再是catkin_make。
注意:1. catkin_make命令必須在工作空間這個路徑上執行 2.原先的初始化命令catkin_init_workspace仍然保留
2.2.2 結構介紹
catkin的結構十分清晰,具體的catkin工作空間結構圖如下。初看起來catkin工作空間看起來極其複雜,其實不然,catkin工作空間的結構其實非常清晰。
在工作空間下用tree命令,顯示檔案結構。
$ cd ~/catkin_ws $ sudo apt install tree $ tree
結果為:
─ build │ ├── catkin │ │ └── catkin_generated │ │ └── version │ │ └── package.cmake │ ├── ...... │ ├── catkin_make.cache │ ├── CMakeCache.txt │ ├── CMakeFiles │ │ ├── ...... ├── devel │ ├── env.sh │ ├── lib │ ├── setup.bash │ ├── setup.sh │ ├── _setup_util.py │ └── setup.zsh └── src └── CMakeLists.txt -> /opt/ros/kinetic/share/catkin/cmake/toplevel.cmake
通過tree命令可以看到catkin工作空間的結構,它包括了src
、build
、devel
三個路徑,在有些編譯選項下也可能包括其他。但這三個資料夾是catkin編譯系統預設的。它們的具體作用如下:
- src/: ROS的catkin軟體包(原始碼包)
- build/: catkin(CMake)的快取資訊和中間檔案
- devel/: 生成的目標檔案(包括標頭檔案,動態連結庫,靜態連結庫,可執行檔案等)、環境變數
在編譯過程中,它們的工作流程如圖:
後兩個路徑由catkin系統自動生成、管理,我們日常的開發一般不會去涉及,而主要用到的是src資料夾,我們寫的ROS程式、網上下載的ROS原始碼包都存放在這裡。
在編譯時,catkin編譯系統會遞迴的查詢和編譯src/
下的每一個原始碼包。因此你也可以把幾個原始碼包放到同一個資料夾下,如下圖所示:
小結
catkin工作空間基本就是以上的結構,package是catkin工作空間的基本單元,我們在ROS開發時,寫好程式碼,然後catkin_make,系統就會完成所有編譯構建的工作。至於更詳細的package內容,我們將在下節繼續介紹。
2.3 Package軟體包
在1.6節我們曾對package軟體包進行了分類,分別介紹了二進位制包和原始碼包。而ROS中的package的定義更加具體,它不僅是Linux上的軟體包,更是catkin編譯的基本單元,我們呼叫catkin_make
編譯的物件就是一個個ROS的package,也就是說任何ROS程式只有組織成package才能編譯。所以package也是ROS原始碼存放的地方,任何ROS的程式碼無論是C++還是Python都要放到package中,這樣才能正常的編譯和執行。
一個package可以編譯出來多個目標檔案(ROS可執行程式、動態靜態庫、標頭檔案等等)。
2.3.1 package結構
一個package下常見的檔案、路徑有:
├── CMakeLists.txt #package的編譯規則(必須)
├── package.xml #package的描述資訊(必須)
├── src/ #原始碼檔案
├── include/ #C++標頭檔案
├── scripts/ #可執行指令碼
├── msg/ #自定義訊息
├── srv/ #自定義服務
├── models/ #3D模型檔案
├── urdf/ #urdf檔案
├── launch/ #launch檔案
其中定義package的是CMakeLists.txt
和package.xml
,這兩個檔案是package中必不可少的。catkin編譯系統在編譯前,首先就要解析這兩個檔案。這兩個檔案就定義了一個package。
- CMakeLists.txt: 定義package的包名、依賴、原始檔、目標檔案等編譯規則,是package不可少的成分
- package.xml: 描述package的包名、版本號、作者、依賴等資訊,是package不可少的成分
- src/: 存放ROS的原始碼,包括C++的原始碼和(.cpp)以及Python的module(.py)
- include/: 存放C++原始碼對應的標頭檔案
- scripts/: 存放可執行指令碼,例如shell指令碼(.sh)、Python指令碼(.py)
- msg/: 存放自定義格式的訊息(.msg)
- srv/: 存放自定義格式的服務(.srv)
- models/: 存放機器人或模擬場景的3D模型(.sda, .stl, .dae等)
- urdf/: 存放機器人的模型描述(.urdf或.xacro)
- launch/: 存放launch檔案(.launch或.xml)
通常ROS檔案組織都是按照以上的形式,這是約定俗成的命名習慣,建議遵守。以上路徑中,只有CMakeLists.txt
和package.xml
是必須的,其餘路徑根據軟體包是否需要來決定。
2.3.2 package的建立
建立一個package需要在catkin_ws/src
下,用到catkin_create_pkg
命令,用法是:catkin_create_pkg package depends
其中package是包名,depends是依賴的包名,可以依賴多個軟體包。
例如,新建一個package叫做test_pkg
,依賴roscpp、rospy、std_msgs(常用依賴)。
$ catkin_create_pkg test_pkg roscpp rospy std_msgs
這樣就會在當前路徑下新建test_pkg
軟體包,包括:
├── CMakeLists.txt
├── include
│ └── test_pkg
├── package.xml
└── src
catkin_create_pkg
幫你完成了軟體包的初始化,填充好了CMakeLists.txt
和package.xml
,並且將依賴項填進了這兩個檔案中。
2.3.3 package相關命令
rospack
rospack是對package管理的工具,命令的用法如下:
rostopic命令 | 作用 |
---|---|
rospack help |
顯示rospack的用法 |
rospack list |
列出本機所有package |
rospack depends [package] |
顯示package的依賴包 |
rospack find [package] |
定位某個package |
rospack profile |
重新整理所有package的位置記錄 |
以上命令如果package預設,則預設為當前目錄(如果當前目錄包含package.xml)
roscd
roscd
命令類似與Linux系統的cd
,改進之處在於roscd
可以直接cd
到ROS的軟體包。
rostopic命令 | 作用 |
---|---|
roscd [pacakge] |
cd到ROS package所在路徑 |
rosls
rosls
也可以視為Linux指令ls
的改進版,可以直接ls
ROS軟體包的內容。
rosls命令 | 作用 |
---|---|
rosls [pacakge] |
列出pacakge下的檔案 |
rosdep
rosdep
是用於管理ROS package依賴項的命令列工具,用法如下:
rosdep命令 | 作用 |
---|---|
rosdep check [pacakge] |
檢查package的依賴是否滿足 |
rosdep install [pacakge] |
安裝pacakge的依賴 |
rosdep db |
生成和顯示依賴資料庫 |
rosdep init |
初始化/etc/ros/rosdep中的源 |
rosdep keys |
檢查package的依賴是否滿足 |
rosdep update |
更新本地的rosdep資料庫 |
一個較常使用的命令是rosdep install --from-paths src --ignore-src --rosdistro=kinetic -y
,用於安裝工作空間中src
路徑下所有package的依賴項(由pacakge.xml檔案指定)。