当前位置: 首页 > article >正文

ROS2-python服务service和client节点(实现加法运算)

当节点通过服务进行通讯的时候,发送数据请求的一方我们称之为客户端接收数据然后相应的一端我们称之为服务器端请求和响应的数据结构有一个.srv文件决定

本例程当中我们做一个加法运算,一个节点发送一个将两个整数相加的请求,另外一个节点对请求进行相应。

第一步:创建包

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

 功能包叫py_srvcli,example_interfaces也添加到package.xml里面了。

这个接口并不需要我们自己去写,在以后的应用场景下我们也可以自定义接口。(之后的文章会教大家如何写自定义接口)

这个example_interfaces接口可以按照如下方法查找它的路径

ros2 pkg prefix example_interfaces
cat /opt/ros/<ros2-distro>/share/example_interfaces/srv/AddTwoInts.srv

这时你就可以看到数据结构srv里的内容了

第二步:编写服务service节点

进入dev_ws/src/py_srvcli/py_srvcli,创建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()

代码解释:

1、第一行加载了服务的消息类型(也就是接口的路径import它里面的类),然后加载了ROS2的Python客户端和节点的类

from example_interfaces.srv import AddTwoInts

import rclpy
from rclpy.node import Node

2、接下来在构造函数里面初始化了节点的名字minimal_service(可以自定义节点名称但保证下面的代码要改对)

服务类型AddTwoInts ,这是example_interfaces包中定义的服务类型

服务名称add_two_ints,客户端将使用这个名称来找到并调用这个服务

回调函数self.add_two_ints_callback

def __init__(self):
    super().__init__('minimal_service')
    self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback)

3、回调函数将接收到的两个数字相加后返回相应,同时往控制台打印消息。(只有服务端要写回调)

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客户端,创建服务节点,等待处理回调。

def main(args=None):
    rclpy.init(args=args)

    minimal_service = MinimalService()

    rclpy.spin(minimal_service)

    rclpy.shutdown()

第三步:编写客户端client节点

进入 dev_ws/src/py_srvcli/py_srvcli,创建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()
代码解释

由于我们需要获得程序输入的参数,我们新加了一行import sys

和服务端类似,首先定义了一个类,然后在构造函数中创建了一个类型名称和服务端一样的节点。

然后white循环一直寻找服务端
之后是发送请求的函数和main函数的定义
在主函数中while循环检测等待服务的相应,同时进行了一个异常处理,如果响应正确打印消息。

添加程序入口

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

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

编译运行

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

cd ~/dev_ws
colcon build

打开一个新的终端,我们运行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

效果如下:


http://www.kler.cn/a/393800.html

相关文章:

  • 如何使用ffmpeg命令行进行录屏
  • Microsoft 365 Exchange如何设置可信发件IP白名单
  • Rust 所有权机制
  • 基于混合配准策略的多模态医学图像配准方法研究
  • openSUSE 环境下通过 zypper 安装软件
  • 【STM32】基于SPI协议读写SD,详解!
  • linux命令详解,openssl+历史命令详解
  • JDBC概述
  • 移动端【01】面试系统的MVVM重构实践
  • 重构代码之替换参数为显式方法
  • axios如何给某一个请求设置请求头信息
  • 让SQL更优雅!深入浅出【公用表表达式(CTE)】语法及实战案例
  • llama-cpp模型轻量化部署与量化
  • HTTP的了解
  • [智能车摄像头是一种安装在汽车上用于辅助驾驶和提高安全性的重要设备]
  • caozha-CEPCS(新冠肺炎疫情防控系统)
  • odoo-040 odoo17前端的js方法调用后端py方法action报错
  • Java与HTML中的标题、文本和图像
  • 排序算法 - 冒泡
  • Kubernetes实现故障转移和微服务弹性伸缩
  • 「Py」Python基础篇 之 Python都可以做哪些自动化?
  • 本地启动浏览器,并禁用web安全性,解决本地启动时,服务端强制要求https协议导致请求不通的问题
  • RabbitMQ的死信队列
  • UE5 HLSL 学习笔记
  • ISP——你可以从这里起步(二)
  • 基于微信小程序的农场管理系统的设计与实现,LW+源码+讲解