Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Humanoid Path Planner
hpp-fcl
Commits
26342669
Commit
26342669
authored
Aug 29, 2019
by
Joseph Mirabel
Browse files
[GJK] Fix normalization issues
parent
88e90823
Changes
5
Hide whitespace changes
Inline
Side-by-side
include/hpp/fcl/narrowphase/gjk.h
View file @
26342669
...
...
@@ -50,7 +50,7 @@ namespace details
{
/// @brief the support function for shape
Vec3f
getSupport
(
const
ShapeBase
*
shape
,
const
Vec3f
&
dir
);
Vec3f
getSupport
(
const
ShapeBase
*
shape
,
const
Vec3f
&
dir
,
bool
dirIsNormalized
);
/// @brief Minkowski difference class of two shapes
///
...
...
@@ -86,15 +86,15 @@ struct MinkowskiDiff
}
/// @brief support function for shape0
inline
Vec3f
support0
(
const
Vec3f
&
d
)
const
inline
Vec3f
support0
(
const
Vec3f
&
d
,
bool
dIsNormalized
)
const
{
return
getSupport
(
shapes
[
0
],
d
);
return
getSupport
(
shapes
[
0
],
d
,
dIsNormalized
);
}
/// @brief support function for shape1
inline
Vec3f
support1
(
const
Vec3f
&
d
)
const
inline
Vec3f
support1
(
const
Vec3f
&
d
,
bool
dIsNormalized
)
const
{
return
oR1
*
getSupport
(
shapes
[
1
],
oR1
.
transpose
()
*
d
)
+
ot1
;
return
oR1
*
getSupport
(
shapes
[
1
],
oR1
.
transpose
()
*
d
,
dIsNormalized
)
+
ot1
;
}
/// @brief support function for the pair of shapes
...
...
@@ -169,6 +169,10 @@ struct GJK
return
simplex
;
}
/// Get the closest points on each object.
/// \return true on success
bool
getClosestPoints
(
const
MinkowskiDiff
&
shape
,
Vec3f
&
w0
,
Vec3f
&
w1
)
const
;
/// @brief get the guess from current simplex
Vec3f
getGuessFromSimplex
()
const
;
...
...
include/hpp/fcl/narrowphase/narrowphase.h
View file @
26342669
...
...
@@ -80,7 +80,7 @@ namespace fcl
Vec3f
w0
(
Vec3f
::
Zero
());
for
(
size_t
i
=
0
;
i
<
epa
.
result
.
rank
;
++
i
)
{
w0
+=
shape
.
support0
(
epa
.
result
.
vertex
[
i
]
->
d
)
*
w0
+=
shape
.
support0
(
epa
.
result
.
vertex
[
i
]
->
d
,
false
)
*
epa
.
result
.
coefficient
[
i
];
}
if
(
penetration_depth
)
*
penetration_depth
=
-
epa
.
depth
;
...
...
@@ -131,7 +131,7 @@ namespace fcl
Vec3f
w0
(
Vec3f
::
Zero
());
for
(
size_t
i
=
0
;
i
<
epa
.
result
.
rank
;
++
i
)
{
w0
+=
shape
.
support0
(
epa
.
result
.
vertex
[
i
]
->
d
)
*
w0
+=
shape
.
support0
(
epa
.
result
.
vertex
[
i
]
->
d
,
false
)
*
epa
.
result
.
coefficient
[
i
];
}
distance
=
-
epa
.
depth
;
...
...
@@ -144,16 +144,15 @@ namespace fcl
case
details
::
GJK
::
Failed
:
{
col
=
false
;
Vec3f
w0
(
Vec3f
::
Zero
()),
w1
(
Vec3f
::
Zero
());
for
(
size_t
i
=
0
;
i
<
gjk
.
getSimplex
()
->
rank
;
++
i
)
{
FCL_REAL
p
=
gjk
.
getSimplex
()
->
coefficient
[
i
];
w0
+=
shape
.
support0
(
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
w1
+=
shape
.
support1
(
-
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
}
distance
=
(
w0
-
w1
).
norm
();
p1
=
tf1
.
transform
(
w0
);
p2
=
tf1
.
transform
(
w1
);
gjk
.
getClosestPoints
(
shape
,
p1
,
p2
);
// TODO On degenerated case, the closest point may be wrong
// (i.e. an object face normal is colinear to gjk.ray
// assert (distance == (w0 - w1).norm());
distance
=
gjk
.
distance
;
p1
=
tf1
.
transform
(
p1
);
p2
=
tf1
.
transform
(
p2
);
assert
(
distance
>
0
);
}
break
;
...
...
@@ -190,13 +189,8 @@ namespace fcl
{
// TODO: understand why GJK fails between cylinder and box
assert
(
distance
*
distance
<
sqrt
(
eps
));
Vec3f
w0
(
Vec3f
::
Zero
()),
w1
(
Vec3f
::
Zero
());
for
(
size_t
i
=
0
;
i
<
gjk
.
getSimplex
()
->
rank
;
++
i
)
{
FCL_REAL
p
=
gjk
.
getSimplex
()
->
coefficient
[
i
];
w0
+=
shape
.
support0
(
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
w1
+=
shape
.
support1
(
-
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
}
Vec3f
w0
,
w1
;
gjk
.
getClosestPoints
(
shape
,
w0
,
w1
);
distance
=
0
;
p1
=
p2
=
tf1
.
transform
(
.5
*
(
w0
+
w1
));
normal
=
Vec3f
(
0
,
0
,
0
);
...
...
@@ -204,18 +198,14 @@ namespace fcl
}
else
if
(
gjk_status
==
details
::
GJK
::
Valid
)
{
Vec3f
w0
(
Vec3f
::
Zero
()),
w1
(
Vec3f
::
Zero
());
for
(
size_t
i
=
0
;
i
<
gjk
.
getSimplex
()
->
rank
;
++
i
)
{
FCL_REAL
p
=
gjk
.
getSimplex
()
->
coefficient
[
i
];
w0
+=
shape
.
support0
(
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
w1
+=
shape
.
support1
(
-
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
}
distance
=
(
w0
-
w1
).
norm
();
p1
=
tf1
.
transform
(
w0
);
p2
=
tf1
.
transform
(
w1
);
gjk
.
getClosestPoints
(
shape
,
p1
,
p2
);
// TODO On degenerated case, the closest point may be wrong
// (i.e. an object face normal is colinear to gjk.ray
// assert (distance == (w0 - w1).norm());
distance
=
gjk
.
distance
;
p1
=
tf1
.
transform
(
p1
);
p2
=
tf1
.
transform
(
p2
);
return
true
;
}
else
...
...
@@ -231,7 +221,7 @@ namespace fcl
Vec3f
w0
(
Vec3f
::
Zero
());
for
(
size_t
i
=
0
;
i
<
epa
.
result
.
rank
;
++
i
)
{
w0
+=
shape
.
support0
(
epa
.
result
.
vertex
[
i
]
->
d
)
*
w0
+=
shape
.
support0
(
epa
.
result
.
vertex
[
i
]
->
d
,
false
)
*
epa
.
result
.
coefficient
[
i
];
}
assert
(
epa
.
depth
>=
-
eps
);
...
...
@@ -242,17 +232,11 @@ namespace fcl
}
else
{
Vec3f
w0
(
Vec3f
::
Zero
()),
w1
(
Vec3f
::
Zero
());
for
(
size_t
i
=
0
;
i
<
gjk
.
getSimplex
()
->
rank
;
++
i
)
{
FCL_REAL
p
=
gjk
.
getSimplex
()
->
coefficient
[
i
];
w0
+=
shape
.
support0
(
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
w1
+=
shape
.
support1
(
-
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
}
gjk
.
getClosestPoints
(
shape
,
p1
,
p2
);
distance
=
0
;
p1
=
tf1
.
transform
(
w0
);
p2
=
tf1
.
transform
(
w1
);
p1
=
tf1
.
transform
(
p1
);
p2
=
tf1
.
transform
(
p2
);
}
return
false
;
}
...
...
src/narrowphase/gjk.cpp
View file @
26342669
...
...
@@ -166,41 +166,50 @@ void getShapeSupport(const Convex* convex, const Vec3f& dir, Vec3f& support)
}
}
Vec3f
getSupport
(
const
ShapeBase
*
shape
,
const
Vec3f
&
dir
)
#define CALL_GET_SHAPE_SUPPORT(ShapeType) \
getShapeSupport (static_cast<const ShapeType*>(shape), \
(shape_traits<ShapeType>::NeedNormalizedDir && !dirIsNormalized) \
? dir.normalized() : dir, \
support)
Vec3f
getSupport
(
const
ShapeBase
*
shape
,
const
Vec3f
&
dir
,
bool
dirIsNormalized
)
{
Vec3f
support
;
switch
(
shape
->
getNodeType
())
{
case
GEOM_TRIANGLE
:
getShapeSupport
(
static_cast
<
const
TriangleP
*>
(
shape
),
dir
,
support
);
CALL_GET_SHAPE_SUPPORT
(
TriangleP
);
break
;
case
GEOM_BOX
:
getShapeSupport
(
static_cast
<
const
Box
*>
(
shape
),
dir
,
support
);
CALL_GET_SHAPE_SUPPORT
(
Box
);
break
;
case
GEOM_SPHERE
:
getShapeSupport
(
static_cast
<
const
Sphere
*>
(
shape
),
dir
,
support
);
CALL_GET_SHAPE_SUPPORT
(
Sphere
);
break
;
case
GEOM_CAPSULE
:
getShapeSupport
(
static_cast
<
const
Capsule
*>
(
shape
),
dir
,
support
);
CALL_GET_SHAPE_SUPPORT
(
Capsule
);
break
;
case
GEOM_CONE
:
getShapeSupport
(
static_cast
<
const
Cone
*>
(
shape
),
dir
,
support
);
CALL_GET_SHAPE_SUPPORT
(
Cone
);
break
;
case
GEOM_CYLINDER
:
getShapeSupport
(
static_cast
<
const
Cylinder
*>
(
shape
),
dir
,
support
);
CALL_GET_SHAPE_SUPPORT
(
Cylinder
);
break
;
case
GEOM_CONVEX
:
getShapeSupport
(
static_cast
<
const
Convex
*>
(
shape
),
dir
,
support
);
CALL_GET_SHAPE_SUPPORT
(
Convex
);
break
;
case
GEOM_PLANE
:
case
GEOM_HALFSPACE
:
default:
support
.
setZero
();
;
// nothing
}
return
support
;
}
#undef CALL_GET_SHAPE_SUPPORT
template
<
typename
Shape0
,
typename
Shape1
>
void
getSupportTpl
(
const
Shape0
*
s0
,
const
Shape1
*
s1
,
const
Matrix3f
&
oR1
,
const
Vec3f
&
ot1
,
...
...
@@ -300,6 +309,19 @@ Vec3f GJK::getGuessFromSimplex() const
return
ray
;
}
bool
GJK
::
getClosestPoints
(
const
MinkowskiDiff
&
shape
,
Vec3f
&
w0
,
Vec3f
&
w1
)
const
{
w0
.
setZero
();
w1
.
setZero
();
for
(
size_t
i
=
0
;
i
<
getSimplex
()
->
rank
;
++
i
)
{
FCL_REAL
p
=
getSimplex
()
->
coefficient
[
i
];
w0
+=
shape
.
support0
(
getSimplex
()
->
vertex
[
i
]
->
d
,
false
)
*
p
;
w1
+=
shape
.
support1
(
-
getSimplex
()
->
vertex
[
i
]
->
d
,
false
)
*
p
;
}
return
true
;
}
GJK
::
Status
GJK
::
evaluate
(
const
MinkowskiDiff
&
shape_
,
const
Vec3f
&
guess
)
{
size_t
iterations
=
0
;
...
...
src/narrowphase/narrowphase.cpp
View file @
26342669
...
...
@@ -644,26 +644,24 @@ bool GJKSolver_indep::shapeDistance<Capsule, Capsule>
details
::
GJK
::
Status
gjk_status
=
gjk
.
evaluate
(
shape
,
-
guess
);
if
(
enable_cached_guess
)
cached_guess
=
gjk
.
getGuessFromSimplex
();
Vec3f
w0
(
Vec3f
::
Zero
()),
w1
(
Vec3f
::
Zero
());
for
(
size_t
i
=
0
;
i
<
gjk
.
getSimplex
()
->
rank
;
++
i
)
{
FCL_REAL
p
=
gjk
.
getSimplex
()
->
coefficient
[
i
];
w0
+=
shape
.
support0
(
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
w1
+=
shape
.
support1
(
-
gjk
.
getSimplex
()
->
vertex
[
i
]
->
d
)
*
p
;
}
gjk
.
getClosestPoints
(
shape
,
p1
,
p2
);
if
((
gjk_status
==
details
::
GJK
::
Valid
)
||
(
gjk_status
==
details
::
GJK
::
Failed
))
{
dist
=
(
w0
-
w1
).
norm
();
p1
=
tf1
.
transform
(
w0
);
p2
=
tf1
.
transform
(
w1
);
// TODO On degenerated case, the closest point may be wrong
// (i.e. an object face normal is colinear to gjk.ray
// assert (dist == (w0 - w1).norm());
dist
=
gjk
.
distance
;
p1
=
tf1
.
transform
(
p1
);
p2
=
tf1
.
transform
(
p2
);
return
true
;
}
else
if
(
gjk_status
==
details
::
GJK
::
Inside
)
{
p1
=
tf1
.
transform
(
w0
);
p2
=
tf1
.
transform
(
w1
);
p1
=
tf1
.
transform
(
p1
);
p2
=
tf1
.
transform
(
p2
);
if
(
enable_penetration
)
{
FCL_REAL
penetrationDepth
=
details
::
computePenetration
...
...
test/test_fcl_capsule_box_1.cpp
View file @
26342669
...
...
@@ -78,7 +78,8 @@ BOOST_AUTO_TEST_CASE(distance_capsule_box)
BOOST_CHECK_CLOSE
(
o1
[
0
],
1.0
,
1e-1
);
CHECK_CLOSE_TO_0
(
o1
[
1
],
1e-1
);
BOOST_CHECK_CLOSE
(
o2
[
0
],
0.5
,
1e-1
);
CHECK_CLOSE_TO_0
(
o1
[
1
],
1e-1
);
// This cannot be ensured with the current code.
// CHECK_CLOSE_TO_0 (o2 [1], 1e-1);
// Move capsule above box
tf1
=
hpp
::
fcl
::
Transform3f
(
hpp
::
fcl
::
Vec3f
(
0.
,
0.
,
8.
));
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment