服务数据的定义与使用
- 服务通信过程中服务的数据类型需要用户自己定义,与消息不同,节点并不提供标准服务类型
定义srv文件
创建
| roscd finaltest |
| mkdir srv |
| cd srv |
| touch Person.srv |
| |
| string name |
| uint8 age |
| uint8 sex |
| |
| uint8 unknown = 0 |
| uint8 male = 1 |
| uint8 female = 2 |
| |
| --- |
| string result |
配置
package.xml
| <build_depend>message_generation</build_depend> |
| <exec_depend>message_runtime</exec_depend> |
注意,在构建时,其实只需要message_generation
,而在运行时,我们只需要message_runtime
CMakeLists.txt
- 将message_generation加在括号闭合前即可
| find_package(catkin REQUIRED COMPONENTS |
| std_msgs |
| message_generation |
| ) |
| add_service_files( |
| FILES |
| Person.srv |
| ) |
- 添加生成消息的依赖,默认的时候要添加 std_msgs
| generate_messages( |
| DEPENDENCIES |
| std_msgs |
| ) |
| catkin_package( |
| CATKIN_DEPENDS message_runtime |
| ) |
注意,定义完srv文件后必须先编译生成头文件,然后再放Client和Server的源代码
Client
- 在 finaltest 包中 创建 person_client.cpp
| #include <ros/ros.h> |
| #include "finaltest/Person.h" |
| |
| int main(int argc, char** argv) |
| { |
| |
| ros::init(argc, argv, "person_client"); |
| |
| ros::NodeHandle node("~"); |
| |
| |
| ros::service::waitForService("/show_person"); |
| ros::ServiceClient person_client = node.serviceClient<finaltest::Person>("/show_person"); |
| |
| |
| finaltest::Person srv; |
| srv.request.name = "Tom"; |
| srv.request.age = 20; |
| srv.request.sex = finaltest::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; |
| }; |
总结:
- 初始化ROS节点
- 创建一个Client实例
- 发布服务器请求数据
- 等待Server处理之后的应答结果
Server
- 在 finaltest 包中 创建 person_server.cpp
| #include <ros/ros.h> |
| #include "finaltest/Person.h" |
| |
| |
| bool personCallback(finaltest::Person::Request &req, finaltest::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::init(argc, argv, "person_server"); |
| |
| |
| ros::NodeHandle n("~"); |
| |
| |
| ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback); |
| |
| |
| ROS_INFO("Ready to show person informtion."); |
| ros::spin(); |
| |
| return 0; |
| } |
总结:
- 初始化ROS节点
- 创建Server实例
- 循环等待服务请求,进入回调函数
- 在回调函数中完成服务功能的处理,并反馈应答数据
配置CMakeLists.txt
| 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) |
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现