Force/Impulse timebase

pico
Posts: 229
Joined: Sun Sep 30, 2007 7:58 am

Force/Impulse timebase

Post by pico » Tue Oct 23, 2007 9:31 am

Hi,

i have an understanding problem how the functions applyForce and applyImpulse work.

When "impulse = force*time" and Bullets time is the given framerate (default 60fps),
then why do objects behave differently when using one of those calls:

applyCentralForce(btVector3(force,0,0));
or
applyCentralImpulse(btVector3(force/frameRate,0,0));

I hope this is not a too dumb question ;)

Thanks

User avatar
Erwin Coumans
Site Admin
Posts: 4193
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Force/Impulse timebase

Post by Erwin Coumans » Thu Oct 25, 2007 7:34 am

pico wrote: applyCentralForce(btVector3(force,0,0));
or
applyCentralImpulse(btVector3(force/frameRate,0,0));
Can you reproduce this in a Bullet demo?
If so, please attach the zipped demo to this topic.
Thanks,
Erwin

dbrank0
Posts: 6
Joined: Thu Nov 15, 2007 8:54 am

Re: Force/Impulse timebase

Post by dbrank0 » Fri Nov 30, 2007 12:29 am

First, I have to say I'm newbie to physical simulation and bullet, and maybe I'm simply doing something the wrong way, but maybe I have a problem that might be related to this topic.

Are RigidBody forces supposed to reset to 0 after each simulation step in bullet? And why?

So, how do I keep constant force applied to body? I can set it to appropriate value before each simulation step, but this leads to problems, when simulation step requires substeps, since forces are reset after first step. So, insted of selected force f applied for 1/60s, if a frame rate (and simulation rate) drops to let's say 1/20s, force f is applied for first 1/60 s, but forces are reset then and in next two substeps 0 force is applied - producing noticably slower acceleration.

That is if I'm not going wrong about all this or having bugs in my code. :wink:
Any hints?

User avatar
Erwin Coumans
Site Admin
Posts: 4193
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Force/Impulse timebase

Post by Erwin Coumans » Fri Nov 30, 2007 12:35 am

Forces are cleared out after each simulation step.

If you really want to apply a continuous force for a longer while, it is best to modify the 'gravity' vector (it can be changed every simulation step, and is available for each rigid body).

See also:
http://www.bulletphysics.com/Bullet/php ... f=9&t=1716

Hope this helps,
Erwin

Cleanrock
Posts: 7
Joined: Tue May 01, 2007 6:23 pm

Re: Force/Impulse timebase

Post by Cleanrock » Fri Nov 30, 2007 5:59 am

i have also run into this force problem in combination with sub steps, i really think this behaviour needs to be looked over if force applying should be usuable/predictable

when i started to use bullet i was surprised that forces were reset this way, can someone explain the logic/good of forces being reset instead of letting the user manually reset them ?

User avatar
Erwin Coumans
Site Admin
Posts: 4193
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Force/Impulse timebase

Post by Erwin Coumans » Fri Nov 30, 2007 7:06 am

I agree that with the internal substeps, it is better to clear out the user force _after_ all substeps completed. It will be fixed for next release (2.65).

Other physics SDKs, like Havok and Ageia also clear out the force after the simulation step I think, but I need to verify.
Thanks for the feedback,
Erwin

dbrank0
Posts: 6
Joined: Thu Nov 15, 2007 8:54 am

Re: Force/Impulse timebase

Post by dbrank0 » Fri Nov 30, 2007 8:43 am

Thanks for a prompt reply.

Setting body's gravity would do it, if I wouldn't also need to apply constant torque. :) I'm controlling player's rocket with torques and forces, and right now control sensitivity changes as framerate (and number of substeps) changes.

I'll come up with something, but it's great to hear this behavior will be changed in next version.

ola
Posts: 169
Joined: Sun Jan 14, 2007 7:56 pm
Location: Norway
Contact:

Re: Force/Impulse timebase

Post by ola » Fri Nov 30, 2007 3:37 pm

Setting body's gravity would do it, if I wouldn't also need to apply constant torque. :) I'm controlling player's rocket with torques and forces, and right now control sensitivity changes as framerate (and number of substeps) changes.
Hi there,

in the game I am working on, I use lots of forces all the time (for example, aerodynamic forces on wings, such things). In order to update these per step in bullet, you can do what I have done which is do create my own derived dynamics world class. I described it in this post:
http://www.bulletphysics.com/Bullet/php ... f=9&t=1570

Just scroll down a bit, at the moment it's the second last post. It's pretty useful for more stuff than just applying forces.

Best regards,
Ola

chunky
Posts: 146
Joined: Tue Oct 30, 2007 9:23 pm

Re: Force/Impulse timebase

Post by chunky » Fri Dec 07, 2007 8:39 pm

I, also, am having problems with this and I don't really understand the overreaching "correct" way to do this stuff.

I'm making an overhead space shooter type game. The player holds down a "boost" key to cause the rocket to boost forward, which is basically just applying forces regularly. This is essentially my main loop:

Code: Select all

time_gameclock = time_physics_prev = time_physics_curr = worldTimer.getMilliseconds();

while (!done) {
  mTWVideo->renderOneFrame();

  long long dt =  worldTimer.getMilliseconds() - time_gameclock;
		
  while(dt >= TickMs) {
    dt -= TickMs;
    time_gameclock += TickMs;
			
// ADD FORCES HERE
    mPlayer->boost(mTWInputstate->mBoost);
  }		

  /* Physics handling part of the loop
  This, like the rendering, ticks every time around.*/
// Note that at super high framerates [850fps], the number being passed to this function is regularly "1" or "2"
//  Whereas at lower framerates [60fps], the number being passed is "16" or "17"
  time_physics_curr = worldTimer.getMilliseconds();
  mWorld->stepSimulation((float)(time_physics_curr - time_physics_prev));
  time_physics_prev = time_physics_curr;
}
I added a comment "ADD FORCES HERE" where I'm actually adding forces to the spaceship. So far, this whole thing seems reasonable to me. The problem is that my framerate can be as low as 60fps [with vsync enabled], or it runs at about 850fps without vsync. The difference in simulation between 60fps and 850fps is drastic.

I've tried experimenting with the last two params to mWorld->stepSimulation(), but they don't appear to fix what's wrong here. [I've tried 0,1,500... for the numSubSteps, and for the step length, I've tried numbers from 1/850th of a second [for my top framerate] up to 1/32 of a second [to match my input loop]].

I've now tried previous suggestion in this thread, and my boost function calls spaceship->setGravity instead of spaceship->addCentralForce, but it still seems heavily dependant on framerate.

Strangely, I'm getting another effect where the spaceship doesn't strictly accellerate at the speed of gravity; there's a point, based on a bunch of factors I haven't been able to figure out [one of which is the framerate], where the accelleration of the spaceship suddenly goes from really slow [pixels per second, on-screen] to really high [multiple screenwidths every tick].

I'm sorry, I'm probably being really stupid, but I just can't see what's going on here.

I *used* to divide the number passed stepSimulation by a thousand, but then I always seemed to get weird twitching in the bodies. It seems like the number should be divided by a thousand [since I'm passing milliseconds now], but the twitching of the bodies was what I was trying to fix.

Thanks,
Gary (-;

chunky
Posts: 146
Joined: Tue Oct 30, 2007 9:23 pm

Re: Force/Impulse timebase

Post by chunky » Fri Dec 07, 2007 11:15 pm

I was just looking at this page: http://www.continuousphysics.com/mediaw ... BulletTodo
and it mentions:
Done:
limits and motors for Generic D6 constraint
I just checked out the bullet svn, but couldn't see any reference to motors in the D6 constraint. Am I missing something? Presumably motors would be a good way to solve my actual problem of moving a spaceship around?

Thank-you very much,
Gary (-;

User avatar
Erwin Coumans
Site Admin
Posts: 4193
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Force/Impulse timebase

Post by Erwin Coumans » Wed Dec 12, 2007 1:25 am

chunky wrote:I just checked out the bullet svn, but couldn't see any reference to motors in the D6 constraint. Am I missing something? Presumably motors would be a good way to solve my actual problem of moving a spaceship around?

Thank-you very much,
Gary (-;
Have you checked the btScalar btRotationalLimitMotor::solveAngularLimits?

Thanks,
Erwin

dbrank0
Posts: 6
Joined: Thu Nov 15, 2007 8:54 am

Re: Force/Impulse timebase

Post by dbrank0 » Wed Dec 12, 2007 11:21 am

chunky: I also still observe acceleration/framerate dependence, even using gravity insted of force. It's far better this way, though, but I still need to investigate this.

I'm also wandering, why setting gravity to, let's say (0,0,1) has absolutely no effect on rigid body, until I set it some non-zero initial speed. Setting gravity to (0,0,10) or so has immediate effect. (Body has deactivation disabled, mass is 1. There is no friction (no contacts with other bodies).)

chunky
Posts: 146
Joined: Tue Oct 30, 2007 9:23 pm

Re: Force/Impulse timebase

Post by chunky » Wed Dec 12, 2007 9:06 pm

I'm also wandering, why setting gravity to, let's say (0,0,1) has absolutely no effect on rigid body, until I set it some non-zero initial speed. Setting gravity to (0,0,10) or so has immediate effect. (Body has deactivation disabled, mass is 1. There is no friction (no contacts with other bodies).)
Interestingly, I had a similar problem. It was more observable when explicitly using addForce instead of setGravity, but noticably there.

I *appear* to have mostly solved my framerate dependance by increasing the granularity of stepSimulation and putting a cap on my framerate. Reading here: http://continuousphysics.com/Bullet/php ... f=9&t=1064, I experimented with the numSubSteps and the internalTimeStep. Saliently, from this quote from Erwin:
If you pass the real timestep, then make sure maxNumSubSteps is large enough so that stepTime < maxNumSubSteps * internalTimeStep
Eventually, I ended up with a framerate cap about 150 [it can go up to 180 or so, the cap isn't very rigid], numSubSteps at 80, and internalTimeStep at 1/200. That'll satisfy erwin's equation above when the game is as low as 3fps, and definitely satisfy it [at the cost of some CPU] at 150.

Bullet doesn't appear to do interpolation between steps [I'm sure I remember reading that it does, but looking at world->stepSimulation, I don't know how it can], so effectively I'm just ensuring that you always get at least one real step. I'm semi certain that's what it does, at least, but for some reason I have a mental block on how world->stepSimulation actually works. It seems obvious, but my brain won't accept it. Ho, hum.
Have you checked the btScalar btRotationalLimitMotor::solveAngularLimits?
Ah. I was thinking that a linear motor would probably be a better option for this kind of simlation than modifying gravity or adding forces, and was looking for that.

Gary (-;

User avatar
Erwin Coumans
Site Admin
Posts: 4193
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Force/Impulse timebase

Post by Erwin Coumans » Wed Dec 12, 2007 10:21 pm

Bullet doesn't appear to do interpolation between steps [I'm sure I remember reading that it does, but looking at world->stepSimulation, I don't know how it can],
Yes, Bullet interpolates between simulation steps. Please use the btMotionState. You can see the implementation in see btDiscreteDynamicsWorld::synchronizeMotionStates.
So the renderer has to get the world matrix from the motionstate, and not directly from the btRigidBody:

Code: Select all

	for (int i=0;i<numObjects;i++)
		{
			btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i];
			btRigidBody* body = btRigidBody::upcast(colObj);

			if (body && body->getMotionState())
			{
				btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState();
				myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m);
			}
Check out CcdPhysicsDemo:
Enable #define VERBOSE_TIMESTEPPING_CONSOLEOUTPUT 1 at the top,
Then in pause mode (press i ) and press 's' for simulation, you will see in the console interpolated and simulated (and dropped) steps.

By the way, Bullet 2.65 beta2 the force is only cleared out at the end of the simulation step, not during the internal substeps.

Hope this helps,
Erwin

chunky
Posts: 146
Joined: Tue Oct 30, 2007 9:23 pm

Re: Force/Impulse timebase

Post by chunky » Wed Dec 12, 2007 10:47 pm

Please use the btMotionState.
Yep, I am. I'm using Ogre, this is my appropriate function:

Code: Select all

void TWShipMotionState::setWorldTransform(const btTransform &worldTrans) {
	if(NULL == mVisibleobj) return; // silently return before we set a node
	
	btQuaternion rot = worldTrans.getRotation();
	mVisibleobj->setOrientation(rot.w(), rot.x(), rot.y(), rot.z());
	
	btVector3 pos = worldTrans.getOrigin();
	mVisibleobj->setPosition(pos.x(), pos.y(), pos.z());
}
It's strange because I get really jerky movement on-screen, and I've been unable to figure out what's causing it. I was reading through the source for just stepSimulation, I've looked a little further and I think I understand now, thank-you.

I'm downloading that version [2.65b2] now.

Thank-you very much for all your help,
Gary (-;

Post Reply