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

Ed Jones ed.jones at oracle.com
Fri Mar 18 12:44:26 MST 2005


I love you!

I was hitting exactly this problem myself last night.
The issue is that the docs say;

"Calling dCollide between a ray and another geom will result in at most 
one contact point."

I foolishly assumed that this meant the closest contact point would be 
returned, and soon realised that that's not what it does.
I'd just decided to ignore that documentation, generate lots of contacts 
and sort them myself.

However, now I can use this undocumented feature, Hurrah!

Cheers,
Ed.



Simon Barratt wrote:

>That'll teach me to not check the actual code, as Adam pointed out
>OPCODE does have a closest hit feature. 
>you can use the dGeomRaySetClosestHit (dGeomID g, int closestHit) and
>the dCollide function you had should return the contact you desired.
>
>Cheers
>
>--
>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: Simon Barratt 
>>Sent: 17 March 2005 10:38
>>To: 'ode at q12.org'
>>Subject: RE: [ODE] Bug either in ODE or in implementation 
>>(more likely?)
>>
>>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
>>>
>>>
>>>
>>>
>>>      
>>>
>
>
>
>_______________________________________________
>ODE mailing list
>ODE at q12.org
>http://q12.org/mailman/listinfo/ode
>  
>


More information about the ODE mailing list