ROS2 study notes written in the Python service service and client nodes papers
Learning objectives: to create and run a simple service of the client and server nodes using Python.
background
When the service node through the communication party sends a data request we call the client, then the received data corresponding end we call server. Data structure of a request and response .srv
file decision.
This routine which we make a summation, a node sends a request to add two integers, another node request accordingly.
Preparatory
We know how to create a work space and feature packs
Learning Content
1 Create package
Create a new package for the tutorial
cd ~/dev_ws/src
ros2 pkg create --build-type ament_python py_srvcli --dependencies rclpy example_interfaces
1.1 update package.xml
Since we use the --dependencies
option, we will not need to add dependent options. We only need to fill Feature Pack description defenders name and contact information, license content
<description>Python client server tutorial</description>
<maintainer email="[email protected]">Your Name</maintainer>
<license>Apache License 2.0</license>
1.2 update setup.py
Updated setup.py
and package.xml
consistent
maintainer='Your Name',
maintainer_email='[email protected]',
description='Python client server tutorial',
license='Apache License 2.0',
2. Write the service node service
Into the dev_ws/src/py_srvcli/src
folder, create a service_member_function.py
file, paste the following content saved.
from example_interfaces.srv import AddTwoInts
import rclpy
from rclpy.node import Node
class MinimalService(Node):
def __init__(self):
super().__init__('minimal_service')
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback)
def add_two_ints_callback(self, request, response):
response.sum = request.a + request.b
self.get_logger().info('Incoming request\na: %d b: %d' % (request.a, request.b))
return response
def main(args=None):
rclpy.init(args=args)
minimal_service = MinimalService()
rclpy.spin(minimal_service)
rclpy.shutdown()
if __name__ == '__main__':
main()
2.1 Code Explanation
The first line of service loading message type, and then loaded and ROS2 of the Python client node classes
from example_interfaces.srv import AddTwoInts
import rclpy
from rclpy.node import Node
Next, define a class later, in the constructor function initializes the node's name, and the name of the service, and the type of callback function
def __init__(self):
super().__init__('minimal_service')
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback)
Two numbers of the received callback function returns after respective addition, while print message to the console.
def add_two_ints_callback(self, request, response):
response.sum = request.a + request.b
self.get_logger().info('Incoming request\na: %d b: %d' % (request.a, request.b))
return response
Finally, the main function of the main class initialization ROS2 Python client, create a service node, pending callback.
2.2 Add Program Entry
Open setup.py
and then console_scripts
adding the next program line inlet brackets:
'service = py_srvcli.service_member_function:main',
3. Write client client node
Into the dev_ws/src/py_srvcli/src
folder, create a client_member_function.py
file, paste the following content saved.
import sys
from example_interfaces.srv import AddTwoInts
import rclpy
from rclpy.node import Node
class MinimalClientAsync(Node):
def __init__(self):
super().__init__('minimal_client_async')
self.cli = self.create_client(AddTwoInts, 'add_two_ints')
while not self.cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('service not available, waiting again...')
self.req = AddTwoInts.Request()
def send_request(self):
self.req.a = int(sys.argv[1])
self.req.b = int(sys.argv[2])
self.future = self.cli.call_async(self.req)
def main(args=None):
rclpy.init(args=args)
minimal_client = MinimalClientAsync()
minimal_client.send_request()
while rclpy.ok():
rclpy.spin_once(minimal_client)
if minimal_client.future.done():
try:
response = minimal_client.future.result()
except Exception as e:
minimal_client.get_logger().info(
'Service call failed %r' % (e,))
else:
minimal_client.get_logger().info(
'Result of add_two_ints: for %d + %d = %d' %
(minimal_client.req.a, minimal_client.req.b, response.sum))
break
minimal_client.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
3.1 Code Explanation
Because we need to get input parameters of the program, we have added a new line of import sys
similar and server, first define a class, and then create a type name and server as a node in the constructor.
Then the loop continues looking white server
defined functions and main function is to send the request after
a while loop to detect the corresponding main function in waiting for service while being an exception handling, if the response message is correctly printed.
3.2 Add Program Entry
Open the setup.py
file, and server as we add a client program entry
entry_points={
'console_scripts': [
'service = py_srvcli.service_member_function:main',
'client = py_srvcli.client_member_function:main',
],
},
4. Compile and run
Into the workspace root compile
cd ~/dev_ws
colcon build --packages-select py_srvcli
Open a new terminal, we run the service server
cd ~/dev_ws
source install/setup.bash
ros2 run py_srvcli service
And then open a new terminal, we run the client client
cd ~/dev_ws
source install/setup.bash
ros2 run cpp_srvcli client 2 3
After the client receives the response server-side exit, following receipt of the response
[INFO] [minimal_client_async]: Result of add_two_ints: for 2 + 3 = 5
While also prints out a message server, the client's request received is displayed
[INFO] [minimal_service]: Incoming request
a: 2 b: 3
Now Ctrl+ CTurn off two nodes.
to sum up
Similar operating procedures and topics for the entrance Python remember to add the program otherwise ros2 run
not find the executable file.