栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

ROS2教程 09 服务通信Service

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ROS2教程 09 服务通信Service

一、服务端 Server 1.新建功能包
ros2 pkg create --build-type ament_python py_srv_cli --dependencies rclpy example_interfaces

此处在新建功能包时为其添加了依赖 rclpy和example_interfaces
example_interfaces是ros2的数据类型接口,里面有用于ROS2教学的一些样例数据类型,比如example_interfaces/srv/AddTwoInts就是本示例要使用的数据类型

2.新建服务端 Server
from example_interfaces.srv import AddTwoInts # 导入需要使用的srv数据类型

import rclpy
from rclpy.node import Node


class MinimalService(Node):

    def __init__(self):
        super().__init__('minimal_service')
        # 创建server 
        # 数据类型,服务名称,回调函数
        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 requestna: %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()
3.添加依赖

在功能包目录下打开package.xml,修改以下内容[可选,不影响使用]
例子:

Examples of minimal publisher/subscriber using rclpy
Herman Ye
Apache License 2.0

继续添加内容[必须]
当功能包里的代码被执行时,这些语句声明了功能包的依赖
因为在创建功能包时已经添加了依赖,因此此处无需重复添加

  rclpy
  example_interfaces
4.添加入口点

打开setup.py,添加入口点

maintainer='Herman Ye',
maintainer_email='hermanye233@icloud.com',
description='Examples of minimal publisher/subscriber using rclpy',
license='Apache License 2.0',

在entry_points下的这个位置添加以下命令

'service = py_srv_cli.service_member_function:main',

最终效果:

    entry_points={
        'console_scripts': [
        'service = py_srv_cli.service_member_function:main',
        ],
    },
二、客户端 Client 1.新建客户端 Client

在和服务端相同的目录下新建client_member_function.py
源码如下:

import sys #客户端节点代码使用sys.argv来访问命令行输入的请求命令的参数,这是客户端的特别之处

from example_interfaces.srv import AddTwoInts # 数据类型导入
import rclpy
from rclpy.node import Node # 节点必备的类


class MinimalClientAsync(Node):

    def __init__(self):
        super().__init__('minimal_client_async') # 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() #request部分定义

    def send_request(self): # 发送函数
        self.req.a = int(sys.argv[1]) # 命令行输入的数1
        self.req.b = int(sys.argv[2]) # 命令行输入的数2 sys.argv[x]获取了命令行输入的参数
        self.future = self.cli.call_async(self.req) #future包含反馈的response


def main(args=None):
    rclpy.init(args=args) #初始化rclpy

    minimal_client = MinimalClientAsync() # 客户端
    minimal_client.send_request() # 客户端发送请求

    while rclpy.ok(): # 当ros准备就绪时
        rclpy.spin_once(minimal_client) # 循环客户端
        if minimal_client.future.done(): # 当future完成时,代表服务端已经完成了服务并且反馈response了result
            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()

call_async()
也可以使用call_async()来执行异步呼叫服务,作用和上文中的send_request类似但更简单,上文的send_request有输入参数,因此独立成发送函数

call_async(request)
Make a service request and asyncronously get the result.

Parameters
request (~SrvTypeRequest) – The service request.

Return type
Future

Returns
A future that completes when the request does.

Raises
TypeError if the type of the passed request isn’t an instance of the Request type of the provided service when the client was constructed.

要获取更多信息请查阅rclpy文档

2.添加入口点

打开setup.py,添加入口点
在entry_points下的这个位置添加以下命令

'client = py_srv_cli.client_member_function:main',

最终效果:

    entry_points={
        'console_scripts': [
        'service = py_srv_cli.service_member_function:main',
        'client = py_srv_cli.client_member_function:main',
        ],
    },
三、测试 客户端-服务-服务端 1.编译
colcon build --packages-select py_srv_cli
2.运行

先运行服务端

ros2 run py_srvcli service

随后运行客户端并键入参数

ros2 run py_srvcli client 2 3
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/921033.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号