Explain why collisionValidationFunction would refuse a configuration.
Runs the same checks under the same request as the predicate, and reports the first that finds contacts. Callers that only need a verdict should use the predicate: this one requests contact details, so it costs more per call and is meant for the failure path.
Reports self-collisions before environment ones. That is this function's own order, not the predicate's: collisionValidationFunction issues a single checkCollision, which checks the environment first and self-collisions second. So a configuration that is in both kinds of collision is named here by its self-collision, while the predicate would have hit the environment contact first. Both are real contacts of the same configuration under the same request — what the predicate cannot express either way is which, since it answers with a bare bool.
Contacts come back in the returned PlanningError::collision_info, which is what lets a caller draw where the configuration touched rather than only that it did. Deriving them from a separate check of the caller's own devising risks reporting a contact that is not the one that refused the pose; sharing the request is the point of this function.
- Parameters
-
| group | Joint model group associated with joint_positions. |
| joint_positions | Configuration to explain. Must hold one value per active variable of group, exactly as collisionValidationFunction requires. |
| planning_scene | Planning scene to check against. Its current state's group joints are overwritten with joint_positions. |
| pad_environment_collisions | Whether link padding applies to robot-environment checks. |
| pad_self_collisions | Whether link padding applies to self-collision checks. When false, the returned message omits the padding hint for a self-collision, which would otherwise name a padding value that had no part in the refusal. |
- Returns
- A
PlanningError naming the colliding bodies, carrying the contacts and joint_positions, or std::nullopt if neither check recorded a contact — which is not the same as valid, since a caller may refuse the configuration for reasons this function does not check.
- Note
- "No contact recorded" and "no collision" coincide only because the request asks for contacts and leaves room for them: FCL stops storing once the contact budget is spent and reports the collision through a flag instead. That budget is set here and never by the caller, so the two stay equivalent — but the branch is on the contacts, because they are what the message needs.