什么是ROS服務(wù)通信模式

本篇文章為大家展示了什么是ROS服務(wù)通信模式,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

公司主營業(yè)務(wù):網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出奎文免費(fèi)做網(wǎng)站回饋大家。

ROS 服務(wù)通信模式

服務(wù)(services)是節(jié)點(diǎn)之間通訊的另一種方式。服務(wù)允許節(jié)點(diǎn)發(fā)送請(qǐng)求(request) 并獲得一個(gè)響應(yīng)(response)

AddTwoInts.h文件是根據(jù)AddTwoInts.srv文件生成的

還會(huì)自動(dòng)生成

AddTwoIntsRequest.h

AddTwoIntsResponse.h

AddTwoInts.h所在的目錄是

\catkin_ws\devel

AddTwoInts.srv

int64 aint64 b---int64 sum

server.cpp

/** * AddTwoInts Server */#include "ros/ros.h"#include "learning_communication/AddTwoInts.h"// service回調(diào)函數(shù),輸入?yún)?shù)req,輸出參數(shù)resbool add(learning_communication::AddTwoInts::Request &req,     learning_communication::AddTwoInts::Response &res){  // 將輸入?yún)?shù)中的請(qǐng)求數(shù)據(jù)相加,結(jié)果放到應(yīng)答變量中  res.sum = req.a + req.b;  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);  ROS_INFO("sending back response: [%ld]", (long int)res.sum);  return true;}int main(int argc, char **argv){  // ROS節(jié)點(diǎn)初始化  ros::init(argc, argv, "add_two_ints_server");  // 創(chuàng)建節(jié)點(diǎn)句柄  ros::NodeHandle n;  // 創(chuàng)建一個(gè)名為add_two_ints的server,注冊(cè)回調(diào)函數(shù)add()  ros::ServiceServer service = n.advertiseService("add_two_ints", add);  // 循環(huán)等待回調(diào)函數(shù)  ROS_INFO("Ready to add two ints.");  ros::spin();  return 0;}

client.cpp

/** * AddTwoInts Client */#include <cstdlib>#include "ros/ros.h"#include "learning_communication/AddTwoInts.h"int main(int argc, char **argv){  // ROS節(jié)點(diǎn)初始化  ros::init(argc, argv, "add_two_ints_client");  // 從終端命令行獲取兩個(gè)加數(shù)  if (argc != 3)  {    ROS_INFO("usage: add_two_ints_client X Y");    return 1;  }  // 創(chuàng)建節(jié)點(diǎn)句柄  ros::NodeHandle n;  // 創(chuàng)建一個(gè)client,請(qǐng)求add_two_int service  // service消息類型是learning_communication::AddTwoInts  ros::ServiceClient client = n.serviceClient<learning_communication::AddTwoInts>("add_two_ints");  // 創(chuàng)建learning_communication::AddTwoInts類型的service消息  learning_communication::AddTwoInts srv;  srv.request.a = atoll(argv[1]);  srv.request.b = atoll(argv[2]);  // 發(fā)布service請(qǐng)求,等待加法運(yùn)算的應(yīng)答結(jié)果  if (client.call(srv))  {    ROS_INFO("Sum: %ld", (long int)srv.response.sum);  }  else  {    ROS_ERROR("Failed to call service add_two_ints");    return 1;  }  return 0;}

CMakeLists.txt

add_executable(server src/server.cpp)target_link_libraries(server ${catkin_LIBRARIES})add_dependencies(server ${PROJECT_NAME}_gencpp)add_executable(client src/client.cpp)target_link_libraries(client ${catkin_LIBRARIES})add_dependencies(client ${PROJECT_NAME}_gencpp)

package.xml

<?xml version="1.0"?><package> <name>learning_communication</name> <version>0.0.0</version> <description>The learning_communication package</description> <maintainer email="hcx@todo.todo">hcx</maintainer> <license>TODO</license> <buildtool_depend>catkin</buildtool_depend> <build_depend>geometry_msgs</build_depend> <build_depend>roscpp</build_depend> <build_depend>rospy</build_depend> <build_depend>std_msgs</build_depend> <run_depend>geometry_msgs</run_depend> <run_depend>roscpp</run_depend> <run_depend>rospy</run_depend> <run_depend>std_msgs</run_depend> <build_depend>message_generation</build_depend> <run_depend>message_runtime</run_depend> <!-- The export tag contains other, unspecified, tags --> <export>  <!-- Other tools can request additional information be placed here --> </export></package>

文件夾的主要功能

1)config:放置功能包中的配置文件,由用戶創(chuàng)建,文件名可以不同。2)include:放置功能包中需要用到的頭文件。3)scripts:放置可以直接運(yùn)行的Python腳本。4)src:放置需要編譯的C++代碼。5)launch:放置功能包中的所有啟動(dòng)文件。6)msg:放置功能包自定義的消息類型。7)srv:放置功能包自定義的服務(wù)類型。8)action:放置功能包自定義的動(dòng)作指令。9)CMakeLists.txt:編譯器編譯功能包的規(guī)則。

如何自定義服務(wù)數(shù)據(jù)

與話題消息類似,ROS中的服務(wù)數(shù)據(jù)可以通過srv文件進(jìn)行語言無關(guān)的接口定義,一般放置在功能包根目錄下的srv文件夾中。該文件包含請(qǐng)求與應(yīng)答兩個(gè)數(shù)據(jù)域,數(shù)據(jù)域中的內(nèi)容與話題消息的數(shù)據(jù)類型相同,只是在請(qǐng)求與應(yīng)答的描述之間,需要使用“—”三個(gè)橫線進(jìn)行分割。

針對(duì)加法運(yùn)算例程中的服務(wù)需求,創(chuàng)建一個(gè)定義服務(wù)數(shù)據(jù)類型的srv文件learning_communication/srv/AddTwoInts.sint64 a

int64 b

int64 sumv文件的內(nèi)容較為簡(jiǎn)單,在服務(wù)請(qǐng)求的數(shù)據(jù)域中定義了兩個(gè)int64類型的變量a和b,用來存儲(chǔ)兩個(gè)加數(shù); 又在服務(wù)應(yīng)答的數(shù)據(jù)域中定義了一個(gè)int64類型的變量sum,用來存儲(chǔ)“a+b”的結(jié)果。

完成服務(wù)數(shù)據(jù)類型的描述后,與話題消息一樣,還需要在功能包的package.xml和CMakeLists.txt文件中配置依賴與編譯規(guī)則,在編譯過程中將該描述文件轉(zhuǎn)換成編程語言所能識(shí)別的代碼。

打開package.xml文件,添加以下依賴配置

message_generation message_runtime

打開CMakeLists.txt文件,添加如下配置

find_package(catkin REQUIRED COMPONENTS geometry_msgs roscpp rospy std_msgs message_generation )add_service_files( FILES AddTwoInts.srv )

message_generation包不僅可以針對(duì)話題消息產(chǎn)生相應(yīng)的代碼,還可以根據(jù)服務(wù)消息的類型描述文件產(chǎn)生相關(guān)的代碼。 功能包編譯成功后,在服務(wù)的Server節(jié)點(diǎn)和Client節(jié)點(diǎn)的代碼實(shí)現(xiàn)中就可以直接調(diào)用這些定義好的服務(wù)消息了。 接下來我們就編寫Server和Client節(jié)點(diǎn)的代碼,完成兩數(shù)相加求和的服務(wù)過程。

代碼解釋

Server節(jié)點(diǎn)實(shí)現(xiàn)過程

1. 頭文件

#include "learning-communication/AddTwoInts.h"

使用ROS中的服務(wù),必須包含服務(wù)數(shù)據(jù)類型的頭文件,這里使用的頭文件是learning_communication/AddTwoInts.h,該頭文件根據(jù)我們之前創(chuàng)建的服務(wù)數(shù)據(jù)類型的描述文件AddTwoInts.srv自動(dòng)生成。

2.主函ros::ServiceServer service = n.advertiseService(“add_two_ints”, add);部分相對(duì)簡(jiǎn)單,先初始化節(jié)點(diǎn),創(chuàng)建節(jié)點(diǎn)句柄,重點(diǎn)是要?jiǎng)?chuàng)建一個(gè)服務(wù)的Server,指定服務(wù)的名稱以及接收到服務(wù)數(shù)據(jù)后的回調(diào)函數(shù)。然后開始 循環(huán)等待服務(wù)請(qǐng)求;一旦有服務(wù)請(qǐng)求,Server就跳入回調(diào)函數(shù)進(jìn)行處理。

3.回調(diào)函數(shù)部分

bool add(learning_communication::AddTwoInts::Request &req,learning_communication::AddTwoInts::Response &res)

回調(diào)函數(shù)是真正實(shí)現(xiàn)服務(wù)功能的部分,也是設(shè)計(jì)的重點(diǎn)。add()函數(shù)用于完成兩個(gè)變量相加的功能,其傳入?yún)?shù)便是我們?cè)诜?wù)數(shù)據(jù)類型描述文件中聲明的請(qǐng)求與應(yīng)答的數(shù)據(jù)結(jié)構(gòu)。

{ res.sum = req.a + req.b;ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);ROS_INFO("sending back response: [%ld]", (long int)res.sum);ROS_INFO("sending back response: [%ld]", (long int)res.sum);return true;}

在完成加法運(yùn)算后,求和結(jié)果會(huì)放到應(yīng)答數(shù)據(jù)中,反饋到Client,回調(diào)函數(shù)返回true。

服務(wù)中的Server實(shí)現(xiàn)流程如下:

·初始化ROS節(jié)點(diǎn)。

·創(chuàng)建Server實(shí)例。

·循環(huán)等待服務(wù)請(qǐng)求,進(jìn)入回調(diào)函數(shù)。

·在回調(diào)函數(shù)中完成服務(wù)功能的處理并反饋應(yīng)答數(shù)據(jù)。

Client節(jié)點(diǎn)的實(shí)現(xiàn)過程。

1.創(chuàng)建Client

ros::ServiceClient client = n.serviceClient<learning_communication::AddTwoInts> ("add_two_ints");

首先需要?jiǎng)?chuàng)建一個(gè)add_two_ints的Client實(shí)例,指定服務(wù)類型為learning_communication:AddTwoInts。

2.發(fā)布服務(wù)請(qǐng)求

learning_communication::AddTwoInts srv;srv.request.a = atoll(argv[1]);srv.request.b = atoll(argv[2]);

然后實(shí)例化一個(gè)服務(wù)數(shù)據(jù)類型的變量,該變量包含兩個(gè)成員:request和response。將節(jié)點(diǎn)運(yùn)行時(shí)輸入的兩個(gè)參數(shù)作為需要相加的兩個(gè)整型數(shù)存儲(chǔ)到變量中。

if (client.call(srv))

接著進(jìn)行服務(wù)調(diào)用。該調(diào)用過程會(huì)發(fā)生阻塞,調(diào)用成功后返回true,訪問srv.reponse即可獲取服務(wù)請(qǐng)求的結(jié)果。如果調(diào)用失敗會(huì)返回false,srv.reponse則不可使用。

服務(wù)中的Client實(shí)現(xiàn)流程如下:

·初始化ROS節(jié)點(diǎn)。

·創(chuàng)建一個(gè)Client實(shí)例。

·發(fā)布服務(wù)請(qǐng)求數(shù)據(jù)。

·等待Server處理之后的應(yīng)答結(jié)果。

編譯功能包

編輯CMakeLists.txt文件,加入如下編譯規(guī)則:

add_executable(server src/server.cpp)target_link_libraries(server ${catkin_LIBRARIES})add_dependencies(server ${PROJECT_NAME}_gencpp)add_executable(client src/client.cpp)target_link_libraries(client ${catkin_LIBRARIES})add_dependencies(client ${PROJECT_NAME}_gencpp)

現(xiàn)在就可以使用catkin_make命令編譯功能包了。

運(yùn)行Server和Client

運(yùn)行編譯生成的Server和Client節(jié)點(diǎn)。

1.啟動(dòng)roscore

在運(yùn)行節(jié)點(diǎn)之前,首先需要確保ROS Master已經(jīng)成功啟動(dòng):

roscore2.運(yùn)行Server節(jié)點(diǎn)打開終端,使用如下命令運(yùn)行Server節(jié)點(diǎn):roscore

2.運(yùn)行Server節(jié)點(diǎn)打開終端,使用如下命令運(yùn)行

Server節(jié)點(diǎn): rosrun learning_communication server

3.運(yùn)行Client節(jié)點(diǎn)

打開一個(gè)新的終端,運(yùn)行Client節(jié)點(diǎn),同時(shí)需要輸入加法運(yùn)算的兩個(gè)加數(shù)值:

$ rosrun learning_communication client 3 5

Client啟動(dòng)后發(fā)布服務(wù)請(qǐng)求,并成功接收到反饋結(jié)果

Server接收到服務(wù)調(diào)用后完成加法求解,并將結(jié)果反饋給Client

wiki

rosservice list     輸出可用服務(wù)的信息rosservice call     調(diào)用帶參數(shù)的服務(wù)rosservice type     輸出服務(wù)類型rosservice find     依據(jù)類型尋找服務(wù)find services by service typerosservice uri     輸出服務(wù)的ROSRPC uri

上述內(nèi)容就是什么是ROS服務(wù)通信模式,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站名稱:什么是ROS服務(wù)通信模式
URL網(wǎng)址:http://muchs.cn/article10/pdhigo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、靜態(tài)網(wǎng)站、、企業(yè)建站、做網(wǎng)站營銷型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計(jì)公司