ModelingToolkit extension

Everything on this page lives in InductionMachineDrivesMTKExt and exists only when both ModelingToolkit and OrdinaryDiffEq are loaded:

using ModelingToolkit, OrdinaryDiffEq, InductionMachineDrives

Julia loads an extension only once every package in its trigger list is present. using ModelingToolkit alone leaves the four public builders at zero methods, and calling one then raises a MethodError listing no methods — that means a trigger is missing, not that the function is broken.

InductionMachineDrivesMTKExt.InductionMachineDrivesMTKExt — Module
InductionMachineDrivesMTKExt

ModelingToolkit extension for InductionMachineDrives.

Everything symbolic lives here: the continuous equation builders and the two acausal system assemblies. It loads automatically once both ModelingToolkit and OrdinaryDiffEq are present in the session, so

using InductionMachineDrives                                        # hybrid simulators only, no MTK
using InductionMachineDrives, ModelingToolkit, OrdinaryDiffEq       # + the MTK system builders

Both triggers are required. Julia loads an extension only once every package in its trigger list is present, so using ModelingToolkit alone leaves the builders at zero methods — OrdinaryDiffEq is not optional here, because the simulate_* functions default to Rodas5P() and call solve.

The hybrid FOC simulators in src/simulators/ are plain Julia over concrete Float64 state and never touch symbolic types, which is what makes this split possible — see Plan.md.

Note on D: the equation builders write D(x) ~ ... without ever naming ModelingToolkit. They depend on the D_nounits as D alias imported below, which used to live at the top of the main module. Moving a builder out of this module without carrying that import along will fail at parse time.

source

Public system builders

These four names are declared as empty stubs in src/InductionMachineDrives.jl and get their methods here. A package extension can add methods to a function its parent already declares, but it cannot introduce a new binding into the parent's namespace — which is why the stubs exist at all.

InductionMachineDrives.build_scalar_im_system — Function
build_scalar_im_system(; kwargs...)

Builds the complete scalar-control induction-machine system.

This is the equivalent of the top-level Simulink diagram.

Connections:

frequency profile -> scalar V/f controller -> IM plant
load profile -------------------------------> IM plant
IM plant outputs ---------------------------> optional observer
source
InductionMachineDrives.build_foc_current_im_system — Function
build_foc_current_im_system(; kwargs...)

Builds a first current-loop FOC test system.

Connections:

current reference profile -> FOC current controller -> IM plant
load profile ---------------------------------------> IM plant
IM plant outputs -----------------------------------> rotor-flux observer
observer outputs -----------------------------------> FOC current controller

This is not yet full FOC. It is only the inner current-loop test.

source

build_scalar_im_model is a backward-compatible const alias for build_scalar_im_system, declared in the parent module for the same binding reason.

Reference profiles

InductionMachineDrivesMTKExt.build_frequency_command_eqs — Method
build_frequency_command_eqs(f_cmd; frequency_profile, f_ref, f_ref_val,
                            f_step_val, t_hold_val, t_step_val)

Builds the frequency reference profile equations.

This block is a test/reference generator, not a controller and not the plant.

Supported profiles:

  • :constant
  • :steps

For :steps, with:

f_ref_val = 25.0
f_step_val = 5.0
t_hold_val = 1.0
t_step_val = 1.0

the profile is:

0–1 s      -> 0 Hz
1–2 s      -> 5 Hz
2–3 s      -> 10 Hz
3–4 s      -> 15 Hz
4–5 s      -> 20 Hz
5 s onward -> 25 Hz
source
InductionMachineDrivesMTKExt.build_load_torque_eqs — Method
build_load_torque_eqs(Tload_cmd; load_profile, Tload,
                      Tload_step1_val, Tload_step2_val,
                      t_load_step1_val, t_load_step2_val)

Builds the load torque profile equations.

This block is a mechanical input generator, not the plant.

Supported profiles:

  • :constant
  • :steps

For :steps, the profile is:

0–t_load_step1       -> 0 Nm
t_load_step1–t_load_step2 -> Tload_step1_val
after t_load_step2   -> Tload_step2_val
source

Controls

InductionMachineDrivesMTKExt.build_foc_current_controller_eqs — Method
build_foc_current_controller_eqs(vars, pars)

Continuous-time simplified FOC current controller for an induction machine.

This block is based on the MATLAB current-controller logic, adapted to the continuous-time ModelingToolkit model.

Inputs:

  • isdref, isqref
  • isdeobs, isqeobs
  • ws_obs
  • λrdeobs

Outputs:

  • vsdref, vsqref
  • vsα, vsβ
  • isdreflim, isqreflim
  • voltage_saturation
  • ismodobs

The controller does not contain plant equations.

source

Plant

InductionMachineDrivesMTKExt.build_induction_machine_alpha_beta_eqs — Method
build_induction_machine_alpha_beta_eqs(vars, pars)

Builds the induction machine plant equations in stationary αβ coordinates.

Plant inputs:

  • vsα
  • vsβ
  • Tload_cmd

Plant states:

  • isα, isβ
  • irα, irβ
  • ωm, θm

Plant outputs:

  • Te
  • n_rpm
  • fluxes and currents

The plant does not know whether the voltage was generated by scalar control, FOC, a measured profile, or another controller.

source

Observer

InductionMachineDrivesMTKExt.build_rotor_flux_observer_eqs — Method
build_rotor_flux_observer_eqs(vars, pars)

Rotor-flux and torque observer for the induction machine.

This is based on the MATLAB function obs_flujo_L1_alfabeta, adapted to continuous-time ModelingToolkit equations.

Important robustness detail: At startup, rotor flux is zero, so the flux angle is undefined. To avoid a singular atan2(0,0), the angle is regularized with a small epsilon.

source
The `D` alias

The equation builders above write D(x) ~ ... without ever naming ModelingToolkit. They rely on the D_nounits as D import at the top of ext/InductionMachineDrivesMTKExt.jl. Moving a builder out of that module without carrying the import fails at parse time.