Skip to content

Commit

Permalink
Refactoring (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhinkkan authored Apr 11, 2024
1 parent cd5ff27 commit c84f792
Show file tree
Hide file tree
Showing 33 changed files with 449 additions and 283 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"editor.rulers": [
80
79
],
"editor.formatOnType": false,
"editor.formatOnSave": true,
Expand Down
2 changes: 1 addition & 1 deletion examples/flux_vector/plot_flux_vector_pmsm_2kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
# %%
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=1.6)

# %%
Expand Down
31 changes: 17 additions & 14 deletions examples/flux_vector/plot_flux_vector_pmsyrm_5kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
=========================
This example simulates sensorless stator-flux-vector control of a 5.5-kW
PM-SyRM (Baldor ECS101M0H7EF4) drive. The machine model is parametrized using an
algebraic saturation model, fitted to the flux linkage maps measured using the
constant-speed test. For comparison, the measured data is plotted together with
the model predictions. Notice that the control system used in this example does
not consider the saturation, only the system model does.
PM-SyRM (Baldor ECS101M0H7EF4) drive. The machine model is parametrized using
an algebraic saturation model, fitted to the flux linkage maps measured using
the constant-speed test. For comparison, the measured data is plotted together
with the model predictions. Notice that the control system used in this example
does not consider the saturation, only the system model does.
"""

Expand Down Expand Up @@ -35,14 +35,15 @@
# available later.


# pylint: disable=too-many-locals
def i_s(psi_s):
"""
Saturation model for a 5.5-kW PM synchronous reluctance machine.
Saturation model for a 5.5-kW PM-SyRM.
This model takes into account the bridge saturation in addition to the
regular self- and cross-saturation effects of the d- and q-axis. The bridge
saturation model is based on a nonlinear reluctance element in parallel
with the Norton-equivalent PM model.
with the Norton-equivalent PM model.
Parameters
----------
Expand All @@ -56,8 +57,9 @@ def i_s(psi_s):
Notes
-----
This model can also be used for other PM synchronous reluctance machines by
changing the model parameters.
For simplicity, the saturation model parameters are hard-coded in the
function below. This model can also be used for other PM-SyRMs by changing
the model parameters.
"""
# d-axis self-saturation
Expand Down Expand Up @@ -131,8 +133,8 @@ def i_s(psi_s):
plt.show()

# %%
# Solve the PM flux linkage for the initial value of the stator flux, which is
# needed in the machine model below.
# Solve the PM flux linkage for the initial value of the stator flux linkage,
# which is needed in the machine model below.

res = minimize_scalar(
lambda psi_d: np.abs(i_s(psi_d)), bounds=(0, base.psi), method="bounded")
Expand All @@ -143,12 +145,13 @@ def i_s(psi_s):

machine = model.sm.SynchronousMachineSaturated(
n_p=2, R_s=.63, current=i_s, psi_s0=psi_s0)
# Magnetically linear PMSyRM model for comparison
# Magnetically linear PM-SyRM model for comparison
# machine = model.sm.SynchronousMachine(
# n_p=2, R_s=.63, L_d=18e-3, L_q=110e-3, psi_f=.47)
# n_p=2, R_s=.63, L_d=18e-3, L_q=110e-3, psi_f=.47)
mechanics = model.Mechanics(J=.015)
converter = model.Inverter(u_dc=540)
mdl = model.sm.Drive(machine, mechanics, converter)
# mdl.pwm = model.CarrierComparison() # Enable the PWM model

# %%
# Configure the control system.
Expand Down Expand Up @@ -178,7 +181,7 @@ def i_s(psi_s):
# %%
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=4)

# %%
Expand Down
2 changes: 1 addition & 1 deletion examples/flux_vector/plot_flux_vector_syrm_7kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def i_s(psi_s):
# %%
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=4)

# %%
Expand Down
6 changes: 2 additions & 4 deletions examples/obs_vhz/plot_obs_vhz_ctrl_im_2kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,9 @@
# mdl.mech.tau_L_w = lambda w_M: np.sign(w_M)*k*w_M**2

# %%
# Create the simulation object and simulate it. You can also enable the PWM
# model (which makes simulation slower). One-sampling-period computational
# delay is modeled.
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False, delay=1)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=4)

# %%
Expand Down
6 changes: 2 additions & 4 deletions examples/obs_vhz/plot_obs_vhz_ctrl_pmsm_2kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,9 @@
mdl.mechanics.tau_L_t = Sequence(times, values)

# %%
# Create the simulation object and simulate it. You can also enable the PWM
# model (which makes simulation slower). One-sampling-period computational
# delay is modeled.
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False, delay=1)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=8)

# %%
Expand Down
6 changes: 3 additions & 3 deletions examples/obs_vhz/plot_obs_vhz_ctrl_pmsm_2kw_two_mass.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
This example simulates observer-based V/Hz control of a 2.2-kW PMSM drive. The
mechanical subsystem is modeled as a two-mass system. The resonance frequency
of the mechanics is around 85 Hz. The mechanical parameters correspond to
[#Saa2015]_, except that the torsional damping is set to a smaller value in this
example.
[#Saa2015]_, except that the torsional damping is set to a smaller value in
this example.
"""

Expand Down Expand Up @@ -57,7 +57,7 @@
# %%
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=1.2)
# sphinx_gallery_thumbnail_number = 3
plot(sim, base) # Plot results in per-unit values
Expand Down
6 changes: 2 additions & 4 deletions examples/obs_vhz/plot_obs_vhz_ctrl_pmsyrm_thor.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,9 @@ def i_s(psi_s):
# mdl.mechanics.tau_L_t = Sequence(times, values)

# %%
# Create the simulation object and simulate it. You can also enable the PWM
# model (which makes simulation slower). One-sampling-period computational
# delay is modeled.
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False, delay=1)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=8)

# %%
Expand Down
10 changes: 4 additions & 6 deletions examples/obs_vhz/plot_obs_vhz_ctrl_syrm_7kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
# but the same model structure can also be used for other synchronous motors.
# For PM motors, the magnetomotive force (MMF) of the PMs can be modeled using
# constant current source `i_f` on the d-axis [#Awa2018]_, [#Jah1986]_.
# Correspondingly, this approach assumes that the MMFs of the d-axis current and
# of the PMs are in series. This model cannot capture the desaturation
# Correspondingly, this approach assumes that the MMFs of the d-axis current
# and of the PMs are in series. This model cannot capture the desaturation
# phenomenon of thin iron ribs, see [#Arm2009]_ for details. For such motors,
# look-up tables can be used.

Expand Down Expand Up @@ -104,11 +104,9 @@ def i_s(psi_s):
mdl.mechanics.tau_L_t = Sequence(times, values)

# %%
# Create the simulation object and simulate it. You can also enable the PWM
# model (which makes simulation slower). One-sampling-period computational
# delay is modeled.
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False, delay=1)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=8)

# %%
Expand Down
2 changes: 1 addition & 1 deletion examples/signal_inj/plot_signal_inj_pmsm_2kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
# %%
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=4)

# %%
Expand Down
4 changes: 2 additions & 2 deletions examples/signal_inj/plot_signal_inj_syrm_7kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

# Speed reference
times = np.array([0, .25, .25, .375, .5, .625, .75, .75, 1])*4
values = np.array([0, 0, 1, 1, 0, -1, -1, 0, 0])*base.w*.1
values = np.array([0, 0, 1, 1, 0, -1, -1, 0, 0])*.1*base.w
ctrl.w_m_ref = Sequence(times, values)
# External load torque
times = np.array([0, .125, .125, .875, .875, 1])*4
Expand All @@ -56,7 +56,7 @@
# %%
# Create the simulation object and simulate it.

sim = model.Simulation(mdl, ctrl, pwm=False)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=4)

# %%
Expand Down
21 changes: 6 additions & 15 deletions examples/vector/plot_vector_ctrl_im_2kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

def L_s(psi):
"""
Stator inductance saturation model for a 2.2-kW machine.
Stator inductance saturation model for a 2.2-kW induction machine.
Parameters
----------
Expand Down Expand Up @@ -59,13 +59,15 @@ def L_s(psi):
n_p=2, R_s=3.7, R_r=2.5, L_ell=.023, L_s=L_s)
# Unsaturated machine model, using its inverse-Γ parameters (uncomment to try)
# machine = model.im.InductionMachineInvGamma(
# R_s=3.7, R_R=2.1, L_sgm=.021, L_M=.224, n_p=2)
# n_p=2, R_s=3.7, R_R=2.1, L_sgm=.021, L_M=.224)
# Alternatively, configure the machine model using its Γ parameters
# machine = model.im.InductionMachine(
# R_s=3.7, R_r=2.5, L_ell=.023, L_s=.245, n_p=2)
# n_p=2, R_s=3.7, R_r=2.5, L_ell=.023, L_s=.245)
mechanics = model.Mechanics(J=.015)
converter = model.Inverter(u_dc=540)
mdl = model.im.Drive(machine, mechanics, converter)
# mdl.pwm = model.CarrierComparison() # Try to enable the PWM model
# mdl.delay = model.Delay(2) # Try longer computational delay

# %%
# Configure the control system.
Expand Down Expand Up @@ -94,22 +96,11 @@ def L_s(psi):
# ctrl.w_m_ref = lambda t: (t > .2)*(2*base.w)
# mdl.mechanics.tau_L_t = lambda t: 0

# Speed reversals under the rated load (uncomment to try, change t_stop=8 below)
# import numpy as np
# from motulator.helpers import Sequence
# times = np.array([0, .125, .25, .375, .5, .625, .75, .875, 1])*8
# values = np.array([0, 0, 1, 1, 0, -1, -1, 0, 0])*base.w
# ctrl.w_m_ref = Sequence(times, values)
# # External load torque
# times = np.array([0, .125, .125, .875, .875, 1])*8
# values = np.array([0, 0, 1, 1, 0, 0])*base.tau_nom
# mdl.mechanics.tau_L_t = Sequence(times, values)

# %%
# Create the simulation object and simulate it. You can also enable the PWM
# model (which makes simulation slower).

sim = model.Simulation(mdl, ctrl, pwm=False)
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=1.5)

# %%
Expand Down
37 changes: 11 additions & 26 deletions examples/vector/plot_vector_ctrl_pmsm_2kw.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
"""
2.2-kW PMSM
===========
2.2-kW PMSM, diode bridge
=========================
This example simulates sensorless vector control of a 2.2-kW PMSM drive.
This example simulates sensorless vector control of a 2.2-kW PMSM drive.
"""

# %%
# Imports.

import numpy as np
from motulator import model, control
from motulator import BaseValues, Sequence, plot, plot_extra
from motulator import BaseValues, plot

# %%
# Compute base values based on the nominal values (just for figures).
Expand All @@ -27,6 +26,7 @@
mechanics = model.Mechanics(J=.015)
converter = model.Inverter(u_dc=540)
mdl = model.sm.Drive(machine, mechanics, converter)
# mdl.pwm = model.CarrierComparison() # Enable the PWM model

# %%
# Configure the control system.
Expand All @@ -40,30 +40,15 @@
# Set the speed reference and the external load torque.

# Speed reference
times = np.array([0, .125, .25, .375, .5, .625, .75, .875, 1])*4
values = np.array([0, 0, 1, 1, 0, -1, -1, 0, 0])*base.w
ctrl.w_m_ref = Sequence(times, values)
# External load torque
times = np.array([0, .125, .125, .875, .875, 1])*4
values = np.array([0, 0, 1, 1, 0, 0])*base.tau_nom
mdl.mechanics.tau_L_t = Sequence(times, values)
ctrl.w_m_ref = lambda t: (t > .2)*2*base.w

# mdl.mechanics.tau_L_t = lambda t: (t > .8)*base.tau_nom*.7
# ctrl.w_m_ref = lambda t: (t > .2)*(2*base.w)
# External load torque
mdl.mechanics.tau_L_t = lambda t: (t > .8)*.7*base.tau_nom

# %%
# Create the simulation object and simulate it.

# Simulate the system without modeling PWM
sim = model.Simulation(mdl, ctrl, pwm=False)
sim.simulate(t_stop=4)
plot(sim, base) # Plot results in per-unit values.

# Repeat the same simulation with PWM model enabled (takes a bit longer)
mdl.clear() # First clear the stored data from the previous simulation run
ctrl.clear()
sim = model.Simulation(mdl, ctrl, pwm=True)
sim.simulate(t_stop=4)
# Simulate the system and plot results in per-unit values
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=1.4)
plot(sim, base)
# Plot a zoomed view
plot_extra(sim, t_span=(1.1, 1.125), base=base)
58 changes: 58 additions & 0 deletions examples/vector/plot_vector_ctrl_pmsm_2kw_diode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""
2.2-kW PMSM, diode bridge
=========================
This example simulates sensorless vector control of a 2.2-kW PMSM drive,
equipped with a diode bridge rectifier.
"""

# %%
# Imports.

from motulator import model, control
from motulator import BaseValues, plot, plot_extra

# %%
# Compute base values based on the nominal values (just for figures).

base = BaseValues(
U_nom=370, I_nom=4.3, f_nom=75, tau_nom=14, P_nom=2.2e3, n_p=3)

# %%
# Configure the system model.

machine = model.sm.SynchronousMachine(
n_p=3, R_s=3.6, L_d=.036, L_q=.051, psi_f=.545)
mechanics = model.Mechanics(J=.015)
converter = model.FrequencyConverter(L=2e-3, C=235e-6, U_g=400, f_g=50)
mdl = model.sm.DriveWithDiodeBridge(machine, mechanics, converter)
mdl.pwm = model.CarrierComparison() # Enable the PWM model

# %%
# Configure the control system.

par = control.sm.ModelPars(
n_p=3, R_s=3.6, L_d=.036, L_q=.051, psi_f=.545, J=.015)
ref = control.sm.CurrentReferencePars(par, w_m_nom=base.w, i_s_max=1.5*base.i)
ctrl = control.sm.VectorCtrl(par, ref, T_s=250e-6, sensorless=True)

# %%
# Set the speed reference and the external load torque.

# Speed reference
ctrl.w_m_ref = lambda t: (t > .2)*base.w

# External load torque
mdl.mechanics.tau_L_t = lambda t: (t > .6)*base.tau_nom

# %%
# Create the simulation object and simulate it.

# Simulate the system
sim = model.Simulation(mdl, ctrl)
sim.simulate(t_stop=1)

# Plot results in per-unit values
plot(sim, base)
plot_extra(sim, base, t_span=(.8, .825))
Loading

0 comments on commit c84f792

Please sign in to comment.