天天看點

ROS服務通訊(service)1.相關指令2.自定義服務消息類型

在使用了話題通訊之後,服務通訊一直沒怎麼使用過,這裡記錄一下服務通訊的使用經曆。

話題通訊有點兒像是廣播資料,就像村口的大喇叭一樣,一直以自己的頻率去廣播消息,把話題消息廣播出去,隻要在廣場上的人都能聽見。

而服務不一樣,服務是基于請求的。跟網頁服務是一樣的機理,就是當我們點選網頁中的按鈕的時候,網站伺服器相應一下,把相應的網頁給我們用戶端顯示出來。這個屬于一問一答的形式,問了才答,不問不答。

1.相關指令

rosservice list             //列印服務清單
rosservice info 服務名稱     //列印該服務相關資訊
rosservice args 服務名稱     //列印服務參數
rosservice type 服務名稱     //列印消息類型
           

我們可以把小烏龜例程跑起來配合指令來做實驗

1)列印服務清單

rosservice list    //列印服務清單
           

 列印效果如下:

ROS服務通訊(service)1.相關指令2.自定義服務消息類型

2)列印該服務相關資訊

rosservice info /spawn
           

 效果如下:

ROS服務通訊(service)1.相關指令2.自定義服務消息類型

 3)列印服務參數

rosservice args /spawn
           

 列印效果如下

ROS服務通訊(service)1.相關指令2.自定義服務消息類型

4)列印消息類型

rosservice type /spawn
           

 列印效果如下

ROS服務通訊(service)1.相關指令2.自定義服務消息類型

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;

}
           

這裡已經可以用指令行嘗試發起請求了,如下圖所示。

ROS服務通訊(service)1.相關指令2.自定義服務消息類型

用戶端程式:

#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 參數一 參數二
           
ROS服務通訊(service)1.相關指令2.自定義服務消息類型