[ODE] Framerate problem *again*

skjold@cistron.nl skjold at cistron.nl
Sun Feb 16 07:49:02 2003


> There's something in your code that I can't figure out.
> We said to pass to dWorldStep() always a constant value (like 0.01).
> Right? Ok. And with integrations we can pass N times the same value
> until step*N ~= ElapsedTime. ok?
> 
> But:
> 1) you pass to dWorldStep() not 0.01 but 0.01/4 that's a very little
> step (maybe it's good too).
> 2) your FOR cycle is executed 4 times ALWAYS, indipendently from how
> much time is passed since last frame (ElapsedTime). This seems wrong
> to me... you're not integrating anything, you make always the same
> cycle! Maybe your posted code is incomplete and I misunderstood all.

So you are saying that I use a constant interval for dWorldStep (0.01/4), that the cycle repeats identically for each frame, and that I disregard how much real-world time passes between each frame? Well then, I hope you are correct, because that is exactly what I intended :P I don't want to vary the cycle interval, nor the sub-frame integration resolution, because that affects the outcome of the simulation. For games I understand that the added accuracy is a bonus only when there is processor-time to spare, which is a resource of varying availability between frames. Now, I think everyone here is either creating a game or evolving virtual creatures :P  I belong to the group that is evolving virtual creatures, and for this purpose the best thing is to keep any timesteps constant (or at least fully deterministic) sothat it doesn't affect fitness-evaluation in an unpredictable way (meaning by effects from outside the simulated system).

Well then, I defined each cycle to represent a 10 ms period. And I mean 10 ms in the simulated world, not in the real world. If I want a real-time simulation, then I just have to make sure that each cycle also takes 10 ms of real time, but in the end the results in the simulated world will be exactly the same, regardless of how fast (or slow) I render it on screen (as long as that doesn't affect the simulation timestep, nor the sub-frame integration resolution, which is 4 little steps per frame, thus representing 10/4 ms each). By the way, these numbers are just examples, I might as well use cycles of 50 ms, with two integration steps of 25 ms each for example (for purposes of illustrating the issue in these emails). So, the FOR-loop takes care of multiple integration steps, which indeed should be constant throughout a simulation.

I don't know if integration is the correct term for it, though. I guess it depends on how you look at it. You could say I run the simulation at a 0.0100-second timestep, and integrate each step at a resolution of 1/4th the stepsize. On the other hand, you could say I run the simulation at a 0.0025-second timestep, and only bother to do collision detection every 4 steps. But in the end, the only thing actually being integrated is the simulation as a whole, and I figured that the resolution of that integration could be measured for two things independently: Rigid-body Dynamics and Collision Detection. You can set both to a resolution of 10 ms, and everything will be fine. If I increase the resolution of the Dynamics while keeping the resolution of Collisions the same, then - or so I thought - I should at least benefit from higher accuracy in those Dynamics. But this doesn't seem to be the case. So I'll just stick with doing Dynamics and Collisions at the same interval until I find out where my reasoning fails.


> And I think finally the best solution is to call dJointGroupEmpty()
> just BEFORE dSpaceCollide(), so that contact joints are kept during
> all the multiple calls to dWorldStep() until a new call to dSpaceCollide
> is made.

Sounds like a good way to ensure the lifetime of those contact joints (being one full frame together with all the dWorldStep integration steps). In the first code example of my previous post, I indeed kept the contact joints until after the calls to dWorldStep were finished, and that was the idea I tried to convey all along - but which doesn't seem to work for me somehow. In the second code example, I deleted the contact joints immediately after the first call to dWorldStep, which I thought was the idea that you were proposing. I put that 2nd example there to illustrate how I interpreted the difference between your idea and mine, but now I'm not sure anymore what you're proposing :P But, if you're saying that you delete your contact joints just before dSpaceCollide (meaning they are old contact joints from the previous frame), then we were both essentially talking about the same idea when it comes to the lifetime of contact joints. Still, I haven't been able to get it working like that, but I'll happily settle for doing one dWorldStep per dSpaceCollide :-)

Greets,
Mark