ROS之初見Hello World

前言

最近在玩ROS,筆記中斷了一段時間。

ROS即Robot Operating System,機器人作業系統,是一個開源框架,主力語言是C++和python,提供了硬體抽象、設備驅動、庫函數、可視化、消息傳遞和軟體包管理等諸多功能。

咱先拋開機器人不談,ROS的設計思路還是值得學習的,它內部的最小運行單位是節點(node),運行時,啟動很多節點,每個節點完成一種特定的功能,且每個節點直接可以通訊。相似功能的節點組成一個包(package)。從原理上講,一個節點就是一個進程,多個節點的通訊就是進程間的通訊,而ROS中的進程間通訊不是傳統伺服器中的管道、消息隊列這些,而是基於TCP/IP協議的通訊。

ROS框架中的進程間通訊的方式有多種,像發布-訂閱者模式和流行的開源中間件是一樣的,其底層協議也是TCP和RPC,這個在後面文章中會詳細說明。

先來熟悉一下ROS,就先從Hello World開始吧!!!

1、創建工作空間

在需要防止程式碼的地方打開命令行

#新建工作空間文件夾
mkdir catkin_ws && cd catkin_ws
#新建src文件夾
mkdir src
#初始化src目錄,生成CMakeLists.txt,為功能包編譯配置
cd src
catkin_init_workspace

這時候src目錄下會出現CMakeLists.txt,指令提示如下:

Creating symlink "/home/eco/project/MyCode/test_ws/src/CMakeLists.txt" pointing to "/opt/ros/kinetic/share/catkin/cmake/toplevel.cmake"

可知,這個CMakeLists.txt只是一個ROS庫中的鏈接,後面不要更改它

#回到工作空間,並對工作空間進行一次編譯
cd ..
catkin_make

這時候,工作區下面會出現 builddevel 兩個文件夾以及 .catkin_workspace 文件

#配置環境變數,使新建的工作空間可用
source devel/setup.bash
#查看配置的變數
echo $ROS_PACKAGE_PATH

到此,一個新的ROS工作空間已經創建完成

一個工作空間可以包含多個功能包,所有的功能包都在工作空間的src目錄下

2、創建功能包

現在,我們想創建一個功能包,名稱是 hello_world

#到工作空間的src目錄下創建功能包
cd src
catkin_create_pkg hello_world

這時,工作空間的 src 目錄下出現 hello_world 文件夾,這個名稱就是功能包的名稱及其唯一標誌符,功能包創建完成

3、編寫功能包源程式碼

本次,我們編寫一個能列印 hello world 的程式

我們在功能包的目錄新建一個 src 文件夾,用於存放C++的源程式碼,這個不是必須的,但是出於規範考慮,最好這樣做,便於組織程式碼結構

cd hello_world
mkdir src && cd src
#創建程式碼文件
touch my_hello_world_node.cpp

在 my_hello_world_node.cpp 中編寫程式碼

#include "ros/ros.h"
//ros.h是ROS提供的C++客戶端庫,後面需要在編譯配置中添加依賴庫roscpp
 
int main(int argc,char **argv) 
{
    //初始化ros節點並知名節點名稱
    //程式運行後,ros的計算圖中被註冊為hello_node名稱標識的節點
  	ros::init(argc,argv,"hello_node");
    //聲明一個ros節點句柄,初始化ros節點必須的
  	ros::NodeHandle nh;
    //ROS_INFO_STREAM是roscpp庫中的列印資訊方法,這裡列印一個字元串
  	ROS_INFO_STREAM("hello world!!!");
}

4、功能包編譯配置

這時候的工作空間是有兩個 CMakeLists.txt 的,工作空間下的是鏈接,不要更改,修改功能包中的CMakeLists.txt,本次修改的內容有下面幾種

4.1、添加依賴項

因為程式碼中用到了 ros/ros.h ,因此需要 roscpp 庫

find_package(catkin REQUIRED COMPONENTS roscpp)

include_directories(
# include
 ${catkin_INCLUDE_DIRS}
)

修改功能包目錄下的 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、聲明可執行文件

add_executable(my_hello_world_node src/my_hello_world_node.cpp)
#鏈接時需要鏈接哪些庫,在find_package中定義
target_link_libraries(my_hello_world_node ${catkin_LIBRARIES})

至此,功能包的編譯配置完成

5、功能包編譯

前面說過,一個工作空間可以有多個功能包,因此編譯功能包有兩種方式:

  1. 編譯工作空間內的所有功能包;
  2. 編譯工作空間內的指定功能包;

5.1、編譯所有功能包

cd ~/project/catkin_ws/
catkin_make

5.2、編譯指定功能包

使用 DCATKIN_WHITELIST_PACKAGES 參數指定

cd ~/project/catkin_ws
catkin_make -DCATKIN_WHITELIST_PACKAGES="hello_world"

6、功能包啟動運行

先啟動ROS節點管理器,這個是所有節點運行的基礎

roscore

然後激活工作空間

cd ~/project/catkin_ws
source devel/setup.bash

最後啟動功能包中的節點

rosrun hello_world my_hello_world_node

rosrun 指令的第一個參數是功能包名,第二個參數是需要啟動的節點名

輸出

[ INFO] [1620370500.474021642]: hello world!!!

到此,第一個程式完成,後面會繼續學習ROS和C++,並深入框架層面,研究其原理。

Tags: