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

.. only:: html

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

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

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

.. _sphx_glr_drive_examples_current_vector_plot_2kw_im_cvc_discrete.py:


2.2-kW IM, discrete-time current control
========================================

This example compares the continuous-time and direct discrete-time designs of the
current controller in sensorless current-vector control of a 2.2-kW induction machine
(IM). The sampling frequency is 5 kHz and the current-control bandwidth is 2π·700 rad/s,
which is high compared with the sampling frequency.

.. GENERATED FROM PYTHON SOURCE LINES 12-20

.. code-block:: Python


    from math import pi

    import matplotlib.pyplot as plt

    import motulator.drive.control.im as control
    from motulator.drive import model, utils








.. GENERATED FROM PYTHON SOURCE LINES 21-22

Compute base values based on the nominal values.

.. GENERATED FROM PYTHON SOURCE LINES 22-26

.. code-block:: Python


    nom = utils.NominalValues(U=400, I=5, f=50, P=2.2e3, tau=14.6)
    base = utils.BaseValues.from_nominal(nom, n_p=2)








.. GENERATED FROM PYTHON SOURCE LINES 27-28

Configure the machine parameters.

.. GENERATED FROM PYTHON SOURCE LINES 28-36

.. code-block:: Python


    par = model.InductionMachineInvGammaPars(
        n_p=2, R_s=3.7, R_R=2.1, L_sgm=0.021, L_M=0.224
    )
    est_par = control.InductionMachineInvGammaPars(
        n_p=2, R_s=3.7, R_R=2.1, L_sgm=0.021, L_M=0.224
    )








.. GENERATED FROM PYTHON SOURCE LINES 37-40

Simulate the drive in torque-control mode at the constant speed of 0.5 p.u. The
discrete-time design compensates for the delays itself, which is taken into account
in the PWM configuration.

.. GENERATED FROM PYTHON SOURCE LINES 40-69

.. code-block:: Python



    def simulate(discrete: bool):
        mdl = model.Drive(
            model.InductionMachine(par),
            model.ExternalRotorSpeed(),
            model.VoltageSourceConverter(u_dc=540),
            pwm=True,
        )
        mdl.mechanics.set_external_rotor_speed(lambda t: 0.5 * base.w_M)
        cfg = control.CurrentVectorControllerCfg(
            psi_s_nom=base.psi,
            i_s_max=2 * base.i,
            alpha_c=2 * pi * 700,
            T_s=200e-6,
            discrete=discrete,
        )
        pwm = control.PWM(k_comp=0) if discrete else None
        vector_ctrl = control.CurrentVectorController(est_par, cfg)
        vector_ctrl.observer.speed_observer.w_M = 0.5 * base.w_M  # Initial speed estimate
        ctrl = control.VectorControlSystem(vector_ctrl, pwm=pwm)
        ctrl.set_torque_ref(
            lambda t: nom.tau * (0.3 * (t > 0.3) + 0.2 * (t > 0.32) - 0.8 * (t > 0.34))
        )
        return model.Simulation(mdl, ctrl).simulate(t_stop=0.37)


    res_cont, res_disc = simulate(discrete=False), simulate(discrete=True)








.. GENERATED FROM PYTHON SOURCE LINES 70-71

Plot the current responses in per-unit values.

.. GENERATED FROM PYTHON SOURCE LINES 71-90

.. code-block:: Python


    _, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 5), sharex=True)
    for res, ls, label in [(res_cont, "--", "continuous"), (res_disc, "-", "discrete")]:
        t, i_s = res.ctrl.t, res.ctrl.fbk.i_s / base.i
        ax1.plot(t, i_s.real, ls, ds="steps-post", label=label)
        ax2.plot(t, i_s.imag, ls, ds="steps-post", label=label)
    i_s_ref = res_disc.ctrl.ref.i_s / base.i
    ax1.plot(t, i_s_ref.real, "k:", ds="steps-post", label="reference")
    ax2.plot(t, i_s_ref.imag, "k:", ds="steps-post", label="reference")
    ax1.set_ylabel(r"$i_\mathrm{d}$ (p.u.)")
    ax1.set_ylim(0.5, 0.7)
    ax2.set_ylabel(r"$i_\mathrm{q}$ (p.u.)")
    ax2.set_xlabel("Time (s)")
    ax2.set_xlim(0.29, 0.37)
    ax2.legend(loc="lower left")
    for ax in (ax1, ax2):
        ax.grid(True)
    plt.show()




.. image-sg:: /drive_examples/current_vector/images/sphx_glr_plot_2kw_im_cvc_discrete_001.png
   :alt: plot 2kw im cvc discrete
   :srcset: /drive_examples/current_vector/images/sphx_glr_plot_2kw_im_cvc_discrete_001.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 91-93

At this bandwidth, the continuous-time design results in poorly damped oscillations,
while the discrete-time design is well damped.


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

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


.. _sphx_glr_download_drive_examples_current_vector_plot_2kw_im_cvc_discrete.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_im_cvc_discrete.ipynb <plot_2kw_im_cvc_discrete.ipynb>`

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

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

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

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


.. only:: html

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

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