-
-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathexample_dcmotor.py
More file actions
128 lines (94 loc) · 3.72 KB
/
example_dcmotor.py
File metadata and controls
128 lines (94 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#########################################################################################
##
## PathSim DC Motor Speed Control Example
##
#########################################################################################
# IMPORTS ===============================================================================
import numpy as np
import matplotlib.pyplot as plt
from pathsim import Simulation, Connection
from pathsim.blocks import StepSource, Integrator, Amplifier, Adder, Scope, AntiWindupPID, Clip
from pathsim.solvers import RKCK54
# DC MOTOR PARAMETERS ===================================================================
# Electrical parameters
R = 1.0 # Armature resistance [Ohm]
L = 0.001 # Armature inductance [H]
K_e = 0.1 # Back-EMF constant [V·s/rad]
# Mechanical parameters
J = 0.01 # Rotor inertia [kg·m²]
B = 0.001 # Viscous friction [N·m·s/rad]
K_t = 0.1 # Torque constant [N·m/A]
# PID controller parameters
Kp, Ki, Kd = 8.0, 15.0, 0.2
f_max = 100 # Derivative filter cutoff [Hz]
# Voltage limits
V_min, V_max = -24, 24
# SOURCE SIGNALS ========================================================================
# Speed setpoint: 50 -> 100 -> 75 -> 50 rad/s
spt_amplitudes = [50, 100, 75, 50]
spt_times = [0, 5, 15, 25]
# Load torque: brief spike then sustained load (negative opposes motion)
load_amplitudes = [0, -0.05, 0, -0.02, 0]
load_times = [0, 10, 12, 20, 30]
# SYSTEM SETUP ==========================================================================
# Control blocks
spt = StepSource(amplitude=spt_amplitudes, tau=spt_times)
lod = StepSource(amplitude=load_amplitudes, tau=load_times)
err = Adder("+-")
pid = AntiWindupPID(Kp, Ki, Kd, f_max=f_max, Ks=10, limits=[V_min, V_max])
sat = Clip(min_val=V_min, max_val=V_max)
# Electrical subsystem: L * di/dt = V - R*i - K_e*ω
V_R = Amplifier(-R) # Voltage drop across resistance
V_L = Amplifier(1/L) # di/dt calculation
emf = Amplifier(-K_e) # Back-EMF
V_sum = Adder("+++") # Voltage summation
I_int = Integrator(0) # Current integrator
# Mechanical subsystem: J * dω/dt = K_t*i - B*ω - T_load
T_m = Amplifier(K_t) # Motor torque
T_f = Amplifier(-B) # Friction torque
T_sum = Adder("+++") # Torque summation
alp = Amplifier(1/J) # Angular acceleration
omg = Integrator(0) # Angular velocity integrator
# Measurement
sco1 = Scope(labels=["Setpoint [rad/s]", "Speed [rad/s]"])
sco2 = Scope(labels=["Current [A]", "Voltage [V]"])
blocks = [
spt, lod, err, pid, sat,
V_R, V_L, emf, V_sum, I_int,
T_m, T_f, T_sum, alp, omg,
sco1, sco2
]
# CONNECTIONS ===========================================================================
connections = [
# Control loop
Connection(spt, err, sco1[0]),
Connection(omg, err[1], sco1[1]),
Connection(err, pid),
Connection(pid, sat),
# Electrical subsystem
Connection(sat, V_sum[0], sco2[1]),
Connection(I_int, V_R),
Connection(V_R, V_sum[1]),
Connection(omg, emf),
Connection(emf, V_sum[2]),
Connection(V_sum, V_L),
Connection(V_L, I_int),
# Mechanical subsystem
Connection(I_int, T_m, sco2[0]),
Connection(T_m, T_sum[0]),
Connection(omg, T_f),
Connection(T_f, T_sum[1]),
Connection(lod, T_sum[2]),
Connection(T_sum, alp),
Connection(alp, omg)
]
# SIMULATION ============================================================================
Sim = Simulation(blocks, connections, Solver=RKCK54)
# Run Example ===========================================================================
if __name__ == "__main__":
# Run simulation
Sim.run(30)
# Plot results
sco1.plot(lw=2)
sco2.plot(lw=2)
plt.show()