Usage

Contents

Usage#

After Installation, the system model and the control system are built as in motulator, see the usage of motulator. The package has a module for each system type:

from motulator_impedance import drive, grid

The system model and the control system are built in motulator as usual. The mechanical impedance of a drive, whose rotor speed is imposed by ExternalRotorSpeed:

import motulator.drive.control.im as control
import numpy as np
from motulator.drive import model

from motulator_impedance import drive

par = model.InductionMachineInvGammaPars(
    n_p=2, R_s=60e-3, R_R=30e-3, L_sgm=2.2e-3, L_M=24.5e-3
)
mechanics = model.ExternalRotorSpeed()
mechanics.set_external_rotor_speed(40.0)  # Operating-point speed (rad/s)
mdl = model.Drive(
    model.InductionMachine(par), mechanics, model.VoltageSourceConverter(u_dc=540)
)
cfg = control.ObserverBasedVHzControllerCfg(psi_s_nom=1.04, i_s_max=170.0)
ctrl = control.VHzControlSystem(control.ObserverBasedVHzController(par, cfg))
ctrl.set_speed_ref(40.0)

meas_cfg = drive.MeasurementCfg(abs_w_e=0.3, freqs=np.geomspace(1, 500, 50))

if __name__ == "__main__":  # Needed for the parallel processes, see Scope
    Z_M = drive.measure_mechanical_impedance(mdl, ctrl, meas_cfg)
    drive.plot_mechanical_impedance(Z_M)

The output admittance of a grid converter:

import numpy as np
from motulator.grid import control, model

from motulator_impedance import grid

mdl = model.GridConverterSystem(
    model.VoltageSourceConverter(u_dc=650),
    model.LFilter(L_f=5e-3),
    model.ThreePhaseSource(w_g=2 * np.pi * 50, e_g=326.6),
)
cfg = control.CurrentVectorControllerCfg(i_max=30.0, L=5e-3, T_s=1 / 10e3)
ctrl = control.GridConverterControlSystem(control.CurrentVectorController(cfg))
ctrl.set_power_ref(5e3)
ctrl.set_reactive_power_ref(0.0)

meas_cfg = grid.MeasurementCfg(abs_u_e=3.0, freqs=np.geomspace(1, 10e3, 100))

if __name__ == "__main__":
    Y = grid.measure_output_admittance(mdl, ctrl, meas_cfg)
    grid.plot_output_admittance(Y, form="re_im")

The results are dataclasses, which can be saved, e.g., by scipy.io.savemat(path, dataclasses.asdict(Y)). Complete examples are in the example gallery.

Scope#

  • The frequencies are simulated in parallel processes by default (multiprocess=True), so the model and the control system must be picklable: use module-level functions or callable objects as references, not lambda functions. In a script, call the measurement under if __name__ == "__main__":, since the processes import the script again on Windows and macOS, as well as on Linux from Python 3.14 onward. In the interactive interpreter, use multiprocess=False.

  • With carrier-comparison PWM, background switching harmonics can bias the measured admittance near the switching harmonics and their sidebands.

  • The grid impedance and the DC bus of the system model are included in the operating point; the admittance is measured with the PCC voltage imposed.