pydynamicestimator.devices.inverter_pll

Inverter phase-locked-loop (frequency/phase estimator) strategies.

The PLL is a measurement strategy, separate from the angle source – the inverter analogue of the synchronous machine’s PSS: it produces a signal (omega_pll) consumed by another strategy (the angle source), host-mediated via host.pll_frequency(dae), and never references its consumer. Keeping it a distinct axis is what lets a grid-forming converter carry a PLL for FRT/monitoring without baking it into “grid-following” (see docs/inverter_modernization_design.md §4.2). pll=None (the default) means no PLL block.

It owns its integrator/angle states (epsilon / delta_pll), registered LAST in the state vector so that – with the angle source owning Pc_tilde / delta_c near the front – the original GridFollowing ordering is reproduced byte-for-byte.

Attributes

PLL_REGISTRY

Classes

PLL

Abstract base class for inverter PLL (frequency estimator) strategies.

SRF_PLL

Synchronous-reference-frame PLL: locks the PLL frame to the filter voltage

Module Contents

class pydynamicestimator.devices.inverter_pll.PLL[source]

Bases: abc.ABC

Abstract base class for inverter PLL (frequency estimator) strategies.

Like the SG strategies, the PLL does NOT own state arrays or DAE indices; it declares them and the host Inverter registers them on itself. Its fgcall() writes its own state equations into dae.f and publishes the estimated synchronizing frequency on host.omega_pll (an algebraic expression, not a registered variable), which the host exposes to consumers via host.pll_frequency(dae) and which the reference-frame machinery in system.py reads for grid-following devices.

abstract states() List[str][source]
Return type:

List[str]

algebs() List[str][source]
Return type:

List[str]

algebs_units() Dict[str, str][source]
Return type:

Dict[str, str]

algebs_noise() Dict[str, float][source]
Return type:

Dict[str, float]

algebs_x0() Dict[str, float][source]
Return type:

Dict[str, float]

abstract units() List[str][source]
Return type:

List[str]

abstract params() Dict[str, float][source]
Return type:

Dict[str, float]

abstract states_noise() Dict[str, float][source]
Return type:

Dict[str, float]

abstract states_init_error() Dict[str, float][source]
Return type:

Dict[str, float]

abstract x0() Dict[str, float][source]
Return type:

Dict[str, float]

abstract descriptions() Dict[str, str][source]
Return type:

Dict[str, str]

abstract fgcall(host, dae: pydynamicestimator.system.Dae, omega_ref_vec, omega_b) None[source]

Write the PLL state equations into dae.f and set host.omega_pll to the estimated synchronizing frequency (read by the angle source via host.pll_frequency(dae)).

Parameters:

dae (pydynamicestimator.system.Dae)

Return type:

None

abstract finit_sequential(host, dae: pydynamicestimator.system.Dae, Vfd_ext, Vfq_ext) Dict[str, numpy.ndarray][source]

Steady-state init of the PLL from the filter voltage (decoupled). Returns its state values (e.g. epsilon, delta_pll). The base raises so a PLL without a sequential init falls under the joint init.

Parameters:

dae (pydynamicestimator.system.Dae)

Return type:

Dict[str, numpy.ndarray]

class pydynamicestimator.devices.inverter_pll.SRF_PLL[source]

Bases: PLL

Synchronous-reference-frame PLL: locks the PLL frame to the filter voltage by driving its q-axis component to zero through a PI loop.

States: epsilon (PI integrator), delta_pll (PLL-frame angle relative to the network). Equivalent to the PLL equations previously hardcoded in GridFollowing; the trajectory is byte-identical.

states() List[str][source]
Return type:

List[str]

units() List[str][source]
Return type:

List[str]

params() Dict[str, float][source]
Return type:

Dict[str, float]

states_noise() Dict[str, float][source]
Return type:

Dict[str, float]

states_init_error() Dict[str, float][source]
Return type:

Dict[str, float]

x0() Dict[str, float][source]
Return type:

Dict[str, float]

descriptions() Dict[str, str][source]
Return type:

Dict[str, str]

fgcall(host, dae: pydynamicestimator.system.Dae, omega_ref_vec, omega_b) None[source]

Write the PLL state equations into dae.f and set host.omega_pll to the estimated synchronizing frequency (read by the angle source via host.pll_frequency(dae)).

Parameters:

dae (pydynamicestimator.system.Dae)

Return type:

None

finit_sequential(host, dae: pydynamicestimator.system.Dae, Vfd_ext, Vfq_ext) Dict[str, numpy.ndarray][source]

PLL lock at steady state: the PLL frame aligns so its q-axis voltage is zero (Vfq_pll = 0), the integrator settles (epsilon = 0), and delta_pll is the filter-voltage angle. Solved as a 3x3 Newton for (Vfq_pll, epsilon, delta_pll); the first is an intermediate.

Parameters:

dae (pydynamicestimator.system.Dae)

Return type:

Dict[str, numpy.ndarray]

pydynamicestimator.devices.inverter_pll.PLL_REGISTRY: Dict[str, type]