[SOLVED] motion->getWorldTransform->getOrigin lag 1 step?

Post Reply
hyyou
Posts: 96
Joined: Wed Mar 16, 2016 10:11 am

[SOLVED] motion->getWorldTransform->getOrigin lag 1 step?

Post by hyyou »

I want to indirectly control btRigidBody's position by setting velocity,
but the Bullet's function getOrigin seem to lag (delay) by one timestep.

Here are pseudo code :-


At every time step (just before "stepSimulation") , I called this

Code: Select all

old   = getPositon(rigidBody);                      //print to "old"
targetPositionWish = Vec3(0,20,0);               //print to "wish"
velocityShould = targetPositionWish - old   ;  //print to "vel"
rigidBody->setLinearVelocity(velocityShould / timeInSecondPerTimeStep );
getPositon() uses getOrigin()

Code: Select all

btTransform kk;
motion->getWorldTransform(kk);    <---- this motion is the same pointer as when create RigidBody
return kk.getOrigin();
output

Code: Select all

0 old=(0,0,0)
0   wish=(0,20,0)
0   vel=(0,1200,0)
1 old=(0,0,0)    //<----- should be (0,20,0) now
1   wish=(0,20,0)
1   vel=(0,1200,0)
2 old=(0,20,0)   //<----- it happen at this line instead, too lag
2   wish=(0,20,0)
2   vel=(0,0.0001144409107,0)
Is it a known behavior? or .... Did I call wrong function/order?
If it is designed to be laggy (delay), how to set position via linear velocity?
Any a wild guess can help, thank! :D

Edit1: I misunderstood that linearVelocity is laggy, but actually getOrigin() is laggy.
Edit2: Using rigidBody->getCenterOfMassPosition() instead of getOrigin() is the solution for this problem.
But ... why getOrigin()!=getCenterOfMassPosition()?
Last edited by hyyou on Thu Mar 17, 2016 5:44 am, edited 1 time in total.
co2
Posts: 9
Joined: Mon Mar 14, 2016 3:46 pm

Re: motion-> getWorldTransform-> getOrigin() lag by 1 timest

Post by co2 »

Are you grabbing the extrapolated transform or the absolute transform? Bullet passes an extrapolated transform to your motion state. If you want the absolute transform you'll need to call btRigidBody::getWorldTransform(). That might be causing the mix-up you are encountering.
hyyou
Posts: 96
Joined: Wed Mar 16, 2016 10:11 am

Re: motion-> getWorldTransform-> getOrigin() lag by 1 timest

Post by hyyou »

Thank, co2! Your answer clarifies a lot.

How do I know whether I grabbed extrapolated transform or the absolute transform from motion?

Is motion always "extrapolated", if so can it be disabled?

I guess that bullet's motion extrapolate like that to be convenient for smooth-motion-rendering, but it is not common-sense for newbie like me.

If you don't mind, may you tell me how come you know that the btRigidBody's function is the answer (way of learning Bullet)?
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: [SOLVED] motion->getWorldTransform->getOrigin lag 1 step

Post by drleviathan »

I am wondering: What are you really trying to do? Are you trying to slave a dynamic object to a known constant position? Or are you trying to slave it to a known position that is changing? Does your object really need to be dynamic (is it even dynamic?) or can it be kinematic (moves but does not get deflected by collisions)?

Setting the position of a dynamic RigidBody by directly setting linear velocity can be a bit tricky. It tends to pump energy into the system.

Some ideas:

(1) You could try using a btFixedConstraint. This would tend to be more stable, and it would compute the velocities for you.

(2) If you really want to slam the velocity directly AND you can tolerate it taking a few simulation steps to get there then it is possible to provide "approximate stable critically damped motion" toward the target position by doing something like this:

Code: Select all

const btScalar DAMPED_TIMESCALE = 3.0 * timeInSecondPerTimeStep; // adjust this multiple as necessary, but for stability don't go below 3.0
btScalar clampedTimeRatio = (dt > DAMPED_TIMESCALE) ? 1.0 : dt / DAMPED_TIMESCALE; // clamp to 1.0 to enforce stability
btVector3 newLinearVelocity = (targetPosition - rigidBody->getPosition()) * clampedTimeRatio;
rigidBody->setLinearVelocity(newLinearVelocity);
It is stable, relatively fast, and easy to tune: just adjust DAMPED_TIMESCALE as needed. The timescale is basically the amount of time it would take the object to reduce its offset distance to 1/e of what it is now, so if its motion is uninhibited by collisions it should get very close to its target position within two or three timescales. Note that the object's current velocity is not accounted for in the math above, so it is "critically damped motion assuming starting from rest" -- it will not oscillate or overshoot its target at all. BTW, your own math is the same as this... for the case where clampedTimeRatio is always 1.0... when DAMPED_TIMESCALE is less than the timestep.
hyyou
Posts: 96
Joined: Wed Mar 16, 2016 10:11 am

Re: [SOLVED] motion->getWorldTransform->getOrigin lag 1 step

Post by hyyou »

drleviathan wrote:What are you really trying to do?
Bullet's constraint does not enforce the constraint condition precisely in every time step.

In some situation like animating a robot arm (child) attaching a main body (parent), I really want that precision.

I solved it by
  • 1. using Bullet's constraint.
    2. To render, I queries the physic position (and orientation) of the body from Bullet and calculate a fake position for the children.
drleviathan wrote: It tends to pump energy into the system.
Agree, so this fake position is usually used just for 3D rendering.
  • It is rarely set directly to the physic position of any objects.
    (The cases occur in only special events because it is physically incorrect.)
Without the fake , arm will be seen a bit detached from the body e.g. lag by 1-2 timesteps.

If it still seems to be silly, it is good to know.
Post Reply