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程式,接下來開始總結學習如何記錄與回放資料了。