1. 程式人生 > >ROS總結——ROS伺服器和客戶端

ROS總結——ROS伺服器和客戶端

伺服器和客戶端 (C++)

上一個部落格總結了ROS訊息釋出和訂閱,本部落格將繼續總結ROS如何用 C++ 編寫伺服器節點和客戶端節點。請確保已經按照ROS訊息和ROS服務creating the AddTwoInts.srv的步驟建立了本節部落格所需要的srv。
1. 編寫ROS伺服器節點
在這裡,將建立一個簡單的service節點(“add_two_ints_server”),該節點將接收到兩個整形數字,並返回它們的和。進入先前在catkin workspace教程中所建立的beginner_tutorials包所在的目錄:

$  cd ~/catkin_ws/src/beginner_tutorials

1.1 src/add_two_ints_server.cpp程式碼

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"

bool add(beginner_tutorials::AddTwoInts::Request &req, beginner_tutorials::AddTwoInts::Response &res)
{
    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::init(argc, argv, "add_two_ints_server"); ros::NodeHandle n; ros::ServiceServer service = n.advertiseService("add_two_ints", add); ROS_INFO("Ready to add two ints."
); ros::spin(); return 0; }

1.2 程式碼解釋說明

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"

beginner_tutorials/AddTwoInts.h是由編譯系統自動根據我們先前建立的srv檔案生成的對應該srv檔案的標頭檔案。

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

這個函式提供兩個int值求和的服務,int值從request裡面獲取,而返回資料裝入response內,這些資料型別都定義在srv檔案內部,函式返回一個boolean值。

{
    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值已經相加,並把結果存入response中,然後一些關於request和response的資訊被記錄下來。最後,service完成計算後返回true值。

ros::ServiceServer service = n.advertiseService("add_two_ints", add);

service已經建立起來,並在ROS內釋出出來。

2. 編寫ROS客戶端節點
在beginner_tutorials包中建立src/add_two_ints_client.cpp檔案。
2.1 src/add_two_ints_client.cpp程式碼

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
#include <cstdlib>

int main(int argc, char **argv)
{
    ros::init(argc, argv, "add_two_ints_client");
    if (argc != 3)
    {
        ROS_INFO("usage: add_two_ints_client X Y");
        return 1;
    }
    ros::NodeHandle n;
    ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
    beginner_tutorials::AddTwoInts srv;
    srv.request.a = atoll(argv[1]);
    srv.request.b = atoll(argv[2]);
    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;
}

2.2 程式碼解釋說明

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

這段程式碼為add_two_ints service建立一個client。ros::ServiceClient 物件待會用來呼叫service。

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

這裡例項化一個由ROS編譯系統自動生成的service類,並給其request成員賦值。一個service類包含兩個成員request和response。同時也包括兩個類定義Request和Response。

  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;
    }

這段程式碼是在呼叫service。由於service的呼叫是模態過程(呼叫的時候佔用程序阻止其他程式碼的執行),一旦呼叫完成,將返回呼叫結果。如果service呼叫成功,call()函式將返回true,srv.response裡面的值將是合法的值。如果呼叫失敗,call()函式將返回false,srv.response裡面的值將是非法的。

3. 編譯節點
再來編輯一下beginner_tutorials裡面的CMakeLists.txt,並將下面的程式碼新增在檔案末尾:

## Build service client and server

add_executable(add_two_ints_server src/add_two_ints_server.cpp)
target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
add_dependencies(add_two_ints_server beginner_tutorials_gencpp)

add_executable(add_two_ints_client src/add_two_ints_client.cpp)
target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
add_dependencies(add_two_ints_client beginner_tutorials_gencpp)

這段程式碼將生成兩個可執行程式”add_two_ints_server”和”add_two_ints_client”,這兩個可執行程式預設被放在~/catkin_ws/devel/lib/share/,這裡為beginner_tutorials。可以直接呼叫可執行程式,或者使用rosrun命令去執行它們。
在工作空間之下以下命令:

# In your catkin workspace
cd ~/catkin_ws
catkin_make

4. 執行測試
確保roscore可用,在一個視窗中並執行:

這裡需要先執行伺服器端,再執行客戶埠。
$  roscore

新開一個視窗執行:

$  rosrun beginner_tutorials add_two_ints_server
[ INFO] [1495069320.366383192]: Ready to add two ints.
執行完客戶端將會顯示
[ INFO] [1495069385.058497162]: request: x=3, y=2
[ INFO] [1495069385.058580460]: sending back response: [5]
在伺服器端計算完成後將結果返回給客戶端

新開另一個視窗執行:

$  rosrun beginner_tutorials add_two_ints_client 3 
[ INFO] [1495069385.058816327]: Sum: 5

到現在已經成功地運行了Service和Client程式,接下來開始總結學習如何記錄與回放資料了。