Skip to content

Commit 70f767c

Browse files
committed
docs: refactor DCMotor with @mtkmodel
1 parent 04d8d08 commit 70f767c

File tree

1 file changed

+48
-45
lines changed

1 file changed

+48
-45
lines changed

docs/src/tutorials/dc_motor_pi.md

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,51 +20,54 @@ using ModelingToolkitStandardLibrary.Mechanical.Rotational
2020
using ModelingToolkitStandardLibrary.Blocks
2121
using OrdinaryDiffEq
2222
using Plots
23-
24-
R = 0.5 # [Ohm] armature resistance
25-
L = 4.5e-3 # [H] armature inductance
26-
k = 0.5 # [N.m/A] motor constant
27-
J = 0.02 # [kg.m²] inertia
28-
f = 0.01 # [N.m.s/rad] friction factor
29-
tau_L_step = -0.3 # [N.m] amplitude of the load torque step
30-
nothing # hide
3123
```
3224

3325
The actual model can now be composed.
3426

3527
```@example dc_motor_pi
36-
systems = @named begin
37-
ground = Ground()
38-
source = Voltage()
39-
ref = Blocks.Step(height = 1, start_time = 0)
40-
pi_controller = Blocks.LimPI(k = 1.1, T = 0.035, u_max = 10, Ta = 0.035)
41-
feedback = Blocks.Feedback()
42-
R1 = Resistor(R = R)
43-
L1 = Inductor(L = L)
44-
emf = EMF(k = k)
45-
fixed = Fixed()
46-
load = Torque()
47-
load_step = Blocks.Step(height = tau_L_step, start_time = 3)
48-
inertia = Inertia(J = J)
49-
friction = Damper(d = f)
50-
speed_sensor = SpeedSensor()
28+
@mtkmodel DCMotor begin
29+
@parameters begin
30+
R = 0.5, [description = "Armature resistance"] # Ohm
31+
L = 4.5e-3, [description = "Armature inductance"] # H
32+
k = 0.5, [description = "Motor constant"] # N.m/A
33+
J = 0.02, [description = "Inertia"] # kg.m²
34+
f = 0.01, [description = "Friction factor"] # N.m.s/rad
35+
tau_L_step = -0.3, [description = "Amplitude of the load torque step"] # N.m
36+
end
37+
@components begin
38+
ground = Ground()
39+
source = Voltage()
40+
ref = Blocks.Step(height = 1, start_time = 0)
41+
pi_controller = Blocks.LimPI(k = 1.1, T = 0.035, u_max = 10, Ta = 0.035)
42+
feedback = Blocks.Feedback()
43+
R1 = Resistor(R = R)
44+
L1 = Inductor(L = L)
45+
emf = EMF(k = k)
46+
fixed = Fixed()
47+
load = Torque()
48+
load_step = Blocks.Step(height = tau_L_step, start_time = 3)
49+
inertia = Inertia(J = J)
50+
friction = Damper(d = f)
51+
speed_sensor = SpeedSensor()
52+
end
53+
@equations begin
54+
connect(fixed.flange, emf.support, friction.flange_b)
55+
connect(emf.flange, friction.flange_a, inertia.flange_a)
56+
connect(inertia.flange_b, load.flange)
57+
connect(inertia.flange_b, speed_sensor.flange)
58+
connect(load_step.output, load.tau)
59+
connect(ref.output, feedback.input1)
60+
connect(speed_sensor.w, :y, feedback.input2)
61+
connect(feedback.output, pi_controller.err_input)
62+
connect(pi_controller.ctr_output, :u, source.V)
63+
connect(source.p, R1.p)
64+
connect(R1.n, L1.p)
65+
connect(L1.n, emf.p)
66+
connect(emf.n, source.n, ground.g)
67+
end
5168
end
5269
53-
connections = [connect(fixed.flange, emf.support, friction.flange_b)
54-
connect(emf.flange, friction.flange_a, inertia.flange_a)
55-
connect(inertia.flange_b, load.flange)
56-
connect(inertia.flange_b, speed_sensor.flange)
57-
connect(load_step.output, load.tau)
58-
connect(ref.output, feedback.input1)
59-
connect(speed_sensor.w, :y, feedback.input2)
60-
connect(feedback.output, pi_controller.err_input)
61-
connect(pi_controller.ctr_output, :u, source.V)
62-
connect(source.p, R1.p)
63-
connect(R1.n, L1.p)
64-
connect(L1.n, emf.p)
65-
connect(emf.n, source.n, ground.g)]
66-
67-
@named model = ODESystem(connections, t; systems)
70+
@named model = DCMotor()
6871
nothing # hide
6972
```
7073

@@ -75,12 +78,12 @@ so that it can be represented as a system of `ODEs` (ordinary differential equat
7578
```@example dc_motor_pi
7679
sys = structural_simplify(model)
7780
prob = ODEProblem(sys, unknowns(sys) .=> 0.0, (0, 6.0))
78-
sol = solve(prob, Rodas4())
81+
sol = solve(prob)
7982
80-
p1 = plot(sol.t, sol[inertia.w], ylabel = "Angular Vel. in rad/s",
83+
p1 = plot(sol.t, sol[sys.inertia.w], ylabel = "Angular Vel. in rad/s",
8184
label = "Measurement", title = "DC Motor with Speed Controller")
82-
plot!(sol.t, sol[ref.output.u], label = "Reference")
83-
p2 = plot(sol.t, sol[load.tau.u], ylabel = "Disturbance in Nm", label = "")
85+
plot!(sol.t, sol[sys.ref.output.u], label = "Reference")
86+
p2 = plot(sol.t, sol[sys.load.tau.u], ylabel = "Disturbance in Nm", label = "")
8487
plot(p1, p2, layout = (2, 1))
8588
```
8689

@@ -89,8 +92,8 @@ plot(p1, p2, layout = (2, 1))
8992
When implementing and tuning a control system in simulation, it is a good practice to analyze the closed-loop properties and verify robustness of the closed-loop with respect to, e.g., modeling errors. To facilitate this, we added two analysis points to the set of connections above, more specifically, we added the analysis points named `:y` and `:u` to the connections (for more details on analysis points, see [Linear Analysis](@ref))
9093

9194
```julia
92-
connect(speed_sensor.w, :y, feedback.input2)
93-
connect(pi_controller.ctr_output, :u, source.V)
95+
connect(sys.speed_sensor.w, :y, feedback.input2)
96+
connect(sys.pi_controller.ctr_output, :u, source.V)
9497
```
9598

9699
one at the plant output (`:y`) and one at the plant input (`:u`). We may use these analysis points to calculate, e.g., sensitivity functions, illustrated below. Here, we calculate the sensitivity function $S(s)$ and the complimentary sensitivity function $T(s) = I - S(s)$, defined as
@@ -108,7 +111,7 @@ matrices_S, simplified_sys = Blocks.get_sensitivity(
108111
model, :y, op = Dict(unknowns(sys) .=> 0.0))
109112
So = ss(matrices_S...) |> minreal # The output-sensitivity function as a StateSpace system
110113
matrices_T, simplified_sys = Blocks.get_comp_sensitivity(
111-
model, :y, op = Dict(inertia.phi => 0.0, inertia.w => 0.0))
114+
model, :y, op = Dict(model.inertia.phi => 0.0, model.inertia.w => 0.0))
112115
To = ss(matrices_T...)# The output complementary sensitivity function as a StateSpace system
113116
bodeplot([So, To], label = ["S" "T"], plot_title = "Sensitivity functions",
114117
plotphase = false)

0 commit comments

Comments
 (0)