AnyMath 文档
Notebook

在控制列中距离的任务中,PD和PID控制器与防缠绕的比较。

立柱移动控制是智能交通系统领域的关键任务之一。 主要目标是确保相邻汽车之间具有设定距离的一组车辆的同步运动,最大限度地减少抽搐,消除车队内部超车并保证安全。 为了实现这一目标,每个被驱动的车辆都配备有一个控制器,该控制器根据关于前方车辆的位置和速度的信息来计算所需的加速度。 然而,实际条件–加速度和速度限制,通信信道延迟,测量噪声-使任务显着复杂化。 本文介绍了在Engee仿真环境下实现的列控制系统的两个模型:基于经典PD控制器的基本模型和使用PID控制器的改进模型。 在这个例子中,根据诸如保持距离的准确性,超车的存在和对扰动的抵抗等标准对它们的有效性进行比较分析。

简单模型(PD控制器)

基本版本使用经典的PD控制器。:

,

哪里( )-距离误差,

(D)-设定距离,

( )-速度误差。

该模型演示了并行构造的变体,其中奴隶努力占据相对于领导者的指定位置。 在模拟过程中,观察到对"Slave-1和Slave‑3"以及"Slave‑2和Slave‑4"同步排队—每对与领导者的距离相同。 由于不同的起始位置,您可以清楚地看到奴隶如何以不同的方式加速以达到所需的距离。

但是,当前的实现具有以下限制:

*如果存在恒定的外部干扰(例如,道路坡度或侧风),则系统会出现固定距离误差-从站无法准确保持设定距离。

*死区切断小控制信号。 再加上调节器中缺少一个组成部分,这导致了长期的位置漂移,并最终导致领导者的僚机超车。 因此,纯粹的PD控制器不能在长时间间隔内提供对距离的稳定跟踪。

从机的结构包括误差计算、信号放大、加法器、加速度限制单元和双积分器(速度→位置)。

image.png

所有从站都具有相同的架构并并行连接:来自领导者的信息直接进入每个从站,这导致形成成对的"Slave‑1和Slave‑3","Slave‑2和Slave‑4"同步移动。

image.png
In [ ]:
function run_model(name)
    p, is_loaded = joinpath(@__DIR__, name * ".engee"), name  [m.name for m in engee.get_all_models()]
    is_loaded && engee.load(p, force=true)
    out = engee.run(engee.open(name), verbose=true)
    is_loaded && engee.close(name, force=true)
    sleep(0.1); return out
end

initial_positions = [-10.0, -20.0, -30.0, -40.0] # 僚机相对于首领的初始位置
accel_limit_lower = -3.0   # 敏。 加速度,m/s2
accel_limit_upper =  3.0   # 麦克斯 加速度,m/s2
speed_limit_lower = 0.0    # 敏。 速度,m/s
speed_limit_upper = 15.0   # 麦克斯 速度,m/s

# PD控制器参数
D = 10.0          # 设定距离,m
Kp = 0.5          # 比例系数
Kd = 2.0          # 的微分系数

run_model("Platooning_Basic")
Building...
Progress 0%
Progress 100%
Progress 100%
Out[0]:
SimulationResult(
    run_id => 12,
    "奴隶-4。x" => WorkspaceArray{Float64}("Platooning_Basic/奴隶-4。x")
,
    "奴隶-1。x" => WorkspaceArray{Float64}("Platooning_Basic/Slave-1。x")
,
    "奴隶-2。v" => WorkspaceArray{Float64}("Platooning_Basic/Slave-2。v")
,
    "奴隶-3。v" => WorkspaceArray{Float64}("Platooning_Basic/奴隶-3。v")
,
    "领袖。X_0" => WorkspaceArray{Float64}("Platooning_Basic/领导者.X_0")
,
    "奴隶-1。v" => WorkspaceArray{Float64}("Platooning_Basic/Slave-1。v")
,
    "奴隶-3。x" => WorkspaceArray{Float64}("Platooning_Basic/奴隶-3。x")
,
    "领袖。V_0" => WorkspaceArray{Float64}("Platooning_Basic/领导者.V_0")
,
    "奴隶-2。x" => WorkspaceArray{Float64}("Platooning_Basic/Slave-2。x")
,
    "奴隶-4。v" => WorkspaceArray{Float64}("Platooning_Basic/奴隶-4。v")

)
In [ ]:
# 数据提取与细化
function get_signal(simout, key, step=1)
    t = collect(simout[key]).time
    val = collect(simout[key]).value
    return t[1:step:end], val[1:step:end]
end
t_lx, x_l = get_signal(simout, "Platooning_Basic/领导者.X_0", 5)
t_lv, v_l = get_signal(simout, "Platooning_Basic/领导者.V_0", 5)
t1x, x1 = get_signal(simout, "Platooning_Basic/Slave-1。x", 5)
t1v, v1 = get_signal(simout, "Platooning_Basic/Slave-1。v", 5)
t2x, x2 = get_signal(simout, "Platooning_Basic/Slave-2。x", 5)
t2v, v2 = get_signal(simout, "Platooning_Basic/Slave-2。v", 5)
t3x, x3 = get_signal(simout, "Platooning_Basic/奴隶-3。x", 5)
t3v, v3 = get_signal(simout, "Platooning_Basic/奴隶-3。v", 5)
t4x, x4 = get_signal(simout, "Platooning_Basic/奴隶-4。x", 5)
t4v, v4 = get_signal(simout, "Platooning_Basic/奴隶-4。v", 5)

# 速度图
plot(title="速度/速度", xlabel="时间", ylabel="速度(m/s)")
plot!(t_lv, v_l, label="领袖")
plot!(t1v, v1, label="奴隶-1")
plot!(t2v, v2, label="奴隶-2")
plot!(t3v, v3, label="奴隶-3")
display(plot!(t4v, v4, label="奴隶-4"))

# 位置图
plot(title="职位", xlabel="时间", ylabel="职位(m)")
plot!(t_lx, x_l, label="领袖")
plot!(t1x, x1, label="奴隶-1")
plot!(t2x, x2, label="奴隶-2")
plot!(t3x, x3, label="奴隶-3")
plot!(t4x, x4, label="奴隶-4")
Out[0]:

正如我们所看到的,僚机彼此领先,这不应该是这种情况。

改进的模型(PID控制器与防风)

为了消除这些问题,开发了一个更复杂的版本,它实现了带有附加机制的PID控制器。:

所做的改进:

  1. 增加了一个积分通道-它提供零稳态误差和恒定扰动。
  2. 积分器限制(防上卷)-误差积分器输出饱和内([-0.3; 0.3]), 这防止了在死区中或在加速/速度饱和中控制信号的长时间存在期间其无限累积。 防发条-这是一组方法和技术,旨在防止或减轻控制系统中的"发条"效应,特别是在PID控制器中,当控制信号超过执行器的能力时(例如,达到功率或速度限制)。 这种影响可导致误差的累积、系统的不稳定性和其性能的劣化。
    ![图像。png](附件:图片。png)
  3. 使用加速度限制。
  4. 重新调整系数-为了改善瞬态,增加了微分系数(K_d=2.0),为了减缓积分的累积,选择了一个相对较小的积分系数(K_i=0.05)。 比例系数保持不变(K_p=0.5)。
image.png

本文演示了模型的演变:从一个简单的PD控制器到一个完整的pid控制器与发条保护。 结果表明,增加了一个整体组件和一个防缠绕机制,可以完全消除超车的影响,通过适当的调整,可以消除超车,确保稳定的距离保持和真实的柱行为超过长的模拟间隔。

工作结果可用于自适应巡航控制(ACC)系统的设计和无人柱的控制。

image.png
In [ ]:
leader_speed_max = 10.0          # 麦克斯 领导者的速度,m/s
leader_accel_max = 3.0           # 领导者的加速,m/s2
D = 10.0                         # 设定距离,m
Kp, Kd, Ki = 0.5, 2.0, 0.05      # PID控制器的系数
accel_limit_lower, accel_limit_upper = -2.0, 2.0   # 加速度极限,m/s2
speed_limit_lower, speed_limit_upper = 0.0, 15.0   # 速度限制,m/s
int_err_lower, int_err_upper = -0.3, 0.3           # 反windows集成器

# 测量噪音
noise_mean = 0.0
noise_variance_position = 0.01
noise_variance_speed = 5
noise_sample_time = 0.01

delay_time = 0.3 # 运输延误,与
initial_positions = [-20.0, -40.0, -60.0] # 奴隶的初始位置(来自领导者)

run_model("Platooning_AntiWindup")

t_lx, x_l = get_signal(simout, "Platooning_AntiWindup/领导者.X_0")
t_lv, v_l = get_signal(simout, "Platooning_AntiWindup/领导者.V_0")
t1x, x1 = get_signal(simout, "Platooning_AntiWindup/奴隶-1。x")
t1v, v1 = get_signal(simout, "Platooning_AntiWindup/奴隶-1。v")
t2x, x2 = get_signal(simout, "Platooning_AntiWindup/奴隶-2。x")
t2v, v2 = get_signal(simout, "Platooning_AntiWindup/奴隶-2。v")
t3x, x3 = get_signal(simout, "Platooning_AntiWindup/奴隶-3。x")
t3v, v3 = get_signal(simout, "Platooning_AntiWindup/奴隶-3。v")
t = t_lx # 一般时间表(使用领导者的时间)
n = length(t);
Building...
Progress 0%
Progress 100%
Progress 100%

该图显示了僚机相对于领导者的相对位置随时间的动态,其中负值对应于滞后,零线是领导者的位置,并且没有这条线的交叉点证实了没有超车。

In [ ]:
t = t_lx
plot(t, [x1 .- x_l, x2 .- x_l, x3 .- x_l], 
     label=["Ved-1" "Ved-2" "吠陀-3"], 
     xlabel="时间", ylabel="相对位置(m)")
hline!([0], linestyle=:dash, label="领导者的位置")
Out[0]:

相位肖像的动画说明了坐标"位置–速度"中所有汽车轨迹的演变,其中驾驶者的轨迹与领导者的轨迹没有交集证实了安全驾驶模式而不超车。

In [ ]:
@gif for i in 1:n fps = 5
    plot(title="柱的相位画像",
         xlabel="位置,m", ylabel="速度,m/s",
         legend=:bottomright, xlims=(minimum(x_l)-10, maximum(x_l)+5), ylims=(-1, 16))
    # 当前位置点
    scatter!([x_l[i]], [v_l[i]], label="领袖", markersize=8, color=:black)
    scatter!([x1[i]], [v1[i]], label="奴隶-1", markersize=6, color=:red)
    scatter!([x2[i]], [v2[i]], label="奴隶-2", markersize=6, color=:green)
    scatter!([x3[i]], [v3[i]], label="奴隶-3", markersize=6, color=:blue)
    # 最后5秒的轨迹线
    dt = 5.0
    idx = findall(t .>= t[i] - dt)
    plot!(x_l[idx], v_l[idx], color=:black, alpha=0.5, linewidth=1, label="")
    plot!(x1[idx], v1[idx], color=:red, alpha=0.5, linewidth=1, label="")
    plot!(x2[idx], v2[idx], color=:green, alpha=0.5, linewidth=1, label="")
    plot!(x3[idx], v3[idx], color=:blue, alpha=0.5, linewidth=1, label="")
    annotate!(x_l[i], v_l[i]+0.6, text("t=$(round(t[i],digits=1))with", 8, :black))
end
Out[0]:
No description has been provided for this image

此动画显示列在与领导者相关联的参照系中的移动,其中每个驱动的汽车显示为具有签名当前速度的道路上的点,并且沿横坐标轴的负值对应于滞后,

In [ ]:
y_coord = 1.0
colors = [:black, :red, :green, :blue]
labels = ["领袖", "奴隶-1", "奴隶-2", "奴隶-3"]
x_min = -80
x_max = 10

@gif for i in 1:n fps = 3
    # 相对于领导者的位置
    pos_leader = x_l[i] - x_l[i]      # 0
    pos1 = x1[i] - x_l[i]
    pos2 = x2[i] - x_l[i]
    pos3 = x3[i] - x_l[i]
    positions = [pos_leader, pos1, pos2, pos3]
    speeds = [v_l[i], v1[i], v2[i], v3[i]]
    current_time = round(t[i], digits=1)
    # 基本时间表
    scatter(positions, fill(y_coord, 4),
        markersize = 12,
        markercolor = colors,
        xlim = (x_min, x_max),
        ylim = (0.5, 1.5),
        xlabel = "与领导者的距离(m)",
        ylabel = "",
        yticks = ([y_coord], ["道路"]),
        legend = false,
        title = "时间:$(current_time)s,领导速度:$(round(v_l[i],digits=1))m/s"
    )
    for (j, (pos, sp)) in enumerate(zip(positions, speeds))
        if j == 1
            continue  
        else
            annotate!(pos + 2, y_coord + 0.05, text("$((sp,数字=1))m/s", 8, colors[j]))
        end
    end
    for x in range(-100, 50, step=5)
        if x_min < x < x_max
            plot!([x, x], [0.6, 1.4], linewidth=0.5, color=:gray, alpha=0.4, label="")
        end
    end
end
Out[0]:
No description has been provided for this image

从数据分析可以看出,所有的从机都在相位域内运动,而没有越过leader的运动轨迹。

积分组件成功地补偿了噪声和不准确性的影响,并且抗绕组机制防止了长时间饱和期间的过冲。 因此,色谱柱在整个仿真过程中保持稳定。

结论

本文比较了两种列距控制方法:经典的PD控制器和具有windup保护的PID控制器。 在Engee环境中建模表明:

-PD控制器易于实现,但存在既定错误,对死区和噪声敏感,这导致奴隶超越领导者的不可接受的效果。
-防缠绕PID控制器完全消除了这些缺点。 积分通道的加入保证了稳态时的零误差,积分器的限制是饱和时的稳定性。 改进的模型展示了柱在长时间间隔内的正确行为,抗噪声和延迟,这使得它适合在自适应巡航控制(ACC)和无人柱控制系统中实际使用。

因此,从PD到具有防缠绕的PID控制器的演变对于确保车队的可靠和安全运动是必要的。