機器人操做系統入門(六)roscpp客戶端庫

參考資料:node

https://www.icourse163.org/course/ISCAS-1002580008?tid=1003713012  //中國大學MOOC服務器

https://www.bilibili.com/video/av23401751  //B站多線程

《ROS操做系統入門講義》PDF下載ide

連接:https://pan.baidu.com/s/1OCja2WLDRnjYXMrpnZ3-sQ 
提取碼:mziy函數

第六章 roscppui

1、ROS支持的客戶端庫和總體的包結構分佈this

2、roscpp:位於/opt/ros/kinetic  // #include<ros/ros.h>spa

1. 主要部分操作系統

(1)ros::init():解析傳入的ROS參數,建立node第一步須要用到的函數  //能夠爲node命名線程

(2)ros::NodeHandle:和topic、service、param等交互的公共接口  //類,須要建立句柄對象

(3)ros::master:包含從master查詢信息的函數  //命名空間,無需建立對象

(4)ros::this_node:包含查詢這個進程(node)的函數

(5)ros::service:包含查詢服務的函數

(6)ros::param:包含查詢參數服務器的函數,而不須要用到NodeHandle

(7)ros::names:包含處理ROS圖資源名稱的函數

2. 按功能分類

  • Initialization and Shutdown 初始與關閉
  • Topics 話題
  • Services 服務
  • Parameter Server 參數服務器
  • Timers 定時器
  • NodeHandles 節點句柄
  • Callbacks and Spinning 回調和自旋(輪詢
  • Logging 日誌
  • Names and Node Information 名稱管理
  • Time 時鐘
  • Exception 異常

3、節點初始化、關閉以及句柄NodeHandle

1. 初始化

(1)ros::init():初始化節點的名稱和其餘信息

(2)ros::NodeHandle對象:節點句柄,用來建立Publisher、Subscriber等

注:句柄NodeHandle是對節點資源的描述,經過它對節點進行操做,如爲程序提供服務、監聽某個topic上的消息、訪問和修改param等

2. 關閉節點

(1)終端輸入"Ctrl + C"  //自動觸發SIGINT句柄關閉進程

(2)調用ros::shutdown()  //手動關閉節點

注:經常使用執行流程以下  // 啓動節點+獲取句柄

3. NodeHandle類的經常使用成員函數  //

4、基於roscpp的topic通訊

(1)功能:自定義一個類型爲gps的消息(包括位置x,y和工做狀態state信息),一個node以必定頻率發佈模擬的gps消息,另外一個node接收並處理,算出到原點的距離

(2)自定義gps.msg消息  //相似於C語言中的結構體

string state  #工做狀態

float32 x  #x座標

float32 y  #y座標

(3)修改CMakeLists.txt和package.xml  //編譯自定義消息

CMakeLists.txt:

package.xml:

  <build_depend>message_generation</build_depend>

  <run_depend>message_runtime</run_depend>

注:

  • 回到工做空間編譯完成後,會在devel路徑下自動生成gps.msg對應的頭文件,其中定義了topic_demo::gps類
  • 經過 #include<topic_demo/gps.h>,使用自定義消息類型
  • topic_demo::gps mygpsmsg;
    mygpsmsg.x = 1.6;
    mygpsmsg.y = 5.5;
    mygpsmsg.state = "working";

(4)消息發佈節點 talker.cpp  //發佈gps_info話題

(5)消息訂閱節點 listener.cpp

注:

  • 經過定義回調函數,爲gps_info話題預先準備一個回調函數,接收到消息時被觸發執行
  • 回調函數做爲參數被傳入到了另外一個函數中(在本例中傳遞的是函數指針),在將來某個時刻(當有新的message到達),就會當即執行

(6)修改CMakeList.txt

(7)spin調用方式  //多線程用於分別處理不一樣數據

5、基於roscpp的service通訊

(1)自定義服務文件Greeting.srv

string name #短橫線上邊部分是服務請求的數據

int32 age

--- #短橫線下面是服務回傳的內容。

string feedback

注:至關於嵌套了請求和響應兩個結構體

(2)修改CMakeList.txt:add_service_files(FILES Greeting.srv)

經過#include <service_demo/Greeting.h>進行調用

service_demo::Greeting grt; //grt分爲grt.request和grt.response兩部分

grt.request.name = "HAN"; //不能用grt.name或者grt.age來訪問

grt.request.age = "20";

(3)服務提供節點 server.cpp

注:

  • 服務的處理操做由handle_function()函數肯定,輸入參數爲Greeting的Request和Response兩部分,對對Requst數據進行須要的操做,將結果寫入到Response中
  • 返回值爲bool值,用於判斷服務是否調用成功  //不輸出Response

(4)服務請求節點 client.cpp

注:CMakeList.txt和package.xml的修改和topic_demo相似

6、基於roscpp的參數服務器設置

(1)兩種方式

  • ros::param命名空間
  • ros::NodeHandle節點句柄

(2)實際項目中對參數的設置一般都不在程序中,而是利用launch文件  //launch文件能夠方便地修改參數,而寫成代碼以後,修改參數必須從新編譯

(3)命名空間對param的影響  // ros::NodeHandle n; 和 ros::NodeHandle nh("~") 的區別

假設參數定義以下:

那麼 name_demo.cpp文件以下:

輸出:

可見:

  • n爲全局命名空間句柄,當訪問節點私有命名空間內的參數時,須要添加節點名
  • nh爲局部命名空間句柄,當訪問全局命名空間的參數時,須要添加全局命名空間 /

7、時鐘

(1)兩種時間表示方法  //均由秒和納秒組成:int32 sec;int32 nsec

  • ros::Time  //某個時刻,#include<ros/time.h>
  • ros::Duration  //某個時段,#include<ros/duration.h>

用法示例:

  • ros::Time begin = ros::Time::now();  //獲取當前時間
  • ros::Time at_some_time1(5,20000000);  //5.2s
  • ros::Time at_some_time2(5.2)  //同上,重載了float類型和兩個uint類型的構造函數
  • ros::Duration one_hour(60*60,0);  //1h
  • double secs1 = at_some_time1.toSec();  //將Time轉爲double型時間
  • double secs2 = one_hour.toSec();  //將Duration轉爲double型時間

時刻Time和Duration時長之間存在加減運算

  • ros::Time t1 = ros::Time::now() - ros::Duration(5.5);  //t1是5.5s前的時刻,Time加減Duration返回都是Time
  • ros::Time t2 = ros::Time::now() + ros::Duration(3.3);  //t2是當前時刻日後推3.3s的時刻
  • ros::Duration d1 = t2 - t1;  //從t1到t2的時長,兩個Time相減返回Duration類型
  • ros::Duration d2 = d1 -ros::Duration(0,300);  //兩個Duration相減,仍是Duration

注:不存在Time+Time

(2)休眠功能sleep

注:Rate的功能是指定一個頻率,讓某些動做按照這個頻率來循環執行

(3)定時器Timer:與Rate相似,經過設定回調函數和觸發時間實現某些動做的反覆執行,建立方法相似topic中的subscriber

8、日誌和異常

(1)日誌log

  • 每一個節點都會把日誌信息發送到統一的話題 /rosout
  • rosout自己也是一個節點,負責日誌的記錄

(2)日誌的輸出:#include<ros/console.h>

五個級別:

  • DEBUG:ROS_DEBUG("The velocity is %f", vel);
  • INFO:ROS_INFO
  • WARN:ROS_WARN("Warn: the use is deprecated.");
  • ERROR:ROS_ERROR
  • FATAL:ROS_FATAL("Cannot start this node.");

(3)異常Exception  //針對兩類錯誤

  • ros::InvalidNodeNameException  //當無效的基礎名稱傳給ros::init(),一般是名稱中有/,就會觸發
  • ros::InvalidNameExcaption  //當無效名稱傳給了roscpp
相關文章
相關標籤/搜索