本節(jié)介紹使用C++編寫ROS消息服務器節(jié)點和客戶端節(jié)點的方法和步驟,以及如何構建和測試這兩個節(jié)點。
1.編寫服務器節(jié)點代碼
使用kdevelop在ros_tutorials/src目錄下創(chuàng)建一個名為add_two_ints_server的C++文件:
$ roscd ros_tutorials
$ cd src
$ kdevelopadd_two_ints_server.cpp
輸入如下代碼:
#include"ros/ros.h"
#include "ros_tutorials/AddTwoInts.h"
bool add(ros_tutorials::AddTwoInts::Request &req,
ros_tutorials::AddTwoInts::Response&res)
{
res.sum = req.a + req.b;1
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;
}
部分代碼解釋如下:
#include "ros_tutorials/AddTwoInts.h"
ros_tutorials/AddTwoInts.h是由編譯系統(tǒng)自動根據先前創(chuàng)建的srv文件生成的對應該srv文件的頭文件。
bool add(ros_tutorials::AddTwoInts::Request &req,
ros_tutorials::AddTwoInts::Response&res)
該函數提供兩個int值求和的服務,int值從Request里面獲取,而返回數據裝入Response內,這些數據類型都定義在srv文件內部,函數返回一個bool值。
{
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;
}
進行兩個整數相加運算,結果存儲在Response中。把Request和Response的一些信息記錄日志,最后當運算完成時服務返回True。
ros::ServiceServerservice = n.advertiseService("add_two_ints", add);
創(chuàng)建服務service并在ROS網絡上進行廣播。
2.編寫客戶端節(jié)點代碼
使用kdevelop在ros_tutorials/src目錄下創(chuàng)建一個名為add_two_ints_client的C++文件:
$ roscd ros_tutorials
$ cd src
$ kdevelopadd_two_ints_client.cpp
輸入如下代碼:
#include"ros/ros.h"
#include "ros_tutorials/AddTwoInts.h"
#include
int main(int argc, char**argv)
{
ros::init(argc, argv,"add_two_ints_client");
if (argc != 3)
{
ROS_INFO("usage: add_two_ints_client XY");
return 1;
}
ros::NodeHandle n;
ros::ServiceClient client =n.serviceClient ("add_two_ints");
ros_tutorials::AddTwoInts srv;
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
if (client.call(srv))
{
ROS_INFO("Sum: %ld", (longint)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call serviceadd_two_ints");
return 1;
}
return 0;
}
部分代碼解釋如下:
ros::ServiceClientclient = n.serviceClient ("add_two_ints");
為add_two_ints服務創(chuàng)建一個客戶端。ros::ServiceClient對象用來隨后調用服務。
ros_tutorials::AddTwoIntssrv;
srv.request.a= atoll(argv[1]);
srv.request.b= atoll(argv[2]);
實例化一個自動生成的服務類,并為其request成員賦值。一個服務類包含兩個成員,request和response,也包括兩個類的定義:Request和Response。
if(client.call(srv))
調用服務,調用完成后立即返回。如果服務調用成功,call()將返回true,此時srv.response中的值有效。如果服務調用失敗,call()將返回false,srv.response中的值無效。
3.生成節(jié)點
打開~/catkin_ws/src/ros_tutorials/CMakeLists.txt,將以下代碼添加到最后:
add_executable(add_two_ints_serversrc/add_two_ints_server.cpp)
target_link_libraries(add_two_ints_server${catkin_LIBRARIES})
add_dependencies(add_two_ints_serverros_tutorials_gencpp)
add_executable(add_two_ints_clientsrc/add_two_ints_client.cpp)
target_link_libraries(add_two_ints_client${catkin_LIBRARIES})
add_dependencies(add_two_ints_clientros_tutorials_gencpp)
這將會創(chuàng)建兩個可執(zhí)行程序,add_two_ints_server和add_two_ints_client。默認情況下,它們將會位于你的開發(fā)空間里面的ros_tutorials功能包目錄下(~/catkin_ws/devel/lib/ros_tutorials),你可以直接調用它們或者使用rosrun運行它們。
運行 catkin_make:
# In your catkinworkspace
$ cd ~/catkin_ws
$ catkin_make
4.測試服務器和客戶端節(jié)點
首先啟動roscore:
$ roscore
在另一個終端窗口運行下面的命令啟動服務器節(jié)點:
$ rosrun ros_tutorialsadd_two_ints_server
你會看到下面的輸出:
Ready to add two ints.
新建一個終端,運行客戶端節(jié)點:
$ rosrun ros_tutorials add_two_ints_client 2 3
你會看到類似下面的輸出:
Requesting 2+3
2 + 3 = 5