2026a

# 使用 SyslabFunction 模块的雷达跟踪


模型路径为SyslabWorkspace.Examples.Demo_SyslabFunction_RadarTracking.RadarTracking

此示例说明如何将扩展 Kalman 滤波器与 SyslabFunction 模块结合使用,以根据雷达测量估计位置。扩展 Kalman 滤波器在SyslabFunction中实现。

Sysplorer 仿真结束后,在 Syslab 中对仿真结果进行分析,系统通过三个图显示以下信息:实际轨迹与估计轨迹的比较;范围的估计残差;以及实际位置、测量位置和估计位置。

其中,Julia 全局配置代码为:

using LinearAlgebra

# 定义全局变量,命名以 g_ 为前缀
g_P = zeros(4, 4)
g_xhat = [0.001; 0.01; 0.001; 400;;] # 4x1矩阵

扩展 Kalman 滤波函数的实现代码为:

function EXTKALMAN(meas, deltat, time)
    # 声明全局变量
    global g_P
    global g_xhat

    # Initialization
    residual = []
    xhatOut = []

    # Radar update time deltat is inherited from model workspace
    # 1. Compute Phi, Q, and R 
    Phi = [1 deltat 0 0; 0 1 0 0; 0 0 1 deltat; 0 0 0 1]
    Q = Diagonal([0, 0.005, 0, 0.005]) # 对应Matlab的diag
    R = Diagonal([300^2, 0.001^2])

    # 2. Propagate the covariance matrix:
    g_P = Phi * g_P * Phi' .+ Q

    # 3. Propagate the track estimate::
    g_xhat = Phi * g_xhat

    # 4 a). Compute observation estimates:
    Rangehat = sqrt(g_xhat[1]^2 + g_xhat[3]^2)
    Bearinghat = atan(g_xhat[3], g_xhat[1]) # 对应Matlab的atan2

    # 4 b). Compute observation vector y and linearized measurement matrix M 
    yhat = [Rangehat
        Bearinghat]
    M = [cos(Bearinghat) 0 sin(Bearinghat) 0
        -sin(Bearinghat)/Rangehat 0 cos(Bearinghat)/Rangehat 0]

    # 4 c).  Compute residual (Estimation Error)
    residual = meas .- yhat

    # 5. Compute Kalman Gain:
    W = g_P * M' * inv(M * g_P * M' .+ R)

    # 6. Update estimate
    g_xhat = g_xhat .+ W * residual

    # 7. Update Covariance Matrix
    g_P = (eye(4) .- W * M) * g_P * (eye(4) .- W * M)' .+ W * R * W'

    xhatOut = g_xhat

    # return residual, xhatOut
    return residual, xhatOut
end

function eye(n::Integer)
    return Int.(Matrix(I(n)))    
end

仿真结束后,系统将通过 ToWorkspace 组件将实际位置、测量位置、估计位置等仿真结果发送到 Syslab 工作区中,在 Syslab 中使用如下代码进行绘图分析:

using TyPlot
#从Sysplorer获取卡尔曼滤波结果
residual = out.residual
X_hat = out.xhatOut
XYCoords = out.XYCoords
PolarCoords = out.PolarCoords
Measurement_noise = out.Measurement_noise
deltat = 1

# 绘图1
figure(figsize=[11.25, 8.1])

margin = [ 0.075, 0.075, -0.1, -0.1 ];
pos = [ 0, 0.5, 0.33, 0.5 ];
axp = pos + margin;
ax = subplot(2, 2, 1, position=axp, projection="polar");
h = polarplot(ax, PolarCoords[:,2] .- Measurement_noise[:,2],
      PolarCoords[:,1] .- Measurement_noise[:,1], "r", linewidth=0.5)
ax.set_yticks([20000,40000])

hold("on")
rangehat = sqrt.(X_hat[:,1].^2 .+ X_hat[:,3].^2);
bearinghat = atan.(X_hat[:,3], X_hat[:,1]);
polarplot(ax, bearinghat,rangehat, color=[0,1,0],linewidth=0.5);
annotation("textbox", [0.1056,0.5378,0.1714,0.0584],
  string="Actual Trajectory (red)\nEstimated Trajectory (green)",
  fitboxtotext="on", edgecolor="none", ha="center")

#绘图2
margin = [ 0.08, 0.075, -0.05, -0.1 ];
pos = [ 0, 0, 0.33, 0.5 ];
axp = pos .+ margin;
ax = subplot(2,2,2, position=axp);
plot(ax, residual[:,1], linewidth=0.5);
grid("on");
xlim([0 length(residual[:,1])]);
xlabel(ax, "Number of Measurements");
ylabel(ax, "Range Estimate Error - Feet")
title(ax, "Estimation Residual for Range")

#绘图3
XYMeas = [PolarCoords[:,1].*cos.(PolarCoords[:,2]) PolarCoords[:,1].*sin.(PolarCoords[:,2])];
numTSteps = size(XYCoords)[1];
t_full    = 0.1 .* (0:numTSteps-1)';
t_hat     = (0:deltat:t_full[end])';

margin = [ 0.1, 0.05, -0.12, -0.1 ];
pos = [ 0.33, 0.5, 0.66, 0.5 ];
axp = pos .+ margin;
axesH = subplot(2,2,3, position=axp);
plot(axesH, t_full, XYCoords[:,2],"r", linewidth=0.5);
grid("on");
hold("on");
plot(axesH, t_full,XYMeas[:,2], color=[0,1,0]);
plot(axesH, t_hat,X_hat[:,3],"b");
title(axesH, "E-W Position");
legend(axesH, ["Actual","Meas","Est"],loc="northwest");
hold("off")

#绘图4
margin = [ 0.1, 0.075, -0.12, -0.1 ];
pos = [ 0.33, 0, 0.66, 0.5 ];
axp = pos .+ margin;
axesH = subplot(2,2,4, position=axp);
plot(axesH, t_full,XYCoords[:,1],"r");
grid("on");
hold("on");
plot(axesH, t_full,XYMeas[:,1],color=[0,1,0]);
plot(axesH, t_hat,X_hat[:,1],"b");
xlabel(axesH, "Time (sec)");
title(axesH, "N-S Position");
hold("off")


plot(t_full,XYCoords[:,1],"r");
grid("on");
hold("on");
plot(t_full,XYMeas[:,1],color=[0,1,0]);
plot(t_hat,X_hat[:,1],"b");
xlabel("Time (sec)");
title("N-S Position");
hold("off")

绘图结果为: