ROS學習筆記三:編寫第一個ROS節點程序


在編寫第一個ROS節點程序之前需要創建工作空間(workspace)和功能包(package)。


一、創建工作空間(workspace)

創建一個catkin_ws:

#注意:如果使用sudo一次性創建多個目錄,則這多個目錄屬主都為root,若是非root用戶創建的ROS,則無法在root目錄創建工作空間
sudo mkdir -p ~/dev/catkin_ws/src
cd ~/dev/catkin_ws/src
catkin_init_workspace

當我們創建工作空間文件夾后,里面並沒有功能包,只有CMakeList.txt。下一步是編譯工作空間,使用下面命令:

cd ~/dev/catkin_ws
catkin_make

現在,如果你輸入ls -l命令,可以看到上面命令創建的新文件夾,分別是“build”和一個“devel”文件夾:

zlkj@ubuntu:~/dev/catkin_ws$ ls -l
total 12
drwxrwxr-x 7 zlkj zlkj 4096 Mar 19 12:10 build
drwxrwxr-x 3 zlkj zlkj 4096 Mar 19 12:10 devel
drwxrwxr-x 2 zlkj zlkj 4096 Mar 19 11:23 src

zlkj@ubuntu:~/dev/catkin_ws/build$ ls -l
total 64
drwxrwxr-x 3 zlkj zlkj  4096 Mar 19 12:10 catkin
drwxrwxr-x 4 zlkj zlkj  4096 Mar 19 12:10 catkin_generated
-rw-rw-r-- 1 zlkj zlkj     0 Mar 19 12:10 CATKIN_IGNORE
-rw-rw-r-- 1 zlkj zlkj   125 Mar 19 12:10 catkin_make.cache
-rw-rw-r-- 1 zlkj zlkj 16071 Mar 19 12:10 CMakeCache.txt
drwxrwxr-x 9 zlkj zlkj  4096 Mar 19 12:10 CMakeFiles
-rw-rw-r-- 1 zlkj zlkj  7365 Mar 19 12:10 cmake_install.cmake
-rw-rw-r-- 1 zlkj zlkj   284 Mar 19 12:10 CTestTestfile.cmake
drwxrwxr-x 3 zlkj zlkj  4096 Mar 19 12:10 gtest
-rw-rw-r-- 1 zlkj zlkj  8578 Mar 19 12:10 Makefile
drwxrwxr-x 2 zlkj zlkj  4096 Mar 19 12:10 test_results

zlkj@ubuntu:~/dev/catkin_ws/devel$ ls -l
total 36
-rwxr-xr-x 1 zlkj zlkj   506 Mar 19 12:10 env.sh
drwxrwxr-x 2 zlkj zlkj  4096 Mar 19 12:10 lib
-rw-r--r-- 1 zlkj zlkj   260 Mar 19 12:10 setup.bash
-rw-r--r-- 1 zlkj zlkj  2542 Mar 19 12:10 setup.sh
-rwxr-xr-x 1 zlkj zlkj 12378 Mar 19 12:10 _setup_util.py
-rw-r--r-- 1 zlkj zlkj   270 Mar 19 12:10 setup.zsh

可以看到在devel目錄下,有很多setup.*sh文件,讀取這些文件中的任何一個都會將當前工作空間的環境變量置於所有環境變量的最上層。如果我們打開這些文件會發現,最終都是要讀取setup.bash文件,這個文件中定義了catkin_ws空間所需要的環境變量。


讀取setup.bash文件:

source devel/setup.bash

確認已經加載好catkin工作空間環境變量:

echo $ROS_PACKAGE_PATH

//顯示出:
/home/zlkj/catkin_ws/src:/opt/ros/indigo/share:/opt/ros/indigo/stacks

這時ROS的工作空間已經創建好了。


總結:

初始化ROS的catkin工作空間:catkin_init_workspace

編譯ROS的catkin工作空間:catkin_make

讀取當前catkin工作空間的環境變量:source devel/setup.bash

驗證ROS工作空間的環境變量加載成功:echo $ROS_PACKAGE_PATH


二、創建功能包(package)

使用catkin_create_pkg命令行工具在之前創建的工作空間創建新的功能包:

cd ~/dev/catkin_ws/src
catkin_create_pkg amin std_msgs roscpp

其實,這個功能包創建命令沒有做太多工作,它只不過創建了一個存放這個功能包的目錄(也就是我所創建的功能包amin),並在amin那個目錄下生成了兩個配置文件。

  • 第一個配置文件,叫做 package.xml,稱為清單文件。
  • 第二個文件,叫做 CMakeLists.txt,是一個 Cmake 的腳本文件,Cmake 是一個符合工業標准的跨平台編譯系統。這個文件包含了一系列的編譯指令,包括應該生成哪種可執行文件,需要哪些源文件,以及在哪里可以找到所需的頭文件和鏈接庫。當然,這個文件表明 catkin 在內部使用了 Cmake。

catkin_create_pkg命令的格式包括功能包的名稱和依賴項。在上面示例中,依賴項為std_msgs和roscpp。如以下命令行所示:

catkin_create_pkg [package_name] [depend1] [depend2] [depend3]

這些依賴項包括:

  • std_msgs 包含了常見消息類型,表示基本數據類型和其他基本的消息構造,如多維數組。
  • roscpp 使用C++實現ROS的各種功能。它提供了一個客戶端庫,讓C++程序員能夠調用這些接口快速完成與ROS的主題、服務和參數相關的開發工作。

注意:ROS 功能包的命名遵循一個命名規范,只允許使用小寫字母、數字和下划線,而且首字符必須是一個小寫字母。一些 ROS工具,包括 catkin,不支持那些不遵循此命名規范的功能包。


三、編寫ROS節點程序

編寫一個簡單的ros節點程序,命名為hello.cpp。這個名為 hello.cpp 的源文件也存放在你的功能包 amin文件夾中 , 挨着 package.xml 和 CMakeLists.txt。

注意:一些在線教程建議在你的功能包目錄中創建 src 目錄來存放 C ++源文件。這個附加的組織結構可能是有益的,特別是對於那些含有多種類型文件的較大的功能包,但它不是嚴格必要的。

ROS節點程序如下:

#include <ros/ros.h>

int main (int argc, char **argv) 
{
  ros::init(argc, argv, "hello") ;
  ros::NodeHandle nh;
  ROS_INFO_STREAM("Hello, ROS!") ;
}

四、編譯Hello.cpp程序

我們該如何編譯和運行這個程序呢?這些交給ROS的catkin編譯系統來處理。

第一步:聲明依賴庫

首先,我們需要聲明程序所依賴的其他功能包。對於 c++程序而言,此步驟是必要的,以確保 catkin 能夠向 c++編譯器提供合適的標記來定位編譯功能包所需的頭文件和鏈接庫。

為了給出依賴庫,需要編輯功能目錄下的 CMakeLists.txt 與 package.xml 文件,通過使用build_depend (編譯依賴)和 run_depend(運行依賴)兩個關鍵字實現,格式如下:

<build_depend>package-name</build_depend>
<run_depend>package-name</run_depend>

不過這一步可以省略,因為在創建功能包說明依賴項的同時,系統自動聲明了依賴庫,除非創建時未說明依賴項。

使用rospack depend1 amin可以查看直接功能包的直接依賴。在很多情況下,我們會遇到依賴的依賴,即間接依賴。例如amin的依賴文件roscpp也有其他依賴。如果我們使用rospack depends amin,則會列出amin功能包的所有依賴文件。


第二步:聲明可執行文件

接下來,我們需要在 CMakeLists.txt 中添加兩行,來聲明我們需要創建的可執行文件。其一般形式是:

add_executable(executable-name source-files)
target_link_libraries(executable-name ${catkin_LIBRARIES})
  • 第一行聲明了我們想要的可執行文件的文件名,以及生成此可執行文件所需的源文件列表。如果你有多個源文件,把它們列在此處,並用空格將其區分開。
  • 第二行告訴 Cmake 當鏈接此可執行文件時需要鏈接哪些庫(在上面的 find_package 中定義)。如果你的包中包括多個可執行文件,為每一個可執行文件復制和修改上述兩行代碼。

在本例程中,我們需要一個名為 hello 的可執行文件,它通過名為 hello.cpp 的源文件編譯而來。所以我們需要添加如下兩行代碼到 CMakeLists.txt 文件中 include_directories(include ${catkin_INCLUDE_DIRS}) 之后:

add_executable(hello hello.cpp)
target_link_libraries(hello ${catkin_LIBRARIES})

第三步:編譯工作區

利用catkin_make這個命令進行編譯,注意必須在你的工作空間目錄運行。

cd ~/dev/catkin_ws
catkin_make

運行完后會在 ~/dev/catkin_ws/devel/amin 目錄下生產 hello 這個可執行文件。下圖為運行的結果。


五、執行hello程序

首先要啟動 roscore:這個程序是一個節點,節點需要一個節點管理器才可以正常運行。啟動節點管理器的命令:

roscore

啟動完節點管理器后,執行名為 setup.bash 的腳本文件,它是 catkin_make 在你工作區的 devel 子目錄下生成的。這個自動生成的腳本文件設置了若干環境變量,從而使 ROS 能夠找到你創建的功能包和新生成的可執行文件。(也就是將程序注冊)

source devel/setup.bash

最后一步,運行節點,用命令:使用格式為"rosrun package-name executable-name" ,package-name 為功能包名稱, executable-name為可執行文件名稱。

rosrun amin hello


運行結果如圖:

這樣一個簡單的ROS程序就完成了。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM