-
Notifications
You must be signed in to change notification settings - Fork 287
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
Avoid NaN values caused by zero-length normals in ContactConstraint #881
Conversation
That's a really interesting problem. In my mind, that raises some pretty fundamental questions: What is the actual meaning of a zero-length normal? I would be inclined to interpret that as a bug in the collision detector, unless the collision detection library assigns some special semantic meaning to a normal vector of zero length (perhaps it means the direction of the normal is ambiguous or indeterminable?). Furthermore, are non-unit-length normal vectors something that should be expected in general? Is there a special meaning to these lengths? If it's nothing more than a bug, then I might propose discarding that specific contact point (because other aspects of its contact info might also be bugged) and maybe printing a warning for the user. But if the vector length has some deeper meaning, then it might be a good idea to work with it rather than against it. |
You are right, the interpretation of the contact normal may vary from collision detector to collision detector. In FCL it is the "Contact normal, pointing from o1 to o2" - a bit of a vague definition in the documentation (would need to dig up the code which computes it to know more). The penetration depth in FCL is a separate field, which makes me think the length will always be 1. I'm not sure how this normal is to be interpreted, but my guess of what would make most sense: if the objects are moved along this normal for a length equalling the penetration depth, they are not touching any more - and the normal points along the minimum penetration depth between the objects. But that's just a guess, I'd have to dig into the collision detectors more deeply to look up how they all exactly calculate this. A more general interpretation of the contact normal would be that it is the force component perpendicular to the surface of contact (the "normal force"). In this case the length could be the actual force. Some collision detectors (maybe even future ones) may actually use this definition. So bottom line IMO: at least in principle, the definition can vary between collision detectors. Therefore I would probably try to allow zero normals in dart, and leave the catching of this error to the collision detector: if it regards a zero-length normal as an error, it should not return a contact in the first place. If there is a bug in the collision detector, and zero length normals are returned anyway, DART should at least not crash. As to the length of the normal: this can probably be similarly ambiguous between collision detectors. The world "normal" alone suggests unit length - otherwise it would (or should) be a "direction". However when thinking of "normal force", the length of the normal can be the actual force exerted in normal direction. Unless the normal length is actually used as a force in DART (which I don't think it is, it's only interpreted as direction?), I think it should always be normalized just in case, to be sure it doesn't cause issues. |
Thanks for catching this issue. However, I wonder if the zero-length normal was generated because Even if that's not the case, I still believe zero-length contact normal is just a bug of the collision detector. AFAIK, at least FCL doesn't intend to return zero-length normal (or even non-unit vector) in any case.
This is possible in dynamics simulation, but I don't believe collision detectors use "normal" field for that purpose.
👍 Here is what I would like to propose instead:
|
Sounds good to me. Will extend this PR to include the proposed changes. Will probably do this within the next days, gotta finish something else first ;) |
I've done the suggested changes for FCL... before I do the same for bullet, let me know if this is what you had in mind, of if you had thought of it differently. So the error happens when |
Yes. That's what I intended. Additionally, I would like to handle the second bullet points in my previous comment, but it is not necessary to be addressed in this PR though. 😄 |
I thought that was already addressing the first and 2nd bullet point together, so I must be misunderstanding this ;) Anyway, if that's the kind of fix you had in mind, I'll do the same for bullet, and then we can merge. Coming up soon :) |
Sorry for taking so long. I have added the changes for bullet too - should there ever be the case that it produces zero length normals at all. I also added another case where zero length normals could sneak in, in Which way would you suggest is the best to test this with bullet? I see |
Sorry, this PR was accidentally closed as the target branch is deleted. Reopening. |
# Conflicts: # dart/collision/bullet/BulletCollisionDetector.cpp
Sorry for late response. I made some changes to resolve conflictions with the target branch ( I think we can merge this unless receiving more feedback soon. Thank you for your contribution!
We could test Bullet (and other collision detectors) for the same test of FCL by making the collision detector as a parameter to the test like this test for example. |
When testing the integration of DART 6 into Gazebo (see PR 2547) one issue was found with the iRobot Hand model: Some contacts with a zero-length normal were generated, which lead to NaN values, which in turn lead to a crash.
This PR fixes the issue, though it is only a suggestion on how to handle this. We could also prevent zero-length normals from counting as valid contact altogether (e.g. in ConstraintSolver.cpp), and not insert them to the list of contacts. That would prevent the issue as well.