ROS1快速入门学习笔记 - 10服务数据的定义和使用

2024-05-01 12:12

本文主要是介绍ROS1快速入门学习笔记 - 10服务数据的定义和使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、服务模型(客户端/服务器)

二、自定义服务数据

1.  定义srv文件 

2. 在package.xml中添加功能包依赖

3. 在CMakeLists.txt添加编译选项

4. 编译生成语言相关文件

5. 配置服务器/客户端代码编译规则

6. 编译并运行程序 

7. Python文件


一、服务模型(客户端/服务器)

二、自定义服务数据

1.  定义srv文件 

string name
uint8 age
uint8 sexuint8 unknow = 0
uint8 male = 1
uint8 female = 2---
string result

三个横线作为一个区分,上面是request,下面是response;

创建完之后如下所示

2. 在package.xml中添加功能包依赖

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

如下图所示: 

 

3. 在CMakeLists.txt添加编译选项

  • find_package(...... message_generation)
  • add_service_files(FILES Person.srv)
  • generate_messages(DEPENDENCIES std_msgs)
  • catkin_package(...... message_runtime)

 

4. 编译生成语言相关文件

在catkin_ws目录下进行编译,最后生成的了三个头文件,位于catkin_ws/devel/include/learning_service

(生成三个头文件是因为srv文件上面会生成一个文件,下面也会生成一个头文件,最后整体装再生成一个头文件位于Person.h内)

接下来通过使用客户端和服务器来验证服务模型

客户端的代码如下:

 * 该例程将请求/show_person服务,服务数据类型learning_service::Person*/#include <ros/ros.h>
#include "learning_service/Person.h"int main(int argc, char** argv)
{// 初始化ROS节点ros::init(argc, argv, "person_client");// 创建节点句柄ros::NodeHandle node;// 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的serviceros::service::waitForService("/show_person");ros::ServiceClient person_client = node.serviceClient<learning_service::Person>("/show_person");// 初始化learning_service::Person的请求数据learning_service::Person srv;srv.request.name = "Tom";srv.request.age  = 20;srv.request.sex  = learning_service::Person::Request::male;// 请求服务调用ROS_INFO("Call service to show person[name:%s, age:%d, sex:%d]", srv.request.name.c_str(), srv.request.age, srv.request.sex);person_client.call(srv);// 显示服务调用结果ROS_INFO("Show person result : %s", srv.response.result.c_str());return 0;
};

服务器的代码如下:

#include <ros/ros.h>
#include "learning_service/Person.h"// service回调函数,输入参数req,输出参数res
bool personCallback(learning_service::Person::Request  &req,learning_service::Person::Response &res)
{// 显示请求数据ROS_INFO("Person: name:%s  age:%d  sex:%d", req.name.c_str(), req.age, req.sex);// 设置反馈数据res.result = "OK";return true;
}int main(int argc, char **argv)
{// ROS节点初始化ros::init(argc, argv, "person_server");// 创建节点句柄ros::NodeHandle n;// 创建一个名为/show_person的server,注册回调函数personCallbackros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);// 循环等待回调函数ROS_INFO("Ready to show person informtion.");ros::spin();return 0;
}

5. 配置服务器/客户端代码编译规则

配置CMakeLists.txtx中的编译:

  • 设置需要编译的代码和生成的可知悉文件;
  • 设置链接库;
  • 添加依赖项
add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
add_dependencies(person_server ${PROJECT_NAME}_gencpp)add_executable(person_client src/person_client.cpp)
target_link_libraries(person_client ${catkin_LIBRARIES})
add_dependencies(person_client ${PROJECT_NAME}_gencpp)

编译后的结果可以在 catkin_ws/devel/include/learning_service中

6. 编译并运行程序 

 运行后客户端每次发送数据,服务器会收到,而且服务器会给客户端回复一个OK

7. Python文件

客户端程序如下:

import sys
import rospy
from learning_service.srv import Person, PersonRequestdef person_client():# ROS节点初始化rospy.init_node('person_client')# 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的servicerospy.wait_for_service('/show_person')try:person_client = rospy.ServiceProxy('/show_person', Person)# 请求服务调用,输入请求数据response = person_client("Tom", 20, PersonRequest.male)return response.resultexcept rospy.ServiceException, e:print "Service call failed: %s"%eif __name__ == "__main__":#服务调用并显示调用结果print "Show person result : %s" %(person_client())

服务器程序如下:

import rospy
from learning_service.srv import Person, PersonResponsedef personCallback(req):# 显示请求数据rospy.loginfo("Person: name:%s  age:%d  sex:%d", req.name, req.age, req.sex)# 反馈数据return PersonResponse("OK")def person_server():# ROS节点初始化rospy.init_node('person_server')# 创建一个名为/show_person的server,注册回调函数personCallbacks = rospy.Service('/show_person', Person, personCallback)# 循环等待回调函数print "Ready to show person informtion."rospy.spin()if __name__ == "__main__":person_server()

 

 

 

 

 

这篇关于ROS1快速入门学习笔记 - 10服务数据的定义和使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/951657

相关文章

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

prometheus如何使用pushgateway监控网路丢包

《prometheus如何使用pushgateway监控网路丢包》:本文主要介绍prometheus如何使用pushgateway监控网路丢包问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录监控网路丢包脚本数据图表总结监控网路丢包脚本[root@gtcq-gt-monitor-prome

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I