Files
bullet3/Demos3/bullet2/MultiBodyDemo/MultiBodyVehicle.cpp
Erwin Coumans eac8b32782 add very basic multibody vehicle
tweak finite element experiment with parameter
2014-10-31 14:14:45 -07:00

237 lines
7.7 KiB
C++

//test addJointTorque
#include "MultiBodyVehicle.h"
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
#include "BulletDynamics/Featherstone/btMultiBody.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
#include "BulletDynamics/Featherstone/btMultiBodyLink.h"
#include "BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h"
#include "BulletDynamics/Featherstone/btMultiBodyJointMotor.h"
#include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h"
#include "BulletCollision/CollisionShapes/btBoxShape.h"
btScalar gVehicleBaseMass = 100.f;
btScalar gVehicleWheelMass = 5.f;
float friction = 1.f;
btVector3 gVehicleBaseHalfExtents(1, 0.1, 2);
btVector3 gVehicleWheelHalfExtents(0.2, 0.2, 0.2);
btVector3 gVehicleWheelOffset(0, 0, 0.5);
btVector3 wheelAttachmentPosInWorld[4] = {
btVector3(1, 0, 2.),
btVector3(-1, 0, 2.),
btVector3(1, 0, -2.),
btVector3(-1, 0, -2.)
};
MultiBodyVehicleSetup::MultiBodyVehicleSetup()
{
}
MultiBodyVehicleSetup::~MultiBodyVehicleSetup()
{
}
class btMultiBody* MultiBodyVehicleSetup::createMultiBodyVehicle()
{
class btMultiBodyDynamicsWorld* world = m_dynamicsWorld;
int numWheels = 4;
int totalLinks = numWheels;//number of body parts (links) (in)directly attached to the base, NOT including the base/root itself
btCollisionShape* chassis = new btBoxShape(gVehicleBaseHalfExtents);//CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS));
m_collisionShapes.push_back(chassis);
btCollisionShape* wheel = new btCylinderShapeX(gVehicleWheelHalfExtents);//CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS));
m_collisionShapes.push_back(wheel);
btVector3 baseLocalInertia(0, 0, 0);
chassis->calculateLocalInertia(gVehicleBaseMass, baseLocalInertia);
bool multiDof = false;
bool isFixedBase = false;
bool canSleep = false;
btMultiBody * bod = new btMultiBody(totalLinks, gVehicleBaseMass, baseLocalInertia, isFixedBase, canSleep);// , multiDof);
bod->setHasSelfCollision(false);
btQuaternion baseOrn(0, 0, 0, 1);
btVector3 basePos(0, 0, 0);
bod->setBasePos(basePos);
bod->setWorldToBaseRot(baseOrn);
btVector3 vel(0, 0, 0);
bod->setBaseVel(vel);
{
int linkNum = 0;
btVector3 wheelJointAxisWorld(1, 0, 0);
btQuaternion parent_to_child = baseOrn.inverse();//??
for (int j = 0; j < numWheels; j++, linkNum++)
{
int parent_link_num = -1;
float initial_joint_angle = 0.0;
btVector3 localWheelInertia(0, 0, 0);
wheel->calculateLocalInertia(gVehicleWheelMass, localWheelInertia);
bool disableParentCollision = true;
btVector3 pivotToChildCOM(0, 0, 0.25);
btVector3 pivotToWheelCOM(0, 0, 0);
{
bod->setupRevolute(linkNum, gVehicleWheelMass, localWheelInertia, parent_link_num, parent_to_child, wheelJointAxisWorld,
wheelAttachmentPosInWorld[j], pivotToWheelCOM, disableParentCollision);
}
bod->setJointPos(linkNum, initial_joint_angle);
if (j<2)
{
btMultiBodyJointMotor* con = new btMultiBodyJointMotor(bod, linkNum, 1., 50);
world->addMultiBodyConstraint(con);
}
}
}
//add a collider for the base
{
btAlignedObjectArray<btQuaternion> world_to_local;
world_to_local.resize(totalLinks + 1);
btAlignedObjectArray<btVector3> local_origin;
local_origin.resize(totalLinks + 1);
world_to_local[0] = bod->getWorldToBaseRot();
local_origin[0] = bod->getBasePos();
{
float pos[4] = { local_origin[0].x(), local_origin[0].y(), local_origin[0].z(), 1 };
float quat[4] = { -world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w() };
if (1)
{
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(bod, -1);
col->setCollisionShape(chassis);
btTransform tr;
tr.setIdentity();
tr.setOrigin(local_origin[0]);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
world->addCollisionObject(col, btBroadphaseProxy::DefaultFilter, btBroadphaseProxy::AllFilter);// 2, 1 + 2);
col->setFriction(friction);
bod->setBaseCollider(col);
}
}
//initialize local coordinate frames, relative to parent
for (int i = 0; i<bod->getNumLinks(); i++)
{
const int parent = bod->getParent(i);
world_to_local[i + 1] = bod->getParentToLocalRot(i) * world_to_local[parent + 1];
local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), bod->getRVector(i)));
}
int linkIndex = 0;
for (int j = 0; j<numWheels; j++, linkIndex++)
{
btVector3 posr = local_origin[linkIndex + 1];
float pos[4] = { posr.x(), posr.y(), posr.z(), 1 };
float quat[4] = { -world_to_local[linkIndex + 1].x(), -world_to_local[linkIndex + 1].y(), -world_to_local[linkIndex + 1].z(), world_to_local[linkIndex + 1].w() };
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(bod, linkIndex);
col->setCollisionShape(wheel);
btTransform tr;
tr.setIdentity();
tr.setOrigin(posr);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
col->setFriction(friction);
world->addCollisionObject(col, btBroadphaseProxy::DefaultFilter, btBroadphaseProxy::AllFilter);// 2, 1 + 2);
bod->getLink(linkIndex).m_collider = col;
}
}
world->addMultiBody(bod);
// world->setGravity(btVector3(0,0,0));
return bod;
}
void MultiBodyVehicleSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge)
{
int upAxis = 1;
btVector4 colors[4] =
{
btVector4(1,0,0,1),
btVector4(0,1,0,1),
btVector4(0,1,1,1),
btVector4(1,1,0,1),
};
int curColor = 0;
gfxBridge.setUpAxis(upAxis);
this->createEmptyDynamicsWorld();
gfxBridge.createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(
//btIDebugDraw::DBG_DrawConstraints
+btIDebugDraw::DBG_DrawWireframe
+btIDebugDraw::DBG_DrawContactPoints
+btIDebugDraw::DBG_DrawAabb
);//+btIDebugDraw::DBG_DrawConstraintLimits);
createMultiBodyVehicle();
if (1)
{
btVector3 groundHalfExtents(20,20,20);
groundHalfExtents[upAxis]=1.f;
btBoxShape* box = new btBoxShape(groundHalfExtents);
box->initializePolyhedralFeatures();
gfxBridge.createCollisionShapeGraphicsObject(box);
btTransform start; start.setIdentity();
btVector3 groundOrigin(0,0,0);
groundOrigin[upAxis]=-1.5;
start.setOrigin(groundOrigin);
btRigidBody* body = createRigidBody(0,start,box);
btVector4 color = colors[curColor];
curColor++;
curColor&=3;
gfxBridge.createRigidBodyGraphicsObject(body,color);
}
}
void MultiBodyVehicleSetup::stepSimulation(float deltaTime)
{
m_dynamicsWorld->stepSimulation(deltaTime);
}