Skip to content

Commit 39b9d00

Browse files
adds missing rotational components
1 parent 70ff6ab commit 39b9d00

File tree

7 files changed

+398
-60
lines changed

7 files changed

+398
-60
lines changed

docs/src/API/mechanical.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,22 @@ Inertia
3434
Spring
3535
Damper
3636
IdealGear
37+
RotationalFriction
38+
ViscousFriction
3739
```
3840

3941
### Rotational Sources
4042

4143
```@docs
4244
Torque
45+
Speed
46+
```
47+
48+
### Rotational Sensors
49+
50+
```@docs
51+
AngleSensor
52+
SpeedSensor
53+
TorqueSensor
54+
RelSpeedSensor
4355
```

src/Mechanical/Rotational/Rotational.jl

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

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

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

12-
export Flange
12+
export Flange, Support
1313
include("utils.jl")
1414

15-
export Fixed, Inertia, Spring, Damper, IdealGear
15+
export Fixed, Inertia, Spring, Damper, IdealGear, RotationalFriction
1616
include("components.jl")
1717

18-
export Torque
18+
export Torque, Speed
1919
include("sources.jl")
2020

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

src/Mechanical/Rotational/components.jl

Lines changed: 88 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
44
Flange fixed in housing at a given angle.
55
6+
# Connectors:
7+
- `flange` [Flange](@ref)
8+
69
# Parameters:
7-
- `phi0`: [rad] Fixed offset angle of housing
10+
- `phi0`: [`rad`] Fixed offset angle of housing
811
"""
912
function Fixed(;name, phi0=0.0)
1013
@named flange = Flange()
@@ -18,16 +21,20 @@ end
1821
1922
1D-rotational component with inertia.
2023
21-
# Parameters:
22-
- `J`: [kg·m²] 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/s²] Initial value of absolute angular acceleration of component
26-
2724
# 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))
25+
- `phi`: [`rad`] Absolute rotation angle of component
26+
- `w`: [`rad/s`] Absolute angular velocity of component (= D(phi))
27+
- `a`: [`rad/s²`] Absolute angular acceleration of component (= D(w))
28+
29+
# Connectors:
30+
- `flange_a` [Flange](@ref) Left flange
31+
- `flange_b` [Flange](@ref) Right flange
32+
33+
# Parameters:
34+
- `J`: [`kg·m²`] Moment of inertia
35+
- `phi_start`: [`rad`] Initial value of absolute rotation angle of component
36+
- `w_start`: [`rad/s`] Initial value of absolute angular velocity of component
37+
- `a_start`: [`rad/s²`] Initial value of absolute angular acceleration of component
3138
"""
3239
function Inertia(;name, J, phi_start=0.0, w_start=0.0, a_start=0.0)
3340
@named flange_a = Flange()
@@ -53,9 +60,17 @@ end
5360
5461
Linear 1D rotational spring
5562
63+
# States:
64+
- `phi_rel(t)`: [`rad`] Relative rotation angle (`flange_b.phi - flange_a.phi`)
65+
- `tau(t)`: [`N.m`] Torque between flanges (`flange_b.tau`)
66+
67+
# Connectors:
68+
- `flange_a` [Flange](@ref)
69+
- `flange_b` [Flange](@ref)
70+
5671
# Parameters:
57-
- `c`: [N.m/rad] Spring constant
58-
- `phi_rel0`: Unstretched spring angle
72+
- `c`: [`N.m/rad`] Spring constant
73+
- `phi_rel0`: [`rad`] Unstretched spring angle
5974
"""
6075
function Spring(;name, c, phi_rel0=0.0)
6176
@named partial_comp = PartialCompliant()
@@ -73,8 +88,18 @@ end
7388
7489
Linear 1D rotational damper
7590
91+
# States:
92+
- `phi_rel(t)`: [`rad`] Relative rotation angle (= flange_b.phi - flange_a.phi)
93+
- `w_rel(t)`: [`rad/s`] Relative angular velocity (= D(phi_rel))
94+
- `a_rel(t)`: [`rad/s²`] Relative angular acceleration (= D(w_rel))
95+
- `tau(t)`: [`N.m`] Torque between flanges (= flange_b.tau)
96+
97+
# Connectors:
98+
- `flange_a` [Flange](@ref)
99+
- `flange_b` [Flange](@ref)
100+
76101
# Parameters:
77-
- `d`: [N.m.s/rad] Damping constant
102+
- `d`: [`N.m.s/rad`] Damping constant
78103
"""
79104
function Damper(;name, d)
80105
@named partial_comp = PartialCompliantWithRelativeStates()
@@ -91,6 +116,15 @@ Ideal gear without inertia.
91116
92117
This element characterizes any type of gear box which is fixed in the ground and which has one driving shaft and one driven shaft.
93118
119+
# States:
120+
- `phi_a(t)`: [`rad`] Relative angle between shaft a and the support
121+
- `phi_b(t)`: [`rad`] Relative angle between shaft b and the support
122+
123+
# Connectors:
124+
- `flange_a` [Flange](@ref)
125+
- `flange_b` [Flange](@ref)
126+
- `support` [Support](@ref) if `use_support == true`
127+
94128
# Parameters:
95129
- `ratio`: Transmission ratio (flange_a.phi/flange_b.phi)
96130
- `use_support`: If support flange enabled, otherwise implicitly grounded
@@ -107,4 +141,44 @@ function IdealGear(;name, ratio, use_support=false)
107141
0 ~ ratio*flange_a.tau + flange_b.tau
108142
]
109143
extend(ODESystem(eqs, t, sts, [ratio]; name=name), partial_element)
110-
end
144+
end
145+
146+
147+
"""
148+
RotationalFriction(;name, f, tau_c, w_brk, tau_brk)
149+
150+
Models rotational friction with Stribeck effect, Coulomb friction and viscous friction between the two flanges.
151+
The friction torque is a function of the relative angular velocity between flange_a and flange_b.
152+
153+
Friction model: "Armstrong, B. and C.C. de Wit, Friction Modeling and Compensation, The Control Handbook, CRC Press, 1995."
154+
155+
# States:
156+
- `phi_rel(t)`: [`rad`] Relative rotation angle (= flange_b.phi - flange_a.phi)
157+
- `w_rel(t)`: [`rad/s`] Relative angular velocity (= D(phi_rel))
158+
- `a_rel(t)`: [`rad/s²`] Relative angular acceleration (= D(w_rel))
159+
- `tau(t)`: [`N.m`] Torque between flanges (= flange_b.tau)
160+
161+
# Connectors:
162+
- `flange_a` [Flange](@ref)
163+
- `flange_b` [Flange](@ref)
164+
165+
# Parameters:
166+
- `f`: [`N⋅m/(rad/s)`] Viscous friction coefficient
167+
- `tau_c`: [`N⋅m`] Coulomb friction torque
168+
- `w_brk`: [`rad/s`] Breakaway friction velocity
169+
- `tau_brk`: [`N⋅m`] Breakaway friction torque
170+
"""
171+
function RotationalFriction(;name, f, tau_c, w_brk, tau_brk)
172+
@named partial_comp = PartialCompliantWithRelativeStates()
173+
@unpack w_rel, tau = partial_comp
174+
pars = @parameters f=f tau_c=tau_c w_brk=w_brk tau_brk=tau_brk
175+
176+
str_scale = sqrt(2*exp(1)) * (tau_brk - tau_c)
177+
w_st = w_brk * sqrt(2)
178+
w_coul = w_brk / 10
179+
180+
eqs = [
181+
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
182+
]
183+
extend(ODESystem(eqs, t, [], pars; name=name), partial_comp)
184+
end

src/Mechanical/Rotational/sensors.jl

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
"""
2+
AngleSensor(;name)
3+
4+
Ideal sensor to measure the absolute flange angle
5+
6+
# Connectors:
7+
- `flange`: [Flange](@ref) Flange of shaft from which sensor information shall be measured
8+
- `phi`: [RealOutput](@ref) Absolute angle of flange
9+
"""
10+
function AngleSensor(;name)
11+
@named flange = Flange()
12+
@named phi = RealOutput()
13+
eqs = [
14+
phi.u ~ flange.phi
15+
flange.tau ~ 0
16+
]
17+
return ODESystem(eqs, t, [], []; name=name, systems=[flange, phi])
18+
end
19+
20+
"""
21+
SpeedSensor(;name)
22+
23+
Ideal sensor to measure the absolute flange angular velocity
24+
25+
# Connectors:
26+
- `flange`: [Flange](@ref) Flange of shaft from which sensor information shall be measured
27+
- `w`: [RealOutput](@ref) Absolute angular velocity of flange
28+
"""
29+
function SpeedSensor(;name)
30+
@named flange = Flange()
31+
@named w = RealOutput()
32+
eqs = [
33+
D(flange.phi) ~ w.u
34+
flange.tau ~ 0
35+
]
36+
return ODESystem(eqs, t, [], []; name=name, systems=[flange, w])
37+
end
38+
39+
"""
40+
TorqueSensor(;name)
41+
42+
Ideal sensor to measure the torque between two flanges (`= flange_a.tau`)
43+
44+
# Connectors:
45+
- `flange_a`: [Flange](@ref) Left flange of shaft
46+
- `flange_b`: [Flange](@ref) Left flange of shaft
47+
- `tau`: [RealOutput](@ref) Torque in flange flange_a and flange_b (`tau = flange_a.tau = -flange_b.tau`)
48+
"""
49+
function TorqueSensor(;name)
50+
@named flange_a = Flange()
51+
@named flange_b = Flange()
52+
@named tau = RealOutput()
53+
eqs = [
54+
flange_a.phi ~ flange_b.phi
55+
tau.u ~ flange_a.tau
56+
]
57+
return ODESystem(eqs, t, [], []; name=name, systems=[flange_a, flange_b, tau])
58+
end
59+
60+
"""
61+
RelSpeedSensor(;name)
62+
63+
Ideal sensor to measure the relative angular velocity
64+
65+
# Connectors:
66+
- `flange_a`: [Flange](@ref) Flange of shaft from which sensor information shall be measured
67+
- `flange_b`: [Flange](@ref) Flange of shaft from which sensor information shall be measured
68+
- `w`: [RealOutput](@ref) Absolute angular velocity of flange
69+
"""
70+
function RelSpeedSensor(;name)
71+
@named flange_a = Flange()
72+
@named flange_b = Flange()
73+
@named w_rel = RealOutput()
74+
@variables phi_rel(t)=0.0
75+
eqs = [
76+
0 ~ flange_a.tau + flange_b.tau
77+
phi_rel ~ flange_b.phi - flange_a.phi
78+
D(phi_rel) ~ w_rel.u
79+
0 ~ flange_a.tau
80+
]
81+
return ODESystem(eqs, t, [phi_rel], []; name=name, systems=[flange_a, flange_b, w_rel])
82+
end

src/Mechanical/Rotational/sources.jl

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,61 @@
22
Torque(;name)
33
44
Input signal acting as external torque on a flange
5+
6+
# States:
7+
- `phi_support(t)`: [`rad`] Absolute angle of support flange"
8+
9+
# Connectors:
10+
- `flange` [Flange](@ref)
11+
- `tau` [RealInput](@ref) Accelerating torque acting at flange `-flange.tau`
12+
13+
# Parameters:
14+
- `use_support`
515
"""
616
function Torque(;name, use_support=false)
717
@named partial_element = PartialElementaryOneFlangeAndSupport2(use_support=use_support)
818
@unpack flange = partial_element
9-
@named tau = RealInput() # Accelerating torque acting at flange (= -flange.tau)
19+
@named tau = RealInput()
1020
eqs = [flange.tau ~ -tau.u]
1121
return extend(ODESystem(eqs, t, [], []; name=name, systems=[tau]), partial_element)
22+
end
23+
24+
25+
26+
"""
27+
Speed(; name, use_support=false, exact=false, f_crit=50)
28+
29+
Forced movement of a flange according to a reference angular velocity signal
30+
31+
# States:
32+
- `phi_support(t)`: [`rad`] Absolute angle of support flange"
33+
34+
# Connectors:
35+
- `flange` [Flange](@ref)
36+
- `w_ref` [RealInput](@ref) Reference angular velocity of flange with respect to support as input signal needs to be continuously differential
37+
38+
# Parameters:
39+
- `use_support`: If support flange enabled, otherwise implicitly grounded
40+
- `exact`: true/false exact treatment/filtering the input signal
41+
- `tau_filt`: [`rad/s`] if exact=false, Time constant of low-pass filter to filter input signal
42+
"""
43+
function Speed(;name, use_support=false, exact=false, tau_filt=50)
44+
@named partial_element = PartialElementaryOneFlangeAndSupport2(use_support=use_support)
45+
@unpack flange, phi_support = partial_element
46+
@named w_ref = RealInput()
47+
@variables phi(t)=0.0 w(t)=0.0 a(t)=0.0
48+
eqs = [
49+
phi ~ flange.phi - phi_support
50+
D(phi) ~ w
51+
]
52+
if exact
53+
pars = []
54+
push!(eqs, w ~ w_ref.u)
55+
push!(eqs, a ~ 0)
56+
else
57+
pars = @parameters tau_filt=tau_filt
58+
push!(eqs, D(w) ~ a)
59+
push!(eqs, a ~ (w_ref.u - w) * tau_filt)
60+
end
61+
return extend(ODESystem(eqs, t, [phi, w, a], pars; name=name, systems=[w_ref]), partial_element)
1262
end

0 commit comments

Comments
 (0)