rotating wheel space station: timesteps & jitter

Post Reply
scallop
Posts: 1
Joined: Fri Oct 05, 2012 4:08 am

rotating wheel space station: timesteps & jitter

Post by scallop »

Hi all,

I'm playing with a simulation of a "rotating wheel space station", like in the movie 2001. (I'll assume you're familiar with the idea).

I have some questions about timesteps & how to tweak bullet for this situation.

In each timestep the objects in the wheel move tangientially to the wheel, but the surface of the wheel curves and pushes them radially inwards (simulating gravity). So in each timestep there is penetration of the objects into the wheel surface that needs to be corrected.

Now, stepSimulation() divides the step into substeps, and I found it is important that I rotate the wheel (a kinematic object) for every substep to have the correct contacts. I see two ways to do this. The 'built-in' way is to use mWorld->setInternalTickCallback and rotate the wheel each time the callback is called. The other way is to manually subdivide time for each frame and call stepSimulation() repeatedly with a small time step, updating the wheel before each call. I would expect these to give similar results, but I found that using the callback results in a lot more jitter, and that the jitter increases as I decrease the substep size (!).

Here is the relevant code showing both methods. I'm using dbvt for broadphase and the sequential impulse constraint solver with numiterations=20 and splitimpulse=true. Everything else is default. The wheel is made out of ~100 box shapes arranged in a circle.

Code: Select all

void tickCallBack(btDynamicsWorld *world, btScalar timeStep){
	StationDemo *demo = static_cast<StationDemo *>(world->getWorldUserInfo());
	demo->stepStation(timeStep);
}

void StationDemo::stepStation(btScalar timeStep){
	for(int i = 0; i < nStationSegments; i++){
		stationMotions[i]->step(timeStep);
	}
}

void StationDemo::clientMoveAndDisplay()
{

	float ms = getDeltaTimeMicroseconds();
	double dt = ms/1000000.f;
	double subdt = (1.0/60)/EXTRASUBDIV;
	int nsubdiv = dt/subdt;

#ifdef SUBDIVIDE
	for(int i = 0; i < nsubdiv; i++){
		stepStation(subdt);
		m_dynamicsWorld->stepSimulation(subdt,0);
	} //(I realize I am losing a small 'partial substep' of time here if dt/subdt is not an integer)
#else
	m_dynamicsWorld->stepSimulation(dt, nsubdiv+10, subdt);
	//and elsewhere call m_dynamicsWorld->setInternalTickCallback(tickCallBack, static_cast<void *>(this));
#endif

	.... (render)
}
I can post the full code if desired.

Secondly, I find I need to have fairly small substeps (when I do substeps manually) to reduce the jitter to "reasonable" levels. The jitter is mainly noticeable when the objects are sliding on the surface. On the one hand, I went into this expecting a lot of jitter because the outer edge of the wheel moves at very high velocity & there will be frequent penetration. On the other hand, the amount of penetration of the object into the wheel in one timestep should be very similar in magnitude to the penetration of an object falling under gravity onto a flat surface in one timestep. (I adjust the angular velocity of the wheel so that the 'effective gravity' is earth gravity). The difference is that in the wheel case, the object + surface are also moving to the side at high velocity, and there is a tiny amount of rotation happening each time step. How much do these differences contribute to the jitter? Or is something else the most significant contribution (eg invalidation of contact manifolds or something like that?) I've gathered that bullet treats motion due to gravity specially - could that treatment be extended to this "simulated gravity"?

I did some other tests involving a block falling on a moving platform: First, of a block falling under gravity onto a surface, but both block & surface are moving to the side at high velocity. This one didn't have much jitter. Second, where there is no gravity, but the surface is accelerating upwards (into the block) at 9.81 m/s2. I get lots of extra jitter here when using the 'callback' method to move the surface, and bit of extra jitter when manually subdividing time.

Does anyone have any insight into how I might reduce jitter without decreasing the time step? Am I using the callback correctly?
Post Reply