[ODE] Bug either in ODE or in implementation (more likely?)

Simon Barratt Barog at pineapple-interactive.com
Thu Mar 17 10:53:43 MST 2005


Hi,

> n = dCollide(o1, o2, 1, &contact, sizeof(contact));

Your thought was correct, this is just asking for one contact to be
returned what you should do is ask for an array, OPCODE returns all the
hits with that ray vs trimesh as obviously it's not its job to sort them
out for you or deal with them.

So pass in a larger number of contacts into dCollide (the value 1 is the
number of contacts, it's actually a flags value but the mask for number
of contacts is 0xffff). Then find the nearest hit from your array of
returned 'n' contacts and use that as your ray 't'.

Good luck

--
Simon Barratt, Lead Developer, Pineapple Interactive Ltd
e: barog at pineapple-interactive.com
w: http://www.pineapple-interactive.com
t: +44 (0)1274 480185
 

> -----Original Message-----
> From: ode-bounces at q12.org [mailto:ode-bounces at q12.org] On 
> Behalf Of Sawyer
> Sent: 17 March 2005 03:06
> To: ode at q12.org
> Subject: [ODE] Bug either in ODE or in implementation (more likely?)
> 
> 
> These are the only two functions that ask ode for collision 
> information.  Also as far as I can tell gazebo is basically 
> returning the depth of a random triangle collision depending 
> on what order they are processed in.  I have not seen 
> problems with any object type other than trimesh.  Any help 
> is greatly appreciated.
> 
> Here is the code block from gazebo dealing with collisions:
> in file: RayProximity.cc
> //////////////////////////////////////////////////////////////
> ////////////////
> // Update the sensor information
> void RayProximity::Update()
> {
>   int i;
>   GzPose pose;
>   RayGeom *ray;
>   GzVector a, b;
> 
>   // Get the pose of the sensor body (global cs)
>   pose = this->body->GetPose();
> 
>   // Reset the ray lengths and mark the geoms as dirty (so they get
>   // redrawn)
>   for (i = 0; i < this->rayCount; i++)
>   {
>     ray = this->rays[i];
>     ray->dirty = true;
>     ray->contactDepth = DBL_MAX;
>     ray->contactRetro = 0.0;
>     ray->contactFiducial = -1;
> 
>     // Update the ray endpoints (global cs)
>     a = GzCoordPositionAdd(ray->pos_a, pose.pos, pose.rot);
>     b = GzCoordPositionAdd(ray->pos_b, pose.pos, pose.rot);
>     ray->Set(a, GzVectorUnit(GzVectorSub(b, a)));
>   }
> 
>   // Do collision detection
>   dSpaceCollide2( ( dGeomID ) ( this->superSpaceId ),
>                   ( dGeomID ) ( this->world->GetSpaceId() ),
>                   this, &UpdateCallback );
> 
>   return;
> }
> 
> //////////////////////////////////////////////////////////////
> ////////////////
> // Callback for ray intersection test
> void RayProximity::UpdateCallback( void *data, dGeomID o1, 
> dGeomID o2 ) {
>   int n;
>   dContactGeom contact;
>   Geom *geom1, *geom2;
>   RayGeom *rayGeom;
>   Geom *hitGeom;
>   RayProximity *self;
> 
>   self = (RayProximity*) data;
> 
>   // Check space
>   if ( dGeomIsSpace( o1 ) || dGeomIsSpace( o2 ) )
>   {
>     if (dGeomGetSpace(o1) == self->superSpaceId || 
> dGeomGetSpace(o2) == 
> self->superSpaceId)
>     {
>       dSpaceCollide2( o1, o2, self, &UpdateCallback );
>     }
>     if (dGeomGetSpace(o1) == self->raySpaceId || dGeomGetSpace(o2) == 
> self->raySpaceId)
>     {
>       dSpaceCollide2( o1, o2, self, &UpdateCallback );
>     }
>   }
>   else
>   {
>     geom1 = NULL;
>     geom2 = NULL;
> 
>     // Get pointers to the underlying geoms
>     if (dGeomGetClass(o1) == dGeomTransformClass)
>       geom1 = (Geom*) dGeomGetData(dGeomTransformGetGeom(o1));
>     else
>       geom1 = (Geom*) dGeomGetData(o1);
> 
>     if (dGeomGetClass(o2) == dGeomTransformClass)
>       geom2 = (Geom*) dGeomGetData(dGeomTransformGetGeom(o2));
>     else
>       geom2 = (Geom*) dGeomGetData(o2);
> 
>     assert(geom1 && geom2);
> 
>     rayGeom = NULL;
>     hitGeom = NULL;
> 
>     // Figure out which one is a ray; note that this assumes
>     // that the ODE dRayClass is used *soley* by the RayGeom.
>     if (dGeomGetClass(o1) == dRayClass)
>     {
>       rayGeom = (RayGeom*) geom1;
>       hitGeom = geom2;
>     }
> 
>     if (dGeomGetClass(o2) == dRayClass)
>     {
>       assert(rayGeom == NULL);
>       rayGeom = (RayGeom*) geom2;
>       hitGeom = geom1;
>     }
> 
>     // Check for ray/geom intersections
>     if ( rayGeom && hitGeom )
>     {
>       n = dCollide(o1, o2, 1, &contact, sizeof(contact));
>       if ( n > 0 )
>       {
>         if (contact.depth < rayGeom->contactDepth)
>         {
>           //printf("%p %p %f \n", o1, o2, contact.depth);
>           rayGeom->contactDepth = contact.depth;
>           rayGeom->contactRetro = hitGeom->GetRetro();
>           rayGeom->contactFiducial = hitGeom->GetFiducial();
>         }
>       }
>     }
>   }
>   return;
> }
> 
> Thanks again,
> Sawyer Larkin
> 
> _______________________________________________
> ODE mailing list
> ODE at q12.org
> http://q12.org/mailman/listinfo/ode
> 
> 
> 
> 





More information about the ODE mailing list