
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples/plot_2kw_ipmsm_fvc.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_plot_2kw_ipmsm_fvc.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_plot_2kw_ipmsm_fvc.py:


2.2-kW IPMSM, FVC
=================

This example simulates sensorless flux-vector control (FVC) of a 2.2-kW interior
permanent-magnet synchronous machine (IPMSM) drive natively. The system is that of the
*motulator* example :doc:`motulator:drive_examples/flux_vector/plot_2kw_ipmsm_fvc`.
The same system is also simulated in *motulator*, and the run times and the
differences are printed.

.. GENERATED FROM PYTHON SOURCE LINES 14-23

.. code-block:: Python

    import time
    from math import pi

    import motulator.drive.control.sm as control
    import numpy as np
    from motulator.drive import model, utils

    from motulator_export import native








.. GENERATED FROM PYTHON SOURCE LINES 24-25

Compute base values based on the nominal values.

.. GENERATED FROM PYTHON SOURCE LINES 25-30

.. code-block:: Python


    nom = utils.NominalValues(U=370, I=4.3, f=75, P=2.2e3, tau=14)
    base = utils.BaseValues.from_nominal(nom, n_p=3)









.. GENERATED FROM PYTHON SOURCE LINES 31-33

Configure the system model and the control system, as in the *motulator* example.
The function builds a new system for each simulation.

.. GENERATED FROM PYTHON SOURCE LINES 33-57

.. code-block:: Python



    def build_system() -> tuple[model.Drive, control.VectorControlSystem]:
        """Build the system model and the control system."""
        par = model.SynchronousMachinePars(
            n_p=3, R_s=3.6, L_d=0.036, L_q=0.051, psi_f=0.545
        )
        machine = model.SynchronousMachine(par)
        mechanics = model.MechanicalSystem(J=0.015)
        converter = model.VoltageSourceConverter(u_dc=540)
        mdl = model.Drive(machine, mechanics, converter)

        est_par = par  # Assume accurate model parameter estimates
        cfg = control.FluxVectorControllerCfg(i_s_max=1.5 * base.i, sensorless=True)
        vector_ctrl = control.FluxVectorController(est_par, cfg)
        speed_ctrl = control.SpeedController(J=0.015, alpha_s=2 * pi * 4)
        ctrl = control.VectorControlSystem(vector_ctrl, speed_ctrl)

        # Speed reference and external load torque
        ctrl.set_speed_ref(lambda t: (t > 0.2) * 2 * base.w_M)
        mdl.mechanics.set_external_load_torque(lambda t: (t > 0.8) * 0.7 * nom.tau)
        return mdl, ctrl









.. GENERATED FROM PYTHON SOURCE LINES 58-61

Simulate the system natively. Only the simulation object differs from the
*motulator* example: `native.Simulation` replaces `model.Simulation`, and the
results are plotted with the plotting functions of *motulator*.

.. GENERATED FROM PYTHON SOURCE LINES 61-69

.. code-block:: Python


    mdl, ctrl = build_system()
    sim = native.Simulation(mdl, ctrl)
    start = time.perf_counter()
    res = sim.simulate(t_stop=1.6)
    t_native = time.perf_counter() - start
    utils.plot(res, base)




.. image-sg:: /examples/images/sphx_glr_plot_2kw_ipmsm_fvc_001.png
   :alt: plot 2kw ipmsm fvc
   :srcset: /examples/images/sphx_glr_plot_2kw_ipmsm_fvc_001.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 70-72

Simulate the same system in *motulator*. The native simulation takes the same solver
steps, so the results agree to the rounding errors.

.. GENERATED FROM PYTHON SOURCE LINES 72-86

.. code-block:: Python


    mdl, ctrl = build_system()
    start = time.perf_counter()
    res_py = model.Simulation(mdl, ctrl).simulate(t_stop=1.6)
    t_py = time.perf_counter() - start

    print(f"Run time: native {t_native:.2f} s, motulator {t_py:.1f} s")
    diff = {
        "rotor speed (rad/s)": res.mdl.mechanics.w_M - res_py.mdl.mechanics.w_M,
        "stator current (A)": res.mdl.machine.i_s_ab - res_py.mdl.machine.i_s_ab,
        "torque reference (Nm)": res.ctrl.ref.tau_M - res_py.ctrl.ref.tau_M,
    }
    for name, d in diff.items():
        print(f"Maximum difference in the {name}: {np.max(np.abs(d)):.1e}")




.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    Run time: native 1.12 s, motulator 7.7 s
    Maximum difference in the rotor speed (rad/s): 2.3e-13
    Maximum difference in the stator current (A): 5.8e-13
    Maximum difference in the torque reference (Nm): 3.1e-13





.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 10.181 seconds)


.. _sphx_glr_download_examples_plot_2kw_ipmsm_fvc.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_2kw_ipmsm_fvc.ipynb <plot_2kw_ipmsm_fvc.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_2kw_ipmsm_fvc.py <plot_2kw_ipmsm_fvc.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_2kw_ipmsm_fvc.zip <plot_2kw_ipmsm_fvc.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
