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
這時候,工作區下面會出現 build 和 devel 兩個文件夾以及 .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、功能包編譯
前面說過,一個工作空間可以有多個功能包,因此編譯功能包有兩種方式:
- 編譯工作空間內的所有功能包;
- 編譯工作空間內的指定功能包;
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++,並深入框架層面,研究其原理。