编写ros服务节点:
观看此教程之前,请确保您已经按照ros编写srv教程编写了srv文件
首先,我们设置并打开相应的路径,使用指令:
. ~/catkin_ws/devel/setup.bash
roscd beginner_tutorials
然后创建文件,指令:
gedit 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;
}
现在,让我们来解释一下各行代码的作用:
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
beginner_tutorials / AddTwoInts.h是从我们之前创建的srv文件生成的头文件。
bool add(beginner_tutorials::AddTwoInts::Request &req,
beginner_tutorials::AddTwoInts::Response &res)
此函数提供添加两个int的服务,它接受srv文件中定义的请求和响应类型并返回一个布尔值。
{
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;
}
这里添加了两个整数并存储在响应中。然后记录有关请求和响应的一些信息。最后,服务在完成后返回true。
ros::ServiceServer service = n.advertiseService("add_two_ints", add);
这里的服务是通过ROS创建和宣传(advertise)的。
编写客户端节点
在beginner_tutorials包中创建src/add_two_ints_client.cpp文件,指令:
cd src
gedit 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;
}
现在,让我们解释一下各行代码:
ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
这将为add_two_ints服务创建一个客户端。该ROS :: ServiceClient对象用于以后调用服务。
beginner_tutorials::AddTwoInts srv;
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中的值将无效。
构建节点
编辑位于beginner_tutorials的CMakeLists.txs文件,指令:
roscd beginner_tutorials
gedit CMakeLists.txt
在最后面加上以下代码:
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,默认情况下将进入devel空间的包目录,默认位于〜/catkin_ws/devel/lib/<package name>。您可以直接调用可执行文件,也可以使用rosrun来调用它们。它们不会放在’<prefix> / bin’中,因为在将软件包安装到系统时会污染PATH。
现在运行catkin_make:
cd ~/catkin_ws
catkin_make
接下来让我们检验一下自己的劳动成果,首先运行ros核心:
roscore
然后打开新的终端,运行node:
rosrun beginner_tutorials add_two_ints_server
你应该会看到Ready to add two ints.
如果你的rosrun找不到beginner_tutorials
试着输入指令
. ~/devel/setup.bash
然后再重复上面的命令。
接下来打开新的终端,运行客户端,指令:
rosrun beginner_tutorials add_two_ints_client 1 3
你将会看到
[ INFO] [1556180034.901625414]: Sum: 4
在上一个终端中,您应该看到类似于:
[ INFO] [1556180034.901459798]: request: x=1, y=3 [ INFO]
[1556180034.901491998]: sending back response: [4]