Jumpy kinematic->dynamic collisions at small timesteps

kate
Posts: 41
Joined: Thu Jan 08, 2009 11:20 am
Location: London, UK
Contact:

Jumpy kinematic->dynamic collisions at small timesteps

Post by kate » Fri Jul 17, 2009 10:38 am

Hi,

I'm finding that collisions between kinematic and dynamic objects get "twitchy" when I use a small fixedTimeStep in the stepSimulation function (the value of maxSubSteps doesn't seem to make a difference) - by which I mean that instead of, say, gently pushing a dynamic object along, the kinematic one will cause it to move in a series of jumps; the collision impulse increases as the time step decreases. I've tried setting the "ERP" value to 0 but that doesn't help.

I think that the problem may be due in part to the fact that the kinematic objects' positions are updated only once per frame (i.e. 24 times a second), whereas the simulation is run at a (much) faster rate... updating the kinematic bodies more often does seem to help in some cases (not all), but this is not ideal as it makes things really slow.

Has anyone encountered this before, or does anyone have any suggestions as to how to get round it?

All input is much appreciated :)

Thanks,

Kate

P.S. I realise that Bullet should really be run with a fixed time step of 1/60, but often we need greater accuracy and stability than that can give...

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

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by pico » Sat Jul 18, 2009 8:28 am

Hi,

i assume you dont use a motionState for the kinematic bodies. This should interpolate automatically between the simulation frames.

kate
Posts: 41
Joined: Thu Jan 08, 2009 11:20 am
Location: London, UK
Contact:

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by kate » Mon Jul 20, 2009 9:31 am

Hi Pico,

Actually, I use a motionState that's pretty much identical to the one in the docs (except that its setWorldTransform is implemented so it can be used for dynamic objects too, I just call the appropriate function for each)...

K.

nokto
Posts: 8
Joined: Fri Apr 17, 2009 12:04 am

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by nokto » Mon Jul 20, 2009 10:01 am

Hi Kate,

I had the same problem before in my app, or something very similar, and, as you point, it was caused by the fact I updated my objects' position in my world more often than in the bullet world. Have you tried to step your simulation at the same rate you update your objects' position? say, once each 1/24s.

nokto.-

kate
Posts: 41
Joined: Thu Jan 08, 2009 11:20 am
Location: London, UK
Contact:

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by kate » Mon Jul 20, 2009 3:47 pm

Hi Nokto,

Thanks for the suggestion. Running at 24 frames a second is too slow for the sim to be any good, but I tried doing some simple interpolation to update the positions more frequently (to match the fixedTimeStep) - which didn't seem to help at all :( So I'm starting to wonder if the timing is the (whole) issue after all...

Kate

nokto
Posts: 8
Joined: Fri Apr 17, 2009 12:04 am

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by nokto » Tue Jul 21, 2009 12:02 am

Hi again,

Isn't running your app at 60fps not an option? If it isn't, I'd try to test it anyway, to see if the problem solves. If it does, we'll have to work around it.

nokto.-

kate
Posts: 41
Joined: Thu Jan 08, 2009 11:20 am
Location: London, UK
Contact:

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by kate » Tue Jul 21, 2009 9:55 am

Hi Nokto,

I have tried running at 60fps (for the fixedTimeStep; the position updates for the kinematic objects are always at 24fps), and the objects behave reasonably. As I decrease the fixedTimeStep, however, the collision impulses between kinematic and dynamic objects increase, even though the velocities of the kinematic objects remain constant. I've attached a couple of videos to show the difference in behaviour (the blue cubes are kinematic and the red ones are dynamic; '60fps' has a fixedTimeStep of 0.0167 and the impulse of the first collision between the red and blue cubes on the left is 0.0669, '480fps' has a fixedTimeStep of 0.0021 and the impulse is 0.4560).

As I mentioned before, though, the default 60fps unfortunately doesn't always provide enough accuracy for our needs (e.g. when there are many rigid bodies stacked together, they tend to "explode" or fall apart at larger timesteps).

Thanks,

Kate
Attachments
jumpy.zip
(40.92 KiB) Downloaded 289 times

kate
Posts: 41
Joined: Thu Jan 08, 2009 11:20 am
Location: London, UK
Contact:

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by kate » Thu Jul 23, 2009 4:38 pm

Can anyone tell me where the collision impulses actually get calculated? (I'm trying to figure out why the values change when the timestep is altered...)

Thanks,

Kate

Dirk Gregorius
Posts: 874
Joined: Sun Jul 03, 2005 4:06 pm
Location: Kirkland, WA

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by Dirk Gregorius » Thu Jul 23, 2009 4:57 pm

Some ideas. Maybe this helps:

1) Do you actually set the velocity at the beginning of the timestep such that you reach the desired position at the end? Otherwise you just beam objects around. This would definetely help the solver.
2) I would also try to adjust solver (Bullet) if you set a target position and you take several small substeps in a way that the current and target positions get interpolated and that you only reach the target position at the last substep.

It might be that this is actually already done in Bullet. I am just guessing here...!



HTH,
-Dirk

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

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by Erwin Coumans » Thu Jul 23, 2009 6:05 pm

Dirk Gregorius wrote: 1) Do you actually set the velocity at the beginning of the timestep such that you reach the desired position at the end? Otherwise you just beam objects around. This would definetely help the solver.
2) I would also try to adjust solver (Bullet) if you set a target position and you take several small substeps in a way that the current and target positions get interpolated and that you only reach the target position at the last substep.

It might be that this is actually already done in Bullet. I am just guessing here...!
Both things should be already done in Bullet, if you use the motionstate.
kate wrote: Can anyone tell me where the collision impulses actually get calculated? (I'm trying to figure out why the values change when the timestep is altered...)
It happens in Bullet/src/BulletDynamics/ConstrainsSolver/btSequentialImpulseConstraintSolver.cpp around line 590. Currently, only the penetration uses the error reduction parameter, let's add 'm_erp2' to scale the velocity impulse for Bullet 2.75 final version:

Code: Select all

	positionalError = -penetration * infoGlobal.m_erp/infoGlobal.m_timeStep;
	btScalar	velocityError = (restitution - rel_vel)*infoGlobal.m_erp2;
	btScalar  penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
	btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
kate wrote: collisions between kinematic and dynamic objects get "twitchy" when I use a small fixedTimeStep
Can you provide a reproduction in one of the Bullet samples, so we can look at it, and try to improve it?
Thanks,
Erwin

kate
Posts: 41
Joined: Thu Jan 08, 2009 11:20 am
Location: London, UK
Contact:

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by kate » Fri Jul 24, 2009 11:56 am

Erwin Coumans wrote:
Dirk Gregorius wrote: 1) Do you actually set the velocity at the beginning of the timestep such that you reach the desired position at the end? Otherwise you just beam objects around. This would definetely help the solver.
2) I would also try to adjust solver (Bullet) if you set a target position and you take several small substeps in a way that the current and target positions get interpolated and that you only reach the target position at the last substep.

It might be that this is actually already done in Bullet. I am just guessing here...!
Both things should be already done in Bullet, if you use the motionstate.
Hmm... I wonder if there's something wrong with my motionState - maybe it doesn't do something that it should?

Code: Select all

class myMotionState : public btMotionState
{
public:
					myMotionState(const btTransform& transform = btTransform::getIdentity()) :
						m_transform(transform),
						m_isDynamic(true) {}
	virtual			~myMotionState() {}
	
	/// Gets the current world position/rotation; used in Bullet calculations
	virtual	void	getWorldTransform(btTransform& transform) const { transform = m_transform; }
	
	/// \brief Sets the world position/rotation value for dynamic RBs.
	virtual void	setWorldTransform(const btTransform& transform) { if (m_isDynamic) m_transform = transform; }
	
	/// Sets whether the rigid body this belongs to is dynamic or not
			void	setDynamic(bool isDynamic) { m_isDynamic = isDynamic; }

	/// \brief Sets the world position/rotation value for kinematic RBs.			
			void	setKinematicTransform(const btTransform& transform)  { if (!m_isDynamic) m_transform = transform; }

protected:
	bool			m_isDynamic;		///< Is the rigid body this motion state relates to dynamic
	btTransform		m_transform;		///< Current world transform
};
Erwin Coumans wrote:
kate wrote: Can anyone tell me where the collision impulses actually get calculated? (I'm trying to figure out why the values change when the timestep is altered...)
It happens in Bullet/src/BulletDynamics/ConstrainsSolver/btSequentialImpulseConstraintSolver.cpp around line 590. Currently, only the penetration uses the error reduction parameter, let's add 'm_erp2' to scale the velocity impulse for Bullet 2.75 final version:

Code: Select all

	positionalError = -penetration * infoGlobal.m_erp/infoGlobal.m_timeStep;
	btScalar	velocityError = (restitution - rel_vel)*infoGlobal.m_erp2;
	btScalar  penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
	btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
Thanks :)

I tried adding the 'm_erp2' factor, and it seemed to help the issue a little - but it made things very bouncy.
Erwin Coumans wrote:Can you provide a reproduction in one of the Bullet samples, so we can look at it, and try to improve it?
I'll work on it...

Thanks,

Kate

kate
Posts: 41
Joined: Thu Jan 08, 2009 11:20 am
Location: London, UK
Contact:

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by kate » Fri Jul 24, 2009 4:57 pm

OK, I've hacked the BasicDemo code to approximate what I'm doing in my system (there may be some differences in implementation/settings, but the resulting behaviour looks about the same), and attached the modified code.

If you change the value of FIXED_TIME_STEP at line 19 of BasicDemo.cpp to e.g. 1/720 (a value we do use), you should notice that the dynamic cube on the right moves much faster/further on collision with the kinematic object on the left...

Thanks,

Kate
Attachments
BasicDemo_hacked.zip
(4.03 KiB) Downloaded 237 times

bradclancy
Posts: 7
Joined: Thu Jun 25, 2009 4:32 am

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by bradclancy » Mon Jul 27, 2009 12:34 pm

Hey Kate,

Just a quick guess: In your code file you call

m_dynamicsWorld->stepSimulation(ms / 1000000.f, 1, FIXED_TIME_STEP);

if FIXED_TIME_STEP is greater than ms/ 1000000.f then the simulation will do nothing for a number of frames and you'll only get motion update (i.e. 1 sub-step every) every FIXED_TIME_STEP/(ms/1000000.f) frames...

It seems you want each sub-step to be 1/720 of a second? what is your time scale? ms/1000000.f makes me think 1ms = 1 nano second? So, try setting FIXED_TIME_STEP to say 5 nano seconds? (5.0e-9) and assuming your updates are at least 5 milli seconds appart you should get at least 1 update per frame. Keep dropping FIXED_TIME_STEP till it is always less than your min timeStep (i.e. first parameter to setpSimulation).

Or Call the fn like this:

m_dynamicsWorld->stepSimulation(FIXED_TIME_STEP, 0, 0.f); // last param doesn't matter.

this way you'll use a variable timestep (that you've made constant by passing in the same time each frame). Though, your simulation will be completely independent of any 'real time'.

Cheers,
Brad

kate
Posts: 41
Joined: Thu Jan 08, 2009 11:20 am
Location: London, UK
Contact:

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by kate » Tue Jul 28, 2009 9:34 am

Hi Brad,

Thanks for the suggestions.

It looks like I was a little too quick to post the demo code, as your suggestions for changing the parameters to stepSimulation do fix the issue in this case.

Unfortunately, however, they don't seem to make any difference in my own code (they were actually one of the first things I thought of to try)...

I'll see if I can get the demo code to match the behaviour properly, though the setup is a little different.

Kate

DannyChapman
Posts: 85
Joined: Sun Jan 07, 2007 4:29 pm
Location: Oxford, England
Contact:

Re: Jumpy kinematic->dynamic collisions at small timesteps

Post by DannyChapman » Tue Jul 28, 2009 12:06 pm

This is a stab in the dark, since I don't use Bullet... but if the solver is aiming to eliminate the penetration error (or some fraction of it) over a fixed number of updates using Baumgarte stabilisation, then a very small timestep will result in large error-correcting velocities because they'll be proportional to penetration/timestep. Unless the correction is capped, of course (which it may be).
I've seen this with PhysX - especially with the joint limits - articulated bodies can go very twitchy with small timesteps.

Post Reply