diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 000000000..ad7bb27cc
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,8 @@
+{
+ "recommendations": [
+ "ms-python.python"
+ "ms-python.pylint",
+ "eeyore.yapf",
+ "streetsidesoftware.code-spell-checker",
+ ]
+}
\ No newline at end of file
diff --git a/docs/source/control/control_system.rst b/docs/source/control/control_system.rst
index d7ff0fcea..ed024a173 100644
--- a/docs/source/control/control_system.rst
+++ b/docs/source/control/control_system.rst
@@ -1,15 +1,15 @@
-Control Systems
-===============
+Common
+======
Main Control Loop
-----------------
-By default, the discrete-time controllers in *motulator* run the following scheme in a main control loop:
+By default, discrete-time control systems in *motulator* run the following scheme in their main control loop:
- 1. Get the feedback signals. This step may contain first getting the measurements and then optionally computing the observer outputs.
- 2. Compute the reference signals (controller outputs) based on the feedback signals.
- 3. Update the control system states for the next sampling instant.
- 4. Save the feedback signals and the reference signals.
+ 1. Get the feedback signals for the controllers. This step may contain first getting the measurements and then optionally computing the observer outputs. These measured and estimated signals are collected to the SimpleNamespace object named `fbk`.
+ 2. Get the reference signals and compute the controller outputs based on the feedback signals `fbk`. These reference signals are collected to the SimpleNamespace object named `ref`.
+ 3. Update the states of the control system for the next sampling instant.
+ 4. Save the feedback signals `fbk` and the reference signals `ref` so they can be accessed after the simulation.
5. Return the sampling period `T_s` and the duty ratios `d_abc` for the carrier comparison.
-The main control loop is implemented in the base class for control systems in :class:`motulator.common.control.ControlSystem`.
\ No newline at end of file
+A template of this main control loop is available in the base class for control systems in :class:`motulator.common.control.ControlSystem`. Using this template is not necessary, but it may simplify the implementation of new control systems.
\ No newline at end of file
diff --git a/docs/source/control/grid/synchronization.rst b/docs/source/control/grid/synchronization.rst
index 0eea7d6e5..e64494369 100644
--- a/docs/source/control/grid/synchronization.rst
+++ b/docs/source/control/grid/synchronization.rst
@@ -1,65 +1,91 @@
-Synchronization Methods
-=======================
+Disturbance-Observer-Based PLL
+==============================
-Phase-Locked Loop
+A phase-locked loop (PLL) is commonly used in grid-following converters to synchronize the converter output with the grid [#Kau1997]_. Here, we represent the PLL using the disturbance observer structure [#Fra1997]_, which may be simpler to extend than the classical PLL. Furthermore, this structure allows to see links to synchronization methods used in grid-forming converters, see [#Nur2024]_.
+
+Disturbance Model
-----------------
-The :doc:`/grid_examples/grid_following/index` examples use a Phase-Locked Loop (PLL) to synchronize with the grid. The block diagram of the PLL is shown in the figure below.
+Consider the positive-sequence voltage at the point of common coupling (PCC) in general coordinates, rotating at the angular speed :math:`\omega_\mathrm{c}`. The dynamics of the PCC voltage :math:`\boldsymbol{u}_\mathrm{g}` can be modeled using a disturbance model as
+
+.. math::
+ \frac{\mathrm{d}\boldsymbol{u}_\mathrm{g}}{\mathrm{d}t} = \mathrm{j}(\omega_\mathrm{g} - \omega_\mathrm{c})\boldsymbol{u}_\mathrm{g}
+ :label: disturbance
+
+where :math:`\omega_\mathrm{g}` is the grid angular frequency. If needed, this disturbance model could be extended, e.g., with a negative-sequence component, allowing to design the PLL for unbalanced grids.
+
+PLL in General Coordinates
+--------------------------
+
+Based on :eq:`disturbance`, the disturbance observer containing the regular PLL functionality can be formulated as
+
+.. math::
+ \frac{\mathrm{d}\hat{\boldsymbol{u}}_\mathrm{g}}{\mathrm{d}t} = \mathrm{j}(\hat{\omega}_\mathrm{g} - \omega_\mathrm{c})\hat{\boldsymbol{u}}_\mathrm{g} + \alpha_\mathrm{g} (\boldsymbol{u}_\mathrm{g} - \hat{\boldsymbol{u}}_\mathrm{g} )
+ :label: pll
-.. figure:: ../figs/pll.svg
- :width: 100%
- :align: center
- :alt: Block diagram of the phase-locked loop for grid synchronization
- :target: .
+where :math:`\hat{\boldsymbol{u}}_\mathrm{g} = \hat{u}_\mathrm{g} \mathrm{e}^{\mathrm{j}\hat{\vartheta}_\mathrm{g}}` is the estimated PCC voltage, :math:`\hat{\omega}_\mathrm{g}` is the grid angular frequency estimate (either constant corresponding to the nominal value or dynamic from grid-frequency tracking), and :math:`\alpha_\mathrm{g}` is the bandwidth. If needed, the disturbance observer can be extended with the frequency tracking as
- Block diagram of the phase-locked loop.
+.. math::
+ \frac{\mathrm{d}\hat{\omega}_\mathrm{g}}{\mathrm{d}t} = k_\omega\mathrm{Im}\left\{ \frac{\boldsymbol{u}_\mathrm{g} - \hat{\boldsymbol{u}}_\mathrm{g}}{\hat{\boldsymbol{u}}_\mathrm{g}} \right\}
+ :label: frequency_tracking
-The PLL drives the signal :math:`\hat{u}_\mathrm{gq}` to zero, leading to :math:`\hat{\vartheta}_\mathrm{g}=\vartheta_\mathrm{g}` and :math:`\hat{u}_\mathrm{gd}=u_\mathrm{gd}` in ideal conditions. The grid voltage-vector :math:`\boldsymbol{u}_\mathrm{g}^\mathrm{s}=u_\mathrm{g} \mathrm{e}^{\mathrm{j} \vartheta_\mathrm{g}}` is measured. The angle :math:`\vartheta_\mathrm{g}` can be noisy and it is not directly used in the control. Instead, the PLL tracks :math:`\vartheta_{g}` and filters its noise and harmonics above the PLL bandwidth.
+where :math:`k_\omega` is the frequency-tracking gain. Notice that :eq:`pll` and :eq:`frequency_tracking` are both driven by the estimation error :math:`\boldsymbol{u}_\mathrm{g} - \hat{\boldsymbol{u}}_\mathrm{g}` of the PCC voltage.
-The gain selection:
+PLL in Estimated PCC Voltage Coordinates
+----------------------------------------
-.. math::
- k_\mathrm{p} = \frac{2 \zeta \omega_\mathrm{0,PLL}}{u_\mathrm{gN}} \qquad
- k_\mathrm{i} = \frac{\omega_\mathrm{0,PLL}^2}{u_\mathrm{gN}}
+The disturbance observer :eq:`pll` can be equivalently expressed in estimated PCC voltage coordinates, where :math:`\hat{\boldsymbol{u}}_\mathrm{g} = \hat{u}_\mathrm{g}` and :math:`\omega_\mathrm{c} = \mathrm{d} \hat{\vartheta}_\mathrm{g}/ \mathrm{d} t`, resulting in
-where :math:`\zeta` is the damping factor, :math:`\omega_\mathrm{0,PLL}` is the natural frequency of the PLL, and :math:`u_\mathrm{gN}` is the nominal grid voltage amplitude.
+.. math::
+ \frac{\mathrm{d}\hat{u}_\mathrm{g}}{\mathrm{d}t} &= \alpha_\mathrm{g} \left(\mathrm{Re}\{\boldsymbol{u}_\mathrm{g}\} - \hat{u}_\mathrm{g} \right) \\
+ \frac{\mathrm{d} \hat{\vartheta}_\mathrm{g}}{\mathrm{d} t} &= \hat{\omega}_\mathrm{g} + \frac{\alpha_\mathrm{g}}{\hat{u}_\mathrm{g}}\mathrm{Im}\{ \boldsymbol{u}_\mathrm{g} \} = \omega_\mathrm{c}
+ :label: pll_polar
-More details on the control methods used can be found in [#Kau1997]_.
+It can be seen that the first equation in :eq:`pll_polar` is low-pass filtering of the measured PCC voltage magnitude and the second equation is the conventional angle-tracking PLL. In these coordinates, the frequency tracking :eq:`frequency_tracking` reduces to
-This controller is implemented in the class :class:`motulator.grid.control.PLL`.
+.. math::
+ \frac{\mathrm{d} \hat{\omega}_\mathrm{g}}{\mathrm{d} t} = \frac{k_\omega}{\hat{u}_\mathrm{g} } \mathrm{Im}\{ \boldsymbol{u}_\mathrm{g} \}
+ :label: frequency_tracking_polar
-Power Synchronization
----------------------
+It can be noticed that the disturbance observer with the frequency tracking equals the conventional frequency-adaptive PLL [#Kau1997]_, with the additional feature of low-pass filtering the PCC voltage magnitude. The low-pass filtered PCC voltage can be used as a feedforward term in current control [#Har2009]_.
-In :doc:`/grid_examples/grid_forming/plot_gfm_rfpsc_13kva` a power synchronization loop (PSL) is used as a means of synchronizing with the grid. The dynamics of a synchronous machine are emulated, as the converter output active power is tied to the angle of the converter output voltage. This allows for synchronization of a converter with the grid without the use of a PLL. More details on the control method used can be found in [#Har2020]_.
+Linearized Closed-Loop System
+-----------------------------
-The PSL is implemented as
+The estimation-error dynamics are analyzed by means of linearization. Using the PCC voltage as an example, the small-signal deviation about the operating point is denoted by :math:`\Delta \boldsymbol{u}_\mathrm{g} = \boldsymbol{u}_\mathrm{g} - \boldsymbol{u}_\mathrm{g0}`, where :math:`\boldsymbol{u}_\mathrm{g0}` is the operating-point quantity. From :eq:`disturbance`--:eq:`frequency_tracking`, the linearized model for the estimation-error dynamics is obtained as
.. math::
- \frac{\mathrm{d}\vartheta_\mathrm{c}}{\mathrm{d}t} = \omega_\mathrm{g} + k_\mathrm{p} (p_\mathrm{g,ref} - p_\mathrm{g})
- :label: psl
+ \frac{\mathrm{d}\Delta \tilde{\boldsymbol{u}}_\mathrm{g}}{\mathrm{d}t} &= -\alpha_\mathrm{g}\Delta \tilde{\boldsymbol{u}}_\mathrm{g} + \mathrm{j}\boldsymbol{u}_\mathrm{g0} (\Delta \omega_\mathrm{g} - \Delta \hat{\omega}_\mathrm{g}) \\
+ \frac{\mathrm{d}\Delta \hat{\omega}_\mathrm{g}}{\mathrm{d}t} &= k_\omega\mathrm{Im}\left\{ \frac{\Delta \tilde{\boldsymbol{u}}_\mathrm{g}}{\boldsymbol{u}_\mathrm{g0}} \right\}
+ :label: linearized_model
+
+where :math:`\Delta \tilde{\boldsymbol{u}}_\mathrm{g} = \Delta\boldsymbol{u}_\mathrm{g} - \Delta \hat{\boldsymbol{u}}_\mathrm{g}` is the estimation error.
-where :math:`\vartheta_\mathrm{c}` is the converter output voltage angle, :math:`\omega_\mathrm{g}` the nominal grid angular frequency and :math:`k_\mathrm{p}` the active power control gain. Furthermore, :math:`p_\mathrm{g,ref}` and :math:`p_\mathrm{g}` are the reference and realized value for the converter active power output, respectively. The active power output is calculated from the measured converter current and the realized converter output voltage obtained from the PWM.
+First, assume that the grid frequency :math:`\omega_\mathrm{g}` is constant and the frequency tracking is disabled. From :eq:`linearized_model`, the closed-loop transfer function from the PCC voltage to its estimate becomes
-Disturbance Observer
---------------------
+.. math::
+ \frac{\Delta\hat{\boldsymbol{u}}_\mathrm{g}(s)}{\Delta\boldsymbol{u}_\mathrm{g}(s)} = \frac{\alpha_\mathrm{g}}{s + \alpha_\mathrm{g}}
+ :label: closed_loop_pll
+
+It can be realized that both the angle and magnitude of the PCC voltage estimate converge with the bandwidth :math:`\alpha_\mathrm{g}`.
-In :doc:`/grid_examples/grid_forming/plot_gfm_obs_13kva`, a disturbance observer-based control method is used, where the disturbance observer provides grid synchronization [#Nur2024]_. The observer is implemented in coordinates rotating at angular frequency :math:`\omega_\mathrm{c}` as
+Next, the frequency-tracking dynamics are also considered. From :eq:`linearized_model`, the closed-loop transfer function from the grid angular frequency to its estimate becomes
.. math::
- \frac{\mathrm{d}\hat{\boldsymbol{v}}_\mathrm{c}'}{\mathrm{d}t} &= (\boldsymbol{k}_\mathrm{o}
- + \mathrm{j}\hat{\omega}_\mathrm{g})\boldsymbol{e}_\mathrm{c} + \mathrm{j}(\hat{\omega}_\mathrm{g}
- - \omega_\mathrm{c})\hat{\boldsymbol{v}}_\mathrm{c}'\\
- \hat{\boldsymbol{v}}_\mathrm{c} &= \hat{\boldsymbol{v}}_\mathrm{c}'
- - \boldsymbol{k}_\mathrm{o}\hat{L}\boldsymbol{i}_\mathrm{c}
- :label: gfm_obs_eqs
+ \frac{\Delta\hat{\omega}_\mathrm{g}(s)}{\Delta\omega_\mathrm{g}(s)}
+ = \frac{k_\omega}{s^2 + \alpha_\mathrm{g}s + k_\omega}
+ :label: closed_loop_pll_frequency_tracking
-where :math:`\hat{\boldsymbol{v}}_\mathrm{c}` is the quasi-static converter output voltage estimate, :math:`\boldsymbol{k}_\mathrm{o}` the observer gain, :math:`\hat{\omega}_\mathrm{g}` the grid angular frequency estimate, :math:`\boldsymbol{e}_\mathrm{c}` the feedback correction term, :math:`\hat{L}` the total inductance estimate, and :math:`\boldsymbol{i}_\mathrm{c}` the measured converter current.
+Choosing :math:`k_\omega = \alpha_\mathrm{pll}^2` and :math:`\alpha_\mathrm{g} = 2\alpha_\mathrm{pll}` yields the double pole at :math:`s = -\alpha_\mathrm{pll}`, where :math:`\alpha_\mathrm{pll}` is the frequency-tracking bandwidth.
+
+This PLL is implemented in the class :class:`motulator.grid.control.PLL`. The :doc:`/grid_examples/grid_following/index` examples use the PLL to synchronize with the grid.
.. rubric:: References
-.. [#Kau1997] Kaura and Blasko, "Operation of a phase locked loop system under distorted utility conditions," in IEEE Trans. Ind. Appl., vol. 33, no. 1, pp. 58-63, Jan.-Feb. 1997, https://doi.org/10.1109/28.567077
+.. [#Kau1997] Kaura and Blasko, "Operation of a phase locked loop system under distorted utility conditions," in IEEE Trans. Ind. Appl., 1997, https://doi.org/10.1109/28.567077
+
+.. [#Fra1997] Franklin, Powell, Workman, "Digital Control of Dynamic Systems," 3rd ed., Menlo Park, CA: Addison-Wesley, 1997
-.. [#Har2020] Harnefors, Rahman, Hinkkanen, Routimo, "Reference-Feedforward Power-Synchronization Control," IEEE Trans. Power Electron., Sep. 2020, https://doi.org/10.1109/TPEL.2020.2970991
+.. [#Nur2024] Nurminen, Mourouvin, Hinkkanen, Kukkola, "Multifunctional grid-forming converter control based on a disturbance observer, "IEEE Trans. Power Electron., 2024, https://doi.org/10.1109/TPEL.2024.3433503
-.. [#Nur2024] Nurminen, Mourouvin, Hinkkanen, Kukkola, "Multifunctional grid-forming converter control based on a disturbance observer, "IEEE Trans. Power Electron., 2024, https://doi.org/10.1109/TPEL.2024.3433503
\ No newline at end of file
+.. [#Har2009] Harnefors, Bongiorno, "Current controller design for passivity of the input admittance," in Proc. EPE, 2009
\ No newline at end of file
diff --git a/docs/source/index.rst b/docs/source/index.rst
index dbe148647..85828c49c 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -1,7 +1,7 @@
*motulator:* Motor Drive and Grid Converter Simulator in Python
===============================================================
-This open-source software includes simulation models and controllers for electric machine drives and grid-connected converters. The machine models include an induction machine, a synchronous reluctance machine, and a permanent-magnet synchronous machine. Various models are provided for grid converter-related electrical subsystems such as an inductive-capacitive-inductive (LCL) filter connected to an inductive-resistive grid.
+This open-source software includes simulation models and controllers for electric machine drives and grid converter systems. The machine models include an induction machine, a synchronous reluctance machine, and a permanent-magnet synchronous machine. Various subsystem models are provided for modeling grid converter systems, such as an LCL filter connected to an inductive-resistive grid.
The system models are simulated in the continuous-time domain while the control methods run in discrete time. The default solver is the explicit Runge-Kutta method of order 5(4) from `scipy.integrate.solve_ivp`_. A number of control methods are provided as examples. The example methods aim to be simple yet feasible.
@@ -31,14 +31,13 @@ The system models are simulated in the continuous-time domain while the control
:name: models
:maxdepth: 1
- model/system
- model/converters
+ model/common
model/drive/index
model/grid/index
.. toctree::
:titlesonly:
- :caption: Design Notes on Control Methods
+ :caption: Control Methods
:name: controllers
:maxdepth: 1
@@ -48,7 +47,7 @@ The system models are simulated in the continuous-time domain while the control
.. toctree::
:titlesonly:
- :caption: Class references
+ :caption: Class Reference
:name: api
:maxdepth: 1
diff --git a/docs/source/installation.rst b/docs/source/installation.rst
index 10a0bad44..4ad08affb 100644
--- a/docs/source/installation.rst
+++ b/docs/source/installation.rst
@@ -40,10 +40,12 @@ Several powerful open-source IDEs are available for Python. The following instru
4) Create a virtual environment in the workspace using the instructions provided here: https://code.visualstudio.com/docs/python/environments.
5) Enable installation of optional dependencies from ``pyproject.toml`` (selecting at least ``dev`` is recommended). Alternatively, for installing the project with its core dependencies, you may run the command ``pip install .`` in the VS Code terminal after the virtual environment is created and activated (or to include optional dependencies, run ``pip install .[dev,doc]``).
-After completing the above steps, the virtual environment can be found in the ``.venv`` directory at the root of the repository. Now you should be able to run all the examples as well as to modify the existing code. When you start VS Code next time, it will automatically detect the virtual environment and use it.
+After completing the above steps, the virtual environment can be found in the ``.venv`` directory at the root of the repository. Now you should be able to run all the examples as well as to modify the existing code. When you start VS Code next time, it will automatically detect the virtual environment and use it. If you installed the ``dev`` dependencies, you can also use the interactive IPython console (click on the *Play* button dropdown menu in VS Code).
-If you installed the ``dev`` dependencies, you can also use the interactive IPython console (click on the *Play* button dropdown menu in VS Code). If you aim to work with the documentation, install also the ``doc`` dependencies. For previewing the documentation in VS Code, you can install the Esbonio extension: https://docs.esbon.io/en/latest/lsp/editors/vscode.html.
+If you use Windows, you may need to change the default terminal from the PowerShell to the Command Prompt (press Ctrl+Shift+P for the command palette and search for *Terminal: Select Default Profile*). We hope that these instructions allow you to create a virtual environment and start working on the project. Similar steps can be followed for other IDEs.
-If you use Windows, you may need to change the default terminal from the PowerShell to the Command Prompt (press Ctrl+Shift+P for the command palette and search for *Terminal: Select Default Profile*).
+Notes for Developers
+^^^^^^^^^^^^^^^^^^^^
+We recommend to install the ``dev`` dependencies. In this project, we use the YAPF Python code formatter (https://github.com/google/yapf), configured based on the PEP8 coding conventions (https://peps.python.org/pep-0008/). To enable YAPF in VS Code, you need to install the YAPF extension (https://marketplace.visualstudio.com/items?itemName=eeyore.yapf).
-We hope that these instructions allow you to create a virtual environment and start working on the project. Similar steps can be followed for other IDEs.
+If you aim to work with the documentation, install also the ``doc`` dependencies. For previewing the documentation in VS Code, you can install the Esbonio extension (https://marketplace.visualstudio.com/items?itemName=swyddfa.esbonio). Alternatively, you can build the documentation locally using the command ``make html`` in the ``docs`` directory. The documentation will be built in the ``docs/build`` directory.
\ No newline at end of file
diff --git a/docs/source/model/common.rst b/docs/source/model/common.rst
new file mode 100644
index 000000000..39993dba0
--- /dev/null
+++ b/docs/source/model/common.rst
@@ -0,0 +1,140 @@
+Common
+======
+
+Concepts and models common to machine drives and grid converter systems are described in this section.
+
+Sampled-Data Systems
+--------------------
+
+Machine drives and grid converter systems are sampled-data systems, consisting of a continuous-time system and a discrete-time control system as well as the interfaces between them [#Fra1997]_, [#Bus2015]_. The figure below shows a generic example system. The same architecture is used in *motulator*: the continuous-time system model is simulated in the continuous-time domain while the discrete-time control system runs in the discrete-time domain. The default solver is the explicit Runge-Kutta method of order 5(4) from `scipy.integrate.solve_ivp`_.
+
+.. _scipy.integrate.solve_ivp: https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html
+
+.. figure:: figs/system.svg
+ :width: 100%
+ :align: center
+ :alt: Block diagram of a sampled-data system
+ :target: .
+
+ Block diagram of a sampled-data system. Discrete signals and systems are shown in blue, and continuous signals and systems are shown in red.
+
+As mentioned, the physical components of a machine drive or a grid converter system are modeled as continuous-time systems. Such a system model comprises a power converter model along with other subsystem models, such as an electric machine model or grid model. In addition to the inputs :math:`\boldsymbol{q}(t)` from the control system, the continuous-time system may have external continuous-time inputs :math:`\boldsymbol{e}(t)`, such as a load torque or power fed to the DC bus. After the simulation, all continuous-time states :math:`\boldsymbol{x}(t)` are available for post-processing and plotting. In the :doc:`/drive_examples/index` and :doc:`/grid_examples/index` examples, the instances of continuous-time system model classes are named `mdl`.
+
+A discrete-time control system (named `ctrl` in the examples) contains control algorithms, such as a speed controller and current controller. The reference signals :math:`\boldsymbol{r}(k)` could contain, e.g., a speed reference of an electric machine or a power reference of a grid converter. The feedback signals :math:`\boldsymbol{y}(k)` typically contain at least the measured DC-bus voltage and converter phase currents.
+
+Digital control systems typically have a computational delay of one sampling period, :math:`N=1`. The PWM block shown in the figure models the carrier comparison. If the switching ripple is not of interest in simulations, the carrier comparison can be replaced with a zero-order hold (ZOH).
+
+Space Vectors
+-------------
+
+The system models in *motulator* apply peak-valued complex space vectors, marked with boldface in the following equations [#Hin2024]_. As an example, the space vector of the converter current is
+
+.. math::
+ \boldsymbol{i}^\mathrm{s}_\mathrm{c} = \frac{2}{3}\left(i_\mathrm{a} + i_\mathrm{b}\mathrm{e}^{\mathrm{j}2\pi/3} + i_\mathrm{c}\mathrm{e}^{\mathrm{j} 4\pi/3}\right)
+ :label: space_vector
+
+where :math:`i_\mathrm{a}`, :math:`i_\mathrm{b}`, and :math:`i_\mathrm{c}` are the phase currents, which may vary freely in time. In our notation, the subscript c refers to the converter-side AC quantities and the superscript s refers to the stationary coordinates. In addition, the subscript c is also used to denote the phase :math:`c` quantities, but the meaning should be clear from the context.
+
+The space vector does not include the zero-sequence component, which is defined as
+
+.. math::
+ i_0 = \frac{1}{3}\left(i_\mathrm{a} + i_\mathrm{b} + i_\mathrm{c}\right)
+ :label: zero_sequence
+
+Even though the zero-sequence voltage exists at the output of typical converters, there is no path for the zero-sequence current to flow (i.e., :math:`i_0 = 0`), if the three-phase system is delta-connected or its star point is not connected. Consequently, the zero-sequence voltage cannot produce power or torque.
+
+The space vector transformation in :eq:`space_vector` is implemented in the function :func:`motulator.common.utils.abc2complex` and its inverse transformation in the function :func:`motulator.common.utils.complex2abc`.
+
+Voltage-Source Converter
+------------------------
+
+The figure below shows a three-phase two-level voltage-source converter, where :math:`u_\mathrm{dc}` is the DC-bus voltage, :math:`i_\mathrm{dc}` is the external DC current, and :math:`C_\mathrm{dc}` is the DC-bus capacitance. This converter can operate both as an inverter and a rectifier, depending on the direction of the power flow.
+
+.. figure:: figs/inverter.svg
+ :width: 100%
+ :align: center
+ :alt: Three-phase two-level voltage-source converter
+ :target: .
+
+ Three-phase two-level voltage-source converter. The negative potential of the DC bus is marked with N and the output terminals with a, b, and c.
+
+Assuming ideal transistors and diodes, the converter can be modeled with the equivalent circuit shown in the figure below, in which the legs are modeled as bi-positional switches. Each changeover switch is connected to either negative or positive potential of the DC bus, and the switching phenomena are assumed to be infinitely fast. The state of each switch is defined using the switching state, which, using phase :math:`a` as an example, is :math:`q_\mathrm{a} = 0` when the switch is connected to the negative potential and
+:math:`q_\mathrm{a} = 1` when the switch is connected to the positive potential.
+
+.. figure:: figs/pwm_inverter.svg
+ :width: 100%
+ :align: center
+ :alt: Voltage-source converter and carrier comparison
+ :target: .
+
+ Equivalent circuit of a three-phase voltage-source converter, connected to a generic three-phase load. The neutral point of the load is marked with n. In this example, the positions of the bi-positional switches correspond to the instantaneous switching states :math:`q_\mathrm{a} = 1`, :math:`q_\mathrm{b} = 0`, and :math:`q_\mathrm{c}=0`.
+
+By default, the DC-bus voltage is constant, i.e., the DC-bus capacitor is replaced with a constant DC voltage source. Alternatively, if the DC bus is fed from an external current source :math:`i_\mathrm{dc}`, the DC-bus dynamics are modeled as
+
+.. math::
+ C_\mathrm{dc}\frac{\mathrm{d}u_\mathrm{dc}}{\mathrm{d} t} = i_\mathrm{dc} - i'_\mathrm{dc}
+ :label: DC_bus_model
+
+where the converter-side DC current depends on the phase currents :math:`i_\mathrm{a}`, :math:`i_\mathrm{b}`, and :math:`i_\mathrm{c}` as
+
+.. math::
+ i'_\mathrm{dc} = q_\mathrm{a} i_\mathrm{a} + q_\mathrm{b} i_\mathrm{b} + q_\mathrm{c} i_\mathrm{c}
+ :label: DC_current
+
+The voltage-source converter model is provided in the class :class:`motulator.drive.model.VoltageSourceConverter`. This model can be extended with a diode bridge model, see :doc:`/model/drive/diode_bridge`.
+
+Carrier Comparison
+^^^^^^^^^^^^^^^^^^
+
+In pulse-width modulation (PWM), carrier comparison is commonly used to generate instantaneous switching state signals :math:`q_\mathrm{a}`, :math:`q_\mathrm{b}`, and :math:`q_\mathrm{c}` from duty ratios :math:`d_\mathrm{a}`, :math:`d_\mathrm{b}`, and :math:`d_\mathrm{c}`. The duty ratios are continuous signals in the range [0, 1] while the switching states are either 0 or 1.
+
+The figure below shows the principle of carrier comparison. The logic shown in the figure is implemented in the class :class:`motulator.common.model.CarrierComparison`, where the switching instants are explicitly computed in the beginning of each sampling period (instead of searching for zero crossings), allowing faster simulations.
+
+.. figure:: figs/carrier_comparison.svg
+ :width: 100%
+ :align: center
+ :alt: Carrier comparison
+ :target: .
+
+ Carrier comparison. The duty ratios are :math:`d_\mathrm{a}`, :math:`d_\mathrm{b}`, and :math:`d_\mathrm{c}` are constant over the sampling period :math:`T_\mathrm{s}` (or, optionally, over the the switching period :math:`T_\mathrm{sw} = 2T_\mathrm{s}`). The carrier signal is the same for all three phases and varies between 0 and 1.
+
+The zero-sequence voltage does not affect the phase currents if the neutral of the load is not connected. Therefore, the reference potential of the phase voltages can be freely chosen when computing the space vector of the converter output voltage. The converter voltage vector in stationary coordinates is
+
+.. math::
+ \boldsymbol{u}_\mathrm{c}^\mathrm{s} &= \frac{2}{3}\left(u_\mathrm{an} + u_\mathrm{bn}\mathrm{e}^{\mathrm{j}2\pi/3} + u_\mathrm{cn}\mathrm{e}^{\mathrm{j} 4\pi/3}\right) \\
+ &= \frac{2}{3}\left(u_\mathrm{aN} + u_\mathrm{bN}\mathrm{e}^{\mathrm{j} 2\pi/3} + u_\mathrm{cN}\mathrm{e}^{\mathrm{j} 4\pi/3}\right) \\
+ &= \underbrace{\frac{2}{3}\left(q_\mathrm{a} + q_\mathrm{b}\mathrm{e}^{\mathrm{j} 2\pi/3} + q_\mathrm{c}\mathrm{e}^{\mathrm{j} 4\pi/3}\right)}_{\boldsymbol{q}_\mathrm{c}^\mathrm{s}}u_\mathrm{dc}
+ :label: carrier_comparison
+
+where :math:`\boldsymbol{q}_\mathrm{c}^\mathrm{s}` is the switching-state space vector.
+
+.. note::
+ The carrier comparison is compatible with all standard pulse-width modulation (PWM) methods, such as space-vector PWM (see :class:`motulator.common.control.PWM`) and discontinuous PWM methods [#Hol1994]_, [#Hav1999]_.
+
+ The sampling period :math:`T_\mathrm{s}` is returned by the control method, and it does not need to be constant.
+
+ If the zero sequence is of interest, it could be easily added to the converter model.
+
+Switching-Cycle Averaging
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If the switching ripple is not of interest in simulations, the carrier comparison can be replaced with zero-order hold (ZOH) of the duty ratios. In this case, the output voltage vector is
+
+.. math::
+ \boldsymbol{u}_\mathrm{c}^\mathrm{s} = \underbrace{\frac{2}{3}\left(d_\mathrm{a} + d_\mathrm{b}\mathrm{e}^{\mathrm{j} 2\pi/3} + d_\mathrm{c}\mathrm{e}^{\mathrm{j} 4\pi/3}\right)}_{\boldsymbol{d}_\mathrm{c}^\mathrm{s}}u_\mathrm{dc}
+ :label: switching_cycle_averaging
+
+where :math:`\boldsymbol{d}_\mathrm{c}^\mathrm{s}` is the duty ratio space vector. This ZOH is the default option in most of :doc:`/drive_examples/index` and :doc:`/grid_examples/index` examples.
+
+.. rubric:: References
+
+.. [#Fra1997] Franklin, Powell, Workman, "Digital Control of Dynamic Systems," Menlo Park, CA, USA: Addison-Wesley, 1997
+
+.. [#Bus2015] Buso, Mattavelli, "Digital Control in Power Electronics," 2nd ed., Morgan & Claypool, 2015, https://doi.org/10.2200/S00637ED1V01Y201503PEL007
+
+.. [#Hin2024] Hinkkanen, Harnefors, Kukkola, "Fundamentals of Electric Machine Drives," lecture notes, 2024, https://doi.org/10.5281/zenodo.10609166
+
+.. [#Hol1994] Holtz, "Pulsewidth modulation for electronic power conversion," Proc. IEEE, 1994, https://doi.org/10.1109/5.301684
+
+.. [#Hav1999] Hava, Kerkman, Lipo, "Simple analytical and graphical methods for carrier-based PWM-VSI drives," IEEE Trans. Ind. Appl., 1999, https://doi.org/10.1109/63.737592
+
diff --git a/docs/source/model/converters.rst b/docs/source/model/converters.rst
deleted file mode 100644
index b56174b75..000000000
--- a/docs/source/model/converters.rst
+++ /dev/null
@@ -1,122 +0,0 @@
-Converters
-==========
-
-Voltage-Source Converter
-------------------------
-
-The figure below shows a three-phase two-level voltage-source converter, where :math:`u_\mathrm{dc}` is the DC-bus voltage, :math:`i_\mathrm{dc}` is the external DC current, :math:`i'_\mathrm{dc}` is the converter DC current and :math:`C_\mathrm{dc}` is the DC-bus capacitance. This converter can operate both as an inverter and a rectifier, depending on the direction of the power flow.
-
-.. figure:: figs/inverter.svg
- :width: 100%
- :align: center
- :alt: Three-phase two-level voltage-source converter
- :target: .
-
- Three-phase two-level voltage-source converter.
-
-The figure below then shows the equivalent model for the three-phase voltage-source converter, where ideal switches are assumed. In the equivalent model, each changeover switch is connected to either negative or positive potential of the DC bus and the switching phenomena are assumed to be infinitely fast. This converter model is provided in the class :class:`motulator.drive.model.VoltageSourceConverter`.
-
-.. figure:: figs/inverter_eq.svg
- :width: 100%
- :align: center
- :alt: Equivalent model of three-phase voltage-source converter
- :target: .
-
- Equivalent model of a three-phase voltage-source converter.
-
-By default, the DC-bus voltage is stiff, i.e. the capacitor is replaced by an ideal voltage source. Alternatively, the capacitive dynamics of the DC-bus can be simulated. The model is implemented as
-
-.. math::
- C_{dc}\frac{\mathrm{d}u_\mathrm{dc}}{\mathrm{d} t}
- = i_\mathrm{dc}
- - i'_\mathrm{dc}
- :label: DC_bus_model
-
-where the converter DC current is calculated from the converter phase currents and switching states as
-
-.. math::
- i'_\mathrm{dc}
- = q_\mathrm{a} i_\mathrm{a} + q_\mathrm{b} i_\mathrm{b} + q_\mathrm{c} i_\mathrm{c}
- :label: DC_current
-
-Six-Pulse Diode Bridge
-----------------------
-
-The figure below shows a six-pulse diode bridge rectifier, where the inductor :math:`L_\mathrm{dc}` is placed in the DC link. For simplicity, a three-phase supply voltage is assumed to be stiff. The voltage-source converter described above is extended with this diode bridge model in the class :class:`motulator.drive.model.FrequencyConverter`.
-
-.. figure:: figs/diode_bridge.svg
- :width: 100%
- :align: center
- :alt: Six-pulse diode bridge rectifier an three-phase supply voltage
- :target: .
-
- Six-pulse diode bridge rectifier.
-
-The model is implemented as
-
-.. math::
- L_{\mathrm{dc}} \frac{\mathrm{d}i_{L}}{\mathrm{d}t}
- = u_{\mathrm{di}} - u_\mathrm{dc}
- :label: diode_bridge
-
-where :math:`i_\mathrm{L}` is the DC-bus current, :math:`u_\mathrm{di}` is the voltage over the diode bridge, :math:`u_\mathrm{dc}` is the DC-bus voltage, and :math:`L_{\mathrm{dc}}` is the DC link inductance.
-
-Examples using the six-pulse diode bridge can be found in :doc:`/drive_examples/vhz/plot_vhz_ctrl_im_2kw` and
-:doc:`/drive_examples/vector/plot_vector_ctrl_pmsm_2kw_diode`
-
-Carrier Comparison
-------------------
-
-The figure below shows a converter equipped with a generic three-phase load. In pulse-width modulation (PWM), carrier comparison is commonly used to generate instantaneous switching state signals :math:`q_\mathrm{a}`, :math:`q_\mathrm{b}`, and :math:`q_\mathrm{c}` from duty ratios :math:`d_\mathrm{a}`, :math:`d_\mathrm{b}`, and :math:`d_\mathrm{c}`. The duty ratios are continuous signals in the range [0, 1} while the switching states are either 0 or 1.
-
-.. figure:: figs/pwm_inverter.svg
- :width: 100%
- :align: center
- :alt: Voltage-source converter and carrier comparison
- :target: .
-
- Instantaneous switching states are defined by the carrier comparison. In this example, the switching states are :math:`q_\mathrm{a}=1`, :math:`q_\mathrm{b}=0`, and :math:`q_\mathrm{c}=0`.
-
-The figure below shows the principle of carrier comparison. The logic shown in the figure is implemented in the class :class:`motulator.common.model.CarrierComparison`, where the switching instants are explicitly computed in the beginning of each sampling period (instead of searching for zero crossings), allowing faster simulations.
-
-.. figure:: figs/carrier_comparison.svg
- :width: 100%
- :align: center
- :alt: Carrier comparison
- :target: .
-
- Carrier comparison. The duty ratios are :math:`d_\mathrm{a}`, :math:`d_\mathrm{b}`, and :math:`d_\mathrm{c}` are constant over the sampling period :math:`T_\mathrm{s}` (or, optionally, over the the switching period :math:`T_\mathrm{sw}=2T_\mathrm{s}`). The carrier signal is the same for all three phases and varies between 0 and 1.
-
-The zero-sequence voltage does not affect the phase currents if the neutral of the load is not connected. Therefore, the reference potential of the phase voltages can be freely chosen when computing the space vector of the converter output voltage. The converter voltage vector in stationary coordinates is
-
-.. math::
- \boldsymbol{u}_\mathrm{c}^\mathrm{s} &= \frac{2}{3}\left(u_\mathrm{an} + u_\mathrm{bn}\mathrm{e}^{\mathrm{j}2\pi/3} + u_\mathrm{cn}\mathrm{e}^{\mathrm{j} 4\pi/3}\right) \\
- &= \frac{2}{3}\left(u_\mathrm{aN} + u_\mathrm{bN}\mathrm{e}^{\mathrm{j} 2\pi/3} + u_\mathrm{cN}\mathrm{e}^{\mathrm{j} 4\pi/3}\right) \\
- &= \underbrace{\frac{2}{3}\left(q_\mathrm{a} + q_\mathrm{b}\mathrm{e}^{\mathrm{j} 2\pi/3} + q_\mathrm{c}\mathrm{e}^{\mathrm{j} 4\pi/3}\right)}_{\boldsymbol{q}_\mathrm{c}^\mathrm{s}}u_\mathrm{dc}
- :label: carrier_comparison
-
-where :math:`\boldsymbol{q}_\mathrm{c}^\mathrm{s}` is the switching-state space vector.
-
-.. note::
- The carrier comparison is compatible with all standard pulse-width modulation (PWM) methods, such as space-vector PWM (see :class:`motulator.common.control.PWM`) and discontinuous PWM methods [#Hol1994]_, [#Hav1999]_.
-
- The sampling period :math:`T_\mathrm{s}` is returned by the control method, and it does not need to be constant.
-
- If the zero sequence is of interest, it could be easily added to the converter model.
-
-Switching-Cycle Averaging
--------------------------
-
-If the switching ripple is not of interest in simulations, the carrier comparison can be replaced with zero-order hold (ZOH) of the duty ratios. In this case, the output voltage vector is
-
-.. math::
- \boldsymbol{u}_\mathrm{c}^\mathrm{s} = \underbrace{\frac{2}{3}\left(d_\mathrm{a} + d_\mathrm{b}\mathrm{e}^{\mathrm{j} 2\pi/3} + d_\mathrm{c}\mathrm{e}^{\mathrm{j} 4\pi/3}\right)}_{\boldsymbol{d}_\mathrm{c}^\mathrm{s}}u_\mathrm{dc}
- :label: switching_cycle_averaging
-
-where :math:`\boldsymbol{d}_\mathrm{c}^\mathrm{s}` is the duty ratio space vector. This ZOH is the default option in most of :doc:`/drive_examples/index` and :doc:`/grid_examples/index`.
-
-.. rubric:: References
-
-.. [#Hol1994] Holtz, "Pulsewidth modulation for electronic power conversion," Proc. IEEE, 1994, https://doi.org/10.1109/5.301684
-
-.. [#Hav1999] Hava, Kerkman, Lipo, "Simple analytical and graphical methods for carrier-based PWM-VSI drives," IEEE Trans. Ind. Appl., 1999, https://doi.org/10.1109/63.737592
\ No newline at end of file
diff --git a/docs/source/model/drive/ac_filter.rst b/docs/source/model/drive/ac_filter.rst
index 5542d5bae..5c726cbdd 100644
--- a/docs/source/model/drive/ac_filter.rst
+++ b/docs/source/model/drive/ac_filter.rst
@@ -1,7 +1,7 @@
Output LC Filter
================
-This document describes a continuous-time model of an LC filter, which may be used between the converter and the electric machine in some applications [#Sal2006]_. Space vectors are used to represent the three-phase quantities. The subscript c and s refer to the converter-side and the stator-side quantities, respectively. The superscript s refers to the stationary coordinates.
+An LC filter may be used between the voltage-source converter and the electric machine in some applications [#Sal2006]_. The subscripts c and s refer to the converter-side and stator-side quantities, respectively. The superscript s refers to the stationary coordinates.
.. figure:: ../figs/lc_filter.svg
:width: 100%
@@ -14,14 +14,14 @@ This document describes a continuous-time model of an LC filter, which may be us
A dynamic model of the filter is
.. math::
- L_\mathrm{fc} \frac{\mathrm{d}\boldsymbol{i}_\mathrm{c}^\mathrm{s}}{\mathrm{d} t}
+ L_\mathrm{f} \frac{\mathrm{d}\boldsymbol{i}_\mathrm{c}^\mathrm{s}}{\mathrm{d} t}
&= \boldsymbol{u}_\mathrm{c}^\mathrm{s} - \boldsymbol{u}_\mathrm{s}^\mathrm{s}
- - R_\mathrm{fc} \boldsymbol{i}_\mathrm{c}^\mathrm{s} \\
+ - R_\mathrm{f} \boldsymbol{i}_\mathrm{c}^\mathrm{s} \\
C_\mathrm{f} \frac{\mathrm{d}\boldsymbol{u}_\mathrm{s}^\mathrm{s}}{\mathrm{d} t}
&= \boldsymbol{i}_\mathrm{c}^\mathrm{s} - \boldsymbol{i}_\mathrm{s}^\mathrm{s}
:label: LC_filter_model
-where :math:`L_\mathrm{fc}` is the filter inductance, :math:`R_\mathrm{fc}` is the series resistance of the filter inductor and :math:`C_\mathrm{f}` the filter capacitance. Furthermore, :math:`\boldsymbol{i}_\mathrm{c}^\mathrm{s}` is the converter current, :math:`\boldsymbol{i}_\mathrm{s}^\mathrm{s}` is the stator current, :math:`\boldsymbol{u}_\mathrm{c}^\mathrm{s}` is the converter voltage,and :math:`\boldsymbol{u}_\mathrm{s}^\mathrm{s}` is the capacitor voltage (corresponding to the stator voltage).
+where :math:`L_\mathrm{f}` is the filter inductance, :math:`R_\mathrm{f}` is the series resistance of the filter inductor, and :math:`C_\mathrm{f}` the filter capacitance. Furthermore, :math:`\boldsymbol{i}_\mathrm{c}^\mathrm{s}` is the converter current, :math:`\boldsymbol{i}_\mathrm{s}^\mathrm{s}` is the stator current, :math:`\boldsymbol{u}_\mathrm{c}^\mathrm{s}` is the converter voltage, and :math:`\boldsymbol{u}_\mathrm{s}^\mathrm{s}` is the capacitor voltage (corresponding to the stator voltage).
The filter model is implemented in the class :class:`motulator.drive.model.LCFilter`. For its usage, see the example :doc:`/drive_examples/vhz/plot_vhz_ctrl_im_2kw_lc`.
diff --git a/docs/source/model/drive/diode_bridge.rst b/docs/source/model/drive/diode_bridge.rst
new file mode 100644
index 000000000..6e579db3c
--- /dev/null
+++ b/docs/source/model/drive/diode_bridge.rst
@@ -0,0 +1,23 @@
+Six-Pulse Diode Bridge
+======================
+
+The figure below shows a six-pulse diode bridge rectifier, where the inductor :math:`L_\mathrm{dc}` is placed in the DC link. For simplicity, a three-phase supply voltage is assumed to be stiff. The DC current dynamics are
+
+.. math::
+ L_\mathrm{dc} \frac{\mathrm{d}i_\mathrm{L}}{\mathrm{d}t}
+ = u_\mathrm{di} - u_\mathrm{dc}
+ :label: diode_bridge
+
+where :math:`i_\mathrm{L}` is the DC-bus current, :math:`u_\mathrm{di}` is the voltage over the diode bridge, :math:`u_\mathrm{dc}` is the DC-bus voltage, and :math:`L_{\mathrm{dc}}` is the DC-bus inductance.
+
+.. figure:: ../figs/diode_bridge.svg
+ :width: 100%
+ :align: center
+ :alt: Six-pulse diode bridge rectifier an three-phase supply voltage
+ :target: .
+
+ Six-pulse diode bridge rectifier.
+
+The voltage-source converter described in :doc:`/model/common` is extended with this diode bridge model in the class :class:`motulator.drive.model.FrequencyConverter`. Examples using the six-pulse diode bridge can be found in :doc:`/drive_examples/vhz/plot_vhz_ctrl_im_2kw` and :doc:`/drive_examples/vector/plot_vector_ctrl_pmsm_2kw_diode`.
+
+
diff --git a/docs/source/model/drive/index.rst b/docs/source/model/drive/index.rst
index ee7631b95..049ee8ae9 100644
--- a/docs/source/model/drive/index.rst
+++ b/docs/source/model/drive/index.rst
@@ -1,12 +1,11 @@
-************
-Drive System
-************
-
-Drive-specific models
+******
+Drives
+******
.. toctree::
:maxdepth: 2
machines
mechanics
- ac_filter
\ No newline at end of file
+ ac_filter
+ diode_bridge
\ No newline at end of file
diff --git a/docs/source/model/figs/dc_bus.svg b/docs/source/model/figs/dc_bus.svg
deleted file mode 100644
index 759da02d2..000000000
--- a/docs/source/model/figs/dc_bus.svg
+++ /dev/null
@@ -1,1113 +0,0 @@
-
-
diff --git a/docs/source/model/figs/diode_bridge.svg b/docs/source/model/figs/diode_bridge.svg
index c0fc0f350..f2bf20f80 100644
--- a/docs/source/model/figs/diode_bridge.svg
+++ b/docs/source/model/figs/diode_bridge.svg
@@ -4,7 +4,7 @@
height="115"
id="svg3470"
sodipodi:version="0.32"
- inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="diode_bridge.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
@@ -27,9 +27,9 @@
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="1.4142136"
- inkscape:cx="173.24116"
- inkscape:cy="35.708893"
+ inkscape:zoom="2.8284272"
+ inkscape:cx="172.35727"
+ inkscape:cy="37.299882"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="true"
@@ -37,10 +37,10 @@
inkscape:object-paths="true"
inkscape:object-points="false"
inkscape:grid-bbox="false"
- inkscape:window-width="1680"
- inkscape:window-height="979"
- inkscape:window-x="-8"
- inkscape:window-y="-8"
+ inkscape:window-width="2560"
+ inkscape:window-height="1403"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
width="349.29px"
height="359.4px"
showguides="true"
@@ -311,10 +311,6 @@
style="display:inline;opacity:1"
inkscape:label="Labels"
transform="translate(305, -105)">
-
-
-
-
-
-
-
-
-
@@ -545,15 +505,6 @@
d="m -200.70089,138.99997 h -7.27272"
sodipodi:nodetypes="cc"
id="path3178" />
-
-
@@ -692,7 +634,7 @@
inkscape:export-ydpi="300" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ d="M 22.999999,209.99999 -99.999999,210 -100,130 h 37.5"
+ id="path1"
+ sodipodi:nodetypes="cccc" />
+
+
+
+
+
+
+
+
diff --git a/docs/source/model/figs/inverter.svg b/docs/source/model/figs/inverter.svg
index acd520b6f..9769abfaf 100644
--- a/docs/source/model/figs/inverter.svg
+++ b/docs/source/model/figs/inverter.svg
@@ -4,7 +4,7 @@
height="110"
id="svg3470"
sodipodi:version="0.32"
- inkscape:version="1.3.2 (091e20e, 2023-11-25)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="inverter.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
@@ -26,9 +26,9 @@
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="2.2766006"
- inkscape:cx="231.26586"
- inkscape:cy="34.700861"
+ inkscape:zoom="4.5532012"
+ inkscape:cx="234.67006"
+ inkscape:cy="62.263886"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="true"
@@ -36,10 +36,10 @@
inkscape:object-paths="true"
inkscape:object-points="false"
inkscape:grid-bbox="false"
- inkscape:window-width="1496"
- inkscape:window-height="749"
+ inkscape:window-width="2560"
+ inkscape:window-height="1403"
inkscape:window-x="0"
- inkscape:window-y="38"
+ inkscape:window-y="0"
width="349.29px"
height="359.4px"
showguides="true"
@@ -52,7 +52,7 @@
inkscape:bbox-paths="true"
inkscape:snap-global="true"
inkscape:snap-guide="true"
- inkscape:window-maximized="0"
+ inkscape:window-maximized="1"
inkscape:snap-grids="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-to-guides="false"
@@ -422,6 +422,13 @@
style="stroke-width:0" />
+
+
+
@@ -446,7 +453,7 @@
id="layer2"
style="display:inline;opacity:1"
inkscape:label="Labels"
- transform="translate(215,-125)">
+ transform="translate(215, -125)">
+ d="M 0.093661,176.83843 Z" />
-
+ d="M 120.09366,176.83843 Z" />
-
+ d="m 135.09366,212.50001 -0.0468,14.99999 -214.953215,0"
+ sodipodi:nodetypes="ccc" />
-
+ transform="matrix(1.0011488,0,0,0.99999998,-140.01553,74.095846)">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ inkscape:label=""
+ transform="translate(-32.280963,128.30501)"
+ id="g1053">
+ id="g23"
+ transform="matrix(1.33333,0,0,1.33333,-0.395833,0.0221666)">
+ id="use21"
+ transform="translate(0,7.4889998)">
+ id="path41" />
+ id="g27"
+ transform="matrix(1.33333,0,0,1.33333,-0.395833,0.0221666)">
+ id="use25"
+ transform="translate(3.4319999,3.8740001)">
+ id="path45" />
+ clip-path="url(#clipPath2128)"
+ id="g1051"
+ transform="matrix(1.33333,0,0,1.33333,-0.395833,0.0221666)">
-
+ fill="#000000"
+ fill-opacity="1"
+ id="g1049">
+
+
+
+
+
+
+
+
+
+
+
-
+ style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.8;stroke-opacity:1"
+ id="g821">
+
+
+
diff --git a/docs/source/model/figs/inverter_eq.svg b/docs/source/model/figs/inverter_eq.svg
deleted file mode 100644
index 878dad63c..000000000
--- a/docs/source/model/figs/inverter_eq.svg
+++ /dev/null
@@ -1,1461 +0,0 @@
-
-
diff --git a/docs/source/model/figs/l_filter.svg b/docs/source/model/figs/l_filter.svg
index e745df27a..9f0744b02 100644
--- a/docs/source/model/figs/l_filter.svg
+++ b/docs/source/model/figs/l_filter.svg
@@ -4,7 +4,7 @@
height="100"
id="svg3470"
sodipodi:version="0.32"
- inkscape:version="1.3.2 (091e20e, 2023-11-25)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="l_filter.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
@@ -27,8 +27,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.2766006"
- inkscape:cx="212.8173"
- inkscape:cy="20.644816"
+ inkscape:cx="175.04168"
+ inkscape:cy="92.023168"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="true"
@@ -36,10 +36,10 @@
inkscape:object-paths="true"
inkscape:object-points="false"
inkscape:grid-bbox="false"
- inkscape:window-width="1416"
- inkscape:window-height="663"
+ inkscape:window-width="2560"
+ inkscape:window-height="1403"
inkscape:window-x="0"
- inkscape:window-y="38"
+ inkscape:window-y="0"
width="349.29px"
height="359.4px"
showguides="true"
@@ -52,7 +52,7 @@
inkscape:bbox-paths="true"
inkscape:snap-global="true"
inkscape:snap-guide="true"
- inkscape:window-maximized="0"
+ inkscape:window-maximized="1"
inkscape:snap-grids="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-to-guides="false"
@@ -88,25 +88,6 @@
-
-
-
-
-
-
-
-
-
-
- image/svg+xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ id="g49"
+ style="stroke-width:0">
+
-
-
-
+
+
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
+
+
+
+
-
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id="g3818-3-3-8-7-5-0-2-9-7-1-3-1-8-3">
@@ -2039,102 +2525,93 @@
+ id="g27343-4">
+ id="g27347-2">
-
-
+ id="g27350-4">
-
-
+ id="g3818-3-3-8-7-5-0-2-9-7-1-3-1-8-8-5">
+
+
+
@@ -2142,42 +2619,61 @@
+ id="g32073-2">
+ id="g32077-3">
+
+
+
+
+
+ id="g3818-3-3-8-7-5-0-2-9-7-1-3-1-2-5-4-5">
@@ -2219,84 +2715,76 @@
+ id="g101016-3-4">
+ id="g101020-3-7">
+ id="g3818-3-3-8-7-5-0-2-9-7-1-3-1-8-8-83-5-7-3">
-
-
-
@@ -2304,140 +2792,93 @@
-
-
-
-
-
+ id="g108093-8-7">
+ id="g108097-8-8">
-
-
+ id="path32135-7" />
+
+ id="path19709" />
-
-
-
-
+ id="g8285-0-8">
+ id="g24533-2-4-6-4-1">
+ id="path24539-0-8-2-2-6" />
-
+ style="display:inline;fill:none;stroke:#000000;stroke-width:0.999993;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 130,195 v 20 H -80"
+ id="path37746-4"
+ sodipodi:nodetypes="ccc" />
+ id="path50958-3" />
+ id="g4554-3"
+ ns3:jacobian_sqrt="1.06667"
+ style="display:inline">
+ id="id-a2cc729c-875a-425d-8155-06a3230a2f7a-3">
+ id="g6050">
+ id="g6044">
+ id="path6042" />
+ id="g6048">
+ id="path6046" />
+ id="g6862-8">
+ id="id-e6552432-130b-4577-a5b8-e81fa4f5e113-9" />
+ id="g2829-7">
+ id="id-a3d50fa8-1b59-42de-94f7-f074db03cf92-7" />
+ id="g7776-6">
+ id="id-0b597772-c453-4d84-9556-11d170312f93-4" />
+
+
+
-
+ inkscape:label=""
+ transform="translate(-98.208328,178.71646)"
+ id="g10029"
+ style="display:inline">
+
-
-
-
-
-
-
+ id="use18"
+ transform="translate(0,6.618)">
+
+
+
+
+
+
+
+
+
+
+ id="use26"
+ transform="translate(6.7849998,9.0810003)">
+ id="path10024" />
-
+
+
+
+ id="g12348"
+ transform="matrix(1.33333,0,0,1.33333,-0.416667,0.143167)">
+ id="g12346"
+ transform="translate(0,7.4460001)">
+ d="m 3.328125,-6.4375 c 0,-0.265625 -0.203125,-0.484375 -0.484375,-0.484375 -0.375,0 -0.703125,0.359375 -0.703125,0.6875 0,0.265625 0.1875,0.484375 0.484375,0.484375 0.359375,0 0.703125,-0.34375 0.703125,-0.6875 z m 0.25,4.96875 c 0,-0.140625 -0.15625,-0.140625 -0.234375,-0.140625 -0.125,0 -0.1875,0 -0.234375,0.125 -0.3125,1.046875 -0.8125,1.203125 -1.03125,1.203125 -0.09375,0 -0.15625,-0.03125 -0.15625,-0.21875 0,-0.234375 0.09375,-0.453125 0.328125,-1.046875 l 0.671875,-1.71875 C 2.96875,-3.40625 3,-3.515625 3,-3.609375 3,-4.140625 2.484375,-4.5 1.859375,-4.5 0.828125,-4.5 0.3125,-3.171875 0.3125,-2.953125 c 0,0.140625 0.15625,0.140625 0.25,0.140625 0.109375,0 0.1875,0 0.21875,-0.125 0.3125,-1.046875 0.828125,-1.203125 1.03125,-1.203125 0.09375,0 0.15625,0.03125 0.15625,0.21875 0,0.21875 -0.078125,0.4375 -0.328125,1.046875 l -0.65625,1.71875 c -0.0625,0.125 -0.09375,0.25 -0.09375,0.34375 0,0.515625 0.53125,0.890625 1.140625,0.890625 1.046875,0 1.546875,-1.328125 1.546875,-1.546875 z m 0,0"
+ id="path12344" />
+ id="g12353"
+ transform="matrix(1.33333,0,0,1.33333,-0.416667,0.143167)">
+ id="g12351"
+ transform="translate(4.033,3.0020001)">
+ d="m 2.640625,-2.921875 c 0,-0.125 0,-0.1875 -0.09375,-0.1875 -0.03125,0 -0.046875,0 -0.140625,0.078125 -0.015625,0.015625 -0.078125,0.078125 -0.125,0.109375 -0.21875,-0.140625 -0.46875,-0.1875 -0.734375,-0.1875 -1,0 -1.234375,0.53125 -1.234375,0.875 0,0.21875 0.09375,0.40625 0.265625,0.546875 0.265625,0.21875 0.53125,0.265625 0.96875,0.34375 0.34375,0.0625 0.90625,0.15625 0.90625,0.625 0,0.265625 -0.1875,0.59375 -0.859375,0.59375 -0.671875,0 -0.90625,-0.4375 -1.03125,-0.90625 -0.03125,-0.09375 -0.03125,-0.125 -0.125,-0.125 -0.125,0 -0.125,0.046875 -0.125,0.1875 v 0.859375 C 0.3125,0 0.3125,0.0625 0.40625,0.0625 0.46875,0.0625 0.609375,-0.078125 0.75,-0.234375 1.046875,0.0625 1.421875,0.0625 1.59375,0.0625 c 0.90625,0 1.25,-0.484375 1.25,-0.96875 0,-0.265625 -0.125,-0.484375 -0.3125,-0.640625 -0.265625,-0.25 -0.578125,-0.3125 -0.828125,-0.34375 -0.546875,-0.109375 -1,-0.1875 -1,-0.5625 0,-0.21875 0.1875,-0.484375 0.84375,-0.484375 0.8125,0 0.84375,0.5625 0.859375,0.765625 0,0.078125 0.09375,0.078125 0.109375,0.078125 0.125,0 0.125,-0.046875 0.125,-0.1875 z m 0,0"
+ id="path40" />
+
+
-
+ fill="#000000"
+ fill-opacity="1"
+ id="g12359">
+
+
+
-
+ inkscape:label=""
+ transform="translate(145.16667,178.90918)"
+ id="g19284"
+ style="display:inline">
+
-
-
-
-
-
-
+ id="g19266"
+ transform="translate(0,6.618)">
+
+
+
+
+
+
+
+
+
+
+ id="g19278"
+ transform="translate(5.5149999,9.0810003)">
+ d="m 1,-1.234375 c 0.109375,0.0625 0.359375,0.203125 0.765625,0.203125 C 2.484375,-1.03125 3,-1.5 3,-2.046875 3,-2.328125 2.875,-2.53125 2.703125,-2.71875 c 0.328125,-0.21875 0.59375,-0.234375 0.71875,-0.234375 -0.03125,0.03125 -0.0625,0.0625 -0.0625,0.171875 0,0.140625 0.09375,0.21875 0.21875,0.21875 0.09375,0 0.21875,-0.0625 0.21875,-0.21875 0,-0.171875 -0.125,-0.359375 -0.40625,-0.359375 -0.109375,0 -0.484375,0.015625 -0.8125,0.3125 -0.203125,-0.140625 -0.5,-0.25 -0.8125,-0.25 -0.71875,0 -1.234375,0.484375 -1.234375,1.03125 0,0.265625 0.140625,0.515625 0.328125,0.703125 -0.046875,0.0625 -0.203125,0.296875 -0.203125,0.5625 0,0.09375 0.015625,0.421875 0.296875,0.625 -0.3125,0.09375 -0.6875,0.328125 -0.6875,0.6875 0,0.515625 0.765625,0.890625 1.71875,0.890625 0.875,0 1.703125,-0.34375 1.703125,-0.90625 0,-0.203125 -0.078125,-0.578125 -0.46875,-0.78125 -0.40625,-0.21875 -0.828125,-0.21875 -1.5,-0.21875 -0.15625,0 -0.40625,0 -0.453125,-0.015625 C 1.03125,-0.546875 0.90625,-0.75 0.90625,-0.953125 0.90625,-1.125 0.96875,-1.1875 1,-1.234375 Z m 0.765625,0 c -0.671875,0 -0.671875,-0.671875 -0.671875,-0.8125 0,-0.109375 0,-0.390625 0.125,-0.578125 0.109375,-0.109375 0.296875,-0.234375 0.546875,-0.234375 0.6875,0 0.6875,0.671875 0.6875,0.8125 0,0.109375 0,0.390625 -0.140625,0.5625 -0.109375,0.125 -0.296875,0.25 -0.546875,0.25 z m 0,1.21875 c 0.625,0 1.5,0 1.5,0.546875 0,0.375 -0.5625,0.6875 -1.28125,0.6875 -0.734375,0 -1.28125,-0.328125 -1.28125,-0.6875 0,-0.25 0.21875,-0.546875 0.65625,-0.546875 z m 0,0"
+ id="path19276" />
-
+
+
+
+ id="g26218"
+ transform="matrix(1.33333,0,0,1.33333,-0.416667,0.141833)">
+ id="g26216"
+ transform="translate(0,6.618)">
+ d="m 5.609375,-3.15625 c 0.078125,-0.28125 0.1875,-0.765625 0.1875,-0.828125 0,-0.21875 -0.15625,-0.4375 -0.46875,-0.4375 -0.15625,0 -0.515625,0.078125 -0.65625,0.53125 -0.03125,0.125 -0.484375,1.9375 -0.5625,2.265625 -0.0625,0.234375 -0.125,0.515625 -0.15625,0.703125 C 3.78125,-0.6875 3.390625,-0.28125 2.875,-0.28125 c -0.578125,0 -0.59375,-0.5 -0.59375,-0.71875 0,-0.609375 0.3125,-1.390625 0.59375,-2.109375 C 2.96875,-3.375 3,-3.4375 3,-3.609375 3,-4.1875 2.421875,-4.5 1.875,-4.5 c -1.0625,0 -1.5625,1.34375 -1.5625,1.546875 0,0.140625 0.15625,0.140625 0.25,0.140625 0.109375,0 0.1875,0 0.21875,-0.125 0.328125,-1.109375 0.875,-1.203125 1.03125,-1.203125 0.078125,0 0.171875,0 0.171875,0.203125 0,0.234375 -0.125,0.515625 -0.15625,0.625 -0.421875,1.046875 -0.609375,1.609375 -0.609375,2.09375 0,1.140625 1,1.296875 1.578125,1.296875 0.296875,0 0.734375,-0.03125 1.265625,-0.546875 0.328125,0.484375 0.90625,0.546875 1.140625,0.546875 0.375,0 0.65625,-0.203125 0.875,-0.5625 0.234375,-0.40625 0.375,-0.9375 0.375,-0.984375 0,-0.140625 -0.15625,-0.140625 -0.25,-0.140625 -0.109375,0 -0.140625,0 -0.1875,0.046875 -0.03125,0.015625 -0.03125,0.03125 -0.078125,0.28125 -0.203125,0.78125 -0.421875,1 -0.6875,1 -0.140625,0 -0.21875,-0.09375 -0.21875,-0.359375 0,-0.171875 0.03125,-0.34375 0.125,-0.734375 0.078125,-0.28125 0.171875,-0.671875 0.234375,-0.890625 z m 0,0"
+ id="path26214" />
+ id="g26224"
+ transform="matrix(1.33333,0,0,1.33333,-0.416667,0.141833)">
+ id="g26222"
+ transform="translate(6.7849998,3.003)">
+ d="m 2.640625,-2.921875 c 0,-0.125 0,-0.1875 -0.09375,-0.1875 -0.03125,0 -0.046875,0 -0.140625,0.078125 -0.015625,0.015625 -0.078125,0.078125 -0.125,0.109375 -0.21875,-0.140625 -0.46875,-0.1875 -0.734375,-0.1875 -1,0 -1.234375,0.53125 -1.234375,0.875 0,0.21875 0.09375,0.40625 0.265625,0.546875 0.265625,0.21875 0.53125,0.265625 0.96875,0.34375 0.34375,0.0625 0.90625,0.15625 0.90625,0.625 0,0.265625 -0.1875,0.59375 -0.859375,0.59375 -0.671875,0 -0.90625,-0.4375 -1.03125,-0.90625 -0.03125,-0.09375 -0.03125,-0.125 -0.125,-0.125 -0.125,0 -0.125,0.046875 -0.125,0.1875 v 0.859375 C 0.3125,0 0.3125,0.0625 0.40625,0.0625 0.46875,0.0625 0.609375,-0.078125 0.75,-0.234375 1.046875,0.0625 1.421875,0.0625 1.59375,0.0625 c 0.90625,0 1.25,-0.484375 1.25,-0.96875 0,-0.265625 -0.125,-0.484375 -0.3125,-0.640625 -0.265625,-0.25 -0.578125,-0.3125 -0.828125,-0.34375 -0.546875,-0.109375 -1,-0.1875 -1,-0.5625 0,-0.21875 0.1875,-0.484375 0.84375,-0.484375 0.8125,0 0.84375,0.5625 0.859375,0.765625 0,0.078125 0.09375,0.078125 0.109375,0.078125 0.125,0 0.125,-0.046875 0.125,-0.1875 z m 0,0"
+ id="path26220" />
+
+
-
+ fill="#000000"
+ fill-opacity="1"
+ id="g26230">
+
+
+
+
+
+
diff --git a/docs/source/model/figs/lc_filter.svg b/docs/source/model/figs/lc_filter.svg
index 0b167e647..a0dcd1974 100644
--- a/docs/source/model/figs/lc_filter.svg
+++ b/docs/source/model/figs/lc_filter.svg
@@ -4,7 +4,7 @@
height="85"
id="svg3470"
sodipodi:version="0.32"
- inkscape:version="1.3.2 (091e20e, 2023-11-25)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="lc_filter.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
@@ -26,9 +26,9 @@
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="3.2195994"
- inkscape:cx="218.81604"
- inkscape:cy="39.6012"
+ inkscape:zoom="4.5532011"
+ inkscape:cx="192.94118"
+ inkscape:cy="30.198534"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="true"
@@ -36,10 +36,10 @@
inkscape:object-paths="true"
inkscape:object-points="false"
inkscape:grid-bbox="false"
- inkscape:window-width="1512"
- inkscape:window-height="684"
+ inkscape:window-width="2560"
+ inkscape:window-height="1403"
inkscape:window-x="0"
- inkscape:window-y="38"
+ inkscape:window-y="0"
width="349.29px"
height="359.4px"
showguides="true"
@@ -52,7 +52,7 @@
inkscape:bbox-paths="true"
inkscape:snap-global="true"
inkscape:snap-guide="true"
- inkscape:window-maximized="0"
+ inkscape:window-maximized="1"
inkscape:snap-grids="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-to-guides="false"
@@ -428,6 +428,378 @@
id="id-0e3da49b-3550-4662-922a-c4b41e5e472b-1" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -492,182 +864,18 @@
id="layer1-9"
style="display:inline"
inkscape:label="Circuit" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+ id="g3208"
+ transform="matrix(1.33333,0,0,1.33333,-0.416667,0.143167)">
+ id="g3206"
+ transform="translate(4.033,3.0020001)">
+ d="m 2.640625,-2.921875 c 0,-0.125 0,-0.1875 -0.09375,-0.1875 -0.03125,0 -0.046875,0 -0.140625,0.078125 -0.015625,0.015625 -0.078125,0.078125 -0.125,0.109375 -0.21875,-0.140625 -0.46875,-0.1875 -0.734375,-0.1875 -1,0 -1.234375,0.53125 -1.234375,0.875 0,0.21875 0.09375,0.40625 0.265625,0.546875 0.265625,0.21875 0.53125,0.265625 0.96875,0.34375 0.34375,0.0625 0.90625,0.15625 0.90625,0.625 0,0.265625 -0.1875,0.59375 -0.859375,0.59375 -0.671875,0 -0.90625,-0.4375 -1.03125,-0.90625 -0.03125,-0.09375 -0.03125,-0.125 -0.125,-0.125 -0.125,0 -0.125,0.046875 -0.125,0.1875 v 0.859375 C 0.3125,0 0.3125,0.0625 0.40625,0.0625 0.46875,0.0625 0.609375,-0.078125 0.75,-0.234375 1.046875,0.0625 1.421875,0.0625 1.59375,0.0625 c 0.90625,0 1.25,-0.484375 1.25,-0.96875 0,-0.265625 -0.125,-0.484375 -0.3125,-0.640625 -0.265625,-0.25 -0.578125,-0.3125 -0.828125,-0.34375 -0.546875,-0.109375 -1,-0.1875 -1,-0.5625 0,-0.21875 0.1875,-0.484375 0.84375,-0.484375 0.8125,0 0.84375,0.5625 0.859375,0.765625 0,0.078125 0.09375,0.078125 0.109375,0.078125 0.125,0 0.125,-0.046875 0.125,-0.1875 z m 0,0"
+ id="path3204" />
+ clip-path="url(#clipPath3784)"
+ id="g3216"
+ transform="matrix(1.33333,0,0,1.33333,-0.416667,0.143167)">
-
+ fill="#000000"
+ fill-opacity="1"
+ id="g3214">
+
+
+
-
-
-
-
+ transform="translate(-149.118,-127.953)">
+ transform="translate(-149.118,-127.953)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/source/model/figs/lcl_filter.svg b/docs/source/model/figs/lcl_filter.svg
index a1de6ecf1..036732f1c 100644
--- a/docs/source/model/figs/lcl_filter.svg
+++ b/docs/source/model/figs/lcl_filter.svg
@@ -1,13 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1159,12 +1302,7 @@
id="layer2"
style="display:inline;opacity:1"
inkscape:label="Labels"
- transform="translate(215,-125)">
-
+ transform="translate(215, -125)">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ id="g3818-3-3-8-7-5-0-2-9-7-1-3-1-2-0">
@@ -1697,58 +1714,51 @@
+ id="g52503-0">
+ id="g52507-1">
-
-
+ id="g52510-7">
+ id="g3818-3-3-8-7-5-0-2-9-7-1-3-1-8-8-83-8">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ sodipodi:nodetypes="ccc" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -2368,84 +1904,76 @@
+ id="g101016-3">
+ id="g101020-3">
+ id="g3818-3-3-8-7-5-0-2-9-7-1-3-1-8-8-83-5-7">
-
-
-
@@ -2453,48 +1981,32 @@
-
-
-
-
-
+ id="g108093-8">
+ id="g108097-8">
@@ -2502,84 +2014,55 @@
-
-
-
-
-
-
+ sodipodi:nodetypes="ccc" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/source/model/figs/pwm_inverter.svg b/docs/source/model/figs/pwm_inverter.svg
index 3b7f4abf9..a5f17afeb 100644
--- a/docs/source/model/figs/pwm_inverter.svg
+++ b/docs/source/model/figs/pwm_inverter.svg
@@ -4,7 +4,7 @@
height="170"
id="svg3470"
sodipodi:version="0.32"
- inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="pwm_inverter.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
@@ -15,7 +15,8 @@
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
- xmlns:dc="http://purl.org/dc/elements/1.1/">
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:ns3="http://www.iki.fi/pav/software/textext/">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -620,7 +1433,14 @@
id="layer2"
style="display:inline;opacity:1"
inkscape:label="Labels"
- transform="translate(-30,-115)">
+ transform="translate(-30, -115)">
+
-
-
-
-
-
-
-
-
-
-
-
+ width="30"
+ id="rect5876"
+ style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
@@ -814,11 +1549,11 @@
inkscape:export-filename="/home/mhinkkan/Desktop/testi.png"
id="path10918-9-9-0-0-8-9-18"
sodipodi:nodetypes="cc"
- d="M 215,152.5 V 210"
+ d="M 215,157.5 V 215"
style="display:inline;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-mid:none;marker-end:url(#marker52572)" />
+ transform="matrix(1,0,0,-1,112.5,399.90414)">
+ transform="matrix(1,0,0,-1,112.5,339.90414)">
+ transform="translate(42.500001,-49.904151)">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ d="M 285,209.49999 V 215 H 145"
+ id="path1"
+ sodipodi:nodetypes="ccc" />
+ d="M 285,190.5 V 135 H 145"
+ id="path2"
+ sodipodi:nodetypes="ccc" />
+
+
+ id="g1640-2">
+ id="path1636-1" />
+ id="g1650-8">
+ id="path1642-2" />
+ id="path1646-5" />
+
+
+
+
+
+
+
+
+
+
+
+
+ transform="matrix(0,1,1,0,0,0)"
+ id="circle9003"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:'Nimbus Roman No9 L';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.333;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ cx="200.00002"
+ cy="400"
+ r="10" />
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:'Nimbus Roman No9 L';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.333;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="circle9005"
+ transform="matrix(0,1,1,0,0,0)"
+ cx="175.00002"
+ cy="400"
+ r="10" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/source/model/figs/system.svg b/docs/source/model/figs/system.svg
index a9263edf2..391f44f15 100644
--- a/docs/source/model/figs/system.svg
+++ b/docs/source/model/figs/system.svg
@@ -4,7 +4,7 @@
height="150"
id="svg6781"
version="1.1"
- inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="system.svg"
viewBox="0 0 480 150"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
@@ -14,8 +14,7 @@
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:ns3="http://www.iki.fi/pav/software/textext/">
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1620,13 +1759,13 @@
transform="translate(-150, -420)">
@@ -1634,13 +1773,13 @@
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4641"
- d="m 155,480 h 45"
+ d="m 155,480 h 40"
style="display:inline;fill:none;stroke:#0000ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-end:url(#Arrow2Mend-9-78375)" />
@@ -1675,11 +1814,11 @@
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3783"
- d="M 425,550 H 180 v -40 h 20"
+ d="M 430,550 H 175 v -40 h 20"
style="display:inline;fill:none;stroke:#0000ff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Mend-924749623)" />
@@ -1688,14 +1827,14 @@
id="rect4397-8"
width="40"
y="480"
- x="325"
+ x="330"
height="30"
inkscape:export-filename="C:\Documents and Settings\mhinkkan\Desktop\testi3.png"
inkscape:export-xdpi="300"
inkscape:export-ydpi="300" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ id="g26534"
+ style="stroke:#0000ff;stroke-opacity:1"
+ transform="translate(25,140)">
+
+ transform="translate(-322.91614,-145.40467)">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ transform="translate(84.173263,-149.69466)">
-
-
-
-
-
-
-
-
+ inkscape:label=""
+ transform="translate(510.66737,475.73596)"
+ id="g28864">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id="use80"
+ transform="translate(171.16299,26.733)">
+ d="m 2.078125,-1.9375 c 0.21875,0.046875 1.03125,0.203125 1.03125,0.921875 0,0.5 -0.34375,0.90625 -1.125,0.90625 -0.84375,0 -1.203125,-0.5625 -1.390625,-1.421875 C 0.5625,-1.65625 0.5625,-1.6875 0.453125,-1.6875 c -0.125,0 -0.125,0.0625 -0.125,0.234375 V -0.125 c 0,0.171875 0,0.234375 0.109375,0.234375 0.046875,0 0.0625,-0.015625 0.25,-0.203125 0.015625,-0.015625 0.015625,-0.03125 0.203125,-0.21875 0.4375,0.40625 0.890625,0.421875 1.09375,0.421875 1.140625,0 1.609375,-0.671875 1.609375,-1.390625 0,-0.515625 -0.296875,-0.828125 -0.421875,-0.9375 C 2.84375,-2.546875 2.453125,-2.625 2.03125,-2.703125 1.46875,-2.8125 0.8125,-2.9375 0.8125,-3.515625 c 0,-0.359375 0.25,-0.765625 1.109375,-0.765625 1.09375,0 1.15625,0.90625 1.171875,1.203125 0,0.09375 0.09375,0.09375 0.109375,0.09375 0.140625,0 0.140625,-0.046875 0.140625,-0.234375 v -1.015625 c 0,-0.15625 0,-0.234375 -0.109375,-0.234375 -0.046875,0 -0.078125,0 -0.203125,0.125 -0.03125,0.03125 -0.125,0.125 -0.171875,0.15625 -0.375,-0.28125 -0.78125,-0.28125 -0.9375,-0.28125 -1.21875,0 -1.59375,0.671875 -1.59375,1.234375 0,0.34375 0.15625,0.625 0.421875,0.84375 0.328125,0.25 0.609375,0.3125 1.328125,0.453125 z m 0,0"
+ id="path160" />
+ id="use82"
+ transform="translate(175.09225,26.733)">
+ d="m 4.140625,-3.34375 c 0.25,-0.640625 0.765625,-0.640625 0.921875,-0.640625 v -0.3125 c -0.234375,0.015625 -0.515625,0.03125 -0.75,0.03125 -0.171875,0 -0.640625,-0.015625 -0.859375,-0.03125 v 0.3125 c 0.3125,0 0.46875,0.171875 0.46875,0.421875 0,0.109375 -0.015625,0.125 -0.0625,0.25 L 2.84375,-0.875 1.75,-3.546875 C 1.703125,-3.65625 1.6875,-3.6875 1.6875,-3.734375 c 0,-0.25 0.359375,-0.25 0.5625,-0.25 v -0.3125 c -0.265625,0.015625 -0.921875,0.03125 -1.09375,0.03125 -0.265625,0 -0.671875,-0.015625 -0.96875,-0.03125 v 0.3125 c 0.484375,0 0.671875,0 0.8125,0.34375 L 2.5,0 C 2.4375,0.125 2.296875,0.453125 2.25,0.59375 2.03125,1.140625 1.75,1.828125 1.109375,1.828125 c -0.046875,0 -0.28125,0 -0.46875,-0.1875 0.3125,-0.03125 0.390625,-0.25 0.390625,-0.421875 0,-0.25 -0.1875,-0.40625 -0.421875,-0.40625 -0.203125,0 -0.421875,0.125 -0.421875,0.421875 0,0.453125 0.421875,0.8125 0.921875,0.8125 0.625,0 1.03125,-0.578125 1.265625,-1.140625 z m 0,0"
+ id="path164" />
+ id="use84"
+ transform="translate(180.35051,26.733)">
+ d="m 2.078125,-1.9375 c 0.21875,0.046875 1.03125,0.203125 1.03125,0.921875 0,0.5 -0.34375,0.90625 -1.125,0.90625 -0.84375,0 -1.203125,-0.5625 -1.390625,-1.421875 C 0.5625,-1.65625 0.5625,-1.6875 0.453125,-1.6875 c -0.125,0 -0.125,0.0625 -0.125,0.234375 V -0.125 c 0,0.171875 0,0.234375 0.109375,0.234375 0.046875,0 0.0625,-0.015625 0.25,-0.203125 0.015625,-0.015625 0.015625,-0.03125 0.203125,-0.21875 0.4375,0.40625 0.890625,0.421875 1.09375,0.421875 1.140625,0 1.609375,-0.671875 1.609375,-1.390625 0,-0.515625 -0.296875,-0.828125 -0.421875,-0.9375 C 2.84375,-2.546875 2.453125,-2.625 2.03125,-2.703125 1.46875,-2.8125 0.8125,-2.9375 0.8125,-3.515625 c 0,-0.359375 0.25,-0.765625 1.109375,-0.765625 1.09375,0 1.15625,0.90625 1.171875,1.203125 0,0.09375 0.09375,0.09375 0.109375,0.09375 0.140625,0 0.140625,-0.046875 0.140625,-0.234375 v -1.015625 c 0,-0.15625 0,-0.234375 -0.109375,-0.234375 -0.046875,0 -0.078125,0 -0.203125,0.125 -0.03125,0.03125 -0.125,0.125 -0.171875,0.15625 -0.375,-0.28125 -0.78125,-0.28125 -0.9375,-0.28125 -1.21875,0 -1.59375,0.671875 -1.59375,1.234375 0,0.34375 0.15625,0.625 0.421875,0.84375 0.328125,0.25 0.609375,0.3125 1.328125,0.453125 z m 0,0"
+ id="path168" />
+ id="use86"
+ transform="translate(184.27975,26.733)">
+ d="m 1.71875,-3.984375 h 1.4375 v -0.3125 H 1.71875 V -6.125 h -0.25 c 0,0.8125 -0.296875,1.875 -1.28125,1.921875 v 0.21875 h 0.84375 v 2.75 c 0,1.21875 0.9375,1.34375 1.296875,1.34375 0.703125,0 0.984375,-0.703125 0.984375,-1.34375 v -0.5625 h -0.25 V -1.25 c 0,0.734375 -0.296875,1.109375 -0.671875,1.109375 -0.671875,0 -0.671875,-0.90625 -0.671875,-1.078125 z m 0,0"
+ id="path172" />
+ id="use88"
+ transform="translate(188.15422,26.733)">
+ d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0"
+ id="path176" />
+ id="use90"
+ transform="translate(192.58159,26.733)">
+ d="M 1.09375,-3.421875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.359375,-0.015625 0.859375,-0.03125 1.140625,-0.03125 0.25,0 0.765625,0.015625 1.109375,0.03125 v -0.3125 c -0.671875,0 -0.78125,0 -0.78125,-0.4375 V -2.59375 C 1.78125,-3.625 2.5,-4.1875 3.125,-4.1875 c 0.640625,0 0.75,0.53125 0.75,1.109375 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.34375,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.25,0 0.78125,0.015625 1.109375,0.03125 v -0.3125 c -0.65625,0 -0.765625,0 -0.765625,-0.4375 v -1.84375 c 0,-1.03125 0.703125,-1.59375 1.34375,-1.59375 0.625,0 0.734375,0.53125 0.734375,1.109375 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.34375,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.265625,0 0.78125,0.015625 1.125,0.03125 v -0.3125 c -0.515625,0 -0.765625,0 -0.78125,-0.296875 v -1.90625 c 0,-0.859375 0,-1.15625 -0.3125,-1.515625 -0.140625,-0.171875 -0.46875,-0.375 -1.046875,-0.375 -0.828125,0 -1.28125,0.59375 -1.4375,0.984375 C 4.390625,-4.296875 3.65625,-4.40625 3.203125,-4.40625 2.46875,-4.40625 2,-3.984375 1.71875,-3.359375 V -4.40625 L 0.3125,-4.296875 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 z m 0,0"
+ id="path180" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id="use94"
+ transform="translate(171.16299,26.733)">
+ d="m 2.078125,-1.9375 c 0.21875,0.046875 1.03125,0.203125 1.03125,0.921875 0,0.5 -0.34375,0.90625 -1.125,0.90625 -0.84375,0 -1.203125,-0.5625 -1.390625,-1.421875 C 0.5625,-1.65625 0.5625,-1.6875 0.453125,-1.6875 c -0.125,0 -0.125,0.0625 -0.125,0.234375 V -0.125 c 0,0.171875 0,0.234375 0.109375,0.234375 0.046875,0 0.0625,-0.015625 0.25,-0.203125 0.015625,-0.015625 0.015625,-0.03125 0.203125,-0.21875 0.4375,0.40625 0.890625,0.421875 1.09375,0.421875 1.140625,0 1.609375,-0.671875 1.609375,-1.390625 0,-0.515625 -0.296875,-0.828125 -0.421875,-0.9375 C 2.84375,-2.546875 2.453125,-2.625 2.03125,-2.703125 1.46875,-2.8125 0.8125,-2.9375 0.8125,-3.515625 c 0,-0.359375 0.25,-0.765625 1.109375,-0.765625 1.09375,0 1.15625,0.90625 1.171875,1.203125 0,0.09375 0.09375,0.09375 0.109375,0.09375 0.140625,0 0.140625,-0.046875 0.140625,-0.234375 v -1.015625 c 0,-0.15625 0,-0.234375 -0.109375,-0.234375 -0.046875,0 -0.078125,0 -0.203125,0.125 -0.03125,0.03125 -0.125,0.125 -0.171875,0.15625 -0.375,-0.28125 -0.78125,-0.28125 -0.9375,-0.28125 -1.21875,0 -1.59375,0.671875 -1.59375,1.234375 0,0.34375 0.15625,0.625 0.421875,0.84375 0.328125,0.25 0.609375,0.3125 1.328125,0.453125 z m 0,0"
+ id="path194" />
+ id="g34179"
+ transform="translate(175.09225,26.733)">
+ d="m 4.140625,-3.34375 c 0.25,-0.640625 0.765625,-0.640625 0.921875,-0.640625 v -0.3125 c -0.234375,0.015625 -0.515625,0.03125 -0.75,0.03125 -0.171875,0 -0.640625,-0.015625 -0.859375,-0.03125 v 0.3125 c 0.3125,0 0.46875,0.171875 0.46875,0.421875 0,0.109375 -0.015625,0.125 -0.0625,0.25 L 2.84375,-0.875 1.75,-3.546875 C 1.703125,-3.65625 1.6875,-3.6875 1.6875,-3.734375 c 0,-0.25 0.359375,-0.25 0.5625,-0.25 v -0.3125 c -0.265625,0.015625 -0.921875,0.03125 -1.09375,0.03125 -0.265625,0 -0.671875,-0.015625 -0.96875,-0.03125 v 0.3125 c 0.484375,0 0.671875,0 0.8125,0.34375 L 2.5,0 C 2.4375,0.125 2.296875,0.453125 2.25,0.59375 2.03125,1.140625 1.75,1.828125 1.109375,1.828125 c -0.046875,0 -0.28125,0 -0.46875,-0.1875 0.3125,-0.03125 0.390625,-0.25 0.390625,-0.421875 0,-0.25 -0.1875,-0.40625 -0.421875,-0.40625 -0.203125,0 -0.421875,0.125 -0.421875,0.421875 0,0.453125 0.421875,0.8125 0.921875,0.8125 0.625,0 1.03125,-0.578125 1.265625,-1.140625 z m 0,0"
+ id="path198" />
+ id="g34182"
+ transform="translate(180.35051,26.733)">
+ id="path202" />
+ id="g34185"
+ transform="translate(184.27975,26.733)">
+ d="m 1.71875,-3.984375 h 1.4375 v -0.3125 H 1.71875 V -6.125 h -0.25 c 0,0.8125 -0.296875,1.875 -1.28125,1.921875 v 0.21875 h 0.84375 v 2.75 c 0,1.21875 0.9375,1.34375 1.296875,1.34375 0.703125,0 0.984375,-0.703125 0.984375,-1.34375 v -0.5625 h -0.25 V -1.25 c 0,0.734375 -0.296875,1.109375 -0.671875,1.109375 -0.671875,0 -0.671875,-0.90625 -0.671875,-1.078125 z m 0,0"
+ id="path206" />
+ id="g34188"
+ transform="translate(188.15422,26.733)">
+ d="M 1.109375,-2.515625 C 1.171875,-4 2.015625,-4.25 2.359375,-4.25 c 1.015625,0 1.125,1.34375 1.125,1.734375 z m 0,0.21875 h 2.78125 c 0.21875,0 0.25,0 0.25,-0.21875 0,-0.984375 -0.546875,-1.953125 -1.78125,-1.953125 -1.15625,0 -2.078125,1.03125 -2.078125,2.28125 0,1.328125 1.046875,2.296875 2.1875,2.296875 C 3.6875,0.109375 4.140625,-1 4.140625,-1.1875 4.140625,-1.28125 4.0625,-1.3125 4,-1.3125 c -0.078125,0 -0.109375,0.0625 -0.125,0.140625 -0.34375,1.03125 -1.25,1.03125 -1.34375,1.03125 -0.5,0 -0.890625,-0.296875 -1.125,-0.671875 -0.296875,-0.46875 -0.296875,-1.125 -0.296875,-1.484375 z m 0,0"
+ id="path210" />
+ id="g34191"
+ transform="translate(192.58159,26.733)">
+ d="M 1.09375,-3.421875 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.359375,-0.015625 0.859375,-0.03125 1.140625,-0.03125 0.25,0 0.765625,0.015625 1.109375,0.03125 v -0.3125 c -0.671875,0 -0.78125,0 -0.78125,-0.4375 V -2.59375 C 1.78125,-3.625 2.5,-4.1875 3.125,-4.1875 c 0.640625,0 0.75,0.53125 0.75,1.109375 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.34375,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.25,0 0.78125,0.015625 1.109375,0.03125 v -0.3125 c -0.65625,0 -0.765625,0 -0.765625,-0.4375 v -1.84375 c 0,-1.03125 0.703125,-1.59375 1.34375,-1.59375 0.625,0 0.734375,0.53125 0.734375,1.109375 V -0.75 c 0,0.4375 -0.109375,0.4375 -0.78125,0.4375 V 0 c 0.34375,-0.015625 0.859375,-0.03125 1.125,-0.03125 0.265625,0 0.78125,0.015625 1.125,0.03125 v -0.3125 c -0.515625,0 -0.765625,0 -0.78125,-0.296875 v -1.90625 c 0,-0.859375 0,-1.15625 -0.3125,-1.515625 -0.140625,-0.171875 -0.46875,-0.375 -1.046875,-0.375 -0.828125,0 -1.28125,0.59375 -1.4375,0.984375 C 4.390625,-4.296875 3.65625,-4.40625 3.203125,-4.40625 2.46875,-4.40625 2,-3.984375 1.71875,-3.359375 V -4.40625 L 0.3125,-4.296875 v 0.3125 c 0.703125,0 0.78125,0.0625 0.78125,0.5625 z m 0,0"
+ id="path214" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id="g39838"
+ transform="translate(5.586,17.877001)">
+ id="path39836" />
+
+
+
+
+
+
+
+
+
+ id="g39852"
+ transform="translate(14.96,17.877001)">
-
-
-
-
-
-
+ id="path39850" />
-
+
+
+
+ id="g41599"
+ transform="matrix(1.33333,0,0,1.33333,-0.4375,0.0164998)">
+ id="g41571"
+ transform="translate(0,7.4720001)">
+ id="path41569" />
+ id="use68"
+ transform="translate(6.7805462,7.4720001)">
+ id="path41573" />
+ id="g41578"
+ transform="translate(12.038806,7.4720001)">
+ id="path41576" />
+ id="g41582"
+ transform="translate(15.913261,7.4720001)">
+ id="path41580" />
+ id="g41586"
+ transform="translate(20.340639,7.4720001)">
+ id="path41584" />
+ id="g41590"
+ transform="translate(24.24299,7.4720001)">
+ id="path41588" />
+ id="use78"
+ transform="translate(29.778212,7.4720001)">
+ id="path41592" />
+ id="g41597"
+ transform="translate(34.75951,7.4720001)">
+ id="path41595" />
+ id="g108"
+ transform="matrix(1.33333,0,0,1.33333,-0.4375,0.0164998)">
+ id="g41603"
+ transform="translate(40.844666,7.4720001)">
+ id="path41601" />
+ id="g41607"
+ transform="translate(46.379887,7.4720001)">
+ id="path41605" />
+ id="g41611"
+ transform="translate(49.147499,7.4720001)">
+ id="path41609" />
+ id="g41615"
+ transform="translate(53.076748,7.4720001)">
+ id="path41613" />
+ id="use92"
+ transform="translate(56.951202,7.4720001)">
+ id="path41617" />
+ id="g41622"
+ transform="translate(62.486423,7.4720001)">
+ id="path41620" />
+ id="use96"
+ transform="translate(66.388771,7.4720001)">
+ id="path41624" />
+ id="use98"
+ transform="translate(71.923996,7.4720001)">
+ id="path41627" />
+ id="use100"
+ transform="translate(76.905296,7.4720001)">
+ id="path41630" />
+ id="use102"
+ transform="translate(82.440514,7.4720001)">
+ id="path41633" />
+ id="use104"
+ transform="translate(86.867897,7.4720001)">
+ id="path41636" />
+
+
+
+ id="g112"
+ transform="matrix(1.33333,0,0,1.33333,-0.4375,0.0164998)">
+ id="use110"
+ transform="translate(98.546997,7.4720001)">
+ id="path41643" />
+ clip-path="url(#clipPath3996)"
+ id="g118"
+ transform="matrix(1.33333,0,0,1.33333,-0.4375,0.0164998)">
-
+ fill="#000000"
+ fill-opacity="1"
+ id="g116">
+
+
+
+ id="g122"
+ transform="matrix(1.33333,0,0,1.33333,-0.4375,0.0164998)">
+ id="use120"
+ transform="translate(107.937,7.4720001)">
+ id="path222" />
+ clip-path="url(#clipPath7831)"
+ id="g128"
+ transform="matrix(1.33333,0,0,1.33333,-0.4375,0.0164998)">
-
+ fill="#000000"
+ fill-opacity="1"
+ id="g126">
+
+
+
diff --git a/docs/source/model/grid/filter_and_grid.rst b/docs/source/model/grid/filter_and_grid.rst
index 18a75c61b..7ff69d080 100644
--- a/docs/source/model/grid/filter_and_grid.rst
+++ b/docs/source/model/grid/filter_and_grid.rst
@@ -1,28 +1,27 @@
AC Filter and Grid Impedance
============================
-This document describes continuous-time alternating current (AC) filter and grid-impedance models.
+This document describes continuous-time models of an AC filter and grid impedance.
L Filter
--------
-A dynamic model for an inductive L filter and inductive-resistive grid impedance is implemented in the class :class:`motulator.grid.model.LFilter`. The model is implemented in stationary coordinates as
+A dynamic model of an L filter and inductive-resistive grid impedance is implemented in the class :class:`motulator.grid.model.LFilter`. The model in stationary coordinates is
.. math::
- L_\mathrm{t}\frac{\mathrm{d}\boldsymbol{i}_\mathrm{g}^\mathrm{s}}{\mathrm{d} t}
- = \boldsymbol{u}_\mathrm{c}^\mathrm{s}
- - \boldsymbol{e}_\mathrm{g}^\mathrm{s}
- - R_\mathrm{t}\boldsymbol{i}_\mathrm{g}^\mathrm{s}
+ L_\mathrm{t}\frac{\mathrm{d}\boldsymbol{i}_\mathrm{c}^\mathrm{s}}{\mathrm{d} t}
+ = \boldsymbol{u}_\mathrm{c}^\mathrm{s} - \boldsymbol{e}_\mathrm{g}^\mathrm{s}
+ - R_\mathrm{t}\boldsymbol{i}_\mathrm{c}^\mathrm{s}
:label: L_filt_model
-where :math:`\boldsymbol{i}_\mathrm{g}^\mathrm{s}` is the grid current, :math:`\boldsymbol{u}_\mathrm{c}^\mathrm{s}` is the converter voltage, :math:`\boldsymbol{e}_\mathrm{g}^\mathrm{s}` is the grid voltage, :math:`R_\mathrm{t} = R_\mathrm{fc} + R_\mathrm{g}` is the total resistance comprising the filter series resistance :math:`R_\mathrm{fc}` and the grid resistance :math:`R_\mathrm{g}`, and :math:`L_\mathrm{t} = L_\mathrm{fc} + L_\mathrm{g}` is the total inductance comprising the filter inductance :math:`L_\mathrm{fc}` and the grid inductance :math:`L_\mathrm{g}`. The point of common coupling (PCC) is modeled to be between the L filter and grid impedance. The voltage at the PCC is obtained as
+where :math:`\boldsymbol{i}_\mathrm{c}^\mathrm{s}` is the converter current, :math:`\boldsymbol{u}_\mathrm{c}^\mathrm{s}` is the converter voltage, :math:`\boldsymbol{e}_\mathrm{g}^\mathrm{s}` is the grid voltage, :math:`R_\mathrm{t} = R_\mathrm{fc} + R_\mathrm{g}` is the total resistance comprising the filter series resistance :math:`R_\mathrm{fc}` and the grid resistance :math:`R_\mathrm{g}`, and :math:`L_\mathrm{t} = L_\mathrm{fc} + L_\mathrm{g}` is the total inductance comprising the filter inductance :math:`L_\mathrm{fc}` and the grid inductance :math:`L_\mathrm{g}`. The point of common coupling (PCC) is modeled to be between the L filter and the grid impedance. The voltage at the PCC is
.. math::
\boldsymbol{u}_\mathrm{g}^\mathrm{s}
= \frac{L_\mathrm{g}(\boldsymbol{u}_\mathrm{c}^\mathrm{s}
- - R_\mathrm{fc}\boldsymbol{i}_\mathrm{g}^\mathrm{s})
+ - R_\mathrm{fc}\boldsymbol{i}_\mathrm{c}^\mathrm{s})
+ L_\mathrm{fc}(\boldsymbol{e}_\mathrm{g}^\mathrm{s}
- + R_\mathrm{g}\boldsymbol{i}_\mathrm{g}^\mathrm{s})}{L_\mathrm{t}}
+ + R_\mathrm{g}\boldsymbol{i}_\mathrm{c}^\mathrm{s})}{L_\mathrm{t}}
:label: L_filt_PCC_voltage
.. figure:: ../figs/l_filter.svg
@@ -36,7 +35,7 @@ where :math:`\boldsymbol{i}_\mathrm{g}^\mathrm{s}` is the grid current, :math:`\
LCL Filter
----------
-A dynamic model for an inductive-capacitive-inductive (LCL) filter and inductive-resistive grid impedance is implemented in the class :class:`motulator.grid.model.LCLFilter`. The model is implemented in stationary coordinates as
+A dynamic model of an LCL filter and inductive-resistive grid impedance is implemented in the class :class:`motulator.grid.model.LCLFilter`. The model in stationary coordinates is
.. math::
L_\mathrm{fc}\frac{\mathrm{d}\boldsymbol{i}_\mathrm{c}^\mathrm{s}}{\mathrm{d} t}
@@ -52,9 +51,7 @@ A dynamic model for an inductive-capacitive-inductive (LCL) filter and inductive
- R_\mathrm{t}\boldsymbol{i}_\mathrm{g}^\mathrm{s}
:label: LCL_filt_model
-where :math:`\boldsymbol{i}_\mathrm{c}^\mathrm{s}` is the converter-side and :math:`\boldsymbol{i}_\mathrm{g}^\mathrm{s}` is the grid-side current of the LCL filter (i.e., converter and grid current, respectively), and :math:`\boldsymbol{u}_\mathrm{f}^\mathrm{s}` is the filter capacitor voltage. The converter-side and grid-side inductances of the LCL filter are :math:`L_\mathrm{fc}` and :math:`L_\mathrm{fg}`, and their series resistances are :math:`R_\mathrm{fc}` and :math:`R_\mathrm{fg}`, respectively. The filter capacitance is :math:`C_\mathrm{f}`. In the LCL filter model, the total grid-side indutance and resistance are :math:`L_\mathrm{t} = L_\mathrm{fg} + L_\mathrm{g}` and :math:`R_\mathrm{t} = R_\mathrm{fg} + R_\mathrm{g}`, respectively.
-
-The PCC is modeled to be between the LCL filter and the inductive-resistive grid impedance (:math:`L_\mathrm{g}`, :math:`R_\mathrm{g}`). The voltage at the PCC is obtained as
+where :math:`\boldsymbol{i}_\mathrm{c}^\mathrm{s}` is the converter current, :math:`\boldsymbol{i}_\mathrm{g}^\mathrm{s}` is the grid current, and :math:`\boldsymbol{u}_\mathrm{f}^\mathrm{s}` is the capacitor voltage. The converter-side and grid-side inductances of the LCL filter are :math:`L_\mathrm{fc}` and :math:`L_\mathrm{fg}`, respectively, and their series resistances are :math:`R_\mathrm{fc}` and :math:`R_\mathrm{fg}`, respectively. The filter capacitance is :math:`C_\mathrm{f}`. The total grid-side inductance and resistance are :math:`L_\mathrm{t} = L_\mathrm{fg} + L_\mathrm{g}` and :math:`R_\mathrm{t} = R_\mathrm{fg} + R_\mathrm{g}`, respectively. The PCC is modeled to be between the LCL filter and the inductive-resistive grid impedance. The voltage at the PCC is
.. math::
\boldsymbol{u}_\mathrm{g}^\mathrm{s}
diff --git a/docs/source/model/grid/grid_volt_source.rst b/docs/source/model/grid/grid_volt_source.rst
index ad63c1871..e49df14f2 100644
--- a/docs/source/model/grid/grid_volt_source.rst
+++ b/docs/source/model/grid/grid_volt_source.rst
@@ -1,15 +1,10 @@
-Grid Voltage Source
-===================
+Three-Phase Voltage Source
+==========================
-This document describes continuous-time models for three-phase AC voltage sources.
-
-Ideal three-phase voltage source
---------------------------------
-
-A model for an ideal three-phase voltage source is implemented in the class :class:`motulator.grid.model.ThreePhaseVoltageSource`. The grid voltage space vector is calculated as a combination of a positive sequence and optional negative sequence component as
+A model for an ideal three-phase voltage source is implemented in the class :class:`motulator.grid.model.ThreePhaseVoltageSource`. The voltage space vector is calculated as a combination of a positive-sequence and optional negative-sequence components as
.. math::
\boldsymbol{e}_\mathrm{g}^\mathrm{s} = e_\mathrm{g+}\mathrm{e}^{\mathrm{j}(\vartheta_\mathrm{g} + \phi_\mathrm{+})} + e_\mathrm{g-}\mathrm{e}^{-\mathrm{j}(\vartheta_\mathrm{g} + \phi_\mathrm{-})}
:label: grid_voltage_vector
-where :math:`e_\mathrm{g+}` and :math:`e_\mathrm{g-}` are the magnitudes of the positive and negative sequence components, :math:`\phi_\mathrm{+}` and :math:`\phi_\mathrm{-}` the respective phase shifts, and :math:`\vartheta_\mathrm{g}` the angle of the grid voltage. The grid voltage angle is obtained by integrating the angular frequency :math:`\omega_\mathrm{g}`. All parameters can be given as time-varying functions to simulate various fault conditions.
\ No newline at end of file
+where :math:`e_\mathrm{g+}` and :math:`e_\mathrm{g-}` are the magnitudes of the positive-sequence and negative-sequence components, respectively, :math:`\phi_\mathrm{+}` and :math:`\phi_\mathrm{-}` are the positive-sequence and negative-sequence phase shifts, respectively, and :math:`\vartheta_\mathrm{g}` is the angle obtained by integrating the angular frequency :math:`\omega_\mathrm{g}`. All parameters can be given as time-varying functions to simulate various fault conditions.
\ No newline at end of file
diff --git a/docs/source/model/grid/index.rst b/docs/source/model/grid/index.rst
index f37aa7b8e..b0f45de14 100644
--- a/docs/source/model/grid/index.rst
+++ b/docs/source/model/grid/index.rst
@@ -1,8 +1,6 @@
-*********************
-Grid Converter System
-*********************
-
-Grid converter-specific models
+***************
+Grid Converters
+***************
.. toctree::
:maxdepth: 2
diff --git a/docs/source/model/system.rst b/docs/source/model/system.rst
deleted file mode 100644
index eb47a92f3..000000000
--- a/docs/source/model/system.rst
+++ /dev/null
@@ -1,46 +0,0 @@
-Introduction
-============
-
-Sampled-Data Systems
---------------------
-
-Machine drives and grid-connected converters are sampled-data systems, consisting of continuous-time systems and discrete-time systems as well as the interfaces between them [#Fra1997]_, [#Bus2015]_. The figure below shows a generic example system. The same architecture is used in *motulator*.
-
-.. figure:: figs/system.svg
- :width: 100%
- :align: center
- :alt: Block diagram of a sampled-data system
- :target: .
-
- Block diagram of a sampled-data system. Discrete signals and systems are shown in blue, and continuous signals and systems are shown in red.
-
-The continuous-time system (named `mdl` in the provided example scripts) is the model of a physical machine drive or grid converter system. The system comprises a power converter along with other subsystem models depending on the application. The continuous-time system may have external inputs, such as a load torque or power fed to a DC-bus of the converter.
-
-The discrete-time controller (named `ctrl`) contains control algorithms, such as speed control and current control. The reference signals could be, e.g., the speed and flux or voltage and power references. The feedback signal :math:`\boldsymbol{y}(k)` typically contains the measured DC-bus voltage and stator/converter currents.
-
-Digital control systems typically have a computational delay of one sampling period, :math:`N=1`. The PWM block shown in the figure models the carrier comparison, see more details in :doc:`converters`. The carrier comparison is implemented in the class :class:`motulator.common.model.CarrierComparison`. If the switching ripple is not of interest in simulations, the carrier comparison can be replaced with a zero-order hold (ZOH).
-
-Space Vectors
--------------
-
-The system models in *motulator* apply peak-valued complex space vectors, marked with boldface in the following equations. As an example, the space vector of the converter current is
-
-.. math::
- \boldsymbol{i}^\mathrm{s}_\mathrm{c} = \frac{2}{3}\left(i_\mathrm{a} + i_\mathrm{b}\mathrm{e}^{\mathrm{j}2\pi/3} + i_\mathrm{c}\mathrm{e}^{\mathrm{j} 4\pi/3}\right)
- :label: space_vector
-
-where :math:`i_\mathrm{a}`, :math:`i_\mathrm{b}`, and :math:`i_\mathrm{c}` are the phase currents, which may vary freely in time. In our notation, the subscript c refers to the converter-side AC quantities and the superscript s refers to the stationary coordinates. The space vector does not include the zero-sequence component, which is defined as
-
-.. math::
- i_\mathrm{c0} = \frac{1}{3}\left(i_\mathrm{a} + i_\mathrm{b} + i_\mathrm{c}\right)
- :label: zero_sequence
-
-Even though the zero-sequence voltage exists at the ouput of typical converters (see :doc:`/model/converters`), there is no path for the zero-sequence current to flow if the stator winding of a machine is delta-connected, or the star point of the three-phase system is not connected, i.e., :math:`i_\mathrm{c0} = 0`. Consequently, the zero-sequence voltage cannot produce power or torque.
-
-The space vector transformation in :eq:`space_vector` is implemented in the function :func:`motulator.common.utils.abc2complex` and its inverse transformation in the function :func:`motulator.common.utils.complex2abc`.
-
-.. rubric:: References
-
-.. [#Fra1997] Franklin, Powell, Workman, "Digital Control of Dynamic Systems," Menlo Park, CA, USA: Addison-Wesley, 1997
-
-.. [#Bus2015] Buso, Mattavelli, "Digital Control in Power Electronics," 2nd ed., Morgan & Claypool, 2015, https://doi.org/10.2200/S00637ED1V01Y201503PEL007
diff --git a/docs/source/usage.rst b/docs/source/usage.rst
index 934d24582..6124563c8 100644
--- a/docs/source/usage.rst
+++ b/docs/source/usage.rst
@@ -22,7 +22,7 @@ After :doc:`installation`, *motulator* can be used by creating a continuous-time
mdl = model.Drive(converter, machine, mechanics)
# Discrete-time controller
- par = InductionMachineInvGammaPars( # Machine model parameter estimates
+ par = InductionMachineInvGammaPars( # Machine model parameter estimates
n_p=2, R_s=3.7, R_R=2.1, L_sgm=.021, L_M=.224)
cfg = control.CurrentReferenceCfg(par, max_i_s=1.5*np.sqrt(2)*5)
ctrl = control.CurrentVectorControl(par, cfg, J=.015)
diff --git a/examples/drive/README.txt b/examples/drive/README.txt
index da2a742c3..feda4dd06 100644
--- a/examples/drive/README.txt
+++ b/examples/drive/README.txt
@@ -1,4 +1,4 @@
Drives
======
-A collection of example scripts for motor drives.
\ No newline at end of file
+A collection of example scripts for machine drives.
\ No newline at end of file
diff --git a/examples/grid/README.txt b/examples/grid/README.txt
index 09b9cda29..9be358723 100644
--- a/examples/grid/README.txt
+++ b/examples/grid/README.txt
@@ -1,4 +1,4 @@
Grid Converters
===============
-A collection of example scripts for grid-connected converters.
\ No newline at end of file
+A collection of example scripts for grid converters.
\ No newline at end of file
diff --git a/examples/grid/grid_following/README.txt b/examples/grid/grid_following/README.txt
index c6bbdc86b..d4524c1f0 100644
--- a/examples/grid/grid_following/README.txt
+++ b/examples/grid/grid_following/README.txt
@@ -1,4 +1,4 @@
Grid-Following Control
----------------------
-These examples demonstrate grid-following control for grid-connected converters.
\ No newline at end of file
+These examples demonstrate grid-following control.
\ No newline at end of file
diff --git a/examples/grid/grid_following/plot_gfl_dc_bus_10kva.py b/examples/grid/grid_following/plot_gfl_dc_bus_10kva.py
index c63d078bb..203230167 100644
--- a/examples/grid/grid_following/plot_gfl_dc_bus_10kva.py
+++ b/examples/grid/grid_following/plot_gfl_dc_bus_10kva.py
@@ -58,8 +58,8 @@
ctrl.ref.u_dc = lambda t: 600 + (t > .02)*50
ctrl.ref.q_g = lambda t: (t > .04)*4e3
-# Set the external DC-bus current
-mdl.converter.i_ext = lambda t: (t > .06)*10
+# Set the external current fed to the DC bus
+mdl.converter.i_dc = lambda t: (t > .06)*10
# %%
# Create the simulation object and simulate it.
diff --git a/examples/grid/grid_forming/README.txt b/examples/grid/grid_forming/README.txt
index 696c50619..394d89339 100644
--- a/examples/grid/grid_forming/README.txt
+++ b/examples/grid/grid_forming/README.txt
@@ -1,7 +1,7 @@
Grid-Forming Control
--------------------
-These examples demonstrate grid-forming control for grid-connected converters. The example :doc:`/grid_examples/grid_forming/plot_gfm_rfpsc_13kva` uses a power-synchronization loop for synchronizing with the grid [#Har2020]_. In :doc:`/grid_examples/grid_forming/plot_gfm_obs_13kva`, disturbance-observer-based control is used [#Nur2024]_.
+These examples demonstrate grid-forming control. The example :doc:`/grid_examples/grid_forming/plot_gfm_rfpsc_13kva` uses a power-synchronization loop for synchronizing with the grid [#Har2020]_. In :doc:`/grid_examples/grid_forming/plot_gfm_obs_13kva`, disturbance-observer-based control is used [#Nur2024]_.
.. rubric:: References
diff --git a/motulator/__init__.py b/motulator/__init__.py
index a75a40173..7ee6af615 100644
--- a/motulator/__init__.py
+++ b/motulator/__init__.py
@@ -1,8 +1,8 @@
"""
-*motulator*: Motor Drive Simulator in Python
+*motulator*: Motor Drive and Grid Converter Simulator in Python
-This software includes continuous-time simulation models for induction machines
-and synchronous machines. Furthermore, selected examples of discrete-time
-control algorithms are included.
+This software includes continuous-time simulation models for electric machines
+drives and grid-connected converters. Furthermore, selected examples of
+discrete-time control algorithms are included.
"""
diff --git a/motulator/common/__init__.py b/motulator/common/__init__.py
index a2fcfc80d..5e5525a56 100644
--- a/motulator/common/__init__.py
+++ b/motulator/common/__init__.py
@@ -1,2 +1 @@
"""Common functions and classes."""
-
diff --git a/motulator/common/control/__init__.py b/motulator/common/control/__init__.py
index a88eb428e..9f906b5f4 100644
--- a/motulator/common/control/__init__.py
+++ b/motulator/common/control/__init__.py
@@ -1,12 +1,7 @@
"""Common control functions and classes."""
+
from motulator.common.control._control import (
- Clock,
- ComplexPIController,
- ControlSystem,
- PIController,
- PWM,
- RateLimiter,
-)
+ Clock, ComplexPIController, ControlSystem, PIController, PWM, RateLimiter)
__all__ = [
"Clock",
diff --git a/motulator/common/control/_control.py b/motulator/common/control/_control.py
index 79e001036..d60a86c19 100644
--- a/motulator/common/control/_control.py
+++ b/motulator/common/control/_control.py
@@ -23,6 +23,9 @@ class PWM:
k_comp : float, optional
Compensation factor for the delay effect on the voltage vector angle.
The default is 1.5.
+ u_cs0 : float, optional
+ Initial voltage (V) in stationary coordinates. This is used to compute
+ the realized voltage. The default is 0.
overmodulation : str, optional
Select one of the following overmodulation methods: minimum-magnitude-
error ("MME"); minimum-phase-error ("MPE"); six-step ("six_step"). The
@@ -40,11 +43,11 @@ class PWM:
"""
- def __init__(self, k_comp=1.5, overmodulation="MME"):
+ def __init__(self, k_comp=1.5, u_cs0=0, overmodulation="MME"):
self.k_comp = k_comp
self.overmodulation = overmodulation
- self.realized_voltage = 0
- self._old_u_cs = 0
+ self.realized_voltage = u_cs0
+ self._old_u_cs = u_cs0
@staticmethod
def six_step_overmodulation(ref_u_cs, u_dc):
@@ -191,7 +194,6 @@ def get_realized_voltage(self):
def update(self, u_cs):
"""Update the realized voltage."""
- # Update the voltage estimate for the next sampling instant
self.realized_voltage = .5*(self._old_u_cs + u_cs)
self._old_u_cs = u_cs
diff --git a/motulator/common/model/__init__.py b/motulator/common/model/__init__.py
index 806111b90..3a104c7a6 100644
--- a/motulator/common/model/__init__.py
+++ b/motulator/common/model/__init__.py
@@ -1,12 +1,7 @@
"""Common functions and classes for continuous-time system models."""
from motulator.common.model._simulation import (
- CarrierComparison,
- Delay,
- Model,
- Subsystem,
- zoh,
-)
+ CarrierComparison, Delay, Model, Subsystem, zoh)
__all__ = [
"CarrierComparison",
diff --git a/motulator/common/model/_converter.py b/motulator/common/model/_converter.py
index 6d004cd7b..c791025ae 100644
--- a/motulator/common/model/_converter.py
+++ b/motulator/common/model/_converter.py
@@ -7,7 +7,6 @@
wherever applicable.
"""
-
from types import SimpleNamespace
import numpy as np
@@ -28,21 +27,20 @@ class VoltageSourceConverter(Subsystem):
used as the initial condition.
C_dc : float, optional
DC-bus capacitance (F). The default is None.
- i_ext : callable, optional
+ i_dc : callable, optional
External current (A) fed to the DC bus. Needed if `C_dc` is not None.
"""
- def __init__(self, u_dc, C_dc=None, i_ext=lambda t: None):
+ def __init__(self, u_dc, C_dc=None, i_dc=lambda t: None):
super().__init__()
- self.i_ext = i_ext
self.par = SimpleNamespace(u_dc=u_dc, C_dc=C_dc)
self.inp = SimpleNamespace(q_cs=None, i_cs=0j)
- # Initialize states
if C_dc is not None:
self.state = SimpleNamespace(u_dc=u_dc)
self.sol_states = SimpleNamespace(u_dc=[])
- self.inp.i_ext = i_ext(0)
+ self.i_dc = i_dc
+ self.inp.i_dc = i_dc(0)
self.sol_q_cs = []
@property
@@ -58,8 +56,8 @@ def u_cs(self):
return self.inp.q_cs*self.u_dc
@property
- def i_dc(self):
- """DC-side current (A)."""
+ def i_dc_int(self):
+ """Converter-side DC current (A)."""
return 1.5*np.real(self.inp.q_cs*np.conj(self.inp.i_cs))
def set_outputs(self, _):
@@ -69,16 +67,15 @@ def set_outputs(self, _):
def set_inputs(self, t):
"""Set input variables."""
- if self.par.C_dc is None:
- pass
- self.inp.i_ext = self.i_ext(t)
+ if self.par.C_dc is not None:
+ self.inp.i_dc = self.i_dc(t)
def rhs(self):
"""Compute the state derivatives."""
- if self.par.C_dc is None:
- return None
- d_u_dc = (self.inp.i_ext - self.i_dc)/self.par.C_dc
- return [d_u_dc]
+ if self.par.C_dc is not None:
+ d_u_dc = (self.inp.i_dc - self.i_dc_int)/self.par.C_dc
+ return [d_u_dc]
+ return []
def meas_dc_voltage(self):
"""Measure the converter DC-bus voltage (V)."""
@@ -87,19 +84,19 @@ def meas_dc_voltage(self):
def post_process_states(self):
"""Post-process data."""
data = self.data
- if self.par.C_dc is None:
+ if self.par.C_dc is not None:
+ data.u_dc = data.u_dc.real
+ else:
if callable(self.u_dc):
self.data.u_dc = self.u_dc(self.data.t)
else:
self.data.u_dc = np.full(np.size(self.data.t), self.u_dc)
- else:
- data.u_dc = data.u_dc.real
data.u_cs = data.q_cs*data.u_dc
def post_process_with_inputs(self):
"""Post-process data with inputs."""
data = self.data
- data.i_dc = 1.5*np.real(data.q_cs*np.conj(data.i_cs))
+ data.i_dc_int = 1.5*np.real(data.q_cs*np.conj(data.i_cs))
# %%
@@ -136,11 +133,10 @@ def set_outputs(self, t):
"""Set output variables."""
super().set_outputs(t)
self.out.i_L = self.state.i_L.real
- self.out.i_dc = self.i_dc
def set_inputs(self, t):
"""Set output variables."""
- self.inp.i_ext = self.out.i_L
+ self.inp.i_dc = self.out.i_L
self.inp.u_dc = self.out.u_dc
def rhs(self):
diff --git a/motulator/common/utils/__init__.py b/motulator/common/utils/__init__.py
index 67a639c40..107b52d73 100644
--- a/motulator/common/utils/__init__.py
+++ b/motulator/common/utils/__init__.py
@@ -1,11 +1,6 @@
"""Common utilities."""
from motulator.common.utils._utils import (
- abc2complex,
- complex2abc,
- Sequence,
- Step,
- wrap,
-)
+ abc2complex, complex2abc, Sequence, Step, wrap)
__all__ = [
"abc2complex",
diff --git a/motulator/common/utils/_utils.py b/motulator/common/utils/_utils.py
index 5590d5346..02b515559 100644
--- a/motulator/common/utils/_utils.py
+++ b/motulator/common/utils/_utils.py
@@ -2,7 +2,6 @@
# %%
from dataclasses import dataclass
-from abc import ABC
import numpy as np
@@ -171,7 +170,7 @@ class NominalValues:
P : float
Power (W).
tau : float, optional
- Torque (Nm). Default value is None.
+ Torque (Nm). The default value is None.
"""
@@ -208,9 +207,9 @@ class BaseValues:
C : float
Capacitance (F).
tau : float, optional
- Torque (Nm). Default is None.
+ Torque (Nm). The default is None.
n_p : int, optional
- Number of pole pairs. Default is None.
+ Number of pole pairs. The default is None.
"""
u: float
@@ -243,7 +242,7 @@ def from_nominal(cls, nom, n_p=None):
n_p : int, optional
Number of pole pairs. If not given it is assumed that base values
- for a grid converter are calculated. Default is None.
+ for a grid converter are calculated. The default is None.
Returns
-------
diff --git a/motulator/drive/control/__init__.py b/motulator/drive/control/__init__.py
index bcbe595ea..8d6173fde 100644
--- a/motulator/drive/control/__init__.py
+++ b/motulator/drive/control/__init__.py
@@ -1,4 +1,8 @@
"""Controllers for machine drives."""
+
from motulator.drive.control._common import DriveControlSystem, SpeedController
-__all__ = ["DriveControlSystem", "SpeedController"]
+__all__ = [
+ "DriveControlSystem",
+ "SpeedController",
+]
diff --git a/motulator/drive/control/im/__init__.py b/motulator/drive/control/im/__init__.py
index 3547e89ed..2330427bb 100644
--- a/motulator/drive/control/im/__init__.py
+++ b/motulator/drive/control/im/__init__.py
@@ -1,4 +1,5 @@
"""Controls for induction machines."""
+
from motulator.drive.control.im._common import (
FullOrderObserver, FullOrderObserverCfg, Observer, ObserverCfg)
from motulator.drive.control.im._current_vector import (
diff --git a/motulator/drive/control/im/_obs_vhz.py b/motulator/drive/control/im/_obs_vhz.py
index de188d06c..3753b5590 100644
--- a/motulator/drive/control/im/_obs_vhz.py
+++ b/motulator/drive/control/im/_obs_vhz.py
@@ -1,6 +1,5 @@
"""Observer-based V/Hz control for induction machine drives."""
-# %%
from types import SimpleNamespace
from dataclasses import dataclass
diff --git a/motulator/drive/control/im/_vhz.py b/motulator/drive/control/im/_vhz.py
index a460b7462..5143376f5 100644
--- a/motulator/drive/control/im/_vhz.py
+++ b/motulator/drive/control/im/_vhz.py
@@ -1,6 +1,5 @@
"""V/Hz control for induction motor drives."""
-# %%
from dataclasses import dataclass, field, InitVar
from types import SimpleNamespace
from typing import Literal
diff --git a/motulator/drive/control/sm/__init__.py b/motulator/drive/control/sm/__init__.py
index 827d5b84c..e394eefdf 100644
--- a/motulator/drive/control/sm/__init__.py
+++ b/motulator/drive/control/sm/__init__.py
@@ -1,4 +1,5 @@
"""Controls for synchronous machines."""
+
from motulator.drive.control.sm._common import Observer, ObserverCfg
from motulator.drive.control.sm._flux_vector import (
FluxTorqueReference, FluxTorqueReferenceCfg, FluxVectorControl)
diff --git a/motulator/drive/control/sm/_torque.py b/motulator/drive/control/sm/_torque.py
index ba0c5a53f..ebf289a76 100644
--- a/motulator/drive/control/sm/_torque.py
+++ b/motulator/drive/control/sm/_torque.py
@@ -14,7 +14,6 @@
https://doi.org/10.1109/28.60058
"""
-
from sys import float_info
from types import SimpleNamespace
diff --git a/motulator/drive/model/__init__.py b/motulator/drive/model/__init__.py
index 921c049c9..7f1ff7ed3 100644
--- a/motulator/drive/model/__init__.py
+++ b/motulator/drive/model/__init__.py
@@ -1,29 +1,14 @@
"""Continuous-time machine drive models."""
from motulator.common.model._converter import (
- FrequencyConverter,
- VoltageSourceConverter,
-)
-from motulator.common.model._simulation import (
- CarrierComparison,
- Simulation,
-)
+ FrequencyConverter, VoltageSourceConverter)
+from motulator.common.model._simulation import CarrierComparison, Simulation
from motulator.drive.model._drive import (
- Drive,
- DriveWithLCFilter,
- DriveWithDiodeBridge,
-)
+ Drive, DriveWithLCFilter, DriveWithDiodeBridge)
from motulator.drive.model._lc_filter import LCFilter
-
-from motulator.drive.model._machine import (
- InductionMachine,
- SynchronousMachine,
-)
+from motulator.drive.model._machine import InductionMachine, SynchronousMachine
from motulator.drive.model._mechanics import (
- ExternalRotorSpeed,
- StiffMechanicalSystem,
- TwoMassMechanicalSystem,
-)
+ ExternalRotorSpeed, StiffMechanicalSystem, TwoMassMechanicalSystem)
__all__ = [
"CarrierComparison",
diff --git a/motulator/drive/utils/__init__.py b/motulator/drive/utils/__init__.py
index 858a18b68..f936601eb 100644
--- a/motulator/drive/utils/__init__.py
+++ b/motulator/drive/utils/__init__.py
@@ -1,26 +1,13 @@
"""This module contains utility functions for machine drives."""
+
from motulator.drive.utils._helpers import (
- InductionMachineInvGammaPars,
- InductionMachinePars,
- SynchronousMachinePars,
- TwoMassMechanicalSystemPars,
-)
-from motulator.drive.utils._plots import (
- plot,
- plot_extra,
-)
+ InductionMachineInvGammaPars, InductionMachinePars, SynchronousMachinePars,
+ TwoMassMechanicalSystemPars)
+from motulator.drive.utils._plots import plot, plot_extra
from motulator.drive.utils._flux_maps import (
- import_syre_data,
- plot_flux_map,
- plot_flux_vs_current,
- plot_torque_map,
-)
+ import_syre_data, plot_flux_map, plot_flux_vs_current, plot_torque_map)
from motulator.common.utils._utils import (
- BaseValues,
- NominalValues,
- Sequence,
- Step,
-)
+ BaseValues, NominalValues, Sequence, Step)
__all__ = [
"BaseValues",
diff --git a/motulator/drive/utils/_flux_maps.py b/motulator/drive/utils/_flux_maps.py
index b8d4cb331..0aa3174c5 100644
--- a/motulator/drive/utils/_flux_maps.py
+++ b/motulator/drive/utils/_flux_maps.py
@@ -1,6 +1,5 @@
"""Import and plot flux maps from the SyR-e project."""
-# %%
from types import SimpleNamespace
import numpy as np
diff --git a/motulator/drive/utils/_helpers.py b/motulator/drive/utils/_helpers.py
index 6a6cf1e5f..ce018f5f3 100644
--- a/motulator/drive/utils/_helpers.py
+++ b/motulator/drive/utils/_helpers.py
@@ -1,6 +1,5 @@
"""Common dataclasses usable in models and control of machine drives."""
-# %%
from abc import ABC
from dataclasses import dataclass
# Note: Union can be replaced by "|" in Python 3.10
diff --git a/motulator/drive/utils/_plots.py b/motulator/drive/utils/_plots.py
index 15502359c..c16dd3020 100644
--- a/motulator/drive/utils/_plots.py
+++ b/motulator/drive/utils/_plots.py
@@ -1,6 +1,5 @@
"""Example plotting scripts for machine drives."""
-# %%
from types import SimpleNamespace
import numpy as np
@@ -334,7 +333,7 @@ def plot_extra(sim, base=None, t_span=None):
label=r"$i_\mathrm{L}$")
ax2.plot(
mdl.converter.data.t,
- mdl.converter.data.i_dc/base.i,
+ mdl.converter.data.i_dc_int/base.i,
label=r"$i_\mathrm{dc}$")
ax2.plot(
mdl.converter.data.t,
diff --git a/motulator/grid/control/__init__.py b/motulator/grid/control/__init__.py
index cf0622ca8..2e3c6d64d 100644
--- a/motulator/grid/control/__init__.py
+++ b/motulator/grid/control/__init__.py
@@ -1,25 +1,13 @@
"""Controllers for grid-connected converters."""
from motulator.grid.control._common import (
- CurrentLimiter,
- DCBusVoltageController,
- GridConverterControlSystem,
- PLL,
-)
+ CurrentLimiter, DCBusVoltageController, GridConverterControlSystem, PLL)
from motulator.grid.control._grid_following import (
- CurrentController,
- CurrentRefCalc,
- GFLControl,
- GFLControlCfg,
-)
+ CurrentController, CurrentRefCalc, GFLControl, GFLControlCfg)
from motulator.grid.control._observer_gfm import (
- ObserverBasedGFMControl,
- ObserverBasedGFMControlCfg,
-)
+ ObserverBasedGFMControl, ObserverBasedGFMControlCfg)
from motulator.grid.control._power_synchronization import (
- RFPSCControl,
- RFPSCControlCfg,
-)
+ RFPSCControl, RFPSCControlCfg)
__all__ = [
"CurrentController",
diff --git a/motulator/grid/control/_common.py b/motulator/grid/control/_common.py
index b76122395..8299e7c6b 100644
--- a/motulator/grid/control/_common.py
+++ b/motulator/grid/control/_common.py
@@ -1,4 +1,5 @@
"""Common control functions and classes."""
+
from abc import ABC
from types import SimpleNamespace
@@ -11,36 +12,49 @@
# %%
class PLL:
"""
- Phase-locked loop.
+ Phase-locked loop including the voltage-magnitude filtering.
+
+ This class provides a simple frequency-tracking phase-locked loop. The
+ magnitude of the measured PCC voltage is also filtered.
Parameters
----------
- k_p : float
- Proportional gain.
- k_i : float
- Integral gain.
+ alpha_pll : float
+ Frequency-tracking bandwidth.
+ abs_u_g0 : float
+ Initial value for the grid voltage estimate.
w_g0 : float
- Initial value for the grid angular frequency estimate.
+ Initial value for the grid angular frequency estimate.
"""
- def __init__(self, k_p, k_i, w_g0, theta_g0=0):
- self.est = SimpleNamespace(w_g=w_g0, theta_g=theta_g0)
- self.gain = SimpleNamespace(k_p=k_p, k_i=k_i)
+ def __init__(self, alpha_pll, abs_u_g0, w_g0, theta_c0=0):
+ self.est = SimpleNamespace(
+ w_g=w_g0, theta_c=theta_c0, abs_u_g=abs_u_g0)
+ self.gain = SimpleNamespace(alpha_g=2*alpha_pll, k_w=alpha_pll**2)
def output(self, fbk):
- """Compute the frequency and phase angle estimates."""
- # Measured voltage in control coordinates
- fbk.u_g = fbk.u_gs*np.exp(-1j*fbk.theta_c)
- # Grid frequency estimate for the angle calculation
- fbk.w_g = self.gain.k_p*fbk.u_g.imag + self.est.w_g
+ """Output the estimates and coordinate transformed quantities."""
+ # Observer states
+ fbk.theta_c = self.est.theta_c
+ fbk.w_g = self.est.w_g
+ # Coordinate transformations
+ fbk.u_g = np.exp(-1j*fbk.theta_c)*fbk.u_gs
+ fbk.i_c = np.exp(-1j*fbk.theta_c)*fbk.i_cs
+ fbk.u_c = np.exp(-1j*fbk.theta_c)*fbk.u_cs
+ # Error signal
+ fbk.eps = fbk.u_g.imag/self.est.abs_u_g if self.est.abs_u_g > 0 else 0
+ # Angular speed of the coordinate system
+ fbk.w_c = fbk.w_g + self.gain.alpha_g*fbk.eps
return fbk
def update(self, T_s, fbk):
"""Update the integral states."""
- self.est.w_g += T_s*self.gain.k_i*fbk.u_g.imag
- self.est.theta_g += T_s*fbk.w_g
- self.est.theta_g = wrap(self.est.theta_g)
+ self.est.theta_c += T_s*fbk.w_c
+ self.est.theta_c = wrap(self.est.theta_c)
+ self.est.w_g += T_s*self.gain.k_w*fbk.eps
+ self.est.abs_u_g += T_s*self.gain.alpha_g*(
+ fbk.u_g.real - self.est.abs_u_g)
# %%
diff --git a/motulator/grid/control/_grid_following.py b/motulator/grid/control/_grid_following.py
index 204af8985..daca061b4 100644
--- a/motulator/grid/control/_grid_following.py
+++ b/motulator/grid/control/_grid_following.py
@@ -1,7 +1,6 @@
"""Grid-following control methods for grid converters."""
-# %%
-from dataclasses import dataclass, InitVar
+from dataclasses import dataclass
import numpy as np
@@ -29,32 +28,20 @@ class GFLControlCfg:
Sampling period (s). The default is 100e-6.
alpha_c : float, optional
Current-control bandwidth (rad/s). The default is 2*pi*400.
- alpha_ff : float, optional
- Low-pass-filtering bandwidth (rad/s) for the voltage-feedforward term.
- The default is 2*pi*200.
- w0_pll : float, optional
- Undamped natural frequency of the PLL. The default is 2*pi*20.
- zeta_pll : float, optional
- Damping ratio of the PLL. The default is 1.
+ alpha_pll : float, optional
+ PLL frequency-tracking bandwidth (rad/s). The default is 2*pi*20.
C_dc : float, optional
DC-bus capacitance (F). The default is None.
"""
-
grid_par: GridPars
filter_par: FilterPars
max_i: float
T_s: float = 100e-6
alpha_c: float = 2*np.pi*400
- alpha_ff: float = 2*np.pi*200
- w0_pll: InitVar[float] = 2*np.pi*20
- zeta_pll: InitVar[float] = 1
+ alpha_pll: float = 2*np.pi*20
C_dc: float = None
- def __post_init__(self, w0_pll, zeta_pll):
- self.k_p_pll = 2*zeta_pll*w0_pll/self.grid_par.u_gN
- self.k_i_pll = w0_pll**2/self.grid_par.u_gN
-
# %%
class GFLControl(GridConverterControlSystem):
@@ -80,27 +67,15 @@ def __init__(self, cfg):
super().__init__(cfg.grid_par, cfg.C_dc, cfg.T_s)
self.cfg = cfg
self.current_ctrl = CurrentController(cfg)
- self.pll = PLL(cfg.k_p_pll, cfg.k_i_pll, cfg.grid_par.w_gN)
+ self.pll = PLL(cfg.alpha_pll, cfg.grid_par.u_gN, cfg.grid_par.w_gN)
self.current_reference = CurrentRefCalc(cfg)
- # Initialize the states
- self.u_flt = cfg.grid_par.u_gN + 0j
-
def get_feedback_signals(self, mdl):
fbk = super().get_feedback_signals(mdl)
- fbk.theta_c = self.pll.est.theta_g
- # Transform the measured current in dq frame
- fbk.u_g = np.exp(-1j*fbk.theta_c)*fbk.u_gs
- fbk.i_c = np.exp(-1j*fbk.theta_c)*fbk.i_cs
- fbk.u_c = np.exp(-1j*fbk.theta_c)*fbk.u_cs
-
- # Calculating of active and reactive powers
- fbk.p_g = 1.5*np.real(fbk.u_c*np.conj(fbk.i_c))
- fbk.q_g = 1.5*np.imag(fbk.u_c*np.conj(fbk.i_c))
-
- # PLL
fbk = self.pll.output(fbk)
-
+ s_g = 1.5*fbk.u_c*np.conj(fbk.i_c)
+ fbk.p_g = s_g.real
+ fbk.q_g = s_g.imag
return fbk
def output(self, fbk):
@@ -109,21 +84,18 @@ def output(self, fbk):
ref = super().output(fbk)
ref = super().get_power_reference(fbk, ref)
ref = self.current_reference.get_current_reference(ref)
-
# Voltage reference generation in synchronous coordinates
- ref.u_c = self.current_ctrl.output(ref.i_c, fbk.i_c, self.u_flt)
+ ref.u_c = self.current_ctrl.output(
+ ref.i_c, fbk.i_c, self.pll.est.abs_u_g)
ref.u_cs = np.exp(1j*fbk.theta_c)*ref.u_c
-
# Duty ratios for PWM
- ref.d_abc = self.pwm(ref.T_s, ref.u_cs, fbk.u_dc, fbk.w_g)
-
+ ref.d_abc = self.pwm(ref.T_s, ref.u_cs, fbk.u_dc, fbk.w_c)
return ref
def update(self, fbk, ref):
"""Extend the base class method."""
super().update(fbk, ref)
- self.current_ctrl.update(ref.T_s, fbk.u_c, self.grid_par.w_gN)
- self.u_flt += ref.T_s*self.cfg.alpha_ff*(fbk.u_g - self.u_flt)
+ self.current_ctrl.update(ref.T_s, fbk.u_c, fbk.w_c)
self.pll.update(ref.T_s, fbk)
diff --git a/motulator/grid/control/_observer_gfm.py b/motulator/grid/control/_observer_gfm.py
index 4aa103536..98f2cf815 100644
--- a/motulator/grid/control/_observer_gfm.py
+++ b/motulator/grid/control/_observer_gfm.py
@@ -1,6 +1,5 @@
"""Disturbance-observer-based grid-forming control for grid converters."""
-# %%
from dataclasses import dataclass
import numpy as np
diff --git a/motulator/grid/control/_power_synchronization.py b/motulator/grid/control/_power_synchronization.py
index 5d416f3ef..5a8debae4 100644
--- a/motulator/grid/control/_power_synchronization.py
+++ b/motulator/grid/control/_power_synchronization.py
@@ -1,12 +1,12 @@
"""Power synchronization control for grid-connected converters."""
-# %%
from dataclasses import dataclass
import numpy as np
from motulator.common.utils import wrap
-from motulator.grid.control._common import CurrentLimiter, GridConverterControlSystem
+from motulator.grid.control._common import (
+ CurrentLimiter, GridConverterControlSystem)
from motulator.grid.utils import FilterPars, GridPars
diff --git a/motulator/grid/model/__init__.py b/motulator/grid/model/__init__.py
index 3cc8cf7dd..a4412738e 100644
--- a/motulator/grid/model/__init__.py
+++ b/motulator/grid/model/__init__.py
@@ -1,15 +1,8 @@
"""Continuous-time grid converter models."""
from motulator.common.model._converter import VoltageSourceConverter
-from motulator.common.model._simulation import (
- CarrierComparison,
- Simulation,
-)
-from motulator.grid.model._ac_filter import (
- ACFilter,
- LCLFilter,
- LFilter,
-)
+from motulator.common.model._simulation import CarrierComparison, Simulation
+from motulator.grid.model._ac_filter import ACFilter, LCLFilter, LFilter
from motulator.grid.model._converter_system import GridConverterSystem
from motulator.grid.model._voltage_source import ThreePhaseVoltageSource
diff --git a/motulator/grid/model/_ac_filter.py b/motulator/grid/model/_ac_filter.py
index bc0a80afa..52338532b 100644
--- a/motulator/grid/model/_ac_filter.py
+++ b/motulator/grid/model/_ac_filter.py
@@ -75,7 +75,7 @@ class LFilter(ACFilter):
An L filter and an inductive-resistive grid, between the converter and grid
voltage sources, are modeled combining their inductances and series
resistances. The point-of-common-coupling (PCC) voltage between the L
- filter and the grid impedance is separately calculated.
+ filter and the grid impedance is calculated.
Parameters
----------
diff --git a/motulator/grid/utils/__init__.py b/motulator/grid/utils/__init__.py
index aca162ef4..ceffac616 100644
--- a/motulator/grid/utils/__init__.py
+++ b/motulator/grid/utils/__init__.py
@@ -1,18 +1,8 @@
"""This module contains utility functions for grid converters."""
-from motulator.common.utils._utils import (
- BaseValues,
- NominalValues,
- Step,
-)
-from motulator.grid.utils._plots import (
- plot,
- plot_voltage_vector,
-)
-from motulator.grid.utils._utils import (
- FilterPars,
- GridPars,
-)
+from motulator.common.utils._utils import BaseValues, NominalValues, Step
+from motulator.grid.utils._plots import plot, plot_voltage_vector
+from motulator.grid.utils._utils import FilterPars, GridPars
__all__ = [
"BaseValues",
diff --git a/motulator/grid/utils/_plots.py b/motulator/grid/utils/_plots.py
index be5adda91..53bf383db 100644
--- a/motulator/grid/utils/_plots.py
+++ b/motulator/grid/utils/_plots.py
@@ -1,6 +1,5 @@
"""Example plotting scripts for grid converters."""
-# %%
from types import SimpleNamespace
import numpy as np
@@ -62,10 +61,8 @@ def plot(sim, base=None, plot_pcc_voltage=True, plot_w=False, t_span=None):
u_g_abc = complex2abc(mdl.ac_filter.data.u_gs).T
# Calculation of active and reactive powers
- p_g = 1.5*np.asarray(
- np.real(mdl.ac_filter.data.e_gs*np.conj(mdl.ac_filter.data.i_gs)))
- q_g = 1.5*np.asarray(
- np.imag(mdl.ac_filter.data.e_gs*np.conj(mdl.ac_filter.data.i_gs)))
+ p_g = 1.5*np.real(mdl.ac_filter.data.e_gs*np.conj(mdl.ac_filter.data.i_gs))
+ q_g = 1.5*np.imag(mdl.ac_filter.data.e_gs*np.conj(mdl.ac_filter.data.i_gs))
# Coordinate transformation in the case of observer-based GFM control
if hasattr(sim.ctrl, "observer"):
diff --git a/motulator/grid/utils/_utils.py b/motulator/grid/utils/_utils.py
index 07a1faede..0f24a855a 100644
--- a/motulator/grid/utils/_utils.py
+++ b/motulator/grid/utils/_utils.py
@@ -1,6 +1,5 @@
"""Common dataclasses usable in models and control of grid converters."""
-# %%
from abc import ABC
from dataclasses import dataclass