【问题标题】:ROS - How do I publish a message and get the subscribed callback immediatelyROS - 如何发布消息并立即获取订阅的回调
【发布时间】:2019-10-30 16:32:11
【问题描述】:

我有一个 ROS 节点,它允许您向它“发布”一个数据结构,它通过发布输出来响应它。我发布的内容和它发布的内容的时间戳是匹配的。

是否有一种阻止功能的机制,用于发送/发布和输出,它会一直等到我收到输出?

【问题讨论】:

  • 如果您正在寻找快速通信,ROS 通信不是您的目的,因为它比 ZeroMQ 这样的无代理通信器慢。 ZeroMQ is REQ/REP 中等效的 ROS 服务模式。
  • 是的,我决定放弃 ROS,因为它对我的需求来说太慢了。我很惊讶它甚至无法在 localhost 内以 60 fps 处理 512x512 有组织的点云
  • 我在 UPDATE 部分更新了我的答案,希望对您有所帮助。

标签: ros


【解决方案1】:

我认为您需要 ROS_Services(客户端/服务器)模式而不是发布者/订阅者。


这是一个在 Python 中执行此操作的简单示例:

客户端代码sn-p:

import rospy
from test_service.srv import MySrvFile

rospy.wait_for_service('a_topic')
try:
    send_hi = rospy.ServiceProxy('a_topic', MySrvFile)
    print('Client: Hi, do you hear me?')
    resp = send_hi('Hi, do you hear me?')
    print("Server: {}".format(resp.response))

except rospy.ServiceException, e:
    print("Service call failed: %s"%e)

服务器代码sn-p:

import rospy
from test_service.srv import MySrvFile, MySrvFileResponse

def callback_function(req):
    print(req)
    return MySrvFileResponse('Hello client, your message received.')

rospy.init_node('server')
rospy.Service('a_topic', MySrvFile, callback_function)
rospy.spin()

MySrvFile.srv

string request
---
string response

服务器输出:

request: "Hi, do you hear me?"

客户出局:

Client: Hi, do you hear me?
Server: Hello client, your message received.

Learn more in ros-wiki


[更新]

  • 如果您正在寻找快速通信,TCP-ROS 通信不是您的目的,因为它比 ZeroMQ 等无代理通信器慢(它具有低延迟和高吞吐量):

    1. ZeroMQ 中等效的 ROS 服务模式是 REQ/REP (client/server)
    2. ZeroMQ 中等效的 ROS 发布者/订阅者模式为 PUB/SUB
    3. ZeroMQ 中具有 waitformessage 等效项的 ROS 发布者/订阅者是 PUSH/PULL

    ZeroMQ 支持 Python 和 C++

  • 此外,为了传输大量数据(即pointcloud),ROS 中有一种称为nodelet 的机制,仅在 C++ 中支持。这种通信基于机器上的共享内存而不是 TCP-ROS 套接字。

    What exactly is a nodelet?

【讨论】:

  • 嘿,我看到我们同时回答了这个问题。我觉得你的回答比较详细,那我应该删掉我的回答吗?
  • 嗨@Malefitz,不需要删除,因为我们的答案有不同的内容(你提到了一个C++示例......)
  • 是的,我想我唯一的选择是将整个代码库更改为 nodelet 格式,这需要一个月的工程时间。
【解决方案2】:

为了获得这种请求/回复行为,ROS 有一个称为ROS service 的机制。

您可以在类似于 ROS 消息定义的服务文件中指定服务的输入和输出。然后,您可以使用您的输入调用节点的服务,并且在服务完成后调用将收到输出。

Here 是一个如何在 python 中使用这种机制的教程。如果你更喜欢 C++,也有一个,你应该找到它。

【讨论】:

  • rosservice 太慢了。拨打电话需要 50 毫秒
【解决方案3】:

由于您想坚持发布/订阅者,假设从您的评论来看,服务速度很慢,我会看看 waitForMessage (Documentation)。

有关如何使用它的示例,您可以查看this ros answers question

您需要做的就是发布您的数据并立即在输出主题上调用 waitForMessage 并将收到的消息手动传递给您的“回调”。

我希望这就是你要找的。​​p>

【讨论】:

  • waitForMessage 太慢了。看起来没有办法解决这个问题,而且 ROS 没有这种机制的快速版本。
  • 所以问题是,你想要请求/回复有不同的节点/进程还是可以相同(或一个nodelet)。如果不同的进程当然会很慢,因为你在通信中包含了 TCP/IP 开销。但至少对于发布/订阅来说,有可能对消息使用共享指针,如果相同的进程随后发布和订阅消息,则消息通过共享内存传递,这要快得多。需要确定这是否也适用于服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-28
  • 1970-01-01
相关资源
最近更新 更多