Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version jazzy-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version kilted-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version lyrical-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version rolling-devel
Last Updated 2026-10-02
Dev Status MAINTAINED
Released UNRELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro ardent showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro bouncy showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro crystal showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro eloquent showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro dashing showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro galactic showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

Package Summary

Version 0.21.1
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version foxy-devel
Last Updated 2023-04-09
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe
README
No README found. See repository README.
CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

Package Summary

Version 0.21.5
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version iron-devel
Last Updated 2024-07-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe
README
No README found. See repository README.
CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro lunar showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro jade showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro indigo showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro hydro showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro kinetic showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

No version for distro melodic showing humble. Known supported distros are highlighted in the buttons above.

Package Summary

Version 0.23.13
License BSD
Build type AMENT_CMAKE
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version humble-devel
Last Updated 2026-10-01
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe

rtabmap_slam

The SLAM node of RTAB-Map: it takes a pose from odometry and data from the sensors, builds a graph of where the robot has been, and corrects that graph whenever it recognizes a place it has seen before — in the current run or in a previous one, so a map can be extended over several sessions.

Contents

Nodes

Node Description
rtabmap Graph SLAM with appearance- and proximity-based loop closure detection, memory management, map assembly and planning on the graph.
flowchart LR
    SYNC["<div style='text-align:left'><b>synchronized</b><br>RGB-D camera(s)<br>Stereo camera(s)<br>2D LiDAR<br>3D LiDAR<br>Odometry</div>"]
    ASYNC["<div style='text-align:left'><b>asynchronous</b><br>IMU<br>GPS<br>Landmarks (markers, tags, fiducials)</div>"]
    RTAB(["<b>rtabmap</b>"])
    GRAPH["Graph"]
    INFO["Info"]
    MAPS["<div style='text-align:left'><b>maps</b><br>2D occupancy grid<br>OctoMap<br>Elevation map<br>3D point cloud</div>"]
    TF["TF map → odom"]
    SYNC --> RTAB
    ASYNC --> RTAB
    RTAB --> GRAPH
    RTAB --> INFO
    RTAB --> MAPS
    RTAB --> TF

Conventions

Frames and TF

The node publishes map → odom, the correction from the optimized graph; odometry publishes odom → base_link, and the sensors are attached to base_link. See Frames and TF for the parameters.

flowchart TB
    MAP(["map<br><i>map_frame_id</i>"])
    ODOM(["odom<br><i>odometry frame</i>"])
    BASE(["base_link<br><i>frame_id</i>"])
    SENSOR(["camera, lidar, imu..."])
    MAP -->|this node| ODOM
    ODOM -->|odometry| BASE
    BASE -->|static, URDF| SENSOR

The database

The map is stored in database_path, ~/.ros/rtabmap.db by default (under $ROS_HOME if that is set). Set delete_db_on_start, or pass -d as an argument, to start from an empty one. Otherwise restarting on an existing database continues it: the map is reloaded, the next update starts a new session, and a loop closure between the new session and an old one merges the two. That is how a map is extended over several runs.

The database is saved on shutdown. A node that is killed rather than shut down loses whatever had not been written yet.

The database also remembers the parameters it was built with, and reopening it without setting them again brings them back. For example, a map made with ICP registration keeps using ICP, which is what makes the new session compatible with the old ones. Anything set explicitly still wins, and delete_db_on_start forgets them along with the map.

Update rate and dropped updates

Rtabmap/DetectionRate is how many updates per second are processed. It is 1 Hz by default because SLAM does not need more: odometry carries the pose between nodes, and each node costs memory, loop closure detection and optimization time for as long as the map exists.

Warning: Rtabmap/DetectionRate at 0 with sensor updates faster than about 2 Hz makes loop closure detection, graph optimization and map generation intractable fast. Every update then becomes a node, and each node is compared against all the nodes in working memory, adds a pose to optimize and data to assemble into the maps, so the map, and the time each update takes, grow at the sensors’ rate until the node cannot keep up. Keep a detection rate of 1 to 2 Hz, or bound working memory with Rtabmap/TimeThr or Rtabmap/MemoryThr.

A robot standing still does not grow the map. An update that moved less than both RGBD/LinearUpdate and RGBD/AngularUpdate since the last node is still used to detect loop closures, and then dropped. Set both to 0 to add a node every time.

An update arriving while the previous one is still being processed is dropped, not queued. SLAM time grows with the map, so a queue would only fall further behind; dropping keeps the node on the newest data. info shows how long each update took (RtabmapROS/TimeTotal/ms), and /diagnostics how many arrived versus how many were processed.

Odometry, covariance and new maps

The link between two consecutive nodes is the odometry between them, weighted by its covariance — its inverse becomes the link’s information matrix, so the optimizer knows how far to trust each one.

Which covariance is used:

  • The twist covariance, if it is set. It is the uncertainty of the motion since the previous message, which is what a link between two nodes is.
  • Otherwise half the pose covariance, for odometry sources that only fill that one. This assumes it is the error of the motion since the previous message, as visual odometry often publishes it, not the unbounded uncertainty of the pose estimated by a filtered odometry.
  • Otherwise odom_tf_linear_variance and odom_tf_angular_variance (0.001 by default), for a covariance that is zero, not finite, or exactly 1 — which is what several drivers publish to mean “not set”. Many do publish zeros, and taking those at face value would make each link infinitely confident.

Between two nodes, the largest covariance seen is kept, so updates dropped by the rate do not make the link look more certain than any of the motions that made it up.

An odometry reset starts a new map, in the same database, rather than deforming the graph across a jump the robot never made:

Odometry is reset (identity pose or high variance detected). Increment map id!

A reset is an identity pose after a non-identity one, or 9999 on both the pose and the twist covariance diagonals — which is what the odometry nodes publish when they lose track or restart. Odometry read from TF has no covariance, so only the identity pose counts there. The new map is merged back into the old one on the first loop closure between them.

A consequence worth knowing: an odometry that returns to exactly the identity is taken for a reset. Real odometry never does, but a simulator or a test that drives back to the origin will.

staleness_factor treats a long silence the same way. With Rtabmap/DetectionRate at 1 Hz and a factor of 2, an update more than 2 seconds after the previous one starts a new map. It is for odometry sources that go quiet instead of reporting a reset — a gap that long means the motion across it is not known, even if the next pose looks plausible.

Mapping and localization

Mem/IncrementalMemory chooses between the two:

File truncated at 100 lines see the full file

CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

No plugins found.

Recent questions tagged rtabmap_slam at Robotics Stack Exchange

Package Summary

Version 0.21.13
License BSD
Build type CATKIN
Use RECOMMENDED

Repository Summary

Checkout URI https://github.com/introlab/rtabmap_ros.git
VCS Type git
VCS Version noetic-devel
Last Updated 2025-04-27
Dev Status MAINTAINED
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Package Description

RTAB-Map's SLAM package.

Additional Links

Maintainers

  • Mathieu Labbe

Authors

  • Mathieu Labbe
README
No README found. See repository README.
CHANGELOG
No CHANGELOG found.

Launch files

No launch files found

Messages

No message files found.

Services

No service files found

Plugins

Recent questions tagged rtabmap_slam at Robotics Stack Exchange