ROS application development entry service data definition and use

ROS is the abbreviation of Robot Operating System. This article introduces the introduction of ROS application development, the definition and use of service data. The communication between the client and the server uses service data. This article first defines a service data. After the compilation is successful, use a server and a client to verify. The client can also use the rosservice call directly, so that the client does not need a program. The test verification is the C++ code first, and then the python code. You can also choose to only look at the one you are familiar with.

Function package creation

This article is   a continuation of the programming of the Client Client in the introduction to ROS application development . If you have created a function package in that article, you don't need it here, just skip this section.

The  ROS workspace  is established in the article ROS Development and Application Preparation: Create a Workspace . Now, create a functional package:

cd ~/catkin_ws/src

catkin_create_pkg  learning_service std_msgs roscpp rospy geometry_msgs turtlesim
 

Custom service data

Create a new directory srv under the project package directory

cd ~/catkin_ws/src/learning_service

mkdir srv

cd srv

Then create a new Person.srv file

nano Person.srv

The content of the file is:

string name
uint8  age
uint8  sex

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

---
string result

Let's take a look at the characteristics of this file:

 

The request data and the response data are separated by --- 3 horizontal lines-, the upper part is the request data, and the lower part is the response data.

The above is to send data, the data type that is not assigned is the data type, and the assigned value may be an enumeration class, so you need to enter 3 variables string name, uint8 age, uint8 sex

Below is the response data, here is just a string

 

Go back to the project package directory, open and edit package.xml:

 cd ~/catkin_ws/src/learning_service

nano package.xml

Add the following 2 lines:

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


The added position refers to the following position, which is above the comment in front of <export>:

 <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>turtlesim</exec_depend>
 
  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>
 
  <!-- The export tag contains other, unspecified, tags -->
  <export>


Then open and edit CMakeLists.txt, a total of 3

nano CMakeLists.txt

First add message_generation in find_package and
add it as follows:

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

 Add the following code, which can also be used as 2 lines,

add_service_files(
  FILES
  Person.srv
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

The adding location is as follows: 

## Generate added messages and services with any dependencies listed here
# generate_messages(
#   DEPENDENCIES
#   geometry_msgs#   std_msgs
# )

add_service_files(
  FILES
  Person.srv
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

################################################
## Declare ROS dynamic reconfigure parameters ##
################################################

In catkin_package, uncomment the CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim line, and add message_runtime to
have the following effect:

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

After modifying these two files, compile in the workspace.

Compilation must go back to the ~/catkin_ws directory

cd ~/catkin_ws

catkin_make

If the compilation is successful, the service data is defined and ready.

Look at the final stage of compilation information

Scanning dependencies of target learning_service_generate_messages_py
[ 40%] Generating Python code from SRV learning_service/Person
[ 45%] Generating Python srv __init__.py for learning_service
[ 45%] Built target turtle_command_server
Scanning dependencies of target learning_service_generate_messages_eus
[ 50%] Generating EusLisp code from learning_service/Person.srv
[ 54%] Generating EusLisp manifest code for learning_service
[ 54%] Built target learning_service_generate_messages_py
Scanning dependencies of target learning_service_generate_messages_nodejs
[ 59%] Generating Javascript code from learning_service/Person.srv
[ 59%] Built target learning_service_generate_messages_nodejs
Scanning dependencies of target learning_service_generate_messages_cpp
[ 63%] Generating C++ code from learning_service/Person.srv
[ 63%] Built target learning_service_generate_messages_cpp
Scanning dependencies of target learning_service_generate_messages_lisp
[ 68%] Generating Lisp code from learning_service/Person.srv
[ 68%] Built target learning_service_generate_messages_lisp
[ 72%] Built target learning_topic_generate_messages_nodejs
[ 77%] Built target learning_topic_generate_messages_cpp
[ 86%] Built target learning_topic_generate_messages_eus
[ 95%] Built target learning_topic_generate_messages_py
[100%] Built target learning_topic_generate_messages_lisp
[100%] Built target learning_topic_generate_messages
[100%] Built target learning_service_generate_messages_eus
Scanning dependencies of target learning_service_generate_messages
[100%] Built target learning_service_generate_messages

It seems to be ready for multiple languages.

c++ verify source code

To use the service data to verify, you need two programs for the server and the client, and we put them in the src directory of the project directory

Go to the src directory and create the files person_client.cpp and person_server.cpp.cpp respectively

cd ~/catkin_ws/src/learning_service/src

nano person_client.cpp

The content of the file is:

/**
 * 该例程将请求/show_person服务,服务数据类型learning_service::Person
 */

#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 = "Tom";
        srv.request.age  = 20;
        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;
};

nano person_server.cpp

The content of the file is:

/**
 * 该例程将执行/show_person服务,服务数据类型learning_service::Person
 */
 
#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;
}


2 files are ready.

Configure cmake file

In the ~/catkin_ws/src/learning_service/ directory, there is a CMakeLists.txt file, we need to modify this file

cd  ~/catkin_ws/src/learning_service/

nano CMakeLists.txt 

Add the following lines to this file,

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)

The added position is the end of the Build section. Refer to the following position, which is in front of ## install ##, and then the previous client and the server add 2 lines after each:

## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
#   ${catkin_LIBRARIES}
# )
add_executable(turtle_spawn src/turtle_spawn.cpp)
target_link_libraries(turtle_spawn ${catkin_LIBRARIES})

add_executable(turtle_command_server src/turtle_command_server.cpp)
target_link_libraries(turtle_command_server ${catkin_LIBRARIES})

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)

#############
## Install ##
#############

Save, exit

This completes the compilation and configuration.

Compile and run the test

Compilation must go back to the ~/catkin_ws directory

cd ~/catkin_ws

catkin_make

It should be sourced once after compilation:

source devel/setup.bash

If there is an error in the compilation, the error must be eliminated and the test will be run after the compilation is complete.

Open a terminal, start ros, execute

roscore

Open another terminal, start the server, and execute

rosrun learning_service person_server

Open another terminal and start the client:

rosrun learning_service person_client

In fact, you can also use rosservice directly as a client for testing

rosservice call /show_person leon 12 2

or

leon@ubuntu:~$ rosservice call /show_person "name:'Leon'
age: 50
sex: 20" The 
program running results are as follows: the client first executes the client twice, then the rosservice call twice, and then the client again

c++ verification is successful.

python verify source code

To verify the service data, two programs, the server side and the client side, are required. We put them in the scripts directory of the project directory.

Go to the scripts directory and create the files person_client.py and person_server.py respectively, if not, create one (mkdir scripts).

~/catkin_ws/src/learning_service/scripts

nano person_server.py

The content of the file is:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 该例程将执行/show_person服务,服务数据类型learning_service::Person

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():
	# ROS节点初始化
    rospy.init_node('person_server')

	# 创建一个名为/show_person的server,注册回调函数personCallback
    s = rospy.Service('/show_person', Person, personCallback)

	# 循环等待回调函数
    print "Ready to show person informtion."
    rospy.spin()

if __name__ == "__main__":
    person_server()


nano person_client.py

The content of the file is:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 该例程将请求/show_person服务,服务数据类型learning_service::Person

import sys
import rospy
from learning_service.srv import Person, PersonRequest

def person_client():
	# ROS节点初始化
    rospy.init_node('person_client')

	# 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
    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, e:
        print "Service call failed: %s"%e

if __name__ == "__main__":
	#服务调用并显示调用结果
    print "Show person result : %s" %(person_client())


Run test

Because python does not need to be compiled, but needs to be set as an executable file

chmod +x *.py

Open a terminal, start ros, execute

roscore

First source:

source ~/catkin_ws/devel/setup.bash

Open another terminal, start the server, and execute

rosrun learning_service person_server.py 

Open another terminal and start the client:

rosrun learning_service person_client.py

Client authentication can also directly use rosservice call

rosservice call /show_person leon 12 2

or

leon@ubuntu:~$ rosservice call /show_person "name: 'Leon'
age: 50
sex: 20" 

rosservice list can list all service names.

The results of the program are as follows:

 

Python verification is successful.

The source code can also be downloaded at https://github.com/huchunxu/ros_21_tutorials

The full text is introduced here.
 

Guess you like

Origin blog.csdn.net/leon_zeng0/article/details/114994859