十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
本篇文章为大家展示了什么是ROS服务通信模式,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
公司主营业务:网站设计、成都做网站、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联推出奎文免费做网站回馈大家。
ROS 服务通信模式
服务(services)是节点之间通讯的另一种方式。服务允许节点发送请求(request) 并获得一个响应(response)
AddTwoInts.h文件是根据AddTwoInts.srv文件生成的
还会自动生成
AddTwoIntsRequest.h
AddTwoIntsResponse.h
AddTwoInts.h所在的目录是
\catkin_ws\devel
AddTwoInts.srv
int64 aint64 b---int64 sum
server.cpp
/** * AddTwoInts Server */#include "ros/ros.h"#include "learning_communication/AddTwoInts.h"// service回调函数,输入参数req,输出参数resbool add(learning_communication::AddTwoInts::Request &req, learning_communication::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节点初始化 ros::init(argc, argv, "add_two_ints_server"); // 创建节点句柄 ros::NodeHandle n; // 创建一个名为add_two_ints的server,注册回调函数add() ros::ServiceServer service = n.advertiseService("add_two_ints", add); // 循环等待回调函数 ROS_INFO("Ready to add two ints."); ros::spin(); return 0;}
client.cpp
/** * AddTwoInts Client */#include
CMakeLists.txt
add_executable(server src/server.cpp)target_link_libraries(server ${catkin_LIBRARIES})add_dependencies(server ${PROJECT_NAME}_gencpp)add_executable(client src/client.cpp)target_link_libraries(client ${catkin_LIBRARIES})add_dependencies(client ${PROJECT_NAME}_gencpp)
package.xml
文件夹的主要功能
1)config:放置功能包中的配置文件,由用户创建,文件名可以不同。2)include:放置功能包中需要用到的头文件。3)scripts:放置可以直接运行的Python脚本。4)src:放置需要编译的C++代码。5)launch:放置功能包中的所有启动文件。6)msg:放置功能包自定义的消息类型。7)srv:放置功能包自定义的服务类型。8)action:放置功能包自定义的动作指令。9)CMakeLists.txt:编译器编译功能包的规则。
如何自定义服务数据
与话题消息类似,ROS中的服务数据可以通过srv文件进行语言无关的接口定义,一般放置在功能包根目录下的srv文件夹中。该文件包含请求与应答两个数据域,数据域中的内容与话题消息的数据类型相同,只是在请求与应答的描述之间,需要使用“—”三个横线进行分割。
针对加法运算例程中的服务需求,创建一个定义服务数据类型的srv文件learning_communication/srv/AddTwoInts.sint64 a
int64 b
int64 sumv文件的内容较为简单,在服务请求的数据域中定义了两个int64类型的变量a和b,用来存储两个加数; 又在服务应答的数据域中定义了一个int64类型的变量sum,用来存储“a+b”的结果。
完成服务数据类型的描述后,与话题消息一样,还需要在功能包的package.xml和CMakeLists.txt文件中配置依赖与编译规则,在编译过程中将该描述文件转换成编程语言所能识别的代码。
打开package.xml文件,添加以下依赖配置
message_generation message_runtime
打开CMakeLists.txt文件,添加如下配置
find_package(catkin REQUIRED COMPONENTS geometry_msgs roscpp rospy std_msgs message_generation )add_service_files( FILES AddTwoInts.srv )
message_generation包不仅可以针对话题消息产生相应的代码,还可以根据服务消息的类型描述文件产生相关的代码。 功能包编译成功后,在服务的Server节点和Client节点的代码实现中就可以直接调用这些定义好的服务消息了。 接下来我们就编写Server和Client节点的代码,完成两数相加求和的服务过程。
代码解释
Server节点实现过程
1. 头文件
#include "learning-communication/AddTwoInts.h"
使用ROS中的服务,必须包含服务数据类型的头文件,这里使用的头文件是learning_communication/AddTwoInts.h,该头文件根据我们之前创建的服务数据类型的描述文件AddTwoInts.srv自动生成。
2.主函ros::ServiceServer service = n.advertiseService(“add_two_ints”, add);部分相对简单,先初始化节点,创建节点句柄,重点是要创建一个服务的Server,指定服务的名称以及接收到服务数据后的回调函数。然后开始 循环等待服务请求;一旦有服务请求,Server就跳入回调函数进行处理。
3.回调函数部分
bool add(learning_communication::AddTwoInts::Request &req,learning_communication::AddTwoInts::Response &res)
回调函数是真正实现服务功能的部分,也是设计的重点。add()函数用于完成两个变量相加的功能,其传入参数便是我们在服务数据类型描述文件中声明的请求与应答的数据结构。
{ 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);ROS_INFO("sending back response: [%ld]", (long int)res.sum);return true;}
在完成加法运算后,求和结果会放到应答数据中,反馈到Client,回调函数返回true。
服务中的Server实现流程如下:
·初始化ROS节点。
·创建Server实例。
·循环等待服务请求,进入回调函数。
·在回调函数中完成服务功能的处理并反馈应答数据。
Client节点的实现过程。
1.创建Client
ros::ServiceClient client = n.serviceClient
首先需要创建一个add_two_ints的Client实例,指定服务类型为learning_communication:AddTwoInts。
2.发布服务请求
learning_communication::AddTwoInts srv;srv.request.a = atoll(argv[1]);srv.request.b = atoll(argv[2]);
然后实例化一个服务数据类型的变量,该变量包含两个成员:request和response。将节点运行时输入的两个参数作为需要相加的两个整型数存储到变量中。
if (client.call(srv))
接着进行服务调用。该调用过程会发生阻塞,调用成功后返回true,访问srv.reponse即可获取服务请求的结果。如果调用失败会返回false,srv.reponse则不可使用。
服务中的Client实现流程如下:
·初始化ROS节点。
·创建一个Client实例。
·发布服务请求数据。
·等待Server处理之后的应答结果。
编译功能包
编辑CMakeLists.txt文件,加入如下编译规则:
add_executable(server src/server.cpp)target_link_libraries(server ${catkin_LIBRARIES})add_dependencies(server ${PROJECT_NAME}_gencpp)add_executable(client src/client.cpp)target_link_libraries(client ${catkin_LIBRARIES})add_dependencies(client ${PROJECT_NAME}_gencpp)
现在就可以使用catkin_make命令编译功能包了。
运行Server和Client
运行编译生成的Server和Client节点。
1.启动roscore
在运行节点之前,首先需要确保ROS Master已经成功启动:
roscore2.运行Server节点打开终端,使用如下命令运行Server节点:roscore
2.运行Server节点打开终端,使用如下命令运行
Server节点: rosrun learning_communication server
3.运行Client节点
打开一个新的终端,运行Client节点,同时需要输入加法运算的两个加数值:
$ rosrun learning_communication client 3 5
Client启动后发布服务请求,并成功接收到反馈结果
Server接收到服务调用后完成加法求解,并将结果反馈给Client
wiki
rosservice list 输出可用服务的信息rosservice call 调用带参数的服务rosservice type 输出服务类型rosservice find 依据类型寻找服务find services by service typerosservice uri 输出服务的ROSRPC uri
上述内容就是什么是ROS服务通信模式,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。