ROS:服务机制(Service)

张开发
2026/4/17 20:39:47 15 分钟阅读

分享文章

ROS:服务机制(Service)
ROS 的服务机制Service是一种同步的请求-响应通信方式类似于RPCRemote Procedure Call远程过程调用。它通常用于一次性请求 返回结果的场景比如机器人请求地图服务器加载地图请求计算某个结果例如两个数相加请求机器人执行某个动作并返回结果和Topic发布/订阅不同Service 是一对一 同步通信。一、ROS通信方式整体结构在 ROS 中主要有三种通信机制通信方式特点使用场景Topic异步、发布订阅传感器数据、控制指令Service同步、请求响应计算请求、状态查询Action长时间任务导航、机械臂动作二、Service 的核心组成ROS Service 由三部分组成Service├── Service Server服务端├── Service Client客户端└── Service Messagesrv文件Service Server服务端服务器负责接收客户端请求执行计算返回结果Service Client客户端调用服务的一方客户端会发送请求等待服务器处理接收返回值Service Messagesrv 文件Service 使用.srv 文件定义通信格式格式Request---Response示例int64 aint64 b---int64 sum含义客户端发送ab服务器返回sum三、Service 工作流程核心完整流程如下Client Server| ||----- request (a,b) ----------|| || 执行计算| ||------ response (sum) ------|| |详细步骤第一步Server 注册服务服务端启动ros::ServiceServer service nh.advertiseService(...)此时会向ROS Master注册第二步Client 查询服务客户端调用client nh.serviceClient(...)Client 会向ROS Master 查询/add_two_ints 在哪里Master 返回Service Server 地址第三步建立 TCP 连接ROS 使用TCPROS客户端与服务器建立 TCP 连接。第四步发送 Request客户端发送ab第五步Server 处理请求Server 执行回调函数bool add(Request req, Response res) { res.sum req.a req.b; }第六步返回 ResponseServer 返回sum客户端收到结果四、Service 通信结构底层ROS Service 的底层是TCP ROS 序列化通信流程Client|| 1 查询服务vROS Master|| 2 返回Server地址vClient ----TCP---- ServerRequestResponse注意ROS Master 不参与实际数据通信它只负责服务发现五、Service 的特点同步通信调用服务时client.call()一对一通信Service 只能一个 Client - 一个 Server不像 Topic 可以多个 subscriber适合短任务Service 不适合长时间任务例如导航机械臂抓取这些应该用Action。六、Service 的代码结构C服务端#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; return true; } int main(int argc, char **argv) { ros::init(argc, argv, add_two_ints_server); ros::NodeHandle nh; ros::ServiceServer service nh.advertiseService(add_two_ints, add); ros::spin(); return 0; }客户端#include ros/ros.h #include beginner_tutorials/AddTwoInts.h int main(int argc, char **argv) { ros::init(argc, argv, add_two_ints_client); ros::NodeHandle nh; ros::ServiceClient client nh.serviceClientbeginner_tutorials::AddTwoInts(add_two_ints); beginner_tutorials::AddTwoInts srv; srv.request.a 1; srv.request.b 2; if(client.call(srv)) { ROS_INFO(sum: %ld, srv.response.sum); } return 0; }

更多文章