Syncronized callbacks in ROS2

Hello,
while playing with the beta wanted to create a callback on two topics.
In ROS it is possible through the message_filters package e.g.

message_filters::Subscriber image1_sub(nh, “image1”, 1);
message_filters::Subscriber image2_sub(nh, “image2”, 1);
TimeSynchronizer<Image, Image> sync(image1_sub, image2_sub, 10);
sync.registerCallback(boost::bind(&callback, _1, _2));

i don’t know if this is possible in ROS2 yet? I couldn’t find anything in the demos.

That’s one of the parts that hasn’t been ported/migrated to ROS2 yet. It’s definitely in the cards, we just haven’t had time to do it. If you are up for it, contributions are welcome.

I just happened to see this thread while trying to find out ROS2 message filter solution.
@clalancette, I saw the ros_astra_camera project code, and have one question.
Is the file astra_camera_nodelet.cpp used ?

@clalancette, if I want to do the porting job, which branch should be my start point?

thank you
Peter Han

@Peter9606 usually we do a port on a branch, then PR into ros2.

If you are porting, do keep in mind that some of the changes can be upstreamed, so they should be done in separate commits (package.xml migration, tf2 migration, de-boostifying, etc) and a PR likely filed upstream so that the ROS1 side of things can be improved.

@allenh1 Thank you for you kindly reminders.
I’m afraid I didn’t put my question clear.
Let me take message_filters as an example, if I want to port message_filters to ROS2, which branch I should forked from the ros_comm project. lunar_devel or kinetic_devel or some else, as there are too much branch.

Regards,
Peter Han

I would recommend to always fork from the latest branch.

For message_filter porting, what’s the recommend approach, creating a new repo in https://github.com/ros2 or put it under a existing repo?

Keeping it together with the existing ROS package i certainly preferred.

In the future we hope that a single code base using the same branch will be able to support both ROS versions.

1 Like

In the future we hope that a single code base using the same branch will be able to support both ROS versions.

That would be wonderful!

Are there any preliminary design notes suggesting how that could be done?

REP 149 addresses the blocker of package manifests being able to declare separate ROS 1 and ROS 2 dependencies.

From a technical point of view it is then possible to have a ROS package using a single branch. The CMake logic can be made conditional based on the ROS version (the ROS 1 part using catkin, the ROS 2 part using ament). And the source code needs to distinguish between the ROS versions using whatever approach preferred (based on preprocessor definitions and/or conditional includes in C++, conditional imports in Python).

Of course anything which reduces differences between the ROS versions makes this more convenient and requires less conditional logic, e.g. typedefs, API shims, etc. On the other hand if a ROS package would like to use features from ROS 2 which aren’t available in ROS 1 (e.g. multiple nodes in a single executable) than the code will need to be different for that.

1 Like

I like to see ament support in ROS 1.

In code I have seen, that could significantly reduce the diffs. For example, consider the diffs between the master and ros2 branches of the simple unique_identifier packages.

I agree with you that this would be great to have. But supporting ament in ROS 1 implies a tremendous effort which we are not sure atm we can and want to spend. There is no technical reason not to do it - only a problem of available resource. This “feature” could also be contributed by the community which makes it less “necessary” that OSRF is spending its sparse resources on.

As mentioned above with REP 149 implemented you should be able to avoid that part of the diff and maintain the CMake code on a single branch. The CMake would have two sections - one using catkin and one using ament. You can use common programming language feature to try to deduplicate e.g the list of source files, targets, etc.

This is off-topic, but: I haven’t been paying attention to ament too much. Could you briefly describe what would be needed to get it to work with ROS1 (ie: what would the “tremendous effort” entail exactly)?

Beside releasing the packages into ROS 1 the build tools will likely need to be updated to support the way ament_cmake generates the package specific setup files. That should be not too much effort though.

I am mostly referring to writing documentation, updating tutorials, writing a migration guide for ROS 1, etc. That effort will in my opinion exceed any “programming” part by a lot.

I am mostly referring to writing documentation, updating tutorials, writing a migration guide for ROS 1, etc. That effort will in my opinion exceed any “programming” part by a lot.

If we had a working ROS 1 version to try out, I believe the community would probably help with those kinds of documentation.

I’m actually a big proponent of the idea to backport ament to ROS 1 (and maybe even some ament features to catkin), because I think it lets people take a step toward ROS 2 without jumping in with both feet while simultaneously gaining some benefits (assumption is ament is better than catkin, which I do believe). Also, it lets developers more easily support ROS 1 and ROS 2 at the same time (same branch). This is especially attractive for packages which are mostly ROS agnostic, e.g. class_loader or the new rviz_rendering package.

I don’t want to hijack the thread, but just to expand on what @dirk-thomas said, I collected a list of things that would need to be addressed a while back:

  • support building packages with the build_type of ament_cmake (catkin_make_isolated and catkin_tools)
    • make the setup.*sh files (which are installed to the install folder’s root) source both catkin and ament setup files and environment hooks (currently only handles catkin stuff)
    • address conflicts which may occur when ament_cmake uses Python3, but the ROS 1 packages and the build tool in ROS 1 (catkin_make_isolated or catkin_tools) uses Python2
  • release all packages in the ament/ament_cmake, ament/ament_lint, and possibly ament/ament_index repositories
  • deal with ROS_PACKAGE_PATH versus ament_index
  • consolidate ros-infrastructure/catkin_pkg and ament/ament_package
    • not strictly needed, but would prevent us from having two implementations of package.xml parsing
  • deal with any issue that arise and update documentation so people are aware of the changes
1 Like

Dirk, I am not sure I understand your point. So, if I’d like port message_filter which is originally in https://github.com/ros/ros_comm, you mean create a ros2 branch in ros_comm or create a directory under an existing ROS2 repo such as rclutils?

Actually, ros_comm ROS package include some other stuffs, e.g client libraries and introspect tools which were already into ROS2, under different repos. However , message_filter which is under ros_comm/message_filter have not ported yet. Can you point the direction more clearly how to port message_filter from ros_comm/message_filter to ros2, which repo should it stay? thanks.

@jwang11 message_filters is certainly not a simple case for migration. The location in ros_comm with the various other packages makes it more challenging to maintain a ros2 branch. A separation of that repository into smaller repo is certainly desired but would require a significant amount of effort.

Currently a separate branch or fork is required since we can’t support both ROS versions from a single code base yet. In the (near) future the goal is to make that possible though. As soon as that is the case I would prefer to merge any ROS 2 specific patches directly into the default branch and aim to minimize conditional code as much as possible.

1 Like

@dirk-thomas yes, location of message_filter make it a challenging case for migration. As you said, split it out from ros_comm and into a small repo require significant effort, so you prefer to separate a branch/fork on ros_comm, right? In new branch, I try make message_filter support both ros version with some conditional code? how I handle other packages, keep them intact?