Skip to content

Commit d5fa3ea

Browse files
Improve force element implementation
- Replace frames type AbstractObject3D -> Object3D. - Use variable type arguments for force laws of SpringDamperPtP. - Update test models.
1 parent 2e29515 commit d5fa3ea

File tree

4 files changed

+60
-57
lines changed

4 files changed

+60
-57
lines changed

src/Composition/ForceElements/Bushing.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ influence the resulting forces.
1313
"""
1414
mutable struct Bushing <: Modia3D.AbstractForceElement
1515

16-
obj1::Modia3D.AbstractObject3D
17-
obj2::Modia3D.AbstractObject3D
16+
obj1::Object3D
17+
obj2::Object3D
1818

1919
nominalForce::SVector{3,Float64}
2020
stiffness::SVector{3,Float64}
2121
damping::SVector{3,Float64}
2222

23-
function Bushing(; obj1::Modia3D.AbstractObject3D,
24-
obj2::Modia3D.AbstractObject3D,
23+
function Bushing(; obj1::Object3D,
24+
obj2::Object3D,
2525
nominalForce::AbstractVector = Modia3D.ZeroVector3D,
2626
stiffness::AbstractVector = Modia3D.ZeroVector3D,
2727
damping::AbstractVector = Modia3D.ZeroVector3D)

src/Composition/ForceElements/SpringDamperPtP.jl

Lines changed: 39 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,58 @@
11

22
"""
33
force = SpringDamperPtP(; obj1, obj2,
4-
nominalLength = 0.0,
5-
nominalForce = 0.0,
6-
stiffness = 0.0,
7-
stiffnessForceFunction = nothing,
8-
damping = 0.0,
9-
dampingForceFunction = nothing )
4+
nominalLength = 0.0,
5+
nominalForce = 0.0,
6+
springForceLaw = 0.0,
7+
damperForceLaw = 0.0 )
108
119
Return a `force` acting as point-to-point parallel spring-damper between
1210
`obj1::`[`Object3D`](@ref) and `obj2::`[`Object3D`](@ref).
1311
1412
# Arguments
1513
16-
- `nominalLength`: Nominal length, i.e. distance between `obj1` and `obj2`
17-
where deflection of stiffness force is zero.
18-
- `nominalForce`: Nominal force, i.e. force that acts when stiffness and
19-
damping forces are zero. Positive values represent tensil forces.
20-
- `stiffness`: Linear stiffness coefficient of spring. Ignored if
21-
`stiffnessForceFunction` is defined.
22-
- `stiffnessForceFunction`: Univariate function which computes the
23-
stiffness force dependent of the stiffness force deflection.
24-
- `damping`: Linear damping coefficient of damper. Ignored if
25-
`dampingForceFunction` is defined.
26-
- `dampingForceFunction`: Univariate function which computes the
27-
damping force dependent of the damper velocity.
14+
- `nominalLength` defines the nominal length, i.e. the distance between
15+
`obj1` and `obj2` where the deflection of the spring is zero.
16+
- `nominalForce` defines the nominal force, i.e. the force that acts when
17+
spring and damper forces are zero. Positive values represent tension.
18+
- `springForceLaw` defines the force law of the spring:
19+
A `Float64` value represents a linear stiffness coefficient.
20+
An univariate `Function` is used to compute the spring force dependent
21+
of its deflection. Positive values represent tension.
22+
- `damperForceLaw` defines the force law of the damper:
23+
A `Float64` value represents a linear damping coefficient.
24+
An univariate `Function` is used to compute the damper force dependent
25+
of its deflection velocity. Positive values represent expansion.
2826
"""
2927
mutable struct SpringDamperPtP <: Modia3D.AbstractForceElement
3028

31-
obj1::Modia3D.AbstractObject3D
32-
obj2::Modia3D.AbstractObject3D
29+
obj1::Object3D
30+
obj2::Object3D
3331

3432
nominalLength::Float64
3533
nominalForce::Float64
34+
springForceFunction::Function
35+
damperForceFunction::Function
3636

37-
stiffness::Float64
38-
stiffnessForceFunction::Union{Function, Nothing}
39-
40-
damping::Float64
41-
dampingForceFunction::Union{Function, Nothing}
42-
43-
function SpringDamperPtP(; obj1::Modia3D.AbstractObject3D,
44-
obj2::Modia3D.AbstractObject3D,
37+
function SpringDamperPtP(; obj1::Object3D,
38+
obj2::Object3D,
4539
nominalLength::Float64 = 0.0,
4640
nominalForce::Float64 = 0.0,
47-
stiffness::Float64 = 0.0,
48-
stiffnessForceFunction::Union{Function, Nothing} = nothing,
49-
damping::Float64 = 0.0,
50-
dampingForceFunction::Union{Function, Nothing} = nothing)
51-
52-
nomLength = Modia3D.convertAndStripUnit(Float64, u"m" , nominalLength)
53-
nomForce = Modia3D.convertAndStripUnit(Float64, u"N" , nominalForce)
54-
stiff = Modia3D.convertAndStripUnit(Float64, u"N/m" , stiffness)
55-
damp = Modia3D.convertAndStripUnit(Float64, u"N*s/m", damping)
56-
57-
return new(obj1, obj2, nomLength, nomForce, stiff, stiffnessForceFunction, damp, dampingForceFunction)
58-
41+
springForceLaw::Union{Float64, Function} = 0.0,
42+
damperForceLaw::Union{Float64, Function} = 0.0 )
43+
44+
nomLength = Modia3D.convertAndStripUnit(Float64, u"m", nominalLength)
45+
nomForce = Modia3D.convertAndStripUnit(Float64, u"N", nominalForce)
46+
if (typeof(springForceLaw) == Float64)
47+
stiffness = Modia3D.convertAndStripUnit(Float64, u"N/m", springForceLaw)
48+
springForceLaw = eval(:(fc(pos) = $stiffness * pos))
49+
end
50+
if (typeof(damperForceLaw) == Float64)
51+
damping = Modia3D.convertAndStripUnit(Float64, u"N*s/m", damperForceLaw)
52+
damperForceLaw = eval(:(fd(vel) = $damping * vel))
53+
end
54+
55+
return new(obj1, obj2, nomLength, nomForce, springForceLaw, damperForceLaw)
5956
end
6057
end
6158

@@ -71,16 +68,8 @@ function evaluateForceElement(force::SpringDamperPtP)
7168
vel = measFrameDistVelocity(force.obj2; frameOrig=force.obj1)
7269

7370
defl = pos - force.nominalLength
74-
if isnothing(force.stiffnessForceFunction)
75-
fc = force.stiffness * defl
76-
else
77-
fc = force.stiffnessForceFunction(defl)
78-
end
79-
if isnothing(force.dampingForceFunction)
80-
fd = force.damping * vel
81-
else
82-
fd = force.dampingForceFunction(vel)
83-
end
71+
fc = force.springForceFunction(defl)
72+
fd = force.damperForceFunction(vel)
8473
f12 = (fc + fd + force.nominalForce) * norm
8574

8675
applyFrameForcePair!(force.obj2, force.obj1, f12; frameCoord=force.obj1)

test/ForceElements/BoxNonLinearSpringDamperPtP.jl

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,20 @@ using ModiaLang
55
import Modia3D
66
using Modia3D.ModiaInterface
77

8+
interpolatedForceLaws = false
89
l0 = 0.1
910
f0 = 5.0
1011
fc(x) = sign(x) * 100.0 * abs(x)^1.2
1112
fd(v) = sign(v) * 2.0 * abs(v)^0.8
13+
if (interpolatedForceLaws)
14+
using Interpolations
15+
xc = -1.0:0.1:1.0
16+
yc = [fc(x) for x in xc]
17+
fc(x) = CubicSplineInterpolation(xc, yc)(x)
18+
xd = -10.0:0.1:10.0
19+
yd = [fd(x) for x in xd]
20+
fd(v) = LinearInterpolation(xd, yd)(v)
21+
end
1222

1323
SpringDamper = Model(
1424
Length = 0.1,
@@ -25,14 +35,18 @@ SpringDamper = Model(
2535
feature=Visual(shape=CoordinateSystem(length=:(Length/2))),
2636
translation=:[Length/2, Length/2, Length/2]),
2737
joint = FreeMotion(obj1=:world, obj2=:box),
28-
force = SpringDamperPtP(obj1=:world, obj2=:boxCornerFrame, nominalLength=l0, nominalForce=f0, stiffnessForceFunction=fc, dampingForceFunction=fd)
38+
force = SpringDamperPtP(obj1=:world, obj2=:boxCornerFrame, nominalLength=l0, nominalForce=f0, springForceLaw=fc, damperForceLaw=fd)
2939
)
3040

3141
springDamper = @instantiateModel(buildModia3D(SpringDamper), aliasReduction=false, unitless=true)
3242

3343
stopTime = 5.0
3444
dtmax = 0.1
35-
requiredFinalStates = [-0.021471022585945587, -0.021471338063312084, -0.22257979374805176, 0.3258966598257503, 0.3258956068893249, 0.007390650203910464, -0.014365742162847027, 0.014364567804398353, 0.00010407183716342378, -0.2720750966146867, 0.27207423475429426, 8.60986118342952e-7]
45+
if (interpolatedForceLaws)
46+
requiredFinalStates = [-0.018609840194419268, -0.018610063010666804, -0.22128548799442815, 0.3091309586280587, 0.3091307182143652, 0.019491580480008697, -0.01289771100508473, 0.012897263597266288, 8.547830805609731e-5, -0.24873244248570697, 0.2487317559006742, 6.865934996471178e-7]
47+
else
48+
requiredFinalStates = [-0.021471022585945587, -0.021471338063312084, -0.22257979374805176, 0.3258966598257503, 0.3258956068893249, 0.007390650203910464, -0.014365742162847027, 0.014364567804398353, 0.00010407183716342378, -0.2720750966146867, 0.27207423475429426, 8.60986118342952e-7]
49+
end
3650
simulate!(springDamper, stopTime=stopTime, dtmax=dtmax, log=true, requiredFinalStates=requiredFinalStates)
3751

3852
@usingModiaPlot

test/ForceElements/BoxSpringDamperPtP.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ SpringDamper = Model(
2222
feature=Visual(shape=CoordinateSystem(length=:(Length/2))),
2323
translation=:[Length/2, Length/2, Length/2]),
2424
joint = FreeMotion(obj1=:world, obj2=:box),
25-
force = SpringDamperPtP(obj1=:world, obj2=:boxCornerFrame, stiffness=:Stiffness, damping=:Damping)
25+
force = SpringDamperPtP(obj1=:world, obj2=:boxCornerFrame, springForceLaw=:Stiffness, damperForceLaw=:Damping)
2626
)
2727

2828
springDamper = @instantiateModel(buildModia3D(SpringDamper), aliasReduction=false, unitless=true)

0 commit comments

Comments
 (0)