Ask Your Question

Mechanism to prevent multiple publishers simultaneously publishing contradictory messages to a topic?

asked 2020-04-13 06:58:01 -0500

grouchy gravatar image

Is there a way to prevent multiple publishers simultaneously publishing messages to the same topic? I think I'm looking for a way for a node to lock access to a topic and release it when it's done. While a node holds the lock, no other nodes should be able to publish to this topic and their requests to lock the resource should fail. I realize this idea contradicts the principles of pub-sub, so perhaps I'm thinking about this in the wrong way.

The cmd_vel (geometry_msgs/Twist) topic is a pertinent example as interleaving messages from multiple publishers containing drastically different velocities could cause rather undesirable vibrations in the robot.

The obvious solution is to simply not run multiple nodes that can publish to the same topic, but I would like to run multiple nodes that could publish this topic at any time depending on user input. E.g. the operator could nudge a joystick while a trajectory planner is running.

I was wondering if anyone else had thought of an elegant solution to this problem or approached the problem differently before I reinvented the wheel. remote_mutex looks promising, but there is precious little information about it, and no mention of a repository as far as I can tell.

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2020-04-13 07:31:28 -0500

gvdhoorn gravatar image

updated 2020-04-13 08:01:20 -0500

I realize this idea contradicts the principles of pub-sub, so perhaps I'm thinking about this in the wrong way.

yes, what you suggest does indeed seem like it clashes with the idea of anonymous publish-subscribe.

Afaik, in ROS 1, this is not supported natively.

In ROS 2, with SROS2, you could probably use access control exposed by the ROS 2 DDS-Security integration to set up a static form of what you describe (static, as afaik, access control cannot be changed at runtime, perhaps @ruffsl can confirm this).

As to the remote_mutex page you found: from the description this sounds completely voluntary (ie: cannot be enforced with nodes that have not been written to take it into account) and it's also a package from 2011. A quick search shows has a copy, but again, I doubt its utility as it has to be integrated into nodes -- which limits its use to nodes under your control.

E.g. the operator could nudge a joystick while a trajectory planner is running.

While not a perfect solution (as rogue publishers could still publish Twists to any topic), the typical approach I've seen is to remap the default cmd_vel to something else, place a cmd_vel_mux between Twist producers and the consumer and then configure the mux intelligently. The way the Kobuki/Turtlebot2 control stack is configured is an example of this: kobuki/Tutorials/Kobuki's Control System. The Kobuki uses yocs_cmd_vel_mux for this.

By remapping cmd_vel on the consumers side, rogue publishers which assume cmd_vel is being listened to will not achieve anything, and producers which play nice can be muxed appropriately by the muxer.

But as ROS 1 has no access control (by design), it'll stay security through obscurity at best.

Edit: re: remote_mutex: reading the code and assuming a subscriber is under your control, you could potentially use the mutex_guard to make the subscriber ignore messages coming in from sources which have not previously acquired it. The mutex_guard has a field holder, which seems to contain the name of the entity (?) which currently holds the lock.

For messages coming from sources which don't hold the lock, ignoring them would result in the behaviour you describe.

It would however seem to couple nodes in at least two of the three dimensions described in #q203129. Personally, that seems like a substantial cost.

edit flag offensive delete link more


Just thinking out loud here, but: by changing the ROS Master implementation, you could extend it to return only a specific list of publishers for certain topics. As data exchange is peer-to-peer, subscribers have to actively make connections with publishers. If a publisher does not appear in the list of publishers for a certain topic, subscribers should not create connections to them.

Not very maintainable (as you're now running a custom version of ROS Master), but it would allow you to do what you describe. It would again be a form of security-through-obscurity, as nothing is really prevented, just hidden. But at the roscpp and rospy level, nodes would not be able to setup connections to nodes they cannot see, so even with nodes not under your control this could work. It's a poor-mans' version almost of the access control in SROS 2.

This may be something more ...(more)

gvdhoorn gravatar image gvdhoorn  ( 2020-04-13 08:09:43 -0500 )edit

There’s also a muxing program included in topic_tools. It was recommended for awhile for cmd_vel specifically for multiple clients but its unclear to me how common it was in practice. But that’s an option.

stevemacenski gravatar image stevemacenski  ( 2020-04-13 12:24:13 -0500 )edit

Thank you for taking the time to carefully consider my question.

I had considered this issue orthogonal to security. For the sake of simplicity I assume none of the nodes in the system are nefarious, if only for the context of this problem. Assuming all publishing nodes behave themselves and are under my control, a voluntary based system like remote_mutex might be acceptable or even preferable as it would support backwards compatibility with standard tools like rosbag playback (albeit without any arbitration, but at least it'll work).

Using a muxing proxy node is an interesting idea. It's good it works without modifying the nodes so it'll work with stock tools like ros_control and MoveIt. It also allows priorities rather than first come first serve like the mutex. As Steve says it already exists too in topic_tools! The only feature it lacks is the ability for a publishing ...(more)

grouchy gravatar image grouchy  ( 2020-04-13 15:57:27 -0500 )edit

Thanks for turning me onto vapour_master, it's pretty interesting for plenty of reasons. Otherwise as you say running a custom master could present other challenges, and I'd quite like to make it easier to migrate to ROS2 one day.

grouchy gravatar image grouchy  ( 2020-04-13 16:17:11 -0500 )edit

I had considered this issue orthogonal to security

well, access control is what you are describing in your OP. That is a part of security and safety.

For the sake of simplicity I assume none of the nodes in the system are nefarious

they don't need to be bad actors. I've seen what you describe happen many times to users who did not configure their systems correctly. Nothing nefarious there, just simple misconfiguration.

As Steve says it already exists too in topic_tools!

I would still recommend the yocs versions -- they are not specific to the Turtlebot/Kobuki stacks and I believe are nicer in their implementation and ROS API. Be aware they got renamed, so it's yocs_cmd_vel_mux, not cmd_vel_mux.

The only feature it lacks is the ability for a publishing node to know when it hasn't got access to the hardware so it can respond accordingly ...

gvdhoorn gravatar image gvdhoorn  ( 2020-04-14 02:34:39 -0500 )edit

.. not of the nodes you are talking about, but of another node (or set of nodes) which are responsible for coordination of the application (at whichever level). yocs_velocity_smoother publishes the active input (on the private active topic), so whatever is coordinating your application should be able to take that into account and act accordingly (or make other nodes act accordingly).

gvdhoorn gravatar image gvdhoorn  ( 2020-04-14 02:36:01 -0500 )edit

Just to confirm, the access control policy enforced in SROS2 with Secure DDS is in fact static, and must be defined at design time. I'd concur with @gvdhoorn suggestion of using a mux. One could perhaps modify the mux to publish a select topic that states the current input selected (based on input priority, or other logic, etc), that the input publishers could subscribe to and discern if they are currently being subsumed.

ruffsl gravatar image ruffsl  ( 2020-04-21 20:29:05 -0500 )edit

One could perhaps modify the mux to publish a select topic that states the current input selected

The yocs implementation of the mux does this.

gvdhoorn gravatar image gvdhoorn  ( 2020-04-22 03:28:32 -0500 )edit

answered 2020-07-11 03:16:48 -0500

grouchy gravatar image

It's been three months so I figured I'd give an update on where I got to with this.

Based on gvdhoorn's et al suggestions, I ended up creating a mux node which allows switching between various inputs via a service that the user can control. The reason I created my own node for this is because it also allows the user to tune some domain specific settings such as the frame and magnitude of the twist. It works well for my needs. A publishing node has no idea if it is the currently selected input but the mux node knows when a non-selected input starts publishing and can throw up a warning.

I also discovered the bond package which looks like it could be used for resource acquisition, similar to remote_mutex except the bond package looks well supported.

From the docs:

Bonds can be used to track resource ownership. The creation of a bond indicates a lease on the resource, and breaking a bond indicates that the lease is broken.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2020-04-13 06:58:01 -0500

Seen: 51 times

Last updated: Jul 11