ROS Service 通信简单示例
需求
在无人机任务执行的过程中,可能会遇到不可识别的单位,需要将采集到的数据,传输给数据处理节点,并获取有关信息。
在此,我们将实现client提交两个整数,server负责计算并返回给client。
服务端 Service Node
思路
初始化 ROS 节点和句柄;
创建服务并发布到 ROS;
编写回调函数;
cpp实现
创建 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;
}代码解释
beginner_tutorials/AddTwoInts.h是我们前面创建的.srv文件生成的头文件。
这一方法为实现两个int相加服务。它携带两个参数,分别为.srv文件的 Request 和 Response 部分,并返回一个 boolean 值。
两个整数相加并存储在 Response 部分。
打印请求响应相关信息。
最后完成服务并返回 true。
这一语句将创建并发布服务信息。第一个参数是 service名字,第二个是回调函数名。
Notes :
转化长整型的原因:
beginner_tutorials::AddTwoIntsResponse_<std::allocator<void> >::_sum_type {aka long int}
服务端 Client Node
思路
初始化 ROS 节点、句柄;
创建该服务的Client 对象;
填写
srv消息的request部分;调用服务;
cpp实现
创建 add_two_ints_client.cpp 文件:
代码解释
这将为 add_two_ints 服务创建一个客户端。ros::Service Client 对象用于稍后调用服务。
在这里,我们实例化一个自动生成的服务类,并将值分配给它的成员变量 request。 一个服务类包含两个部分,请求request和响应response。它还包含两个类定义,请求Request 和响应 Response。
这是实际调用服务的地方。该服务调用是阻塞的,调用返程即返回。 如果服务调用成功, call() 将返回 true 并且 srv.response 中的值将是有效的。 如果调用不成功, call() 将返回 false 并且 srv.response 中的值将无效。
编译
CMakeLists.txt
catkin_make
如果编译失败,很大的原因是因为前面创建AddTwoInts.srv的问题。
运行
运行 roscore
运行 Server Node
打开新终端,设置环境变量,运行节点:
运行 Client Node
在client节点:
在 server节点:
优化
值得注意的是,在这里我们先启动了 server,后启动了client。如果先启动 client,服务会调用失败。
在这里我们可以使用client.waitForExistence()或ros::service::waitForService("add_two_ints")来进行程序的优化。即使client先启动也会一直等待服务的启动。
launch文件启动
在 launch 文件夹下创建 server_client.launch 文件,输入:
Notes:args是命令行参数,即 add_two_ints_client a b。事实上使用 launch 文件启动,后面还会有两个参数__name:=xxx、__logs:=xxx。
打开命令行,输入执行:
Reference
Last updated