IMU Signal Processing
Master inertial measurement techniques and filtering
Tutorial Overview
🎯 Learning Objectives
By the end of this tutorial, you will:
✅ Understand IMU sensor principles (accelerometer + gyroscope)
✅ Identify and characterize sensor noise
✅ Implement complementary filters for sensor fusion
✅ Calculate orientation from IMU data
✅ Deal with gyroscope drift and accelerometer noise
✅ Apply low-pass and high-pass filters
✅ Calibrate IMU sensors
✅ Compare filtering techniques
⏱️ Time Required
Reading & Theory: 25 minutes
Data Collection: 15 minutes
Filtering Implementation: 40 minutes
Calibration: 20 minutes
Total: ~100 minutes
📚 Prerequisites
✅ Completed Sensor Data Visualization
✅ Can visualize and record IMU data
✅ Basic understanding of signals (helpful, not required)
✅ Python basics (for filtering scripts)
✅ Can record and analyze rosbags
🛠️ What You'll Need
✅ Beetlebot (powered, IMU active)
✅ Laptop with ROS2 + Python
✅ Wireless controller
✅ Level surface for calibration
✅ Protractor or phone compass (optional)
✅ Calculator or Python for math
Part 1: IMU Fundamentals
What's Inside an IMU?
Your LSM6DSRTR has two sensors:
1. Accelerometer (3-axis)
Measures: Linear acceleration (m/s²)
Axes: X (forward/back), Y (left/right), Z (up/down)
Range: ±2g (±19.6 m/s²)
Measures: Gravity + motion acceleration
2. Gyroscope (3-axis)
Measures: Angular velocity (rad/s or °/s)
Axes: Roll (X), Pitch (Y), Yaw (Z)
Range: ±250 dps (degrees per second)
Measures: Rotation rate
Understanding Accelerometer
Key insight: Accelerometer measures ALL accelerations, including gravity!
Stationary robot:
Why Z = 9.81?
Gravity pulls down at 9.81 m/s²
Accelerometer measures upward force from ground
Sitting still = constant upward acceleration from ground support
Moving forward:
Tilted robot (nose up 30°):
Key point: Accelerometer can't distinguish:
Gravity vs. linear acceleration
Tilt vs. acceleration
This is why we need gyroscope!
Understanding Gyroscope
Measures rotation rate, NOT angle!
Stationary robot:
Turning left (yaw):
To get angle, must integrate:
Problem: Integration accumulates error!
Small measurement error → grows over time
Called "gyro drift"
After 1 minute, angle could be off by 10-20°
The Complementary Problem
Accelerometer:
✅ Good long-term (doesn't drift)
❌ Noisy short-term (vibrations, motion)
✅ Measures gravity (knows "down")
❌ Can't distinguish tilt from acceleration
Gyroscope:
✅ Good short-term (smooth, fast)
❌ Drifts long-term (integration error)
✅ Not affected by linear motion
❌ Doesn't know absolute orientation
Solution: Combine both! (Complementary filter)
Part 2: Collecting IMU Data
Record Raw IMU Data
Collect baseline data:
Collect motion data:
Exercise 5.1: Noise Characterization
Task: Measure IMU noise levels
Analysis script:
Script content:
Run analyzer:
While robot sits still, observe output every 10 seconds:
What you learned:
Standard deviation = noise level
Typical: 0.04-0.05 m/s² accel noise, 0.003-0.004 rad/s gyro noise
Z-axis accel reads ~9.81 (gravity)
Gyro has small bias (mean ≠ 0)
Part 3: Low-Pass Filtering
What is Low-Pass Filtering?
Goal: Remove high-frequency noise, keep low-frequency signal
Analogy: Smoothing bumpy data
Sudden spikes → smoothed out
Slow trends → preserved
Simple method: Moving average
Implement Moving Average Filter
Create filter node:
Script:
Run filter:
Compare raw vs filtered:
Exercise 5.2: Filter Tuning
Task: Find optimal window size
Test different window sizes:
For each window size:
Run filter
Drive robot in circle
Plot raw vs filtered
Note:
Noise reduction (smoother?)
Response delay (laggy?)
Optimal window: Balance smoothness vs. delay
Too small: Still noisy
Too large: Delayed response (bad for control)
Typical: 5-10 samples works well
Part 4: Complementary Filter
Theory
Combine accelerometer + gyroscope for orientation:
Accelerometer angle (from gravity):
Gyroscope angle (from integration):
Complementary filter (combine both):
Why this works:
Gyro dominates short-term (smooth, fast)
Accel corrects long-term (prevents drift)
Alpha balances trust between sensors
Implement Complementary Filter
Create orientation estimator:
Script:
Run estimator:
Test:
Exercise 5.3: Complementary Filter Tuning
Task: Find optimal alpha value
Test alpha values:
For each alpha:
Let robot sit still for 2 minutes
Note final roll/pitch values
Did it drift from 0°?
Then test dynamic response:
Tilt robot back and forth
Does angle follow smoothly?
Any lag?
Optimal alpha: Usually 0.96-0.98
Higher = smoother, but drifts more
Lower = noisier, but less drift
Part 5: Gyro Drift Compensation
Understanding Drift
Problem: Gyro has small bias
Even sitting still, reads small non-zero value
Integration accumulates this error
After minutes, angle is way off
Example:
Calibration Solution
Idea: Measure bias when stationary, subtract it
Calibration procedure:
Script:
Run calibration:
Output:
Update orientation estimator:
Exercise 5.4: Measure Drift Improvement
Task: Compare drift with vs without bias compensation
Test 1: No compensation
Test 2: With compensation
Expected results:
Without: 10-20° drift after 5 minutes
With: <2° drift after 5 minutes
Part 6: Accelerometer Calibration
Why Calibrate Accelerometer?
Issues:
Sensor not perfectly aligned with robot frame
Slight bias (reads 0.1 instead of 0.0)
Scale factors (reads 9.7 instead of 9.81)
Calibration finds:
Zero offsets (bias)
Scale factors
Axis alignment
Simple Calibration Method
Six-position method:
Script:
Run calibration:
Note: This requires physically manipulating robot (may be difficult with wired robot). Optional advanced exercise!
Part 7: Advanced Filtering (Optional)
Kalman Filter Concept
Better than complementary filter:
Dynamically adjusts trust based on noise
Provides uncertainty estimates (covariance)
Optimal for Gaussian noise
Implementation: Complex (beyond this tutorial) Library: robot_localization package (already used for /odometry/filtered)
Key idea:
Prediction step (gyro)
Update step (accel)
Gain adjustment based on noise
Madgwick Filter
Popular alternative:
Quaternion-based (no gimbal lock)
Computationally efficient
Widely used in drones/quadcopters
Python library:
Example usage:
Part 8: Practical Applications
Use Case 1: Tilt Detection
Detect if robot is stuck on obstacle:
Use Case 2: Vibration Monitoring
Detect mechanical issues:
Use Case 3: Motion Classification
Detect driving patterns:
Part 9: Troubleshooting
IMU Readings Look Wrong
Check coordinate frame:
/imu/data_rawmay be in sensor frame/imu/datashould be in base_link frameUse
tf2_echoto check transform
Filter Output Drifts
Possible causes:
Gyro bias not calibrated
Alpha value too high (too much gyro weight)
Robot actually tilting (check level surface)
Temperature drift (warm up motors, re-calibrate)
Accelerometer Jumpy
Normal! Accelerometers are noisy short-term
Increase filter window size
Use complementary filter (gyro smooths it)
Check for motor vibrations
General Debugging
Most IMU issues fixed by:
⚡ Power cycle robot
Re-run calibration
Check IMU topic rate (should be 100 Hz)
Verify sensor not physically damaged
Part 10: Knowledge Check
Concept Quiz
Why does accelerometer read 9.81 m/s² when stationary?
What's the main problem with gyroscope for long-term orientation?
What does alpha=0.98 mean in complementary filter?
Why calibrate gyroscope?
Can IMU measure absolute orientation (North/South/East/West)?
Hands-On Challenge
Task: Implement complete IMU processing pipeline
Requirements:
Gyro calibration (measure bias)
Moving average low-pass filter (window=7)
Complementary filter (alpha=0.97)
Publish filtered orientation on new topic
Test for 5 minutes, measure final drift
Bonus:
Add tilt warning (>15°)
Add vibration detection (>2 m/s²)
Plot raw vs filtered on same graph
Part 11: What You've Learned
✅ Congratulations!
You now understand:
IMU Fundamentals:
✅ Accelerometer measures gravity + motion
✅ Gyroscope measures rotation rate (not angle)
✅ Each sensor has strengths and weaknesses
✅ Sensor fusion combines best of both
Signal Processing:
✅ Noise characterization (mean, std dev)
✅ Low-pass filtering (moving average)
✅ Complementary filtering (sensor fusion)
✅ Integration and differentiation
Calibration:
✅ Gyro bias measurement
✅ Drift compensation
✅ Accelerometer calibration (optional)
Practical Skills:
✅ Implementing filters in Python/ROS2
✅ Tuning filter parameters
✅ Analyzing sensor data
✅ Troubleshooting IMU issues
Next Steps
🎯 You're Now Ready For:
Immediate Next: → Teleoperation Control - Drive robot with sensor feedback
Advanced Sensor Topics: → Sensor Fusion with EKF - Full state estimation → SLAM Mapping - Use IMU to aid mapping
Robotics Applications:
Balance control (tilt compensation)
Bump detection (sudden acceleration)
Activity recognition (walking/running/falling patterns)
Quick Reference
Essential IMU Commands
Key Equations
Completed IMU Signal Processing! 🎉
→ Continue to Teleoperation Control → Or return to Tutorial Index
Last Updated: January 2026 Tutorial 5 of 11 - Intermediate Level Estimated completion time: 100 minutes
Last updated