Skip to content

Commit c0b3795

Browse files
Merge pull request #102 from ModiaSim/an_allocCollision
An alloc collision
2 parents fbd9a9d + 4e1ea40 commit c0b3795

File tree

9 files changed

+105
-59
lines changed

9 files changed

+105
-59
lines changed

src/Composition/dynamicCollision.jl

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
# (see file ...\ContactDetectionMPR\handler.jl)
66
# after computing all distances between colliding shapes response calculations are done
77
function computeContactForcesAndTorques(sim::Modia.SimulationModel, scene, world, time, file)
8-
ch = scene.options.contactDetection
9-
# Compute signed distances of all contact shapes during zero-crossing computation
10-
#try
8+
if typeof(scene.options.contactDetection) <: Modia3D.ContactDetectionMPR_handler
9+
ch::Modia3D.ContactDetectionMPR_handler = scene.options.contactDetection
10+
# Compute signed distances of all contact shapes during zero-crossing computation
11+
#try
1112
setComputationFlag(ch)
1213
if Modia.isEvent(sim) # with Event
1314
# handle event
@@ -20,9 +21,14 @@ function computeContactForcesAndTorques(sim::Modia.SimulationModel, scene, world
2021
TimerOutputs.@timeit sim.timer "Modia3D_1 getDistances!" getDistances!(scene, ch, world)
2122
end
2223
TimerOutputs.@timeit sim.timer "Modia3D_1 dealWithContacts!" dealWithContacts!(sim, scene, ch, world, time, file)
24+
# dealWithContacts!(sim, scene, ch, world, time, file)
2325
#catch e
2426
#println("Bug in Modia3D/src/Composition/dynamicCollision.jl: error curing collision detection at time = ", time)
2527
#end
28+
else
29+
error("No contact detection handler is defined")
30+
end
31+
return nothing
2632
end
2733

2834
# each shape pair in contact is stored in ch.contactDict
@@ -33,27 +39,53 @@ end
3339
# (see file ...\Composition\responseCalculation\elasticCollisionResponse.jl)
3440
# further, at an event simulation status is updated, contact material is replaced
3541
# and the actual contactDict is stored
36-
function dealWithContacts!(sim, scene::Scene{F}, ch, world, time, file) where F <: Modia3D.VarFloatType
37-
simh = sim.eventHandler
42+
function dealWithContacts!(sim::Modia.SimulationModel{F, T}, scene::Scene{F}, ch::Composition.ContactDetectionMPR_handler{M,F}, world::Composition.Object3D{F}, time::Float64, file::Nothing)::Nothing where {F <: Modia3D.VarFloatType, T, M}
43+
44+
simh::Modia.EventHandler{F,T} = sim.eventHandler
3845
f1::SVector{3,F}=Modia3D.ZeroVector3D(F)
3946
f2::SVector{3,F}=Modia3D.ZeroVector3D(F)
4047
t1::SVector{3,F}=Modia3D.ZeroVector3D(F)
4148
t2::SVector{3,F}=Modia3D.ZeroVector3D(F)
4249

43-
for (pairID, pair) in ch.contactDict
50+
for (pairID::Int64, pair::ContactPair{F}) in ch.contactDict
4451
obj1 = pair.obj1
45-
obj2 = pair.obj2
46-
rContact = (pair.contactPoint1 + pair.contactPoint2)/F(2.0)
52+
obj2= pair.obj2
53+
rContact= (pair.contactPoint1 + pair.contactPoint2)/F(2.0)
4754
contactNormal = pair.contactNormal
4855
if Modia.isEvent(sim)
4956
# println("$(sim.time): ", obj1.path, " ", obj2.path)
5057
getMaterialContactStart(scene, ch, simh, pair, pairID, obj1, obj2, rContact, contactNormal)
5158
visualizeContactAndSupportPoints(ch, world)
5259
end
5360
if scene.options.enableContactDetection
54-
(f1,f2,t1,t2) = responseCalculation(pair.contactPairMaterial, obj1, obj2,
61+
if pair.pairKind == Modia3D.NoContactPairKind
62+
noContactPairMaterial::Shapes.NoContactPairMaterial = pair.contactPairMaterial
63+
(f1,f2,t1,t2) = responseCalculation(noContactPairMaterial, obj1, obj2,
5564
rContact, contactNormal,
5665
pair.distanceWithHysteresis, time, file, sim)
66+
elseif pair.pairKind == Modia3D.ElasticContactPairKind
67+
elasticContactPairMaterial::Composition.ElasticContactPairResponseMaterial = pair.contactPairMaterial
68+
(f1,f2,t1,t2) = responseCalculation(elasticContactPairMaterial, obj1, obj2,
69+
rContact, contactNormal,
70+
pair.distanceWithHysteresis, time, file, sim)
71+
elseif pair.pairKind == Modia3D.ObserverContactPairKind
72+
observerContactPairMaterial::Shapes.ObserverContactPairMaterial = pair.contactPairMaterial
73+
(f1,f2,t1,t2) = responseCalculation(observerContactPairMaterial, obj1, obj2,
74+
rContact, contactNormal,
75+
pair.distanceWithHysteresis, time, file, sim)
76+
elseif pair.pairKind == Modia3D.ImpulseContactPairKind
77+
impulseContactPairMaterial::Shapes.ImpulseContactPairMaterial = pair.contactPairMaterial
78+
(f1,f2,t1,t2) = responseCalculation(impulseContactPairMaterial, obj1, obj2,
79+
rContact, contactNormal,
80+
pair.distanceWithHysteresis, time, file, sim)
81+
elseif pair.pairKind == Modia3D.WheelRailContactPairKind
82+
wheelRailContactPairMaterial::Shapes.WheelRailContactPairMaterial = pair.contactPairMaterial
83+
(f1,f2,t1,t2) = responseCalculation(wheelRailContactPairMaterial, obj1, obj2,
84+
rContact, contactNormal,
85+
pair.distanceWithHysteresis, time, file, sim)
86+
else
87+
error("not supported contact pair material")
88+
end
5789

5890
# Transform forces/torques in local part frames
5991
obj1.f += obj1.R_abs*f1
@@ -70,7 +102,6 @@ function dealWithContacts!(sim, scene::Scene{F}, ch, world, time, file) where F
70102
end
71103

72104

73-
74105
# mainly its for assigning contact materials.
75106
# therefore, lastContactDict stores information of shape pairs in contact at last step
76107
# if the actual shape pair was in contact at the last step as well, the already assigned contact material is taken
@@ -79,12 +110,13 @@ function getMaterialContactStart(scene, ch, simh, pair, pairID, obj1, obj2, rCon
79110
if haskey(ch.lastContactDict, pairID)
80111
# use material (reference) from previous event
81112
if scene.options.enableContactDetection
82-
pair.contactPairMaterial = ch.lastContactDict[pairID].contactPairMaterial # improve later (should avoid to inquire pairID twice)
113+
pair.contactPairMaterial = ch.lastContactDict[pairID].contactPairMaterial # improve later (should avoid to inquire pairID twice)
114+
pair.pairKind = ch.lastContactDict[pairID].pairKind
83115
end
84116
else
85117
# determine contact pair material
86118
if scene.options.enableContactDetection
87-
pair.contactPairMaterial = contactStart(obj1, obj2, rContact, contactNormal,
119+
(pair.contactPairMaterial, pair.pairKind) = contactStart(obj1, obj2, rContact, contactNormal,
88120
scene.options.elasticContactReductionFactor,
89121
scene.options.maximumContactDamping)
90122
end

src/Composition/massPropertiesComputation.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ end
4444
# It sums up common mass, inertia tensor and center of mass.
4545
# The results are stored twice in actual root of super object:
4646
# massProperties: container for actual values
47-
function addMassPropertiesOfAllSuperObjChildsToRootSuperObj!(rootSuperObj::Object3D, actualMassSuperObject::Vector{Object3D{F}}) where F <: Modia3D.VarFloatType
47+
function addMassPropertiesOfAllSuperObjChildsToRootSuperObj!(rootSuperObj::Object3D{F}, actualMassSuperObject::Vector{Object3D{F}}) where F <: Modia3D.VarFloatType
4848
if length(actualMassSuperObject) > 0
4949
for i=1:length(actualMassSuperObject)
5050
obj = actualMassSuperObject[i]
@@ -74,7 +74,8 @@ end
7474

7575
# function computeInertiaTensorForTwoBodies!(massPropParent, massPropObj, obj; add=true)
7676
function addOrSubtractMassPropertiesOfChildToRoot!(obj_root::Object3D{F}, obj_child::Object3D{F}; add=true)::Nothing where F <: Modia3D.VarFloatType
77-
massProperties_child = obj_child.feature.massProperties
77+
solid::Shapes.Solid{F} = obj_child.feature
78+
massProperties_child::Shapes.MassProperties{F} = solid.massProperties
7879

7980
R_child = obj_child.R_rel
8081
r_child = obj_child.r_rel
@@ -94,7 +95,7 @@ function addOrSubtractMassPropertiesOfChildToRoot!(obj_root::Object3D{F}, obj_ch
9495
# (no need of rotation matrices)
9596
I_child_steiner = Modia3D.NullRotation(F) * I_child * Modia3D.NullRotation(F)' +
9697
m_child * Modia3D.skew(rCM_child_new)' * Modia3D.skew(rCM_child_new)
97-
I_root_steiner = I_root +
98+
I_root_steiner = I_root +
9899
m_root * Modia3D.skew(rCM_root)' * Modia3D.skew(rCM_root)
99100

100101
if add
@@ -108,13 +109,12 @@ function addOrSubtractMassPropertiesOfChildToRoot!(obj_root::Object3D{F}, obj_ch
108109

109110
# I: substract new common mass multiplied with skew matrices of
110111
# center of mass from the sum of I_root_steiner and I_child_steiner
111-
I = I_root_steiner + I_child_steiner - m * Modia3D.skew(rCM)' * Modia3D.skew(rCM)
112+
I =I_root_steiner + I_child_steiner - m * Modia3D.skew(rCM)' * Modia3D.skew(rCM)
112113

113114
# Assign to obj_root
114115
obj_root.m = m
115116
obj_root.r_CM = rCM
116117
obj_root.I_CM = I
117-
return nothing
118118

119119
#= # other way to compute inertia tensor
120120
a1 = rCM_new - rCM_child_new
@@ -143,5 +143,6 @@ function addOrSubtractMassPropertiesOfChildToRoot!(obj_root::Object3D{F}, obj_ch
143143
obj_root.m = m
144144
obj_root.r_CM = rCM
145145
obj_root.I_CM = I
146-
return nothing
147-
end; end
146+
end
147+
return nothing
148+
end

src/Composition/responseCalculation/elasticCollisionResponse.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,22 @@ function resultantDampingCoefficient(cor, abs_vreln, vsmall, maximumContactDampi
3636
return d_res
3737
end
3838

39-
function elasticContactPairCoefficients(obj1::Object3D, obj2::Object3D)
40-
solid1::Shapes.Solid = obj1.feature
41-
solid2::Shapes.Solid = obj2.feature
42-
39+
function elasticContactPairCoefficients(obj1::Object3D{F}, obj2::Object3D{F}) where F <: Modia3D.VarFloatType
40+
solid1::Shapes.Solid{F} = obj1.feature
41+
solid2::Shapes.Solid{F} = obj2.feature
42+
mu_r_geo = F(0.0)
4343
if !solid1.isFlat && solid2.isFlat
4444
mu_r_geo = solid1.contactSphereRadius
4545
elseif solid1.isFlat && !solid2.isFlat
4646
mu_r_geo = solid2.contactSphereRadius
4747
else # (solid1.isFlat && solid2.isFlat) || (!solid1.isFlat && !solid2.isFlat)
48-
r1 = solid1.contactSphereRadius
49-
r2 = solid2.contactSphereRadius
48+
r1::F = solid1.contactSphereRadius
49+
r2::F = solid2.contactSphereRadius
5050
mu_r_geo = r1*r2/(r1 + r2)
5151
end
5252

53-
n_geo = 1.5
54-
c_geo = 4/3*sqrt(mu_r_geo)
53+
n_geo = F(1.5)
54+
c_geo = F(4/3*sqrt(mu_r_geo))
5555

5656
return (c_geo, n_geo, mu_r_geo)
5757
end
@@ -105,7 +105,7 @@ function contactStart(matPair::Shapes.ElasticContactPairMaterial,
105105
matPair.rotationalResistanceCoefficient, mu_r_geo,
106106
matPair.vsmall, matPair.wsmall)
107107
end
108-
return responseMaterial
108+
return (responseMaterial, Shapes.ElasticContactPairKind)
109109
end
110110

111111

src/Composition/responseCalculation/othersCollisionResponse.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
contactStart(matPair::Shapes.NoContactPairMaterial, obj1::Object3D{F}, obj2::Object3D{F}, rContact::SVector{3,F}, contactNormal::SVector{3,F}, elasticContactReductionFactor::F, maximumContactDamping::F) where F <: Modia3D.VarFloatType =
2-
matPair
2+
(matPair, Shapes.NoContactPairKind)
33

4-
contactStart(matPair::Shapes.ObserverContactPairMaterial, obj1::Object3D{F}, obj2::Object3D{F}, rContact::SVector{3,F}, contactNormal::SVector{3,F}, elasticContactReductionFactor::F, maximumContactDamping::F) where F <: Modia3D.VarFloatType = matPair
4+
contactStart(matPair::Shapes.ObserverContactPairMaterial, obj1::Object3D{F}, obj2::Object3D{F}, rContact::SVector{3,F}, contactNormal::SVector{3,F}, elasticContactReductionFactor::F, maximumContactDamping::F) where F <: Modia3D.VarFloatType = (matPair, Shapes.ObserverContactPairKind)
55

66

77
contactStart(matPair::Shapes.ImpulseContactPairMaterial, obj1::Object3D{F}, obj2::Object3D{F}, rContact::SVector{3,F}, contactNormal::SVector{3,F}, elasticContactReductionFactor::F, maximumContactDamping::F) where F <: Modia3D.VarFloatType =

src/Composition/scene.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ struct SceneOptions{F <: Modia3D.VarFloatType}
202202

203203
### Contact detection ###
204204
enableContactDetection::Bool # = true, if contact detection is enabled
205-
contactDetection::Modia3D.AbstractContactDetection
205+
contactDetection::ContactDetectionMPR_handler{Modia3D.MPRFloatType, F}
206206
elasticContactReductionFactor::F # c_res_used = c_res * elasticContactReductionFactor (> 0)
207207
maximumContactDamping::F
208208
gap::Float64

src/Shapes/_module.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ export ShapeKind, UndefinedShapeKind, SphereKind, EllipsoidKind, BoxKind, Cylind
6666

6767
@enum ShapeKind UndefinedShapeKind SphereKind EllipsoidKind BoxKind CylinderKind ConeKind CapsuleKind BeamKind FileMeshKind CoordinateSystemKind GridKind SpringKind GearWheelKind ModelicaKind TextKind
6868

69+
export PairMaterialKind, ElasticContactPairKind, NoContactPairKind, ObserverContactPairKind, ImpulseContactPairKind, WheelRailContactPairKind
70+
71+
@enum PairMaterialKind ElasticContactPairKind NoContactPairKind ObserverContactPairKind ImpulseContactPairKind WheelRailContactPairKind
72+
6973
include("color.jl")
7074
include("visualMaterial.jl")
7175
include("text.jl")

src/contactDetection/ContactDetectionMPR/ContactDetectionMPR_handler.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ mutable struct ContactPair{F <: Modia3D.VarFloatType}
3636
support2B::SVector{3,F}
3737
support3B::SVector{3,F}
3838

39+
pairKind::Shapes.PairMaterialKind
3940
contactPairMaterial::Union{Modia3D.AbstractContactPairMaterial,Nothing} # only if contact = true, otherwise not defined
4041

4142
ContactPair{F}(contactPoint1::SVector{3,F}, contactPoint2::SVector{3,F},

src/contactDetection/ContactDetectionMPR/handler.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,22 @@ AABB_touching(aabb1::Basics.BoundingBox, aabb2::Basics.BoundingBox) = aabb1.x_ma
1010

1111

1212

13-
function Composition.initializeContactDetection!(world::Composition.Object3D, scene::Composition.Scene)::Nothing
13+
function Composition.initializeContactDetection!(world::Composition.Object3D{F}, scene::Composition.Scene{F})::Nothing where F <: Modia3D.VarFloatType
1414
if typeof(scene.options.contactDetection) <: Modia3D.ContactDetectionMPR_handler
15-
ch = scene.options.contactDetection
15+
ch::Modia3D.ContactDetectionMPR_handler = scene.options.contactDetection
1616
ch.contactPairs = Composition.ContactPairs(world, scene, ch.visualizeContactPoints,
1717
ch.visualizeSupportPoints, ch.defaultContactSphereDiameter)
1818
if ch.contactPairs.nz == 0
1919
Composition.closeContactDetection!(ch)
2020
scene.collide = false
2121
@warn "... From Modia3D collision handler: Collision handling switched off, since no contacts can take place (nz=0).\n" *
2222
"... You might need to set canCollide=true at joints.\n"
23-
return
23+
return nothing
2424
end
2525
@assert(ch.contactPairs.ne > 0)
2626
@assert(ch.contactPairs.nz > 0)
2727
end
28+
return nothing
2829
end
2930

3031

src/contactDetection/ContactDetectionMPR/utilitiesPairID.jl

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,35 @@
22
# Copyright 2017-2018, DLR Institute of System Dynamics and Control
33

44

5-
const i16max = Int64(typemax(Int16))
6-
const i32max = Int64(typemax(Int32))
5+
i16max()::Int64 = Int64(typemax(Int16))
6+
i32max()::Int64 = Int64(typemax(Int32))
77

8-
pack16(i1::Integer, i2::Integer)::Integer = Int64(i1) + i16max*Int64(i2)
8+
pack16(i1::Int64, i2::Int64)::Int64 = Int64(i1) + i16max()*Int64(i2)
99

10-
function pack(i1::Integer, i2::Integer,i3::Integer,i4::Integer)::Integer
10+
function pack(i1::Int64, i2::Int64,i3::Int64,i4::Int64)::Int64
1111
@assert(i1 >= 0 && i1 <= typemax(Int16))
1212
@assert(i2 >= 0 && i2 <= typemax(Int16))
1313
@assert(i3 >= 0 && i3 <= typemax(Int16))
1414
@assert(i4 >= 0 && i4 <= typemax(Int16))
15-
return pack16(i1,i2) + i32max*pack16(i3,i4)
15+
return pack16(i1,i2) + i32max()*pack16(i3,i4)
1616
end
1717

1818

19-
function unpack16(i::Int64)
20-
i1 = rem(i,i16max)
21-
i2 = div(i-i1, i16max)
19+
function unpack16(i::Int64)::Tuple{Int64, Int64}
20+
i1 = rem(i,i16max())
21+
i2 = div(i-i1, i16max())
2222
return (i1,i2)
2323
end
2424

2525

26-
function unpack32(i::Int64)
27-
i1 = rem(i,i32max)
28-
i2 = div(i-i1, i32max)
26+
function unpack32(i::Int64)::Tuple{Int64, Int64}
27+
i1 = rem(i,i32max())
28+
i2 = div(i-i1, i32max())
2929
return (i1,i2)
3030
end
3131

3232

33-
function unpack(i::Int64)
33+
function unpack(i::Int64)::Tuple{Int64, Int64, Int64, Int64}
3434
@assert(i >= 0 && i <= typemax(Int64))
3535
(tmp1,tmp2) = unpack32(i)
3636
(i1,i2) = unpack16(tmp1)
@@ -41,14 +41,17 @@ end
4141

4242
### -------------------computation of pairID -----------------------------------
4343
### it returns a unique ID
44-
function orderPositions(is,i,js,j)::Integer
44+
function orderPositions(is::Int64, i::Int64, js::Int64, j::Int64)::Int64
45+
p = 0
4546
if is < js
46-
return pack(is,i,js,j)
47+
p = pack(is,i,js,j)
4748
elseif is > js
48-
return pack(js,j,is,i)
49+
p = pack(js,j,is,i)
4950
else
5051
error("from orderPositions: is == js.")
51-
end; end
52+
end
53+
return p
54+
end
5255

5356
#getPositionsOfObj(scene::Composition.Scene, obj::Composition.Object3D,
5457
# movablePos::Nothing) = (false, 0, 0)
@@ -57,25 +60,29 @@ function getPositionsOfObj(scene::Composition.Scene,
5760
if movablePos == 0
5861
return (false, 0, 0)
5962
else
60-
return (true, movablePos, findall(x->x==obj, scene.superObjs[movablePos].superObjMovable.superObj)[1] )
63+
# findall(x->x==obj, scene.superObjs[movablePos].superObjMovable.superObj)[1] # needs to be improved
64+
return (true, movablePos, 0 )
6165
end
6266
end
6367

64-
function computePairID(scene::Composition.Scene,
65-
actObj::Composition.Object3D, nextObj::Composition.Object3D,
66-
is, i, js, j)::Integer
68+
function computePairID(scene::Composition.Scene{F},
69+
actObj::Composition.Object3D{F}, nextObj::Composition.Object3D{F},
70+
is::Int64, i::Int64, js::Int64, j::Int64)::Int64 where F
6771
# is: actual super - object
6872
# js: subsequent super - object
6973
# i: Object3D of is_th super - object
7074
# j: Object3D of js_th super - object
7175
(isSetAct, isPosActSuper, iPosActObj) = getPositionsOfObj(scene, actObj, actObj.interactionManner.movablePos)
7276
(isSetNext, jsPosNextSuper, jPosNextObj) = getPositionsOfObj(scene, nextObj, nextObj.interactionManner.movablePos)
77+
pairID = 0
7378
if isSetAct && isSetNext
74-
return orderPositions(isPosActSuper,iPosActObj,jsPosNextSuper,jPosNextObj)
79+
pairID = orderPositions(isPosActSuper,iPosActObj,jsPosNextSuper,jPosNextObj)
7580
elseif isSetAct && !isSetNext
76-
return orderPositions(isPosActSuper,iPosActObj,js,j)
81+
pairID = orderPositions(isPosActSuper,iPosActObj,js,j)
7782
elseif isSetNext && !isSetAct
78-
return orderPositions(is,i,jsPosNextSuper,jPosNextObj)
83+
pairID = orderPositions(is,i,jsPosNextSuper,jPosNextObj)
7984
else
80-
return orderPositions(is,i,js,j)
81-
end; end
85+
pairID = orderPositions(is,i,js,j)
86+
end
87+
return pairID
88+
end

0 commit comments

Comments
 (0)