在使用了話題通訊之後,服務通訊一直沒怎麼使用過,這裡記錄一下服務通訊的使用經曆。
話題通訊有點兒像是廣播資料,就像村口的大喇叭一樣,一直以自己的頻率去廣播消息,把話題消息廣播出去,隻要在廣場上的人都能聽見。
而服務不一樣,服務是基于請求的。跟網頁服務是一樣的機理,就是當我們點選網頁中的按鈕的時候,網站伺服器相應一下,把相應的網頁給我們用戶端顯示出來。這個屬于一問一答的形式,問了才答,不問不答。
1.相關指令
rosservice list //列印服務清單
rosservice info 服務名稱 //列印該服務相關資訊
rosservice args 服務名稱 //列印服務參數
rosservice type 服務名稱 //列印消息類型
我們可以把小烏龜例程跑起來配合指令來做實驗
1)列印服務清單
rosservice list //列印服務清單
列印效果如下:

2)列印該服務相關資訊
rosservice info /spawn
效果如下:
3)列印服務參數
rosservice args /spawn
列印效果如下
4)列印消息類型
rosservice type /spawn
列印效果如下
2.自定義服務消息類型
服務端程式:
#include "ros/ros.h"
#include "hello/service.h"
bool doReq(hello::service::Request& req,
hello::service::Response& resp){
int num1 = req.num1;
int num2 = req.num2;
ROS_INFO("伺服器接收到的請求資料為:num1 = %d, num2 = %d",num1, num2);
//邏輯處理
if (num1 < 0 || num2 < 0)
{
ROS_ERROR("送出的資料異常:資料不可以為負數");
return false;
}
//如果沒有異常,那麼相加并将結果指派給 resp
resp.sum = num1 + num2;
return true;
}
int main(int argc,char *argv[])
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"AddInts_Server");
ros::NodeHandle nh;
ros::ServiceServer server = nh.advertiseService("AddInts",doReq);
ROS_INFO("服務已經啟動....");
ros::spin();
return 0;
}
這裡已經可以用指令行嘗試發起請求了,如下圖所示。
用戶端程式:
#include "ros/ros.h"
#include "hello/service.h"
int main(int argc,char *argv[])
{
setlocale(LC_ALL,"");
if (argc != 3)
// if (argc != 5)//launch 傳參(0-檔案路徑 1傳入的參數 2傳入的參數 3節點名稱 4日志路徑)
{
ROS_ERROR("請送出兩個整數");
return 1;
}
ros::init(argc,argv,"AddInts_Client");
ros::NodeHandle nh;
ros::ServiceClient client = nh.serviceClient<hello::service>("AddInts");
ros::service::waitForService("AddInts");
hello::service ai;
ai.request.num1 = atoi(argv[1]);
ai.request.num2 = atoi(argv[2]);
bool flag = client.call(ai);
if (flag)
{
ROS_INFO("請求正常處理,響應結果:%d",ai.response.sum);
}
else
{
ROS_ERROR("請求處理失敗....");
return 1;
}
return 0;
}
運作用戶端: rosrun hello client 參數一 參數二