RobotLocomotion / drake

Model-based design and verification for robotics.
https://drake.mit.edu
Other
3.25k stars 1.25k forks source link

[geometry] Per-frame collision filtering #11554

Open SeanCurtis-TRI opened 5 years ago

SeanCurtis-TRI commented 5 years ago

Problem

Collision filtering (SceneGraph::ExcludeCollisionsWithin() and SceneGraph::ExcludeCollisionsBetween()) is an instantaneous act. It operates on geometry that is currently registered with SceneGraph, but has no impact on subsequent geometry.

It is a reasonable (and common) workflow to e.g., declare that some one or more frames should be filtered from anchored geometry (i.e., the world frame). Calling ExcludeCollisionsBetween(GeometrySet{get_world_frame()}, GeometrySet{{f1, f2, f3}); will accomplish that. But if I subsequently register geometry to any of those frames, it will not be filtered. Collision filtering needs to be repeated.

Feature request

It would be good that if I declare filtered collisions between frames, that that declaration applies to all geometries that are subsequently registered.

Proposal

Currently, collision cliques are only associated with geometries. We can achieve the desired affect (in the current filtering mechanism) by also associating collision cliques with frames and then always making sure geometries (in some sense) inherit those cliques from the frames they are rigidly affixed to.

It may be necessary, to preserve backward compatibility, to make this an "opt-in" behavior. Such that it's a property of the SceneGraph that can be set by a user. Something like the following:

SceneGraph<double> sg;
sg.SetInheritFrameCollisionFilters(true);
FrameId f1 = sg.RegisterFrame("f1");
FrameId f2 = sg.RegisterFrame("f2");
sg.ExcludeCollisionsBetween(GeometrySet{f1}, GeometrySet{f2});
GeometryId g1 = sg.RegisterGeometry(f1, ...);
GeometryId g2 = sg.RegisterGeometry(f2, ...);
EXPECT_TRUE(sg.model_inspector().CollisionFiltered(g1, g2));
SeanCurtis-TRI commented 5 years ago

cc @calderpg-tri @EricCousineau-TRI

Combine this with #11087 and we have some high utility collision filter convenience.

SeanCurtis-TRI commented 5 years ago

NOTE: There is a current work around.

A caller can create persistent GeometrySet instances. As geometries get registered on SceneGraph, the returned GeometryId can be added to one or more GeometrySet instances and calls to ExcludeCollisions*() can be deferred or redundantly invoked. However, this workflow doesn't necessarily work well in conjunction with collision filters declared in SDF files, whereas the proposed solution does.