这个例子展示了如何生成一个MATLAB®卡尔曼滤波函数的C代码,卡尔曼滤波
,它根据过去的噪声测量值估计运动对象的位置。它还显示了如何为该MATLAB代码生成MEX函数,以提高算法在MATLAB中的执行速度。
这个示例没有先决条件。
卡尔曼滤波
函数的卡尔曼滤波
函数根据移动对象的过去值预测其位置。它使用一个卡尔曼滤波器估计器,一个递归自适应滤波器,从一系列噪声测量估计动态系统的状态。卡尔曼滤波在信号和图像处理、控制设计和计算金融等领域有着广泛的应用。
卡尔曼估计器通过计算和更新卡尔曼状态向量来计算位置向量。状态向量定义为一个6乘1的列向量,其中包括二维笛卡尔空间中的位置(x和y)、速度(Vx Vy)和加速度(Ax和Ay)测量值。基于经典运动定律:
捕捉这些规律的迭代公式反映在Kalman状态转移矩阵“A”中。请注意,通过编写大约10行MATLAB代码,您可以根据许多自适应滤波教科书中的理论数学公式实现Kalman估计器。
类型kalmanfilter.m
% Copyright 2010 The MathWorks, Inc. function y = kalmanfilter(z) %#codegen dt=1;初始化状态转移矩阵A=[1 0 dt 0 0 0;…% [x] 0 1 0 dt 0 0;…% [y] 0 0 1 0 dt 0;…% [Vx] 0 0 0 1 0 dt;…% [Vy] 0 0 0 0 1 0;…% [Ax] 0 0 0 0 1;% [Ay] H = [1 0 0 0 0 0;0 1 0 0 0 0];%初始化测量矩阵Q =眼(6); R = 1000 * eye(2); persistent x_est p_est % Initial state conditions if isempty(x_est) x_est = zeros(6, 1); % x_est=[x,y,Vx,Vy,Ax,Ay]' p_est = zeros(6, 6); end % Predicted state and covariance x_prd = A * x_est; p_prd = A * p_est * A' + Q; % Estimation S = H * p_prd' * H' + R; B = H * p_prd'; klm_gain = (S \ B)'; % Estimated state and covariance x_est = x_prd + klm_gain * (z - H * x_prd); p_est = p_prd - klm_gain * H * p_prd; % Compute the estimated measurements y = H * x_est; end % of the function
要跟踪的对象的位置被记录为笛卡尔空间中的x和y坐标,保存在MAT文件中位置_data.mat
.下面的代码加载MAT文件并绘制位置的轨迹。测试数据包括两个位置上的突然移动或不连续,用来检查卡尔曼滤波器能否快速地重新调整和跟踪目标。
负载位置_data.mat持有;网格;
当前绘图保持不变
为idx=1:numPts z=位置(:,idx);绘图(z(1),z(2),“bx”);轴([-11-11]);结束头衔(“具有2个突然不连续的卡尔曼滤波的测试向量”);包含(“轴”);伊莱贝尔(“轴”);持有;
目前公布的情节
ObjTrack
函数的ObjTrack.m
函数调用Kalman filter算法,以蓝色绘制对象的轨迹,以绿色绘制Kalman filter估计的位置。最初,您会发现估计的位置需要很短的时间才能收敛到对象的实际位置。然后,位置会发生三次突然移动。每次Kalman filter重新调整并在几次迭代后跟踪对象。
类型ObjTrack
% Copyright 2010 The MathWorks, Inc. function ObjTrack(position) %#codegen %%处理并绘制300个样品图;保持;网格;% Prepare plot window % Main loop for idx = 1: numPts z = position(:,idx);%获取输入数据y = kalmanfilter(z);%调用卡尔曼滤波估计位置plot_trajectory(z,y);%绘制结果结束保持;函数的结束%
ObjTrack(位置)
当前绘图保持不变
目前公布的情节
的codegen
指挥-配置:lib
选项生成打包为独立C库的C代码。
因为C使用静态类型,codegen
必须在编译时确定MATLAB文件中所有变量的属性。这里,这个arg游戏
命令行选项提供了一个示例输入,以便codegen
可以根据输入类型推断新的类型。
的-报告
选项生成编译报告,其中包含编译结果的摘要和到所生成文件的链接。编译MATLAB代码后,codegen
提供到此报表的超链接。
z =位置(:1);codegen-配置:lib-报告- ckalmanfilter.marg游戏{z}
代码生成成功:要查看报告,打开('codegen/lib/kalmanfilter/html/report.mldatx')
生成的C代码位于codegen / lib / kalmanfilter /
文件夹中。的文件是:
dircodegen / lib / kalmanfilter /
.kalmanfilter.h..kalmanfilter\u data.c.gitignore kalmanfilter\u data.h\u clang格式kalmanfilter\u initialize.c buildInfo.mat kalmanfilter\u initialize.h codeInfo.mat kalmanfilter\u rtw.mk codescriptor.dmr kalmanfilter\u terminate.c compileInfo.mat kalmanfilter\u terminate.h defines.txt kalmanfilter类型.h示例rtw项目html RTYpes.h接口卡尔曼过滤器
kalmanfilter.c
函数类型codegen/lib/kalmanfilter/kalmanfilter.c
/**文件:kalmanfilter.c**MATLAB编码器版本:5.3*c/c++源代码生成日期:2021年9月1日08:20:37*/*包括文件*/#包括“kalmanfilter.h”#包括“kalmanfilter_data.h”#包括“kalmanfilter_initialize.h”#包括
您可以加速的执行速度卡尔曼滤波
函数,该函数使用codegen
命令从MATLAB代码生成MEX函数。
kalman_loop
处理大型数据集的函数首先,在MATLAB中使用大量的数据样本运行卡尔曼算法。的kalman_loop
函数运行卡尔曼滤波
函数循环。循环迭代的次数等于函数输入的第二个维度。
类型kalman_loop
%版权所有2010 MathWorks,Inc.函数y=kalman_loop(z)%Call kalman estimator in The loop for large data set testing%#codegen[DIM,LEN]=size(z);y=zeros(DIM,LEN);%n=1的初始化输出:LEN%回路中的输出y(:,n)=kalman滤波器(z(:,n));结束;
现在用MATLAB算法计时。使用randn
命令生成随机数并创建输入矩阵位置
由100,000个(2x1)位置向量样本组成。从当前文件夹中删除所有MEX文件。使用MATLAB秒表定时器(抽搐
和toc
命令)来测量在运行kalman_loop
函数。
清晰的墨西哥人删除([“*”。mexext])位置=兰登(2100000);tic,kalman_环(位置);a=总有机碳;
接下来,使用命令生成一个MEX函数codegen
后跟MATLAB函数的名称kalman_loop
.的codegen
命令生成一个被调用的MEX函数kalman_loop_mex
.然后可以比较这个MEX函数与原始MATLAB算法的执行速度。
codegenarg游戏{position}kalman_loop.m
代码生成成功。
哪一个kalman_loop_mex
/tmp/Bdoc21b_1757077_258750/tpe931db2c/coder-ex53054096/kalman_loop_mex.mexa64
现在,给MEX函数计时kalman_loop_mex
.使用相同的信号位置
如前所述的输入,以确保执行速度的公平比较。
tic,kalman\u loop\u mex(位置);b=toc;
注意使用生成的MEX函数时的速度执行差异。
显示(sprintf)('使用在基线MATLAB函数上生成的MEX,加速比为%.1f倍。'a / b));
在基线MATLAB函数上使用生成的MEX可以得到17.2倍的加速。