Skip to content

Commit 4dd5d20

Browse files
Add Spring, Damper components and their test
1 parent 6c0a910 commit 4dd5d20

File tree

4 files changed

+183
-15
lines changed

4 files changed

+183
-15
lines changed

src/Mechanical/PlanarMechanics/PlanarMechanics.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ D = Differential(t)
1616
export Frame, FrameResolve, PartialTwoFrames, ZeroPosition
1717
include("utils.jl")
1818

19-
export Fixed, Body, FixedTranslation, SpringDamper
19+
export Fixed, Body, FixedTranslation, Spring, Damper, SpringDamper
2020
include("components.jl")
2121

2222
export Revolute, Prismatic

src/Mechanical/PlanarMechanics/components.jl

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,140 @@ A fixed translation between two components (rigid rod)
152152
end
153153
end
154154

155+
"""
156+
Spring(; name, c_x = 1, c_y = 1, c_phi = 1e5, s_relx0 = 0, s_rely0 = 0, phi_rel0 = 0, s_small = 1.e-10)
157+
158+
Linear 2D translational spring
159+
160+
# Parameters:
161+
162+
- `c_x`: [N/m] Spring constant in x dir
163+
- `c_y`: [N/m] Spring constant in y dir
164+
- `c_phi`: [N.m/rad] Spring constant in phi dir
165+
- `s_relx0`: [m] Unstretched spring length
166+
- `s_rely0`: [m] Unstretched spring length
167+
- `phi_rel0`: [rad] Unstretched spring angle
168+
- `s_small`: [m] Prevent zero-division if distance between frame_a and frame_b is zero
169+
170+
171+
# Connectors:
172+
173+
- `frame_a` [Frame](@ref) Coordinate system fixed to the component with one cut-force and cut-torque
174+
- `frame_b` [Frame](@ref) Coordinate system fixed to the component with one cut-force and cut-torque
175+
176+
https://github.com/dzimmer/PlanarMechanics/blob/743462f58858a808202be93b708391461cbe2523/PlanarMechanics/Parts/Spring.mo
177+
"""
178+
@mtkmodel Spring begin
179+
@extend frame_a, frame_b = partial_frames = PartialTwoFrames()
180+
181+
@parameters begin
182+
c_x = 1, [description = "Spring constant in x dir"]
183+
c_y = 1, [description = "Spring constant in y dir"]
184+
c_phi = 1.0e5, [description = "Spring constant"]
185+
s_relx0 = 0, [description = "Unstretched spring length"]
186+
s_rely0 = 0, [description = "Unstretched spring length"]
187+
phi_rel0 = 0, [description = "Unstretched spring angle"]
188+
s_small = 1.e-10,
189+
[
190+
description = "Prevent zero-division if distance between frame_a and frame_b is zero",
191+
]
192+
end
193+
194+
@variables begin
195+
s_relx(t) = 0
196+
s_rely(t) = 0
197+
phi_rel(t) = 0
198+
f_x(t)
199+
f_y(t)
200+
end
201+
202+
begin
203+
r_rel_0 = [s_relx, s_rely, 0]
204+
l = sqrt(r_rel_0' * r_rel_0)
205+
e_rel_0 = r_rel_0 / max(l, s_small)
206+
end
207+
208+
@equations begin
209+
phi_rel ~ frame_b.phi - frame_a.phi
210+
frame_a.j ~ 0
211+
frame_b.j ~ 0
212+
s_relx ~ frame_b.x - frame_a.x
213+
s_rely ~ frame_b.y - frame_a.y
214+
f_x ~ c_x * (s_relx - s_relx0)
215+
f_y ~ c_y * (s_rely - s_rely0)
216+
frame_a.fx ~ -f_x
217+
frame_b.fx ~ f_x
218+
frame_a.fy ~ -f_y
219+
frame_b.fy ~ f_y
220+
end
221+
end
222+
223+
"""
224+
Damper(; name, d = 1, s_smal = 1.e-10)
225+
226+
Linear (velocity dependent) damper
227+
228+
# Parameters:
229+
230+
- `d`: [N.s/m] Damoing constant
231+
- `s_small`: [m] Prevent zero-division if distance between frame_a and frame_b is zero
232+
233+
234+
# Connectors:
235+
236+
- `frame_a` [Frame](@ref) Coordinate system fixed to the component with one cut-force and cut-torque
237+
- `frame_b` [Frame](@ref) Coordinate system fixed to the component with one cut-force and cut-torque
238+
239+
240+
https://github.com/dzimmer/PlanarMechanics/blob/743462f58858a808202be93b708391461cbe2523/PlanarMechanics/Parts/Damper.mo
241+
"""
242+
@mtkmodel Damper begin
243+
@extend frame_a, frame_b = partial_frames = PartialTwoFrames()
244+
245+
@parameters begin
246+
d = 1, [description = "damping constant"]
247+
s_small = 1.e-10,
248+
[
249+
description = "Prevent zero-division if distance between frame_a and frame_b is zero",
250+
]
251+
end
252+
253+
@variables begin
254+
r0x(t) = 0
255+
r0y(t) = 0
256+
d0x(t) = 0
257+
d0y(t) = 0
258+
vx(t) = 0
259+
vy(t) = 0
260+
v(t)
261+
f(t)
262+
end
263+
264+
begin
265+
r0 = [r0x, r0y]
266+
l = sqrt(r0' * r0)
267+
end
268+
269+
@equations begin
270+
frame_a.x + r0x ~ frame_b.x
271+
frame_a.y + r0y ~ frame_b.y
272+
D(frame_a.x) + vx ~ D(frame_b.x)
273+
D(frame_a.y) + vy ~ D(frame_b.y)
274+
v ~ [vx, vy]' * [d0x, d0y]
275+
f ~ -d * v
276+
d0x ~ ifelse(l < s_small, r0[1], r0[1] / l)
277+
d0y ~ ifelse(l < s_small, r0[2], r0[2] / l)
278+
frame_a.fx ~ d0x * f
279+
frame_a.fy ~ d0y * f
280+
frame_a.j ~ 0
281+
frame_a.fx + frame_b.fx ~ 0
282+
frame_a.fy + frame_b.fy ~ 0
283+
frame_a.j + frame_b.j ~ 0
284+
285+
# lossPower ~ -f * v
286+
end
287+
end
288+
155289
"""
156290
SpringDamper(; name, c_x = 1, c_y = 1, c_phi = 1e5, d_x = 1, d_y = 1, d_phi = 1, s_relx0 = 0, s_rely0 = 0, phi_rel0 = 0, s_small = 1.e-10)
157291

src/Mechanical/PlanarMechanics/joints.jl

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ A revolute joint
2222
2323
"""
2424
@component function Revolute(;
25-
name,
26-
constant_phi = nothing,
27-
constant_ω = nothing,
28-
constat_tau = nothing,
29-
use_flange = false)
25+
name,
26+
constant_phi = nothing,
27+
constant_ω = nothing,
28+
constat_tau = nothing,
29+
use_flange = false)
3030
@named partial_frames = PartialTwoFrames()
3131
@unpack frame_a, frame_b = partial_frames
3232
@named fixed = Rotational.Fixed()
@@ -98,12 +98,12 @@ A prismatic joint
9898
- `support` [Support](@ref) if `use_flange == true`
9999
"""
100100
@component function Prismatic(;
101-
name,
102-
x,
103-
y,
104-
constant_f = 0,
105-
constant_s = 0,
106-
use_flange = false)
101+
name,
102+
x,
103+
y,
104+
constant_f = 0,
105+
constant_s = 0,
106+
use_flange = false)
107107
@named partial_frames = PartialTwoFrames()
108108
@unpack frame_a, frame_b = partial_frames
109109
@named fixed = TranslationalModelica.Support()
@@ -129,7 +129,7 @@ A prismatic joint
129129
r0 = e0 * s
130130

131131
eqs = [
132-
ifelse(constant_s === nothing, s ~ s, s ~ constant_s),
132+
# ifelse(constant_s === nothing, s ~ s, s ~ constant_s),
133133
ifelse(constant_f === nothing, f ~ f, f ~ constant_f),
134134
v ~ D(s),
135135
a ~ D(v),

test/Mechanical/planar_mechanics.jl

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using ModelingToolkit, OrdinaryDiffEq, Test
22
using ModelingToolkitStandardLibrary.Mechanical.PlanarMechanics
3-
# using Plots
43

54
@parameters t
65
D = Differential(t)
@@ -243,4 +242,39 @@ end
243242
prob = ODEProblem(sys, unset_vars .=> 0.0, (0, 5), []; jac = true)
244243
sol = solve(prob, Rodas5P())
245244
@test SciMLBase.successful_retcode(sol)
246-
end
245+
end
246+
247+
@testset "Spring and damper demo" begin
248+
# https://github.com/dzimmer/PlanarMechanics/blob/743462f58858a808202be93b708391461cbe2523/PlanarMechanics/Examples/SpringDemo.mo
249+
@named body = Body(; m = 0.5, j = 0.1)
250+
@named fixed = Fixed()
251+
@named spring = Spring(; c_y = 10, s_rely0 = -0.5, c_x = 1, c_phi = 1e5)
252+
@named damper = Damper(d = 1)
253+
@named prismatic = Prismatic(; x = 0, y = 1)
254+
255+
connections = [
256+
connect(fixed.frame, spring.frame_a),
257+
connect(spring.frame_b, body.frame),
258+
connect(damper.frame_a, spring.frame_a),
259+
connect(damper.frame_b, spring.frame_b),
260+
connect(spring.frame_a, prismatic.frame_a),
261+
connect(prismatic.frame_b, spring.frame_b),
262+
]
263+
264+
@named model = ODESystem(connections,
265+
t,
266+
[],
267+
[],
268+
systems = [
269+
body,
270+
fixed,
271+
spring,
272+
damper,
273+
prismatic,
274+
])
275+
sys = structural_simplify(model)
276+
unset_vars = setdiff(states(sys), keys(ModelingToolkit.defaults(sys)))
277+
prob = ODEProblem(sys, unset_vars .=> 0.0, (0, 5), []; jac = true)
278+
sol = solve(prob, Rodas5P())
279+
@test SciMLBase.successful_retcode(sol)
280+
end

0 commit comments

Comments
 (0)