Getting Started¶
Prerequisites¶
- ROS 2 Jazzy Jalisco (Ubuntu 24.04) or Humble Hawksbill (Ubuntu 22.04)
- A colcon workspace (
~/ros2_ws)
Install¶
FusionCore is a monorepo with these packages:
| Package | Purpose | Required? |
|---|---|---|
compass_msgs |
Custom heading message type | Yes |
fusioncore_core |
Pure C++ UKF library, no ROS | Yes |
fusioncore_ros |
ROS 2 lifecycle node | Yes |
fusioncore_gazebo |
Simulation world + demo launch | Optional |
fusioncore_ublox |
u-blox NavPVT Doppler bridge | Optional (only builds with ublox_msgs installed) |
The repo must live inside src/ for colcon to find them.
Humble users
Replace jazzy with humble in all commands below.
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 --packages-up-to fusioncore_ros
source install/setup.bash
Run colcon from the workspace root, not from inside the repo
Always run colcon build from ~/ros2_ws, not from ~/ros2_ws/src/fusioncore.
colcon discovers packages by scanning src/ from the workspace root. Running it
from inside the repo produces a nested install/ that conflicts with the workspace.
Headless machines (Raspberry Pi, servers)
--packages-up-to fusioncore_ros already skips Gazebo and the ublox bridge. To be explicit:
Run the tests¶
cd ~/ros2_ws
colcon build --packages-select fusioncore_core --cmake-args -DBUILD_TESTING=ON
colcon test --packages-select fusioncore_core
colcon test-result --verbose
Expected: 64 tests, 0 errors, 0 failures, 0 skipped
First launch¶
FusionCore is a lifecycle node. It needs to be configured (load params, validate TF) and then activated (start processing) before it does anything.
The provided launch files handle this automatically:
# With Nav2
ros2 launch fusioncore_ros fusioncore_nav2.launch.py \
fusioncore_config:=/path/to/your_robot.yaml
# Without Nav2
ros2 launch fusioncore_ros fusioncore.launch.py \
fusioncore_config:=/path/to/your_robot.yaml
Or manually in a second terminal:
Verify it's publishing:
WSL2
If ros2 lifecycle set returns "Node not found", use the launch file's auto-configure instead. WSL2 DDS discovery latency can prevent manual lifecycle commands from finding the node. The launch file handles this with timed events.
Verify it works (single command)¶
Starts FusionCore with fake sensors, runs through configure → activate, checks all outputs. Takes about 15 seconds. Prints [PASS] / [FAIL] for each check.
Expected output:
FusionCore Quick Test
=====================
[....] Sourcing ROS environment...
[PASS] ROS environment sourced
[....] Starting TF publishers...
[....] Launching FusionCore...
[PASS] Lifecycle: configure → activate
[....] Publishing fake IMU at 100 Hz (stationary, gravity pointing up)...
[....] Publishing fake wheel odometry at 50 Hz (stationary)...
[....] Waiting 6 s for filter to initialize...
Checks:
-------
[PASS] /fusion/odom publishing (main output)
[PASS] /fusion/pose publishing
[PASS] /diagnostics publishing
[PASS] /fusioncore/reset service responds
All checks passed. FusionCore is working correctly.
If a check fails, the script prints the exact diagnostic command to run next.
Docker
The script also runs inside the container:
Manual verification (if you want to inspect each output)¶
If you want to observe the filter behavior directly rather than run the automated check:
# Terminal 1: launch
source /opt/ros/jazzy/setup.bash && source ~/ros2_ws/install/setup.bash
ros2 launch fusioncore_ros fusioncore.launch.py
# Terminal 2: TF + lifecycle
source /opt/ros/jazzy/setup.bash && source ~/ros2_ws/install/setup.bash
ros2 run tf2_ros static_transform_publisher --frame-id base_link --child-frame-id imu_link &
ros2 run tf2_ros static_transform_publisher --frame-id odom --child-frame-id base_link &
sleep 1 && ros2 lifecycle set /fusioncore configure
sleep 1 && ros2 lifecycle set /fusioncore activate
# Terminal 3: diagnostics
ros2 topic echo /diagnostics --once
ros2 topic hz /fusion/odom
ros2 topic echo /fusion/odom --field twist.twist.linear
You should see /fusion/odom, /fusion/pose, and /fusioncore/reset in the topic/service list.