ROS入門筆記(九):編寫ROS的第一個程序hello world(重點)
1 Catkin工作空間
-
工作空間(workspace)是一個存放工程開發相關文件的文件夾。
src:代碼空間(Source Space) build:編譯空間(Build Space) devel:開發空間(Development Space) install:安裝空間(Install Space) -
Catkin工作空間是創建、修改、編譯catkin軟件包的目錄。catkin的工作空間,直觀的形容就是一個倉庫,里面裝載着ROS的各種項目工程,便於系統組織管理調用。在可視化圖形界面里是一個文件夾。
-
我們自己寫的ROS代碼通常就放在工作空間中,本節就來介紹catkin工作空間的結構。
1.1 創建catkin工作空間
創建一個 catkin 工作空間:
$ mkdir -p ~/catkin_ws/src # 創建了第二層級的文件夾src,這是放ROS軟件包的地方
$ cd ~/catkin_ws/src # 進入工作空間,catkin_make必須在工作空間這個路徑上執行
$ catkin_init_workspace # 初始化src目錄,生成的CMakeLists.txt為功能包編譯配置
1.2 編譯工作空間
$ cd ~/catkin_ws # 回到工作空間,catkin_make必須在工作空間下執行;
$ catkin_make # 開始編譯,調用系統自動完成編譯和鏈接過程,構建生成目標文件
注意: catkin編譯之前需要回到工作空間目錄,catkin_make在其他路徑下編譯不會成功。
編譯完成后,如果有新的目標文件產生(原來沒有),那么一般緊跟着要source刷新環境,使得系統能夠找到剛才編譯生成的ROS可執行文件。這個細節比較容易遺漏,致使后面出現可執行文件無法打開等錯誤。
catkin_make命令也有一些可選參數,例如:
catkin_make [args]
-h, --help 幫助信息
-C DIRECTORY, --directory DIRECTORY
工作空間的路徑 (默認為 '.')
--source SOURCE src的路徑 (默認為'workspace_base/src')
--build BUILD build的路徑 (默認為'workspace_base/build')
--use-ninja 用ninja取代make
--use-nmake 用nmake取'make
--force-cmake 強制cmake,即使已經cmake過
--no-color 禁止彩色輸出(只對catkin_make和CMake生效)
--pkg PKG [PKG ...] 只對某個PKG進行make
--only-pkg-with-deps ONLY_PKG_WITH_DEPS [ONLY_PKG_WITH_DEPS ...]
將指定的package列入白名單CATKIN_WHITELIST_PACKAGES,
之編譯白名單里的package。該環境變量存在於CMakeCache.txt。
--cmake-args [CMAKE_ARGS [CMAKE_ARGS ...]]
傳給CMake的參數
--make-args [MAKE_ARGS [MAKE_ARGS ...]]
傳給Make的參數
--override-build-tool-check
用來覆蓋由於不同編譯工具產生的錯誤
注意, 對於 Python 3 用戶,在一個空的 catkin 工作空間中第一次運行 catkin_make的命令應為:
$ catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
這將會配置 catkin_make 使用 Python 3.你可以在隨后的構建中只使用 catkin_make。
1.3 設置環境變量
另外,如果你查看一下當前目錄應該能看到 'build' 和 'devel' 這兩個文件夾。在 'devel' 文件夾里面你可以看到幾個 setup.*sh 文件。source 這些文件中的任何一個都可以將當前工作空間設置在ROS工作環境的最頂層。接下來首先 source 一下新生成的 setup.*sh 文件:
$ source devel/setup.bash # 刷新壞境
1.4 檢查環境變量
要想保證工作空間已配置正確,需確保ROS_PACKAGE_PATH環境變量包含你的工作空間目錄,采用以下命令查看:
$ echo $ROS_PACKAGE_PATH
# 出現 /home/<youruser>/catkin_ws/src:/opt/ros/kinetic/share
到此你的工作環境已經搭建完成。
創建好了一個ROS的工作空間了,接下來就是在catkin_ws工作空間下的src目錄下新建功能包並進行功能包程序。
2 創建功能包
同一個工作空間下,不允許存在同名功能包不同工作空間下,允許存在同名功能包
$ catkin_create_pkg <package_name>[depend1] [depend2] [depend3] # 創建功能包,和依賴項
#在catkin_ws/src/下創建取名為hello_world的功能包
# ROS功能包命名規范:只允許使用小寫字母、數字和下划線,
# 且首字符必須為一個小寫字母。
$ cd ~/catkin_ws/src
$ catkin_create_pkg hello_world
3 編寫功能包的源代碼
以c++代碼作為示范,一些在線教程建議在你的功能包目錄中創建src目錄用來存放c++源文件,這個附加的組織結構是很有益處的,特別是對含有很多種類型文件的大型功能包,不過不是嚴格必要的。出於編程規范,我建議把c++源文件放在功能包中的src目錄下。
第一步,在hello_world目錄下新建src目錄;

第二步,再在新建的src目錄下新建一個my_hello_world_node.cpp文件;

第三步,文本編輯器gedit打開my_hello_world_node.cpp文件,並輸入如下內容;
//包含頭文件ros/ros.h,ROS提供的C++客戶端庫,在后面的編譯配置中要添加相應的依賴庫roscpp
#include "ros/ros.h"
int main(int argc,char **argv)
{
ros::init(argc,argv,"hello_node"); //初始化ros節點;並指明節點的名稱為 hello_node
ros::NodeHandle n; //聲明一個ros節點的句柄;
//調用了roscpp庫提供的方法ROS_INFO_STREAM來打印信息。這里打印字符串"hello world!"。
ROS_INFO_STREAM("hello world!");
}
4 功能包的編譯配置
4.1 在package.xml中添加功能包依賴
在package.xml中添加roscpp依賴庫;
用文本編輯器gedit打開功能包目錄下的package.xml文件,找到這樣一句話<buildtool_depend>catkin</buildtool_depend>,在這句話的下面添加如下內容:
<build_depend>roscpp</build_depend>
<build_export_depend>roscpp</build_export_depend>
<exec_depend>roscpp</exec_depend>

4.2 在CMakeLists.txt添加編譯選項
4.2.1 聲明依賴庫
對於我們的my_hello_world_node.cpp程序來說,我們包含了<ros/ros.h>這個庫,因此我們需要添加名為roscpp的依賴庫。
第一步,在CMakeLists.txt中添加roscpp依賴庫;
用文本編輯器gedit打開功能包目錄下的CMakeLists.txt文件,在find_package(catkin REQUIRED ...)字段中添加roscpp,添加后的字段如下:
find_package(catkin REQUIRED COMPONENTS roscpp)

第二步,在CMakeLists.txt中找到include_directories(...)字段,去掉${catkin_INCLUDE_DIRS}前面的注釋,如下:
include_directories(
# include
${catkin_INCLUDE_DIRS}
)

4.2.2 聲明可執行文件
在CMakeLists.txt中添加兩句,來聲明我們需要創建的可執行文件;一般在文件最后一行添加。
add_executable(my_hello_world_node src/my_hello_world_node.cpp)
target_link_libraries(my_hello_world_node ${catkin_LIBRARIES})
第一行聲明了我們想要的可執行文件的文件名,以及生成此可執行文件所需的源文件列表。如果你有多個源文件,把它們列在此處,並用空格將其區分開。
第二行告訴 Cmake 當鏈接此可執行文件時需要鏈接哪些庫(在上面的 find_package 中定義)。如果你的包中包含多個可執行文件,為每一個可執行文件復制和修改上述兩行代碼。

5 編譯功能包
兩種編譯方式,一種是編譯工作空間內的所有功能包,另一種是編譯工作空間內的指定功能包;
5.1 方法一
編譯工作空間內的所有功能包:
$ cd ~/catkin_ws # 回到工作空間,catkin_make必須在工作空間下執行;
$ catkin_make # 開始編譯,調用系統自動完成編譯和鏈接過程,構建生成目標文件
$ source ~/catkin_ws/devel/setup.bash # 刷新環境
編譯完成后,如果有新的目標文件產生(原來沒有),那么一般緊跟着要source刷新環境,使得系統能夠找到剛才編譯生成的ROS可執行文件。
5.2 方法二
編譯工作空間內的指定功能包:
其實就是加入參數 -DCATKIN_WHITELIST_PACKAGES=” ”,在雙引號中填入需要編譯的功能包名字,用空格分割。
$ cd ~/catkin_ws
$ catkin_make -DCATKIN_WHITELIST_PACKAGES="hello_world"
$ source ~/catkin_ws/devel/setup.bash # 激活catkin_ws工作空間
6 啟動功能包
第一步,打開命令行終端,輸入命令:
用roscore命令來啟動ROS節點管理器,ROS節點管理器是所有節點運行的基礎。
$ roscore # 啟動ROS節點管理器
第二步,再打開一個命令行終端,輸入如下命令:
用rosrun <package_name> <node_name>啟動功能包中的節點;
$ source ~/catkin_ws/devel/setup.bash # 激活catkin_ws工作空間
$ rosrun hello_world my_hello_world_node # 啟動功能包中的節點
第三步,看到輸出hello world!,說明程序已經正常執行了,按照我們的設計程序正常打印后會自動結束。

