FastMapping Algorithm#
FastMapping is an Intel®-optimized ROS 2 package designed for real-time 3D volumetric occupancy mapping and 2D planar costmap generation from single or multi-camera RGB-D depth streams. FastMapping replaces the pointer-based tree traversal and discrete ray-casting of traditional OctoMap implementations with a Morton-indexed octree structure, pre-allocated chunked memory pools, and continuous B-spline depth fusion.
The component serves as a drop-in 3D spatial perception and 2D obstacle avoidance ingredient for Autonomous Mobile Robots (AMRs) running navigation stacks such as Nav2.
Overview and Architecture#
FastMapping ingests synchronized depth images and camera intrinsics from one to four cameras, tracks camera poses across the TF2 coordinate tree, and integrates depth observations into an internal volumetric map. The node simultaneously exposes 3D visual markers for RViz2 and publishes a 2D planar occupancy grid sliced between configurable vertical bounds for immediate consumption by navigation stacks such as Nav2.
flowchart TD
subgraph Inputs [Sensor and Transform Inputs]
RGBD[RGB-D Cameras / Depth Topics<br/><code>depth_topic_1..4</code>]
CINFO[Camera Intrinsics<br/><code>depth_info_topic</code>]
TF[TF2 Coordinate Transforms<br/><code>camera_*_optical_frame ↔ map</code>]
end
subgraph FastMappingNode [fast_mapping_node]
SYNC[CameraSubscribers<br/>ApproximateTime Synchronizer]
QUEUE[(DataQueue<br/>Thread-safe Frame Queue)]
WORKER[Worker Thread & TF Lookup]
FMLIB[fast_mapping_lib<br/>Morton Octree + B-Spline Fusion]
MAPMGR[MapManager]
SYNC -->|Enqueue ImageFrame| QUEUE
QUEUE -->|Dequeue| WORKER
TF -->|Look up pose at timestamp| WORKER
WORKER -->|Integrate Depth & Pose| FMLIB
FMLIB -->|Voxel Grid & Free Space| MAPMGR
end
subgraph Outputs [Published ROS 2 Interfaces]
GRID[<code>world/map</code><br/>nav_msgs/OccupancyGrid<br/>2D Planar Costmap / Nav2]
FUSED[<code>world/fused_map</code><br/>visualization_msgs/MarkerArray<br/>3D Occupied Voxels]
OCC[<code>world/occupancy</code><br/>visualization_msgs/MarkerArray<br/>3D Occupied + Free Voxels]
end
RGBD --> SYNC
CINFO --> SYNC
MAPMGR --> GRID
MAPMGR --> FUSED
MAPMGR --> OCC
Key Differences from Standard OctoMap#
Feature |
Standard OctoMap ( |
FastMapping ( |
Architectural Impact |
|---|---|---|---|
Spatial Indexing |
Pointer-linked tree structure with dynamic per-node heap allocations. |
Morton Code (Z-order curve) spatial hashing on contiguous arrays. |
Eliminates pointer dereferencing and reduces cache misses with $O(1)$ block lookups. |
Memory Allocation |
Fine-grained allocations on heap per voxel leaf. |
Pre-allocated Chunked Memory Pools ( |
Mitigates heap fragmentation and eliminates allocation spikes during map growth. |
Ray Integration |
Bresenham 3D ray-casting per depth pixel ($O(N_{\text{rays}} \cdot N_{\text{steps}})$). |
Projective Forward Mapping: projects active voxel blocks into the camera frustum plane. |
Computations scale with visible voxel volume rather than pixel count along each ray. |
Measurement Fusion |
Constant log-odds step increments ($\ell_{\text{hit}}$, $\ell_{\text{miss}}$). |
Continuous B-Spline Fusion ( |
Produces smooth surface boundaries and increases robustness to camera depth noise. |
Planar Grid Generation |
Requires auxiliary nodes to project 3D leaf voxels into 2D space. |
Integrated MapManager: directly generates planar 2D grids during publish cycles. |
Provides native |
Source Code#
The source repository for this component is hosted at: FastMapping on GitHub
Prerequisites and Installation#
Supported Systems#
Complete target platform configuration following the Platform Foundation Getting Started Guide.
Install via APT#
Install the pre-built Debian packages from the Robotics AI Suite repository:
sudo apt update
sudo apt install -y ros-jazzy-fast-mapping
sudo apt update
sudo apt install -y ros-humble-fast-mapping
Note
The ros-${ROS_DISTRO}-fast-mapping package includes a sample ROS 2 bag file for testing and validation. After installation, the bag is located at /opt/ros/${ROS_DISTRO}/share/bagfiles/spinning/.
Environment Setup#
Source the target ROS 2 environment in every terminal:
source /opt/ros/jazzy/setup.bash
source /opt/ros/humble/setup.bash
ROS 2 Integration Interfaces#
Subscribed Topics#
Topic |
Message Type |
Encoding / Format |
Description |
|---|---|---|---|
|
|
N/A |
Camera intrinsic parameters (focal length $f_x, f_y$ and principal point $c_x, c_y$). Default: |
|
|
|
Primary depth image stream. Default: |
|
|
|
Secondary depth stream (active when |
|
|
|
Third depth stream (active when |
|
|
|
Fourth depth stream (active when |
Important
In multi-camera configurations, all depth cameras must share identical optical resolution and intrinsic models when subscribing to a shared depth_info_topic.
Published Topics#
Topic |
Message Type |
QoS Durability |
Description |
|---|---|---|---|
|
|
Transient Local (Reliable, KeepLast(1)) |
2D occupancy grid projected between |
|
|
Transient Local (Reliable, KeepLast(1)) |
3D visual cube markers representing occupied voxels in the world. |
|
|
Transient Local (Reliable, KeepLast(1)) |
3D visual markers for both occupied and observed free voxels in the world. |
Note
FastMapping publishers use Transient Local durability with Reliable reliability. Subscribers (including Nav2 costmap layers and custom listener nodes) must configure their QoS profile to transient_local durability to ensure historical map messages are received when connecting after node initialization.
Transform (TF) Requirements#
fast_mapping_node requires continuous coordinate frame transformations in the TF2 tree connecting the target global map frame (map_frame, default: "map") to the optical frame indicated in the header.frame_id of each depth image (e.g., camera_color_optical_frame).
map ──► odom ──► base_footprint ──► base_link ──► camera_link ──► camera_color_optical_frame
The node uses asynchronous TF lookups with linear interpolation:
The
tf_delayparameter (default:0.7seconds) defines the permissible temporal tolerance when querying poses for incoming frames.If the TF tree fails to provide a transformation within the
tf_delaywindow, the frame is dropped to prevent unaligned map distortion.
For tabletop testing without an active SLAM module or robot base, publish a static transform between map and your camera optical frame:
ros2 run tf2_ros static_transform_publisher 0 0 1 0 0 0 map camera_color_optical_frame
Configuration Parameters#
All parameters can be supplied via a ROS 2 YAML parameter file or overridden from the command line:
Parameter |
Type |
Default |
Unit |
Description |
|---|---|---|---|---|
|
|
|
- |
Target global coordinate frame ID. |
|
|
|
meters |
Resolution (leaf size) of each 3D voxel ($0.04 = 4\text{ cm}$). Smaller values increase spatial resolution but consume more memory and compute. |
|
|
|
meters |
Maximum depth ray distance integrated into the map. Depth pixels exceeding this distance are ignored to avoid far-field sensor noise. |
|
|
|
meters |
Minimum vertical height (z-axis) relative to |
|
|
|
meters |
Maximum vertical height (z-axis) relative to |
|
|
|
meters |
Clearance radius around the robot base cleared as free space in the planar grid. |
|
|
|
- |
Sensor noise factor scaling the B-spline uncertainty model around surface boundaries. |
|
|
|
seconds |
Permissible buffer delay for TF transform lookup synchronization. |
|
|
|
meters |
Lower vertical bound for 3D volumetric voxel integration. |
|
|
|
meters |
Upper vertical bound for 3D volumetric voxel integration. |
|
|
|
count |
Total count of synchronized depth camera streams ( |
|
|
|
- |
Topic publishing camera intrinsics. |
|
|
|
- |
Topic for primary camera depth stream. |
|
|
|
- |
Topic for secondary camera depth stream. |
|
|
|
- |
Topic for third camera depth stream. |
|
|
|
- |
Topic for fourth camera depth stream. |
Parameter Tuning Guide for Common Robotics Scenarios#
Indoor Mobile Robot Navigation (AMR with Nav2):
Set
voxel_size:=0.05($5\text{ cm}$) to match typical Nav2 costmap resolutions.Set
projection_min_z:=0.05(just above ground plane to prevent floor reflections from appearing as obstacles).Set
projection_max_z:=1.20(matching the highest point on the robot chassis or payload).Set
robot_radius:=0.35(matching robot footprint).
Compute-Constrained Platforms (e.g., low-power Intel Atom® or Edge SBCs):
Set
voxel_size:=0.08or0.10($8\text{–}10\text{ cm}$).Set
max_depth_range:=2.5to limit ray-casting volume.
Tabletop or Manipulator 3D Reconstruction:
Set
voxel_size:=0.01or0.02($1\text{–}2\text{ cm}$) for fine geometric detail.Set
zmin:=0.0andzmax:=1.0to constrain map generation to the workspace.
Integration Workflows#
2. Multi-Camera 360-Degree Surround Mapping#
For robots equipped with multiple depth cameras (e.g., front- and side-facing cameras):
ros2 run fast_mapping fast_mapping_node --ros-args \
-p depth_cameras:=2 \
-p depth_topic_1:=/camera_front/depth/image_rect_raw \
-p depth_topic_2:=/camera_left/depth/image_rect_raw \
-p depth_info_topic:=/camera_front/depth/camera_info
FastMapping uses an ApproximateTime synchronizer with a 30-frame message buffer to align timestamps between cameras before integrating depth observations into the shared 3D volume.
3. Live SLAM with Intel® RealSense™ and RTAB-Map#
FastMapping includes a reference launch pipeline combining an Intel® RealSense™ D400 series camera, RTAB-Map SLAM for visual odometry, and RViz2:
Install RTAB-Map ROS dependencies:
sudo apt install -y ros-jazzy-rtabmap-ros
sudo apt install -y ros-humble-rtabmap-ros
Launch the integrated pipeline:
ros2 launch fast_mapping fast_mapping_rtabmap.launch.py
The launch file starts:
RViz2 with pre-configured display profiles.
RTAB-Map SLAM after a 10-second delay for TF stabilization.
fast_mapping_nodeafter 12 seconds.RealSense camera node with depth alignment enabled after 15 seconds.
4. Standalone Sample Execution with Recorded ROS 2 Bag Data#
FastMapping installs a pre-recorded dataset of a mobile robot rotating in an office environment:
ros2 launch fast_mapping fast_mapping.launch.py
Expected video demonstration: FastMapping Sample Video
RViz2 Visualization Setup#
To manually visualize FastMapping outputs in an existing RViz2 session:
Set the Fixed Frame to
map.Add a Map display:
Topic:
/world/mapDurability Policy:
Transient LocalColor Scheme:
costmapormap
Add a MarkerArray display for 3D occupied voxels:
Topic:
/world/fused_map
Add a MarkerArray display for complete occupancy (free and occupied):
Topic:
/world/occupancy
Add a TF display to observe the camera and robot coordinate axes in real time.
Runtime Diagnostics and Diagnostics Interpretation#
fast_mapping_node periodically logs operational statistics (every 3 seconds by default, configured via p_stat_log_interval_):
[INFO] [fast_mapping]: fast_mapping got 90 images in 3.0s. Aligned 90. Processed 90 (30.00 Hz). 0 left in queue
images: Number of raw depth images received by the subscriber.Aligned: Number of frames with valid depth data synchronized across all cameras.Processed: Number of frames successfully matched with a TF pose and integrated into the octree.Hz: Effective mapping throughput.left in queue: Number of pending frames in the buffer. If this number continually grows, the compute platform is saturated; increasevoxel_sizeor decrease input camera frame rate.
Troubleshooting#
[INFO] [fast_mapping]: waiting for camera depth info from ...Cause:
fast_mapping_nodehas not received asensor_msgs/msg/CameraInfomessage.Resolution: Verify that camera intrinsics are published using
ros2 topic echo <depth_info_topic> --once. Ensure the topic name passed todepth_info_topicmatches your camera driver.
TF Transform Lookup Failure / Missing Transforms
Cause: No active TF link connects
map_frameto the optical frame indicated in depth image headers.Resolution: Inspect the TF tree with
ros2 run tf2_tools view_frames. Ensure your SLAM or odometry module publishesmap -> odomand your robot state publisher publishesbase_link -> camera_color_optical_frame. If network latency delays TF frames, increasetf_delay:=1.0.
Map Not Displaying in RViz2 or Nav2 Costmaps
Cause: QoS durability mismatch. FastMapping publishes on
transient_local.Resolution: In RViz2, expand the Map display topic settings and change Durability Policy from
VolatiletoTransient Local. In Nav2, setmap_subscribe_transient_local: Trueinnav2_params.yaml.
[fast_mapping] Image has distortion. Not yet supported!Cause: Camera provides raw unrectified depth with significant distortion coefficients.
Resolution: Use rectified depth topics (e.g.,
aligned_depth_to_color/image_raworimage_rect_raw).
For general platform assistance, refer to the Robotics AI Suite Troubleshooting Guide.