一 ROS基礎教程
ROS教程
這是小弟的學習筆記,有錯求請拍,多指教,謝謝
一 ROS基礎知識
ROS檔案系統介紹
1.功能包集stack
ROS軟體包集合,像Navigation Stack,屬於導航軟體包集合,包含了與導航有關的軟體包,例如地圖軟體包,路徑規劃軟體包,TF座標軟體包,move_base移動控制軟體包等,一整個stack下載後可以任意使用其中的軟體包,每個軟體包都實現其中一個或者好幾個小功能,多個軟體包組成集合實現一個完整的大的功能
http://wiki.ros.org/navigation
2.軟體包package
ROS程式的單元,每個軟體包都包含程式庫,可執行檔案,指令碼。圖中列出的learning_joy軟體包,包含編譯配置檔案CMakeLists.txt,include標頭檔案庫,launch啟動指令碼資料夾,package.xml軟體包概況描述檔案,src程式原始碼庫
軟體包檔案詳解:
1)編譯配置檔案CMakeLists.txt, 使用cmake編譯時要寫的
2)include標頭檔案庫,如果只是使用ROS中附帶有的標頭檔案,include這個資料夾可能會是空的,但是系統會自動建立,當以後需要用到自己的標頭檔案或者新增別人的標頭檔案時,把標頭檔案新增到該資料夾裡便可正確使用
3)launch啟動指令碼資料夾,裡邊包含了字尾名為launch的啟動指令碼,功能是一次性啟動多個節點,至於什麼是節點,以後會詳細講
4)清單檔案package.xml,包含軟體包的相關資訊的描述,包括版本號,開發者資訊,各軟體包之間的依賴關係
5)src程式原始碼庫,存放編寫的cpp或者python原始碼檔案
ROS基本框架
1.節點node
節點是ROS機器人系統裡任何操作的單元,可以理解為每一個節點可以實現一個小功能,一個機器人工程就是由多個節點組成的,節點與節點之間可以相互通訊,相互協調完成工作,比如人手臂的運動,運動指令從大腦發出,經過肩膀,手肘,手腕,最後再到手指,觸感的資訊則是反過來傳遞,每個關節理解成一個節點,它們之間可能是相互傳遞訊息,也可能是一個傳送訊息,一個接收訊息;通常,我們在程式設計的時候就是編寫一個個節點
2.話題topic
話題是ROS裡的一個通訊方法,topic裡包含了訊息的名稱,型別,內容,節點可以釋出或者訂閱某個或某幾個話題,以此達到傳遞的目的;話題有兩個重要的性質:a.話題的釋出頻率;b.話題的訊息型別
3.釋出者和訂閱者publisher & subscriber
ROS裡的節點node可能是釋出者或者是訂閱者,甚至兩者都兼備,釋出者就是釋出topic的節點,訂閱者就是訂閱topic的節點,釋出者以一定的訊息型別格式在ROS伺服器上釋出訊息,訂閱者則根據話題名稱在伺服器上訂閱訊息,訊息型別在ROSwiki上有詳細定義
http://wiki.ros.org/std_msgs
還有一些常用軟體包內需要的訊息型別,如:
common_msgs 檢視各類訊息型別
geometry_msgs 運動幾何學相關的訊息型別,包括速度,加速度等
sensor_msgs 感測器相關的訊息型別,包括鐳射雷達,點雲,IMU慣性測量單元,JoySticks遙控手柄,影象等
4.理解ROS的通訊流程
- master 節點,管理所有的節點,每個節點都需要先向 master 節點註冊, master 節點會讓釋出者和訂閱
者進行匹配;所以每次啟動ROS時,都需要先開啟master節點
[email protected]:~$ roscore
- 釋出者和訂閱者之間通過話題來通訊時,資訊不通過 master
- 釋出者釋出一個話題,訂閱者進行訂閱
- 流程:
1 )訂閱者傳送建立連結請求
2 )釋出者進行反饋,確認連結
3 )訂閱者請求 topic 的資料
4 )釋出者傳送 topic 資料
建立和編譯 ROS 軟體包
1.建立軟體包
1)建立工作空間
在編寫任何ROS程式之前,都應該先建立一個工作空間workspace,因為使用catkin環境,所以一般網上很多教程都會將工作空間命名為catkin_ws,但其實可以任意命名,工作空間就是一個在~/home目錄下的資料夾。工作空間下是存放軟體包的,所以一般而言,工作空間不需要建立太多,除非某個工程特別龐大,才需要為它獨立建立工作空間
建立工作空間目錄:~$ mkdir -p catkin_ws/src
檢視資料夾目錄:tree catkin_ws/
編譯軟體包命令:~/catkin_ws$ catkin_make
即使沒有原始碼檔案,工作空間也是可以通過編譯的,編譯命令要在工作空間資料夾目錄下執行,系統會自動生成build資料夾和devel資料夾,devel資料夾內的檔案與引導路徑有關係,沒有source配置正確的環境變數路徑,即使catkin_make編譯通過,ROS也無法正確識別通過編譯的節點
在工作空間目錄下執行source命令:~/catkin_ws$ source devel/setup.bash
但這個命令只能在該終端內source到正確的環境變數,每次新開啟一個終端,仍需要再次配置,可以修改整個環境:
$ gedit ~/.bashrc
把編輯文字拉到最後,新增:
source ~/catkin_ws/devel/setup.bash
就是新增工作空間下的/devel/setup.bash檔案的路徑,讓終端每次開啟時,都會自動執行source命令
配置完成後,按ctrl+alt+T開啟終端,如果配置不正確,終端會提示找不到路徑
2)建立軟體包
軟體包一般在工作空間的src資料夾下建立,否在ROS可能無法定位你的軟體包,命名要避免與ROS的操作指令重複,不能以數字或者符號開頭,並且不允許大寫字母
建立軟體包命令:
格式: catkin_create_pkg pkg_name pkg_depends
例子: catkin_create_pkg testing_pkg roscpp rospy std_msgs
- pkg_name是對軟體包的命名;
- pkg_depends是軟體包的依賴關係,如roscpp,rospy,std_msgs;軟體包的依賴關係類似依賴某個原始碼或者標頭檔案
- 依賴關係分為一級依賴和間接依賴,一級依賴是我們在建立軟體包過程中新增的依賴項,間接依賴是各依賴項之間的關係,
$ rospack depends1 pkg_name
檢視一級依賴關係
$ rospack depends pkg_name
檢視所有的依賴關係
3)刪除軟體包
軟體包刪除命令:$ rm -rf 資料夾名稱
再重新編譯
2.編寫測試程式碼步驟
1)先進入軟體包目錄下的src資料夾 $ cd catkin_ws/src/testing_pkg/src/
2)開啟編輯器編寫cpp或者python原始碼
$ gedit talker.cpp
$ gedit listener.cpp
如果沒有gedit編輯器,系統會提示安裝gedit $ sudo apt-get install gedit
3)修改編譯配置檔案
4)返回工作空間目錄,編譯程式碼 $ catkin_make
3.編寫釋出者程式碼
1)簡單的釋出者程式碼,釋出者程式碼基本都是這個框架
#include "ros/ros.h"//ROS程式必備的標頭檔案
#include "std_msgs/String.h"//傳遞的訊息型別
#include "sstream"
int main(int argc, char **argv)//寫ROS程式需要加argc,argv,因為init需要傳這兩個引數
{
ros::init(argc, argv, "talker");//初始化ros,向master註冊一個叫“talker”的節點
ros::NodeHandle n;//初始化一個控制代碼,就是將ROS例項化
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
//釋出者註冊一個叫“chatter”的話題,<訊息型別>,1000是訊息佇列大小
//訊息佇列相當於快取訊息,如果處理速度不夠快的話訊息會被儲存在佇列中
ros::Rate loop_rate(10);//執行迴圈的速率,可以理解為釋出訊息的頻率,單位是Hz
int count = 0;
while (ros::ok())//ros::ok()函式用來判斷master節點是否正常
{
std_msgs::String msg;//宣告變數
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
ROS_INFO("%s", msg.data.c_str());//ROS_INFO()可以在終端列印資料
chatter_pub.publish(msg);//釋出該訊息
ros::spinOnce();//動作執行一次
//ros::spin()是迴圈執行,在沒有while的時候使用
loop_rate.sleep();//相當於delay函式,因為程式可能不需要0.1s,就是10Hz的頻率就可以傳送完成,所以sleep()函式可以讓程式暫停一會,讓訊息的傳送頻率符合10Hz
}
return 0;
}
wiki.ros.org/PublisherSubscriber
4.編寫訂閱者程式碼
1)簡單的訂閱者程式碼
#include "ros/ros.h"
#include "std_msgs/String.h"//要和訂閱的訊息型別所匹配
void chatterCallback(const std_msgs::String::ConstPtr& msg)//回撥函式
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");//初始化ros,向master註冊一個叫“listener”的節點
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
//訂閱者向master註冊自己需要訂閱的話題"chatter",訊息佇列大小是1000,chatterCallback是回撥函式
//回撥函式的意義是,當訂閱者從自己所訂閱的話題上接收到訊息,回撥函式自動執行
ros::spin();//因為不在while迴圈體中,所以它要不斷執行,而不是用spinOnce(),只執行一次
return 0;
}
wiki.ros.org/PublisherSubscriber
5.修改CMakeLists.txt檔案
- ctrl+F找到關鍵字 ## Declare a C++ executable
- 去掉#註釋項add_executable(${PROJECT_NAME}_node src/test_pkg_node.cpp),將test_pkg_node.cpp修改成自己所要編譯的cpp檔案,如果有多個cpp檔案需要編譯(一個軟體包內可能存在多個節點),則多新增add_executable語句
- 找到關鍵字target_link_libraries,將註釋去掉,如果有特別需要新增的依賴庫,可以在這裡新增,一般的編譯過程不需要,因為ROS裡已經揉合了很多第三方庫,例如OpenCV
- 每一個軟體包都要配置自己的CMakeLists.txt檔案
6.執行節點
1)先執行master節點 $ roscore
2)執行節點
格式:$ rosrun your_pkg_name your_node_name
例子:$ rosrun testing_pkg talker
rosrun testing_pkg listener
3)如果不記得節點名或者軟體包名稱,可以按Tab鍵補全,但一定要記得先source正確的環境變數
7.編寫launch檔案(可選)
1)launch檔案是xml格式的指令碼,我們把需要啟動的節點資訊寫進去,launch指令碼會自動幫我們執行需要的節點,而不需要手動逐個開啟
2)launch指令碼開啟節點的順序是不確定的,這也是ROS節點編寫的一個理念,儘可能讓節點之間的耦合性降低,節點儘可能地獨立完成某項工作
3)進入軟體包資料夾目錄 $ cd catkin_ws/src/testing_pkg/
4)建立launch資料夾 $ mkdir -p launch
5)進入launch資料夾 $ cd launch
6)新建launch檔案 $ gedit testing_pkg.launch
7)編寫launch檔案
語法格式
每個 xml 檔案都包含根元素,根元素由 launch 標籤來定義
<launch>// 開始標籤
<node pkg=”package_name” type=”executable_name” name=”node_name” output=“screen”/>
//type填寫的是與CMakeLists.txt中add_executable修改的test_pkg_node.cpp名稱一致
...
</launch>// 結束標籤,結束標籤都多一個 /
簡單的launch檔案
<launch>
<node pkg="testing_pkg" type="talker" name="talker" output="screen"/>
<node pkg="testing_pkg" type="listener" name="listener" output="screen"/>
</launch>
8)注意
- launch 檔案中,啟動節點的時候給 node 重新指定了名稱,會覆蓋掉在原始碼檔案中通過 ros::init 賦予節點的名稱,所以在使用launch啟動時要留意被修改的節點名
- 如果 output 沒有定義到 screen ,節點的輸出資訊會在 log 日誌檔案下儲存,檢視方式:
$ ~/.ros/log/run_id/node_name-number-stour.log
8.通過launch檔案啟動節點
1)
格式:$ roslaunch pkg_name launch_name
例子:$ roslaunch testing_pkg testing_pkg.launch
ROS基礎工具
1.rqt_graph
1)通過直觀的圖譜來檢視當前正在執行的節點之間的關係
2)$ rosrun rqt_graph rqt_graph
3)graph圖譜會列出節點,話題等資訊
2.rqt_robot_steering
1)rqt_robot_steering是與機器人運動控制的密切相關的ROS工具,它相當於一個節點,可以釋出/cmd_vel型別的訊息,/cmd_vel類訊息包括了機器人直線運動和轉向運動的控制指令,通過滑動條可以十分方便地控制機器人運動
2)$ rosrun rqt_robot_steering rqt_robot_steering
3.rviz
1)rviz是一款2D&3D的資料視覺化軟體,提供了豐富的ROS介面,可以建立機器人運動模型,鐳射雷達地圖等,並且進行模擬驗證
2)rosrun rviz rviz
4.rqt_logger_level
1)ROS的一個log日誌檢視器,用於檢查每個節點的日誌資訊,比如說什麼時候哪個節點作出了更改,都會記錄在log日誌下
2)$ rosrun rqt_logger_level rqt_logger_level
3)log訊息等級劃分,從Debug到Fatal越來越嚴重
5.rqt_console
1)用來檢視節點輸出資訊,因為有很多訊息並未通過ROS_INFO()函式在終端顯示出來,可以通過console檢視是否有正確輸出
2)rosrun rqt_console rqt_console
6.ROS檔案系統工具
1)rospack 獲取軟體包相關資訊,類似一個 find 的命令,只需要知道軟體包的名稱即可
- rospack help 檢視 rospack 相關功能的命令
- rospack list 列出當前系統中安裝了的軟體包名稱和路徑資訊
- rospack list-names 只檢視軟體包名稱
- rospack list-names | wc -l 統計有多少個軟體包,| 是一個符號,表示上一個命令的結果是下一個命令的輸入
- rospack find [package_name] 查詢軟體包的路徑資訊