What is the best way to store a one-time calculation that other nodes may need?
It seems like a waste to publish a message for data that will be constant. Would my node store it as a parameter?
Edit: Sorry about the vague description. I’m still in the learning phase. I’m not doing something specific yet. I’m imagining how to use these tools.
Maybe I can explain a little more about my context of understanding and where this question came from.
My understanding:
- When nodes publish topic messages they are transmitted (through network or shared memory) to all subscribers ASAP. The send & receive queues are only for managing processing bandwidth but otherwise messages are transient.
- Nodes may have differing lifetimes. Some may start after others and some may terminate before others.
So I’m imagining a scenario where NodeA is running and calculates something that will remain persistent for some time, call it CalibrationA. Later NodeB starts and needs the information called CalibrationA. In my current understanding, described as an example:
- If NodeA publishes CalibrationA as a topic, the message lives long enough to transmit to any current subscribers and then it’s gone.
- When NodeB starts later, it could subscribe to CalibrationA. However, it would only receive this the next time Node_A republishes this constant data.
Since Calibration_A remains constant, it seems like a waste of transmission resources to just keep sending it at regular intervals. I also learned that we have Parameters and Services. Parameters seem like they can persist data but from what I read they are more for configuration.
So from my example, what is the best mechanism to persist Calibration_A so other nodes can access it later?
Asked by pduda on 2020-03-24 15:46:08 UTC
Answers
Since you tagged this with kinetic
, I'm going to give a ROS 1 targetted answer.
Node_A is running and calculates something that will remain persistent for some time, call it Calibration_A. Later Node_B starts and needs the information called Calibration_A. In my current understanding, described as an example:
- If Node_A publishes Calibration_A as a topic, the message lives long enough to transmit to any current subscribers and then it’s gone.
Yes. There is no persistent store for messages to "live" in. All message exchange is peer-to-peer, so if peers are not online, they won't receive the message.
- When Node_B starts later, it could subscribe to Calibration_A. However, it would only receive this the next time Node_A republishes this constant data.
In principle this is true, but see below (there is an optimisation to make here).
Since Calibration_A remains constant, it seems like a waste of transmission resources to just keep sending it at regular intervals. I also learned that we have Parameters and Services. Parameters seem like they can persist data but from what I read they are more for configuration. So from my example, what is the best mechanism to persist Calibration_A so other nodes can access it later?
I would not call this "persisting", as that implies it's stored somewhere with the express purpose of retrieving it later.
From your example, it would seem you're actually interested in late joiners to receive the messages published by Node_A
, regardless of when it was published.
Assuming receiving the last message which Node_A
has published would be the one you're interested in, you could solve this specific requirement by using something called a latched publisher (docs):
Enables "latching" on a connection. When a connection is latched, the last message published is saved and automatically sent to any future subscribers that connect. This is useful for slow-changing to static data like a map.
Note that this only works as long as the publisher is on-line, so Node_A
will need to be running. Otherwise late joiners will not receive the latched message.
If however, the data really "never" changes, I would suggest storing it in a parameter. As long as the parameter server is online, nodes will be able to retrieve it.
Finally:
it seems like a waste of transmission resources to just keep sending it at regular intervals.
this is not a statement that can be made so definitively I believe.
First: if there are no susbcribers, no data is actually transmitted by a publisher, even if the node calls the publish(..)
method for a Publisher
. As all data is exchanged peer-to-peer: no peers -> no data transmission (and it is possible to determine how many subscriptions there are, so in case there are none, nodes can decide to avoid performing costly work).
Especially for topics carrying semi-static data, there would be no need for a node to keep a subscription alive all the time. APIs such as waitForMessage(..) support retrieving a single message from a topic and then unsubscribing. Combined with the no-data-transmitted-until-there-are-subscribers principle, this could allow for very efficient, topic-based, distribution of such data.
Second: unless Calibration_A
is really big, periodically publishing it at a low frequency will most likely not incur too much overhead. This is of course an assumption, but that is also true for the suggestion that it's a waste of resources a priori. Only measurements will be able to answer this.
Asked by gvdhoorn on 2020-03-25 15:02:15 UTC
Comments
Could you provide a little more information about what you are actually trying to do?
There is nothing "in ROS" (as vague as such a statement is) that requires for things to be continuously published, but right now you give us too little information to know what you are encountering.
Asked by gvdhoorn on 2020-03-25 05:38:15 UTC