Skip to content

Commit 42fff05

Browse files
adds DC motor with friction
1 parent 39b9d00 commit 42fff05

File tree

13 files changed

+264
-41
lines changed

13 files changed

+264
-41
lines changed

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ version = "1.4.0"
77
IfElse = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
88
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
99
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
10-
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
1110
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
1211

1312
[compat]
@@ -20,7 +19,9 @@ julia = "1.6"
2019

2120
[extras]
2221
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
22+
Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4"
23+
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
2324
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2425

2526
[targets]
26-
test = ["SafeTestsets", "Test"]
27+
test = ["SafeTestsets", "Sundials", "OrdinaryDiffEq", "Test"]

src/Blocks/Blocks.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
The module `Blocks` contains common input-output components, referred to as blocks.
33
"""
44
module Blocks
5-
using ModelingToolkit, Symbolics, OrdinaryDiffEq
5+
using ModelingToolkit, Symbolics
66
using IfElse: ifelse
77

88
@parameters t

src/Electrical/Analog/ideal_components.jl

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ See [OnePort](@ref)
2626
- `n` Negative pin
2727
2828
# Parameters:
29-
- `R`: [`Ω`] Resistance
29+
- `R`: [`Ohm`] Resistance
3030
"""
3131
function Resistor(;name, R)
3232
@named oneport = OnePort()
@@ -70,8 +70,7 @@ end
7070
Creates an ideal capacitor.
7171
7272
# States:
73-
- `v(t)`: [`V`]
74-
The voltage across the capacitor, given by `D(v) ~ p.i / C`
73+
- `v(t)`: [`V`] The voltage across the capacitor, given by `D(v) ~ p.i / C`
7574
7675
# Connectors:
7776
- `p` Positive pin
@@ -161,4 +160,78 @@ function Short(; name)
161160
@unpack v, i = oneport
162161
eqs = [v ~ 0]
163162
extend(ODESystem(eqs, t, [], []; name=name), oneport)
163+
end
164+
165+
"""
166+
HeatingResistor(;name, R_ref=1.0, T_ref=300.15, alpha=0)
167+
168+
Temperature dependent electrical resistor
169+
170+
# States
171+
- See [OnePort](@ref)
172+
- `R(t)`: [`Ohm`] Temperature dependent resistance `R ~ R_ref*(1 + alpha*(heat_port.T(t) - T_ref))`
173+
174+
# Connectors
175+
- `p` Positive pin
176+
- `n` Negative pin
177+
178+
# Parameters:
179+
- `R_ref`: [`Ω`] Reference resistance
180+
- `T_ref`: [K] Reference temperature
181+
"""
182+
function HeatingResistor(;name, R_ref=1.0, T_ref=300.15, alpha=0)
183+
@named oneport = OnePort()
184+
@unpack v, i = oneport
185+
@named heat_port = HeatPort()
186+
pars = @parameters begin
187+
R_ref=R_ref
188+
T_ref=T_ref
189+
alpha=alpha
190+
end
191+
@variables R
192+
eqs = [
193+
R ~ R_ref*(1 + alpha*(heat_port.T - T_ref))
194+
heat_port.Q_flow ~ -v * i # -LossPower
195+
v ~ i * R
196+
]
197+
extend(ODESystem(eqs, t, [R], pars; name=name, systems=[heat_port]), oneport)
198+
end
199+
200+
"""
201+
EMF(;name, k)
202+
203+
Electromotoric force (electric/mechanic transformer)
204+
205+
# States
206+
- `v(t)`: [`V`] The voltage across component `p.v - n.v`
207+
- `i(t)`: [`A`] The current passing through positive pin
208+
- `phi`: [`rad`] Rotation angle (=flange.phi - support.phi)
209+
- `w`: [`rad/s`] Angular velocity (= der(phi))
210+
211+
# Connectors
212+
- `p` [Pin](@ref) Positive pin
213+
- `n` [Pin](@ref) Negative pin
214+
- `flange` [Flange](@ref) Shaft of EMF shaft
215+
- `support` [Support](@ref) Support/housing of emf shaft
216+
217+
# Parameters:
218+
- `k`: [`N⋅m/A`] Transformation coefficient
219+
"""
220+
function EMF(;name, k)
221+
@named p = Pin()
222+
@named n = Pin()
223+
@named flange = Flange()
224+
@named support = Support()
225+
@parameters k=k
226+
@variables v(t)=0.0 i(t)=0.0 phi(t)=0.0 w(t)=0.0
227+
eqs = [
228+
v ~ p.v - n.v
229+
0 ~ p.i + n.i
230+
i ~ p.i
231+
phi ~ flange.phi - support.phi
232+
D(phi) ~ w
233+
k*w ~ v
234+
flange.tau ~ -k*i
235+
]
236+
ODESystem(eqs, t, [v, i, phi, w], [k]; name=name, systems=[p, n, flange, support])
164237
end

src/Electrical/Electrical.jl

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,27 @@ This library contains electrical components to build up analog circuits.
44
"""
55
module Electrical
66

7-
using ModelingToolkit, Symbolics, IfElse, OrdinaryDiffEq
7+
using ModelingToolkit, Symbolics, IfElse
88
using OffsetArrays
9+
using ..Thermal: HeatPort
10+
using ..Mechanical.Rotational: Flange, Support
11+
using ..Blocks: RealInput, RealOutput
912

1013
@parameters t
1114
D = Differential(t)
1215

13-
using ..Blocks: RealInput, RealOutput
14-
16+
export Pin, OnePort
1517
include("utils.jl")
18+
19+
export Capacitor, Ground, Inductor, Resistor, Short, IdealOpAmp, EMF
1620
include("Analog/ideal_components.jl")
21+
22+
export CurrentSensor, PotentialSensor, VoltageSensor, PowerSensor, MultiSensor
1723
include("Analog/sensors.jl")
24+
25+
export Voltage, Current
1826
include("Analog/sources.jl")
27+
1928
# include("Digital/components.jl")
2029
# include("Digital/gates.jl")
2130
# include("Digital/tables.jl")
@@ -26,23 +35,4 @@ include("Analog/sources.jl")
2635
# - machines
2736
# - multi-phase
2837

29-
export #Interface
30-
Pin,
31-
# Analog Components
32-
Capacitor, Ground, Inductor, Resistor, Conductor,
33-
Short, IdealOpAmp,
34-
# Analog Sensors
35-
CurrentSensor, PotentialSensor, VoltageSensor,
36-
PowerSensor, MultiSensor,
37-
# Analog Sources
38-
Voltage, Current
39-
40-
41-
# # Digital Gates
42-
# And, Or, Not, Xor, Nand, Nor, Xnor,
43-
# # Digital components
44-
# HalfAdder, FullAdder, MUX, DEMUX, Encoder, Decoder,
45-
# # Digital Sources
46-
# DigitalPin, Pulse, PulseDiff
47-
4838
end

src/Mechanical/Rotational/components.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ end
3939
function Inertia(;name, J, phi_start=0.0, w_start=0.0, a_start=0.0)
4040
@named flange_a = Flange()
4141
@named flange_b = Flange()
42+
J > 0 || throw(ArgumentError("Expected `J` to be positive"))
4243
@parameters J=J
4344
sts = @variables begin
4445
phi(t)=phi_start
@@ -75,6 +76,7 @@ Linear 1D rotational spring
7576
function Spring(;name, c, phi_rel0=0.0)
7677
@named partial_comp = PartialCompliant()
7778
@unpack phi_rel, tau = partial_comp
79+
c > 0 || throw(ArgumentError("Expected `c` to be positive"))
7880
pars = @parameters begin
7981
c=c
8082
phi_rel0=phi_rel0
@@ -104,6 +106,7 @@ Linear 1D rotational damper
104106
function Damper(;name, d)
105107
@named partial_comp = PartialCompliantWithRelativeStates()
106108
@unpack w_rel, tau = partial_comp
109+
d > 0 || throw(ArgumentError("Expected `d` to be positive"))
107110
pars = @parameters d=d
108111
eqs = [tau ~ d*w_rel]
109112
extend(ODESystem(eqs, t, [], pars; name=name), partial_comp)
@@ -132,6 +135,7 @@ This element characterizes any type of gear box which is fixed in the ground and
132135
function IdealGear(;name, ratio, use_support=false)
133136
@named partial_element = PartialElementaryTwoFlangesAndSupport2(use_support=use_support)
134137
@unpack phi_support, flange_a, flange_b = partial_element
138+
ratio > 0 || throw(ArgumentError("Expected `ratio` to be positive"))
135139
@parameters ratio=ratio
136140
sts = @variables phi_a(t)=0.0 phi_b(t)=0.0
137141
eqs = [
@@ -143,7 +147,6 @@ function IdealGear(;name, ratio, use_support=false)
143147
extend(ODESystem(eqs, t, sts, [ratio]; name=name), partial_element)
144148
end
145149

146-
147150
"""
148151
RotationalFriction(;name, f, tau_c, w_brk, tau_brk)
149152

src/Mechanical/Rotational/sources.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Torque(;name)
2+
Torque(; name, use_support=false)
33
44
Input signal acting as external torque on a flange
55
@@ -22,7 +22,6 @@ function Torque(;name, use_support=false)
2222
end
2323

2424

25-
2625
"""
2726
Speed(; name, use_support=false, exact=false, f_crit=50)
2827

src/Mechanical/Rotational/utils.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ Partial model for a component with one rotational 1-dim. shaft flange and a supp
121121
function PartialElementaryOneFlangeAndSupport2(;name, use_support=false)
122122
@named flange = Flange()
123123
sys = [flange]
124-
@variables phi_support(t)
124+
@variables phi_support(t)=0.0
125125
if use_support
126126
@named support = Support()
127127
eqs = [

src/ModelingToolkitStandardLibrary.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ module ModelingToolkitStandardLibrary
22

33
include("Blocks/Blocks.jl")
44
include("Mechanical/Mechanical.jl")
5+
include("Thermal/Thermal.jl")
56
include("Electrical/Electrical.jl")
67
include("Magnetic/Magnetic.jl")
7-
include("Thermal/Thermal.jl")
88

99
end

test/Blocks/sources.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ end
9797
sys = structural_simplify(iosys)
9898
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 10.0))
9999
sol = solve(prob, Rodas4())
100-
101100
@test sol.retcode == :Success
102101
@test sol[src.output.u] cosine.(sol.t, frequency, amplitude, phase, offset, start_time) atol=1e-3
103102

@@ -161,7 +160,6 @@ end
161160
sys = structural_simplify(iosys)
162161
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 10.0))
163162
sol = solve(prob, Rodas4())
164-
165163
@test sol.retcode == :Success
166164
@test sol[src.output.u] ramp.(sol.t, offset, height, duration, start_time) atol=1e-3
167165

@@ -350,7 +348,6 @@ end
350348
sys = structural_simplify(iosys)
351349
prob = ODEProblem(sys, Pair[int.x=>0.0], (0.0, 10.0))
352350
sol = solve(prob, Rodas4())
353-
354351
@test sol.retcode == :Success
355352
@test sol[src.output.u] exp_sine.(sol.t, amplitude, frequency, damping, phase, start_time) atol=1e-3
356353

test/Electrical/analog.jl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ end
149149
@named model = ODESystem(connections, t; systems=[resistor, capacitor, source, ground, voltage])
150150
sys = structural_simplify(model)
151151
prob = ODAEProblem(sys, [capacitor.v => 10.0], (0.0, 10.0))
152-
sol = solve(prob, Rodas5())
153-
@test sol.retcode == :Success
154152
sol = solve(prob, Tsit5())
155153
@test sol.retcode == :Success
154+
sol = solve(prob, Rodas4())
155+
@test sol.retcode == :Success
156156

157157
# Plots.plot(sol; vars=[voltage.v, capacitor.v])
158158
end
@@ -272,7 +272,6 @@ _damped_sine_wave(x, f, A, st, ϕ, d) = exp((st-x)*d)*A*sin(2*π*f*(x-st) + ϕ)
272272

273273
prob = ODAEProblem(vsys, u0, (0, 10.0))
274274
sol = solve(prob, dt=0.1, Tsit5())
275-
276275
@test sol.retcode == :Success
277276
@test sol[voltage.V.u] waveforms(i, sol.t) atol=1e-1
278277
@test sol[voltage.p.v] sol[voltage.V.u]
@@ -326,12 +325,11 @@ end
326325

327326
prob = ODAEProblem(isys, u0, (0, 10.0))
328327
sol = solve(prob, dt=0.1, Tsit5())
329-
330328
@test sol.retcode == :Success
331329
@test sol[current.I.u] waveforms(i, sol.t) atol=1e-1
332330
@test sol[current.I.u] sol[current.p.i] atol=1e-1
333331
# For visual inspection
334332
# plt = plot(sol)
335333
# savefig(plt, "test_current_$(source.name)")
336334
end
337-
end
335+
end

0 commit comments

Comments
 (0)