pydynamicestimator.devices.inverter_angle
Inverter angle-source strategies (what makes a converter forming vs following).
The angle source produces the converter frequency omega_c and integrates the
converter-frame angle delta_c – it fuses the synchronous machine’s governor
and shaft roles (there is no separable mechanical-power intermediate in an
inverter), so the active-power droop and the power-measurement state Pc_tilde
live here. It is the mandatory axis: a grid-forming converter sets its own
frequency from the droop off nominal (DroopAngle, exposing host.omega_c);
a grid-following converter rides on a PLL’s frequency (PLLAngle, reading
host.pll_frequency). Future variants: VSM (swing ODE), dVOC, matching control.
See docs/inverter_modernization_design.md §4.1. NOTE (Phase 2 boundary): the
angle source owns the Pc_tilde state and the droop, but the first-order
power-measurement filter equation d Pc_tilde/dt = omega_f (Pc - Pc_tilde) is
written by the host, because Pc is computed from the shared Park-transform loop
in Inverter.fgcall. A later cleanup can move power computation behind a host
accessor and the filter equation into the strategy.
Attributes
Classes
Abstract base class for inverter angle-source strategies (pluggable). |
|
Shared declarations for the power-droop angle family ( |
|
Grid-forming droop: the converter sets its own frequency from the |
|
Grid-following: the converter frequency rides on the PLL's synchronizing |
Module Contents
- class pydynamicestimator.devices.inverter_angle.AngleSource[source]
Bases:
abc.ABCAbstract base class for inverter angle-source strategies (pluggable).
Must own
delta_c(and, for the droop family,Pc_tilde) and expose the converter frequency:fgcall()returns theomega_cvector consumed by the host’s inner control ladder and writesdae.f[delta_c]. The strategy reads host params/states/setpoints by attribute (host.Kp,host.Pref,dae.x[host.Pc_tilde]) and, for the following variant, the synchronizing frequency viahost.pll_frequency(dae).- abstract fgcall(host, dae: pydynamicestimator.system.Dae, omega_ref_vec, omega_b)[source]
Return the
omega_cvector and writedae.f[delta_c](the angle dynamics). Grid-forming variants also sethost.omega_c; grid-following variants leave it unset and readhost.pll_frequency(dae)instead.- Parameters:
- steady_frequency(host, dae: pydynamicestimator.system.Dae) numpy.ndarray[source]
The converter frequency at steady state, fed to the inner-control init’s decoupling terms. Nominal for ANY synchronizing source:
delta_csteady forcesomega_c = omega_ref = omega_net, independent of the angle law.- Parameters:
- Return type:
numpy.ndarray
- abstract finit_sequential(host, dae: pydynamicestimator.system.Dae, Pc: numpy.ndarray, delta_c: numpy.ndarray) Dict[str, numpy.ndarray][source]
Resolve the angle source’s states/setpoints from the (frame-invariant) active power
Pcand the inner-controller’s frame angledelta_c. The base raises so a new angle source declares its own.- Parameters:
Pc (numpy.ndarray)
delta_c (numpy.ndarray)
- Return type:
Dict[str, numpy.ndarray]
- class pydynamicestimator.devices.inverter_angle._PowerDroopAngle[source]
Bases:
AngleSourceShared declarations for the power-droop angle family (
Pc_tilde+delta_cstates,Kpdroop gain,Prefsetpoint). Concrete subclasses differ only in the frequency anchor insidefgcall().- finit_sequential(host, dae: pydynamicestimator.system.Dae, Pc: numpy.ndarray, delta_c: numpy.ndarray) Dict[str, numpy.ndarray][source]
Resolve the angle source’s states/setpoints from the (frame-invariant) active power
Pcand the inner-controller’s frame angledelta_c. The base raises so a new angle source declares its own.- Parameters:
Pc (numpy.ndarray)
delta_c (numpy.ndarray)
- Return type:
Dict[str, numpy.ndarray]
- class pydynamicestimator.devices.inverter_angle.DroopAngle[source]
Bases:
_PowerDroopAngleGrid-forming droop: the converter sets its own frequency from the active-power droop off nominal,
omega_c = omega_net + Kp (Pref - Pc_tilde), and exposes it ashost.omega_c(read by the COI / single reference-frame machinery insystem.py). Byte-identical to the previous GridForming angle.- fgcall(host, dae: pydynamicestimator.system.Dae, omega_ref_vec, omega_b)[source]
Return the
omega_cvector and writedae.f[delta_c](the angle dynamics). Grid-forming variants also sethost.omega_c; grid-following variants leave it unset and readhost.pll_frequency(dae)instead.- Parameters:
- class pydynamicestimator.devices.inverter_angle.PLLAngle[source]
Bases:
_PowerDroopAngleGrid-following: the converter frequency rides on the PLL’s synchronizing frequency (read host-mediated via
host.pll_frequency) plus the active-power droop,omega_c = omega_pll + Kp (Pref - Pc_tilde). Pairs with a PLL strategy (which ownsomega_plland the PLL states). Byte-identical to the previous GridFollowing angle.- fgcall(host, dae: pydynamicestimator.system.Dae, omega_ref_vec, omega_b)[source]
Return the
omega_cvector and writedae.f[delta_c](the angle dynamics). Grid-forming variants also sethost.omega_c; grid-following variants leave it unset and readhost.pll_frequency(dae)instead.- Parameters:
- pydynamicestimator.devices.inverter_angle.ANGLE_REGISTRY: Dict[str, type]