ROS - How do I publish a message and get the subscribed callback immediately

不想你离开。 提交于 2020-01-05 04:13:10

问题


I have a ROS node that allows you to "publish" a data structure to it, to which it responds by publishing an output. The timestamp of what I published and what it publishes is matched.

Is there a mechanism for a blocking function where I send/publish and output, and it waits until I receive an output?


回答1:


I think you need the ROS_Services (client/server) pattern instead of the publisher/subscriber.


Here is a simple example to do that in Python:

Client code snippet:

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)

Server code snippet:

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

Server out:

request: "Hi, do you hear me?"

Client out:

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

Learn more in ros-wiki

  • Project repo on GitHub.

[UPDATE]

  • If you are looking for fast communication, TCP-ROS communication is not your purpose because it is slower than a broker-less communicator like ZeroMQ (it has low latency and high throughput):

    1. ROS-Service pattern equivalent in ZeroMQ is REQ/REP (client/server)
    2. ROS publisher/subscriber pattern equivalent in ZeroMQ is PUB/SUB
    3. ROS publisher/subscriber with waitformessage equivalent in ZeroMQ is PUSH/PULL

    ZeroMQ is available in both Python and C++

  • Also, to transfer huge amounts of data (i.e. pointcloud), there is a mechanism in ROS called nodelet which is supported only in C++. This communication is based on shared memory on a machine instead of TCP-ROS socket.

    What exactly is a nodelet?




回答2:


To get this request/reply behaviour ROS has a mechanism called ROS service.

You can specify the input and output of your service in a service file similar to a ROS message definition. You can then call the service of a node with your input and the call will receive an output when the service is finished.

Here is a tutorial how to use this mechanism in python. If you prefer C++ there is also one, you should find it.




回答3:


Since you want to stick with publish/ subscribers, assuming from your comment, that services are to slow I would have a look at waitForMessage (Documentation).

And for an example on how to use it you can have a look at this ros answers question.

All you need to do is to publish your data and immediately call waitForMessage on the output topic and manually pass the received message to your "callback".

I hope this is what you were looking for.



来源:https://stackoverflow.com/questions/58629945/ros-how-do-i-publish-a-message-and-get-the-subscribed-callback-immediately

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!