Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file
CONTRIBUTING
Repository Summary
| Checkout URI | https://github.com/manankharwar/fusioncore.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-04-19 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| compass_msgs | 0.1.1 |
| fusioncore_core | 0.1.1 |
| fusioncore_gazebo | 0.1.1 |
| fusioncore_ros | 0.1.1 |
README
FusionCore
ROS 2 sensor fusion SDK. Combines IMU, wheel encoders, and GPS into one reliable position estimate. Self-tuning noise covariance. Apache 2.0.
What problem does this solve?
Every mobile robot needs to know where it is. It gets this from multiple sensors: IMU, wheel encoders, GPS: each of which is imperfect in its own way. IMUs drift. Wheels slip. GPS jumps. You need software that intelligently combines all three into one trustworthy position estimate.
That software is called a sensor fusion package. The standard one for ROS, robot_localization, was officially deprecated in September 2023. Its designated replacement (fuse) has incomplete GPS support with no ECEF handling or RTK quality gating as of early 2026. At ROSCon UK 2025 the official workshop was still teaching both tools because no clear accessible replacement existed.
FusionCore is that replacement.
Why FusionCore
| Capability | robot_localization | Fuse | FusionCore |
|---|---|---|---|
| Core filter | EKF or UKF | Factor graph | UKF (22D quaternion state) |
| 3D support | Yes | Yes | Full 3D, native |
| IMU bias estimation | No built-in states | Plugin-dependent | Gyro + accel bias states |
| GPS fusion | navsat_transform node | Plugin, no ECEF/RTK | ECEF-native, single node |
| Dual antenna heading | No | No | Yes |
| IMU frame transform | Manual (YAML) | Manual (YAML) | Automatic via TF |
| Message covariances | Used | Partial | Full 3×3 GNSS + odometry |
| GNSS antenna offset | Ignored | Ignored | Lever arm + observability guard |
| Outlier rejection | mahalanobis_threshold | Robust loss functions | Chi-squared gating, all sensors |
| GPS fix quality gating | No | No | GPS / DGPS / RTK_FLOAT / RTK_FIXED |
| Adaptive noise | Manual | Manual | Auto from innovation sequence |
| TF validation at startup | Basic | No | Startup check + fix commands |
| Multiple GNSS receivers | Workaround | Workaround | Native, independent lever arms |
| compass_msgs/Azimuth | No | No | Yes (ENU/NED, rad/deg) |
| Delay compensation | history_length | Factor graph inherent | Full IMU replay, 500ms |
| Ground constraint | Not built-in | Not built-in | VZ=0 pseudo-measurement |
| ZUPT | Not built-in | Not built-in | Auto when stationary |
| Sensor dropout detection | Basic | Basic | Per-sensor SensorHealth enum |
| /diagnostics | Basic | Basic | Per-sensor health + outliers |
| Published covariance | Yes | Yes | Full UKF P matrix |
| Filter reset service | No | No | ~/reset (no restart needed) |
| Maintenance | Deprecated Sep 2023 | Active | Active, 24h response |
| License | BSD-3 | BSD-3 | Apache 2.0 |
| ROS 2 Jazzy | Ported from ROS 1 | Native | Native, from scratch |
Installation
Prerequisites
- ROS 2 Jazzy Jalisco (primary) or ROS 2 Kilted (community tested)
- A colcon workspace (
~/ros2_ws)
Clone into your workspace
This is a monorepo with 4 independent ament_cmake packages: compass_msgs, fusioncore_core, fusioncore_ros, and fusioncore_gazebo. Each has its own package.xml. Colcon finds them by scanning src/ recursively. The repo root has no package.xml and is not itself a package. The repo must live inside src/ for colcon to find the packages.
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/manankharwar/fusioncore.git
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build
source install/setup.bash
Running the tests
cd ~/ros2_ws
source /opt/ros/jazzy/setup.bash
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected output: 39 tests, 0 errors, 0 failures, 0 skipped
Running FusionCore
# Terminal 1: launch the node
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: configure and activate the lifecycle node
ros2 lifecycle set /fusioncore configure
ros2 lifecycle set /fusioncore activate
# Verify it's publishing at 100Hz
ros2 topic hz /fusion/odom
# expected: average rate: 100.000
File truncated at 100 lines see the full file