Problem about simulating rigid body rotation with bullet physics engine

Post Reply
mggsco
Posts: 1
Joined: Sun Jun 10, 2018 12:58 pm

Problem about simulating rigid body rotation with bullet physics engine

Post by mggsco » Sun Jun 10, 2018 1:06 pm

I want to simulate an object imposed by a torque T={1,1,1} with reference to the world frame. The mass of the object is 1Kg, and its diagonal elements of inertia tensor is {2, 1, 1}. However bullet2.7 and bullet2.8 give me totally different results. Which one is correct and why?

Code: Select all

#include <btBulletDynamicsCommon.h>  
#include <stdio.h>
#include <iostream>
#include <fstream> 
using namespace std;

/// This is a Hello World program for running a basic Bullet physics simulation

int main(int argc, char** argv)
{

btBroadphaseInterface* broadphase = new btDbvtBroadphase();

///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();

///use the default collision dispatcher. For parallel processing you can use a differnt dispatcher
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);

///the default constraint solver. For parallel processing you can use a different solver
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

///instantiate the dynamics world
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);

///sets the gravity
dynamicsWorld->setGravity(btVector3(0, 0, 0));


btCollisionShape* Shape = new btSphereShape(1);


//The btTransform class supports rigid transforms with only translation and rotation 
btDefaultMotionState* MotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 50, 0)));

btScalar mass = 1;
btVector3 Inertia(2, 1, 1);
btVector3 torque(1, 1, 1);
btVector3 angularVelocity(0, 0, 0);

///when bodies are constructed, they are passed certain parameters. This is done through a special structure Bullet provides for this.
///rigid body is dynamic if and only if mass is non zero, otherwise static  
btRigidBody::btRigidBodyConstructionInfo RigidBodyCI(mass, MotionState, Shape, Inertia);
btRigidBody* RigidBody = new btRigidBody(RigidBodyCI);
dynamicsWorld->addRigidBody(RigidBody);

ofstream outfile("data.csv", ios::out);
for (int i = 0; i < 300; i++) {

    RigidBody->applyTorque(torque);

    dynamicsWorld->stepSimulation(1 / 60.f, 10);

    angularVelocity = RigidBody->getAngularVelocity();

    outfile << angularVelocity.getX() << "," << angularVelocity.getY() << "," << angularVelocity.getZ() << endl;
}

outfile.close();

delete Shape;


delete dynamicsWorld;
delete solver;
delete dispatcher;
delete collisionConfiguration;
delete broadphase;

printf("Press a key to exit\n");
getchar();
}
Bullet 2.78:
Image

Bullet 2.83:
Image

User avatar
drleviathan
Posts: 550
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Problem about simulating rigid body rotation with bullet physics engine

Post by drleviathan » Sun Jun 10, 2018 4:44 pm

The Bullet 2.83 results are correct.

How do I know?

You're spinning the object up using a torque that is constant in the world-frame. Therefore the world-frame angular momentum is increasing and always points parallel to the torque. The relation between angular momentum (L), the inertia tensor (I) and the angular velocity (ω) is:

L = Iω

So the direction of L is constant, but since it does not lie on one of the object's planes of symmetry we expect the values in the world-frame inertia tensor I to change over time as the body rotates: they will oscillate among the tensor coefficients. Remember we're talking about the world-frame not local-frame. Meanwhile, the angular velocity ω values must vary in ways that compensate to keep the angular momentum L pointing parallel to the <1,1,1> axis. The 2.83 graph shows varying angular velocity components, therefore we conclude it is more correct.

That is my simplified explanation about why I can look at the two graphs and point at 2.83 as the correct one. I don't think I could do a good job explaining the equations of motion of an axially symmetric rigid body in the inertial frame. For that you'll have to do your own research online or in classic physics textbooks.

Post Reply