logo

동역학계로써의 DC-DC 벅 컨버터 📂동역학

동역학계로써의 DC-DC 벅 컨버터

모델

위와 같은 회로도1의 전압 $V$ 와 전류 $I$ 는 다음과 같은 비자율넌스무스 시스템으로 나타낼 수 있다2. 이를 DC-DC 벅 컨버터DC-DC Buck Converter라 부른다.

$$ \begin{align*} \dot{V} =& - {{ 1 } \over { RC }} V + {{ 1 } \over { C }} I \\ \dot{I} =& - {{ V } \over { L }} + \begin{cases} 0 & , \text{if } V \ge V_{r} (t) \\ E / L & , \text{if } V < V_{r} (t) \end{cases} \\ V_{r} (t) =& \gamma + \eta \left( t \bmod T \right) \end{align*} $$

변수

  • $V(t)$: $t$ 시점에서 전압을 나타낸다.
  • $I(t)$: $t$ 시점에서 전류를 나타낸다.
  • $V_{r}(t)$: $t$ 시점에서의 $T$-주기 컨트롤 시그널이다. 이 시그널보다 전압이 작으면 스위치를 열어 배터리를 충전하고, 크면 스위치를 닫아 전류를 공급한다.

파라미터

  • $\gamma , \eta , T > 0$: 컨트롤의 설정configuration에 관계된 상수들이다. $\gamma = 11.75238 V$ 가 작을수록 낮은 전압에서 전류가 공급되고, $\eta = 1309.524Vs^{-1}$ 가 클수록 높은 전압에서 배터리를 충전한다. $T = 400 \mu s$ 가 작을수록 스위칭이 자주 일어나서 전압을 더 균일하게 유지한다.
  • $C = 47 \mu F$: 캐퍼시턴스capacitance다.
  • $E = 53.500001$: 배터리 전압battery Voltage이다.
  • $L = 20 mH$: 인덕턴스inductance다.
  • $R = 22 \Omega$: 저항resistance이다.

파라미터의 기본값들은 이 포스트에서 재현되는 모든 시뮬레이션에 사용된 값들이고, $m = 10^{-3}$, $\mu = 10^{-6}$ 이다. 참고로 주 참고문헌(Bernardo)에서 $C$ 는 $4.7 \mu F$ 이었지만 다른 참고문헌(Deane)에서는 $C = 47 \mu F$ 고, $4.7 \mu F$ 로 두었을 땐 시뮬레이션이 제대로 되지 않아 $C$ 만 다르게 설정됐다.

설명

DC-DC 벅 컨버터, 줄여서 벅 컨버터는 입력 전압보다 전압을 내리는 용도의 컨버터3로, 사실 필자는 이 ‘물건’에 대해서는 잘 모르며 제목대로 시스템에 대한 설명만 하려고 한다.

넌스무스 시스템

벅 컨버터 시스템은 방정식만 봐도 알 수 있듯 도함수가 연속이 아니라서 넌스무스한 시스템이다. 빨간색 선은 컨트롤 시그널 $V_{r} (t)$ 이고, 전압 $V(t)$ 이 이를 넘느냐 못 넘느냐에 따라서 시스템이 점핑jumping을 하며 넌스무스하게 전환되는 것을 확인 할 수 있다. 이에 따라 시스템의 전압은 대략 11.5~14.0V 사이에서 유지된다.

캐어릭 시스템

스위치가 열리고 닫히고에 따른 서브시스템subsystem만 보면 각자 선형 시스템이라서 별로 어려울 것도 없어보인다. 그런데 문제는 $V(t) = V_{r}(t)$ 가 되는 시점 $t$, 다시 말해 스위치가 켜지고 꺼지는 타이밍이 아무런 일관성도 없다는 것이다.

위의 그림은 트래젝터리에서 언제 스위칭이 일어나는지를 보여주고 있다. 보다시피 점들이 어느정도 무리를 이루는 띠, 그러니까 $V \approx V_{r}$ 인 영역이 없는 건 아니지만 확실히 어떤 조건에서 일어난다고 하기엔 $V,I$ 만 보고 장담할 수가 없다. 이러한 넌스무스성 때문에 이 간단해 보였던 시스템은 사실 캐어릭하며, 오랫동안 많이 연구되어 왔다4.

바이퍼케이션

buck_bifurcation.png

파라미터 $E$ 를 바꿔가면서 시그널의 주기에 맞춰 $V$ 의 값을 찍어 바이퍼케이션 다이어그램을 그려보면 위와 같은 바이퍼케이션을 볼 수 있다. 5 $E \approx 25$ 에서 두 줄기가 생겼다가 교차하고 $E \approx 30$ 에서 가지 주변으로 피리어딕 오빗이 나타나는 것은 정상이다.

코드

트래젝터리

다음은 시스템을 풀고 점핑 포인트의 위치를 나타낸 그림을 재현할 수 있는 줄리아 코드다.

using CSV, DataFrames, Clustering

function RK4(f::Function,v::AbstractVector, h=10^(-2))
    V1 = f(v)
    V2 = f(v + (h/2)*V1)
    V3 = f(v + (h/2)*V2)
    V4 = f(v + h*V3)
    return v + (h/6)*(V1 + 2V2 + 2V3 + V4)
end


if !isfile("./buck.csv")
    m = 10^(-3)
    μ = 10^(-6)
    R = 22
    C = 47μ
    L = 20m
    T = 400μ
    γ = 11.75238
    η = 1309.524
    E = 53.500001

    Vr(t) = γ + η * (mod(t, T))
    function buck(v)
        V, I, t = v

        V̇ = - V/(R*C) + I/C
        İ = - (V/L) + ifelse(V < Vr(t), E/L, 0)
        return [V̇, İ, 1]
    end

    u0 = [12.3, 0.55, 0.0]
    u_ = [u0]
    ∇_ = []
    dt = 0.00001; tend = 0.25
    for t in dt:dt:tend
        push!(∇_, buck(u_[end]))
        push!(u_, RK4(buck, u_[end], dt))
    end
    push!(∇_, buck(u_[end]))
    U = stack(u_)[Not(end), :]
    ∇ = stack(∇_)[Not(end), :]
    CSV.write("buck.csv", DataFrame(
        [collect(0:dt:tend)'; U; ∇; Vr.(0:dt:tend)']'
      , ["t", "V", "I", "dV", "dI", "Vr"]))
end

DATA = CSV.read("data/buck.csv", DataFrame)

Y = select(DATA, [:dV, :dI]) |> Matrix .|> Float32
X = select(DATA, [ :V,  :I]) |> Matrix .|> Float32
XY = [X Y]

dbs = dbscan(col_normalize(Y)', 0.01); nsubsys = length(dbs.clusters); println(nsubsys, " clusters found!")

a1 = plot(DATA.V, DATA.I, alpha = 0.1, legend = :best, label = "Trajectory", xlabel = L"V", ylabel = L"I")
scatter!(a1, 
    DATA.V[Not(1)][.!iszero.(diff(dbs.assignments))]
  , DATA.I[Not(1)][.!iszero.(diff(dbs.assignments))]
  , color = 1, shape = :+, label = "Jumping points")

바이퍼케이션 다이어그램

다음은 바이퍼케이션 다이어그램의 코드다. 다소 기술적인 문제가 있는데, 실제로 벅 컨버터를 시뮬레이션 하려면 시간 간격이 $h = 10^{-7}$ 정도는 되어야 정교하게 재현할 수 있음에 주의해야 한다. 계산량이 너무 많아서 오일러 메소드를 사용했음에도 인텔 i7-12700F를 기준으로 10시간 정도가 걸린다.

const m = 10^(-3)
const μ = 10^(-6)
const R = 22 # 22
const L = 20m # 20m
const C = 47μ # 22μ
const T = 400μ
const γ = 11.7 # 11.75238
const η = 1309.5 # 1309.524
const RC = R*C

using ProgressBars
packages = [:DataFrames, :CSV, :Plots, :LaTeXStrings]
for package in ProgressBar(packages)
    @eval using $(package)
end
println(join(packages, ", "), " loaded!")

function Euler(f::Function,v::AbstractVector, h=10^(-2))
    V1 = f(v)
    return v + h*V1, V1
end

Vr(t) = γ + η * (mod(t, T))

function factory_buck(idx::Int64, E::Number; flag_filesave = false)
    EdL = E/L
    
    controlterm = 0.0
    function buck(v::AbstractVector)
        V, I = v

        V̇ = - V/(RC) + I/C
        İ = - (V/L) + controlterm
        return [V̇, İ]
    end
    dt = 10^(-7); tend = 0.5
    t_ = 0:dt:tend
    Vr_ = Vr.(t_)

    ndatapoints = round(Int64, tend/(100dt))

    len_t_ = length(t_)
    traj = zeros(4, len_t_+1)
    u = [12.0, 0.55]
    du = buck(u)
    traj[1:2, 1] = u

    
    for t in 1:length(t_)
        controlterm = ifelse(u[1] < Vr_[t], EdL, 0)
        u, du = Euler(buck, u, dt)
        if t ≥ ndatapoints
            traj[3:4,   t] = du
            traj[1:2, t+1] = u
        end
    end
    traj = traj[:, 1:(end-1)]'

    if flag_filesave
        data = DataFrame(
            [t_ traj Vr_],
            ["t", "V", "I", "dV", "dI", "Vr"])
            @warn "file saving mode!"
            CSV.write("G:/buck/buck_$(lpad(idx, 6, '0')).csv", data)
        return nothing
    else
        data = DataFrame(
            [t_ traj Vr_][(end-ndatapoints):end, :],
            ["t", "V", "I", "dV", "dI", "Vr"])
    end

    return data
end

# E_range = 15:40
E_range = 15:0.001:40
schedule = DataFrame(idx = eachindex(E_range), E = E_range)

xdots = Float64[]; ydots = Float64[]
for dr in ProgressBar(eachrow(schedule))
    data = factory_buck(dr.idx, dr.E)
    
    idx_sampled = diff(data.Vr) .< 0
    sampledV = data[Not(1), :V][idx_sampled]
    append!(xdots, fill(dr.E, length(sampledV)))
    append!(ydots, sampledV)
end
@time a1 = scatter(xdots, ydots,
xlabel = L"E", ylabel = L"V",
label = :none, msw = 0, color = :black, ms = 0.5, alpha = 0.5, size = (700, 480));

png(a1, "buck_bifurcation")

  1. https://upload.wikimedia.org/wikipedia/commons/c/ca/Commutation_cell_in_converters.svg ↩︎

  2. Di Bernardo, M., Budd, C. J., Champneys, A. R., Kowalczyk, P., Nordmark, A. B., Tost, G. O., & Piiroinen, P. T. (2008). Bifurcations in nonsmooth dynamical systems. SIAM review, 50(4), 629-701. https://doi.org/10.1137/050625060 ↩︎

  3. https://gdnn.tistory.com/85 ↩︎

  4. J. H. B. Deane and D. C. Hamill, “Analysis, simulation and experimental study of chaos in the buck converter,” 21st Annual IEEE Conference on Power Electronics Specialists, San Antonio, TX, USA, 1990, pp. 491-498, doi: https://doi.org/10.1109/PESC.1990.131228↩︎

  5. M. di Bernardo, F. Garefalo, L. Glielmo and F. Vasca, “Switchings, bifurcations, and chaos in DC/DC converters,” in IEEE Transactions on Circuits and Systems I: Fundamental Theory and Applications, vol. 45, no. 2, pp. 133-141, Feb. 1998, doi: https://doi.org/10.1109/81.661675 ↩︎