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

Can ROS2 packages depend on ROS1 packages?

asked 2022-01-19 17:28:27 -0500

lexi gravatar image

How can I specify a dependency on a ROS1 package in a ROS2 package, so that I can include header files?

I am migrating a system from ROS1 to ROS2 and the plan is to move to hybrid system and slowly migrate nodes over time. Right now we have a shared ROS package called projectname_common. And it just includes headers for things like file paths needed in various parts of the system.

When we have a hybrid system setup, I'd like to be able to have ROS1 and ROS2 packages both depend on the common package and not have to maintain two versions.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2022-01-20 15:31:38 -0500

msmcconnell gravatar image

updated 2022-01-20 15:55:24 -0500

Since you mention header files, I'm going to assume you are asking about c++. Short answer is not without changing the package being depended on.

It's important to distinguish between a truly ROS1 package which uses roscpp etc. and a catkin package which uses catkin for its build process, but is otherwise not linked to ROS.

If the package is actually ROS agnostic, except the build system then its quite easy to make it compile for both ROS1 and ROS2. You need to add conditionals to your package.xml and CMakeLists.txt files

Package.xml

<?xml version="1.0"?>
<package format="3"> <!-- Must use package format 3 -->
  <name>my_package</name>
  <version>1.0.0</version>

   <buildtool_depend condition="$ROS_VERSION == 1">catkin</buildtool_depend>
   <buildtool_depend condition="$ROS_VERSION == 2">ament_cmake_auto</buildtool_depend>

  <export>
    <build_type condition="$ROS_VERSION == 1">catkin</build_type>
    <build_type condition="$ROS_VERSION == 2">ament_cmake</build_type>
  </export>
</package>

CMakeList.txt

cmake_minimum_required(VERSION 3.5)
project(my_package)

# Verify ROS installation and get ROS version
find_package(ros_environment REQUIRED)
set(ROS_VERSION $ENV{ROS_VERSION})

if(${ROS_VERSION} EQUAL 1)

  # Add my ROS1 build commands here

else() #ROS2

 # Add my ROS2 build instructions from ament_cmake here

endif()

NOTE: The above approach can also work for message generation if your ROS1 messages conform to the requirements of ROS2 (fields all snake_case etc.).

However, if your package uses ROS libraries such as roscpp, then creating a version that compiles in both cases becomes much more challenging and I would advise creating a separate ROS2 version and or refactoring to allow for some sort of dependency injection of the middleware functions you need. If that's not an option, then you can use precompile flags in your code which is very ugly but will get you what you want. For example this is how you could change some includes:

#if MY_PACKAGE_ROS_VERSION == 2 // ROS2

    #include <rclcpp/rclcpp.hpp>
    // Do some stuff

#else // ROS1

    #include <ros/ros.h>
    // Do some stuff
#endif

In that case, you would set the relevant constant in your CMakeLists.txt file with

add_definitions(-DMY_PACKAGE_ROS_VERSION=2)
edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2022-01-19 17:28:27 -0500

Seen: 287 times

Last updated: Jan 20 '22