Repository Summary

Description
Checkout URI https://github.com/manankharwar/fusioncore.git
VCS Type git
VCS Version main
Last Updated 2026-04-29
Dev Status UNKNOWN
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

README

FusionCore

CI DOI Docs

ROS 2 sensor fusion: IMU + wheel encoders + GPS fused via UKF at 100 Hz. 22-state filter with IMU bias estimation, adaptive noise covariance, and chi-squared outlier rejection on every sensor.


Why I built this

I needed sensor fusion for a mobile robot project and reached for robot_localization like everyone does. It works well. But I wanted a filter that estimated IMU gyro and accelerometer bias as part of the state vector, adapted its noise covariance from real sensor behavior rather than config values, and rejected outliers on every sensor update: not just GPS.

So I built FusionCore. It’s a 22-state UKF that fuses IMU, wheel encoders, and GPS natively. Gyro and accelerometer bias are estimated continuously as filter states. Noise covariance adapts from the innovation sequence automatically. Every sensor update: IMU, wheel odometry, GPS: goes through a chi-squared gate before it touches the filter. GPS is handled in ECEF directly, no coordinate projection.

Trajectory overlay: all 6 sequences, SE3-aligned to RTK GPS ground truth


Benchmark

FusionCore vs robot_localization on the NCLT dataset: same IMU + wheel odometry + GPS, no manual tuning. Six sequences:

RL-EKF run with odom0_twist_rejection_threshold: 4.03 and odom1_pose_rejection_threshold: 3.72 (chi²-equivalent to FusionCore’s thresholds at 99.9% confidence).

Sequence FC ATE RMSE RL-EKF ATE RMSE RL-UKF
2012-01-08 5.6 m 13.0 m NaN divergence at t=31 s
2012-02-04 9.7 m 19.1 m NaN divergence at t=22 s
2012-03-31 4.2 m 54.3 m NaN divergence at t=18 s
2012-08-20 7.5 m 24.1 m NaN divergence
2012-11-04 28.6 m 9.6 m NaN divergence
2013-02-23 4.1 m 11.0 m NaN divergence

Install

Supports ROS 2 Jazzy (Ubuntu 24.04) and Humble (Ubuntu 22.04).

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  # or /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build && source install/setup.bash

Headless / Raspberry Pi: touch ~/ros2_ws/src/fusioncore/fusioncore_gazebo/COLCON_IGNORE before building to skip the Gazebo package.


Quick start

ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
  fusioncore_config:=/path/to/your_robot.yaml


Documentation

manankharwar.github.io/fusioncore


License

Apache 2.0.


Citation

@software{kharwar2026fusioncore,
  author    = {Kharwar, Manan},
  title     = {FusionCore: ROS 2 UKF Sensor Fusion},
  year      = {2026},
  publisher = {Zenodo},
  version   = {0.2.0},
  doi       = {10.5281/zenodo.19834991},
  url       = {https://doi.org/10.5281/zenodo.19834991}
}


File truncated at 100 lines see the full file

CONTRIBUTING

Contributing to FusionCore

Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help.

The fastest way to contribute

The most impactful contributions right now are hardware configs. If you have FusionCore running on a robot, platform, or IMU that isn’t in the repo yet, open a PR adding a YAML under fusioncore_ros/config/. See the hardware config section below.

Before you start

  • Check open issues: the bug may already be reported
  • Check Discussions: the question may already be answered
  • For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code

Development setup

# Clone and build
git clone https://github.com/manankharwar/fusioncore.git
cd fusioncore

source /opt/ros/jazzy/setup.sh  # replace jazzy with humble on Ubuntu 22.04
rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y  # replace jazzy with humble on Ubuntu 22.04
colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON

# Run all tests before and after your change
colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros
colcon test-result --verbose

All 49 tests must pass. CI will catch it if they don’t.

Hardware configs

A hardware config is a YAML file under fusioncore_ros/config/ named after the platform (e.g. clearpath_husky.yaml, ublox_f9p.yaml).

Copy fusioncore_ros/config/fusioncore.yaml as the starting point and adjust:

  • imu.gyro_noise / imu.accel_noise: pull from your IMU’s datasheet
  • gnss.base_noise_xy: your GPS receiver’s CEP spec
  • Any topic remaps specific to your platform

Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster.

Pull request checklist

  • All 49 tests pass (colcon test-result --verbose shows 0 failures)
  • For new features: tests added in fusioncore_core/tests/
  • For hardware configs: YAML includes a comment with platform + sensor details
  • Commit message describes why, not just what

Code style

C++17. Follow the style of the surrounding code: no reformatting unrelated lines. clang-format is not enforced but is appreciated.

Reporting bugs

Use the Bug Report issue template. Include the output of colcon test-result --verbose if tests are involved.

Questions

Open a Discussion rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas.

Response time: typically within 24 hours.

# Contributing to FusionCore Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help. ## The fastest way to contribute The most impactful contributions right now are **hardware configs**. If you have FusionCore running on a robot, platform, or IMU that isn't in the repo yet, open a PR adding a YAML under `fusioncore_ros/config/`. See the [hardware config section](#hardware-configs) below. ## Before you start - Check [open issues](https://github.com/manankharwar/fusioncore/issues): the bug may already be reported - Check [Discussions](https://github.com/manankharwar/fusioncore/discussions): the question may already be answered - For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code ## Development setup ```bash # Clone and build git clone https://github.com/manankharwar/fusioncore.git cd fusioncore source /opt/ros/jazzy/setup.sh # replace jazzy with humble on Ubuntu 22.04 rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y # replace jazzy with humble on Ubuntu 22.04 colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON # Run all tests before and after your change colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros colcon test-result --verbose ``` All 49 tests must pass. CI will catch it if they don't. ## Hardware configs A hardware config is a YAML file under `fusioncore_ros/config/` named after the platform (e.g. `clearpath_husky.yaml`, `ublox_f9p.yaml`). Copy `fusioncore_ros/config/fusioncore.yaml` as the starting point and adjust: - `imu.gyro_noise` / `imu.accel_noise`: pull from your IMU's datasheet - `gnss.base_noise_xy`: your GPS receiver's CEP spec - Any topic remaps specific to your platform Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster. ## Pull request checklist - [ ] All 49 tests pass (`colcon test-result --verbose` shows 0 failures) - [ ] For new features: tests added in `fusioncore_core/tests/` - [ ] For hardware configs: YAML includes a comment with platform + sensor details - [ ] Commit message describes *why*, not just *what* ## Code style C++17. Follow the style of the surrounding code: no reformatting unrelated lines. `clang-format` is not enforced but is appreciated. ## Reporting bugs Use the [Bug Report](.github/ISSUE_TEMPLATE/bug_report.md) issue template. Include the output of `colcon test-result --verbose` if tests are involved. ## Questions Open a [Discussion](https://github.com/manankharwar/fusioncore/discussions) rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas. Response time: typically within 24 hours.

Repository Summary

Description
Checkout URI https://github.com/manankharwar/fusioncore.git
VCS Type git
VCS Version main
Last Updated 2026-04-29
Dev Status UNKNOWN
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

README

FusionCore

CI DOI Docs

ROS 2 sensor fusion: IMU + wheel encoders + GPS fused via UKF at 100 Hz. 22-state filter with IMU bias estimation, adaptive noise covariance, and chi-squared outlier rejection on every sensor.


Why I built this

I needed sensor fusion for a mobile robot project and reached for robot_localization like everyone does. It works well. But I wanted a filter that estimated IMU gyro and accelerometer bias as part of the state vector, adapted its noise covariance from real sensor behavior rather than config values, and rejected outliers on every sensor update: not just GPS.

So I built FusionCore. It’s a 22-state UKF that fuses IMU, wheel encoders, and GPS natively. Gyro and accelerometer bias are estimated continuously as filter states. Noise covariance adapts from the innovation sequence automatically. Every sensor update: IMU, wheel odometry, GPS: goes through a chi-squared gate before it touches the filter. GPS is handled in ECEF directly, no coordinate projection.

Trajectory overlay: all 6 sequences, SE3-aligned to RTK GPS ground truth


Benchmark

FusionCore vs robot_localization on the NCLT dataset: same IMU + wheel odometry + GPS, no manual tuning. Six sequences:

RL-EKF run with odom0_twist_rejection_threshold: 4.03 and odom1_pose_rejection_threshold: 3.72 (chi²-equivalent to FusionCore’s thresholds at 99.9% confidence).

Sequence FC ATE RMSE RL-EKF ATE RMSE RL-UKF
2012-01-08 5.6 m 13.0 m NaN divergence at t=31 s
2012-02-04 9.7 m 19.1 m NaN divergence at t=22 s
2012-03-31 4.2 m 54.3 m NaN divergence at t=18 s
2012-08-20 7.5 m 24.1 m NaN divergence
2012-11-04 28.6 m 9.6 m NaN divergence
2013-02-23 4.1 m 11.0 m NaN divergence

Install

Supports ROS 2 Jazzy (Ubuntu 24.04) and Humble (Ubuntu 22.04).

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  # or /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build && source install/setup.bash

Headless / Raspberry Pi: touch ~/ros2_ws/src/fusioncore/fusioncore_gazebo/COLCON_IGNORE before building to skip the Gazebo package.


Quick start

ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
  fusioncore_config:=/path/to/your_robot.yaml


Documentation

manankharwar.github.io/fusioncore


License

Apache 2.0.


Citation

@software{kharwar2026fusioncore,
  author    = {Kharwar, Manan},
  title     = {FusionCore: ROS 2 UKF Sensor Fusion},
  year      = {2026},
  publisher = {Zenodo},
  version   = {0.2.0},
  doi       = {10.5281/zenodo.19834991},
  url       = {https://doi.org/10.5281/zenodo.19834991}
}


File truncated at 100 lines see the full file

CONTRIBUTING

Contributing to FusionCore

Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help.

The fastest way to contribute

The most impactful contributions right now are hardware configs. If you have FusionCore running on a robot, platform, or IMU that isn’t in the repo yet, open a PR adding a YAML under fusioncore_ros/config/. See the hardware config section below.

Before you start

  • Check open issues: the bug may already be reported
  • Check Discussions: the question may already be answered
  • For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code

Development setup

# Clone and build
git clone https://github.com/manankharwar/fusioncore.git
cd fusioncore

source /opt/ros/jazzy/setup.sh  # replace jazzy with humble on Ubuntu 22.04
rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y  # replace jazzy with humble on Ubuntu 22.04
colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON

# Run all tests before and after your change
colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros
colcon test-result --verbose

All 49 tests must pass. CI will catch it if they don’t.

Hardware configs

A hardware config is a YAML file under fusioncore_ros/config/ named after the platform (e.g. clearpath_husky.yaml, ublox_f9p.yaml).

Copy fusioncore_ros/config/fusioncore.yaml as the starting point and adjust:

  • imu.gyro_noise / imu.accel_noise: pull from your IMU’s datasheet
  • gnss.base_noise_xy: your GPS receiver’s CEP spec
  • Any topic remaps specific to your platform

Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster.

Pull request checklist

  • All 49 tests pass (colcon test-result --verbose shows 0 failures)
  • For new features: tests added in fusioncore_core/tests/
  • For hardware configs: YAML includes a comment with platform + sensor details
  • Commit message describes why, not just what

Code style

C++17. Follow the style of the surrounding code: no reformatting unrelated lines. clang-format is not enforced but is appreciated.

Reporting bugs

Use the Bug Report issue template. Include the output of colcon test-result --verbose if tests are involved.

Questions

Open a Discussion rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas.

Response time: typically within 24 hours.

# Contributing to FusionCore Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help. ## The fastest way to contribute The most impactful contributions right now are **hardware configs**. If you have FusionCore running on a robot, platform, or IMU that isn't in the repo yet, open a PR adding a YAML under `fusioncore_ros/config/`. See the [hardware config section](#hardware-configs) below. ## Before you start - Check [open issues](https://github.com/manankharwar/fusioncore/issues): the bug may already be reported - Check [Discussions](https://github.com/manankharwar/fusioncore/discussions): the question may already be answered - For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code ## Development setup ```bash # Clone and build git clone https://github.com/manankharwar/fusioncore.git cd fusioncore source /opt/ros/jazzy/setup.sh # replace jazzy with humble on Ubuntu 22.04 rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y # replace jazzy with humble on Ubuntu 22.04 colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON # Run all tests before and after your change colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros colcon test-result --verbose ``` All 49 tests must pass. CI will catch it if they don't. ## Hardware configs A hardware config is a YAML file under `fusioncore_ros/config/` named after the platform (e.g. `clearpath_husky.yaml`, `ublox_f9p.yaml`). Copy `fusioncore_ros/config/fusioncore.yaml` as the starting point and adjust: - `imu.gyro_noise` / `imu.accel_noise`: pull from your IMU's datasheet - `gnss.base_noise_xy`: your GPS receiver's CEP spec - Any topic remaps specific to your platform Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster. ## Pull request checklist - [ ] All 49 tests pass (`colcon test-result --verbose` shows 0 failures) - [ ] For new features: tests added in `fusioncore_core/tests/` - [ ] For hardware configs: YAML includes a comment with platform + sensor details - [ ] Commit message describes *why*, not just *what* ## Code style C++17. Follow the style of the surrounding code: no reformatting unrelated lines. `clang-format` is not enforced but is appreciated. ## Reporting bugs Use the [Bug Report](.github/ISSUE_TEMPLATE/bug_report.md) issue template. Include the output of `colcon test-result --verbose` if tests are involved. ## Questions Open a [Discussion](https://github.com/manankharwar/fusioncore/discussions) rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas. Response time: typically within 24 hours.
No version for distro kilted showing humble. Known supported distros are highlighted in the buttons above.

Repository Summary

Description
Checkout URI https://github.com/manankharwar/fusioncore.git
VCS Type git
VCS Version main
Last Updated 2026-04-29
Dev Status UNKNOWN
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

README

FusionCore

CI DOI Docs

ROS 2 sensor fusion: IMU + wheel encoders + GPS fused via UKF at 100 Hz. 22-state filter with IMU bias estimation, adaptive noise covariance, and chi-squared outlier rejection on every sensor.


Why I built this

I needed sensor fusion for a mobile robot project and reached for robot_localization like everyone does. It works well. But I wanted a filter that estimated IMU gyro and accelerometer bias as part of the state vector, adapted its noise covariance from real sensor behavior rather than config values, and rejected outliers on every sensor update: not just GPS.

So I built FusionCore. It’s a 22-state UKF that fuses IMU, wheel encoders, and GPS natively. Gyro and accelerometer bias are estimated continuously as filter states. Noise covariance adapts from the innovation sequence automatically. Every sensor update: IMU, wheel odometry, GPS: goes through a chi-squared gate before it touches the filter. GPS is handled in ECEF directly, no coordinate projection.

Trajectory overlay: all 6 sequences, SE3-aligned to RTK GPS ground truth


Benchmark

FusionCore vs robot_localization on the NCLT dataset: same IMU + wheel odometry + GPS, no manual tuning. Six sequences:

RL-EKF run with odom0_twist_rejection_threshold: 4.03 and odom1_pose_rejection_threshold: 3.72 (chi²-equivalent to FusionCore’s thresholds at 99.9% confidence).

Sequence FC ATE RMSE RL-EKF ATE RMSE RL-UKF
2012-01-08 5.6 m 13.0 m NaN divergence at t=31 s
2012-02-04 9.7 m 19.1 m NaN divergence at t=22 s
2012-03-31 4.2 m 54.3 m NaN divergence at t=18 s
2012-08-20 7.5 m 24.1 m NaN divergence
2012-11-04 28.6 m 9.6 m NaN divergence
2013-02-23 4.1 m 11.0 m NaN divergence

Install

Supports ROS 2 Jazzy (Ubuntu 24.04) and Humble (Ubuntu 22.04).

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  # or /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build && source install/setup.bash

Headless / Raspberry Pi: touch ~/ros2_ws/src/fusioncore/fusioncore_gazebo/COLCON_IGNORE before building to skip the Gazebo package.


Quick start

ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
  fusioncore_config:=/path/to/your_robot.yaml


Documentation

manankharwar.github.io/fusioncore


License

Apache 2.0.


Citation

@software{kharwar2026fusioncore,
  author    = {Kharwar, Manan},
  title     = {FusionCore: ROS 2 UKF Sensor Fusion},
  year      = {2026},
  publisher = {Zenodo},
  version   = {0.2.0},
  doi       = {10.5281/zenodo.19834991},
  url       = {https://doi.org/10.5281/zenodo.19834991}
}


File truncated at 100 lines see the full file

CONTRIBUTING

Contributing to FusionCore

Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help.

The fastest way to contribute

The most impactful contributions right now are hardware configs. If you have FusionCore running on a robot, platform, or IMU that isn’t in the repo yet, open a PR adding a YAML under fusioncore_ros/config/. See the hardware config section below.

Before you start

  • Check open issues: the bug may already be reported
  • Check Discussions: the question may already be answered
  • For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code

Development setup

# Clone and build
git clone https://github.com/manankharwar/fusioncore.git
cd fusioncore

source /opt/ros/jazzy/setup.sh  # replace jazzy with humble on Ubuntu 22.04
rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y  # replace jazzy with humble on Ubuntu 22.04
colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON

# Run all tests before and after your change
colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros
colcon test-result --verbose

All 49 tests must pass. CI will catch it if they don’t.

Hardware configs

A hardware config is a YAML file under fusioncore_ros/config/ named after the platform (e.g. clearpath_husky.yaml, ublox_f9p.yaml).

Copy fusioncore_ros/config/fusioncore.yaml as the starting point and adjust:

  • imu.gyro_noise / imu.accel_noise: pull from your IMU’s datasheet
  • gnss.base_noise_xy: your GPS receiver’s CEP spec
  • Any topic remaps specific to your platform

Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster.

Pull request checklist

  • All 49 tests pass (colcon test-result --verbose shows 0 failures)
  • For new features: tests added in fusioncore_core/tests/
  • For hardware configs: YAML includes a comment with platform + sensor details
  • Commit message describes why, not just what

Code style

C++17. Follow the style of the surrounding code: no reformatting unrelated lines. clang-format is not enforced but is appreciated.

Reporting bugs

Use the Bug Report issue template. Include the output of colcon test-result --verbose if tests are involved.

Questions

Open a Discussion rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas.

Response time: typically within 24 hours.

# Contributing to FusionCore Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help. ## The fastest way to contribute The most impactful contributions right now are **hardware configs**. If you have FusionCore running on a robot, platform, or IMU that isn't in the repo yet, open a PR adding a YAML under `fusioncore_ros/config/`. See the [hardware config section](#hardware-configs) below. ## Before you start - Check [open issues](https://github.com/manankharwar/fusioncore/issues): the bug may already be reported - Check [Discussions](https://github.com/manankharwar/fusioncore/discussions): the question may already be answered - For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code ## Development setup ```bash # Clone and build git clone https://github.com/manankharwar/fusioncore.git cd fusioncore source /opt/ros/jazzy/setup.sh # replace jazzy with humble on Ubuntu 22.04 rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y # replace jazzy with humble on Ubuntu 22.04 colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON # Run all tests before and after your change colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros colcon test-result --verbose ``` All 49 tests must pass. CI will catch it if they don't. ## Hardware configs A hardware config is a YAML file under `fusioncore_ros/config/` named after the platform (e.g. `clearpath_husky.yaml`, `ublox_f9p.yaml`). Copy `fusioncore_ros/config/fusioncore.yaml` as the starting point and adjust: - `imu.gyro_noise` / `imu.accel_noise`: pull from your IMU's datasheet - `gnss.base_noise_xy`: your GPS receiver's CEP spec - Any topic remaps specific to your platform Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster. ## Pull request checklist - [ ] All 49 tests pass (`colcon test-result --verbose` shows 0 failures) - [ ] For new features: tests added in `fusioncore_core/tests/` - [ ] For hardware configs: YAML includes a comment with platform + sensor details - [ ] Commit message describes *why*, not just *what* ## Code style C++17. Follow the style of the surrounding code: no reformatting unrelated lines. `clang-format` is not enforced but is appreciated. ## Reporting bugs Use the [Bug Report](.github/ISSUE_TEMPLATE/bug_report.md) issue template. Include the output of `colcon test-result --verbose` if tests are involved. ## Questions Open a [Discussion](https://github.com/manankharwar/fusioncore/discussions) rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas. Response time: typically within 24 hours.
No version for distro rolling showing humble. Known supported distros are highlighted in the buttons above.

Repository Summary

Description
Checkout URI https://github.com/manankharwar/fusioncore.git
VCS Type git
VCS Version main
Last Updated 2026-04-29
Dev Status UNKNOWN
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

README

FusionCore

CI DOI Docs

ROS 2 sensor fusion: IMU + wheel encoders + GPS fused via UKF at 100 Hz. 22-state filter with IMU bias estimation, adaptive noise covariance, and chi-squared outlier rejection on every sensor.


Why I built this

I needed sensor fusion for a mobile robot project and reached for robot_localization like everyone does. It works well. But I wanted a filter that estimated IMU gyro and accelerometer bias as part of the state vector, adapted its noise covariance from real sensor behavior rather than config values, and rejected outliers on every sensor update: not just GPS.

So I built FusionCore. It’s a 22-state UKF that fuses IMU, wheel encoders, and GPS natively. Gyro and accelerometer bias are estimated continuously as filter states. Noise covariance adapts from the innovation sequence automatically. Every sensor update: IMU, wheel odometry, GPS: goes through a chi-squared gate before it touches the filter. GPS is handled in ECEF directly, no coordinate projection.

Trajectory overlay: all 6 sequences, SE3-aligned to RTK GPS ground truth


Benchmark

FusionCore vs robot_localization on the NCLT dataset: same IMU + wheel odometry + GPS, no manual tuning. Six sequences:

RL-EKF run with odom0_twist_rejection_threshold: 4.03 and odom1_pose_rejection_threshold: 3.72 (chi²-equivalent to FusionCore’s thresholds at 99.9% confidence).

Sequence FC ATE RMSE RL-EKF ATE RMSE RL-UKF
2012-01-08 5.6 m 13.0 m NaN divergence at t=31 s
2012-02-04 9.7 m 19.1 m NaN divergence at t=22 s
2012-03-31 4.2 m 54.3 m NaN divergence at t=18 s
2012-08-20 7.5 m 24.1 m NaN divergence
2012-11-04 28.6 m 9.6 m NaN divergence
2013-02-23 4.1 m 11.0 m NaN divergence

Install

Supports ROS 2 Jazzy (Ubuntu 24.04) and Humble (Ubuntu 22.04).

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  # or /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build && source install/setup.bash

Headless / Raspberry Pi: touch ~/ros2_ws/src/fusioncore/fusioncore_gazebo/COLCON_IGNORE before building to skip the Gazebo package.


Quick start

ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
  fusioncore_config:=/path/to/your_robot.yaml


Documentation

manankharwar.github.io/fusioncore


License

Apache 2.0.


Citation

@software{kharwar2026fusioncore,
  author    = {Kharwar, Manan},
  title     = {FusionCore: ROS 2 UKF Sensor Fusion},
  year      = {2026},
  publisher = {Zenodo},
  version   = {0.2.0},
  doi       = {10.5281/zenodo.19834991},
  url       = {https://doi.org/10.5281/zenodo.19834991}
}


File truncated at 100 lines see the full file

CONTRIBUTING

Contributing to FusionCore

Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help.

The fastest way to contribute

The most impactful contributions right now are hardware configs. If you have FusionCore running on a robot, platform, or IMU that isn’t in the repo yet, open a PR adding a YAML under fusioncore_ros/config/. See the hardware config section below.

Before you start

  • Check open issues: the bug may already be reported
  • Check Discussions: the question may already be answered
  • For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code

Development setup

# Clone and build
git clone https://github.com/manankharwar/fusioncore.git
cd fusioncore

source /opt/ros/jazzy/setup.sh  # replace jazzy with humble on Ubuntu 22.04
rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y  # replace jazzy with humble on Ubuntu 22.04
colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON

# Run all tests before and after your change
colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros
colcon test-result --verbose

All 49 tests must pass. CI will catch it if they don’t.

Hardware configs

A hardware config is a YAML file under fusioncore_ros/config/ named after the platform (e.g. clearpath_husky.yaml, ublox_f9p.yaml).

Copy fusioncore_ros/config/fusioncore.yaml as the starting point and adjust:

  • imu.gyro_noise / imu.accel_noise: pull from your IMU’s datasheet
  • gnss.base_noise_xy: your GPS receiver’s CEP spec
  • Any topic remaps specific to your platform

Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster.

Pull request checklist

  • All 49 tests pass (colcon test-result --verbose shows 0 failures)
  • For new features: tests added in fusioncore_core/tests/
  • For hardware configs: YAML includes a comment with platform + sensor details
  • Commit message describes why, not just what

Code style

C++17. Follow the style of the surrounding code: no reformatting unrelated lines. clang-format is not enforced but is appreciated.

Reporting bugs

Use the Bug Report issue template. Include the output of colcon test-result --verbose if tests are involved.

Questions

Open a Discussion rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas.

Response time: typically within 24 hours.

# Contributing to FusionCore Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help. ## The fastest way to contribute The most impactful contributions right now are **hardware configs**. If you have FusionCore running on a robot, platform, or IMU that isn't in the repo yet, open a PR adding a YAML under `fusioncore_ros/config/`. See the [hardware config section](#hardware-configs) below. ## Before you start - Check [open issues](https://github.com/manankharwar/fusioncore/issues): the bug may already be reported - Check [Discussions](https://github.com/manankharwar/fusioncore/discussions): the question may already be answered - For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code ## Development setup ```bash # Clone and build git clone https://github.com/manankharwar/fusioncore.git cd fusioncore source /opt/ros/jazzy/setup.sh # replace jazzy with humble on Ubuntu 22.04 rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y # replace jazzy with humble on Ubuntu 22.04 colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON # Run all tests before and after your change colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros colcon test-result --verbose ``` All 49 tests must pass. CI will catch it if they don't. ## Hardware configs A hardware config is a YAML file under `fusioncore_ros/config/` named after the platform (e.g. `clearpath_husky.yaml`, `ublox_f9p.yaml`). Copy `fusioncore_ros/config/fusioncore.yaml` as the starting point and adjust: - `imu.gyro_noise` / `imu.accel_noise`: pull from your IMU's datasheet - `gnss.base_noise_xy`: your GPS receiver's CEP spec - Any topic remaps specific to your platform Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster. ## Pull request checklist - [ ] All 49 tests pass (`colcon test-result --verbose` shows 0 failures) - [ ] For new features: tests added in `fusioncore_core/tests/` - [ ] For hardware configs: YAML includes a comment with platform + sensor details - [ ] Commit message describes *why*, not just *what* ## Code style C++17. Follow the style of the surrounding code: no reformatting unrelated lines. `clang-format` is not enforced but is appreciated. ## Reporting bugs Use the [Bug Report](.github/ISSUE_TEMPLATE/bug_report.md) issue template. Include the output of `colcon test-result --verbose` if tests are involved. ## Questions Open a [Discussion](https://github.com/manankharwar/fusioncore/discussions) rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas. Response time: typically within 24 hours.
No version for distro github showing humble. Known supported distros are highlighted in the buttons above.

Repository Summary

Description
Checkout URI https://github.com/manankharwar/fusioncore.git
VCS Type git
VCS Version main
Last Updated 2026-04-29
Dev Status UNKNOWN
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

README

FusionCore

CI DOI Docs

ROS 2 sensor fusion: IMU + wheel encoders + GPS fused via UKF at 100 Hz. 22-state filter with IMU bias estimation, adaptive noise covariance, and chi-squared outlier rejection on every sensor.


Why I built this

I needed sensor fusion for a mobile robot project and reached for robot_localization like everyone does. It works well. But I wanted a filter that estimated IMU gyro and accelerometer bias as part of the state vector, adapted its noise covariance from real sensor behavior rather than config values, and rejected outliers on every sensor update: not just GPS.

So I built FusionCore. It’s a 22-state UKF that fuses IMU, wheel encoders, and GPS natively. Gyro and accelerometer bias are estimated continuously as filter states. Noise covariance adapts from the innovation sequence automatically. Every sensor update: IMU, wheel odometry, GPS: goes through a chi-squared gate before it touches the filter. GPS is handled in ECEF directly, no coordinate projection.

Trajectory overlay: all 6 sequences, SE3-aligned to RTK GPS ground truth


Benchmark

FusionCore vs robot_localization on the NCLT dataset: same IMU + wheel odometry + GPS, no manual tuning. Six sequences:

RL-EKF run with odom0_twist_rejection_threshold: 4.03 and odom1_pose_rejection_threshold: 3.72 (chi²-equivalent to FusionCore’s thresholds at 99.9% confidence).

Sequence FC ATE RMSE RL-EKF ATE RMSE RL-UKF
2012-01-08 5.6 m 13.0 m NaN divergence at t=31 s
2012-02-04 9.7 m 19.1 m NaN divergence at t=22 s
2012-03-31 4.2 m 54.3 m NaN divergence at t=18 s
2012-08-20 7.5 m 24.1 m NaN divergence
2012-11-04 28.6 m 9.6 m NaN divergence
2013-02-23 4.1 m 11.0 m NaN divergence

Install

Supports ROS 2 Jazzy (Ubuntu 24.04) and Humble (Ubuntu 22.04).

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  # or /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build && source install/setup.bash

Headless / Raspberry Pi: touch ~/ros2_ws/src/fusioncore/fusioncore_gazebo/COLCON_IGNORE before building to skip the Gazebo package.


Quick start

ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
  fusioncore_config:=/path/to/your_robot.yaml


Documentation

manankharwar.github.io/fusioncore


License

Apache 2.0.


Citation

@software{kharwar2026fusioncore,
  author    = {Kharwar, Manan},
  title     = {FusionCore: ROS 2 UKF Sensor Fusion},
  year      = {2026},
  publisher = {Zenodo},
  version   = {0.2.0},
  doi       = {10.5281/zenodo.19834991},
  url       = {https://doi.org/10.5281/zenodo.19834991}
}


File truncated at 100 lines see the full file

CONTRIBUTING

Contributing to FusionCore

Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help.

The fastest way to contribute

The most impactful contributions right now are hardware configs. If you have FusionCore running on a robot, platform, or IMU that isn’t in the repo yet, open a PR adding a YAML under fusioncore_ros/config/. See the hardware config section below.

Before you start

  • Check open issues: the bug may already be reported
  • Check Discussions: the question may already be answered
  • For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code

Development setup

# Clone and build
git clone https://github.com/manankharwar/fusioncore.git
cd fusioncore

source /opt/ros/jazzy/setup.sh  # replace jazzy with humble on Ubuntu 22.04
rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y  # replace jazzy with humble on Ubuntu 22.04
colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON

# Run all tests before and after your change
colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros
colcon test-result --verbose

All 49 tests must pass. CI will catch it if they don’t.

Hardware configs

A hardware config is a YAML file under fusioncore_ros/config/ named after the platform (e.g. clearpath_husky.yaml, ublox_f9p.yaml).

Copy fusioncore_ros/config/fusioncore.yaml as the starting point and adjust:

  • imu.gyro_noise / imu.accel_noise: pull from your IMU’s datasheet
  • gnss.base_noise_xy: your GPS receiver’s CEP spec
  • Any topic remaps specific to your platform

Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster.

Pull request checklist

  • All 49 tests pass (colcon test-result --verbose shows 0 failures)
  • For new features: tests added in fusioncore_core/tests/
  • For hardware configs: YAML includes a comment with platform + sensor details
  • Commit message describes why, not just what

Code style

C++17. Follow the style of the surrounding code: no reformatting unrelated lines. clang-format is not enforced but is appreciated.

Reporting bugs

Use the Bug Report issue template. Include the output of colcon test-result --verbose if tests are involved.

Questions

Open a Discussion rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas.

Response time: typically within 24 hours.

# Contributing to FusionCore Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help. ## The fastest way to contribute The most impactful contributions right now are **hardware configs**. If you have FusionCore running on a robot, platform, or IMU that isn't in the repo yet, open a PR adding a YAML under `fusioncore_ros/config/`. See the [hardware config section](#hardware-configs) below. ## Before you start - Check [open issues](https://github.com/manankharwar/fusioncore/issues): the bug may already be reported - Check [Discussions](https://github.com/manankharwar/fusioncore/discussions): the question may already be answered - For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code ## Development setup ```bash # Clone and build git clone https://github.com/manankharwar/fusioncore.git cd fusioncore source /opt/ros/jazzy/setup.sh # replace jazzy with humble on Ubuntu 22.04 rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y # replace jazzy with humble on Ubuntu 22.04 colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON # Run all tests before and after your change colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros colcon test-result --verbose ``` All 49 tests must pass. CI will catch it if they don't. ## Hardware configs A hardware config is a YAML file under `fusioncore_ros/config/` named after the platform (e.g. `clearpath_husky.yaml`, `ublox_f9p.yaml`). Copy `fusioncore_ros/config/fusioncore.yaml` as the starting point and adjust: - `imu.gyro_noise` / `imu.accel_noise`: pull from your IMU's datasheet - `gnss.base_noise_xy`: your GPS receiver's CEP spec - Any topic remaps specific to your platform Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster. ## Pull request checklist - [ ] All 49 tests pass (`colcon test-result --verbose` shows 0 failures) - [ ] For new features: tests added in `fusioncore_core/tests/` - [ ] For hardware configs: YAML includes a comment with platform + sensor details - [ ] Commit message describes *why*, not just *what* ## Code style C++17. Follow the style of the surrounding code: no reformatting unrelated lines. `clang-format` is not enforced but is appreciated. ## Reporting bugs Use the [Bug Report](.github/ISSUE_TEMPLATE/bug_report.md) issue template. Include the output of `colcon test-result --verbose` if tests are involved. ## Questions Open a [Discussion](https://github.com/manankharwar/fusioncore/discussions) rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas. Response time: typically within 24 hours.
No version for distro galactic showing humble. Known supported distros are highlighted in the buttons above.

Repository Summary

Description
Checkout URI https://github.com/manankharwar/fusioncore.git
VCS Type git
VCS Version main
Last Updated 2026-04-29
Dev Status UNKNOWN
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

README

FusionCore

CI DOI Docs

ROS 2 sensor fusion: IMU + wheel encoders + GPS fused via UKF at 100 Hz. 22-state filter with IMU bias estimation, adaptive noise covariance, and chi-squared outlier rejection on every sensor.


Why I built this

I needed sensor fusion for a mobile robot project and reached for robot_localization like everyone does. It works well. But I wanted a filter that estimated IMU gyro and accelerometer bias as part of the state vector, adapted its noise covariance from real sensor behavior rather than config values, and rejected outliers on every sensor update: not just GPS.

So I built FusionCore. It’s a 22-state UKF that fuses IMU, wheel encoders, and GPS natively. Gyro and accelerometer bias are estimated continuously as filter states. Noise covariance adapts from the innovation sequence automatically. Every sensor update: IMU, wheel odometry, GPS: goes through a chi-squared gate before it touches the filter. GPS is handled in ECEF directly, no coordinate projection.

Trajectory overlay: all 6 sequences, SE3-aligned to RTK GPS ground truth


Benchmark

FusionCore vs robot_localization on the NCLT dataset: same IMU + wheel odometry + GPS, no manual tuning. Six sequences:

RL-EKF run with odom0_twist_rejection_threshold: 4.03 and odom1_pose_rejection_threshold: 3.72 (chi²-equivalent to FusionCore’s thresholds at 99.9% confidence).

Sequence FC ATE RMSE RL-EKF ATE RMSE RL-UKF
2012-01-08 5.6 m 13.0 m NaN divergence at t=31 s
2012-02-04 9.7 m 19.1 m NaN divergence at t=22 s
2012-03-31 4.2 m 54.3 m NaN divergence at t=18 s
2012-08-20 7.5 m 24.1 m NaN divergence
2012-11-04 28.6 m 9.6 m NaN divergence
2013-02-23 4.1 m 11.0 m NaN divergence

Install

Supports ROS 2 Jazzy (Ubuntu 24.04) and Humble (Ubuntu 22.04).

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  # or /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build && source install/setup.bash

Headless / Raspberry Pi: touch ~/ros2_ws/src/fusioncore/fusioncore_gazebo/COLCON_IGNORE before building to skip the Gazebo package.


Quick start

ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
  fusioncore_config:=/path/to/your_robot.yaml


Documentation

manankharwar.github.io/fusioncore


License

Apache 2.0.


Citation

@software{kharwar2026fusioncore,
  author    = {Kharwar, Manan},
  title     = {FusionCore: ROS 2 UKF Sensor Fusion},
  year      = {2026},
  publisher = {Zenodo},
  version   = {0.2.0},
  doi       = {10.5281/zenodo.19834991},
  url       = {https://doi.org/10.5281/zenodo.19834991}
}


File truncated at 100 lines see the full file

CONTRIBUTING

Contributing to FusionCore

Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help.

The fastest way to contribute

The most impactful contributions right now are hardware configs. If you have FusionCore running on a robot, platform, or IMU that isn’t in the repo yet, open a PR adding a YAML under fusioncore_ros/config/. See the hardware config section below.

Before you start

  • Check open issues: the bug may already be reported
  • Check Discussions: the question may already be answered
  • For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code

Development setup

# Clone and build
git clone https://github.com/manankharwar/fusioncore.git
cd fusioncore

source /opt/ros/jazzy/setup.sh  # replace jazzy with humble on Ubuntu 22.04
rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y  # replace jazzy with humble on Ubuntu 22.04
colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON

# Run all tests before and after your change
colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros
colcon test-result --verbose

All 49 tests must pass. CI will catch it if they don’t.

Hardware configs

A hardware config is a YAML file under fusioncore_ros/config/ named after the platform (e.g. clearpath_husky.yaml, ublox_f9p.yaml).

Copy fusioncore_ros/config/fusioncore.yaml as the starting point and adjust:

  • imu.gyro_noise / imu.accel_noise: pull from your IMU’s datasheet
  • gnss.base_noise_xy: your GPS receiver’s CEP spec
  • Any topic remaps specific to your platform

Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster.

Pull request checklist

  • All 49 tests pass (colcon test-result --verbose shows 0 failures)
  • For new features: tests added in fusioncore_core/tests/
  • For hardware configs: YAML includes a comment with platform + sensor details
  • Commit message describes why, not just what

Code style

C++17. Follow the style of the surrounding code: no reformatting unrelated lines. clang-format is not enforced but is appreciated.

Reporting bugs

Use the Bug Report issue template. Include the output of colcon test-result --verbose if tests are involved.

Questions

Open a Discussion rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas.

Response time: typically within 24 hours.

# Contributing to FusionCore Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help. ## The fastest way to contribute The most impactful contributions right now are **hardware configs**. If you have FusionCore running on a robot, platform, or IMU that isn't in the repo yet, open a PR adding a YAML under `fusioncore_ros/config/`. See the [hardware config section](#hardware-configs) below. ## Before you start - Check [open issues](https://github.com/manankharwar/fusioncore/issues): the bug may already be reported - Check [Discussions](https://github.com/manankharwar/fusioncore/discussions): the question may already be answered - For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code ## Development setup ```bash # Clone and build git clone https://github.com/manankharwar/fusioncore.git cd fusioncore source /opt/ros/jazzy/setup.sh # replace jazzy with humble on Ubuntu 22.04 rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y # replace jazzy with humble on Ubuntu 22.04 colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON # Run all tests before and after your change colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros colcon test-result --verbose ``` All 49 tests must pass. CI will catch it if they don't. ## Hardware configs A hardware config is a YAML file under `fusioncore_ros/config/` named after the platform (e.g. `clearpath_husky.yaml`, `ublox_f9p.yaml`). Copy `fusioncore_ros/config/fusioncore.yaml` as the starting point and adjust: - `imu.gyro_noise` / `imu.accel_noise`: pull from your IMU's datasheet - `gnss.base_noise_xy`: your GPS receiver's CEP spec - Any topic remaps specific to your platform Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster. ## Pull request checklist - [ ] All 49 tests pass (`colcon test-result --verbose` shows 0 failures) - [ ] For new features: tests added in `fusioncore_core/tests/` - [ ] For hardware configs: YAML includes a comment with platform + sensor details - [ ] Commit message describes *why*, not just *what* ## Code style C++17. Follow the style of the surrounding code: no reformatting unrelated lines. `clang-format` is not enforced but is appreciated. ## Reporting bugs Use the [Bug Report](.github/ISSUE_TEMPLATE/bug_report.md) issue template. Include the output of `colcon test-result --verbose` if tests are involved. ## Questions Open a [Discussion](https://github.com/manankharwar/fusioncore/discussions) rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas. Response time: typically within 24 hours.
No version for distro iron showing humble. Known supported distros are highlighted in the buttons above.

Repository Summary

Description
Checkout URI https://github.com/manankharwar/fusioncore.git
VCS Type git
VCS Version main
Last Updated 2026-04-29
Dev Status UNKNOWN
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

README

FusionCore

CI DOI Docs

ROS 2 sensor fusion: IMU + wheel encoders + GPS fused via UKF at 100 Hz. 22-state filter with IMU bias estimation, adaptive noise covariance, and chi-squared outlier rejection on every sensor.


Why I built this

I needed sensor fusion for a mobile robot project and reached for robot_localization like everyone does. It works well. But I wanted a filter that estimated IMU gyro and accelerometer bias as part of the state vector, adapted its noise covariance from real sensor behavior rather than config values, and rejected outliers on every sensor update: not just GPS.

So I built FusionCore. It’s a 22-state UKF that fuses IMU, wheel encoders, and GPS natively. Gyro and accelerometer bias are estimated continuously as filter states. Noise covariance adapts from the innovation sequence automatically. Every sensor update: IMU, wheel odometry, GPS: goes through a chi-squared gate before it touches the filter. GPS is handled in ECEF directly, no coordinate projection.

Trajectory overlay: all 6 sequences, SE3-aligned to RTK GPS ground truth


Benchmark

FusionCore vs robot_localization on the NCLT dataset: same IMU + wheel odometry + GPS, no manual tuning. Six sequences:

RL-EKF run with odom0_twist_rejection_threshold: 4.03 and odom1_pose_rejection_threshold: 3.72 (chi²-equivalent to FusionCore’s thresholds at 99.9% confidence).

Sequence FC ATE RMSE RL-EKF ATE RMSE RL-UKF
2012-01-08 5.6 m 13.0 m NaN divergence at t=31 s
2012-02-04 9.7 m 19.1 m NaN divergence at t=22 s
2012-03-31 4.2 m 54.3 m NaN divergence at t=18 s
2012-08-20 7.5 m 24.1 m NaN divergence
2012-11-04 28.6 m 9.6 m NaN divergence
2013-02-23 4.1 m 11.0 m NaN divergence

Install

Supports ROS 2 Jazzy (Ubuntu 24.04) and Humble (Ubuntu 22.04).

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  # or /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build && source install/setup.bash

Headless / Raspberry Pi: touch ~/ros2_ws/src/fusioncore/fusioncore_gazebo/COLCON_IGNORE before building to skip the Gazebo package.


Quick start

ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
  fusioncore_config:=/path/to/your_robot.yaml


Documentation

manankharwar.github.io/fusioncore


License

Apache 2.0.


Citation

@software{kharwar2026fusioncore,
  author    = {Kharwar, Manan},
  title     = {FusionCore: ROS 2 UKF Sensor Fusion},
  year      = {2026},
  publisher = {Zenodo},
  version   = {0.2.0},
  doi       = {10.5281/zenodo.19834991},
  url       = {https://doi.org/10.5281/zenodo.19834991}
}


File truncated at 100 lines see the full file

CONTRIBUTING

Contributing to FusionCore

Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help.

The fastest way to contribute

The most impactful contributions right now are hardware configs. If you have FusionCore running on a robot, platform, or IMU that isn’t in the repo yet, open a PR adding a YAML under fusioncore_ros/config/. See the hardware config section below.

Before you start

  • Check open issues: the bug may already be reported
  • Check Discussions: the question may already be answered
  • For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code

Development setup

# Clone and build
git clone https://github.com/manankharwar/fusioncore.git
cd fusioncore

source /opt/ros/jazzy/setup.sh  # replace jazzy with humble on Ubuntu 22.04
rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y  # replace jazzy with humble on Ubuntu 22.04
colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON

# Run all tests before and after your change
colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros
colcon test-result --verbose

All 49 tests must pass. CI will catch it if they don’t.

Hardware configs

A hardware config is a YAML file under fusioncore_ros/config/ named after the platform (e.g. clearpath_husky.yaml, ublox_f9p.yaml).

Copy fusioncore_ros/config/fusioncore.yaml as the starting point and adjust:

  • imu.gyro_noise / imu.accel_noise: pull from your IMU’s datasheet
  • gnss.base_noise_xy: your GPS receiver’s CEP spec
  • Any topic remaps specific to your platform

Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster.

Pull request checklist

  • All 49 tests pass (colcon test-result --verbose shows 0 failures)
  • For new features: tests added in fusioncore_core/tests/
  • For hardware configs: YAML includes a comment with platform + sensor details
  • Commit message describes why, not just what

Code style

C++17. Follow the style of the surrounding code: no reformatting unrelated lines. clang-format is not enforced but is appreciated.

Reporting bugs

Use the Bug Report issue template. Include the output of colcon test-result --verbose if tests are involved.

Questions

Open a Discussion rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas.

Response time: typically within 24 hours.

# Contributing to FusionCore Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help. ## The fastest way to contribute The most impactful contributions right now are **hardware configs**. If you have FusionCore running on a robot, platform, or IMU that isn't in the repo yet, open a PR adding a YAML under `fusioncore_ros/config/`. See the [hardware config section](#hardware-configs) below. ## Before you start - Check [open issues](https://github.com/manankharwar/fusioncore/issues): the bug may already be reported - Check [Discussions](https://github.com/manankharwar/fusioncore/discussions): the question may already be answered - For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code ## Development setup ```bash # Clone and build git clone https://github.com/manankharwar/fusioncore.git cd fusioncore source /opt/ros/jazzy/setup.sh # replace jazzy with humble on Ubuntu 22.04 rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y # replace jazzy with humble on Ubuntu 22.04 colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON # Run all tests before and after your change colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros colcon test-result --verbose ``` All 49 tests must pass. CI will catch it if they don't. ## Hardware configs A hardware config is a YAML file under `fusioncore_ros/config/` named after the platform (e.g. `clearpath_husky.yaml`, `ublox_f9p.yaml`). Copy `fusioncore_ros/config/fusioncore.yaml` as the starting point and adjust: - `imu.gyro_noise` / `imu.accel_noise`: pull from your IMU's datasheet - `gnss.base_noise_xy`: your GPS receiver's CEP spec - Any topic remaps specific to your platform Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster. ## Pull request checklist - [ ] All 49 tests pass (`colcon test-result --verbose` shows 0 failures) - [ ] For new features: tests added in `fusioncore_core/tests/` - [ ] For hardware configs: YAML includes a comment with platform + sensor details - [ ] Commit message describes *why*, not just *what* ## Code style C++17. Follow the style of the surrounding code: no reformatting unrelated lines. `clang-format` is not enforced but is appreciated. ## Reporting bugs Use the [Bug Report](.github/ISSUE_TEMPLATE/bug_report.md) issue template. Include the output of `colcon test-result --verbose` if tests are involved. ## Questions Open a [Discussion](https://github.com/manankharwar/fusioncore/discussions) rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas. Response time: typically within 24 hours.
No version for distro melodic showing humble. Known supported distros are highlighted in the buttons above.

Repository Summary

Description
Checkout URI https://github.com/manankharwar/fusioncore.git
VCS Type git
VCS Version main
Last Updated 2026-04-29
Dev Status UNKNOWN
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

README

FusionCore

CI DOI Docs

ROS 2 sensor fusion: IMU + wheel encoders + GPS fused via UKF at 100 Hz. 22-state filter with IMU bias estimation, adaptive noise covariance, and chi-squared outlier rejection on every sensor.


Why I built this

I needed sensor fusion for a mobile robot project and reached for robot_localization like everyone does. It works well. But I wanted a filter that estimated IMU gyro and accelerometer bias as part of the state vector, adapted its noise covariance from real sensor behavior rather than config values, and rejected outliers on every sensor update: not just GPS.

So I built FusionCore. It’s a 22-state UKF that fuses IMU, wheel encoders, and GPS natively. Gyro and accelerometer bias are estimated continuously as filter states. Noise covariance adapts from the innovation sequence automatically. Every sensor update: IMU, wheel odometry, GPS: goes through a chi-squared gate before it touches the filter. GPS is handled in ECEF directly, no coordinate projection.

Trajectory overlay: all 6 sequences, SE3-aligned to RTK GPS ground truth


Benchmark

FusionCore vs robot_localization on the NCLT dataset: same IMU + wheel odometry + GPS, no manual tuning. Six sequences:

RL-EKF run with odom0_twist_rejection_threshold: 4.03 and odom1_pose_rejection_threshold: 3.72 (chi²-equivalent to FusionCore’s thresholds at 99.9% confidence).

Sequence FC ATE RMSE RL-EKF ATE RMSE RL-UKF
2012-01-08 5.6 m 13.0 m NaN divergence at t=31 s
2012-02-04 9.7 m 19.1 m NaN divergence at t=22 s
2012-03-31 4.2 m 54.3 m NaN divergence at t=18 s
2012-08-20 7.5 m 24.1 m NaN divergence
2012-11-04 28.6 m 9.6 m NaN divergence
2013-02-23 4.1 m 11.0 m NaN divergence

Install

Supports ROS 2 Jazzy (Ubuntu 24.04) and Humble (Ubuntu 22.04).

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  # or /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build && source install/setup.bash

Headless / Raspberry Pi: touch ~/ros2_ws/src/fusioncore/fusioncore_gazebo/COLCON_IGNORE before building to skip the Gazebo package.


Quick start

ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
  fusioncore_config:=/path/to/your_robot.yaml


Documentation

manankharwar.github.io/fusioncore


License

Apache 2.0.


Citation

@software{kharwar2026fusioncore,
  author    = {Kharwar, Manan},
  title     = {FusionCore: ROS 2 UKF Sensor Fusion},
  year      = {2026},
  publisher = {Zenodo},
  version   = {0.2.0},
  doi       = {10.5281/zenodo.19834991},
  url       = {https://doi.org/10.5281/zenodo.19834991}
}


File truncated at 100 lines see the full file

CONTRIBUTING

Contributing to FusionCore

Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help.

The fastest way to contribute

The most impactful contributions right now are hardware configs. If you have FusionCore running on a robot, platform, or IMU that isn’t in the repo yet, open a PR adding a YAML under fusioncore_ros/config/. See the hardware config section below.

Before you start

  • Check open issues: the bug may already be reported
  • Check Discussions: the question may already be answered
  • For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code

Development setup

# Clone and build
git clone https://github.com/manankharwar/fusioncore.git
cd fusioncore

source /opt/ros/jazzy/setup.sh  # replace jazzy with humble on Ubuntu 22.04
rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y  # replace jazzy with humble on Ubuntu 22.04
colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON

# Run all tests before and after your change
colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros
colcon test-result --verbose

All 49 tests must pass. CI will catch it if they don’t.

Hardware configs

A hardware config is a YAML file under fusioncore_ros/config/ named after the platform (e.g. clearpath_husky.yaml, ublox_f9p.yaml).

Copy fusioncore_ros/config/fusioncore.yaml as the starting point and adjust:

  • imu.gyro_noise / imu.accel_noise: pull from your IMU’s datasheet
  • gnss.base_noise_xy: your GPS receiver’s CEP spec
  • Any topic remaps specific to your platform

Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster.

Pull request checklist

  • All 49 tests pass (colcon test-result --verbose shows 0 failures)
  • For new features: tests added in fusioncore_core/tests/
  • For hardware configs: YAML includes a comment with platform + sensor details
  • Commit message describes why, not just what

Code style

C++17. Follow the style of the surrounding code: no reformatting unrelated lines. clang-format is not enforced but is appreciated.

Reporting bugs

Use the Bug Report issue template. Include the output of colcon test-result --verbose if tests are involved.

Questions

Open a Discussion rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas.

Response time: typically within 24 hours.

# Contributing to FusionCore Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help. ## The fastest way to contribute The most impactful contributions right now are **hardware configs**. If you have FusionCore running on a robot, platform, or IMU that isn't in the repo yet, open a PR adding a YAML under `fusioncore_ros/config/`. See the [hardware config section](#hardware-configs) below. ## Before you start - Check [open issues](https://github.com/manankharwar/fusioncore/issues): the bug may already be reported - Check [Discussions](https://github.com/manankharwar/fusioncore/discussions): the question may already be answered - For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code ## Development setup ```bash # Clone and build git clone https://github.com/manankharwar/fusioncore.git cd fusioncore source /opt/ros/jazzy/setup.sh # replace jazzy with humble on Ubuntu 22.04 rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y # replace jazzy with humble on Ubuntu 22.04 colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON # Run all tests before and after your change colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros colcon test-result --verbose ``` All 49 tests must pass. CI will catch it if they don't. ## Hardware configs A hardware config is a YAML file under `fusioncore_ros/config/` named after the platform (e.g. `clearpath_husky.yaml`, `ublox_f9p.yaml`). Copy `fusioncore_ros/config/fusioncore.yaml` as the starting point and adjust: - `imu.gyro_noise` / `imu.accel_noise`: pull from your IMU's datasheet - `gnss.base_noise_xy`: your GPS receiver's CEP spec - Any topic remaps specific to your platform Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster. ## Pull request checklist - [ ] All 49 tests pass (`colcon test-result --verbose` shows 0 failures) - [ ] For new features: tests added in `fusioncore_core/tests/` - [ ] For hardware configs: YAML includes a comment with platform + sensor details - [ ] Commit message describes *why*, not just *what* ## Code style C++17. Follow the style of the surrounding code: no reformatting unrelated lines. `clang-format` is not enforced but is appreciated. ## Reporting bugs Use the [Bug Report](.github/ISSUE_TEMPLATE/bug_report.md) issue template. Include the output of `colcon test-result --verbose` if tests are involved. ## Questions Open a [Discussion](https://github.com/manankharwar/fusioncore/discussions) rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas. Response time: typically within 24 hours.
No version for distro noetic showing humble. Known supported distros are highlighted in the buttons above.

Repository Summary

Description
Checkout URI https://github.com/manankharwar/fusioncore.git
VCS Type git
VCS Version main
Last Updated 2026-04-29
Dev Status UNKNOWN
Released RELEASED
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

README

FusionCore

CI DOI Docs

ROS 2 sensor fusion: IMU + wheel encoders + GPS fused via UKF at 100 Hz. 22-state filter with IMU bias estimation, adaptive noise covariance, and chi-squared outlier rejection on every sensor.


Why I built this

I needed sensor fusion for a mobile robot project and reached for robot_localization like everyone does. It works well. But I wanted a filter that estimated IMU gyro and accelerometer bias as part of the state vector, adapted its noise covariance from real sensor behavior rather than config values, and rejected outliers on every sensor update: not just GPS.

So I built FusionCore. It’s a 22-state UKF that fuses IMU, wheel encoders, and GPS natively. Gyro and accelerometer bias are estimated continuously as filter states. Noise covariance adapts from the innovation sequence automatically. Every sensor update: IMU, wheel odometry, GPS: goes through a chi-squared gate before it touches the filter. GPS is handled in ECEF directly, no coordinate projection.

Trajectory overlay: all 6 sequences, SE3-aligned to RTK GPS ground truth


Benchmark

FusionCore vs robot_localization on the NCLT dataset: same IMU + wheel odometry + GPS, no manual tuning. Six sequences:

RL-EKF run with odom0_twist_rejection_threshold: 4.03 and odom1_pose_rejection_threshold: 3.72 (chi²-equivalent to FusionCore’s thresholds at 99.9% confidence).

Sequence FC ATE RMSE RL-EKF ATE RMSE RL-UKF
2012-01-08 5.6 m 13.0 m NaN divergence at t=31 s
2012-02-04 9.7 m 19.1 m NaN divergence at t=22 s
2012-03-31 4.2 m 54.3 m NaN divergence at t=18 s
2012-08-20 7.5 m 24.1 m NaN divergence
2012-11-04 28.6 m 9.6 m NaN divergence
2013-02-23 4.1 m 11.0 m NaN divergence

Install

Supports ROS 2 Jazzy (Ubuntu 24.04) and Humble (Ubuntu 22.04).

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  # or /opt/ros/humble/setup.bash
rosdep install --from-paths src --ignore-src -r -y
colcon build && source install/setup.bash

Headless / Raspberry Pi: touch ~/ros2_ws/src/fusioncore/fusioncore_gazebo/COLCON_IGNORE before building to skip the Gazebo package.


Quick start

ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
  fusioncore_config:=/path/to/your_robot.yaml


Documentation

manankharwar.github.io/fusioncore


License

Apache 2.0.


Citation

@software{kharwar2026fusioncore,
  author    = {Kharwar, Manan},
  title     = {FusionCore: ROS 2 UKF Sensor Fusion},
  year      = {2026},
  publisher = {Zenodo},
  version   = {0.2.0},
  doi       = {10.5281/zenodo.19834991},
  url       = {https://doi.org/10.5281/zenodo.19834991}
}


File truncated at 100 lines see the full file

CONTRIBUTING

Contributing to FusionCore

Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help.

The fastest way to contribute

The most impactful contributions right now are hardware configs. If you have FusionCore running on a robot, platform, or IMU that isn’t in the repo yet, open a PR adding a YAML under fusioncore_ros/config/. See the hardware config section below.

Before you start

  • Check open issues: the bug may already be reported
  • Check Discussions: the question may already be answered
  • For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code

Development setup

# Clone and build
git clone https://github.com/manankharwar/fusioncore.git
cd fusioncore

source /opt/ros/jazzy/setup.sh  # replace jazzy with humble on Ubuntu 22.04
rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y  # replace jazzy with humble on Ubuntu 22.04
colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON

# Run all tests before and after your change
colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros
colcon test-result --verbose

All 49 tests must pass. CI will catch it if they don’t.

Hardware configs

A hardware config is a YAML file under fusioncore_ros/config/ named after the platform (e.g. clearpath_husky.yaml, ublox_f9p.yaml).

Copy fusioncore_ros/config/fusioncore.yaml as the starting point and adjust:

  • imu.gyro_noise / imu.accel_noise: pull from your IMU’s datasheet
  • gnss.base_noise_xy: your GPS receiver’s CEP spec
  • Any topic remaps specific to your platform

Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster.

Pull request checklist

  • All 49 tests pass (colcon test-result --verbose shows 0 failures)
  • For new features: tests added in fusioncore_core/tests/
  • For hardware configs: YAML includes a comment with platform + sensor details
  • Commit message describes why, not just what

Code style

C++17. Follow the style of the surrounding code: no reformatting unrelated lines. clang-format is not enforced but is appreciated.

Reporting bugs

Use the Bug Report issue template. Include the output of colcon test-result --verbose if tests are involved.

Questions

Open a Discussion rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas.

Response time: typically within 24 hours.

# Contributing to FusionCore Thanks for your interest. Contributions are welcome: hardware configs, bug fixes, tests, and documentation all help. ## The fastest way to contribute The most impactful contributions right now are **hardware configs**. If you have FusionCore running on a robot, platform, or IMU that isn't in the repo yet, open a PR adding a YAML under `fusioncore_ros/config/`. See the [hardware config section](#hardware-configs) below. ## Before you start - Check [open issues](https://github.com/manankharwar/fusioncore/issues): the bug may already be reported - Check [Discussions](https://github.com/manankharwar/fusioncore/discussions): the question may already be answered - For anything bigger than a typo fix, open an issue or Discussion first so we can align before you write code ## Development setup ```bash # Clone and build git clone https://github.com/manankharwar/fusioncore.git cd fusioncore source /opt/ros/jazzy/setup.sh # replace jazzy with humble on Ubuntu 22.04 rosdep install -r --from-paths . --ignore-src --rosdistro jazzy -y # replace jazzy with humble on Ubuntu 22.04 colcon build --packages-up-to compass_msgs fusioncore_core fusioncore_ros --cmake-args -DBUILD_TESTING=ON # Run all tests before and after your change colcon test --packages-select compass_msgs fusioncore_core fusioncore_ros colcon test-result --verbose ``` All 49 tests must pass. CI will catch it if they don't. ## Hardware configs A hardware config is a YAML file under `fusioncore_ros/config/` named after the platform (e.g. `clearpath_husky.yaml`, `ublox_f9p.yaml`). Copy `fusioncore_ros/config/fusioncore.yaml` as the starting point and adjust: - `imu.gyro_noise` / `imu.accel_noise`: pull from your IMU's datasheet - `gnss.base_noise_xy`: your GPS receiver's CEP spec - Any topic remaps specific to your platform Add a comment at the top with: platform name, IMU model, GPS receiver model, and whether it was field-tested or tuned from datasheet only. Field-tested configs get merged faster. ## Pull request checklist - [ ] All 49 tests pass (`colcon test-result --verbose` shows 0 failures) - [ ] For new features: tests added in `fusioncore_core/tests/` - [ ] For hardware configs: YAML includes a comment with platform + sensor details - [ ] Commit message describes *why*, not just *what* ## Code style C++17. Follow the style of the surrounding code: no reformatting unrelated lines. `clang-format` is not enforced but is appreciated. ## Reporting bugs Use the [Bug Report](.github/ISSUE_TEMPLATE/bug_report.md) issue template. Include the output of `colcon test-result --verbose` if tests are involved. ## Questions Open a [Discussion](https://github.com/manankharwar/fusioncore/discussions) rather than an issue. Issues are for bugs and tracked work; Discussions are for questions, configs, and ideas. Response time: typically within 24 hours.