ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
2

How to get/set a "system state" in ROS?

asked 2017-01-11 18:17:18 -0500

Mellon gravatar image

I'm porting a system to ROS that will be composed of several nodes linked by topics in a chain-like structure, in a way that each node produces some data to be consumed by the callback of the next node.

The problem I'm facing is that some of the nodes set variables that represent "system states" that influence the behavior of other nodes later in the chain (not the next imediate one). I'm wondering what is the best way to implement such thing on ROS.

I though about using the parameter server with getParam() and setParam() for that, but I read in the Parameter Server page that:

As it is not designed for high-performance, it is best used for static, non-binary data such as configuration parameters.

So I'm not sure if I should use it for these state variables. I also read about getCachedParam(), but I think the same doubt about the performance applies. I also saw dynamic_reconfigure, but I don't know if it was developed for this kind of scenario.

Could anyone tell me what would be the best way to implement this in ROS?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2017-01-11 22:48:30 -0500

ahendrix gravatar image

For reference, there's also some documentation of common patterns in ROS: http://wiki.ros.org/ROS/Patterns/Comm...

Depending on what you're trying to achieve, and what the timing requirements are, parameters, topics, services, or a single process may all be valid choices.

If each node in the pipeline is responsible for part of the system state, it could publish that state on a latched topic, and your other nodes could subscribe to that topic. ROS doesn't guarantee the timing of message delivery, so if your state needs to be set before the data reaches the next node in the pipeline, this probably isn't the right choice.

If your state follows the data, you could simply include it in the message that is passed from one node to the next. Downside here is that your state isn't persistent outside of the nodes.

If you do have synchronization requirements and your data is small, you could use the parameter server, and call setParam immediately before you publish, and then getParam at the beginning of the next callback. Since these are blocking, you're guaranteed that the new state is pushed to the parameter server before the next node requests it.

If you have synchronization requirements and your shared data is large, or if more than one node can set the same shared variables, you could implement a separate node to hold your shared state, and each node could update that shared state either by publishing (fast but not guaranteed timing) or by service call (blocking and guaranteed update); and then retrieve the shared state either by subscribing to a shared state topic, or by making a service call to request the state. Writing your own node to manage the shared state also gives you built-in type safety and more control over update semantics and atomicity. (this is basically just implementing your own parameter server, with custom data types and less load on the ROS master)

Finally, if your state is very large (100's Megabytes) or you have tight deadlines on how quickly it needs to be transferred to other components, it may be better to pull all of the pieces of your pipeline in a single process (you can still use ROS pub/sub within a process), and communicate your shared state in a more traditional way, with shared memory and mutexs to prevent concurrent updates.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2017-01-11 18:17:18 -0500

Seen: 916 times

Last updated: Jan 11 '17