资讯详情

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


文章目录

  • 一、节点
    • 1.节点概念
    • 2.节点的核心代码
    • 3.创建节点流程
  • 二、话题
    • 1.主题概念
    • 2.主题的核心代码
    • 3.创建主题流程
  • 三、服务
    • 1.服务理念
    • 2.服务核心代码
    • 3.创建服务流程
  • 总结


一、节点

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中最为常用的两种数据通信方法,前者适合传感器、控制指令等周期性、单向传输的数据,后者适合一问一答,同步性要求更高的数据。

标签: 韩国cas传感器型号smn

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台