Skip to content

Commit 01d8a8e

Browse files
committed
if createBabyTetrahedron is false, a warning is triggered
1 parent 1c100de commit 01d8a8e

File tree

1 file changed

+73
-47
lines changed
  • src/contactDetection/ContactDetectionMPR

1 file changed

+73
-47
lines changed

src/contactDetection/ContactDetectionMPR/mpr.jl

Lines changed: 73 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,6 @@ function getSupportPoint(shapeA::Modia3D.Composition.Object3D, shapeB::Compositi
2121
return SupportPoint((a-b).*scale,n,a,b)
2222
end
2323

24-
#=
25-
function getSupportPoint(shapeA::Modia3D.Composition.Object3D, shapeB::Composition.Object3D, n::Nothing; scale::Float64=1.0)
26-
println(Modia3D.fullName(shapeA), " r_abs ", shapeA.r_abs, " R_abs ", shapeA.R_abs)
27-
println(Modia3D.fullName(shapeB), " r_abs ", shapeB.r_abs, " R_abs ", shapeB.R_abs)
28-
error("numerical issues computing normalized vector")
29-
return nothing
30-
end
31-
=#
3224

3325
function barycentric(r1::SupportPoint,r2::SupportPoint,r3::SupportPoint,r4::SupportPoint)
3426
r21 = r2.p - r1.p
@@ -178,7 +170,7 @@ function constructR4(r0::SupportPoint,r1::SupportPoint,r2::SupportPoint,r3::Supp
178170
return (r3, r4, n4)
179171
end
180172

181-
173+
# computes twice a parallelepipedial product (Spatprodukt)
182174
isNextPortal(r0,r1,r2,r4) = dot( cross( (r2.p-r0.p), (r4.p-r0.p) ), r0.n ) <= 0.0 &&
183175
dot( cross( (r4.p-r0.p), (r1.p-r0.p) ), r0.n ) <= 0.0
184176

@@ -191,20 +183,17 @@ isNextPortal(r0,r1,r2,r4) = dot( cross( (r2.p-r0.p), (r4.p-r0.p) ), r0.n ) <= 0.
191183
# r3r1r4
192184
function createBabyTetrahedrons(r0::SupportPoint,r1::SupportPoint,r2::SupportPoint,r3::SupportPoint,r4::SupportPoint,
193185
shapeA::Composition.Object3D,shapeB::Composition.Object3D)
186+
nextPortal = true
194187
if isNextPortal(r0,r1,r2,r4)
195188
r3 = r4
196189
elseif isNextPortal(r0,r2,r3,r4)
197190
r1 = r4
198191
elseif isNextPortal(r0,r3,r1,r4)
199192
r2 = r4
200193
else
201-
# Compute the closest distance to the portal and return it:
202-
(r4.p, distance) = signedDistanceToPortal(r0.p,r1.p,r2.p,r3.p)
203-
barycentric(r1,r2,r3,r4)
204-
error("MPR: Numerical issues with distance computation between shapeA = ", shapeA, " and shapeB = ", shapeB,". Used distance = ",distance)
205-
return (r1, r2, r3)
194+
nextPortal = false # the signs of all tried combinations of parallelepipedial products are not negative
206195
end
207-
return (r1, r2, r3)
196+
return (nextPortal, r1, r2, r3)
208197
end
209198

210199

@@ -221,6 +210,30 @@ function skalarization(r0,r1,r2,r3)
221210
return (r0, r1, r2, r3, scale)
222211
end
223212

213+
function finalTC2(r1, r2, r3, r4)
214+
#println("TC 2")
215+
#if !analyzeFinalPortal(r1.p, r2.p, r3.p, r4.p, neps)
216+
# error("shapeA = ", shapeA, " shapeB = ", shapeB)
217+
#end
218+
distance = -dot(r4.n, r4.p)
219+
barycentric(r1,r2,r3,r4)
220+
return distance, r1, r2, r3, r4
221+
end
222+
223+
function finalTC3(r0, r1, r2, r3, r4)
224+
#println("TC 3")
225+
226+
#doesRayIntersectPortal(r1.p,r2.p,r3.p, r4.p,neps)
227+
#println("r1.p = ", r1.p , " r2.p = ", r2.p ," r3.p = ", r3.p)
228+
#println("r4.p = ", r4.p)
229+
#println(" ")
230+
#if !analyzeFinalPortal(r1.p, r2.p, r3.p, r4.p, neps)
231+
# error("shapeA = ", shapeA, " shapeB = ", shapeB)
232+
#end
233+
(r4.p, distance) = signedDistanceToPortal(r0.p,r1.p,r2.p,r3.p)
234+
barycentric(r1,r2,r3,r4)
235+
return distance, r1, r2, r3, r4
236+
end
224237

225238
# MPR - Minkowski Portal Refinement algorithm
226239
# construction of points r0 is in the interior of Minkowski Difference and points r1,r2,r3,r4 are on the boundary of Minkowski Difference
@@ -301,6 +314,13 @@ function mprGeneral(ch::Composition.ContactDetectionMPR_handler, shapeA::Composi
301314

302315

303316
########### Phase 3, Minkowski Portal Refinement ###################
317+
new_tol = 42.0
318+
isTC2 = false
319+
isTC3 = false
320+
r1_new::SupportPoint = r0
321+
r2_new::SupportPoint = r0
322+
r3_new::SupportPoint = r0
323+
r4_new::SupportPoint = r0
304324
for i in 1:niter_max
305325
### Phase 3.1: construct r4 ###
306326
# Find support point using the tetrahedron face
@@ -311,49 +331,55 @@ function mprGeneral(ch::Composition.ContactDetectionMPR_handler, shapeA::Composi
311331
# check if the new point r4 is already on the plane of the triangle r1,r2,r3,
312332
# we're already as close as we can get to the origin
313333

334+
TC2 = norm(cross(r4.p,r4.n)) # TC2
335+
TC3 = abs(dot(r4.p-r1.p, r4.n)) # TC3
314336
## TERMINATION CONDITION 2 ##
315-
if norm(cross(r4.p,r4.n)) < tol_rel
316-
#println("TC 2")
317-
#if !analyzeFinalPortal(r1.p, r2.p, r3.p, r4.p, neps)
318-
# error("shapeA = ", shapeA, " shapeB = ", shapeB)
319-
#end
320-
distance = -dot(r4.n, r4.p)
321-
barycentric(r1,r2,r3,r4)
322-
337+
if TC2 < tol_rel
338+
(distance,r1,r2,r3,r4) = finalTC2(r1,r2,r3,r4)
323339
return (distance, r4.a, r4.b, r4.n, true, r1.a, r1.b, r2.a, r2.b, r3.a, r3.b)
324340

325341
## TERMINATION CONDITION 3 ##
326-
elseif abs(dot(r4.p-r1.p, r4.n)) < tol_rel
327-
#println("TC 3")
328-
329-
#doesRayIntersectPortal(r1.p,r2.p,r3.p, r4.p,neps)
330-
#println("r1.p = ", r1.p , " r2.p = ", r2.p ," r3.p = ", r3.p)
331-
#println("r4.p = ", r4.p)
332-
#println(" ")
333-
#if !analyzeFinalPortal(r1.p, r2.p, r3.p, r4.p, neps)
334-
# error("shapeA = ", shapeA, " shapeB = ", shapeB)
335-
#end
336-
(r4.p, distance) = signedDistanceToPortal(r0.p,r1.p,r2.p,r3.p)
337-
barycentric(r1,r2,r3,r4)
338-
342+
elseif TC3 < tol_rel
343+
(distance,r1,r2,r3,r4) = finalTC3(r0, r1, r2, r3, r4)
339344
return (distance, r4.a, r4.b, r4.n, true, r1.a, r1.b, r2.a, r2.b, r3.a, r3.b)
345+
else
346+
if TC2 < new_tol
347+
new_tol = TC2
348+
isTC2 = true
349+
isTC3 = false
350+
r1_new = r1
351+
r2_new = r2
352+
r3_new = r3
353+
r4_new = r4
354+
end
355+
if TC3 < new_tol
356+
new_tol = TC3
357+
isTC2 = false
358+
isTC3 = true
359+
r1_new = r1
360+
r2_new = r2
361+
r3_new = r3
362+
r4_new = r4
363+
end
340364
end
341365

342366
#### Phase 3.3: construct baby tetrahedrons with r1,r2,r3,r4 and create a new portal ###
343367
# Construction of three baby tetrahedrons
344-
(r1,r2,r3) = createBabyTetrahedrons(r0,r1,r2,r3,r4,shapeA,shapeB)
345-
346-
347-
#=
348-
r0RayOnPortal = isr0RayOnPortal(r0.p,r1.p,r2.p,r3.p)
349-
if r0RayOnPortal[1] != true
350-
println("r0RayOnPortal = ", r0RayOnPortal, ": Wrong baby-tetrahedron selected. " , i)
368+
(nextPortal, r1,r2,r3) = createBabyTetrahedrons(r0,r1,r2,r3,r4,shapeA,shapeB)
369+
370+
if !nextPortal # createBabyTetrahedrons failed
371+
@warn("MPR (phase 3): Numerical issues with distance computation between $(Modia3D.fullName(shapeA)) and $(Modia3D.fullName(shapeB)). tol_rel increased locally for this computation to $new_tol.")
372+
if isTC2
373+
(distance,r1,r2,r3,r4) = finalTC2(r1_new,r2_new,r3_new,r4_new)
374+
return (distance, r4.a, r4.b, r4.n, true, r1.a, r1.b, r2.a, r2.b, r3.a, r3.b)
375+
end
376+
if isTC3
377+
(distance,r1,r2,r3,r4) = finalTC3(r0, r1_new, r2_new, r3_new, r4_new)
378+
return (distance, r4.a, r4.b, r4.n, true, r1.a, r1.b, r2.a, r2.b, r3.a, r3.b)
379+
end
351380
end
352-
=#
353-
354381
end
355-
error("MPR: Should never get here! Computation failed. Look at shapeA = ", Modia3D.instanceName(shapeA),
356-
" shapeB = ", Modia3D.instanceName(shapeB))
382+
error("MPR (phase 3): Numerical issues with distance computation between $(Modia3D.fullName(shapeA)) and $(Modia3D.fullName(shapeB)).")
357383
end
358384

359385

0 commit comments

Comments
 (0)