ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A

ROS2 Transition Strategy

In the near future we will begin transitioning packages to ROS2 and we are interested in getting feedback on possible strategies for managing ROS1 and ROS2 leveraging GitHub. We recently had a discussed at the ROS-Industrial Developers meeting and two approaches were identified below, but if other exist please let us know. Also we are interested in getting the communities feedback on the Pros and Cons of both approaches to help determine which is the best strategy moving forward.

Option 1 (Multiple Repositories)

  • Repository 1 (Core Libraries) - This would contain libraries that are ROS agnostic which would be leverage by the other repositories. (This may not always exist, depending on the nature of the repository.)
  • Repository 2 (ROS1) - This would contain ROS1 wrappers around the Core Libraries.
  • Repository 3 (ROS2) - This would contain ROS2 wrappers around the Core Libraries.

Option 2 (Single Repositories leveraging multiple branches)

  • Branch 1 (ROS1 and Core Libraries) - This would contain both core libraries and ROS1 wrappers.
  • Branch 2 (ROS2 and Core Libraries) - This would contain both core libraries and ROS2 wrappers.
  • Note: If improvements were made to core libraries they would be cherry-picked to the other branch.

I think there’s a 3rd option:
Repo 1 - Core Libs (same as in option 1)
Repo 2 -

  • Branch 1 (eg: melodic_devel) - ROS wrappers
  • Branch 2 (eg: dashing_devel) - ROS2 wrappers

This option gives you the benefits of Option 1 without as many repos. It assumes the repo maintainers are the same for both ROS and ROS2 wrappers.

I am strongly in favour of Option 1. This is simply because independent functionality should always be separated into a dedicated library. There might be users of your library that want to use it with yet another communication middleware. IMHO, it is also easier to maintain a library interface than cherry-picking between branches and resolving merge conflicts.

I recommend avoiding using branches in a repository to manage completely separate pieces of code (ROS1 wrappers and ROS2 wrappers). It’s not what branches were for and it makes it really easy to make mistakes. I think that option 1 is your best bet.

While I like the separation of concerns with Option 1, why are there multiple reposities needed?
Isn’t it possible to have core, ROS1-wrappers and ROS2-wrappers in different packages within the same repository?

If set up well, the overhead of selecting which wrapper to compile should be less than having to deal with 3 repositories for 1 ROS node.

It does, but seeing as there is most likely a very small intersection between the code for ROS 1 and ROS 2, what would be the benefit apart from reducing the nr of repositories? Chances for cherry-picking are most likely slim (not zero though).

One reason would be to not tie versioning (ie: releases and history) to that of the ROS wrappers.

As nice as ROS is, there are other frameworks/middlewares/software systems out there, and separating things out like this makes integration with those easier (perhaps not just technically, but also psychologically: I’ve seen companies refuse to use particular pieces of software just because it was hosted “somewhere” that they associated with bad practices and NIH).

I think it depends on the amount of shared code between the ROS1 and ROS2 versions. If you already have a ROS-agnostic core library, with separate ROS1 and ROS2 wrappers, there’s probably very little shared code between the three, so it’s best to put them into separate repositories (option 1). Note that this also means that the core library needs a rather stable API, which is also good practice, but needs some discipline and automated testing. If the API is not yet stable, and there are a lot of “tandem” changes (i.e., a change in the library requires a simultaneous change in the wrapper and vice versa), they should go into the same branch of the same repo (option 2).

If the core library is not separated out, but instead mingled with the ROS code (which is the case in the majority of ROS packages), there will be lot of shared code between the ROS1 and ROS2 versions, so they should go into separate branches of the same repo for ease of cherry-picking (option 2). That has its own set of challenges though - branches tend to diverge over time because people forget to cherry-pick.

In short: option 1 is cleaner, so go for it if practical. If it’s not practical for the reasons outlined above, choose option 2. Also, whichever option you choose, you will have the least headaches if the ROS1 and ROS2 wrappers are fairly thin, so you almost never need to touch them, and almost all your development happens in the core library. It depends on the package if this is possible or not.

I originally went down this rout and had one issue. When cloning down a branch that contains a packages for core, ros1 and ros2, I could not find a way to get it to build using ros1 (catkin_tools) and then ros2(colcon). My original thought was, that I would add AMENT_IGNORE to ROS1 packages and CATKIN_IGNORE to ros2 packages and it should build but that was not the case. It appears that both ros1 and ros2 ignore both.


That is exactly the issue we encountered when trying to share a non-ROS library with both ROS1 and ROS2.
If anyone has hints about this route, we would be interested.