Skip to content

Commit 3a9ff08

Browse files
Add basic force elements Bushing and SpringDamperPtP
- Add force element Bushing and test HarmonicOscillator. - Add force element SpringDamperPtP and test BoxSpringDamperPtP. Force elements do not work for non solid Object3Ds for now because these are not yet considered in the equations of motion. Modia/src/Modia3D_Interface.jl needs to be synchronized with Modia3D/src/ModiaInterface/model3D.jl asap.
1 parent 923fe03 commit 3a9ff08

File tree

8 files changed

+172
-4
lines changed

8 files changed

+172
-4
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
"""
3+
force = Bushing(; obj1, obj2, stiffness, damping)
4+
5+
Return a `force` acting as bushing between `obj1::`[`Object3D`](@ref) and
6+
`obj2::`[`Object3D`](@ref). Vectors `stiffness` and `damping` define the
7+
stiffness resp. damping values in x, y and z direction of `obj1`. The
8+
orientation of `obj2` does no influence the resulting forces.
9+
"""
10+
mutable struct Bushing <: Modia3D.AbstractForceElement
11+
12+
obj1::Modia3D.AbstractObject3D
13+
obj2::Modia3D.AbstractObject3D
14+
15+
stiffness::SVector{3,Float64}
16+
damping::SVector{3,Float64}
17+
18+
function Bushing(; obj1::Modia3D.AbstractObject3D,
19+
obj2::Modia3D.AbstractObject3D,
20+
stiffness::AbstractVector = Modia3D.ZeroVector3D,
21+
damping::AbstractVector = Modia3D.ZeroVector3D)
22+
23+
stiff = Modia3D.convertAndStripUnit(SVector{3,Float64}, u"N/m" , stiffness)
24+
damp = Modia3D.convertAndStripUnit(SVector{3,Float64}, u"N*s/m", damping)
25+
26+
return new(obj1, obj2, stiff, damp)
27+
28+
end
29+
end
30+
31+
32+
function initializeForceElement(force::Bushing)
33+
return nothing
34+
end
35+
36+
function evaluateForceElement(time, force::Bushing)
37+
r12 = measFramePosition(force.obj2; frameOrig=force.obj1, frameCoord=force.obj1)
38+
v12 = measFrameTransVelocity(force.obj2; frameOrig=force.obj1, frameCoord=force.obj1, frameObsrv=force.obj1)
39+
f12 = force.stiffness .* r12 + force.damping .* v12
40+
applyFrameForcePair!(force.obj2, force.obj1, f12; frameCoord=force.obj1)
41+
return nothing
42+
end
43+
44+
function terminateForceElement(force::Bushing)
45+
return nothing
46+
end
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
2+
"""
3+
force = SpringDamperPtP(; obj1, obj2, stiffness, damping)
4+
5+
Return a `force` acting as point-to-point parallel spring-damper between
6+
`obj1::`[`Object3D`](@ref) and `obj2::`[`Object3D`](@ref). Values
7+
`stiffness` and `damping` define the stiffness resp. damping coefficient.
8+
"""
9+
mutable struct SpringDamperPtP <: Modia3D.AbstractForceElement
10+
11+
obj1::Modia3D.AbstractObject3D
12+
obj2::Modia3D.AbstractObject3D
13+
14+
stiffness::Float64
15+
damping::Float64
16+
17+
function SpringDamperPtP(; obj1::Modia3D.AbstractObject3D,
18+
obj2::Modia3D.AbstractObject3D,
19+
stiffness::Float64 = 0.0,
20+
damping::Float64 = 0.0)
21+
22+
stiff = Modia3D.convertAndStripUnit(Float64, u"N/m" , stiffness)
23+
damp = Modia3D.convertAndStripUnit(Float64, u"N*s/m", damping)
24+
25+
return new(obj1, obj2, stiff, damp)
26+
27+
end
28+
end
29+
30+
31+
function initializeForceElement(force::SpringDamperPtP)
32+
return nothing
33+
end
34+
35+
function evaluateForceElement(time, force::SpringDamperPtP)
36+
(pos, norm) = measFrameDistance(force.obj2; frameOrig=force.obj1)
37+
vel = measFrameDistVelocity(force.obj2; frameOrig=force.obj1)
38+
frc = force.stiffness * pos + force.damping * vel
39+
f12 = frc * norm
40+
applyFrameForcePair!(force.obj2, force.obj1, f12; frameCoord=force.obj1)
41+
end
42+
43+
function terminateForceElement(force::SpringDamperPtP)
44+
return nothing
45+
end

src/Composition/_module.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export Revolute, setAngle!, connect
3232
export Prismatic, setDistance!
3333
export FreeMotion
3434

35+
export Bushing, SpringDamperPtP
36+
3537
export multibodyResiduals!, setModiaJointVariables!
3638

3739
export distanceAndAngles, distance, planarRotationAngle
@@ -93,12 +95,15 @@ include("object3D.jl")
9395
include("supportPoints.jl")
9496
include("superObjects.jl")
9597

96-
# Joints must be included before scene, because joint memory is stored in scene
98+
# Joints and Force Elements must be included before scene, because memory is stored in scene
9799
include(joinpath("joints", "FreeMotion.jl"))
98100
include(joinpath("joints", "Fix.jl"))
99101
include(joinpath("joints", "Revolute.jl"))
100102
include(joinpath("joints", "Prismatic.jl"))
101103

104+
include(joinpath("ForceElements", "Bushing.jl"))
105+
include(joinpath("ForceElements", "SpringDamperPtP.jl"))
106+
102107
include("contactPairs.jl")
103108
include(joinpath(Modia3D.path, "src", "contactDetection", "ContactDetectionMPR", "ContactDetectionMPR_handler.jl"))
104109

src/ModiaInterface/_module.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export Fix
1717
export Revolute, RevoluteWithFlange
1818
export Prismatic, PrismaticWithFlange
1919
export J123, J132, J123or132, singularRem, FreeMotion, change_rotSequenceInNextIteration!
20+
export Bushing, SpringDamperPtP
2021

2122
export buildModia3D
2223

src/ModiaInterface/model3D.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ Font( ; kwargs...) = Par(; _constructor = :(Modia3D.Font)
2121
TextShape( ; kwargs...) = Par(; _constructor = :(Modia3D.TextShape) , kwargs...)
2222
ModelicaShape( ; kwargs...) = Par(; _constructor = :(Modia3D.ModelicaShape) , kwargs...)
2323
Fix( ; kwargs...) = Par(; _constructor = :(Modia3D.Fix) , kwargs...)
24+
Bushing( ; kwargs...) = Par(; _constructor = :(Modia3D.Bushing) , kwargs...)
25+
SpringDamperPtP( ; kwargs...) = Par(; _constructor = :(Modia3D.SpringDamperPtP) , kwargs...)
2426

25-
MassPropertiesFromShape() = Par(; _constructor = :(Modia3D.MassPropertiesFromShape))
26-
MassPropertiesFromShapeAndMass(;mass) = Par(; _constructor = :(Modia3D.MassPropertiesFromShapeAndMass), mass = mass)
27+
MassPropertiesFromShape() = Par(; _constructor = :(Modia3D.MassPropertiesFromShape))
28+
MassPropertiesFromShapeAndMass(; mass) = Par(; _constructor = :(Modia3D.MassPropertiesFromShapeAndMass), mass = mass)
2729
UniformGravityField(; kwargs...) = Par(; _constructor = :(Modia3D.UniformGravityField), kwargs...)
2830

29-
3031
RefPath(; kwargs...) = Modia3D.ReferencePath(; kwargs...)
3132

3233
ptpJointSpace(; kwargs...) = Modia3D.ptpJointSpace(; kwargs...)

test/Basic/BoxSpringDamperPtP.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module BoxSpringDamperPtP
2+
3+
using ModiaLang
4+
5+
import Modia3D
6+
using Modia3D.ModiaInterface
7+
8+
SpringDamper = Model(
9+
Length = 0.1,
10+
Mass = 1.0,
11+
Stiffness = 100.0,
12+
Damping = 2.0,
13+
visualMaterial = VisualMaterial(color="IndianRed1", transparency=0.5),
14+
world = Object3D(feature=Scene(gravityField=UniformGravityField(g=9.81, n=[0, 0, -1]), nominalLength=:Length)),
15+
worldFrame = Object3D(parent=:world,
16+
feature=Visual(shape=CoordinateSystem(length=:Length))),
17+
box = Object3D(feature=Solid(shape=Box(lengthX=:Length, lengthY=:Length, lengthZ=:Length),
18+
massProperties=MassProperties(; mass=1.0, Ixx=0.1, Iyy=0.1, Izz=0.1),
19+
visualMaterial=:(visualMaterial))),
20+
joint = FreeMotion(obj1=:world, obj2=:box, r=Var(init=[0.1, 0.2, 0.3])),
21+
force = SpringDamperPtP(obj1=:world, obj2=:box, stiffness=:Stiffness, damping=:Damping)
22+
)
23+
24+
springDamper = @instantiateModel(buildModia3D(SpringDamper), aliasReduction=false, unitless=true)
25+
26+
stopTime = 6.0
27+
dtmax = 0.1
28+
requiredFinalStates = [-0.026549009773552276, -0.05309801954749593, -0.10117097852565102, 0.0144068779028959, 0.028813755813570235, 0.02595802582858583, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
29+
simulate!(springDamper, stopTime=stopTime, dtmax=dtmax, log=true, requiredFinalStates=requiredFinalStates)
30+
31+
@usingModiaPlot
32+
plot(springDamper, ["joint.r", "joint.v"], figure=1)
33+
34+
end

test/Basic/HarmonicOscillator.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module HarmonicOscillator
2+
3+
using ModiaLang
4+
5+
import Modia3D
6+
using Modia3D.ModiaInterface
7+
8+
Oscillator = Model(
9+
Length = 0.1,
10+
Mass = 1.0,
11+
Stiffness = 100.0,
12+
Damping = 2.0,
13+
visualMaterial = VisualMaterial(color="IndianRed1", transparency=0.5),
14+
world = Object3D(feature=Scene(gravityField=UniformGravityField(g=9.81, n=[0, 0, -1]), nominalLength=:Length)),
15+
worldFrame = Object3D(parent=:world,
16+
feature=Visual(shape=CoordinateSystem(length=:Length))),
17+
oscillator = Object3D(feature=Solid(shape=Box(lengthX=:Length, lengthY=:Length, lengthZ=:Length),
18+
massProperties=MassProperties(; mass=1.0, Ixx=0.1, Iyy=0.1, Izz=0.1),
19+
visualMaterial=:(visualMaterial))),
20+
joint = Prismatic(obj1=:world, obj2=:oscillator, axis=3, s=Var(init=0.0), v=Var(init=0.0)),
21+
force = Bushing(obj1=:world, obj2=:oscillator, stiffness=:[0.0, 0.0, Stiffness], damping=:[0.0, 0.0, Damping])
22+
)
23+
24+
oscillator = @instantiateModel(buildModia3D(Oscillator), aliasReduction=false, unitless=true)
25+
26+
stopTime = 5.0
27+
dtmax = 0.1
28+
requiredFinalStates = [0.0032763240987720987, -0.09755848695453585]
29+
simulate!(oscillator, stopTime=stopTime, dtmax=dtmax, log=true, requiredFinalStates=requiredFinalStates)
30+
31+
@usingModiaPlot
32+
plot(oscillator, ["joint.s", "joint.v"], figure=1)
33+
34+
end

test/includeTests.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Test.@testset "Basic" begin
99
include(joinpath("Basic", "PendulumWithParameterizedDamper.jl"))
1010
include(joinpath("Basic", "PendulumWithSpring.jl"))
1111
include(joinpath("Basic", "DoublePendulumWithDampers.jl"))
12+
include(joinpath("Basic", "HarmonicOscillator.jl"))
13+
include(joinpath("Basic", "BoxSpringDamperPtP.jl"))
1214
include(joinpath("Basic", "BoxPlanarMotion.jl"))
1315
include(joinpath("Basic", "ShaftFreeMotion.jl"))
1416
include(joinpath("Basic", "ShaftFreeMotionAdaptiveRotSequence.jl"))

0 commit comments

Comments
 (0)