Impulse Based Methode

Please don't post Bullet support questions here, use the above forums instead.
MadMax
Posts: 6
Joined: Sun Jan 28, 2007 11:56 pm

Impulse Based Methode

Post by MadMax »

Hi,

at the moment i'm working on an simple Phyisk engine. I decided to use the Impuls Base Methode for solving constraints.
http://www.impulse-based.de
For testing i have implementet a simple Demo which is just a single pendular mountet on a fix point.
The Problem is that there is an error which slows the pendular over time so that after a long period it stands.

Here is the relevant part of my code may be somebody see an mistake.



This is the code to calculate the correct impuls

Code: Select all

bool MultiBodySystem::check_fix_constraint(STRUCT_JOINT* joint,float time)
{
	VECTOR3 p;
	VECTOR3 vec;
	float   dist;
	float   delta;
	VECTOR3 imp;

	p = joint->att_body1->look_ahead_world(joint->ref_point1,time);

	vec = p-joint->ref_point2;     //joint->ref_point2 == fix point pendular is mounted
	dist = vec.Length();
	
	delta  = joint->float_arr[0]-dist;   //joint->float_arr[0] == length of pendular

	if(abs(delta) < DIS_DELTA)
		return true;

	imp =(joint->att_body1->get_mass())*((delta/dist)*vec);
	imp = 1.0/time*imp;

	joint->att_body1->add_impulse_force(imp);

	return false;

}

Here is the code that is used to apply the impuls to a body

Code: Select all

void RigidBody::add_impulse_force(VECTOR3 force)
{
	this->center_velocity += 1.0/this->body_mass*force;
}
and finaly the code is used for look ahead and also to update position and velocity

Code: Select all


VECTOR3  RigidBody::integrate(bool look_ahead,float time)
{

	this->new_center_position = this->center_position + this->center_velocity*time+0.5*1.0/this->body_mass*time*time*this->frame_force; 
	this->new_center_velocity = this->center_velocity + 1.0/this->body_mass*time*this->frame_force;

	return this->new_center_position;
}

in frame_force is stored the gravity.

PS:

sorry for my bad english i am german.
Jan Bender
Posts: 111
Joined: Fri Sep 08, 2006 1:26 pm
Location: Germany

Post by Jan Bender »

Hi,
For testing i have implementet a simple Demo which is just a single pendular mountet on a fix point.
The Problem is that there is an error which slows the pendular over time so that after a long period it stands.
Your code seems to be okay. I just tried the same example with my own code and the pendulum is not slowed down. So probably something went wrong.

To get some more accurate results you should call the function "check_fix_constraint" multiple times until "abs(delta) < DIS_DELTA" is satisfied for a small DIS_DELTA (the smaller the more accuracy).
Is each joint point in the center of mass of its body?

Maybe you can send me the rest of the code and I take a look at it?

Jan
MadMax
Posts: 6
Joined: Sun Jan 28, 2007 11:56 pm

Post by MadMax »

thanks for your answer.

There is only one joint in the example it is direct in the center of the body.

I send you my code via mail.
Jan Bender
Posts: 111
Joined: Fri Sep 08, 2006 1:26 pm
Location: Germany

Post by Jan Bender »

For those who are interested... The solution of the problem was the following line:

Code: Select all

imp =(joint->att_body1->get_mass())*((delta/dist)*vec); 
This should look like this

Code: Select all

VECTOR3 dir = joint->ref_point1-joint->ref_point2;
imp =(joint->att_body1->get_mass())*((delta/dist)*dir); 
since the impulse must have the direction of the actual difference of the joint points and not the difference in the future.

Jan
raigan2
Posts: 197
Joined: Sat Aug 19, 2006 11:52 pm

Post by raigan2 »

Are you using the future/predicted state to determine the magnitude of the impulse?
Jan Bender
Posts: 111
Joined: Fri Sep 08, 2006 1:26 pm
Location: Germany

Post by Jan Bender »

Are you using the future/predicted state to determine the magnitude of the impulse?
Yes. I use the predicted state to approximate how the velocities of the bodies must change now so that the constraint will be satisfied in the future.

Jan
raigan2
Posts: 197
Joined: Sat Aug 19, 2006 11:52 pm

Post by raigan2 »

I'm not clear on how this works: lets say the current position error is (1,0) and the future error is (0,1) -- if you use the current positions to generate the impulse direction, no amount of scaling will be able to current the future error.
MadMax
Posts: 6
Joined: Sun Jan 28, 2007 11:56 pm

Post by MadMax »

There is no current error. If you start the iteration over the constriants all the constriants are satisfyed.


Image

This pic from Jans homepage should clarify it.

MFG
Manuel Fuchs
raigan2
Posts: 197
Joined: Sat Aug 19, 2006 11:52 pm

Post by raigan2 »

but if there is no current error, wouldn't the vector: dir = joint->ref_point1-joint->ref_point2
be null, since the joint-attachment-points will be coincident??
Jan Bender
Posts: 111
Joined: Fri Sep 08, 2006 1:26 pm
Location: Germany

Post by Jan Bender »

but if there is no current error, wouldn't the vector: dir = joint->ref_point1-joint->ref_point2
be null, since the joint-attachment-points will be coincident??
The direction is just required for the distance joint (a joint where the joint points have a distance > 0). So in this case the vector dir is never 0.

If you want to simulate a simple ball joint, then you don't need this current direction. In this case the impulse is:

p = K^{-1} * future_error

Jan