Modular Inverter Framework

This section describes the modular inverter framework developed in the MARiE-Project funded by the German Federal Ministry for Economic Affairs and Climate Action.

Structure

The inverter model is split in two parts: the inner loop and the outer loop.

The inner loop either acts as a voltage source

           +---------+
u_d_ref -->|         |
u_q_ref -->| Voltage |--> u_d
i_d_dis -->| Source  |--> u_q
i_q_dis -->|         |
           +---------+

which gets a dq voltage reference and tries to achive this reference despite the dq current disturbance.

Alternatively, the inner loop can mimic a current source, which tries to realsize a given current setpoint despite a disturbance voltage at the output terminals:

           +---------+
i_d_ref -->|         |
i_q_ref -->| Current |--> i_d
u_d_dis -->| Source  |--> i_q
u_q_dis -->|         |
           +---------+

The outer loop provides references to the inner loop blocks. As an input, outerloops have acces to the measured currents and voltages at the point of common coupling. They either eject a dq-reference for the inner voltage source or the inner current soruce:

            +---------+
i_d_meas -->|         |
i_q_meas -->|  Outer  |--> u_d_ref or i_d_ref
u_d_meas -->|  Loop   |--> u_q_ref or i_q_ref
u_q_meas -->|         |
            +---------+

PowerDynamics.jl provides predefined outer loop as well as inner loop models as IOBlocks provide by BlockSystems.jl, which can be used to create IONodes (see Custom-Nodes-using-BlockSystems.jl).

Example

In order to construct a modular inverter we need to import the ModularInverter module to the namespace:

using PowerDynamics
using BlockSystems
using PowerDynamics.ModularInverter

First, we need to define the inner loop as an IOBlock object. You can either use your own or make use of the Predefined Inner Loops.

inner = CascadedVoltageControl()
IOBlock :VCFOM with 24 eqs
  ├ inputs:  i_r(t), i_i(t), u_ref_r(t), u_ref_i(t)
  ├ outputs: u_r(t), u_i(t)
  ├ istates: LC₊i_f_r(t), LC₊i_f_i(t), …19…,VC₊γ_i(t)
  └ iparams: (empty)

As you can see, the input/output structure of that innerloop adheres to the volten source innerloop convention.

Next you define the outer loop, either create you own based on the interface or pick from the Predefined Outer Loops.

outer = DroopControl()
IOBlock :droop with 5 eqs
  ├ inputs:  u_meas_i(t), u_meas_r(t), i_meas_i(t), i_meas_r(t)
  ├ outputs: u_ref_r(t), u_ref_i(t)
  ├ istates: P_fil(t), Q_fil(t), δ(t)
  └ iparams: τ_P, τ_Q, …5…,K_Q

There are still a lot of open parameters, we need to assign specific values to create the IONode(@ref) later. We can do so by using the keyword aguments of the constructor:

outer = DroopControl(;
    ω_ref = 2π*50, # frequency reference
    V_ref = 1,     # voltage reference (pu)
    P_ref = 1,     # active power reference (pu)
    Q_ref = 0,     # reactive power reference (pu)
    K_P   = 0.4,   # active droop gain
    K_Q   = 0.004, # reactive droop gain
    τ_P   = 0.1,   # active power filter constant
    τ_Q   = 0.1,   # reactive power filter constant
)
IOBlock :droop with 5 eqs
  ├ inputs:  u_meas_i(t), u_meas_r(t), i_meas_i(t), i_meas_r(t)
  ├ outputs: u_ref_r(t), u_ref_i(t)
  ├ istates: P_fil(t), Q_fil(t), δ(t)
  └ iparams: (empty)

The full inverter model is created by combining outer and inner model:

inv = Inverter(inner, outer)
IOBlock :droop_VCFOM with 27 eqs
  ├ inputs:  i_r(t), i_i(t)
  ├ outputs: u_r(t), u_i(t)
  ├ istates: P_fil(t), Q_fil(t), …22…,VC₊γ_i(t)
  └ iparams: (empty)

Which satisfies the interface for IONodes. To create the node

node = IONode(inv);

Which is a valid node definition which can be used in any PowerDynamics.jl context.

Model Reduction

PowerDynamics.jl also implements automated model order reduction of linear models using the balance residualization technique. Internaly, we make use of the method implementaion in ControlSystems.jl. For that, a linear block (such as the cascaded inner loops) can be decomposed in to its A, B, C and D matrix for regular LTI representation.

For example, we could creat a 10th order representation of the previously defined inner loop by calling

reduced_inner = balresid(inner, 10; reconstruct=false)
IOBlock :VCFOM_trunc_10 with 12 eqs
  ├ inputs:  i_r(t), i_i(t), u_ref_r(t), u_ref_i(t)
  ├ outputs: u_r(t), u_i(t)
  ├ istates: z₁(t), z₂(t), …7…,z₁₀(t)
  └ iparams: (empty)

To obtain the reduced order model we can construct the inverter again:

reduced_inverter = Inverter(reduced_inner, outer)
IOBlock :droop_VCFOM_trunc_10 with 15 eqs
  ├ inputs:  i_r(t), i_i(t)
  ├ outputs: u_r(t), u_i(t)
  ├ istates: P_fil(t), Q_fil(t), …10…,z₁₀(t)
  └ iparams: (empty)

... and the reduced node

reduced_node = IONode(reduced_inverter);
PowerDynamics.ModularInverter.balresidFunction
balresid(blk::IOBlock, order; warn=BlockSystems.WARN[], verbose=false, reconstruct=false)

This function creates a model reduced version of blk of given order using the balanced residualization method. Only works for linear systems. Internaly, it uses the baltrunc function from ControlSystems.jl to apply the method to an LTI. The LTI system matrices A,B,C and D are determined symbolicially from the IOBlock object.

If reconstruct=true the resulting system will include removed_eqs to reconstruct the original states from the projected states z_i.

source

Predefined Inner Loops

PowerDynamics.ModularInverter.CascadedVoltageControlCSFunction
CascadedVoltageControlCS(;pr=true, ff=true)

Cascaded voltage controler over a LCL filter, which controlls the filter voltage using 2 levels of cascaded dq controllers.

Acts as a current source because of the second L in the filter.

source

Predefined Outer Loops

PowerDynamics.ModularInverter.FixedVoltageFunction
FixedVoltage(; params...)

Outer loop control for a voltage source which tries to keep voltage constant (slack like behavior).

  u_d_fix, u_i_fix
          v
+-------------------+
|                   |
| u_r_ref = u_d_fix |--> u_r_ref
| u_i_ref = u_i_fix |--> u_i_ref
|                   |
+-------------------+
source
PowerDynamics.ModularInverter.DroopControlFunction
DroopControl(; params...)

Return block for droop control outer control.

                ω_ref, V_ref, P_ref, Q_ref, K_P, K_Q, τ_P, τ_Q
                                     v
            +-----------------------------------------------------+
            |     P_meas = u_meas_r*i_meas_r + i_meas_i*u_meas_i  |
i_r_meas -->|     Q_meas = -u_meas_r*i_meas_i + i_meas_r*u_meas_i |
i_i_meas -->| d/dt P_fil = (P_meas - P_fil) / τ_P                 |--> u_r_ref
u_r_meas -->| d/dt Q_fil = (Q_meas - Q_fil) / τ_P                 |--> u_i_ref
u_i_meas -->|     d/dt δ = ω_ref - K_P*(-P_ref + P_fil)           |
            |          V = V_ref - K_Q*(-Q_ref + Q_fil)           |
            +-----------------------------------------------------+
source
PowerDynamics.ModularInverter.SynchronverterFunction
Synchronverter(; params...)

Synchronverter outer loop control for a voltage controlled converter.

                     ω0, V_ref, P_ref, Q_ref, Dp, Kq, Kv
                                     v
            +---------------------------------------------------------------------+
            |         V = sqrt(u_meas_r^2 + u_meas_i^2)                           |
            |         Q = -sqrt(3/2) * MfIf * (ω0 + ω)                            |
            |             * (-sin(θ)*i_meas_r + cos(θ)*i_meas_i)                  |
i_r_meas -->|        Te =  sqrt(3/2) * MfIf * (cos(θ)*i_meas_r + sin(θ)*i_meas_i) |
i_i_meas -->|    d/dt ω = 1/J * P_ref/ω0 - Dp*ω - Te,                             |--> u_r_ref
u_r_meas -->|    d/dt θ = ω                                                       |--> u_i_ref
u_i_meas -->| d/dt MfIf = (Q_ref - Q + Dq*(V_ref - V))/Kv],                       |
            |   u_ref_r = sqrt(3/2) * MfIf * (ω0 + ω) * cos(θ)                    |
            |   u_ref_i = sqrt(3/2) * MfIf * (ω0 + ω) * sin(θ)                    |
            +---------------------------------------------------------------------+
source
PowerDynamics.ModularInverter.PLLCurrentFunction
PLLCurrent(; params...)

Outer loop control for a current source inverter, which employs a dynamic PLL to estimate the phase and frequency of the voltage at PCC. The single parameter, i_mag_ref is interpeted as current reference in d component (pure active power injection with fixed current).

source
PowerDynamics.ModularInverter.ConstantPowerFunction
ConstantPower(; params...)

Outer loop control for a current source inverter, which measures the voltage at PCC and commands the i_ref_r and i_ref_i such that the desired power at PCC is achived.

source
PowerDynamics.ModularInverter.FiltConstantPowerFunction
FiltConstantPower(; params...)

Outer loop control for a current source inverter, which measures the voltage at PCC and commands the i_ref_r and i_ref_i such that the desired power at PCC is achived. In contrast to the ConstantPower-outer loop, the current references follow a PT1 behavior with time constant τ.

source

Inverter Construction

PowerDynamics.ModularInverter.InverterFunction

Inverter(inner, outer; name))

Combines an inner and an outer loop to a closed loop model of an voltage-srouce-inverter.

Both inner and outer loops musst be IOBlock objects adhering to the interface

Inner loop inputs/outputs:

           +---------+
u_r_ref -->|         |
u_i_ref -->| Voltage |--> u_r
    i_r -->| Source  |--> u_i
    i_i -->|         |
           +---------+

Outer loop inputs/outputs:

            +---------+
i_r_meas -->|         |
i_i_meas -->|  Outer  |--> u_r_ref
u_r_meas -->|  Loop   |--> u_i_ref
u_i_meas -->|         |
            +---------+
source
PowerDynamics.ModularInverter.InverterCSFunction

InverterCS(inner, outer; name))

Combines an inner and an outer loop to a closed loop model of an current-source-inverter.

Both inner and outer loops musst be IOBlock objects adhering to the interface

Inner loop inputs/outputs:

           +---------+
i_r_ref -->|         |
i_i_ref -->| Current |--> i_r
    u_r -->| Source  |--> i_i
    u_i -->|         |
           +---------+

Outer loop inputs/outputs:

            +---------+
i_r_meas -->|         |
i_i_meas -->|  Outer  |--> i_r_ref
u_r_meas -->|  Loop   |--> i_i_ref
u_i_meas -->|         |
            +---------+
source

This page was generated using Literate.jl.