ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

ROS2学习笔记之编写Python服务service和client节点篇

2020-02-21 17:05:35  阅读:677  来源: 互联网

标签:__ service Python self request client minimal


ROS2学习笔记之编写Python服务service和client节点篇

学习目标:用Python创建并运行简单的服务的客户端和服务端节点。

背景

当节点通过服务进行通讯的时候,发送数据请求的一方我们称之为客户端,接收数据然后相应的一端我们称之为服务器端。请求和响应的数据结构有一个.srv文件决定。
本例程当中我们做一个加法运算,一个节点发送一个将两个整数相加的请求,另外一个节点对请求进行相应。

前期准备

知道如何创建工作空间和功能包

学习内容

1 创建包

为教程新建一个包

cd ~/dev_ws/src
ros2 pkg create --build-type ament_python py_srvcli --dependencies rclpy example_interfaces

1.1 更新 package.xml

由于我们使用了--dependencies选项,我们就不在需要添加依赖选项。我们只需要填写功能包的描述,维护者的姓名和联系方式,许可这些内容

<description>Python client server tutorial</description>
<maintainer email="you@email.com">Your Name</maintainer>
<license>Apache License 2.0</license>

1.2 更新 setup.py

更新setup.pypackage.xml保持一致

maintainer='Your Name',
maintainer_email='you@email.com',
description='Python client server tutorial',
license='Apache License 2.0',

2. 编写服务service节点

进入dev_ws/src/py_srvcli/src文件夹,创建service_member_function.py文件,粘贴下面的内容后保存。

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 代码解释

第一行加载了服务的消息类型,然后加载了ROS2的Python客户端和节点的类

from example_interfaces.srv import AddTwoInts

import rclpy
from rclpy.node import 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

最后,主函数主类初始化ROS2 Python客户端,创建服务节点,等待处理回调。

2.2 添加程序入口

打开setup.py然后在console_scripts 下一行括号之内添加程序入口:

'service = py_srvcli.service_member_function:main',

3 编写客户端client节点

进入dev_ws/src/py_srvcli/src文件夹,创建client_member_function.py文件,粘贴下面的内容后保存。

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 代码解释

由于我们需要获得程序输入的参数,我们新加了一行import sys
和服务端类似,首先定义了一个类,然后在构造函数中创建了一个类型名称和服务端一样的节点。
然后white循环一直寻找服务端
之后是发送请求的函数和main函数的定义
在主函数中while循环检测等待服务的相应,同时进行了一个异常处理,如果响应正确打印消息。

3.2 添加程序入口

打开setup.py文件,和服务端一样我们添加客户端的程序入口

entry_points={
    'console_scripts': [
        'service = py_srvcli.service_member_function:main',
        'client = py_srvcli.client_member_function:main',
    ],
},

4. 编译运行

进入工作空间根目录进行编译

cd ~/dev_ws
colcon build --packages-select py_srvcli

打开一个新的终端,我们运行service服务端

cd ~/dev_ws
source install/setup.bash
ros2 run py_srvcli service

再打开一个新的终端,我们运行client客户端

cd ~/dev_ws
source install/setup.bash
ros2 run cpp_srvcli client 2 3

客户端收到服务端的响应后退出,收到响应如下

[INFO] [minimal_client_async]: Result of add_two_ints: for 2 + 3 = 5

同时服务器端也打印出消息,显示收到客户端的请求

[INFO] [minimal_service]: Incoming request
a: 2 b: 3

现在Ctrl + C关掉两个节点。

总结

操作流程和话题类似,对于Python记得添加程序的入口不然ros2 run找不到可执行的文件。

dckwin 发布了70 篇原创文章 · 获赞 50 · 访问量 3万+ 私信 关注

标签:__,service,Python,self,request,client,minimal
来源: https://blog.csdn.net/qq_38649880/article/details/104429277

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有