dartsim / dart

DART: Dynamic Animation and Robotics Toolkit
http://dartsim.github.io/
BSD 2-Clause "Simplified" License
892 stars 285 forks source link

Plane shape #114

Open jslee02 opened 10 years ago

jslee02 commented 10 years ago

We should consider supporting infinite plane shape for ground.

PlaneShape

jslee02 commented 10 years ago

PlaneShape was added by 4d19d606b1207c2b05dd292af1c3679411f7baa1 but only BulletCollisionDetector supports the PlaneShape.

Our renderer doesn't support PlaneShape yet.

jslee02 commented 9 years ago

Pending until FCLCollisionDetector becomes default collision detector.

JenniferBuehler commented 7 years ago

Has there been any developments on this?

My problem is related to Gazebo integration with DART 6.1: in gazebo::physics::DARTPlaneShapePrivate, a "fake plane", i.e. a Box shape is used instead of a plane, to address this issue here.

Problem is that DART's Shape::setOffset() method has been removed, and as far as I can see, now instead ShapeNode::setRelativeTransform should be used. It appears that ShapeNode is a wrapper to Shape, so I can't just do a ShapeNode instead of the existing the box Shape.

Are there any plans to make the plane shape work in near future?

Thanks Jennifer

mxgrey commented 7 years ago

Are you referring to the "fake plane" floor geometry was being used in simulation? That suggests the Shape was getting passed as a "collision shape" into a BodyNode somewhere. With the arrival of ShapeNode, we can no longer pass shapes directly into a BodyNode; instead, we need to pass the Shape object into a ShapeNode which is attached to a BodyNode. As you've noted, the ShapeNode will allow you to change the offset of the Shape. If the floor is going to be used for collision detection in simulations, then this pipeline must exist somewhere.

However, if you're talking about arbitrary planes that are put into a scene for rendering purposes (which do not need to be a part of any simulation), then you can pass the Shape object into a SimpleFrame instead. SimpleFrame offers the ShapeFrame API (which ShapeNode is also derived from), but unlike ShapeNode, the SimpleFrame is not tied to a BodyNode, so you have complete freedom to do whatever you want with it. However, we recommend storing SimpleFrames in shared_ptrs, so you'll need to store that shared_ptr somewhere. I would suggest adding it to the dart::simulation::World instance using the World::addSimpleFrame(~) function. That way the SimpleFrame instance will persist as long as a reference to the world exists.

Obviously none of this helps with having a genuine PlaneShape class, but I think it addresses the specific problem you've run into. If I'm wrong about that, please let me know.

jslee02 commented 7 years ago

@mxgrey made a good point. BoxShape, for example, only contains the geometry information while ShapeNode (or ShapeFrame) provides the relative transformation including the geometry information as it holds a pointer to BoxShape.

I guess the problem is that the Gazebo data structure for plane shape holds BoxShape rather than ShapeNode so you can't change the relative transformation through BoxShape (there is no way to get ShapeNode from BoxShape). For this case, I think it would make more sense to change DARTPlaneShapePrivate to hold ShapeNode.

mxgrey commented 7 years ago

I'm not sure that DARTPlaneShapePrivate could hold a ShapeNode in any meaningful way without also holding a BodyNodePtr to go along with it. Otherwise, what BodyNode does the ShapeNode instance belong to?

Does the DARTPlaneShapePrivate::dtBoxShape get recycled (e.g. used by multiple different BodyNodes)? If so, perhaps instead of just having a DARTPlaneShapePrivate::dtBoxShape, there should be a utility function like DARTPlaneShapePrivate::addPlaneShape(BodyNode*) const which takes in a BodyNode pointer and adds a ShapeNode to it with the dtBoxShape object and the appropriate offset.

jslee02 commented 7 years ago

Right, I should take back what I said. After looking more closely, it would be better that DARTCollisionPrivate holds ShapeNode. DARTCollisionPrivate takes the parent link point and never change it so it's guaranteed that it always holds the corresponding body node pointer. @mxgrey How do you think?

DARTCollision (the owner of DARTCollisionPrivate) is very similar to ShapeFrame in terms of that it is a frame (that has the parent with relative transform) and holds a shape for the collision geometry. One difference is that it holds only one shape.

It seems it's possible to recycle DARTPlaneShapePrivate::dtBoxShape as it's stored in a shared pointer, but I haven't seen the case yet at least from my experience.

JenniferBuehler commented 7 years ago

Thanks for your quick responses!

Yes, I refer to the "fake plane" to be used as collision shape in place of any plane. The DARTPlaneShapePrivate creates it (and wants to set the offset), and its owner DARTPlaneShape then passes it to its parent, which is a DARTCollision object. DARTCollision takes only Shape objects in the current version, and therefore would need to be changed as well... So I agree with the suggestion by @jslee02: if I understand correctly, DARTCollision/DARTCollisionPrivate will have to be adjusted for the new DART version, and should now use ShapeNode instead of Shape? If you agree, I will make these changes.

As @mxgrey pointed out, a BodyNode will be required to create the ShapeNode - and DARTPlaneShapePrivate which creates the fake plane box, does not know any BodyNode. I would suggest the following: DARTPlaneShapeconstructor (the not deprecated version) gets a DARTCollision refrence, which in turn has a DARTCollision::GetDARTBodyNode(). So it could pass the BodyNode returned by that function into the DARTPlaneShapePrivate constructor, which it then can use to create the ShapeNode. Not sure if by this point the BodyNode returned would already be instantiated, that would have to be asserted. Would that make sense, or am I missing something?

mxgrey commented 7 years ago

That sounds reasonable to me :+1:

Hopefully there isn't a scenario where DARTCollision would be lacking a BodyNode before the DARTPlaneShape is created, but I don't know enough about Gazebo's pipeline to guess how reasonable that expectation is.

jslee02 commented 7 years ago

If you agree, I will make these changes.

:+1:

JenniferBuehler commented 7 years ago

Hmmm that's actually a good point @mxgrey, I'm just looking at this now... we may have to do all this in the DARTCollision::Load() method to ensure that a valid BodyNode exists, though maybe it has already be loaded in the Link.. I'll look into this. I'm also just getting acquainted with the interfaces, but this seems like stuff that can be solved without major headaches (knock on wood). Just wanted to check that you agree before I start doing the changes.

Thanks!

azeey commented 5 years ago

PlaneShape was added by 4d19d60 but only BulletCollisionDetector supports the PlaneShape.

We recently changed our implementation to use PlaneShape instead of BoxShape for planes. We discovered that meshes don't collide with planes properly when using BulletCollisionDetector. Has anyone tried that before? The same mesh-plane collisions work properly when using OdeCollisionDetector though.