-
Notifications
You must be signed in to change notification settings - Fork 421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cylinder half space bug fix #255
Cylinder half space bug fix #255
Conversation
@jslee02, would you be able to review this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good to me. The unit test is very clear. 😄
I just made some minor comments.
Also, it seems there is a similar issue in the cone-halfspace intersection test. Would you mind fixing that as well?
|
||
// Now perform the same test but with the cylinder's z axis Cz pointing down. | ||
X_WC.linear() = AngleAxisd(M_PI, Vector3d::UnitX()).matrix(); | ||
X_WC.translation() = Vector3d(0, 0, 0.049); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: It would be good to change Vector3d
to Vector3<S>
for completeness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent, that's right. I was just copying the patter in other unit tests and I templated everything on <S>
. Did you have a chance to test FCL with AutoDiffXd
? the automatic differentiation scalar from Eigen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote a very simple test case with AutoDiffScalar
here. Is that what you're looking for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent! is fcl::collide()
also supported? will it work with meshes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any particular reason fcl::collide()
wouldn't work as long as everything is templated for the scalar type, which I believe so, but I haven't tested it myself.
EXPECT_NEAR(contacts[0].penetration_depth, 0.051, kTolerance); | ||
|
||
// Now perform the same test but with the cylinder's z axis Cz pointing down. | ||
X_WC.linear() = AngleAxisd(M_PI, Vector3d::UnitX()).matrix(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: It would be good to use AngleAxis<S>
for completeness.
I saw the cone problem also. I don't think I'll have time to push a unit test any time soon. I'll see to write a unit test for that one on Monday. @jslee02, is there a reason to use |
No worries. Let me create an issue for this to track.
I didn't write the code, but here is my hunch. Zero tolerance would be too strict criteria for an object (cylinder or cone) to be regarded laid on the ground parallel to the ground surface. Suppose you drop an object on the ground (halfspace) in a physics simulator, then the object would jitter a lot before it becomes stable due to the on-and-off contact points on the end of edges of the side (e.g., the contact points on the top and bottom of the cylinder). |
That is a problem of the simulator what to do with the information you provide. The problem you mention is because real physical contact does not happen at points but on surfaces patches. I believe that as a geometry engine, the penetration queries should be purely geometrical, irrespective of what a physics engine might do with the results. Attempting to couple them with tricks as using a loose tolerance will most likely bite you back and produce difficult to find bugs. I think the right thing to do would be doing the check against "zero", though I'd need to investigate the math in this particular case further to make sure there is no other pathological case. |
That totally makes sense. Thinking further, I actually presume that's because "comparing floating point number to zero is not safe". Probably, we never get to the case of the if-statement is true if we compare I'm open to using a better way for this. |
Yes, on further thought I agree with you. Using a tolerance is a good idea. However, what is the best way to choose this tolerance? shouldn't it be a number closer to machine epsilon? 1e-7 seems a bit loose to me but there might be a good reason for it. |
Sorry, it's a tricky question to answer to me. 😓 |
Travis CI is failing for this PR. Is that due to this change? |
I also need to ponder this. @amcastro-tri makes a compelling point about the geometry query introducing error before the physics gets a chance to reason at all. However, the idea of testing a float against zero feels categorically wrong. For an arbitrarily oriented plane, it seems that the odds that a cylinder would ever be considered as "lying" on the plane would be roughly 1 in 2 billion. It's like testing for vertex-vertex collision -- simply not worth it. It comes down to the fact that the geometric query itself is subject to numerical accuracy and it should do its best effort to come up with the right geometric answer which accounts for numerical. I think operating with respect to an epsilon in this regard is inevitable. It should be well reasoned and it may be that 1e-7 is far too large for doubles. But, at the end of the day, strictly comparing against 0 just seems suspicious. |
// Pose of half space frame H in the world frame W. | ||
Transform3<S> X_WH = Transform3<S>::Identity(); | ||
|
||
CollisionObject<S> half_sapce_co(half_space, X_WH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sapce -> space
One rational way to choose tolerances is to view them as the result of an optimization in which we try to make a numerical calculation as close to the analytical result as possible. A tolerance of 0 won't do that because the computation will become dominated by roundoff error. A tolerance of 0.1 won't do that because it is a bad approximation of the geometry (sometimes called "truncation error"). Somewhere in between is a tolerance that minimizes some measure of the actual error. In the case of this cylinder vs half space algorithm, I believe the tolerance is being used to choose one of three discrete contact point possibilities: center of an end cap, edge of an end cap, or center of a long edge of the tube. If the objects couldn't interpenetrate, the contact points really would change discretely. But these actually interpenetrate, so there is an overlap volume that evolves continuously. That provides a "right answer" that we could hope to approximate: that the contact "point" is at the centroid of the overlap volume. Ideally the algorithm would just return that point! But if it has to instead make discrete choices, the ideal tolerance would be the one that minimizes a measure of the deviation between the returned point and that centroid. Of course it is easier said than done to make that determination, but at least there is a reasonable way to think about it. |
I've retriggered CI - one test was clearly a flake (and has since passed). The two mac tests seem to fail on an unrelated test. I've retriggered them and may take a peek later if they still fail. However, both mac build tests are stalled in starting. |
@@ -371,7 +371,7 @@ bool cylinderHalfspaceIntersect(const Cylinder<S>& s1, const Transform3<S>& tf1, | |||
Vector3<S> dir_z = R.col(2); | |||
S cosa = dir_z.dot(new_s2.n); | |||
|
|||
if(cosa < halfspaceIntersectTolerance<S>()) | |||
if(std::abs(cosa) < halfspaceIntersectTolerance<S>()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm putting this comment here because github won't let me put it where I want to.
On line 394 we have the line of code:
if (std::abs(cosa + 1) < halfspaceIntersectTolerance<S>() || std::abs(cosa - 1) < halfspaceIntersectTolerance<S>())
It could be replaced with:
if (std::abs(cosa) - 1 < halfspaceIntersectTolerance<S>())
I figured, as long as we're in this code, we could patch this as well (although this isn't a correctness issue, merely an efficiency/compactness issue).
@jslee02 The mac CI is failing on (what seems to be) an unrelated test. I don't have access to a mac; any idea what the best way to resolve this is? Review status: 0 of 3 files reviewed at latest revision, 4 unresolved discussions, some commit checks failed. Comments from Reviewable |
@jslee02 the mac CI keeps failing and it doesn't seem to be an obvious problem. Should we create an issue for this? do you think you'd have an idea on what causes the problem? |
I added issue #260. |
@amcastro-tri I retriggered Travis for master branch builds, which were failed due to failing in installing |
83dc1ad
to
4105549
Compare
I went ahead and addressed the comments. Reviewed 2 of 3 files at r1, 1 of 1 files at r2, 2 of 2 files at r3. include/fcl/narrowphase/detail/primitive_shape_algorithm/halfspace-inl.h, line 374 at r2 (raw file): Previously, SeanCurtis-TRI (Sean Curtis) wrote…
Done test/test_fcl_cylinder_half_space.cpp, line 82 at r1 (raw file): Previously, jslee02 (Jeongseok Lee) wrote…
Done test/test_fcl_cylinder_half_space.cpp, line 83 at r1 (raw file): Previously, jslee02 (Jeongseok Lee) wrote…
Done test/test_fcl_cylinder_half_space.cpp, line 65 at r2 (raw file): Previously, sherm1 (Michael Sherman) wrote…
Done Comments from Reviewable |
1. Fix typos 2. Update copyright 3. Simplify mathematical expression 4. Test w.r.t. templated scalar.
4105549
to
4a1677f
Compare
Thank you @SeanCurtis-TRI! Review status: all files reviewed at latest revision, 2 unresolved discussions. Comments from Reviewable |
Review status: all files reviewed at latest revision, 2 unresolved discussions, some commit checks failed. Comments from Reviewable |
There is a bug with the penetration query for cylinder vs half space. This is reported in RobotLocomotion/drake#8049.
This PR fixes this bug and implements a new unit test that without the fix would not pass.
This change is