Gear Simulation Question

tisdadd
Posts: 4
Joined: Tue Mar 29, 2011 2:48 am

Gear Simulation Question

Post by tisdadd »

Hello,

I have been working on an independent project for school, and my Professor doesn't know much about physics engines and as such said that I should come and ask on the community forums. I am working on creating a series of gears that interlock, and eventually will power wheels, claws, or other simple items that can be created and linked in with toothed edges and such. However, I am having issues with making the one powered gear continuously rotate the other gear at a reasonably consistent rate. I have tried changing tooth sizes and such, but it does not seem to help much, it will still run into this issue. I am linking Ogre with bullet for this.

If you wish to see my entire project so far, I have uploaded it to http://www.megaupload.com/?d=LZCOWCA7.

Otherwise, what I believe to be relevant for physics the gears, I extracted and ordered in the following code block.

Code: Select all

// make the collision shape
	btCompoundShape* gear = new btCompoundShape();
	btCollisionShape* cylinder = new btCylinderShape(btVector3(radius, thickness, 0));
	btTransform norm;
	norm.setIdentity();
	gear->addChildShape(norm, cylinder);
	entityMotionState = new QuickLinkMotionState(entityX, entityY, entityZ, entityNode);
for(int i = 0; i < numExtrusions; i++)
	{ // cubes for extrusions/teeth
		// some bullet cubes so not doing extra loops
		btCollisionShape* bulletCube = new btBoxShape(btVector3(scaler, thickness, scaler * .2) / 2);
		btTransform cubeTransform;
		cubeTransform.setIdentity();
		cubeTransform.setOrigin(btVector3(radius * cos(i * ((Ogre::Math::PI * 2) / numExtrusions)), 0, radius * sin(i * ((Ogre::Math::PI * 2) / numExtrusions))));
		btQuaternion bulletRotation(cos(i * ((Ogre::Math::PI * 2) / numExtrusions)), 0, sin(i * ((Ogre::Math::PI * 2) / numExtrusions)), 0);
		cubeTransform.setRotation(bulletRotation);
		gear->addChildShape(cubeTransform, bulletCube);
	}

	// finish physics
	gear->calculateLocalInertia(entityMass, entityInertia);
	
	btRigidBody::btRigidBodyConstructionInfo CI(entityMass, entityMotionState, gear, entityInertia);
	entityRigidBody = new btRigidBody(CI);

	
	if(entityKinematic)
	{ // make kinimatic
		entityRigidBody->setMassProps(0, btVector3(0,0,0));
		entityRigidBody->setCollisionFlags(entityRigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
		entityRigidBody->setActivationState(DISABLE_DEACTIVATION);
	}
	// add to world
	dynamicsWorld->addRigidBody(entityRigidBody);
That is the creation of the gear, they are declared and used in a separate class, and constraints are added to them. The constraints are like so.

Code: Select all

		btHingeConstraint* test = new btHingeConstraint(*gear->getEntityRigidBody(), btVector3(0, 0, 0), btVector3(0, 1, 0));//new btHingeConstraint(*gear2->getEntityRigidBody(),*gear->getEntityRigidBody(), localA, localB);
		btHingeConstraint* test2 = new btHingeConstraint(*gear2->getEntityRigidBody(), btVector3(0, 0, 0), btVector3(0, 1, 0));
		dynamicsWorld->addConstraint(test, true);
		dynamicsWorld->addConstraint(test2, true);
Finally, I try to rotate them. I have tried with two different types of coding, leaving it as a dynamic object and then setting the angular velocity (called every update), resulting in the gears eventually catching on each other and freezing up

Code: Select all

	gear2->getEntityRigidBody()->setAngularVelocity(btVector3(0, 4.0f, 0));
as well as making it a kinematic object, which works but sometimes shoots the other gear in reverse because it thinks it is teleporting.

Code: Select all

	
	btTransform btt;
	btt.setIdentity();
	btt.setOrigin(btVector3(entityX, entityY, entityZ));
	entityY += .05;
	entityMotionState->getWorldTransform(btt);
	btQuaternion additionalRotation(entityRotationY, 0, 0);
	entityRotationY += 0.01;
	btt.setRotation(additionalRotation);
	entityMotionState->setWorldTransform(btt);
If anyone has any ideas what so ever to make it so that the gears will be able to rotate smoothly, and would be willing to share them with me, that would be most wonderful.

Thanks very much in advance, and please let me know if there is any information other than this needed.
lulzfish
Posts: 43
Joined: Mon Jan 03, 2011 4:26 pm

Re: Gear Simulation Question

Post by lulzfish »

I think gears are out of the scope of a realtime simulation.

I would fudge them (Make them non-colliding and manually rotate them at the proper velocities) and forget about trying to simulate real intermeshing.

As you said, the teeth will end up teleporting through each other, it would only be possible with hundreds or thousands of steps per frame, to avoid this happening.

You would do well to just fake it and use Bullet for the rest of the simulation.
tisdadd
Posts: 4
Joined: Tue Mar 29, 2011 2:48 am

Re: Gear Simulation Question

Post by tisdadd »

lulzfish wrote:I think gears are out of the scope of a realtime simulation.

I would fudge them (Make them non-colliding and manually rotate them at the proper velocities) and forget about trying to simulate real intermeshing.

As you said, the teeth will end up teleporting through each other, it would only be possible with hundreds or thousands of steps per frame, to avoid this happening.

You would do well to just fake it and use Bullet for the rest of the simulation.
If I do it with simply the setAngularVelocity though, it works for a while until one tooth locks onto another.
tisdadd
Posts: 4
Joined: Tue Mar 29, 2011 2:48 am

Re: Gear Simulation Question

Post by tisdadd »

tisdadd wrote:
lulzfish wrote:I think gears are out of the scope of a realtime simulation.

I would fudge them (Make them non-colliding and manually rotate them at the proper velocities) and forget about trying to simulate real intermeshing.

As you said, the teeth will end up teleporting through each other, it would only be possible with hundreds or thousands of steps per frame, to avoid this happening.

You would do well to just fake it and use Bullet for the rest of the simulation.
If I do it with simply the setAngularVelocity though, it works for a while until one tooth locks onto another.
And by using the setAngularVelocity idea along with triangular teeth it works for a long time.... left it running for several hours with no problem. Figured that I would mention this for in case someone else tries. Also, one of my friends mentioned that the teeth on a real gear are double tapered with two different angles...