Update of /cvsroot/playerstage/code/gazebo/server/physics/ode
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11622/server/physics/ode
Added Files:
Tag: ogre
ODEPhysics.cc ODEPhysics.hh SConscript
Log Message:
Added new gazebo files
--- NEW FILE: ODEPhysics.hh ---
#ifndef ODEPHYSICS_HH
#define ODEPHYSICS_HH
#include <ode/ode.h>
#include <map>
#include "PhysicsEngine.hh"
class SphereGeom;
class PlaneGeom;
class BoxGeom;
class CylinderGeom;
class Body;
class Entity;
class ODEPhysics : public PhysicsEngine
{
// Constructor
public: ODEPhysics();
// Destructor
public: virtual ~ODEPhysics();
// Load the ODE engine
public: virtual int Load();
// Initialize the ODE engine
public: virtual int Init();
//Update the ODE engine
public: virtual int Update();
//Finilize the ODE engine
public: virtual int Fini();
// Add an entity
public: virtual int AddEntity(Entity *entity);
// Create a new body
public: virtual Body *CreateBody(Entity *parent);
// Create a new joint
public: virtual Joint *CreateJoint(Joint::Type type);
// Do collision detection
private: static void CollisionCallback( void *data, dGeomID o1, dGeomID o2);
// Top-level world for all bodies
private: dWorldID worldId;
// Top-level space for all sub-spaces/geoms
private: dSpaceID spaceId;
// Collision attributes
private: dJointGroupID contactGroup;
// Simulation step time
private: double stepTime;
protected: std::map<int, Entity*> entities;
};
#endif
--- NEW FILE: SConscript ---
#Import variable
Import('env staticObjs sharedObjs')
sources = Split('ODEPhysics.cc')
staticObjs.append(env.StaticObject('ODEPhysics.cc'))
sharedObjs.append(env.SharedObject('ODEPhysics.cc'))
--- NEW FILE: ODEPhysics.cc ---
#include <assert.h>
#include "Global.hh"
#include "Geom.hh"
#include "Body.hh"
#include "ContactParams.hh"
#include "Entity.hh"
#include "SliderJoint.hh"
#include "HingeJoint.hh"
#include "Hinge2Joint.hh"
#include "BallJoint.hh"
#include "UniversalJoint.hh"
#include "ODEPhysics.hh"
// Constructor
ODEPhysics::ODEPhysics()
: PhysicsEngine()
{
this->worldId = dWorldCreate();
this->spaceId = dSimpleSpaceCreate(0);
this->contactGroup = dJointGroupCreate(0);
this->stepTime = 0.02;
}
// Destructor
ODEPhysics::~ODEPhysics()
{
dSpaceDestroy(this->spaceId);
dWorldDestroy(this->worldId);
this->spaceId = NULL;
this->worldId = NULL;
}
// Load the ODE engine
int ODEPhysics::Load()
{
return 0;
}
// Initialize the ODE engine
int ODEPhysics::Init()
{
dWorldSetGravity(this->worldId, 0.0, -9.8, 0.0);
return 0;
}
//Update the ODE engine
int ODEPhysics::Update()
{
// Do collision detection; this will add contacts to the contact group
dSpaceCollide( this->spaceId, this, CollisionCallback );
// Update the dynamical model
dWorldStep( this->worldId, this->stepTime );
//dWorldStepFast1( this->worldId, step, 10 );
// Very important to clear out the contact group
dJointGroupEmpty( this->contactGroup );
return 0;
}
//Finilize the ODE engine
int ODEPhysics::Fini()
{
return 0;
}
// Add an entity
int ODEPhysics::AddEntity(Entity *entity)
{
// Only the top level parent should have a new space
if (entity->GetParent() == NULL)
{
entity->spaceId = dSimpleSpaceCreate(this->spaceId);
}
else
{
entity->spaceId = entity->GetParent()->spaceId;
}
this->entities[entity->GetId()] = entity;
}
// Create a new body
Body *ODEPhysics::CreateBody(Entity *parent)
{
return new Body(parent, this->worldId);
}
// Create a new joint
Joint *ODEPhysics::CreateJoint(Joint::Type type)
{
switch (type)
{
case Joint::SLIDER:
return new SliderJoint(this->worldId);
case Joint::HINGE:
return new HingeJoint(this->worldId);
case Joint::HINGE2:
return new Hinge2Joint(this->worldId);
case Joint::BALL:
return new BallJoint(this->worldId);
case Joint::UNIVERSAL:
return new UniversalJoint(this->worldId);
}
}
void ODEPhysics::CollisionCallback( void *data, dGeomID o1, dGeomID o2)
{
int i,n;
ODEPhysics *self;
Geom *geom1, *geom2;
dContactGeom contactGeoms[10];
dContact contactInfo;
dJointID joint;
int num;
self = (ODEPhysics*) data;
// Maximum number of contacts
num = sizeof(contactGeoms) / sizeof(contactGeoms[0]);
// If either geom is a space...
if (dGeomIsSpace( o1 ) || dGeomIsSpace( o2 ))
{
// If the spaces/geoms belong to different spaces, collide them
if (dGeomGetSpace(o1) != dGeomGetSpace(o2))
dSpaceCollide2( o1, o2, self, &CollisionCallback );
// If the spaces belong the world space, collide them
else if (dGeomGetSpace(o1) == self->spaceId || dGeomGetSpace(o2) ==
self->spaceId)
dSpaceCollide2( o1, o2, self, &CollisionCallback );
}
else
{
// There should be no geoms in the world space
assert(dGeomGetSpace(o1) != self->spaceId);
assert(dGeomGetSpace(o2) != self->spaceId);
// We should never test two geoms in the same space
assert(dGeomGetSpace(o1) != dGeomGetSpace(o2));
// Get pointers to the underlying geoms
geom1 = NULL;
if (dGeomGetClass(o1) == dGeomTransformClass)
geom1 = (Geom*) dGeomGetData(dGeomTransformGetGeom(o1));
else
geom1 = (Geom*) dGeomGetData(o1);
geom2 = NULL;
if (dGeomGetClass(o2) == dGeomTransformClass)
geom2 = (Geom*) dGeomGetData(dGeomTransformGetGeom(o2));
else
geom2 = (Geom*) dGeomGetData(o2);
assert(geom1 && geom2);
// Detect collisions betweed geoms
n = dCollide(o1, o2, num, contactGeoms, sizeof(contactGeoms[0]));
for (i=0; i < n; i++)
{
dBodyID body1 = dGeomGetBody(contactGeoms[i].g1);
dBodyID body2 = dGeomGetBody(contactGeoms[i].g2);
// Dont add contact joints between already connected bodies.
// Sometimes the body is unspecified; should probably figure out
// what this means
if (body1 && body2)
if (dAreConnectedExcluding(body1, body2, dJointTypeContact))
continue;
contactInfo.geom = contactGeoms[i];
contactInfo.surface.mode = 0;
// Compute the CFM and ERP by assuming the two bodies form a
// spring-damper system.
double h, kp, kd;
h = self->stepTime;
kp = 1 / (1 / geom1->contact->kp + 1 / geom2->contact->kp);
kd = geom1->contact->kd + geom2->contact->kd;
contactInfo.surface.mode |= dContactSoftERP | dContactSoftCFM;
contactInfo.surface.soft_erp = h * kp / (h * kp + kd);
contactInfo.surface.soft_cfm = 1 / (h * kp + kd);
/*
printf("%f %f %f %f \n",
kp, kd,
contactInfo.surface.soft_erp,
contactInfo.surface.soft_cfm);
*/
// Compute friction effects; this is standard Coulomb friction
contactInfo.surface.mode |= dContactApprox1;
contactInfo.surface.mu = MIN(geom1->contact->mu1, geom2->contact->mu1);
// Compute slipping effects
//contactInfo.surface.slip1 = (geom1->contact->slip1 +
geom2->contact->slip1)/2.0;
//contactInfo.surface.slip2 = (geom1->contact->slip2 +
geom2->contact->slip2)/2.0;
// Construct a contact joint between the two bodies
joint = dJointCreateContact(self->worldId, self->contactGroup,
&contactInfo);
dJointAttach(joint, body1, body2);
}
}
return;
}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit