Jumpy kinematic->dynamic collisions at small timesteps
-
- Posts: 41
- Joined: Thu Jan 08, 2009 11:20 am
- Location: London, UK
Jumpy kinematic->dynamic collisions at small timesteps
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...
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...
-
- Posts: 229
- Joined: Sun Sep 30, 2007 7:58 am
Re: Jumpy kinematic->dynamic collisions at small timesteps
Hi,
i assume you dont use a motionState for the kinematic bodies. This should interpolate automatically between the simulation frames.
i assume you dont use a motionState for the kinematic bodies. This should interpolate automatically between the simulation frames.
-
- Posts: 41
- Joined: Thu Jan 08, 2009 11:20 am
- Location: London, UK
Re: Jumpy kinematic->dynamic collisions at small timesteps
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.
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.
-
- Posts: 8
- Joined: Fri Apr 17, 2009 12:04 am
Re: Jumpy kinematic->dynamic collisions at small timesteps
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.-
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.-
-
- Posts: 41
- Joined: Thu Jan 08, 2009 11:20 am
- Location: London, UK
Re: Jumpy kinematic->dynamic collisions at small timesteps
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
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
-
- Posts: 8
- Joined: Fri Apr 17, 2009 12:04 am
Re: Jumpy kinematic->dynamic collisions at small timesteps
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.-
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.-
-
- Posts: 41
- Joined: Thu Jan 08, 2009 11:20 am
- Location: London, UK
Re: Jumpy kinematic->dynamic collisions at small timesteps
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
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
You do not have the required permissions to view the files attached to this post.
-
- Posts: 41
- Joined: Thu Jan 08, 2009 11:20 am
- Location: London, UK
Re: Jumpy kinematic->dynamic collisions at small timesteps
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
Thanks,
Kate
-
- Posts: 861
- Joined: Sun Jul 03, 2005 4:06 pm
- Location: Kirkland, WA
Re: Jumpy kinematic->dynamic collisions at small timesteps
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
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
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Jumpy kinematic->dynamic collisions at small timesteps
Both things should be already done in Bullet, if you use the motionstate.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...!
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: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...)
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;
Can you provide a reproduction in one of the Bullet samples, so we can look at it, and try to improve it?kate wrote: collisions between kinematic and dynamic objects get "twitchy" when I use a small fixedTimeStep
Thanks,
Erwin
-
- Posts: 41
- Joined: Thu Jan 08, 2009 11:20 am
- Location: London, UK
Re: Jumpy kinematic->dynamic collisions at small timesteps
Hmm... I wonder if there's something wrong with my motionState - maybe it doesn't do something that it should?Erwin Coumans wrote:Both things should be already done in Bullet, if you use the motionstate.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...!
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
};
ThanksErwin Coumans wrote: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: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...)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;
I tried adding the 'm_erp2' factor, and it seemed to help the issue a little - but it made things very bouncy.
I'll work on it...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?
Thanks,
Kate
-
- Posts: 41
- Joined: Thu Jan 08, 2009 11:20 am
- Location: London, UK
Re: Jumpy kinematic->dynamic collisions at small timesteps
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
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
You do not have the required permissions to view the files attached to this post.
-
- Posts: 7
- Joined: Thu Jun 25, 2009 4:32 am
Re: Jumpy kinematic->dynamic collisions at small timesteps
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
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
-
- Posts: 41
- Joined: Thu Jan 08, 2009 11:20 am
- Location: London, UK
Re: Jumpy kinematic->dynamic collisions at small timesteps
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
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
-
- Posts: 84
- Joined: Sun Jan 07, 2007 4:29 pm
- Location: Oxford, England
Re: Jumpy kinematic->dynamic collisions at small timesteps
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.
I've seen this with PhysX - especially with the joint limits - articulated bodies can go very twitchy with small timesteps.