MPU9250 九轴 EKF扩展卡尔曼滤波数据融合算法 短时间内我们相信陀螺仪,长时间内我们可以相信加速度计。 使用扩展卡尔曼滤波(EKF)将数据融合。 选取状态量为四元数和三轴陀螺仪的漂移 控制量为陀螺仪采样值 观测量为 三轴加速度计和磁偏角

在传感器应用的领域里,MPU9250九轴传感器凭借其强大的功能脱颖而出。然而,要从这些传感器中获取精准可靠的数据,数据融合技术至关重要,其中扩展卡尔曼滤波(EKF)算法便是一把利器。

为何选择这样的状态量、控制量和观测量?

我们选取状态量为四元数和三轴陀螺仪的漂移。四元数用于描述物体的姿态,相比欧拉角,它能有效避免万向节锁问题,为姿态解算提供更稳定准确的基础。而陀螺仪的漂移是不可避免的,将其纳入状态量,有助于在算法运行过程中实时估计并补偿漂移,提升数据精度。

控制量选择陀螺仪采样值,这是因为陀螺仪能快速响应物体的角速度变化,在短时间内提供较为准确的姿态变化信息。我们相信短时间内陀螺仪数据的可靠性,所以用它作为控制量来驱动状态的更新。

观测量选取三轴加速度计和磁偏角。加速度计在长时间尺度上能稳定地反映重力方向,从而辅助确定姿态。磁偏角则提供了地磁方向信息,进一步校准姿态。长时间来看,加速度计和磁偏角的数据更为可靠,以此作为观测量对状态进行修正。

EKF算法在MPU9250中的实现

下面我们来看一些简化的代码示例(以Python为例),来直观感受EKF在MPU9250数据融合中的应用。

首先,初始化一些必要的参数:

import numpy as np

# 状态量初始化,四元数 q = [q0, q1, q2, q3],陀螺仪漂移 bias = [bx, by, bz]
x = np.array([1, 0, 0, 0, 0, 0, 0], dtype=float)  
# 状态协方差矩阵初始化
P = np.eye(7)  
# 过程噪声协方差矩阵
Q = np.diag([0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001])  
# 观测噪声协方差矩阵
R = np.diag([0.1, 0.1, 0.1, 0.1])  

在上述代码中,我们初始化了状态量x,它包含了四元数和陀螺仪漂移。状态协方差矩阵P用于表示我们对状态估计的不确定程度,初始化为单位矩阵,表示初始时对每个状态变量的不确定度相同。Q矩阵是过程噪声协方差矩阵,反映了系统本身的噪声特性,这里对不同的状态变量设置了不同的噪声强度。R矩阵是观测噪声协方差矩阵,体现了观测数据的噪声水平。

MPU9250 九轴 EKF扩展卡尔曼滤波数据融合算法 短时间内我们相信陀螺仪,长时间内我们可以相信加速度计。 使用扩展卡尔曼滤波(EKF)将数据融合。 选取状态量为四元数和三轴陀螺仪的漂移 控制量为陀螺仪采样值 观测量为 三轴加速度计和磁偏角

接下来是预测步骤:

def predict(x, P, gyro, dt):
    q0, q1, q2, q3, bx, by, bz = x
    w_x, w_y, w_z = gyro

    # 四元数更新方程
    q_dot = 0.5 * np.array([-q1 * (w_x - bx) - q2 * (w_y - by) - q3 * (w_z - bz),
                            q0 * (w_x - bx) + q2 * (w_z - bz) - q3 * (w_y - by),
                            q0 * (w_y - by) - q1 * (w_z - bz) + q3 * (w_x - bx),
                            q0 * (w_z - bz) + q1 * (w_y - by) - q2 * (w_x - bx)])
    q = q + q_dot * dt

    # 状态转移矩阵 F
    F = np.array([[1, -dt * (w_x - bx), -dt * (w_y - by), -dt * (w_z - bz), -dt * q1, -dt * q2, -dt * q3],
                  [dt * (w_x - bx), 1, dt * (w_z - bz), -dt * (w_y - by), dt * q0, -dt * q3, dt * q2],
                  [dt * (w_y - by), -dt * (w_z - bz), 1, dt * (w_x - bx), dt * q3, dt * q0, -dt * q1],
                  [dt * (w_z - bz), dt * (w_y - by), -dt * (w_x - bx), 1, -dt * q2, dt * q1, dt * q0],
                  [0, 0, 0, 0, 1, 0, 0],
                  [0, 0, 0, 0, 0, 1, 0],
                  [0, 0, 0, 0, 0, 0, 1]])

    x = np.array([q[0], q[1], q[2], q[3], bx, by, bz])
    P = F @ P @ F.T + Q

    return x, P

在预测函数中,我们根据陀螺仪测量值gyro和时间间隔dt来更新四元数。这里用到了四元数的微分方程来近似更新四元数。同时构建了状态转移矩阵F,它描述了状态如何随时间变化。最后通过状态转移矩阵和过程噪声协方差矩阵来更新状态协方差矩阵P

然后是更新步骤:

def update(x, P, acc, mag):
    q0, q1, q2, q3, bx, by, bz = x

    # 计算观测预测值
    h = np.array([2 * (q1 * q3 - q0 * q2),
                  2 * (q0 * q1 + q2 * q3),
                  q0 ** 2 - q1 ** 2 - q2 ** 2 + q3 ** 2,
                  # 这里假设磁偏角相关计算,实际需根据具体模型
                  0])  

    # 观测雅可比矩阵 H
    H = np.array([[-2 * q2, 2 * q3, -2 * q0, 2 * q1, 0, 0, 0],
                  [2 * q1, 2 * q0, 2 * q3, 2 * q2, 0, 0, 0],
                  [-2 * q1, -2 * q2, 2 * q3, -2 * q0, 0, 0, 0],
                  [0, 0, 0, 0, 0, 0, 0]])  

    y = np.array(acc + mag) - h
    S = H @ P @ H.T + R
    K = P @ H.T @ np.linalg.inv(S)

    x = x + K @ y
    P = (np.eye(7) - K @ H) @ P

    return x, P

在更新函数里,我们首先根据当前状态计算观测预测值h,这里以加速度计和磁偏角相关计算为例(实际中磁偏角部分需根据具体模型完善)。然后构建观测雅可比矩阵H,它描述了状态变化对观测值的影响。通过实际观测值与预测值的差值y,结合观测噪声协方差矩阵R计算卡尔曼增益K。最后利用卡尔曼增益来更新状态量x和状态协方差矩阵P

通过不断重复预测和更新步骤,EKF算法就能持续融合MPU9250九轴传感器的数据,为我们提供更准确可靠的姿态信息。

MPU9250九轴传感器搭配EKF扩展卡尔曼滤波数据融合算法,在诸如无人机姿态控制、虚拟现实设备追踪等众多领域都有着广泛的应用前景。深入理解并灵活运用这一技术,能为我们打开更多创新应用的大门。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐