|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged mola_bridge_ros2 at Robotics Stack Exchange
|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged mola_bridge_ros2 at Robotics Stack Exchange
|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged mola_bridge_ros2 at Robotics Stack Exchange
|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged mola_bridge_ros2 at Robotics Stack Exchange
|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged mola_bridge_ros2 at Robotics Stack Exchange
|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged mola_bridge_ros2 at Robotics Stack Exchange
|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged mola_bridge_ros2 at Robotics Stack Exchange
|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
Dependant Packages
| Name | Deps |
|---|---|
| mola | |
| mola_lidar_odometry |
Launch files
Messages
Services
Plugins
Recent questions tagged mola_bridge_ros2 at Robotics Stack Exchange
|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged mola_bridge_ros2 at Robotics Stack Exchange
|
mola_bridge_ros2 package from mola repomola mola_bridge_ros2 mola_demos mola_input_lidar_bin_dataset mola_input_rawlog mola_input_rosbag2 mola_input_video mola_kernel mola_launcher mola_metric_maps mola_msgs mola_pose_list mola_relocalization mola_traj_tools mola_viz mola_viz_imgui mola_yaml |
ROS Distro
|
Package Summary
| Version | 3.5.0 |
| License | BSD-3-Clause |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | |
| Checkout URI | https://github.com/MOLAorg/mola.git |
| VCS Type | git |
| VCS Version | develop |
| Last Updated | 2026-11-15 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Additional Links
Maintainers
- Jose-Luis Blanco-Claraco
Authors
mola_bridge_ros2
RawDataSource acting as a bidirectional bridge between ROS2 and MOLA modules.
Can be used to:
- ROS2->MOLA: Interface a real sensor using a ROS driver node and run SLAM with it. See
mola_lidar_odometrydemos. - MOLA->ROS2: Expose a dataset as ROS2 topics, from any of the datasets supported by MOLA. Example: kitti
- ROS2<->MOLA: Run SLAM on a live sensor stream, then send back the reconstructed map and trajectory to ROS for further processing or visualization in RViz. See
mola_lidar_odometrydemos.
If you want to run SLAM on a rosbag, the module mola_input_rosbag2 provides
a more convenient interface, e.g. allows fast-forwarding or skipping parts of a bag.
Building this module requires ROS 2 to be installed, and its setup.bash
activation script being sourced before invoking CMake to configure and build MOLA.
See package docs for instructions and options to install ROS prerequisites.
Provided MOLA modules:
-
BridgeROS2, type RawDataSourceBase.
Build and install
Refer to the root MOLA repository.
Docs and examples
See this package page in the documentation.
License
This package is released under the BSD 3-clause license.
Changelog for package mola_bridge_ros2
3.5.0 (2026-11-15)
- New sensor_msgs/Image input, so camera images can be attached to keyframes.
- Contributors: Jose Luis Blanco-Claraco
3.4.0 (2026-11-01)
- Forward the log messages of all MOLA modules to /rosout, with truncation of long texts (#261)
- Contributors: Jose Luis Blanco-Claraco
3.3.2 (2026-10-09)
- Set input observation timestamps explicitly (IMU, LaserScan, NavSatFix, GPSFix, odometry from /tf).
- Contributors: Jose Luis Blanco-Claraco
3.3.1 (2026-10-05)
3.3.0 (2026-09-23)
- Port to MRPT 3.x (#220)
- Fix map layer publishing against the MRPT 3 points-map API
- Contributors: Jose Luis Blanco-Claraco
3.2.1 (2026-09-15)
- Merge pull request #214 from MOLAorg/fix/reloc-request-race-with-module-discovery FIX: relocalization requests raced with MOLA module discovery
- Throttle and coalesce the on-demand MOLA module scan
- Contributors: Jose Luis Blanco-Claraco
3.2.0 (2026-08-21)
- Merge pull request #198 from Zeal-Robotics/fix/bridge_ros2-tf-buffer-staleness fix(bridge_ros2): keep the TF buffer current under bridge executor load
- fix(bridge_ros2): give the TF listener its own spin thread The listener was constructed with spin_thread=false, against tf2's own default, on the grounds that the bridge already spins rosNode_ and a second spinner would be redundant. That holds only while the bridge executor keeps up with /tf, and makes buffer freshness a function of everything else the node is handling --sensor callbacks, timers, map publishing. When it does not keep up, the failure is silent: lookups still succeed, they just answer from a buffer that is behind, and the resulting poses look plausible. With spin_thread=true the /tf and /tf_static subscriptions move to a callback group and executor the listener owns, so ingestion is independent of the bridge executor's load. No new sharing is introduced. The buffer is already read from other threads --publishLocalizationTf() from the localization source's thread, transform_tree() from whichever module calls it -- and tf2::BufferCore serialises readers and writers on a single mutex. The listener's group is created with automatically_add_to_executor_with_node=false, so add_node() does not adopt it and no second executor can dispatch those subscriptions. Its destructor cancels and joins its thread, and it is declared after tf_buffer_ and rosNode_, so that happens while both are still alive.
- fix(bridge_ros2): drain the ROS queues instead of one message per topic The ROS thread polls [spin_some()]{.title-ref} on a 10 ms sleep. That loop replaced a blocking [rclcpp::spin()]{.title-ref} so the destructor could stop the thread via [shouldExit_]{.title-ref}, and the sleep was only ever there to keep the flag poll from busy-waiting. But [spin_some()]{.title-ref} collects the ready set once and executes each ready entity at most once per call, so the pair caps every subscription at roughly one message per 10 ms and puts a 10 ms floor under handling anything. Any topic arriving faster than ~100 Hz therefore keeps its subscription queue permanently full, and every message the node sees is stale by the whole queue depth. [/tf]{.title-ref} is the worst case: it aggregates every broadcaster on the graph, so on a robot publishing a few hundred transforms/s the listener's KeepLast(100) queue leaves the TF buffer several hundred ms behind. The visible symptom is REP-105 composition falling back to the stale odom transform with "extrapolation into the future" while the odom broadcaster is publishing on time and a normally-spun listener on the same graph reads it as current. A 200 Hz IMU on the same node loses half its samples the same way. [spin_once(timeout)]{.title-ref} blocks until there is work while still bounding how long [shouldExit_]{.title-ref} goes unchecked, and [spin_all()]{.title-ref} then drains whatever else is ready. Both are needed: [spin_some()]{.title-ref} and [spin_all()]{.title-ref} each call [wait_for_work(0ms)]{.title-ref}, so [spin_all()]{.title-ref} alone returns immediately when idle and would busy-wait. With work pending [spin_once()]{.title-ref} returns at once, so no iteration sleeps while a queue is non-empty. Cost is that the two bounds stack: worst case for observing [shouldExit_]{.title-ref} goes from 10 ms to 20 ms. Measured with two TF listeners on the same [/tf]{.title-ref}, one per spin strategy: draining fully leaves the buffer 12.6 ms behind the broadcaster, taking one message per 10 ms tick leaves it 358 ms
File truncated at 100 lines see the full file