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 a
uint8 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>
xxxxxxxxxx
add_service_files(FILES IntPlus.srv)
generate_messages(DEPENDENCIES std_msgs)
xxxxxxxxxx
cd ~/catkin_ws
catkin_make
IntPlus_server.cpp
xxxxxxxxxx
#include <ros/ros.h>
#include "learning_server/IntPlus.h"
// service回调函数,输入参数req,输出参数res
bool 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,注册回调函数IntPlusCallback
ros::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;
}
xxxxxxxxxx
add_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
xxxxxxxxxx
client:
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)
xxxxxxxxxx
roscore
rosrun learning_server IntPlus_client
rosrun 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 rospy
from learning_server.srv import IntPlus, IntPlusResponse
def 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,注册回调函数IntPlusCallback
s = 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 sys
import rospy
from learning_server.srv import IntPlus, IntPlusRequest
def 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.result
except rospy.ServiceException, e:
print "failed to call service : %s"%e
if __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
xxxxxxxxxx
server:
from learning_server.srv import IntPlus, IntPlusResponse
client:
from learning_server.srv import IntPlus, IntPlusRequest
use
xxxxxxxxxx
server:
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
xxxxxxxxxx
sudo chmod a+x IntPlus_server.py
sudo chmod a+x IntPlus_client.py
run a program
xxxxxxxxxx
roscore
rosrun learning_server IntPlus_client.py
rosrun 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.