创建服务端和客户端
ROS message(msg与srv介绍)
msg
简介
- ROS 使用简化的消息描述语言来描述 ROS 节点发布的数据值(又名消息)
- ROS消息类型,即是ROS话题的格式,可视为ROS的数据类型,基本上是指同一个意思
- 消息描述存储在ROS包的 msg/ 子目录中的 .msg 文件中
- msg文件就是简单的文本文件,每行都有一个字段类型和字段名称,用于为不同编程语言编写的消息生成源代码
基本类型
- int8,,int16, int32, int64 (以及 uint*)
- float32, float64
- string
- time,duration
- 其他 msg文件
msg类型 |
C++对应类型 |
Python对应类型 |
bool |
uint8_t |
bool |
int8 |
int8_t |
int |
int16 |
int16_t |
int |
int32 |
int32_t |
int |
int64 |
int64_t |
int,long |
uint8 |
uint8_t |
int |
uint16 |
uint16_t |
int |
uint32 |
uint32_t |
int |
uint64 |
uint64_t |
int,long |
float32 |
float |
float |
float64 |
float |
float |
string |
std:string |
str,bytes |
time |
ros:Time |
rospy.Time |
duration |
ros::Duration |
rospy.Duration |
srv
简介
- ROS 使用简化的服务描述语言(“srv”)来描述 ROS 服务类型
- 服务描述存储在ROS包的 srv/ 子目录中的 .srv 文件中
- 一个srv文件描述一个服务。它由两部分组成:请求(request)和响应(response),以“---”分隔,上方表示 request数据类型,下面是 response类型
例如:
| int8 FOO=1 |
| int8 BAR=2 |
| int8 foobar |
| another_pkg/AnotherMessage msg |
| --- |
| uint32 SECRET=123456 |
| another_pkg/YetAnotherMessage val |
| CustomMessageDefinedInThisPackage value |
| uint32 an_integer |
创建
- 从另一个包复制现有的srv定义,而不是手动创建新的srv
| roscd finaltest |
| mkdir srv |
| roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv |
| rossrv show finaltest/AddTwoInts |

配置
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 |
| AddTwoInts.srv |
| Person.srv |
| ) |
- 添加生成消息的依赖,默认的时候要添加 std_msgs
| generate_messages( |
| DEPENDENCIES |
| std_msgs |
| ) |
| catkin_package( |
| CATKIN_DEPENDS message_runtime |
| ) |
编写服务端节点
- 在finaltest包中创建src/add_two_ints_server.cpp文件
| #include <ros/ros.h> |
| #include "finaltest/AddTwoInts.h" |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| bool add(finaltest::AddTwoInts::Request & req, finaltest::AddTwoInts::Response & res) |
| { |
| res.sum = req.a + req.b; |
| ROS_INFO("request: x=%ld, y=%ld", long (req.a), long (req.b)); |
| ROS_INFO("sending back response: [%ld]", long (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; |
| } |
编写客户端节点
- 在finaltest包中创建src/add_two_ints_client.cpp文件
| #include <ros/ros.h> |
| #include "finaltest/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<finaltest::AddTwoInts>("add_two_ints"); |
| |
| |
| finaltest::AddTwoInts srv; |
| srv.request.a = atoll(argv[1]); |
| srv.request.b = atoll(argv[2]); |
| |
| |
| client.waitForExistence(); |
| |
| |
| if (client.call(srv)) |
| { |
| ROS_INFO("Sum: %ld", long (srv.response.sum)); |
| } |
| else |
| { |
| ROS_ERROR("Failed to call service add_two_ints"); |
| return 1; |
| } |
| return 0; |
| } |
配置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 ${PROJECT_NAME}_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 ${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岁的心里话
· 按钮权限的设计及实现