[ROS study notes] (eight) the definition and use of service data

First, the purpose

Each time the client requests a data request, the server sends the data once. The data format is personal information, such as name, gender, etc.

Two, custom service data

This step is similar to the definition and use process of topic messages

1. Define the srv file

Then learning_servicefolder create a new folder srv, then in srva new folder within the Person.srvfile, as follows

string name
uint8  age
uint8  sex

uint8 unknown = 0
uint8 male    = 1
uint8 female  = 2

---
string result

—The above is the request data, —The following is the response data
Insert picture description here

2. Add function package dependency in package.xml

Open learning_service/package.xml, add the following code in the last part of the file

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

Insert picture description here

3. Add compilation options in CMakeLists.txt

First, find_packageadd a statement in the last line message_generationto add dependent feature packages

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  turtlesim
  message_generation
)

Insert picture description here

Add below this function

add_service_files(
  FILES
  Person.srv
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

add_message_files, using Person.srv as the defined interface

generate_messages, a function package that needs to be relied upon when compiling the Person.srv file
Insert picture description here

Then below catkin specific configurationin catkin_packages, add-dependent message_runtime, the modified code as follows:

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES learning_topic
   CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
#  DEPENDS system_lib
)

Insert picture description here

4. Compile and generate related files
cd ~/catkin_ws
catkin_make

Three, create server code

~/catkin_ws/src/learning_service/srcCreate a person_server.cpp` file in the directory

/**
 * 该例程将执行/show_person服务,服务数据类型learning_service::Person
REFERENCE:www.guyuehome.com
 */
 
#include <ros/ros.h>
#include "learning_service/Person.h"

// service回调函数,输入参数req,输出参数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节点初始化
    ros::init(argc, argv, "person_server");

    // 创建节点句柄
    ros::NodeHandle n;

    // 创建一个名为/show_person的server,注册回调函数personCallback
    ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);

    // 循环等待回调函数
    ROS_INFO("Ready to show person informtion.");
    ros::spin();

    return 0;
}

Fourth, create client code

Also ~/catkin_ws/src/learning_service/srccreate a person_client.cppfile in the directory , its content is:

/**
 * 该例程将请求/show_person服务,服务数据类型learning_service::Person
REFERENCE:www.guyuehome.com
 */

#include <ros/ros.h>
#include "learning_service/Person.h"

int main(int argc, char** argv)
{
    // 初始化ROS节点
	ros::init(argc, argv, "person_client");

    // 创建节点句柄
	ros::NodeHandle node;

    // 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
	ros::service::waitForService("/show_person");
	ros::ServiceClient person_client = node.serviceClient<learning_service::Person>("/show_person");

    // 初始化learning_service::Person的请求数据
	learning_service::Person srv;
	srv.request.name = "Huffie";
	srv.request.age  = 21;
	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);

	person_client.call(srv);

	// 显示服务调用结果
	ROS_INFO("Show person result : %s", srv.response.result.c_str());

	return 0;
};

Insert picture description here

Five, configure server/client code compilation rules

Open learning_service, CMakeLists.txtadd code in the image area

add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
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)

Insert picture description here

Six, compile and run publishers and subscribers

Compile first

cd catkin_ws
catkin_make

Run publisher and subscriber

roscore
rosrun learning_service person_server
rosrun learning_service person_client

Each time the client requests, it will receive data once
Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_44543463/article/details/114140335