Keypoints
- Define srv file
- Add package dependency in package.xml
- Add srv file in CMakeLists.txt
- Compile the package
- Test client and server
srv file is similar to msg file, but it has two parts: request and response.
string name
uint8 age
uint8 sex
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
--- # three dashes is a separator to separate request(up) and response(down)
string result
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
add_service_files(FILES Person.srv)
generate_messages(DEPENDENCIES std_msgs)
catkin_package(
CATKIN_DEPENDS geometry_msgs roscpp rospy turtlesim message_runtime
)
catkin_make
#include <ros/ros.h>
#include "learning_service/Person.h"
int main(int argc, char** argv){
ros::init(argc, argv, "person_client");
ros::NodeHandle nh;
// wait for service to start
ros::service::waitForService("/show_person");
// create client. Data type is learning_service::Person, service name is /show_person, client name is person_client
ros::ServiceClient person_client = nh.serviceClient<learning_service::Person>("/show_person");
learning_service::Person srv;
srv.request.name = "Tom";
srv.request.age = 18;
srv.request.sex = learning_service::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);
// call service
person_client.call(srv);
ROS_INFO("Show person result: %s", srv.response.result.c_str());
}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
import sys
from learning_service.srv import Person, PersonRequest
def person_client():
rospy.init_node('person_client')
# wait for service to start
rospy.wait_for_service('/show_person')
try:
person_client = rospy.ServiceProxy('/show_person', Person)
response = person_client("Tom", 20, PersonRequest.male)
return response.result
except rospy.ServiceException as e:
print("Service call failed: %s" % e)
if __name__ == "__main__":
print("Show person result: %s" % person_client())
#include <ros/ros.h>
#include "learning_service/Person.h"
// parameters are request: req, response: res
bool personCallback(learning_service::Person::Request &req, learning_service::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 nh;
// create server. service name is /show_person, server name is person_server
ros::ServiceServer person_service = nh.advertiseService("/show_person", personCallback);
ROS_INFO("Ready to show person information.");
ros::spin();
}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
from learning_service.srv import Person, PersonResponse
def personCallback(req):
rospy.loginfo("Person: name:%s age:%d sex:%d", req.name, req.age, req.sex)
return PersonResponse("OK")
def person_server():
rospy.init_node('person_server')
s = rospy.Service('/show_person', Person, personCallback)
rospy.loginfo("Ready to show person information.")
rospy.spin()
if __name__ == "__main__":
person_server()
add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
## add_dependencies is used to add dependency on other packages. Here is to add dependency for our dynamic head file.
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)
catkin_make
roscore
rosrun learning_service person_server
rosrun learning_service person_client