Skip to content

Commit 63443e8

Browse files
Merge pull request #38 from ModiaSim/an_checkValidCollisionPairing
check of valid collision pairings is done at initialization
2 parents ed9fe75 + a0e51f4 commit 63443e8

File tree

5 files changed

+114
-10
lines changed

5 files changed

+114
-10
lines changed

src/Composition/contactPairs.jl

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,45 @@ mutable struct ContactPairs
1919
nz::Int # length(z)
2020
nzContact::Int # length(z | z has contact) length of z where zi has contact
2121

22-
function ContactPairs(world::Composition.Object3D, AABB::Vector{Vector{Basics.BoundingBox}}, superObjs::Vector{SuperObjsRow},
23-
allowedToMove::Vector{Union{Bool,Nothing}}, visualizeBoundingBox::Bool, nVisualContSupPoints::Int,
22+
function ContactPairs(world::Composition.Object3D, scene,
2423
visualizeContactPoints::Bool, visualizeSupportPoints::Bool, defaultContactSphereDiameter::Float64)
24+
AABB = scene.AABB
25+
superObjs = scene.superObjs
26+
allowedToMove = scene.allowedToMove
27+
visualizeBoundingBox = scene.options.visualizeBoundingBox
28+
nVisualContSupPoints = scene.options.nVisualContSupPoints
29+
2530
@assert(length(superObjs) > 0)
2631
@assert(nVisualContSupPoints > 0)
2732
dummyObject3D = Composition.emptyObject3DFeature
2833

2934
lengthCollSuperObjs = length(superObjs)
3035
if lengthCollSuperObjs <= 1
3136
error("There's nothing to collide. All Object3Ds are rigidly connected.")
37+
else
38+
# is: actual super - object
39+
# js: subsequent super - object
40+
# i: Object3D of is_th super - object
41+
# j: Object3D of js_th super - object
42+
@inbounds for is = 1:length(superObjs)
43+
actSuperObj = superObjs[is].superObjCollision.superObj
44+
if !isempty(actSuperObj)
45+
for i = 1:length(actSuperObj)
46+
actObj = actSuperObj[i] # determine contact from this Object3D with all Object3Ds that have larger indices
47+
for js = is+1:length(superObjs)
48+
if !(js in scene.noCPairs[is]) # PairID is not in objects which cant collide
49+
nextSuperObj = superObjs[js].superObjCollision.superObj
50+
for j = 1:length(nextSuperObj)
51+
nextObj = nextSuperObj[j]
52+
name1 = actObj.feature.contactMaterial
53+
name2 = nextObj.feature.contactMaterial
54+
Shapes.getContactPairMaterial(name1, name2)
55+
end
56+
end
57+
end
58+
end
59+
end
60+
end
3261
end
3362

3463
nzContact = 0

src/Shapes/contactPairMaterials.jl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,11 @@ function getContactPairMaterial(name1::AbstractString, name2::AbstractString )::
152152
# Combination name1,name2 is not present
153153
value1 = get(contactPairMaterialPalette, TwoNamesKey(name1,name1), NoContactPairMaterial())
154154
value2 = get(contactPairMaterialPalette, TwoNamesKey(name2,name2), NoContactPairMaterial())
155-
if typeof(value1) == NoContactPairMaterial || typeof(value2) == NoContactPairMaterial
156-
error("No contact pair material (\"$name1\",\"$name2\") or\n",
157-
"(\"$name1\",\"$name1\") or (\"$name2\",\"$name2\")\n",
158-
"in Modia3D.contactPairMaterialPalette dictionary.")
155+
if typeof(value1) != NoContactPairMaterial && typeof(value2) != NoContactPairMaterial
156+
return combineContactPairMaterials(value1, value2)
157+
else
158+
error("No contact pair material (\"$name1\",\"$name2\") is defined in Modia3D.contactPairMaterialPalette dictionary. Therefore, (\"$name1\",\"$name1\") and (\"$name2\",\"$name2\") are merged, at least one of these pairings is not defined as well.")
159159
end
160-
return combineContactPairMaterials(value1, value2)
161160
end
162161
return value
163162
end

src/contactDetection/ContactDetectionMPR/handler.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ AABB_touching(aabb1::Basics.BoundingBox, aabb2::Basics.BoundingBox) = aabb1.x_ma
1414
function Composition.initializeContactDetection!(world::Composition.Object3D, scene::Composition.Scene)::Nothing
1515
if typeof(scene.options.contactDetection) == Modia3D.ContactDetectionMPR_handler
1616
ch::Modia3D.ContactDetectionMPR_handler = scene.options.contactDetection
17-
ch.contactPairs = Composition.ContactPairs(world, scene.AABB, scene.superObjs, scene.allowedToMove,
18-
scene.options.visualizeBoundingBox,
19-
scene.options.nVisualContSupPoints, ch.visualizeContactPoints,
17+
ch.contactPairs = Composition.ContactPairs(world, scene, ch.visualizeContactPoints,
2018
ch.visualizeSupportPoints, ch.defaultContactSphereDiameter)
2119
if ch.contactPairs.nz == 0
2220
Composition.closeContactDetection!(ch)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
module InValidCollisionPairingError
2+
3+
using ModiaLang
4+
import Modia3D
5+
using Modia3D.ModiaInterface
6+
using Unitful
7+
8+
vmatRed = Modia3D.VisualMaterial(color="Red")
9+
vmatGreen = Modia3D.VisualMaterial(color="Green")
10+
vmatBlue = Modia3D.VisualMaterial(color="Blue")
11+
vmatGrey = Modia3D.VisualMaterial(color="Grey", transparency=0.5)
12+
13+
BouncingCones = Model(
14+
boxHeigth = 0.1,
15+
gravField = UniformGravityField(g=9.81, n=[0, 0, -1]),
16+
world = Object3D(feature=Scene(gravityField=:gravField,
17+
visualizeFrames=false,
18+
defaultFrameLength=0.2,
19+
enableContactDetection=true,
20+
animationFile="BouncingCones.json")),
21+
worldFrame = Object3D(parent=:world, feature=Visual(shape=CoordinateSystem(length=0.5))),
22+
ground = Object3D(parent=:world,
23+
translation=:[0.0, 0.0, -boxHeigth/2],
24+
feature=Solid(shape=Box(lengthX=5.0, lengthY=3.0, lengthZ=:boxHeigth),
25+
visualMaterial=vmatGrey,
26+
solidMaterial="DryWood",
27+
collision=true)),
28+
frameX = Object3D(parent=:world,
29+
translation=:[-1.0, -0.5, 1.0],
30+
rotation=:[-90*u"°", 0.0, -90*u"°"],
31+
feature=Visual(shape=CoordinateSystem(length=0.5))),
32+
coneX = Object3D(feature=Solid(shape=Cone(axis=1, diameter=0.4, length=1.0, topDiameter=0.3),
33+
visualMaterial=vmatRed,
34+
solidMaterial="BilliardTable",
35+
collision=true)),
36+
jointX = FreeMotion(obj1=:frameX, obj2=:coneX,
37+
r=Var(init=[0.0, 0.0, 0.0]),
38+
rot=Var(init=[0.0, -60*u"°", 0.0]),
39+
v=Var(init=[0.0, 1.0, 0.0])),
40+
frameY = Object3D(parent=:world,
41+
translation=:[0.0, -0.5, 1.0],
42+
rotation=:[90*u"°", 90*u"°", 0.0],
43+
feature=Visual(shape=CoordinateSystem(length=0.5))),
44+
coneY = Object3D(feature=Solid(shape=Cone(axis=2, diameter=0.4, length=1.0, topDiameter=0.3),
45+
visualMaterial=vmatGreen,
46+
solidMaterial="DryWood",
47+
collision=true)),
48+
jointY = FreeMotion(obj1=:frameY, obj2=:coneY,
49+
r=Var(init=[0.0, 0.0, 0.0]),
50+
rot=Var(init=[0.0, 0.0, -60*u"°"]),
51+
v=Var(init=[0.0, 0.0, 1.0])),
52+
frameZ = Object3D(parent=:world,
53+
translation=:[1.0, -0.5, 1.0],
54+
feature=Visual(shape=CoordinateSystem(length=0.5))),
55+
coneZ = Object3D(feature=Solid(shape=Cone(axis=3, diameter=0.4, length=1.0, topDiameter=0.3),
56+
visualMaterial=vmatBlue,
57+
solidMaterial="DryWood",
58+
collision=true)),
59+
jointZ = FreeMotion(obj1=:frameZ, obj2=:coneZ,
60+
r=Var(init=[0.0, 0.0, 0.0]),
61+
rot=Var(init=[-60*u"°", 0.0, 0.0]),
62+
v=Var(init=[1.0, 0.0, 0.0]))
63+
)
64+
65+
bouncingCones = @instantiateModel(buildModia3D(BouncingCones), unitless=true, log=false, logStateSelection=false, logCode=false)
66+
67+
68+
stopTime = 1.3
69+
tolerance = 1e-8
70+
71+
simulate!(bouncingCones, stopTime=stopTime, tolerance=tolerance, log=true, logStates=true, logEvents=true)
72+
73+
@usingModiaPlot
74+
plot(bouncingCones, [("jointX.r", "jointY.r", "jointZ.r") ("jointX.rot", "jointY.rot", "jointZ.rot")
75+
("jointX.v", "jointY.v", "jointZ.v") ("jointX.w", "jointY.w", "jointZ.w")], figure=1)
76+
77+
end

test/includeTests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Test.@testset "Collision" begin
4444
include(joinpath("Collision", "NewtonsCradle.jl"))
4545
include(joinpath("Collision", "Billard4Balls.jl"))
4646
Test.@test_skip include(joinpath("Collision", "Billard16Balls.jl")) # too long computation time
47+
Test.@test_throws LoadError include(joinpath("Collision", "InValidCollisionPairingError.jl")) # not defined collision pair material
4748
end
4849

4950
Test.@testset "Tutorial" begin

0 commit comments

Comments
 (0)