Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Kalman filter

A Kalman filter is a powerful tool for state estimation. It is a recursive filter that is able to estimate the state of a system, even in the presence of noise and uncertainty. In FRC, Kalman filters can be used for a variety of purposes, such as:

  • Estimating the robot's position and orientation.
  • Filtering noisy sensor data.
  • Fusing data from multiple sensors.

WPILib provides a LinearSystem class and a KalmanFilter class that work together.

Example: Estimating Velocity from Position

Let's say we have a motor with an encoder that measures position, but we also want to know its velocity. We can use a Kalman filter to estimate both position and velocity.

This is a conceptual example. In a real robot, you would use a plant model that matches your system (e.g., from SysId).

import wpimath.system
import wpimath.system.plant
import wpimath.kinematics
import numpy as np

# Let's model a simple system: a motor with position and velocity states.
# x = [position, velocity]'
# We can only measure position. We want to estimate both position and velocity.

# System matrices (for a 50Hz loop, dt=0.02s)
# These describe how the state changes over time.
A = np.array([[1, 0.02], [0, 1]])  # State transition matrix
B = np.array([[0], [0.02]])      # Input matrix (how input affects state)
C = np.array([[1, 0]])           # Measurement matrix (we only measure position)
D = np.array([[0]])              # Feedthrough matrix

system = wpimath.system.LinearSystem_2_1_1(A, B, C, D)

# Kalman filter
# We need to provide standard deviations for process noise and measurement noise.
# These represent how much we trust our model and our sensor, and need to be tuned.
process_noise_std_dev = 0.1
measurement_noise_std_dev = 0.01

kalman_filter = wpimath.kinematics.KalmanFilter_2_1_1(
    system,
    [process_noise_std_dev, process_noise_std_dev],  # State standard deviations
    [measurement_noise_std_dev], # Measurement standard deviations
    0.02 # dt
)

# In the robot loop:
# Get motor voltage (u) and measured position (y)
voltage = 5.0 # example input
u = np.array([voltage])
measured_position = 1.2 # example measurement
y = np.array([measured_position])

# Predict the next state based on the model and input
kalman_filter.predict(u, 0.02)

# Correct the state estimate with the new measurement
kalman_filter.correct(u, y)

# Get the estimated state (position and velocity)
estimated_position = kalman_filter.getX(0)
estimated_velocity = kalman_filter.getX(1)

For more information, see the RobotPy Kalman filter documentation: https://robotpy.readthedocs.io/en/stable/wpilib/wpilib.kinematics.KalmanFilter.html