首页 > 代码库 > 二维粒子滤波纯代码

二维粒子滤波纯代码

% 参数设置
N = 100;   %粒子总数
Q = 5;      %过程噪声
R = 5;      %测量噪声
T = 20;     %测量时间
theta = pi/T;       %旋转角度
distance = 80/T;    %每次走的距离
WorldSize = 100;    %世界大小
X = zeros(2, T);    %存储系统状态
Z = zeros(2, T);    %存储系统的观测状态
P = zeros(2, N);    %建立粒子群
PCenter = zeros(2, T);  %所有粒子的中心位置
w = zeros(N, 1);         %每个粒子的权重
err = zeros(1,T);     %误差
X(:, 1) = [50; 20];     %初始系统状态
%wgn(m,n,p)产生一个m行n列的高斯白噪声的矩阵,p以dBW为单位指定输出噪声的强度。
Z(:, 1) = [50; 20] + wgn(2, 1, 10*log10(R));    %初始系统的观测状态

%初始化粒子群
for i = 1 : N
    P(:, i) = [WorldSize*rand; WorldSize*rand];%在worldSize区域内随机生成N个粒子
    dist = norm(P(:, i)-Z(:, 1));     %与测量位置相差的距离,用于估算该粒子的权重
    %由于上面已经随机生成了N个粒子,现在将其与真实的测量值z进行比较,越接近则权重越大,或者说差值越小权重越大
    %这里的权重计算是关于p(z/x)的分布,即观测方程的分布,假设观测噪声满足高斯分布,那么w(i)=p(z/x)
    w(i) = (1 / sqrt(R) / sqrt(2 * pi)) * exp(-(dist)^2 / 2 / R);   %求权重
end
PCenter(:, 1) = sum(P, 2) / N;      %所有粒子的几何中心位置

%%
err(1) = norm(X(:, 1) - PCenter(:, 1));     %粒子几何中心与系统真实状态的误差
figure(1);
%利用set(gca,propertyname,propertyvalue......)命令可以调整图形的坐标属性。
%propertyname和property value分别为坐标属性名称(不区分字母大小写)及对应的属性值。
set(gca,FontSize,10);
hold on%使当前及图形保持而不被刷新,准备接受此后将绘制的新曲线
plot(X(1, 1), X(2, 1), r., markersize,30)   %系统状态位置
%axis[xmin,xmax,ymin,ymax]设定坐标范围,必须满足xmin<xmax,后面同理
axis([0 100 0 100]);
plot(P(1, :), P(2, :), kx, markersize,5);   %绘出各个粒子位置
plot(PCenter(1, 1), PCenter(2, 1), b., markersize,25); %所有粒子的几何中心位置
%图形标注函数legend(string1,string2,string3...),在当前图中添加图例

legend(True State, Particles, The Center of Particles);
%添加图形标题命令title(string),在当前坐标系的顶部加一个文本串string,作为该图形的标题
title(Initial State);
%使当前轴及图形不再具备不被刷新的性质
hold off

%%
%开始运动
for k = 2 : T

    %模拟一个弧线运动的状态
    %wgn(m,n,p)产生一个m行n列的高斯白噪声的矩阵,p以dBW为单位指定输出噪声的强度。
    X(:, k) = X(:, k-1) + distance * [(-cos(k * theta)); sin(k * theta)] + wgn(2, 1, 10*log10(Q));     %状态方程
    Z(:, k) = X(:, k) + wgn(2, 1, 10*log10(R));     %观测方程 

    %粒子滤波
    %预测
    for i = 1 : N
        %将之前生成的粒子带入到状态方程,进行下一步状态的预测
        P(:, i) = P(:, i) + distance * [-cos(k * theta); sin(k * theta)] + wgn(2, 1, 10*log10(Q));
        dist = norm(P(:, i)-Z(:, k));     %与测量位置相差的距离,用于估算该粒子的权重
        %由于上面已经随机生成了N个粒子,现在将其与真实的测量值z进行比较,越接近则权重越大,或者说差值越小权重越大
        %这里的权重计算是关于p(z/x)的分布,即观测方程的分布,假设观测噪声满足高斯分布,那么w(i)=p(z/x)
        w(i) = (1 / sqrt(R) / sqrt(2 * pi)) * exp(-(dist)^2 / 2 / R);   %求权重
    end
%归一化权重
    wsum = sum(w);
    for i = 1 : N
        w(i) = w(i) / wsum;
    end

    %重采样(更新)
    for i = 1 : N
        wmax = 2 * max(w) * rand;  %另一种重采样规则,获取权重当中的最大值与均匀分布在0-1之间数的乘积再乘以2作为后面判断选出大权重粒子的依据
        %randi()函数生成均匀分布的伪随机整数,范围为imin--imax,如果没指定imin,则默认为1
        %r = randi([imin,imax],...)返回一个在[imin,imax]范围内的伪随机整数
        index = randi(N, 1);
        %在这里随机产生N个粒子当中的某个粒子,然后选择该粒子的权值,判断是否是大的粒子权重,是的话就把该粒子选出来
        while(wmax > w(index))
            %使vmax递减,不然的话单个粒子的权重是不可能大于vmax的值的
            wmax = wmax - w(index);
            index = index + 1;
            %如果从某个随机的粒子开始找,没找到从该粒子开始到最后的粒子权值总和大于vmax,那么就重新从第一个粒子开始查找
            if index > N
                index = 1;
            end          
        end
        P(:, i) = P(:, index);     %从上面的index中得到新粒子
    end
    %sum(X,2)表示把X按行求和;如果是sum(X),那就是按列求和
    PCenter(:, k) = sum(P, 2) / N;      %所有粒子的几何中心位置

    %计算误差
    err(k) = norm(X(:, k) - PCenter(:, k));     %粒子几何中心与系统真实状态的误差

    figure(2);
    set(gca,FontSize,12);
    %clf; 用来清除图形的命令。一般在画图之前用
    clf;
    hold on
    plot(X(1, k), X(2, k), r., markersize,50);  %系统状态位置
    axis([0 100 0 100]);
    plot(P(1, :), P(2, :), k., markersize,5);   %各个粒子位置
    plot(PCenter(1, k), PCenter(2, k), b., markersize,25); %所有粒子的中心位置
    legend(True State, Particle, The Center of Particles);
    hold off
    pause(0.1);
end

%%
figure(3);
set(gca,FontSize,12);
plot(X(1,:), X(2,:), r, Z(1,:), Z(2,:), g, PCenter(1,:), PCenter(2,:), b-);
axis([0 100 0 100]);
legend(True State, Measurement, Particle Filter);
xlabel(x, FontSize, 20); ylabel(y, FontSize, 20);

%%
figure(4);
set(gca,FontSize,12);
plot(err,.-);
xlabel(t, FontSize, 20);
title(The err);

 

二维粒子滤波纯代码