您的位置:

ROS通信

一、概述

ROS是机器人操作系统,是一个开源的、灵活的、分布式的软件平台,可以帮助我们快速开发机器人应用程序。ROS中的通信是机器人应用程序开发中最重要的部分之一,它是实现多模块协作和互联的关键。ROS提供了多种通信方式来支持不同类型的应用场景,包括如下:

  • Publisher/Subscriber方式:发布者和订阅者模式,用于实时传输数据。
  • Service/Client方式:客户端和服务端模式,用于请求和响应一个计算任务。
  • Action Server/Action Client方式: 提供了对连续和异步处理的支持。

二、Publisher/Subscriber方式

Publisher/Subscriber(发布者和订阅者)方式是ROS中最常用的通信方式,它是基于消息传递的。通过这种方式,我们可以在一个节点中发布消息,而在其他节点中订阅这个消息。它的原理类似于生产者-消费者模型,其中Publisher(发布者)是生产者,而Subscriber(订阅者)是消费者。

下面是Python代码示例

    
#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def callback(data):
    rospy.loginfo("I heard %s",data.data)

def listener():
    rospy.init_node('listener', anonymous=True)

    rospy.Subscriber("chatter", String, callback)

    rospy.spin()

if __name__ == '__main__':
    listener()
    

这段代码创建了一个名为“listener”的节点,它订阅名为“chatter”的消息。回调函数callback()是Subscriber()从ROS Master获取到信息后需要执行的任务。在此示例中,Subscriber将从话题“chatter”读取消息,并在终端窗口中打印它。

三、Service/Client方式

Service/Client(服务端和客户端)方式是RPC(Remote Procedure Call)风格的模式,可以像调用本地函数一样调用远程计算机上的函数。其中,Service Server提供一个服务,而Service Client向Service Server发送请求。一旦Service Server收到请求,它将计算请求并将结果发送回Service Client。

下面是Python代码示例:

    
#!/usr/bin/env python
from beginner_tutorials.srv import AddTwoInts,AddTwoIntsResponse
import rospy

def handle_add_two_ints(req):
    result = req.a + req.b
    rospy.loginfo("Returning [%s + %s = %s]", req.a, req.b, result)
    return AddTwoIntsResponse(result)

def add_two_ints_server():
    rospy.init_node('add_two_ints_server')
    s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
    rospy.loginfo("Ready to add two ints.")
    rospy.spin()

if __name__ == "__main__":
    add_two_ints_server()
    

在此示例中,代码定义了一个名为“add_two_ints”的服务。handle_add_two_ints()函数是处理“AddTwoInts”服务请求的回调函数,它将两个整数相加并返回结果。add_two_ints_server()函数初始化ROS节点并创建一个服务,当它收到请求时,它调用handle_add_two_ints()函数处理请求,并将其响应返回给Service Client。

四、Action Server/Action Client方式

Action Server/Action Client方式提供了对连续和异步处理的支持。在ROS中,Action是一个新的消息类型,相对于ROS中的其他消息类型来说,它保留了更多的信息,比如跟踪Action调用的进度等。Action Server等待Action Client发送请求,一旦收到请求,就可以在内部执行类似于后台进程的操作。

下面是Python代码示例:

    
#!/usr/bin/env python
import rospy
import actionlib
from beginner_tutorials.msg import FibonacciAction, FibonacciGoal,      FibonacciResult

class FibonacciActionServer(object):
    _feedback = FibonacciFeedback()
    _result = FibonacciResult()
    def __init__(self):
        self._as = actionlib.SimpleActionServer("fibonacci",   FibonacciAction, self.goal_callback, False)
        self._as.start()
    
    def fibonacci(self, n):
        if n == 0:
            return 0
        elif n == 1:
            return 1
        else:
            return self.fibonacci(n-1) + self.fibonacci(n-2)
    
    def goal_callback(self, goal):
        r = rospy.Rate(1)
        success = True

        for i in range(1, goal.order+1):
            if self._as.is_preempt_requested():
                rospy.loginfo('Goal was Preempted')
                self._as.set_preempted()
                success = False
                break
            self._feedback.sequence.append(self.fibonacci(i))
            self._as.publish_feedback(self._feedback)
            r.sleep()

        if success:
            self._result.sequence = self._feedback.sequence
            rospy.loginfo('Goal was successfully completed')
            self._as.set_succeeded(self._result)

if __name__ == '__main__':
    rospy.init_node('fibonacci_action_server')
    server = FibonacciActionServer()
    rospy.spin()
    

在此示例中,代码定义了一个名为“fibonacci”的Action。FibonacciActionServer()类是Action Server,它等待Action Client发送请求。goal_callback()函数是执行操作的回调函数。在这里,它通过计算斐波那契数列来演示操作的执行。在此过程中,它将生成的数据(响应)发送给Action Client。如果Action Client的请求被取消,它将发布Preempted(已取消)状态,如果操作成功完成,它将发布Succeeded(成功)状态,并带上最终响应。