【2】 ROS2学习——核心概念的学习Ⅰ(节点、话题、服务)



一、节点

1.节点的概念

实现机器人的各项功能,如用摄像头获取外界环境信息、用电机驱动轮子前进等等。

特点是:

  1. 执行某些具体的任务;
  2. 每一个节点独立运行的可执行文件;
  3. 节点编程语言可以不同;
  4. 节点处在的位置可以是位于硬件上,也可以位于云端;
  5. 节点是唯一命名的,便于查询节点的状态等。

2.节点的核心代码

"""
创建一个HelloWorld节点, 节点功能输出“HelloWorld”日志
节点实现效果:在终端每隔0.5s输出一句“HelloWorld”
"""
class HelloWorldNode(Node):
    def __init__(self, name):
        super().__init__(name)                     # ROS2节点父类初始化
        while rclpy.ok():                          # ROS2系统是否正常运行
            self.get_logger().info("Hello World")  # ROS2日志输出
            time.sleep(0.5)                        # 休眠控制循环时间

3.创建节点流程

  1. 编程接口初始化
  2. 创建节点并初始化
  3. 实现节点功能
  4. 销毁节点并关闭接口

二、话题

1.话题的概念

节点是机器人实现各种功能,但这些功能并不是独立的,通过话题就可以构建节点间传递数据的桥梁。话题通信的特性是单向传输,从一个节点到另一个节点,发布者发送数据,订阅者接收数据。如发布者发布一个话题的名称,将数据发送到话题上,订阅者就可以通过话题查看发布的内容。

话题通信另一个特性就是异步,发布者发出数据后,并不知道订阅者什么时候可以收到,只管发,适合用于一些周期发布的数据,比如传感器的数据,运动控制的指令等等。

话题模型如上图所示,创建两个节点分别为发布者和订阅者,发布者发布一个话题的名称,将数据发送到话题上,订阅者就可以通过话题查看发布的内容。

多对多模型如上所示,一个发布者发布的数据,可以同时被不同的订阅者获得,即一对多模型。

2.话题的核心代码

话题的发布者:

"""
创建一个发布者节点
"""
class PublisherNode(Node):

    def __init__(self, name):
        super().__init__(name)                                    # ROS2节点父类初始化
        self.pub = self.create_publisher(String, "chatter", 10)   # 创建发布者对象(消息类型、话题名、队列长度)
        self.timer = self.create_timer(0.5, self.timer_callback)  # 创建一个定时器(单位为秒的周期,定时执行的回调函数)

    def timer_callback(self):                                     # 创建定时器周期执行的回调函数
        msg = String()                                            # 创建一个String类型的消息对象
        msg.data = 'Hello World'                                  # 填充消息对象中的消息数据
        self.pub.publish(msg)                                     # 发布话题消息
        self.get_logger().info('Publishing: "%s"' % msg.data)     # 输出日志信息,提示已经完成话题发布

话题的订阅者:

"""
创建一个订阅者节点
"""
class SubscriberNode(Node):

    def __init__(self, name):
        super().__init__(name)                             # ROS2节点父类初始化
        self.sub = self.create_subscription(\
            String, "chatter", self.listener_callback, 10) # 创建订阅者对象(消息类型、话题名、订阅者回调函数、队列长度)

    def listener_callback(self, msg):                      # 创建回调函数,执行收到话题消息后对数据的处理
        self.get_logger().info('I heard: "%s"' % msg.data) # 输出日志信息,提示订阅收到的话题消息

3.创建话题流程

发布者端订阅者端
1. 编程接口初始化1. 编程接口初始化
2. 创建节点并初始化2. 创建节点并初始化
3. 创建发布者对象3. 创建订阅者对象
4. 创建并填充话题消息4. 回调函数处理话题数据
5. 发布话题消息5. 销毁节点并关闭接口
6. 销毁节点并关闭接口

三、服务

1.服务的概念

ROS另一种常用的通信方法是服务,可以实现你问我答的同步通信效果,适合同步性要求更高的数据,比如获取机器视觉识别到的目标位置。

客户端/服务器模型如上图所示,创建两个节点分别为服务端和客户端,客户端在需要某些数据的时候,针对某个具体的服务,发送请求信息,服务器端收到请求之后,就会进行处理并反馈应答信息,即为一问一答的形式。

一对多服务模型
如上图所示为一对多通信。不同的客户端可以向同一个服务端发送请求并获得想要的数据。

2.服务的核心代码

创建服务端:

class adderServer(Node):
    def __init__(self, name):
        super().__init__(name)                                                           # ROS2节点父类初始化
        self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.adder_callback)  # 创建服务器对象(接口类型、服务名、服务器回调函数)

    def adder_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                          # 反馈应答信息

创建客户端:

class adderClient(Node):
    def __init__(self, name):
        super().__init__(name)                                       # ROS2节点父类初始化
        self.client = self.create_client(AddTwoInts, 'add_two_ints') # 创建服务客户端对象(服务接口类型,服务名)
        while not self.client.wait_for_service(timeout_sec=1.0):     # 循环等待服务器端成功启动
            self.get_logger().info('service not available, waiting again...') 
        self.request = AddTwoInts.Request()                          # 创建服务请求的数据对象

    def send_request(self):                                          # 创建一个发送服务请求的函数
        self.request.a = int(sys.argv[1])
        self.request.b = int(sys.argv[2])
        self.future = self.client.call_async(self.request)           # 异步方式发送服务请求

实现结果:客户端将一组数据两个数发送至服务端,服务端接收后,进行数据处理,将两个数相加,发送至客户端作为应答。

3.创建服务流程

服务端客户端
1. 编程接口初始化1. 编程接口初始化
2. 创建节点并初始化2. 创建节点并初始化
3. 创建服务器端对象3. 创建客户端对象
4. 通过回调函数处进行服务4. 创建并发送请求数据
5. 向客户端反馈应答结果5. 等待服务器端应答数据
6. 销毁节点并关闭接口6. 销毁节点并关闭接口

总结

话题和服务是ROS中最为常用的两种数据通信方法,前者适合传感器、控制指令等周期性、单向传输的数据,后者适合一问一答,同步性要求更高的数据。

源码链接:链接:https://pan.baidu.com/s/1-_DWYXiloyIVW6uCmM50aQ 提取码:smn7

致谢:古月居ROS2入门教程。链接:https://book.guyuehome.com/

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值