Skip to content

Commit 31afae3

Browse files
adds DC motor with friction
adds speed sensor test adds DC motor test in runtests.jl adds test for speed sensor adds rel. speed sensor adds tests adds comment adds parameter checks adds ViscousFriction adds checks for return codes Update analog.jl Update rotational.jl fix test adds missing default value add missing link to tutorial
1 parent 1854c8d commit 31afae3

File tree

20 files changed

+711
-166
lines changed

20 files changed

+711
-166
lines changed

Project.toml

Lines changed: 4 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]
@@ -19,8 +18,11 @@ Symbolics = "0.1, 1, 2, 3, 4"
1918
julia = "1.6"
2019

2120
[extras]
21+
DASSL = "e993076c-0cfd-5d6b-a1ac-36489fdf7917"
2222
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
23+
Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4"
24+
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
2325
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2426

2527
[targets]
26-
test = ["SafeTestsets", "Test"]
28+
test = ["DASSL", "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/Blocks/continuous.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Outputs `y = ∫k*u dt`, corresponding to the transfer function `1/s`.
66
# Connectors:
77
- `input`
88
- `output`
9+
10+
# Parameters:
11+
- `k`: Gain of integrator
12+
- `x_start`: Initial value of integrator
913
"""
1014
function Integrator(;name, k=1, x_start=0.0)
1115
@named siso = SISO()

src/Blocks/utils.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@connector function RealInput(;name, nin=1, u_start=nin > 1 ? 0.0 : zeros(nin))
1+
@connector function RealInput(;name, nin=1, u_start=nin > 1 ? zeros(nin) : 0.0)
22
if nin == 1
33
@variables u(t) = u_start
44
else
@@ -20,7 +20,7 @@ Connector with one input signal of type Real.
2020
- `u`: Value of of the connector; if nin=1 this is a scalar
2121
""" RealInput
2222

23-
@connector function RealOutput(;name, nout=1, u_start=nout > 1 ? 0.0 : zeros(nout))
23+
@connector function RealOutput(;name, nout=1, u_start=nout > 1 ? zeros(nout) : 0.0)
2424
if nout == 1
2525
@variables u(t) = u_start
2626
else

src/Electrical/Analog/ideal_components.jl

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,78 @@ function IdealOpAmp(;name)
159159
]
160160
ODESystem(eqs, t, sts, [], systems=[p1, p2, n1, n2], name=name)
161161
end
162+
163+
164+
"""
165+
HeatingResistor(;name, R_ref=1.0, T_ref=300.15, alpha=0)
166+
167+
Temperature dependent electrical resistor
168+
169+
# States
170+
- See [OnePort](@ref)
171+
- `R(t)`: [`Ω`] Temperature dependent resistance `R ~ R_ref*(1 + alpha*(heat_port.T(t) - T_ref))`
172+
173+
# Connectors
174+
- `p` Positive pin
175+
- `n` Negative pin
176+
177+
# Parameters:
178+
- `R_ref`: [`Ω`] Reference resistance
179+
- `T_ref`: [K] Reference temperature
180+
"""
181+
function HeatingResistor(;name, R_ref=1.0, T_ref=300.15, alpha=0)
182+
@named oneport = OnePort()
183+
@unpack v, i = oneport
184+
@named heat_port = HeatPort()
185+
pars = @parameters begin
186+
R_ref=R_ref
187+
T_ref=T_ref
188+
alpha=alpha
189+
end
190+
@variables R
191+
eqs = [
192+
R ~ R_ref*(1 + alpha*(heat_port.T - T_ref))
193+
heat_port.Q_flow ~ -v * i # -LossPower
194+
v ~ i * R
195+
]
196+
extend(ODESystem(eqs, t, [R], pars; name=name, systems=[heat_port]), oneport)
197+
end
198+
199+
"""
200+
EMF(;name, k)
201+
202+
Electromotoric force (electric/mechanic transformer)
203+
204+
# States
205+
- `v(t)`: [`V`] The voltage across component `p.v - n.v`
206+
- `i(t)`: [`A`] The current passing through positive pin
207+
- `phi`: [`rad`] Rotation angle (=flange.phi - support.phi)
208+
- `w`: [`rad/s`] Angular velocity (= der(phi))
209+
210+
# Connectors
211+
- `p` Positive pin
212+
- `n` Negative pin
213+
- `flange` Shaft of EMF shaft
214+
- `support` Support/housing of emf shaft
215+
216+
# Parameters:
217+
- `k`: [`N⋅m/A`] Transformation coefficient
218+
"""
219+
function EMF(;name, k)
220+
@named p = Pin()
221+
@named n = Pin()
222+
@named flange = Flange()
223+
@named support = Support()
224+
@parameters k=k
225+
@variables v(t)=0.0 i(t)=0.0 phi(t)=0.0 w(t)=0.0
226+
eqs = [
227+
v ~ p.v - n.v
228+
0 ~ p.i + n.i
229+
i ~ p.i
230+
phi ~ flange.phi - support.phi
231+
D(phi) ~ w
232+
k*w ~ v
233+
flange.tau ~ -k*i
234+
]
235+
ODESystem(eqs, t, [v, i, phi, w], [k]; name=name, systems=[p, n, flange, support])
236+
end

src/Electrical/Electrical.jl

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,28 @@ 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 SignalVoltage, ConstantVoltage, SineVoltage, StepVoltage, RampVoltage, SquareVoltage, TriangularVoltage, CosineVoltage, ExpSineVoltage
26+
export SignalCurrent, ConstantCurrent, SineCurrent, StepCurrent, RampCurrent, SquareCurrent, TriangularCurrent, CosineCurrent, ExpSineCurrent
1827
include("Analog/sources.jl")
28+
1929
# include("Digital/components.jl")
2030
# include("Digital/gates.jl")
2131
# include("Digital/tables.jl")
@@ -26,23 +36,4 @@ include("Analog/sources.jl")
2636
# - machines
2737
# - multi-phase
2838

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-
4839
end

src/Mechanical/Rotational/Rotational.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,23 @@ Library to model 1-dimensional, rotational mechanical systems
33
"""
44
module Rotational
55

6-
using ModelingToolkit, Symbolics, IfElse, OrdinaryDiffEq
6+
using ModelingToolkit, Symbolics, IfElse
77
using OffsetArrays
88
using ...Blocks: RealInput, RealOutput
99

1010
@parameters t
1111
D = Differential(t)
1212

13-
export Flange
13+
export Flange, Support
1414
include("utils.jl")
1515

16-
export Fixed, Inertia, Spring, Damper, IdealGear
16+
export Fixed, Inertia, Spring, Damper, IdealGear, RotationalFriction, ViscousFriction
1717
include("components.jl")
1818

19-
export Torque
19+
export Torque, Speed
2020
include("sources.jl")
2121

22+
export AngleSensor, SpeedSensor, TorqueSensor, RelSpeedSensor
23+
include("sensors.jl")
24+
2225
end

src/Mechanical/Rotational/components.jl

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,43 @@
33
44
Flange fixed in housing at a given angle.
55
6+
# Connectors:
7+
- `flange` flange
8+
69
# Parameters:
710
- `phi0`: [rad] Fixed offset angle of housing
811
"""
912
function Fixed(;name, phi0=0.0)
1013
@named flange = Flange()
11-
@parameters phi0=phi0
14+
# @parameters phi0=phi0
1215
eqs = [flange.phi ~ phi0]
13-
return compose(ODESystem(eqs, t, [], [phi0]; name=name), flange)
16+
return compose(ODESystem(eqs, t, [], []; name=name), flange)
1417
end
1518

1619
"""
1720
Inertia(;name, J, phi_start=0.0, w_start=0.0, a_start=0.0)
1821
1922
1D-rotational component with inertia.
2023
24+
# States:
25+
- `phi`: [rad] Absolute rotation angle of component
26+
- `w`: [rad/s] Absolute angular velocity of component (= der(phi))
27+
- `a`: [rad/s²] Absolute angular acceleration of component (= der(w))
28+
29+
# Connectors:
30+
- `flange_a` Left flange
31+
- `flange_b` Right flange
32+
2133
# Parameters:
2234
- `J`: [kg·m²] Moment of inertia
2335
- `phi_start`: [rad] Initial value of absolute rotation angle of component
2436
- `w_start`: [rad/s] Initial value of absolute angular velocity of component
2537
- `a_start`: [rad/s²] Initial value of absolute angular acceleration of component
26-
27-
# States:
28-
- `phi`: [rad] Absolute rotation angle of component
29-
- `w`: [rad/s] Absolute angular velocity of component (= der(phi))
30-
- `a`: [rad/s²] Absolute angular acceleration of component (= der(w))
3138
"""
3239
function Inertia(;name, J, phi_start=0.0, w_start=0.0, a_start=0.0)
3340
@named flange_a = Flange()
3441
@named flange_b = Flange()
42+
J > 0 || throw(ArgumentError("Expected `J` to be positive"))
3543
@parameters J=J
3644
sts = @variables begin
3745
phi(t)=phi_start
@@ -53,13 +61,20 @@ end
5361
5462
Linear 1D rotational spring
5563
64+
# States:
65+
- See [PartialCompliant](@ref)
66+
67+
# Connectors:
68+
- See [PartialCompliant](@ref)
69+
5670
# Parameters:
5771
- `c`: [N.m/rad] Spring constant
5872
- `phi_rel0`: Unstretched spring angle
5973
"""
6074
function Spring(;name, c, phi_rel0=0.0)
6175
@named partial_comp = PartialCompliant()
6276
@unpack phi_rel, tau = partial_comp
77+
c > 0 || throw(ArgumentError("Expected `c` to be positive"))
6378
pars = @parameters begin
6479
c=c
6580
phi_rel0=phi_rel0
@@ -73,12 +88,19 @@ end
7388
7489
Linear 1D rotational damper
7590
91+
# States:
92+
- See [PartialCompliantWithRelativeStates](@ref)
93+
94+
# Connectors:
95+
- See [PartialCompliantWithRelativeStates](@ref)
96+
7697
# Parameters:
7798
- `d`: [N.m.s/rad] Damping constant
7899
"""
79100
function Damper(;name, d)
80101
@named partial_comp = PartialCompliantWithRelativeStates()
81102
@unpack w_rel, tau = partial_comp
103+
d > 0 || throw(ArgumentError("Expected `d` to be positive"))
82104
pars = @parameters d=d
83105
eqs = [tau ~ d*w_rel]
84106
extend(ODESystem(eqs, t, [], pars; name=name), partial_comp)
@@ -98,6 +120,7 @@ This element characterizes any type of gear box which is fixed in the ground and
98120
function IdealGear(;name, ratio, use_support=false)
99121
@named partial_element = PartialElementaryTwoFlangesAndSupport2(use_support=use_support)
100122
@unpack phi_support, flange_a, flange_b = partial_element
123+
ratio > 0 || throw(ArgumentError("Expected `ratio` to be positive"))
101124
@parameters ratio=ratio
102125
sts = @variables phi_a(t)=0.0 phi_b(t)=0.0
103126
eqs = [
@@ -107,4 +130,70 @@ function IdealGear(;name, ratio, use_support=false)
107130
0 ~ ratio*flange_a.tau + flange_b.tau
108131
]
109132
extend(ODESystem(eqs, t, sts, [ratio]; name=name), partial_element)
133+
end
134+
135+
"""
136+
RotationalFriction(;name, f, tau_c, w_brk, tau_brk)
137+
138+
Models rotational friction with Stribeck effect, Coulomb friction and viscous friction between the two flanges.
139+
The friction torque is a function of the relative angular velocity between flange_a and flange_b.
140+
141+
Friction model: "Armstrong, B. and C.C. de Wit, Friction Modeling and Compensation, The Control Handbook, CRC Press, 1995."
142+
143+
# States:
144+
- see [`PartialCompliantWithRelativeStates`](@ref)
145+
146+
# Connectors:
147+
- See [`PartialCompliantWithRelativeStates`](@ref)
148+
149+
# Parameters:
150+
- `f`: [`N⋅m/(rad/s)`] Viscous friction coefficient
151+
- `tau_c`: [`N⋅m`] Coulomb friction torque
152+
- `w_brk`: [`rad/s`] Breakaway friction velocity
153+
- `tau_brk`: [`N⋅m`] Breakaway friction torque
154+
"""
155+
function RotationalFriction(;name, f, tau_c, w_brk, tau_brk)
156+
@named partial_comp = PartialCompliantWithRelativeStates()
157+
@unpack w_rel, tau = partial_comp
158+
w_brk > 0 || throw(ArgumentError("Expected `w_brk` to be positive"))
159+
tau_brk > 0 || throw(ArgumentError("Expected `tau_brk` to be positive"))
160+
tau_c > 0 || throw(ArgumentError("Expected `tau_c` to be positive"))
161+
tau_c <= tau_brk || throw(ArgumentError("`tau_brk` to be greater than `tau_c`"))
162+
f >= 0 || throw(ArgumentError("Expected `f` to be not negative"))
163+
pars = @parameters f=f tau_c=tau_c w_brk=w_brk tau_brk=tau_brk
164+
165+
str_scale = sqrt(2*exp(1)) * (tau_brk - tau_c)
166+
w_st = w_brk * sqrt(2)
167+
w_coul = w_brk / 10
168+
169+
eqs = [
170+
tau ~ str_scale * (exp(-(w_rel/w_st)^2) * w_rel / w_st) + tau_c * tanh(w_rel / w_coul) + f * w_rel # Stribeck friction + Coulomb friction + Viscous friction
171+
]
172+
extend(ODESystem(eqs, t, [], pars; name=name), partial_comp)
173+
end
174+
175+
"""
176+
ViscousFriction(;name, f)
177+
178+
Models rotational viscous friction between the two flanges.
179+
The friction torque is a function of the relative angular velocity between flange_a and flange_b.
180+
# States:
181+
- see [`PartialCompliantWithRelativeStates`](@ref)
182+
183+
# Connectors:
184+
- See [`PartialCompliantWithRelativeStates`](@ref)
185+
186+
# Parameters:
187+
- `f`: [`N⋅m/(rad/s)`] Viscous friction coefficient
188+
"""
189+
function ViscousFriction(;name, f)
190+
@named partial_comp = PartialCompliantWithRelativeStates()
191+
@unpack w_rel, tau = partial_comp
192+
f >= 0 || throw(ArgumentError("Expected `f` to be not negative"))
193+
pars = @parameters f=f
194+
195+
eqs = [
196+
tau ~ f * w_rel # Viscous friction
197+
]
198+
extend(ODESystem(eqs, t, [], pars; name=name), partial_comp)
110199
end

0 commit comments

Comments
 (0)