This repository contains a full-stack ROS 2 implementation of a localized autonomy system for a auto_drive_ekf_robot.
The project demonstrates multi-sensor fusion using a custom-built Extended Kalman Filter (EKF) that combines a kinematic motion model with IMU and Visual Odometry (VO) data.
The system is designed to decouple hardware interfacing from autonomous estimation.
-
Command Path
Test Node → /cmd_vel → Velocity Converter → Gazebo -
Estimation Path
/cmd_vel → Prediction Node → EKF Node -
Correction Path
IMU + Visual Odometry → Measurement Node → EKF Node
Implements dead reckoning by integrating commanded velocities over time to estimate the robot pose:
State: [ x , y , θ ]
xₜ₊₁ = xₜ + v · cos(θₜ) · dt
yₜ₊₁ = yₜ + v · sin(θₜ) · dt
θₜ₊₁ = θₜ + ω · dt
Key Notes
- Nonlinear kinematics
- Parameters (
wheel_radius,wheel_separation) match the URDF - Drift accumulates without sensor correction
Pre-processes sensor data before EKF correction.
Sensor Sources
- IMU (orientation, angular velocity)
- ZED Visual Odometry (pose)
Design Choices
-
2D Constraint
z = 0
roll = 0
pitch = 0 -
Asynchronous synchronization
Measurement is published only when both IMU and VO are available.
Resulting measurement vector: Z = [ x , y , θ ]
Implements the standard predict → correct EKF pipeline.
Linearization is required due to nonlinear motion.
State Jacobian (F)
F =
| 1 0 -v·sin(θ)·dt |
| 0 1 v·cos(θ)·dt |
| 0 0 1 |
Covariance Propagation
P = F · P · Fᵀ + Q
P: state covarianceQ: process noise (model uncertainty)
- Innovation: difference between predicted state and measurement
- Kalman Gain
Kbalances sensor trust vs model trust
Angle Normalization
To avoid discontinuities at ±π: θ = atan2( sin(θ), cos(θ) )
Where:
r= wheel radiusL= wheel separation- Output unit = rad/s (Gazebo-compatible)
The robot follows a 2.0 m × 2.0 m square trajectory.
| Path Type | Topic | Description |
|---|---|---|
| Ground Truth | /ground_truth/odom |
Gazebo physics reference |
| Motion Model | /odom_pred |
Pure dead reckoning |
| Measurement | /measurement_model |
Raw IMU + VO data |
| EKF Output | /ekf_odom |
Final fused estimate |
The EKF trajectory should remain closest to ground truth.
- Clone and Build:
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/ampardra/auto_drive_ekf_robot.git
cd ..
colcon build
source install/setup.bash
or zsh based on your shell.
- Launch Simulation:
ros2 launch robot_description gazebo.launch.py
- Launch Localization Suite:
ros2 launch robot_local_localization local_localization.launch.py
- Visualize:
Open RViz and add Path displays for /path/ekf, /path/ground_truth, and /path/prediction.


