Skip to content

Commit b0487ff

Browse files
Merge pull request #34 from ValentinKaisermayer/add-mechanics
Adds rotational components
2 parents b8d481a + 6d01bbe commit b0487ff

File tree

11 files changed

+445
-4
lines changed

11 files changed

+445
-4
lines changed

docs/src/API/magnetic.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
# ModelingToolkitStandardLibrary: Magnetic Components
22

3-
## Magnetic Utilities
3+
## Flux Tubes
4+
5+
### Flux Tube Utilities
46

57
```@docs
68
PositiveMagneticPort
79
NegativeMagneticPort
810
TwoPort
911
```
1012

11-
## Basic Magnetic Blocks
13+
### Basic Flux Tube Blocks
1214

1315
```@docs
1416
Ground
@@ -21,7 +23,7 @@ EddyCurrent
2123
ElectroMagneticConverter
2224
```
2325

24-
## Magnetic Sources
26+
### Flux Tube Sources
2527

2628
```@docs
2729
ConstantMagneticPotentialDifference

docs/src/API/mechanical.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# ModelingToolkit Standard Library: Mechanical Components
2+
3+
## Rotational Components
4+
5+
### Rotational Utils
6+
7+
```@docs
8+
Flange
9+
```
10+
11+
### Rotational Core Components
12+
13+
```@docs
14+
Fixed
15+
Inertia
16+
Spring
17+
Damper
18+
IdealGear
19+
```
20+
21+
### Rotational Sources
22+
23+
```@docs
24+
Torque
25+
```

docs/src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ The following are the constituant libraries of the ModelingToolkit Standard Libr
2323
- [Basic Blocks](http://mtkstdlib.sciml.ai/dev/API/blocks/)
2424
- [Electrical Components](http://mtkstdlib.sciml.ai/dev/API/electrical/)
2525
- [Magnetic Components](http://mtkstdlib.sciml.ai/dev/API/magnetic/)
26+
- [Mechanical Components](http://mtkstdlib.sciml.ai/dev/API/mechanical/)
2627
- [Thermal Components](http://mtkstdlib.sciml.ai/dev/API/thermal/)

src/Mechanical/Mechanical.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"""
2+
Library of mechanical models.
3+
"""
4+
module Mechanical
5+
6+
using ModelingToolkit
7+
8+
include("Rotational/Rotational.jl")
9+
10+
end
11+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
Library to model 1-dimensional, rotational mechanical systems
3+
"""
4+
module Rotational
5+
6+
using ModelingToolkit, Symbolics, IfElse, OrdinaryDiffEq
7+
using OffsetArrays
8+
using ...Blocks: RealInput, RealOutput
9+
10+
@parameters t
11+
D = Differential(t)
12+
13+
export Flange
14+
include("utils.jl")
15+
16+
export Fixed, Inertia, Spring, Damper, IdealGear
17+
include("components.jl")
18+
19+
export Torque
20+
include("sources.jl")
21+
22+
end
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"""
2+
Fixed(;name, phi0=0.0)
3+
4+
Flange fixed in housing at a given angle.
5+
6+
# Parameters:
7+
- `phi0`: Fixed offset angle of housing
8+
"""
9+
function Fixed(;name, phi0=0.0)
10+
@named flange = Flange()
11+
@parameters phi0=phi0
12+
eqs = [flange.phi ~ phi0]
13+
return compose(ODESystem(eqs, t, [], [phi0]; name=name), flange)
14+
end
15+
16+
"""
17+
Inertia(;name, J=1.0, phi_start=0.0, w_start=0.0, a_start=0.0)
18+
19+
1D-rotational component with inertia.
20+
21+
# Parameters:
22+
- `J`: [kg.m2] Moment of inertia
23+
- `phi_start`: [rad] Initial value of absolute rotation angle of component
24+
- `w_start`: [rad/s] Initial value of absolute angular velocity of component
25+
- `a_start`: [rad/s2] 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/s2] Absolute angular acceleration of component (= der(w))
31+
"""
32+
function Inertia(;name, J=1.0, phi_start=0.0, w_start=0.0, a_start=0.0)
33+
@named flange_a = Flange()
34+
@named flange_b = Flange()
35+
@parameters J=J
36+
sts = @variables begin
37+
phi(t)=phi_start
38+
w(t)=w_start
39+
a(t)=a_start
40+
end
41+
eqs = [
42+
phi ~ flange_a.phi
43+
phi ~ flange_b.phi
44+
D(phi) ~ w
45+
D(w) ~ a
46+
J*a ~ flange_a.tau + flange_b.tau
47+
]
48+
return compose(ODESystem(eqs, t, sts, [J]; name=name), flange_a, flange_b)
49+
end
50+
51+
"""
52+
Spring(;name, c, phi_rel0=0.0)
53+
54+
Linear 1D rotational spring
55+
56+
# Parameters:
57+
- `c`: Spring constant
58+
- `phi_rel0`: Unstretched spring angle
59+
"""
60+
function Spring(;name, c=1.0e5, phi_rel0=0.0)
61+
@named partial_comp = PartialCompliant()
62+
@unpack phi_rel, tau = partial_comp
63+
pars = @parameters begin
64+
c=c
65+
phi_rel0=phi_rel0
66+
end
67+
eqs = [tau ~ c*(phi_rel - phi_rel0)]
68+
extend(ODESystem(eqs, t, [], pars; name=name), partial_comp)
69+
end
70+
71+
"""
72+
Damper(;name, d=0.0)
73+
74+
Linear 1D rotational damper
75+
76+
# Parameters:
77+
- `d`: Damping constant
78+
"""
79+
function Damper(;name, d=0.0)
80+
@named partial_comp = PartialCompliantWithRelativeStates()
81+
@unpack w_rel, tau = partial_comp
82+
pars = @parameters d=d
83+
eqs = [tau ~ d*w_rel]
84+
extend(ODESystem(eqs, t, [], pars; name=name), partial_comp)
85+
end
86+
87+
"""
88+
IdealGear(;name, ratio)
89+
90+
Ideal gear without inertia.
91+
92+
This element characterizes any type of gear box which is fixed in the ground and which has one driving shaft and one driven shaft.
93+
94+
# Parameters:
95+
- `ratio`: Transmission ratio (flange_a.phi/flange_b.phi)
96+
"""
97+
function IdealGear(;name, ratio, use_support=false)
98+
@named partial_element = PartialElementaryTwoFlangesAndSupport2(use_support=use_support)
99+
@unpack phi_support, flange_a, flange_b = partial_element
100+
@parameters ratio=ratio
101+
sts = @variables phi_a(t)=0.0 phi_b(t)=0.0
102+
eqs = [
103+
phi_a ~ flange_a.phi - phi_support
104+
phi_b ~ flange_b.phi - phi_support
105+
phi_a ~ ratio*phi_b
106+
0 ~ ratio*flange_a.tau + flange_b.tau
107+
]
108+
extend(ODESystem(eqs, t, sts, [ratio]; name=name), partial_element)
109+
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
"""
2+
Torque(;name)
3+
4+
Input signal acting as external torque on a flange
5+
"""
6+
function Torque(;name, use_support=false)
7+
@named partial_element = PartialElementaryOneFlangeAndSupport2(use_support=use_support)
8+
@unpack flange = partial_element
9+
@named tau = RealInput() # Accelerating torque acting at flange (= -flange.tau)
10+
eqs = [flange.tau ~ -tau.u]
11+
return extend(ODESystem(eqs, t, [], []; name=name, systems=[tau]), partial_element)
12+
end

src/Mechanical/Rotational/utils.jl

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
@connector function Flange(;name)
2+
sts = @variables begin
3+
phi(t)
4+
tau(t), [connect=Flow]
5+
end
6+
ODESystem(Equation[], t, sts, [], name=name, defaults=Dict(phi=>0.0, tau=>0.0))
7+
end
8+
Base.@doc """
9+
Flange(;name)
10+
11+
1-dim. rotational flange of a shaft.
12+
13+
# States:
14+
- `phi`: [rad] Absolute rotation angle of flange
15+
- `tau`: [Nm] Cut torque in the flange
16+
""" Flange
17+
18+
@connector function Support(;name)
19+
sts = @variables begin
20+
phi(t)
21+
tau(t), [connect=Flow]
22+
end
23+
ODESystem(Equation[], t, sts, [], name=name, defaults=Dict(phi=>0.0, tau=>0.0))
24+
end
25+
Base.@doc """
26+
Support(;name)
27+
28+
Support/housing of a 1-dim. rotational shaft
29+
30+
# States:
31+
- `phi`: [rad] Absolute rotation angle of the support/housing
32+
- `tau`: [Nm] Cut torque in the support/housing
33+
""" Support
34+
35+
"""
36+
PartialCompliant(;name, phi_rel_start=0.0, tau_start=0.0)
37+
38+
Partial model for the compliant connection of two rotational 1-dim. shaft flanges.
39+
40+
# Parameters:
41+
- `phi_rel_start`: Initial relative rotation angle
42+
- `tau_start`: Initial torque between flanges
43+
44+
# States:
45+
- `phi_rel`: Relative rotation angle (= flange_b.phi - flange_a.phi)
46+
- `tau`: Torque between flanges (= flange_b.tau)
47+
"""
48+
function PartialCompliant(;name, phi_rel_start=0.0, tau_start=0.0)
49+
@named flange_a = Flange()
50+
@named flange_b = Flange()
51+
sts = @variables begin
52+
phi_rel(t)=phi_rel_start
53+
tau(t)=tau_start
54+
end
55+
eqs = [
56+
phi_rel ~ flange_b.phi - flange_a.phi
57+
flange_b.tau ~ tau
58+
flange_a.tau ~ -tau
59+
]
60+
return compose(ODESystem(eqs, t, sts, []; name=name), flange_a, flange_b)
61+
end
62+
63+
"""
64+
PartialCompliantWithRelativeStates(;name, phi_rel_start=0.0, tau_start=0.0)
65+
66+
Partial model for the compliant connection of two rotational 1-dim. shaft flanges where the relative angle and speed are used as preferred states
67+
68+
# Parameters:
69+
- `phi_rel_start`: Initial relative rotation angle
70+
- `w_rel_start`: Initial relative angular velocity (= der(phi_rel))
71+
- `a_rel_start`: Initial relative angular acceleration (= der(w_rel))
72+
- `tau_start`: Initial torque between flanges
73+
74+
# States:
75+
- `phi_rel`: Relative rotation angle (= flange_b.phi - flange_a.phi)
76+
- `w_rel`: Relative angular velocity (= der(phi_rel))
77+
- `a_rel`: Relative angular acceleration (= der(w_rel))
78+
- `tau`: Torque between flanges (= flange_b.tau)
79+
"""
80+
function PartialCompliantWithRelativeStates(;name, phi_rel_start=0.0, w_start=0.0, a_start=0.0, tau_start=0.0)
81+
@named flange_a = Flange()
82+
@named flange_b = Flange()
83+
sts = @variables begin
84+
phi_rel(t)=phi_rel_start
85+
w_rel(t)=w_start
86+
a_rel(t)=a_start
87+
tau(t)=tau_start
88+
end
89+
eqs = [
90+
phi_rel ~ flange_b.phi - flange_a.phi
91+
D(phi_rel) ~ w_rel
92+
D(w_rel) ~ a_rel
93+
flange_b.tau ~ tau
94+
flange_a.tau ~ -tau
95+
]
96+
return compose(ODESystem(eqs, t, sts, []; name=name), flange_a, flange_b)
97+
end
98+
99+
"""
100+
PartialElementaryOneFlangeAndSupport2(;name, use_support=false)
101+
102+
Partial model for a component with one rotational 1-dim. shaft flange and a support used for textual modeling, i.e., for elementary models
103+
104+
# Parameters:
105+
- `use_support`: If support flange enabled, otherwise implicitly grounded
106+
107+
# States:
108+
- `phi_support`: Absolute angle of support flange"
109+
"""
110+
function PartialElementaryOneFlangeAndSupport2(;name, use_support=false)
111+
@named flange = Flange()
112+
sys = [flange]
113+
@variables phi_support(t)
114+
if use_support
115+
@named support = Support()
116+
eqs = [
117+
support.phi ~ phi_support
118+
support.tau ~ -flange.tau
119+
]
120+
push!(sys, support)
121+
else
122+
eqs = [phi_support ~ 0]
123+
end
124+
return compose(ODESystem(eqs, t, [phi_support], []; name=name), sys)
125+
end
126+
127+
"""
128+
PartialElementaryTwoFlangesAndSupport2(;name, use_support=false)
129+
130+
Partial model for a component with two rotational 1-dim. shaft flanges and a support used for textual modeling, i.e., for elementary models
131+
132+
# Parameters:
133+
- `use_support`: If support flange enabled, otherwise implicitly grounded
134+
135+
# States:
136+
- `phi_support`: Absolute angle of support flange"
137+
"""
138+
function PartialElementaryTwoFlangesAndSupport2(;name, use_support=false)
139+
@named flange_a = Flange()
140+
@named flange_b = Flange()
141+
sys = [flange_a, flange_b]
142+
@variables phi_support(t)=0.0
143+
if use_support
144+
@named support = Support()
145+
eqs = [
146+
support.phi ~ phi_support
147+
support.tau ~ -flange_a.tau - flange_b.tau
148+
]
149+
push!(sys, support)
150+
else
151+
eqs = [phi_support ~ 0]
152+
end
153+
return compose(ODESystem(eqs, t, [phi_support], []; name=name), sys)
154+
end

src/ModelingToolkitStandardLibrary.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module ModelingToolkitStandardLibrary
22

33
include("Blocks/Blocks.jl")
4+
include("Mechanical/Mechanical.jl")
45
include("Electrical/Electrical.jl")
56
include("Magnetic/Magnetic.jl")
67
include("Thermal/Thermal.jl")

0 commit comments

Comments
 (0)