Switch to~/catkin_ ws/src/learning_ Under the server function package directory, create a new folder named srv to store custom service messages.
Switch to the srv directory and create a new blank srv file, with srv as the suffix to indicate that it is an srv file. Here we use IntPlus.srv as an example to copy the following code into the just created srv file.
xuint8 auint8 b---uint8 result
Here is an explanation of the composition of the SRV file, which is divided into two parts by the symbol - - - - -. The upper side represents the request and the lower side is the response.
xxxxxxxxxx<build_depend>message_generation</build_depend><exec_depend>message_runtime</exec_depend>
xxxxxxxxxxadd_service_files(FILES IntPlus.srv)generate_messages(DEPENDENCIES std_msgs)
xxxxxxxxxxcd ~/catkin_wscatkin_make
IntPlus_server.cpp
xxxxxxxxxx#include <ros/ros.h>#include "learning_server/IntPlus.h"// service回调函数,输入参数req,输出参数resbool IntPlusCallback(learning_server::IntPlus::Request &req,learning_server::IntPlus::Response &res){ROS_INFO("number 1 is:%d ,number 2 is:%d ", req.a, req.b);// 显示请求数据res.result = req.a + req.b ;// 反馈结果为两数之和return res.result;}int main(int argc, char **argv){ros::init(argc, argv, "IntPlus_server"); // ROS节点初始化ros::NodeHandle n;// 创建节点句柄// 创建一个server,注册回调函数IntPlusCallbackros::ServiceServer Int_Plus_service = n.advertiseService("/Two_Int_Plus", IntPlusCallback);// 循环等待回调函数ROS_INFO("Ready to caculate.");ros::spin();return 0;}
IntPlus_client.cpp
xxxxxxxxxx#include <ros/ros.h>#include "learning_server/IntPlus.h"#include <iostream>using namespace std;int main(int argc, char** argv){int i,k;cin>>i;cin>>k;ros::init(argc, argv, "IntPlus_client");// 初始化ROS节点ros::NodeHandle node;// 创建节点句柄// 发现/Two_Int_Plus服务后,创建一个服务客户端ros::service::waitForService("/Two_Int_Plus");ros::ServiceClient IntPlus_client = node.serviceClient<learning_server::IntPlus>("/Two_Int_Plus");// 初始化learning_service::IntPlus的请求数据learning_server::IntPlus srv;srv.request.a = i;srv.request.b = k;ROS_INFO("Call service to plus %d and %d", srv.request.a, srv.request.b);// 请求服务调用IntPlus_client.call(srv);// 显示服务调用结果ROS_INFO("Show the result : %d", srv.response.result);// 显示服务调用结果return 0;}
xxxxxxxxxxadd_executable(IntPlus_server src/IntPlus_server.cpp)target_link_libraries(IntPlus_server ${catkin_LIBRARIES})add_dependencies(IntPlus_server ${PROJECT_NAME}_generate_messages_cpp)add_executable(IntPlus_client src/IntPlus_client.cpp)target_link_libraries(IntPlus_client ${catkin_LIBRARIES})add_dependencies(IntPlus_client ${PROJECT_NAME}_generate_messages_cpp)
The implementation process here is the same as before, with the main difference being the introduction of header files and the use of custom service files:The import header file is
xxxxxxxxxx#include "learning_server/IntPlus.h"
Front learning_ Server is the name of the feature pack, followed by IntPlus. h, which is the header file name generated by the previously created srv fileUsing custom service files is
xxxxxxxxxxclient:learning_server::IntPlus srv;srv.request.a = i;srv.request.b = k;#i,k为终端输入的加数ros::ServiceClient IntPlus_client = node.serviceClient<learning_server::IntPlus>("/Two_Int_Plus");IntPlus_client.call(srv);server:ros::ServiceServer Int_Plus_service = n.advertiseService("/Two_Int_Plus", IntPlusCallback);bool IntPlusCallback(learning_server::IntPlus::Request &req,learning_server::IntPlus::Response &res)
xxxxxxxxxxroscorerosrun learning_server IntPlus_clientrosrun learning_server IntPlus_server

Running IntPlus_ After the server, it will prompt to prepare for calculation; Running IntPlus_ After the client, the terminal inputs two integer numbers, followed by IntPlus_ The server accountant calculates the result and returns it to IntPlus_ Client, and then print out the results.
IntPlus_server.py
xxxxxxxxxx#!/usr/bin/env python# -*- coding: utf-8 -*-import rospyfrom learning_server.srv import IntPlus, IntPlusResponsedef IntPlusCallback(req):rospy.loginfo("Ints: a:%d b:%d", req.a, req.b)# 显示请求数据return IntPlusResponse(req.a+req.b)# 反馈数据def IntPlus_server():rospy.init_node('IntPlus_server')# ROS节点初始化# 创建一个server,注册回调函数IntPlusCallbacks = rospy.Service('/Two_Int_Plus', IntPlus, IntPlusCallback)print "Ready to caculate two ints."# 循环等待回调函数rospy.spin()if __name__ == "__main__":IntPlus_server()
IntPlus_client.py
xxxxxxxxxx#!/usr/bin/env python# -*- coding: utf-8 -*-import sysimport rospyfrom learning_server.srv import IntPlus, IntPlusRequestdef Plus_client():# ROS节点初始化rospy.init_node('IntPlus_client')rospy.wait_for_service('/Two_Int_Plus')try:Plus_client = rospy.ServiceProxy('/Two_Int_Plus', IntPlus)response = Plus_client(22, 20)# 请求服务调用,输入请求数据return response.resultexcept rospy.ServiceException, e:print "failed to call service : %s"%eif __name__ == "__main__":#服务调用并显示调用结果print "Show two_int_plus result : %s" %(Plus_client())
Here is mainly an explanation of how to import a custom service message module and use it:Import
xxxxxxxxxxserver:from learning_server.srv import IntPlus, IntPlusResponseclient:from learning_server.srv import IntPlus, IntPlusRequest
use
xxxxxxxxxxserver:s = rospy.Service('/Two_Int_Plus', IntPlus, IntPlusCallback)return IntPlusResponse(req.a+req.b)# 反馈数据client:response = Plus_client(12, 20)# 请求服务调用,输入请求数据return response.result
Before running the program, add executable permissions to the py file
xxxxxxxxxxsudo chmod a+x IntPlus_server.pysudo chmod a+x IntPlus_client.py
run a program
xxxxxxxxxxroscorerosrun learning_server IntPlus_client.pyrosrun learning_server IntPlus_server.py
What is inconsistent with the C++version here is that the addend is set in the program (12 and 20), so once the service is started, the result can be returned immediately.