Page 1 of 1

Impulse Based Methode

Posted: Mon Jan 29, 2007 12:13 am
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.

Posted: Mon Jan 29, 2007 8:54 am
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

Posted: Mon Jan 29, 2007 1:29 pm
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.

Posted: Wed Jan 31, 2007 7:34 am
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

Posted: Wed Jan 31, 2007 2:57 pm
by raigan2
Are you using the future/predicted state to determine the magnitude of the impulse?

Posted: Wed Jan 31, 2007 3:07 pm
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

Posted: Wed Jan 31, 2007 8:06 pm
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.

Posted: Thu Feb 01, 2007 1:09 am
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

Posted: Thu Feb 01, 2007 1:55 am
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??

Posted: Thu Feb 01, 2007 7:08 am
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