Not much luck, I’m afraid. But first, your “works fine” examples have a slight disadvantage: they loose simulation time! Let me explain why:
doPhysics(dt, max_substeps, substep)
If called this way Bullet will advance the simulation using fixed size substeps. The step size if “substep”. It will do up to max_substeps substeps. The remaining time will be used to interpolate the scene (not simulate). A few examples:
1.) doPhysics(0.32, 5, 0.1): Bullet will do 3 substeps, each 0.1 seconds. The remaining 0.02 seconds will be interpolated.
2.) doPhysics(0.16, 5, 0.2): Bullet will do no simulation substep at all, just interpolate.
3.) doPhysics(0.56, 4, 0.1): Bullet will do 4 substeps, since 4 is the max numer of substeps it is told to do.
In your case you have doPhysics(dt~0.002, 5, 0.00002). Bullet will do 5 substeps each 0.00002 = 0.0001 seconds. The remaining time to 0.002 seconds is lost.
In your case you could also call Bullet this way: doPhysics(0.0002, 0). This way Bullet will do no substep, just one simulation step of fixed length each frame, no matter what the frame duration is.
Back to the little insight gained. The problem is that Panda3D’s framerate is not constant. Now and then there are “spikes”. These spikes cause the problems. In general, physics engines run best with constant stepsize. Variable stepsize and interpolation are the death of determinism. Somehow Bullet seems to be very vulnerable to such spikes.
In order to get more stable character movement you could try the following:
1.) A cheap way would be to tell Panda to clamp framerate at, say, 60fps. You will still get single frames which are much longer. Don’t care about frame rate fluctuation. Pass 1./60. to Bullet’s doPhysics. The result will be that the character velocity will change together with the framerate fluctuation, but the huge spikes should be gone.
2.) Collect the elapsed time (task.getDt) in a variable, and before stepping the simulation chekc this accululator. Remove only multiples of a fixed stepsize from the accumulator, and pass these timesteps to Bullet. A good fixed stepsize would be maybe a third of the average frametime, so on average you do 3 simulation steps each frame. Sometimes 2, sometimes 4. This won’t give perfect results, but for me the character movement has become more smooth since interpolation is no longer applied.