SOSS: a whole new approach to your ROS 1-ROS 2 bridge!

SOSS is out there in the wild, as brought up in a recent post. But have you wondered what SOSS can do for you concretely?

SOSS is the core of eProsima Integration-Service, and allows you bridging an arbitrary number of incompatible protocols as smoothly as it can be.

Among the fan of possibilities opened by SOSS, you can communicate your ROS 1 and ROS 2 in a few simple steps! Check out how to do so here, after having taken a look at how to install SOSS and get it going here.

2 Likes

As the ros1_bridge package is typically suggested for ROS 1 <> 2 interoperability, could you write a few words on how SOSS compares?

The linked documentation doesn’t mention services, nor actions. Are only topics supported?

2 Likes

Good morning, this is Jose from eProsima talking.
SOSS offers support for ROS standalone packages with commonly used messages types for topics and services; integrating them within your demo is a easy as dropping a few lines in your CMakeLists.txt using the soss_rosidl_mix() CMake macro.

Also, you can use dynamic types, thanks to the integration with eProsima’s xtypes. This allows you to define your type structure directly in the YAML configuration file, using IDL description language.

Support for services is also available. Regarding actions, they could be achieved by defining a set of services and a topic. We can include a dedicated field in the YAML file for easily configure an action, regarding user’s side, and let SOSS take care of the rest.

SOSS support a bunch of nice features, such as topic and type remapping, and specific middleware features, such as configurable domain change, in the case of ROS-related systemhandles.

Also, of course, SOSS is not limited to ROS1-ROS2 communication; it allows you to interact with other protocols (FIWARE, DDS, Websockets…) and more are to come yet.

This looks great! So would it also be easy to use this to create bridges between ROS 2 distributions as well?

Requiring all nodes to be on the same distribution (Dashing, Foxy, etc.) means that just one node running on an old distribution holds back all other nodes in a large system from upgrading.

For example, right now I am working on a project with nodes running on multiple machines. Most machines run Ubuntu and can easily run the latest distribution, but some of the machines need to run Matlab on Windows. Matlab is super slow about upgrading the ROS toolbox. Their latest release a few weeks ago is still using Dashing. I hate to have my entire system development held up by a company writing proprietary code that I have no control over.

It would be nice to allow each node in the system to run on whichever distribution is most appropriate for that node. Then maybe the entire system could send messages using the very latest distribution and bridges could connect every node running older distributions. Or maybe the system would run some intermediate distribution and every node from either an older distribution or a newer distribution would need a bridge. Then if the system wants to bump to a newer distribution, would all of the bridges then need to be recompiled? Every node may need a bridge for maximum flexibility.

Or would that just get super confusing and error-prone, though, with reduced performance? How would that system look and work in practice? Is it just way safer and easier to force every node to be held back to the oldest distribution?

would it also be easy to use this to create bridges between ROS 2 distributions as well

We tried combining Dashing and Eloquent and that worked fine. As they all use DDS, I would expect that it also works with Foxy. Did you already try to combine Dashing and Foxy?

As @Wilco says, you should not need any kind of bridge between any of Dashing, Eloquent and Foxy. All three are compatible at the communications level.

Awesome, is that true now?

When I asked this question Can nodes from different ROS 2 distributions communicate compatibly? @tfoote said:

Designing a system to rely on that compatibility is not recommended as there are no guarantees.

Has that changed since Dashing, are ROS 2 distributions now guaranteed to be compatible?

You can’t rely on it for any future distributions because we never guarantee compatibility between distributions. For example, the std_msgs are deprecated and are going to go away in a future distribution so you would have to provide them yourself to be compatible with applications running on old distributions that use messages from that package. However for Dashing, Eloquent and Foxy applications generally work together.

2 Likes

@FraFin @jamoralp
CC: @gavanderhoorn

Nice work! thanks for sharing this information :+1:

I believe @gavanderhoorn’s question above really gets to the point, especially on user aspect. So I just created the comparison table for mostly what the user gets?. I might be wrong on some points, so let me know if you find anything I got wrong. that would be really appreciated.

  • Support Status for Bridge Protocol
Protocol SOSS ros1_bridge Note
ROS1 Yes Yes
ROS2 Yes Yes
FIWARE Yes No SOSS-FIWARE
DDS Yes No SOSS-DDS
WebSocket Yes No
REST Yes(W.I.P) No
  • Bridge Component Support
Component SOSS ros1_bridge Note
Topic Yes Yes
Service Yes Yes
Action Yes Yes(W.I.P) SOSS: this can be achieved by defining a set of services and a topic.
Parameter No No I think this is out-of-scope, since architecture design is different between ROS1(Client/Server) and ROS2(Distributed).
  • Bridge Mode Support
Mode SOSS ros1_bridge Note
ROS1 to ROS2 Yes Yes
ROS2 to ROS1 Yes Yes
Bi-Direction ROS1/ROS2 Yes Yes
Static Bridge Yes Yes Describe what to bridge before execution
Dynamic Bridge No Yes Bridge topics and services dynamically at runtime
1 Like

off-topic, but:

Nice how this is mentioned so casually :slight_smile: I don’t think many current users are aware of this.

How would you deal with the changed semantics and state-machine?

2 Likes

So it sounds like, in general, bridges still may be necessary to connect ROS 2 nodes from different distributions.

That or there needs to be a way to force all nodes in a system to switch to a common distribution. That seems like it might be difficult, though, in a system with lots of nodes on lots of machines with lots of users. There may not be a common distribution that would work with every node and changing all of the nodes might be tricky even if there was.

What would be the best way to manage such a system? Perhaps ROS messages are not the most appropriate format for distributing data in such large diverse systems, but if they are not, what is?

Just for clarification: there are two different types of potential incompatibilities for the communication across ROS distributions:

  1. Changed message / service / interface definitions.
  2. Changes in the underlying protocol. E.g. in ROS Bouncy we switched from using DDS partiions to namespaced topic names (see notes). If in the future a conceptional shortcoming like ros2/ros2#921 is addressed that would likely also imply that services will be incompatible with older distros.

If nodes from several distributions are running on the same network they will discover and see each other’s topics correct?

Is there any way to tell to which distribution a message or topic belongs? So, for example, a foxy node would not try to subscribe to an image topic from a bouncy node with the same name? Or would you have to differentiate them manually by using different topic names or domain ids?

If there is a chance that nodes from different distributions will connect to the same network and interfere with each other, would it be safer to separate them with topic names or domain ids?

It’s in the release notes. There’s not much more we can do.

I’m not sure about what you mean by changed semantics, since I’m not an expert in ROS 2 actions; anyway, if it concers to the action types names, remapping can be used to solve the differences between ROS1 and ROS2 naming conventions.

As for the state machine, it would be handled automatically by SOSS; SOSS is fed with the IDL files generated by rosidl from msg/srv/actions files. If I’m not wrong, resulting IDLs from action files already contain the state-related fields in their definition, so the transformation would be done using xTypes and the information would be available on the other side. Anyway, I understand it is tedious for the user to define three services and two topics for each action in the YAML file, specially if they are autogenerated; that is why we could address some improvements to include a specific action section in the SOSS configuration YAML semantics.

@tomoyafujita nice summary! Regarding one of SOSS’ biggest flaws: yes, we do not support dynamic bridging (yet), but it can be easily achieved thanks to the integration with xTypes dynamic types. A dedicated API and implementation for dynamic bridging entities creation/destruction is on the roadmap for 1st semester 2021.

2 Likes

…

An announcement here on Discourse would go a long way, as I don’t know how many people read release notes.

Isn’t this considered a significant, breaking change with a potentially big impact which will affect all users?

std_msgs is used in just about every tutorial, every example and many nodes.

This should be given much more visibility.

Release notes are like API documentation: only if things don’t work, or you don’t understand something, you start looking for them.

The ROS 1 Action state transition diagram (here) is different from that of ROS 2 (here).

This is the reason @ipa-hsd’s action_bridge exists. It bridges (hah) that gap.

Mapping the topics is a necessary part of bridging actions, but seems to be only partial. I haven’t looked into how SOSS would use the IDL files to figure out the state machine differences though. Is that supported?

5 Likes

As a newcomer to ROS I was under the impression that these were part of the “standard library” of ROS.

The release notes say

Although discouraged for a long time

but does not link anywhere or elaborate on the recommended practice

This is starting to get more-and-more off-topic, but:

Afaik there is no documented best practice for this.

Users have always been encouraged to not use std_msgs/Int* or std_msgs/String, but to create semantically meaningful messages. A topic carrying a String doesn’t tell you anything about what its intended use is, nor how the message should be interpreted (other than as a plain String of course).

So usage of std_msgs is discouraged as there are probably better message types you can use, and you also don’t need to use it, as fields in other messages (including your own) should just use the primitive types (ie: string, uint8, etc) instead of their wrapped versions from std_msgs (ie: std_msgs/String, std_msgs/UInt8, etc).

As to some context (almost in some sort-of chronological order):

You should be able to find other related PRs and issues by following the links in the ones I link to here.


The summary of this is the notice in the release notes of Foxy. Additionally, the messages have deprecation notices added.

But if @33thou’s response is any indication, there aren’t that many people aware of this.

I wasn’t aware of this either. So what do you do to replace a std_msgs/Trigger or Bool, where the topic name tells you everything you need to know about the message/intention?

It does seem a little excessive to have to create new messages just to change a field name for those times when the topic name might expressive enough.

So many conversations in one topic!