We have created a sensor representation of a BoxGeom in Gazebo and we'd like to 
test when this box collides with RayGeoms which are being emitted from a laser 
on another robot.  Currently the only collisions we're getting are between 
class types 7&7 or 4&7 which are GeomTransforms and GeomPlanes.  Any ideas on 
what we could be doing wrong?  I've attached our code.  Because we've been 
trying to many things, some parts may be commented out.  We tried to base our 
sensor off the gazebo ray sensor.

Thanks.
~Lexi
/*
 *  Gazebo - Outdoor Multi-Robot Simulator
 *  Copyright (C) 2003
 *     Nate Koenig & Andrew Howard
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
/* Desc: Ear proximity sensor
 * Author: Carle Cote
 * Date: 23 february 2004
 * SVN: $Id: EarSensor.cc 6965 2008-08-20 21:53:33Z natepak $
*/

#include <assert.h>
#include <float.h>
#include <sstream>

#include "SensorFactory.hh"
#include "XMLConfig.hh"
#include "Global.hh"
#include "RayGeom.hh"
#include "World.hh"
#include "PhysicsEngine.hh"
#include "GazeboError.hh"
#include "ODEPhysics.hh"
#include "XMLConfig.hh"
#include "Controller.hh"
#include "EarSensor.hh"
#include "BoxGeom.hh"

#include "Vector3.hh"

using namespace gazebo;

GZ_REGISTER_STATIC_SENSOR("ear", EarSensor);

//////////////////////////////////////////////////////////////////////////////
// Constructor
EarSensor::EarSensor(Body *body)
    : Sensor(body)
{
        this->active = false;

        this->typeName = "ear";

        this->rangeCountP = new Param<int>("rangeCount",0,1);
        this->minRangeP = new Param<double>("minRange",0,1);
        this->maxRangeP = new Param<double>("maxRange",0,1);
        this->originP = new Param<Vector3>("origin", Vector3(0,0,0), 0);
}


//////////////////////////////////////////////////////////////////////////////
// Destructor
EarSensor::~EarSensor()
{
        delete this->rangeCountP;
        delete this->minRangeP;
        delete this->maxRangeP;
        delete this->originP;
}

//////////////////////////////////////////////////////////////////////////////
/// Load the ray using parameter from an XMLConfig node
void EarSensor::LoadChild(XMLConfigNode *node)
{
        if (this->body == NULL) {
                gzthrow("Null body in the ear sensor");
        }

        this->rangeCountP->Load(node);
        this->minRangeP->Load(node);
        this->maxRangeP->Load(node);
        this->originP->Load(node);


        // Create a space to contain the ray space
        this->superSpaceId = dSimpleSpaceCreate( 0 );

        // Create a space to contain all the rays
        this->raySpaceId = dSimpleSpaceCreate( this->superSpaceId );
        //this->raySpaceId = dSimpleSpaceCreate( 0 );

        //this->superSpaceId = dSimpleSpaceCreate( this->raySpaceId );

        // Set collision bits
        //dGeomSetCategoryBits((dGeomID) this->superSpaceId, GZ_ALL_COLLIDE); 
//GZ_ALL_COLLIDE
        //dGeomSetCollideBits((dGeomID) this->superSpaceId, GZ_ALL_COLLIDE);
        
        dGeomSetCategoryBits((dGeomID) this->raySpaceId, GZ_ALL_COLLIDE); 
//GZ_ALL_COLLIDE
        dGeomSetCollideBits((dGeomID) this->raySpaceId, ~GZ_ALL_COLLIDE);

        this->body->spaceId = this->raySpaceId;
        //this->body->spaceId = this->superSpaceId;

}

//////////////////////////////////////////////////////////////////////////////
/// Save the sensor info in XML format
void EarSensor::SaveChild(std::string &prefix, std::ostream &stream)
{
        stream << prefix << "  " << *(this->minRangeP) << "\n";
        stream << prefix << "  " << *(this->maxRangeP) << "\n";
        stream << prefix << "  " << *(this->originP) << "\n";
        stream << prefix << "  " << *(this->rangeCountP) << "\n";
}

//////////////////////////////////////////////////////////////////////////////
// Init the ray
void EarSensor::InitChild()
{
        Pose3d bodyPose;
        double angle;
        Vector3 start, end, axis,size;
        //RayGeom *ray;

        bodyPose = this->body->GetPose();
        this->prevPose = bodyPose;

        //Don't want to send rays out into the environment; just want to detect 
when a ray hits location originP

        //sensorRep = dCreateBox(dSpaceID space, dReal lx, dReal ly, dReal lz);
        sensorRep = new BoxGeom(this->body);
        size.Set(1,1,1);
        sensorRep->SetSize(size);
        //sensorRep->SetCategoryBits( GZ_ALL_COLLIDE );
        //sensorRep->SetCollideBits(~GZ_ALL_COLLIDE );
        //this->body->AttachGeom(sensorRep);
}

//////////////////////////////////////////////////////////////////////////////
// Init the ray
void EarSensor::FiniChild()
{
}

//////////////////////////////////////////////////////////////////////////////
/// Get the minimum range
double EarSensor::GetMinRange() const
{
  return this->minRangeP->GetValue();
}

//////////////////////////////////////////////////////////////////////////////
///  Get the maximum range
double EarSensor::GetMaxRange() const
{
        return this->maxRangeP->GetValue();
}


//////////////////////////////////////////////////////////////////////////////
/// Get the range count
int EarSensor::GetRangeCount() const
{
  //return this->rangeCountP->GetValue();
  return this->ranges.size();
}

//////////////////////////////////////////////////////////////////////////////
// Get detected range for a ray
double EarSensor::GetRange(int index)
{
        if (index < 0 || index >= (int)this->ranges.size()) {
                std::ostringstream stream;
                stream << "index[" << index << "] out of range[0-" << 
this->ranges.size() << "]";
                gzthrow(stream.str());
        }

        return this->ranges[index];
}


//////////////////////////////////////////////////////////////////////////////
// Get detected retro (intensity) value for a ray.
double EarSensor::GetRetro(int index)
{
        if (index < 0 || index >= (int)this->intensity.size()) {
                std::ostringstream stream;
                stream << "index[" << index << "] out of range[0-" << 
this->intensity.size() << "]";
                gzthrow(stream.str());
        }

        return this->intensity[index];
}


 //////////////////////////////////////////////////////////////////////////////
 // Update the sensor information
void EarSensor::UpdateChild()
{
        Pose3d poseDelta;
        Vector3 a, b;

        // Get the pose of the sensor body (global cs)
        poseDelta = this->body->GetPose() - this->prevPose;
        this->prevPose = this->body->GetPose();

        ODEPhysics *ode = 
dynamic_cast<ODEPhysics*>(World::Instance()->GetPhysicsEngine());

        if (ode == NULL) {
                gzthrow( "Invalid physics engine. Must use ODE." );
        }

        // Do collision detection
        //std::cout<<(( dGeomID )this->raySpaceId)<<" "<<( dGeomID 
)this->superSpaceId<<" "<<( dGeomID )ode->GetSpaceId()<<std::endl;
        dSpaceCollide2( ( dGeomID ) ( this->superSpaceId ),
                                        ( dGeomID ) ( ode->GetSpaceId() ),
                                        this, &UpdateCallback );
        // }
}



/////////////////////////////////////////////////////////////////////////////
// Callback for ray intersection test
void EarSensor::UpdateCallback( void *data, dGeomID o1, dGeomID o2 )
{
        int n = 0;
        dContactGeom contact;
        dxGeom *geom1, *geom2 = NULL;
        RayGeom *rayGeom = NULL;
        Geom *hitGeom = NULL;
        EarSensor *self = (EarSensor*) data;
        const double delta = 0.2;
        
        /**********************************
        % dSphereClass          0   Sphere
        % dBoxClass             1   Box
        % dCapsuleClass         2       Capsule (i.e. cylinder with half-sphere 
caps at its ends)
        % dCylinderClass        3       Regular flag ended Cylinder
        % dPlaneClass           4   Infinite plane (non-placeable)
        % dRayClass             5   Ray
        % dConvexClass          6       
        % dGeomTransformClass   7       Geometry transform
        % dTrimeshClass         8       Triangle mesh

   **********************************/
        
        
        
        
        
        

        // 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 = (dxGeom*) 
dGeomGetData(dGeomTransformGetGeom(o1));
                else
                        geom1 = (dxGeom*) dGeomGetData(o1);

                if (dGeomGetClass(o2) == dGeomTransformClass)
                        geom2 = (dxGeom*) 
dGeomGetData(dGeomTransformGetGeom(o2));
                else
                        geom2 = (dxGeom*) dGeomGetData(o2);

                assert(geom1 && geom2);

                std::cout<<"dgeomgetclass = "<<dGeomGetClass(o1)<<' 
'<<dGeomGetClass(o2)<<std::endl;

                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 = (Geom*) geom2;

                        dGeomRaySetParams(o1, 0, 0);
                        dGeomRaySetClosestHit(o1, 1);
                }

                if (dGeomGetClass(o2) == dRayClass) {
                        assert(rayGeom == NULL);
                        rayGeom = (RayGeom*) geom2;
                        hitGeom = (Geom* )geom1;
                        dGeomRaySetParams(o2, 0, 0);
                        dGeomRaySetClosestHit(o2, 1);
                }

                //std::cout<<"geomclass = "<<dGeomGetClass(o1)<<' 
'<<dGeomGetClass(o2)<<' '<<dRayClass<<' '<<dBoxClass<<std::endl;

                // Check for ray/geom intersections
                if ( rayGeom && hitGeom ) {

                        n = dCollide(o1, o2, 1, &contact, sizeof(contact));
                        std::cout<<"dcollide = "<<n<<std::endl;
                        if ( n > 0 ) {
                                //if (contact.depth < rayGeom->GetLength())
                                //{
                                //rayGeom->SetLength( contact.depth );
                                //rayGeom->SetRetro( hitGeom->GetLaserRetro() );
                                int Hit=true;
                                double p;
                                for(int i=0;i<2;i++) {
                                        p = self->originP->GetValue()[i];
                                        if(fabs(contact.pos[i]-p)>delta) {
                                                Hit=false;
                                                break;
                                        }
                                }
                                std::cout<<"Hit: "<<Hit<<std::endl;
                                if (Hit) {
                                        
self->AddSound(contact.depth,hitGeom->GetLaserRetro());
                                        //rayGeom->SetFiducial( 
hitGeom->GetLaserFiducialId() );
                                }
                        }
                }
        }
}

void EarSensor::AddSound(double newrange, double newinten)
{
        this->ranges.push_back(newrange);
        this->intensity.push_back(newinten);
}
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Playerstage-gazebo mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-gazebo

Reply via email to