1.寫一個服務(wù)節(jié)點
- 移動到我們之前創(chuàng)建的beginner_tutorials包中去:
roscd beginner_tutorials
- 在beginner_tutorials包中創(chuàng)建src / add_two_ints_server.cpp文件,并將以下內(nèi)容粘貼到其中:
#include "ros/ros.h"
//beginner_tutorials / AddTwoInts.h是從我們先前創(chuàng)建的srv文件生成的頭文件难捌。
#include "beginer_tutorials/AddTwoInts.h"
#include "cstdlib"
//此函數(shù)提供用于添加兩個int的服務(wù),它接受srv文件中定義的請求和響應(yīng)類型,并返回一個布爾值。
bool add(beginer_tutorials::AddTwoInts::Request &req, beginer_tutorials::AddTwoInts::Response &res)
{
res.sum = req.a + req.b;
ROS_INFO("request x = %ld, y = %ld", (long)req.a, (long)req.b);
ROS_INFO("sending back response: [%ld]", (long)res.sum);
return true;
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "add_two_ints_server");
ros::NodeHandle node_handle;
// 在這里睡蟋,兩個int被添加并存儲在響應(yīng)中。然后記錄有關(guān)請求和響應(yīng)的一些信息。最后证杭,服務(wù)完成后將返回true。
ros::ServiceServer service = node_handle.advertiseService("add_two_ints", add);
ROS_INFO("Ready to add two ints!");
ros::spin();
return 0;
}
經(jīng)過前一章的介紹, 現(xiàn)在的代碼看起來就簡單多了
2.寫一個客服端節(jié)點
- 在beginner_tutorials包中創(chuàng)建src / add_two_ints_client.cpp文件妒御,并將以下內(nèi)容粘貼到其中:
#include "ros/ros.h"
#include "beginer_tutorials/AddTwoInts.h"
#include "cstdlib"
int main(int argc, char** argv)
{
ros::init(argc, argv, "add_two_ints_client");
// 判斷從命令行輸入的參數(shù)數(shù)量是否正確
if(argc != 3)
{
ROS_INFO("usage: add_two_ints_client X Y");
return 1;
}
ros::NodeHandle node_handle;
// 這將為add_two_ints服務(wù)創(chuàng)建一個客戶端。 ros :: ServiceClient對象用于稍后調(diào)用服務(wù)镇饺。
ros::ServiceClient client = node_handle.serviceClient<beginer_tutorials::AddTwoInts>("add_two_ints");
// 在這里乎莉,我們實例化一個自動生成的服務(wù)類,并為其請求成員分配值奸笤。服務(wù)類包含兩個成員惋啃,
// 即請求和響應(yīng)。它還包含兩個類定義:Request和Response监右。
beginer_tutorials::AddTwoInts srv;
// 將命令行讀取的參數(shù)傳入srv中
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
// 這實際上稱為服務(wù)边灭。由于服務(wù)呼叫處于阻塞狀態(tài),因此呼叫完成后將返回健盒。
// 如果服務(wù)調(diào)用成功绒瘦,則call()將返回true,并且srv.response中的值將有效扣癣。
// 如果調(diào)用失敗惰帽,則call()將返回false,并且srv.response中的值將無效父虑。
if(client.call(srv))
{
ROS_INFO("sum: %ld", (long)srv.response.sum);
} else
{
ROS_ERROR("Failed to call server add_two_ints");
return 1;
}
return 0;
}
3.編譯
- 再次編輯?/ catkin_ws / src / beginner_tutorials / CMakeLists.txt中的beginner_tutorials CMakeLists.txt该酗,并在末尾添加以下內(nèi)容:
27 add_executable(add_two_ints_server src/add_two_ints_server.cpp)
28 target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
29 add_dependencies(add_two_ints_server beginner_tutorials_gencpp)
30
31 add_executable(add_two_ints_client src/add_two_ints_client.cpp)
32 target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
33 add_dependencies(add_two_ints_client beginner_tutorials_gencpp)
這將創(chuàng)建兩個可執(zhí)行文件,add_two_ints_server和add_two_ints_client士嚎,它們默認(rèn)情況下將進(jìn)入開發(fā)空間的包目錄呜魄,默認(rèn)情況下位于?/ catkin_ws / devel / lib / <程序包名稱>。您可以直接調(diào)用可執(zhí)行文件莱衩,也可以使用rosrun調(diào)用它們爵嗅。它們沒有放在'<prefix> / bin'中,因為在將軟件包安裝到系統(tǒng)時膳殷,這會污染PATH操骡。如果希望在安裝時將可執(zhí)行文件放在PATH上九火,則可以設(shè)置安裝目標(biāo),請參閱:catkin / CMakeLists.txt
- 由于我們在之前已經(jīng)將srv文件的相關(guān)文件, 所以這里不用添加, 若有問題, 參閱: ROS學(xué)習(xí)--6.msg和srv
回到catkin_ws并編譯:
cd ~/catkin_ws
catkin_make
4.測試(兩種方式)
- 打開三個終端分別運行:
roscore
source ~/catkin_ws/devel/setup.bash
rosrun beginer_tutorials add_two_ints_server
source ~/catkin_ws/devel/setup.bash
rosrun beginer_tutorials add_two_ints_client 4 5
- 打開三個終端分別運行:
roscore
~/catkin_ws/devel/lib/beginer_tutorials/add_two_ints_server
~/catkin_ws/devel/lib/beginer_tutorials/add_two_ints_client 4 5
最后結(jié)果: