多种卡尔曼滤波器的参考代码 #1
							
								
								
									
										580
									
								
								Code/Matlab/AOA-IMU/RUN_AEKF.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										580
									
								
								Code/Matlab/AOA-IMU/RUN_AEKF.m
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,580 @@ | |||||||
|  | clear | ||||||
|  | clc | ||||||
|  | close all | ||||||
|  | load('data1.mat'); | ||||||
|  | nn = size(imuPosX,1); | ||||||
|  | %% lightHouse坐标系转换 | ||||||
|  | x =  lightHousePosX * 100; | ||||||
|  | y = -lightHousePosZ * 100; | ||||||
|  | 
 | ||||||
|  | % 定义误差函数,即均方根误差 | ||||||
|  | errorFunction = @(params) sqrt(mean((x(1:500) * cos(params(1)) - y(1:500) * sin(params(1)) + params(2) - imuPosX(1:500)).^2 + (x(1:500) * sin(params(1)) + y(1:500) * cos(params(1)) + params(3) - imuPosY(1:500)).^2)); | ||||||
|  | 
 | ||||||
|  | % 使用 fminsearch 优化误差函数,找到使误差最小的旋转角和位移 | ||||||
|  | initialGuess = [0, 10, 10]; % 初始猜测值,[旋转角, 位移] | ||||||
|  | optimizedParams = fminsearch(errorFunction, initialGuess); | ||||||
|  | 
 | ||||||
|  | % 输出优化后的旋转角和位移 | ||||||
|  | rotationAngle = optimizedParams(1); | ||||||
|  | xOffset = optimizedParams(2); | ||||||
|  | yOffset = optimizedParams(3); | ||||||
|  | % 旋转坐标 | ||||||
|  | xt = x * cos(rotationAngle) - y * sin(rotationAngle) + xOffset; | ||||||
|  | yt = x * sin(rotationAngle) + y * cos(rotationAngle) + yOffset; | ||||||
|  | %% | ||||||
|  | tagN = 4; | ||||||
|  | %标签坐标 | ||||||
|  | XN(:,1)=[-300;-300]; | ||||||
|  | XN(:,2)=[-300;300]; | ||||||
|  | XN(:,3)=[300;300]; | ||||||
|  | XN(:,4)=[300;-300]; | ||||||
|  | sim2=6; | ||||||
|  | Q=diag(repmat(sim2,1,2*tagN));%协方差矩阵 | ||||||
|  | measure_AOA = zeros(4,nn); | ||||||
|  | measure_d = zeros(4,nn); | ||||||
|  | measure_AOA(1,:) = aoa1'; | ||||||
|  | measure_AOA(2,:) = aoa2'; | ||||||
|  | measure_AOA(3,:) = aoa3'; | ||||||
|  | measure_AOA(4,:) = aoa4'; | ||||||
|  | measure_d(1,:) = d1'; | ||||||
|  | measure_d(2,:) = d2'; | ||||||
|  | measure_d(3,:) = d3'; | ||||||
|  | measure_d(4,:) = d4'; | ||||||
|  | %% uwb解算 | ||||||
|  | x_uwb(1) = 0; | ||||||
|  | y_uwb(1) = 0; | ||||||
|  | theta_uwb=zeros(nn,1); | ||||||
|  | for i=2:nn | ||||||
|  |     if measure_d(1,i) == 0 | ||||||
|  |         x_uwb(i) = x_uwb(i-1); | ||||||
|  |         y_uwb(i) = y_uwb(i-1);         | ||||||
|  |         continue; | ||||||
|  |     end | ||||||
|  |     [t1,theta] = WLS(XN,measure_AOA(:,i),measure_d(:,i),Q); | ||||||
|  |     x_uwb(i) = t1(1); | ||||||
|  |     y_uwb(i) = t1(2); | ||||||
|  |     theta_uwb(i) = 90-theta; | ||||||
|  |     theta_uwb(i) = mod(theta_uwb(i)+180,360)-180; | ||||||
|  |     derr_WLS(i)=norm(t1-[xt(i);yt(i)]); | ||||||
|  | end | ||||||
|  | thetat=zeros(nn,1); | ||||||
|  | for i=2:nn | ||||||
|  | detx=xt(i)-xt(i-1); | ||||||
|  | dety=yt(i)-yt(i-1); | ||||||
|  | thetat(i)=atan2d(detx,dety); | ||||||
|  | end | ||||||
|  | % Uwb.x=x_uwb; | ||||||
|  | % Uwb.y=y_uwb; | ||||||
|  | % Uwb.alpha=theta_uwb; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | % 角速度校准 | ||||||
|  | detW = mean(wZ(1:200)); | ||||||
|  | wZ = wZ - detW; | ||||||
|  | 
 | ||||||
|  | x_imu(1) = 0;  | ||||||
|  | y_imu(1) = 0; | ||||||
|  | Z=zeros(3,1); | ||||||
|  | WW = 0.05; | ||||||
|  | theta_imu(1) = 0; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | %  | ||||||
|  | % Imu.x=x_imu; | ||||||
|  | % Imu.y=y_imu; | ||||||
|  | % Imu.v=v_imu; | ||||||
|  | % Imu.alpha=alpha_imu; | ||||||
|  | % Imu.omega=omega_imu; | ||||||
|  | 
 | ||||||
|  | %%  KF | ||||||
|  | R = diag([1 1 1]); | ||||||
|  | % qq = 1; | ||||||
|  | qq = 0.00001; | ||||||
|  | Q1 = diag([qq qq qq qq qq]); | ||||||
|  | P0 = diag([0 0 0 0 0]); | ||||||
|  | H = [1 0 0 0 0; | ||||||
|  |     0 1 0 0 0; | ||||||
|  |     0 0 0 1 0]; | ||||||
|  | I = eye(5); | ||||||
|  | JF = zeros(5,5); | ||||||
|  | X_pre = zeros(5,nn); | ||||||
|  | X_kf(:,1) = [imuPosX(1);imuPosY(1);vXY(1)*100;0;wZ(1)]; | ||||||
|  | for i=2:nn | ||||||
|  |     % 计算IMU和里程计的时间差值 | ||||||
|  |     detImuTime = imuDataRxTime(i) - imuDataRxTime(i-1); | ||||||
|  |     detOdomTime = odomDataRxTime(i)-odomDataRxTime(i-1); | ||||||
|  |     % 获得此时Z轴角速度 | ||||||
|  |     w = wZ(i); | ||||||
|  |     % 获得小车的水平速度 | ||||||
|  |     v = vXY(i)*100; | ||||||
|  |     % 计算速度增量 | ||||||
|  |     detV=(vXY(i)-vXY(i-1))*100; | ||||||
|  |     % 计算位置增量 | ||||||
|  |     detD = v*detImuTime;  | ||||||
|  |     % 计算角度增量 | ||||||
|  |     detTheta = w*180/pi*detImuTime; | ||||||
|  |     % 计算角速度的变化量 | ||||||
|  |     detW = w-wZ(i-1); | ||||||
|  |     % 积分计算IMU的航位角 | ||||||
|  |     theta_imu(i) = theta_imu(i-1)+detTheta; | ||||||
|  |     % 航向约束 | ||||||
|  |     theta_imu(i) = mod(theta_imu(i)+180,360)-180; | ||||||
|  |      | ||||||
|  |     % 状态更新方程 | ||||||
|  |     F = [1 0 detImuTime*cosd(X_kf(4,i-1)) 0 0; | ||||||
|  |          0 1 detImuTime*sind(X_kf(4,i-1)) 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0;]; | ||||||
|  |     % 获得水平和垂直方向的位置增量 | ||||||
|  |     vtx = detD*cosd(theta_imu(i)); | ||||||
|  |     vty = detD*sind(theta_imu(i)); | ||||||
|  | 
 | ||||||
|  |     x_imu(i) = x_imu(i-1)+vtx;  | ||||||
|  |     y_imu(i) = y_imu(i-1)+vty; | ||||||
|  | 
 | ||||||
|  |     X_next = [vtx;vty;detV;detTheta;detW]; | ||||||
|  |     if (x_uwb(i) == x_uwb(i-1))&&(y_uwb(i) == y_uwb(i-1)) | ||||||
|  |         X_kf(:,i) = X_kf(:,i-1)+X_next; | ||||||
|  |         errKf(i) = norm(X_kf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |         theta_kf(i) = X_kf(4,i); | ||||||
|  |         continue | ||||||
|  |     end     | ||||||
|  |     X_pre(:,i) = X_kf(:,i-1)+X_next; | ||||||
|  |     Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |     P = F*P0*F'+Q1; | ||||||
|  |     Kg_kf = P*H'*inv(H*P*H'+R); | ||||||
|  |     X_kf(:,i) = X_pre(:,i)+Kg_kf*(Z-H*X_pre(:,i)); | ||||||
|  |     P0 = (I-Kg_kf*H)*P; | ||||||
|  | 
 | ||||||
|  |     errKf(i) = norm(X_kf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |     theta_kf(i) = X_kf(4,i); | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | %%  EKF | ||||||
|  | R = diag([1 1 1]); | ||||||
|  | % qq = 1; | ||||||
|  | qq = 0.00001; | ||||||
|  | Q1 = diag([qq qq qq qq qq]); | ||||||
|  | P0 = diag([0 0 0 0 0]); | ||||||
|  | H = [1 0 0 0 0; | ||||||
|  |     0 1 0 0 0; | ||||||
|  |     0 0 0 1 0]; | ||||||
|  | KK = zeros(5,3); | ||||||
|  | X_ekf(:,1) = [imuPosX(1);imuPosY(1);vXY(1)*100;0;wZ(1)]; | ||||||
|  | I = eye(5); | ||||||
|  | JF = zeros(5,5); | ||||||
|  | X_pre = zeros(5,nn); | ||||||
|  | 
 | ||||||
|  | for i=2:nn | ||||||
|  |     detImuTime = imuDataRxTime(i) - imuDataRxTime(i-1); | ||||||
|  |     detOdomTime = odomDataRxTime(i)-odomDataRxTime(i-1); | ||||||
|  |     w = wZ(i); | ||||||
|  |     v = vXY(i)*100; | ||||||
|  |     detV=(vXY(i)-vXY(i-1))*100; | ||||||
|  |     detD = v*detImuTime;  | ||||||
|  |     detTheta = w*180/pi*detImuTime; | ||||||
|  |     detW = w-wZ(i-1); | ||||||
|  |     theta_imu(i) = theta_imu(i-1)+detTheta; | ||||||
|  |     theta_imu(i) = mod(theta_imu(i)+180,360)-180; | ||||||
|  |     F = [1 0 detImuTime*cosd(X_ekf(4,i-1)) 0 0; | ||||||
|  |          0 1 detImuTime*sind(X_ekf(4,i-1)) 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0;]; | ||||||
|  |     if w<WW | ||||||
|  |         vtx = detD*cosd(theta_imu(i)); | ||||||
|  |         vty = detD*sind(theta_imu(i)); | ||||||
|  |     else | ||||||
|  |         vtx = v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |         vty = v/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1)));            | ||||||
|  |     end | ||||||
|  |     x_imu(i) = x_imu(i-1)+vtx;  | ||||||
|  |     y_imu(i) = y_imu(i-1)+vty; | ||||||
|  |     errUwb(i) = norm([x_uwb(i);y_uwb(i)]-[xt(i);yt(i)]); | ||||||
|  |     errImu(i) = norm([x_imu(i);y_imu(i)]-[xt(i);yt(i)]); | ||||||
|  |     X_next = [vtx;vty;detV;detTheta;detW]; | ||||||
|  |     if (x_uwb(i) == x_uwb(i-1))&&(y_uwb(i) == y_uwb(i-1)) | ||||||
|  |         X_ekf(:,i) = X_ekf(:,i-1)+X_next; | ||||||
|  |         errEKf(i) = norm(X_ekf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |         theta_ekf(i) = X_ekf(4,i); | ||||||
|  |         continue | ||||||
|  |     end     | ||||||
|  |     if w<WW | ||||||
|  |         X_pre(:,i) = X_ekf(:,i-1)+X_next; | ||||||
|  |         Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |         P = F*P0*F'+Q1; | ||||||
|  |         Kg = P*H'*inv(H*P*H'+R); | ||||||
|  |         X_ekf(:,i) = X_pre(:,i)+Kg*(Z-H*X_pre(:,i)); | ||||||
|  |         P0 = (I-Kg*H)*P; | ||||||
|  |     else | ||||||
|  |         JF = [1 0 1/w*(sind(theta_imu(i))-sind(theta_imu(i-1))) v/w*(cosd(theta_imu(i))-cosd(theta_imu(i-1))) detD/w*cosd(theta_imu(i))-v/(w^2)*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |              0 1 1/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1))) v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))) detD/w*sind(theta_imu(i))-v/(w^2)*(-cosd(theta_imu(i))+cosd(theta_imu(i-1))); | ||||||
|  |              0 0 1 0 0; | ||||||
|  |              0 0 0 1 detImuTime; | ||||||
|  |              0 0 0 0 1]; | ||||||
|  | 
 | ||||||
|  |         X_pre(:,i) = X_ekf(:,i-1)+X_next; | ||||||
|  |         Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |         P = JF*P0*JF'+Q1; | ||||||
|  |         Kg = P*H'*inv(H*P*H'+R); | ||||||
|  |         X_ekf(:,i) = X_pre(:,i)+Kg*(Z-H*X_pre(:,i)); | ||||||
|  |         P0 = (I-Kg*H)*P; | ||||||
|  |     end | ||||||
|  |     errEKf(i) = norm(X_ekf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |     theta_ekf(i) = X_ekf(4,i); | ||||||
|  | end | ||||||
|  | %%  UKF | ||||||
|  | % UKF settings | ||||||
|  | ukf_L = 5; %numer of states | ||||||
|  | ukf_m = 3; %numer of measurements | ||||||
|  | ukf_kappa = 3 - ukf_L; | ||||||
|  | ukf_alpha = 0.9; | ||||||
|  | ukf_beta = 2; | ||||||
|  | 
 | ||||||
|  | ukf_lambda = ukf_alpha^2*(ukf_L + ukf_kappa) - ukf_L; | ||||||
|  | ukf_gamma = sqrt(ukf_L + ukf_lambda); | ||||||
|  | ukf_W0_c = ukf_lambda / (ukf_L + ukf_lambda) + (1 - ukf_alpha^2 + ukf_beta); | ||||||
|  | ukf_W0_m = ukf_lambda / (ukf_L + ukf_lambda); | ||||||
|  | ukf_Wi_m = 1 / (2*(ukf_L + ukf_lambda)); | ||||||
|  | ukf_Wi_c = ukf_Wi_m; | ||||||
|  | 
 | ||||||
|  | q=0.01;    %std of process  | ||||||
|  | r=5;    %std of measurement | ||||||
|  | p=2; | ||||||
|  | Qu=q*eye(ukf_L); % std matrix of process | ||||||
|  | Ru=r*eye(ukf_m);        % std of measurement  | ||||||
|  | Pu=p*eye(ukf_L); | ||||||
|  | H = [1 0 0 0 0; | ||||||
|  |      0 1 0 0 0; | ||||||
|  |      0 0 0 1 0]; | ||||||
|  | X_ukf(:,1) = [imuPosX(1);imuPosY(1);vXY(1)*100;0;wZ(1)]; | ||||||
|  | I = eye(5); | ||||||
|  | JF = zeros(5,5); | ||||||
|  | X_pre = zeros(5,nn); | ||||||
|  | for i=2:nn | ||||||
|  |     detImuTime = imuDataRxTime(i) - imuDataRxTime(i-1); | ||||||
|  |     detOdomTime = odomDataRxTime(i)-odomDataRxTime(i-1); | ||||||
|  |     w = wZ(i); | ||||||
|  |     v = vXY(i)*100; | ||||||
|  |     detV=(vXY(i)-vXY(i-1))*100; | ||||||
|  |     detD = v*detImuTime;  | ||||||
|  |     detTheta = w*180/pi*detImuTime; | ||||||
|  |     detW = w-wZ(i-1); | ||||||
|  |     theta_imu(i) = theta_imu(i-1)+detTheta; | ||||||
|  |     theta_imu(i) = mod(theta_imu(i)+180,360)-180; | ||||||
|  |     % F = [1 0 detImuTime*cosd(X_ekf(4,i-1)) 0 0; | ||||||
|  |     %      0 1 detImuTime*sind(X_ekf(4,i-1)) 0 0; | ||||||
|  |     %      0 0 0 0 0; | ||||||
|  |     %      0 0 0 0 0; | ||||||
|  |     %      0 0 0 0 0;]; | ||||||
|  |     if w<WW | ||||||
|  |         vtx = detD*cosd(theta_imu(i)); | ||||||
|  |         vty = detD*sind(theta_imu(i)); | ||||||
|  |     else | ||||||
|  |         vtx = v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |         vty = v/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1)));            | ||||||
|  |     end | ||||||
|  |     x_imu(i) = x_imu(i-1)+vtx;  | ||||||
|  |     y_imu(i) = y_imu(i-1)+vty; | ||||||
|  |     errUwb(i) = norm([x_uwb(i);y_uwb(i)]-[xt(i);yt(i)]); | ||||||
|  |     errImu(i) = norm([x_imu(i);y_imu(i)]-[xt(i);yt(i)]); | ||||||
|  |     X_next = [vtx;vty;detV;detTheta;detW]; | ||||||
|  |     if (x_uwb(i) == x_uwb(i-1))&&(y_uwb(i) == y_uwb(i-1)) | ||||||
|  |         X_ukf(:,i) = X_ukf(:,i-1)+X_next; | ||||||
|  |         errUKf(i) = norm(X_ukf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |         theta_ukf(i) = X_ukf(4,i); | ||||||
|  |         continue | ||||||
|  |     end     | ||||||
|  | 
 | ||||||
|  |     xestimate = X_ukf(:,i-1); | ||||||
|  |     Xx = repmat(xestimate, 1, length(xestimate)); | ||||||
|  |     Xsigma = [xestimate, ( Xx + ukf_gamma * Pu ), ( Xx - ukf_gamma * Pu )]; | ||||||
|  |      | ||||||
|  |     %第二步:对Sigma点集进行一步预测 | ||||||
|  |     [Xsigmapre]=fun1(Xsigma,detImuTime); | ||||||
|  |     %第三步:估计预测状态 | ||||||
|  |     Xpred = ukf_W0_m * Xsigmapre(:,1) + ukf_Wi_m * sum(Xsigmapre(:,2:end), 2); | ||||||
|  |     %第四步:均值和方差 | ||||||
|  |       Xx = repmat(Xpred, 1, length(xestimate)*2); | ||||||
|  |      [~, R] = qr([sqrt(ukf_Wi_c) * ( Xsigmapre(:,2:end) - Xx ), Qu]', 0); | ||||||
|  |      Ppred = cholupdate(R, sqrt(ukf_W0_c) * (Xsigmapre(:,1) - Xpred), '-')'; | ||||||
|  | 
 | ||||||
|  |     %第5步:根据预测值,再一次使用UT变换,得到新的sigma点集 | ||||||
|  |     Xx = repmat(Xpred, 1, length(xestimate)); | ||||||
|  |     Xsigmapre = [Xpred, ( Xx + ukf_gamma * Ppred ), ( Xx - ukf_gamma * Ppred )]; | ||||||
|  | 
 | ||||||
|  |     %第6步:观测预测 | ||||||
|  |     Zsigmapre=H*Xsigmapre; | ||||||
|  | 
 | ||||||
|  |     %第7步:计算观测预测均值和协方差 | ||||||
|  |     Zpred = ukf_W0_m * Zsigmapre(:,1) + ukf_Wi_m * sum(Zsigmapre(:,2:end), 2); | ||||||
|  | 
 | ||||||
|  |     Yy = repmat(Zpred, 1, length(xestimate)*2); | ||||||
|  |     [~, Rz] = qr([sqrt(ukf_Wi_c) * (Zsigmapre(:,2:end) - Yy), Ru]', 0); | ||||||
|  |     Pzz = cholupdate(Rz, sqrt(ukf_W0_c) * (Zsigmapre(:,1) - Zpred), '-')'; | ||||||
|  | 
 | ||||||
|  |     Xd = Xsigmapre - repmat(Xpred, 1, length(xestimate)*2 + 1); | ||||||
|  |     Zd = Zsigmapre - repmat(Zpred, 1, length(xestimate)*2 + 1); | ||||||
|  |    | ||||||
|  |     Pxz = ( ukf_W0_c*  Xd(:,1) * Zd(:,1)' ) + ( ukf_Wi_c * Xd(:,2:end) * Zd(:,2:end)' ); | ||||||
|  | 
 | ||||||
|  |     %第七步:计算kalman增益 | ||||||
|  |     Kukf= (Pxz / Pzz') / Pzz; | ||||||
|  |     %第八步:状态和方差更新 | ||||||
|  |     Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |     Xpred=Xpred+Kukf*(Z-Zpred); | ||||||
|  |     U = Kukf * Pzz; | ||||||
|  |     Rp = Ppred'; | ||||||
|  |     for ii=1:size(U, 2) | ||||||
|  |         Rp = cholupdate(Rp, U(:,ii), '-'); | ||||||
|  |     end | ||||||
|  |     Ppred = Rp'; | ||||||
|  |     X_ukf(:,i)=Xpred; | ||||||
|  | 
 | ||||||
|  |     errUKf(i) = norm(X_ukf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |     theta_ukf(i) = X_ukf(4,i); | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | %% | ||||||
|  | %%AEKF | ||||||
|  | R = diag([1 1 1]); | ||||||
|  | % qq = 50; | ||||||
|  | % qq = 10; | ||||||
|  | qq = 0.01; | ||||||
|  | Q = diag([qq qq qq qq qq]); | ||||||
|  | P0 = diag([0 0 0 0 0]); | ||||||
|  | H = [1 0 0 0 0; | ||||||
|  |      0 1 0 0 0; | ||||||
|  |      0 0 0 1 0]; | ||||||
|  | X_aekf = zeros(5,nn); | ||||||
|  | X_aekf(:,1) = [imuPosX(1);imuPosY(1);vXY(1)*100;0;wZ(1)]; | ||||||
|  | I = eye(5); | ||||||
|  | JF = zeros(5,5); | ||||||
|  | X_pre = zeros(5,nn); | ||||||
|  | alfa = 0.97; | ||||||
|  | 
 | ||||||
|  | windowlength=5; | ||||||
|  | x_aekf_sw=zeros(1,nn); | ||||||
|  | y_aekf_sw=zeros(1,nn); | ||||||
|  | for i=2:nn | ||||||
|  |     detImuTime = imuDataRxTime(i) - imuDataRxTime(i-1); | ||||||
|  |     detOdomTime = odomDataRxTime(i)-odomDataRxTime(i-1); | ||||||
|  |     w = wZ(i); | ||||||
|  |     v = vXY(i)*100; | ||||||
|  |     detV=(vXY(i)-vXY(i-1))*100; | ||||||
|  |     detD = v*detImuTime;  | ||||||
|  |     detTheta = w*180/pi*detImuTime; | ||||||
|  |     detW = w-wZ(i-1); | ||||||
|  |     theta_imu(i) = theta_imu(i-1)+detTheta; | ||||||
|  |     theta_imu(i) = mod(theta_imu(i)+180,360)-180; | ||||||
|  |     F = [1 0 detImuTime*cosd(X_aekf(4,i-1)) 0 0; | ||||||
|  |          0 1 detImuTime*sind(X_aekf(4,i-1)) 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0;]; | ||||||
|  |     if w<WW | ||||||
|  |         vtx = detD*cosd(theta_imu(i)); | ||||||
|  |         vty = detD*sind(theta_imu(i)); | ||||||
|  |     else | ||||||
|  |         vtx = v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |         vty = v/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1)));            | ||||||
|  |     end | ||||||
|  |     x_imu(i) = x_imu(i-1)+vtx;  | ||||||
|  |     y_imu(i) = y_imu(i-1)+vty; | ||||||
|  |     X_next = [vtx;vty;detV;detTheta;detW]; | ||||||
|  |     if (x_uwb(i) == x_uwb(i-1))&&(y_uwb(i) == y_uwb(i-1)) | ||||||
|  |         X_aekf(:,i) = X_aekf(:,i-1)+X_next; | ||||||
|  |         errAEKf(i) = norm(X_aekf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |         theta_aekf(i) = X_aekf(4,i); | ||||||
|  |         continue | ||||||
|  |     end     | ||||||
|  |     if w<WW | ||||||
|  |         X_pre(:,i) = X_aekf(:,i-1)+X_next; | ||||||
|  |         Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |         P = F*P0*F'+Q; | ||||||
|  |         Kg = P*H'*inv(H*P*H'+R); | ||||||
|  |         KK(1,1) = Kg(1,1); | ||||||
|  |         KK(2,2) = Kg(2,2); | ||||||
|  |         KK(4,3) = Kg(4,3); | ||||||
|  |         X_aekf(:,i) = X_pre(:,i)+KK*(Z-H*X_pre(:,i)); | ||||||
|  |         P0 = (I-Kg*H)*P; | ||||||
|  |     else | ||||||
|  |         JF = [1 0 1/w*(sind(theta_imu(i))-sind(theta_imu(i-1))) v/w*(cosd(theta_imu(i))-cosd(theta_imu(i-1))) detD/w*cosd(theta_imu(i))-v/(w^2)*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |              0 1 1/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1))) v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))) detD/w*sind(theta_imu(i))-v/(w^2)*(-cosd(theta_imu(i))+cosd(theta_imu(i-1))); | ||||||
|  |              0 0 1 0 0; | ||||||
|  |              0 0 0 1 detImuTime; | ||||||
|  |              0 0 0 0 1]; | ||||||
|  |         X_pre(:,i) = X_aekf(:,i-1)+X_next; | ||||||
|  |         dk = Z - H*X_pre(:,i); | ||||||
|  |         Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |         P = JF*P0*JF'+Q; | ||||||
|  |         Kg = P*H'*inv(H*P*H'+R); | ||||||
|  |         KK(1,1) = Kg(1,1); | ||||||
|  |         KK(2,2) = Kg(2,2); | ||||||
|  |         KK(4,3) = Kg(4,3); | ||||||
|  |         X_aekf(:,i) = X_pre(:,i)+KK*(Z-H*X_pre(:,i)); | ||||||
|  |         epz = Z-H*X_aekf(:,i); | ||||||
|  |         R=alfa*R+(1-alfa)*(epz*epz'+H*P*H'); | ||||||
|  |         Q=alfa*Q+(1-alfa)*Kg*dk*dk'*Kg'; | ||||||
|  |         P0 = (I-Kg*H)*P; | ||||||
|  |     end | ||||||
|  |     errAEKf(i) = norm(X_aekf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |     theta_aekf(i) = X_aekf(4,i); | ||||||
|  |     % if errAEKf(i)>15 | ||||||
|  |     %     xxx = 1; | ||||||
|  |     % end | ||||||
|  | end | ||||||
|  | errAEKf_sw=zeros(1,nn); | ||||||
|  | weightedvector=[0.3;0.25;0.2;0.15;0.1]; | ||||||
|  | for i=1:nn | ||||||
|  | if i>windowlength-1 | ||||||
|  |     x_win=X_aekf(1,i-windowlength+1:i); | ||||||
|  |     y_win=X_aekf(2,i-windowlength+1:i); | ||||||
|  |     x_aekf_sw(i)=x_win*weightedvector; | ||||||
|  |     y_aekf_sw(i)=y_win*weightedvector; | ||||||
|  | else  | ||||||
|  |     x_aekf_sw(i)=X_aekf(1,i); | ||||||
|  |     y_aekf_sw(i)=X_aekf(2,i); | ||||||
|  | end | ||||||
|  | errAEKf_sw(i) = norm([x_aekf_sw(i);y_aekf_sw(i)]-[xt(i);yt(i)]); | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | figure; | ||||||
|  | plot(errAEKf_sw); | ||||||
|  | 
 | ||||||
|  | %% | ||||||
|  | for i=2:length(theta_uwb)-1 | ||||||
|  |     if theta_uwb(i) == 0 | ||||||
|  |         theta_uwb(i) = theta_uwb(i-1); | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | figure(1) | ||||||
|  | clf(1) | ||||||
|  | plot(x_uwb,y_uwb,'.','color',[205/255, 133/255, 63/255],'LineWidth',0.2);hold on | ||||||
|  | plot(x_imu, y_imu, '-','color',[0, 128/255, 0],'LineWidth',0.5); | ||||||
|  | plot(xt, yt, '-black','LineWidth',0.5); | ||||||
|  | legend('AUAM','IMU','True value'); | ||||||
|  | xlabel('X(cm)'); | ||||||
|  | ylabel('Y(cm)'); | ||||||
|  | grid on | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | % figure(1) | ||||||
|  | % clf(1) | ||||||
|  | % hold on | ||||||
|  | % plot((1:nn)/100,thetat,'-black','LineWidth',1); | ||||||
|  | % plot((1:nn)/100,theta_uwb,'-','color','#CD853F','LineWidth',1); | ||||||
|  | % plot((1:nn)/100,theta_imu, '-','color','#008000','LineWidth',1); | ||||||
|  | % legend('LightHouse','UWB', 'INS'); | ||||||
|  | % xlabel('time(s)'); | ||||||
|  | % ylabel('\alpha(°)'); | ||||||
|  | % grid on | ||||||
|  | 
 | ||||||
|  | % figure(2) | ||||||
|  | % clf(2) | ||||||
|  | % hold on | ||||||
|  | % plot(theta_imu,'.'); | ||||||
|  | % plot(theta_uwb,'.'); | ||||||
|  | % legend('imu','uwb'); | ||||||
|  | % xlabel('运行时间(10ms)'); | ||||||
|  | % ylabel('偏航角(°)'); | ||||||
|  | % title('角速度校准后imu和uwb测量偏航角'); | ||||||
|  | % grid on | ||||||
|  | %  | ||||||
|  | % figure(3) | ||||||
|  | % clf(3) | ||||||
|  | % hold on | ||||||
|  | % plot(xt, yt, '.-black','LineWidth',1); | ||||||
|  | % plot(X_ekf(1,:), X_ekf(2,:), '.-','color','#7E2F8E','LineWidth',1); | ||||||
|  | % plot(X_aekf(1,:), X_aekf(2,:), '.-','color','#D95319','LineWidth',0.5) | ||||||
|  | % plot(x_aekf_sw, y_aekf_sw, '.-','color','#2E8B57','LineWidth',0.5) | ||||||
|  | % legend('True','EKF', 'AEKF', 'AEKF-SWF'); | ||||||
|  | % xlabel('x(cm)'); | ||||||
|  | % ylabel('y(cm)'); | ||||||
|  | % grid on | ||||||
|  | %  | ||||||
|  | % figure(4) | ||||||
|  | % clf(4) | ||||||
|  | % hold on | ||||||
|  | % plot(errKf,'.','color','#0072BD'); | ||||||
|  | % plot(errEKf,'.','color','#EDB120'); | ||||||
|  | % plot(errUKf,'.','color','#D95319'); | ||||||
|  | % plot(errAEKf,'.','color','#7E2F8E'); | ||||||
|  | % plot(errAEKf_sw,'.','color','#77AC30'); | ||||||
|  | % legend('KF','EKF','UKF','AEKF','AEKF-SWF'); | ||||||
|  | % xlabel('运行时间(10ms)'); | ||||||
|  | % ylabel('误差(cm)'); | ||||||
|  | % title('定位误差随时间变化图'); | ||||||
|  |   | ||||||
|  | % slt = 1; | ||||||
|  | % uwbcount = 9; | ||||||
|  | % imucount = 15; | ||||||
|  | % ekfcount = 12; | ||||||
|  | % aekfcount = 5; | ||||||
|  | % figure(5) | ||||||
|  | % clf(5) | ||||||
|  | % hold on | ||||||
|  | % [fUWB,xUWB] = ksdensity(errUwb(slt:end)); | ||||||
|  | % [fIMU,xIMU] = ksdensity(errImu(slt:end)); | ||||||
|  | % [fAEKF,xAEKF] = ksdensity(errAEKf(slt:end)); | ||||||
|  | % [fUKF,xUKF] = ksdensity(errUKf(slt:end)); | ||||||
|  | % [fAEKF_sw,xAEKF_sw] = ksdensity(errAEKf_sw(slt:end)); | ||||||
|  | % [fEKF,xEKF] = ksdensity(errEKf(slt:end)); | ||||||
|  | % [fKF,xKF] = ksdensity(errKf(slt:end)); | ||||||
|  | % plot(xKF(ekfcount:end),fKF(ekfcount:end), 'color','#0072BD','LineWidth',0.5); | ||||||
|  | % plot(xEKF(ekfcount:end),fEKF(ekfcount:end),'color','#EDB120','LineWidth',0.5); | ||||||
|  | % plot(xUKF(ekfcount:end), fUKF(ekfcount:end),'color','#D95319','LineWidth',0.5); | ||||||
|  | % plot(xAEKF(aekfcount:end),fAEKF(aekfcount:end),'color','#7E2F8E','LineWidth',0.5); | ||||||
|  | % plot(xAEKF_sw(aekfcount:end),fAEKF_sw(aekfcount:end), 'color','#77AC30','LineWidth',0.5) | ||||||
|  | % legend('KF','EKF','UKF','AEKF','AEKF-SWF');%'UWB','INS', | ||||||
|  | % xlabel('Error(cm)'); | ||||||
|  | % ylabel('Probability(%)'); | ||||||
|  | % grid on | ||||||
|  | %  | ||||||
|  | %  | ||||||
|  | %  | ||||||
|  | % slt = 3000; | ||||||
|  | % uwbcount = 9; | ||||||
|  | % imucount = 9; | ||||||
|  | % ekfcount = 13; | ||||||
|  | % aekfcount = 7; | ||||||
|  | % figure(6) | ||||||
|  | % clf(6) | ||||||
|  | % hold on | ||||||
|  | % [fAEKF,xAEKF] = ksdensity(errAEKf(slt:end)); | ||||||
|  | % [fUKF,xUKF] = ksdensity(errUKf(slt:end)); | ||||||
|  | % [fAEKF_sw,xAEKF_sw] = ksdensity(errAEKf_sw(slt:end)); | ||||||
|  | % [fEKF,xEKF] = ksdensity(errEKf(slt:end)); | ||||||
|  | % [fKF,xKF] = ksdensity(errKf(slt:end)); | ||||||
|  | % plot(xKF(ekfcount:end),fKF(ekfcount:end), 'color','#0072BD','LineWidth',0.5); | ||||||
|  | % plot(xEKF(ekfcount:end),fEKF(ekfcount:end),'color','#EDB120','LineWidth',0.5); | ||||||
|  | % plot(xUKF(ekfcount:end), fUKF(ekfcount:end),'color','#D95319','LineWidth',0.5); | ||||||
|  | % plot(xAEKF(aekfcount:end),fAEKF(aekfcount:end),'color','#7E2F8E','LineWidth',0.5); | ||||||
|  | % plot(xAEKF_sw(aekfcount:end),fAEKF_sw(aekfcount:end), 'color','#77AC30','LineWidth',0.5) | ||||||
|  | % legend('KF','EKF','UKF','AEKF','AEKF-SWF');%'UWB','INS', | ||||||
|  | % xlabel('Error(cm)'); | ||||||
|  | % ylabel('PDF'); | ||||||
|  | % grid on | ||||||
|  | %  | ||||||
|  | % figure(7) | ||||||
|  | % clf(7) | ||||||
|  | % hold on | ||||||
|  | % h1 = cdfplot(errKf(slt:end)); | ||||||
|  | % h2 = cdfplot(errEKf(slt:end)); | ||||||
|  | % h3 = cdfplot(errUKf(slt:end)); | ||||||
|  | % h4 = cdfplot(errAEKf(slt:end)); | ||||||
|  | % h5 = cdfplot(errAEKf_sw(slt:end)); | ||||||
|  | % set(h1,'color','#0072BD','LineWidth',0.5); | ||||||
|  | % set(h2,'color','#EDB120','LineWidth',0.5); | ||||||
|  | % set(h3,'color','#D95319','LineWidth',0.5); | ||||||
|  | % set(h4,'color','#7E2F8E','LineWidth',0.5); | ||||||
|  | % set(h5,'color','#77AC30','LineWidth',0.5); | ||||||
|  | % legend('KF','EKF','UKF','AEKF','AEKF-SWF'); | ||||||
|  | % xlabel('Error(cm)'); | ||||||
|  | % ylabel('CDF'); | ||||||
|  | % grid on | ||||||
							
								
								
									
										33
									
								
								Code/Matlab/AOA-IMU/WLS.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Code/Matlab/AOA-IMU/WLS.m
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | function [x,theta] = WLS(XN,mean_aoa,mean_d,Q) | ||||||
|  | %PLE 此处显示有关此函数的摘要 | ||||||
|  | %   此处显示详细说明 | ||||||
|  | nn = size(XN,2); | ||||||
|  | A = zeros(2*nn, 6); | ||||||
|  | b = zeros(2*nn, 1); | ||||||
|  | for j=1:nn | ||||||
|  |     XN_Tag(1,j)=mean_d(j)*sind(mean_aoa(j)); | ||||||
|  |     XN_Tag(2,j)=mean_d(j)*cosd(mean_aoa(j)); | ||||||
|  |     A(2*j-1,:)  = [XN_Tag(1,j) 0 XN_Tag(2,j) 0 1 0]; | ||||||
|  |     A(2*j,:)    = [0 XN_Tag(1,j) 0 XN_Tag(2,j) 0 1]; | ||||||
|  |     b(2*j-1:2*j)=[XN(1,j) XN(2,j)];      | ||||||
|  | end  | ||||||
|  | f=(A'*A)^(-1)*A'*b; | ||||||
|  | for i=1:2 | ||||||
|  |     for j=1:nn | ||||||
|  |         B(2*j-1,2*j-1) = XN(2,j)-f(6); | ||||||
|  |         B(2*j,2*j) = XN(1,j)-f(5); | ||||||
|  |     end | ||||||
|  |   W = inv(B*Q*B'); | ||||||
|  |   f=(A'*W*A)\A'*W*b; | ||||||
|  | end | ||||||
|  | x=(f(5:6)); | ||||||
|  | theta1(1)=atan2d(-f(2),f(1)); | ||||||
|  | theta1(2)=atan2d(f(3),f(4)); | ||||||
|  | % theta1(1)=acosd(-f(1)); | ||||||
|  | % theta1(2)=asind(-f(2)); | ||||||
|  | % theta1(3)=asind(f(3)); | ||||||
|  | % theta1(4)=acosd(-f(4)); | ||||||
|  | 
 | ||||||
|  | theta = mean(theta1); | ||||||
|  | end | ||||||
|  | 
 | ||||||
							
								
								
									
										
											BIN
										
									
								
								Code/Matlab/AOA-IMU/data1.mat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Code/Matlab/AOA-IMU/data1.mat
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										28
									
								
								Code/Matlab/AOA-IMU/fun1.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								Code/Matlab/AOA-IMU/fun1.m
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | function [Y] = fun1(X,dt) | ||||||
|  | %FUN 此处显示有关此函数的摘要 | ||||||
|  | %   此处显示详细说明 | ||||||
|  | WW = 0.05; | ||||||
|  | nn = size(X,2); | ||||||
|  | Y = zeros(5,nn); | ||||||
|  | 
 | ||||||
|  | for i=1:nn | ||||||
|  |     v = X(3,i); | ||||||
|  |     alfa = X(4,i); | ||||||
|  |     w = X(5,i)*180/pi; | ||||||
|  |     if w<WW | ||||||
|  |         alfa = alfa+w*dt; | ||||||
|  |         Y(:,i) = [X(1,i) + v*dt*cosd(alfa); | ||||||
|  |                   X(2,i) - v*dt*sind(alfa); | ||||||
|  |                   v; | ||||||
|  |                   alfa; | ||||||
|  |                   w*pi/180];         | ||||||
|  |     else | ||||||
|  |         Y(:,i) = [X(1,i) + v/w*(sind(alfa+w*dt)-sind(alfa)); | ||||||
|  |                   X(2,i) - v/w*(cosd(alfa+w*dt)-cosd(alfa)); | ||||||
|  |                   v; | ||||||
|  |                   alfa+w*dt; | ||||||
|  |                   w*pi/180]; | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | end | ||||||
|  | 
 | ||||||
							
								
								
									
										36
									
								
								Code/Matlab/AOA-IMU/script.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Code/Matlab/AOA-IMU/script.m
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | clear | ||||||
|  | clc | ||||||
|  | close all | ||||||
|  | load('data1.mat'); | ||||||
|  | nn = size(imuPosX,1); | ||||||
|  | %% lightHouse坐标系转换 | ||||||
|  | x =  lightHousePosX * 100; | ||||||
|  | y = -lightHousePosZ * 100; | ||||||
|  | 
 | ||||||
|  | plot(x,y,'r',imuPosX,imuPosY); | ||||||
|  | 
 | ||||||
|  | % 定义误差函数,即均方根误差 | ||||||
|  | errorFunction = @(params) sqrt(mean((x(1:500) * cos(params(1)) - y(1:500) * sin(params(1)) + params(2) - imuPosX(1:500)).^2 + (x(1:500) * sin(params(1)) + y(1:500) * cos(params(1)) + params(3) - imuPosY(1:500)).^2)); | ||||||
|  | 
 | ||||||
|  | % 使用 fminsearch 优化误差函数,找到使误差最小的旋转角和位移 | ||||||
|  | initialGuess = [0, 10, 10]; % 初始猜测值,[旋转角, 位移] | ||||||
|  | optimizedParams = fminsearch(errorFunction, initialGuess); | ||||||
|  | 
 | ||||||
|  | % 输出优化后的旋转角和位移 | ||||||
|  | rotationAngle = optimizedParams(1); | ||||||
|  | xOffset = optimizedParams(2); | ||||||
|  | yOffset = optimizedParams(3); | ||||||
|  | % 旋转坐标 | ||||||
|  | xt = x * cos(rotationAngle) - y * sin(rotationAngle) + xOffset; | ||||||
|  | yt = x * sin(rotationAngle) + y * cos(rotationAngle) + yOffset; | ||||||
|  | 
 | ||||||
|  | plot(xt,yt,'r',imuPosX,imuPosY); | ||||||
|  | 
 | ||||||
|  | ds = zeros(1,length(imuDataRxTime)); | ||||||
|  | for i = 1:length(imuDataRxTime)-1 | ||||||
|  |     ds(i) = 1 / (imuDataRxTime(i+1)-imuDataRxTime(i)); | ||||||
|  | end | ||||||
|  | plot(ds) | ||||||
|  | 
 | ||||||
							
								
								
									
										199
									
								
								Code/Matlab/AOA-IMU/script_aekf.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								Code/Matlab/AOA-IMU/script_aekf.m
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,199 @@ | |||||||
|  | clear | ||||||
|  | clc | ||||||
|  | close all | ||||||
|  | load('data1.mat'); | ||||||
|  | nn = size(imuPosX,1); | ||||||
|  | %% lightHouse坐标系转换 | ||||||
|  | x =  lightHousePosX * 100; | ||||||
|  | y = -lightHousePosZ * 100; | ||||||
|  | 
 | ||||||
|  | % 定义误差函数,即均方根误差 | ||||||
|  | errorFunction = @(params) sqrt(mean((x(1:500) * cos(params(1)) - y(1:500) * sin(params(1)) + params(2) - imuPosX(1:500)).^2 + (x(1:500) * sin(params(1)) + y(1:500) * cos(params(1)) + params(3) - imuPosY(1:500)).^2)); | ||||||
|  | 
 | ||||||
|  | % 使用 fminsearch 优化误差函数,找到使误差最小的旋转角和位移 | ||||||
|  | initialGuess = [0, 10, 10]; % 初始猜测值,[旋转角, 位移] | ||||||
|  | optimizedParams = fminsearch(errorFunction, initialGuess); | ||||||
|  | 
 | ||||||
|  | % 输出优化后的旋转角和位移 | ||||||
|  | rotationAngle = optimizedParams(1); | ||||||
|  | xOffset = optimizedParams(2); | ||||||
|  | yOffset = optimizedParams(3); | ||||||
|  | % 旋转坐标 | ||||||
|  | xt = x * cos(rotationAngle) - y * sin(rotationAngle) + xOffset; | ||||||
|  | yt = x * sin(rotationAngle) + y * cos(rotationAngle) + yOffset; | ||||||
|  | %% | ||||||
|  | tagN = 4; | ||||||
|  | %标签坐标 | ||||||
|  | XN(:,1)=[-300;-300]; | ||||||
|  | XN(:,2)=[-300;300]; | ||||||
|  | XN(:,3)=[300;300]; | ||||||
|  | XN(:,4)=[300;-300]; | ||||||
|  | sim2=6; | ||||||
|  | Q=diag(repmat(sim2,1,2*tagN));%协方差矩阵 | ||||||
|  | measure_AOA = zeros(4,nn); | ||||||
|  | measure_d = zeros(4,nn); | ||||||
|  | measure_AOA(1,:) = aoa1'; | ||||||
|  | measure_AOA(2,:) = aoa2'; | ||||||
|  | measure_AOA(3,:) = aoa3'; | ||||||
|  | measure_AOA(4,:) = aoa4'; | ||||||
|  | measure_d(1,:) = d1'; | ||||||
|  | measure_d(2,:) = d2'; | ||||||
|  | measure_d(3,:) = d3'; | ||||||
|  | measure_d(4,:) = d4'; | ||||||
|  | %% uwb解算 | ||||||
|  | x_uwb(1) = 0; | ||||||
|  | y_uwb(1) = 0; | ||||||
|  | theta_uwb=zeros(nn,1); | ||||||
|  | for i=2:nn | ||||||
|  |     if measure_d(1,i) == 0 | ||||||
|  |         x_uwb(i) = x_uwb(i-1); | ||||||
|  |         y_uwb(i) = y_uwb(i-1);         | ||||||
|  |         continue; | ||||||
|  |     end | ||||||
|  |     [t1,theta] = WLS(XN,measure_AOA(:,i),measure_d(:,i),Q); | ||||||
|  |     x_uwb(i) = t1(1); | ||||||
|  |     y_uwb(i) = t1(2); | ||||||
|  |     theta_uwb(i) = 90-theta; | ||||||
|  |     theta_uwb(i) = mod(theta_uwb(i)+180,360)-180; | ||||||
|  |     derr_WLS(i)=norm(t1-[xt(i);yt(i)]); | ||||||
|  | end | ||||||
|  | thetat=zeros(nn,1); | ||||||
|  | for i=2:nn | ||||||
|  | detx=xt(i)-xt(i-1); | ||||||
|  | dety=yt(i)-yt(i-1); | ||||||
|  | thetat(i)=atan2d(detx,dety); | ||||||
|  | end | ||||||
|  | % Uwb.x=x_uwb; | ||||||
|  | % Uwb.y=y_uwb; | ||||||
|  | % Uwb.alpha=theta_uwb; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | % 角速度校准 | ||||||
|  | detW = mean(wZ(1:200)); | ||||||
|  | wZ = wZ - detW; | ||||||
|  | 
 | ||||||
|  | x_imu(1) = 0;  | ||||||
|  | y_imu(1) = 0; | ||||||
|  | Z=zeros(3,1); | ||||||
|  | WW = 0.05; | ||||||
|  | theta_imu(1) = 0; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | %%  EKF | ||||||
|  | KK = zeros(5,3); | ||||||
|  | 
 | ||||||
|  | %% | ||||||
|  | %%AEKF | ||||||
|  | R = diag([1 1 1]); | ||||||
|  | % qq = 50; | ||||||
|  | % qq = 10; | ||||||
|  | qq = 0.01; | ||||||
|  | Q = diag([qq qq qq qq qq]); | ||||||
|  | P0 = diag([0 0 0 0 0]); | ||||||
|  | H = [1 0 0 0 0; | ||||||
|  |      0 1 0 0 0; | ||||||
|  |      0 0 0 1 0]; | ||||||
|  | X_aekf = zeros(5,nn); | ||||||
|  | X_aekf(:,1) = [imuPosX(1);imuPosY(1);vXY(1)*100;0;wZ(1)]; | ||||||
|  | I = eye(5); | ||||||
|  | JF = zeros(5,5); | ||||||
|  | X_pre = zeros(5,nn); | ||||||
|  | alfa = 0.97; | ||||||
|  | 
 | ||||||
|  | windowlength=5; | ||||||
|  | x_aekf_sw=zeros(1,nn); | ||||||
|  | y_aekf_sw=zeros(1,nn); | ||||||
|  | for i=2:nn | ||||||
|  |     detImuTime = imuDataRxTime(i) - imuDataRxTime(i-1); | ||||||
|  |     detOdomTime = odomDataRxTime(i)-odomDataRxTime(i-1); | ||||||
|  |     w = wZ(i); | ||||||
|  |     v = vXY(i)*100; | ||||||
|  |     detV=(vXY(i)-vXY(i-1))*100; | ||||||
|  |     detD = v*detImuTime;  | ||||||
|  |     detTheta = w*180/pi*detImuTime; | ||||||
|  |     detW = w-wZ(i-1); | ||||||
|  |     theta_imu(i) = theta_imu(i-1)+detTheta; | ||||||
|  |     theta_imu(i) = mod(theta_imu(i)+180,360)-180; | ||||||
|  |     F = [1 0 detImuTime*cosd(X_aekf(4,i-1)) 0 0; | ||||||
|  |          0 1 detImuTime*sind(X_aekf(4,i-1)) 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0;]; | ||||||
|  |       | ||||||
|  |     if w<WW | ||||||
|  |         vtx = detD*cosd(theta_imu(i)); | ||||||
|  |         vty = detD*sind(theta_imu(i)); | ||||||
|  |     else | ||||||
|  |         vtx = v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |         vty = v/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1)));            | ||||||
|  |     end | ||||||
|  |      | ||||||
|  |     x_imu(i) = x_imu(i-1)+vtx;  | ||||||
|  |     y_imu(i) = y_imu(i-1)+vty; | ||||||
|  |     X_next = [vtx;vty;detV;detTheta;detW]; | ||||||
|  |      | ||||||
|  |     if (x_uwb(i) == x_uwb(i-1))&&(y_uwb(i) == y_uwb(i-1)) | ||||||
|  |         X_aekf(:,i) = X_aekf(:,i-1)+X_next; | ||||||
|  |         errAEKf(i) = norm(X_aekf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |         theta_aekf(i) = X_aekf(4,i); | ||||||
|  |         continue | ||||||
|  |     end     | ||||||
|  |     if w<WW | ||||||
|  |         X_pre(:,i) = X_aekf(:,i-1)+X_next; | ||||||
|  |         Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |         P = F*P0*F'+Q; | ||||||
|  |         Kg = P*H'*inv(H*P*H'+R); | ||||||
|  |         KK(1,1) = Kg(1,1); | ||||||
|  |         KK(2,2) = Kg(2,2); | ||||||
|  |         KK(4,3) = Kg(4,3); | ||||||
|  |         X_aekf(:,i) = X_pre(:,i)+KK*(Z-H*X_pre(:,i)); | ||||||
|  |         P0 = (I-Kg*H)*P; | ||||||
|  |     else | ||||||
|  |         JF = [1 0 1/w*(sind(theta_imu(i))-sind(theta_imu(i-1))) v/w*(cosd(theta_imu(i))-cosd(theta_imu(i-1))) detD/w*cosd(theta_imu(i))-v/(w^2)*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |              0 1 1/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1))) v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))) detD/w*sind(theta_imu(i))-v/(w^2)*(-cosd(theta_imu(i))+cosd(theta_imu(i-1))); | ||||||
|  |              0 0 1 0 0; | ||||||
|  |              0 0 0 1 detImuTime; | ||||||
|  |              0 0 0 0 1]; | ||||||
|  |         X_pre(:,i) = X_aekf(:,i-1)+X_next; | ||||||
|  |         dk = Z - H*X_pre(:,i); | ||||||
|  |         Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |         P = JF*P0*JF'+Q; | ||||||
|  |         Kg = P*H'*inv(H*P*H'+R); | ||||||
|  |         KK(1,1) = Kg(1,1); | ||||||
|  |         KK(2,2) = Kg(2,2); | ||||||
|  |         KK(4,3) = Kg(4,3); | ||||||
|  |         X_aekf(:,i) = X_pre(:,i)+KK*(Z-H*X_pre(:,i)); | ||||||
|  |         epz = Z-H*X_aekf(:,i); | ||||||
|  |         R=alfa*R+(1-alfa)*(epz*epz'+H*P*H'); | ||||||
|  |         Q=alfa*Q+(1-alfa)*Kg*dk*dk'*Kg'; | ||||||
|  |         P0 = (I-Kg*H)*P; | ||||||
|  |     end | ||||||
|  |     errAEKf(i) = norm(X_aekf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |     theta_aekf(i) = X_aekf(4,i); | ||||||
|  |     % if errAEKf(i)>15 | ||||||
|  |     %     xxx = 1; | ||||||
|  |     % end | ||||||
|  | end | ||||||
|  | errAEKf_sw=zeros(1,nn); | ||||||
|  | weightedvector=[0.3;0.25;0.2;0.15;0.1]; | ||||||
|  | for i=1:nn | ||||||
|  | if i>windowlength-1 | ||||||
|  |     x_win=X_aekf(1,i-windowlength+1:i); | ||||||
|  |     y_win=X_aekf(2,i-windowlength+1:i); | ||||||
|  |     x_aekf_sw(i)=x_win*weightedvector; | ||||||
|  |     y_aekf_sw(i)=y_win*weightedvector; | ||||||
|  | else  | ||||||
|  |     x_aekf_sw(i)=X_aekf(1,i); | ||||||
|  |     y_aekf_sw(i)=X_aekf(2,i); | ||||||
|  | end | ||||||
|  | errAEKf_sw(i) = norm([x_aekf_sw(i);y_aekf_sw(i)]-[xt(i);yt(i)]); | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | figure; | ||||||
|  | plot(errAEKf_sw); | ||||||
|  | figure; | ||||||
|  | plot(x_imu,y_imu,xt,yt); | ||||||
|  | mean(errAEKf_sw) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										342
									
								
								Code/Matlab/AOA-IMU/script_ekf.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								Code/Matlab/AOA-IMU/script_ekf.m
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,342 @@ | |||||||
|  | clear | ||||||
|  | clc | ||||||
|  | close all | ||||||
|  | load('data1.mat'); | ||||||
|  | nn = size(imuPosX,1); | ||||||
|  | %% lightHouse坐标系转换 | ||||||
|  | x =  lightHousePosX * 100; | ||||||
|  | y = -lightHousePosZ * 100; | ||||||
|  | 
 | ||||||
|  | % 定义误差函数,即均方根误差 | ||||||
|  | errorFunction = @(params) sqrt(mean((x(1:500) * cos(params(1)) - y(1:500) * sin(params(1)) + params(2) - imuPosX(1:500)).^2 + (x(1:500) * sin(params(1)) + y(1:500) * cos(params(1)) + params(3) - imuPosY(1:500)).^2)); | ||||||
|  | 
 | ||||||
|  | % 使用 fminsearch 优化误差函数,找到使误差最小的旋转角和位移 | ||||||
|  | initialGuess = [0, 10, 10]; % 初始猜测值,[旋转角, 位移] | ||||||
|  | optimizedParams = fminsearch(errorFunction, initialGuess); | ||||||
|  | 
 | ||||||
|  | % 输出优化后的旋转角和位移 | ||||||
|  | rotationAngle = optimizedParams(1); | ||||||
|  | xOffset = optimizedParams(2); | ||||||
|  | yOffset = optimizedParams(3); | ||||||
|  | % 旋转坐标 | ||||||
|  | xt = x * cos(rotationAngle) - y * sin(rotationAngle) + xOffset; | ||||||
|  | yt = x * sin(rotationAngle) + y * cos(rotationAngle) + yOffset; | ||||||
|  | %% | ||||||
|  | tagN = 4; | ||||||
|  | %标签坐标 | ||||||
|  | XN(:,1)=[-300;-300]; | ||||||
|  | XN(:,2)=[-300;300]; | ||||||
|  | XN(:,3)=[300;300]; | ||||||
|  | XN(:,4)=[300;-300]; | ||||||
|  | sim2=6; | ||||||
|  | Q=diag(repmat(sim2,1,2*tagN));%协方差矩阵 | ||||||
|  | measure_AOA = zeros(4,nn); | ||||||
|  | measure_d = zeros(4,nn); | ||||||
|  | measure_AOA(1,:) = aoa1'; | ||||||
|  | measure_AOA(2,:) = aoa2'; | ||||||
|  | measure_AOA(3,:) = aoa3'; | ||||||
|  | measure_AOA(4,:) = aoa4'; | ||||||
|  | measure_d(1,:) = d1'; | ||||||
|  | measure_d(2,:) = d2'; | ||||||
|  | measure_d(3,:) = d3'; | ||||||
|  | measure_d(4,:) = d4'; | ||||||
|  | %% uwb解算 | ||||||
|  | x_uwb(1) = 0; | ||||||
|  | y_uwb(1) = 0; | ||||||
|  | theta_uwb=zeros(nn,1); | ||||||
|  | for i=2:nn | ||||||
|  |     if measure_d(1,i) == 0 | ||||||
|  |         x_uwb(i) = x_uwb(i-1); | ||||||
|  |         y_uwb(i) = y_uwb(i-1);         | ||||||
|  |         continue; | ||||||
|  |     end | ||||||
|  |     [t1,theta] = WLS(XN,measure_AOA(:,i),measure_d(:,i),Q); | ||||||
|  |     x_uwb(i) = t1(1); | ||||||
|  |     y_uwb(i) = t1(2); | ||||||
|  |     theta_uwb(i) = 90-theta; | ||||||
|  |     theta_uwb(i) = mod(theta_uwb(i)+180,360)-180; | ||||||
|  |     derr_WLS(i)=norm(t1-[xt(i);yt(i)]); | ||||||
|  | end | ||||||
|  | thetat=zeros(nn,1); | ||||||
|  | for i=2:nn | ||||||
|  | detx=xt(i)-xt(i-1); | ||||||
|  | dety=yt(i)-yt(i-1); | ||||||
|  | thetat(i)=atan2d(detx,dety); | ||||||
|  | end | ||||||
|  | % Uwb.x=x_uwb; | ||||||
|  | % Uwb.y=y_uwb; | ||||||
|  | % Uwb.alpha=theta_uwb; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | % 角速度校准 | ||||||
|  | detW = mean(wZ(1:200)); | ||||||
|  | wZ = wZ - detW; | ||||||
|  | 
 | ||||||
|  | x_imu(1) = 0;  | ||||||
|  | y_imu(1) = 0; | ||||||
|  | Z=zeros(3,1); | ||||||
|  | WW = 0.05; | ||||||
|  | theta_imu(1) = 0; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | %  | ||||||
|  | % Imu.x=x_imu; | ||||||
|  | % Imu.y=y_imu; | ||||||
|  | % Imu.v=v_imu; | ||||||
|  | % Imu.alpha=alpha_imu; | ||||||
|  | % Imu.omega=omega_imu; | ||||||
|  | 
 | ||||||
|  | %%  KF | ||||||
|  | R = diag([1 1 1]); | ||||||
|  | % qq = 1; | ||||||
|  | qq = 0.00001; | ||||||
|  | Q1 = diag([qq qq qq qq qq]); | ||||||
|  | P0 = diag([0 0 0 0 0]); | ||||||
|  | H = [1 0 0 0 0; | ||||||
|  |     0 1 0 0 0; | ||||||
|  |     0 0 0 1 0]; | ||||||
|  | I = eye(5); | ||||||
|  | JF = zeros(5,5); | ||||||
|  | X_pre = zeros(5,nn); | ||||||
|  | X_kf(:,1) = [imuPosX(1);imuPosY(1);vXY(1)*100;0;wZ(1)]; | ||||||
|  | for i=2:nn | ||||||
|  |     % 计算IMU和里程计的时间差值 | ||||||
|  |     detImuTime = imuDataRxTime(i) - imuDataRxTime(i-1); | ||||||
|  |     detOdomTime = odomDataRxTime(i)-odomDataRxTime(i-1); | ||||||
|  |     % 获得此时Z轴角速度 | ||||||
|  |     w = wZ(i); | ||||||
|  |     % 获得小车的水平速度 | ||||||
|  |     v = vXY(i)*100; | ||||||
|  |     % 计算速度增量 | ||||||
|  |     detV=(vXY(i)-vXY(i-1))*100; | ||||||
|  |     % 计算位置增量 | ||||||
|  |     detD = v*detImuTime;  | ||||||
|  |     % 计算角度增量 | ||||||
|  |     detTheta = w*180/pi*detImuTime; | ||||||
|  |     % 计算角速度的变化量 | ||||||
|  |     detW = w-wZ(i-1); | ||||||
|  |     % 积分计算IMU的航位角 | ||||||
|  |     theta_imu(i) = theta_imu(i-1)+detTheta; | ||||||
|  |     % 航向约束 | ||||||
|  |     theta_imu(i) = mod(theta_imu(i)+180,360)-180; | ||||||
|  |      | ||||||
|  |     % 状态更新方程 | ||||||
|  |     F = [1 0 detImuTime*cosd(X_kf(4,i-1)) 0 0; | ||||||
|  |          0 1 detImuTime*sind(X_kf(4,i-1)) 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0;]; | ||||||
|  |     % 获得水平和垂直方向的位置增量 | ||||||
|  |     vtx = detD*cosd(theta_imu(i)); | ||||||
|  |     vty = detD*sind(theta_imu(i)); | ||||||
|  | 
 | ||||||
|  |     x_imu(i) = x_imu(i-1)+vtx;  | ||||||
|  |     y_imu(i) = y_imu(i-1)+vty; | ||||||
|  | 
 | ||||||
|  |     X_next = [vtx;vty;detV;detTheta;detW]; | ||||||
|  |     if (x_uwb(i) == x_uwb(i-1))&&(y_uwb(i) == y_uwb(i-1)) | ||||||
|  |         X_kf(:,i) = X_kf(:,i-1)+X_next; | ||||||
|  |         errKf(i) = norm(X_kf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |         theta_kf(i) = X_kf(4,i); | ||||||
|  |         continue | ||||||
|  |     end     | ||||||
|  |     X_pre(:,i) = X_kf(:,i-1)+X_next; | ||||||
|  |     Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |     P = F*P0*F'+Q1; | ||||||
|  |     Kg_kf = P*H'*inv(H*P*H'+R); | ||||||
|  |     X_kf(:,i) = X_pre(:,i)+Kg_kf*(Z-H*X_pre(:,i)); | ||||||
|  |     P0 = (I-Kg_kf*H)*P; | ||||||
|  | 
 | ||||||
|  |     errKf(i) = norm(X_kf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |     theta_kf(i) = X_kf(4,i); | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | %%  EKF | ||||||
|  | R = diag([1 1 1]); | ||||||
|  | % qq = 1; | ||||||
|  | qq = 0.00001; | ||||||
|  | Q1 = diag([qq qq qq qq qq]); | ||||||
|  | P0 = diag([0 0 0 0 0]); | ||||||
|  | H = [1 0 0 0 0; | ||||||
|  |     0 1 0 0 0; | ||||||
|  |     0 0 0 1 0]; | ||||||
|  | KK = zeros(5,3); | ||||||
|  | X_ekf(:,1) = [imuPosX(1);imuPosY(1);vXY(1)*100;0;wZ(1)]; | ||||||
|  | I = eye(5); | ||||||
|  | JF = zeros(5,5); | ||||||
|  | X_pre = zeros(5,nn); | ||||||
|  | 
 | ||||||
|  | for i=2:nn | ||||||
|  |     detImuTime = imuDataRxTime(i) - imuDataRxTime(i-1); | ||||||
|  |     detOdomTime = odomDataRxTime(i)-odomDataRxTime(i-1); | ||||||
|  |     w = wZ(i); | ||||||
|  |     v = vXY(i)*100; | ||||||
|  |     detV=(vXY(i)-vXY(i-1))*100; | ||||||
|  |     detD = v*detImuTime;  | ||||||
|  |     detTheta = w*180/pi*detImuTime; | ||||||
|  |     detW = w-wZ(i-1); | ||||||
|  |     theta_imu(i) = theta_imu(i-1)+detTheta; | ||||||
|  |     theta_imu(i) = mod(theta_imu(i)+180,360)-180; | ||||||
|  |     F = [1 0 detImuTime*cosd(X_ekf(4,i-1)) 0 0; | ||||||
|  |          0 1 detImuTime*sind(X_ekf(4,i-1)) 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0;]; | ||||||
|  |     if w<WW | ||||||
|  |         vtx = detD*cosd(theta_imu(i)); | ||||||
|  |         vty = detD*sind(theta_imu(i)); | ||||||
|  |     else | ||||||
|  |         vtx = v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |         vty = v/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1)));            | ||||||
|  |     end | ||||||
|  |     x_imu(i) = x_imu(i-1)+vtx;  | ||||||
|  |     y_imu(i) = y_imu(i-1)+vty; | ||||||
|  |     errUwb(i) = norm([x_uwb(i);y_uwb(i)]-[xt(i);yt(i)]); | ||||||
|  |     errImu(i) = norm([x_imu(i);y_imu(i)]-[xt(i);yt(i)]); | ||||||
|  |     X_next = [vtx;vty;detV;detTheta;detW]; | ||||||
|  |     if (x_uwb(i) == x_uwb(i-1))&&(y_uwb(i) == y_uwb(i-1)) | ||||||
|  |         X_ekf(:,i) = X_ekf(:,i-1)+X_next; | ||||||
|  |         errEKf(i) = norm(X_ekf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |         theta_ekf(i) = X_ekf(4,i); | ||||||
|  |         continue | ||||||
|  |     end     | ||||||
|  |     if w<WW | ||||||
|  |         X_pre(:,i) = X_ekf(:,i-1)+X_next; | ||||||
|  |         Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |         P = F*P0*F'+Q1; | ||||||
|  |         Kg = P*H'*inv(H*P*H'+R); | ||||||
|  |         X_ekf(:,i) = X_pre(:,i)+Kg*(Z-H*X_pre(:,i)); | ||||||
|  |         P0 = (I-Kg*H)*P; | ||||||
|  |     else | ||||||
|  |         JF = [1 0 1/w*(sind(theta_imu(i))-sind(theta_imu(i-1))) v/w*(cosd(theta_imu(i))-cosd(theta_imu(i-1))) detD/w*cosd(theta_imu(i))-v/(w^2)*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |              0 1 1/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1))) v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))) detD/w*sind(theta_imu(i))-v/(w^2)*(-cosd(theta_imu(i))+cosd(theta_imu(i-1))); | ||||||
|  |              0 0 1 0 0; | ||||||
|  |              0 0 0 1 detImuTime; | ||||||
|  |              0 0 0 0 1]; | ||||||
|  | 
 | ||||||
|  |         X_pre(:,i) = X_ekf(:,i-1)+X_next; | ||||||
|  |         Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |         P = JF*P0*JF'+Q1; | ||||||
|  |         Kg = P*H'*inv(H*P*H'+R); | ||||||
|  |         X_ekf(:,i) = X_pre(:,i)+Kg*(Z-H*X_pre(:,i)); | ||||||
|  |         P0 = (I-Kg*H)*P; | ||||||
|  |     end | ||||||
|  |     errEKf(i) = norm(X_ekf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |     theta_ekf(i) = X_ekf(4,i); | ||||||
|  | end | ||||||
|  | %%  UKF | ||||||
|  | % UKF settings | ||||||
|  | ukf_L = 5; %numer of states | ||||||
|  | ukf_m = 3; %numer of measurements | ||||||
|  | ukf_kappa = 3 - ukf_L; | ||||||
|  | ukf_alpha = 0.9; | ||||||
|  | ukf_beta = 2; | ||||||
|  | 
 | ||||||
|  | ukf_lambda = ukf_alpha^2*(ukf_L + ukf_kappa) - ukf_L; | ||||||
|  | ukf_gamma = sqrt(ukf_L + ukf_lambda); | ||||||
|  | ukf_W0_c = ukf_lambda / (ukf_L + ukf_lambda) + (1 - ukf_alpha^2 + ukf_beta); | ||||||
|  | ukf_W0_m = ukf_lambda / (ukf_L + ukf_lambda); | ||||||
|  | ukf_Wi_m = 1 / (2*(ukf_L + ukf_lambda)); | ||||||
|  | ukf_Wi_c = ukf_Wi_m; | ||||||
|  | 
 | ||||||
|  | q=0.01;    %std of process  | ||||||
|  | r=5;    %std of measurement | ||||||
|  | p=2; | ||||||
|  | Qu=q*eye(ukf_L); % std matrix of process | ||||||
|  | Ru=r*eye(ukf_m);        % std of measurement  | ||||||
|  | Pu=p*eye(ukf_L); | ||||||
|  | H = [1 0 0 0 0; | ||||||
|  |      0 1 0 0 0; | ||||||
|  |      0 0 0 1 0]; | ||||||
|  | X_ukf(:,1) = [imuPosX(1);imuPosY(1);vXY(1)*100;0;wZ(1)]; | ||||||
|  | I = eye(5); | ||||||
|  | JF = zeros(5,5); | ||||||
|  | X_pre = zeros(5,nn); | ||||||
|  | for i=2:nn | ||||||
|  |     detImuTime = imuDataRxTime(i) - imuDataRxTime(i-1); | ||||||
|  |     detOdomTime = odomDataRxTime(i)-odomDataRxTime(i-1); | ||||||
|  |     w = wZ(i); | ||||||
|  |     v = vXY(i)*100; | ||||||
|  |     detV=(vXY(i)-vXY(i-1))*100; | ||||||
|  |     detD = v*detImuTime;  | ||||||
|  |     detTheta = w*180/pi*detImuTime; | ||||||
|  |     detW = w-wZ(i-1); | ||||||
|  |     theta_imu(i) = theta_imu(i-1)+detTheta; | ||||||
|  |     theta_imu(i) = mod(theta_imu(i)+180,360)-180; | ||||||
|  |     % F = [1 0 detImuTime*cosd(X_ekf(4,i-1)) 0 0; | ||||||
|  |     %      0 1 detImuTime*sind(X_ekf(4,i-1)) 0 0; | ||||||
|  |     %      0 0 0 0 0; | ||||||
|  |     %      0 0 0 0 0; | ||||||
|  |     %      0 0 0 0 0;]; | ||||||
|  |     if w<WW | ||||||
|  |         vtx = detD*cosd(theta_imu(i)); | ||||||
|  |         vty = detD*sind(theta_imu(i)); | ||||||
|  |     else | ||||||
|  |         vtx = v/w*(sind(theta_imu(i))-sind(theta_imu(i-1))); | ||||||
|  |         vty = v/w*(-cosd(theta_imu(i))+cosd(theta_imu(i-1)));            | ||||||
|  |     end | ||||||
|  |     x_imu(i) = x_imu(i-1)+vtx;  | ||||||
|  |     y_imu(i) = y_imu(i-1)+vty; | ||||||
|  |     errUwb(i) = norm([x_uwb(i);y_uwb(i)]-[xt(i);yt(i)]); | ||||||
|  |     errImu(i) = norm([x_imu(i);y_imu(i)]-[xt(i);yt(i)]); | ||||||
|  |     X_next = [vtx;vty;detV;detTheta;detW]; | ||||||
|  |     if (x_uwb(i) == x_uwb(i-1))&&(y_uwb(i) == y_uwb(i-1)) | ||||||
|  |         X_ukf(:,i) = X_ukf(:,i-1)+X_next; | ||||||
|  |         errUKf(i) = norm(X_ukf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |         theta_ukf(i) = X_ukf(4,i); | ||||||
|  |         continue | ||||||
|  |     end     | ||||||
|  | 
 | ||||||
|  |     xestimate = X_ukf(:,i-1); | ||||||
|  |     Xx = repmat(xestimate, 1, length(xestimate)); | ||||||
|  |     Xsigma = [xestimate, ( Xx + ukf_gamma * Pu ), ( Xx - ukf_gamma * Pu )]; | ||||||
|  |      | ||||||
|  |     %第二步:对Sigma点集进行一步预测 | ||||||
|  |     [Xsigmapre]=fun1(Xsigma,detImuTime); | ||||||
|  |     %第三步:估计预测状态 | ||||||
|  |     Xpred = ukf_W0_m * Xsigmapre(:,1) + ukf_Wi_m * sum(Xsigmapre(:,2:end), 2); | ||||||
|  |     %第四步:均值和方差 | ||||||
|  |       Xx = repmat(Xpred, 1, length(xestimate)*2); | ||||||
|  |      [~, R] = qr([sqrt(ukf_Wi_c) * ( Xsigmapre(:,2:end) - Xx ), Qu]', 0); | ||||||
|  |      Ppred = cholupdate(R, sqrt(ukf_W0_c) * (Xsigmapre(:,1) - Xpred), '-')'; | ||||||
|  | 
 | ||||||
|  |     %第5步:根据预测值,再一次使用UT变换,得到新的sigma点集 | ||||||
|  |     Xx = repmat(Xpred, 1, length(xestimate)); | ||||||
|  |     Xsigmapre = [Xpred, ( Xx + ukf_gamma * Ppred ), ( Xx - ukf_gamma * Ppred )]; | ||||||
|  | 
 | ||||||
|  |     %第6步:观测预测 | ||||||
|  |     Zsigmapre=H*Xsigmapre; | ||||||
|  | 
 | ||||||
|  |     %第7步:计算观测预测均值和协方差 | ||||||
|  |     Zpred = ukf_W0_m * Zsigmapre(:,1) + ukf_Wi_m * sum(Zsigmapre(:,2:end), 2); | ||||||
|  | 
 | ||||||
|  |     Yy = repmat(Zpred, 1, length(xestimate)*2); | ||||||
|  |     [~, Rz] = qr([sqrt(ukf_Wi_c) * (Zsigmapre(:,2:end) - Yy), Ru]', 0); | ||||||
|  |     Pzz = cholupdate(Rz, sqrt(ukf_W0_c) * (Zsigmapre(:,1) - Zpred), '-')'; | ||||||
|  | 
 | ||||||
|  |     Xd = Xsigmapre - repmat(Xpred, 1, length(xestimate)*2 + 1); | ||||||
|  |     Zd = Zsigmapre - repmat(Zpred, 1, length(xestimate)*2 + 1); | ||||||
|  |    | ||||||
|  |     Pxz = ( ukf_W0_c*  Xd(:,1) * Zd(:,1)' ) + ( ukf_Wi_c * Xd(:,2:end) * Zd(:,2:end)' ); | ||||||
|  | 
 | ||||||
|  |     %第七步:计算kalman增益 | ||||||
|  |     Kukf= (Pxz / Pzz') / Pzz; | ||||||
|  |     %第八步:状态和方差更新 | ||||||
|  |     Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |     Xpred=Xpred+Kukf*(Z-Zpred); | ||||||
|  |     U = Kukf * Pzz; | ||||||
|  |     Rp = Ppred'; | ||||||
|  |     for ii=1:size(U, 2) | ||||||
|  |         Rp = cholupdate(Rp, U(:,ii), '-'); | ||||||
|  |     end | ||||||
|  |     Ppred = Rp'; | ||||||
|  |     X_ukf(:,i)=Xpred; | ||||||
|  | 
 | ||||||
|  |     errUKf(i) = norm(X_ukf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |     theta_ukf(i) = X_ukf(4,i); | ||||||
|  | end | ||||||
|  | plot(errUKf); | ||||||
|  | mean(errUKf) | ||||||
							
								
								
									
										155
									
								
								Code/Matlab/AOA-IMU/script_kf.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								Code/Matlab/AOA-IMU/script_kf.m
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,155 @@ | |||||||
|  | clear | ||||||
|  | clc | ||||||
|  | close all | ||||||
|  | load('data1.mat'); | ||||||
|  | nn = size(imuPosX,1); | ||||||
|  | %% lightHouse坐标系转换 | ||||||
|  | x =  lightHousePosX * 100; | ||||||
|  | y = -lightHousePosZ * 100; | ||||||
|  | 
 | ||||||
|  | % 定义误差函数,即均方根误差 | ||||||
|  | errorFunction = @(params) sqrt(mean((x(1:500) * cos(params(1)) - y(1:500) * sin(params(1)) + params(2) - imuPosX(1:500)).^2 + (x(1:500) * sin(params(1)) + y(1:500) * cos(params(1)) + params(3) - imuPosY(1:500)).^2)); | ||||||
|  | 
 | ||||||
|  | % 使用 fminsearch 优化误差函数,找到使误差最小的旋转角和位移 | ||||||
|  | initialGuess = [0, 10, 10]; % 初始猜测值,[旋转角, 位移] | ||||||
|  | optimizedParams = fminsearch(errorFunction, initialGuess); | ||||||
|  | 
 | ||||||
|  | % 输出优化后的旋转角和位移 | ||||||
|  | rotationAngle = optimizedParams(1); | ||||||
|  | xOffset = optimizedParams(2); | ||||||
|  | yOffset = optimizedParams(3); | ||||||
|  | % 旋转坐标 | ||||||
|  | xt = x * cos(rotationAngle) - y * sin(rotationAngle) + xOffset; | ||||||
|  | yt = x * sin(rotationAngle) + y * cos(rotationAngle) + yOffset; | ||||||
|  | %% | ||||||
|  | tagN = 4; | ||||||
|  | %标签坐标 | ||||||
|  | XN(:,1)=[-300;-300]; | ||||||
|  | XN(:,2)=[-300;300]; | ||||||
|  | XN(:,3)=[300;300]; | ||||||
|  | XN(:,4)=[300;-300]; | ||||||
|  | sim2=6; | ||||||
|  | Q=diag(repmat(sim2,1,2*tagN));%协方差矩阵 | ||||||
|  | measure_AOA = zeros(4,nn); | ||||||
|  | measure_d = zeros(4,nn); | ||||||
|  | measure_AOA(1,:) = aoa1'; | ||||||
|  | measure_AOA(2,:) = aoa2'; | ||||||
|  | measure_AOA(3,:) = aoa3'; | ||||||
|  | measure_AOA(4,:) = aoa4'; | ||||||
|  | measure_d(1,:) = d1'; | ||||||
|  | measure_d(2,:) = d2'; | ||||||
|  | measure_d(3,:) = d3'; | ||||||
|  | measure_d(4,:) = d4'; | ||||||
|  | %% uwb解算 | ||||||
|  | x_uwb(1) = 0; | ||||||
|  | y_uwb(1) = 0; | ||||||
|  | theta_uwb=zeros(nn,1); | ||||||
|  | for i=2:nn | ||||||
|  |     if measure_d(1,i) == 0 | ||||||
|  |         x_uwb(i) = x_uwb(i-1); | ||||||
|  |         y_uwb(i) = y_uwb(i-1);         | ||||||
|  |         continue; | ||||||
|  |     end | ||||||
|  |     [t1,theta] = WLS(XN,measure_AOA(:,i),measure_d(:,i),Q); | ||||||
|  |     x_uwb(i) = t1(1); | ||||||
|  |     y_uwb(i) = t1(2); | ||||||
|  |     theta_uwb(i) = 90-theta; | ||||||
|  |     theta_uwb(i) = mod(theta_uwb(i)+180,360)-180; | ||||||
|  |     derr_WLS(i)=norm(t1-[xt(i);yt(i)]); | ||||||
|  | end | ||||||
|  | thetat=zeros(nn,1); | ||||||
|  | for i=2:nn | ||||||
|  | detx=xt(i)-xt(i-1); | ||||||
|  | dety=yt(i)-yt(i-1); | ||||||
|  | thetat(i)=atan2d(detx,dety); | ||||||
|  | end | ||||||
|  | % Uwb.x=x_uwb; | ||||||
|  | % Uwb.y=y_uwb; | ||||||
|  | % Uwb.alpha=theta_uwb; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | % 角速度校准 | ||||||
|  | detW = mean(wZ(1:200)); | ||||||
|  | wZ = wZ - detW; | ||||||
|  | 
 | ||||||
|  | x_imu(1) = 0;  | ||||||
|  | y_imu(1) = 0; | ||||||
|  | Z=zeros(3,1); | ||||||
|  | WW = 0.05; | ||||||
|  | theta_imu(1) = 0; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | %  | ||||||
|  | % Imu.x=x_imu; | ||||||
|  | % Imu.y=y_imu; | ||||||
|  | % Imu.v=v_imu; | ||||||
|  | % Imu.alpha=alpha_imu; | ||||||
|  | % Imu.omega=omega_imu; | ||||||
|  | 
 | ||||||
|  | %%  KF | ||||||
|  | R = diag([1 1 1]); | ||||||
|  | % qq = 1; | ||||||
|  | qq = 0.005; | ||||||
|  | Q1 = diag([qq qq qq qq qq]); | ||||||
|  | P0 = diag([0 0 0 0 0]); | ||||||
|  | H = [1 0 0 0 0; | ||||||
|  |     0 1 0 0 0; | ||||||
|  |     0 0 0 1 0]; | ||||||
|  | I = eye(5); | ||||||
|  | JF = zeros(5,5); | ||||||
|  | X_pre = zeros(5,nn); | ||||||
|  | X_kf(:,1) = [imuPosX(1);imuPosY(1);vXY(1)*100;0;wZ(1)]; | ||||||
|  | for i=2:nn | ||||||
|  |     % 计算IMU和里程计的时间差值 | ||||||
|  |     detImuTime = imuDataRxTime(i) - imuDataRxTime(i-1); | ||||||
|  |     detOdomTime = odomDataRxTime(i)-odomDataRxTime(i-1); | ||||||
|  |     % 获得此时Z轴角速度 | ||||||
|  |     w = wZ(i); | ||||||
|  |     % 获得小车的水平速度 | ||||||
|  |     v = vXY(i)*100; | ||||||
|  |     % 计算速度增量 | ||||||
|  |     detV=(vXY(i)-vXY(i-1))*100; | ||||||
|  |     % 计算位置增量 | ||||||
|  |     detD = v*detImuTime;  | ||||||
|  |     % 计算角度增量 | ||||||
|  |     detTheta = w*180/pi*detImuTime; | ||||||
|  |     % 计算角速度的变化量 | ||||||
|  |     detW = w-wZ(i-1); | ||||||
|  |     % 积分计算IMU的航位角 | ||||||
|  |     theta_imu(i) = theta_imu(i-1)+detTheta; | ||||||
|  |     % 航向约束 | ||||||
|  |     theta_imu(i) = mod(theta_imu(i)+180,360)-180; | ||||||
|  |      | ||||||
|  |     % 状态更新方程 | ||||||
|  |     F = [1 0 detImuTime*cosd(X_kf(4,i-1)) 0 0; | ||||||
|  |          0 1 detImuTime*sind(X_kf(4,i-1)) 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0; | ||||||
|  |          0 0 0 0 0;]; | ||||||
|  |     % 获得水平和垂直方向的位置增量 | ||||||
|  |     vtx = detD*cosd(theta_imu(i)); | ||||||
|  |     vty = detD*sind(theta_imu(i)); | ||||||
|  | 
 | ||||||
|  |     x_imu(i) = x_imu(i-1)+vtx;  | ||||||
|  |     y_imu(i) = y_imu(i-1)+vty; | ||||||
|  | 
 | ||||||
|  |     X_next = [vtx;vty;detV;detTheta;detW]; | ||||||
|  |     if (x_uwb(i) == x_uwb(i-1))&&(y_uwb(i) == y_uwb(i-1)) | ||||||
|  |         X_kf(:,i) = X_kf(:,i-1)+X_next; | ||||||
|  |         errKf(i) = norm(X_kf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |         theta_kf(i) = X_kf(4,i); | ||||||
|  |         continue | ||||||
|  |     end     | ||||||
|  |     X_pre(:,i) = X_kf(:,i-1)+X_next; | ||||||
|  |     % 观测矩阵: UWB的位置、UWB的航向角 | ||||||
|  |     Z = [x_uwb(i);y_uwb(i);theta_uwb(i)]; | ||||||
|  |     P = F*P0*F'+Q1; | ||||||
|  |     Kg_kf = P*H'*inv(H*P*H'+R); | ||||||
|  |     X_kf(:,i) = X_pre(:,i)+Kg_kf*(Z-H*X_pre(:,i)); | ||||||
|  |     P0 = (I-Kg_kf*H)*P; | ||||||
|  | 
 | ||||||
|  |     errKf(i) = norm(X_kf(1:2,i)-[xt(i);yt(i)]); | ||||||
|  |     theta_kf(i) = X_kf(4,i); | ||||||
|  | end | ||||||
|  | plot(errKf); | ||||||
|  | mean(errKf) | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user