by Julio Jerez » Mon Jan 05, 2009 12:58 pm
That’s and interesting problem.
You can do it in two ways, one is in a force call back, there is making unilateral joint controller.
In both cases the math is the same but the application a little different.
The advantage of the joint is that give you more steering control, but the force callback is good too.
Here sit ha math, and it is all base of the method you are already using to get the rotation that will align the missile to the target.
In you method afte to get the quatenion q this what you do.
Remembet that the expression of a quaterion is given by
Q(q0, q1, q2, q3)
Where
Q0 = cos (a /2)
Q1, q2, q3 = sin(a/2) * vector (x, y, z)
You can interpreted that like this if the missile was at rest, (no angular velocity and no linear velocity)
What instantaneous angular velocity w around the unit vector (x, y, z) will align the missile with the target? The answer is given by.
W = a / dt
You can easily get a from q0
a = 2.0 * acos(q0);
therefore
|W| = a / dt
The direction vector of the angula velocity magnitude is given by:
Dir = normilze (q1, q2, q3)
Now w in vectors form is
W = dir * (a / (k * dt))
Now you know the this is a angular velocity the will take the missile for the rest position, bu if the missil was already spinning you need to subtract the missile velocity from the theoretical W
W = dir * (a / (k * dt)) - Missele.GetOmega();
Now you know what angular velocity to apply to the missile, to convert that into a angular acceleration, all you need to do is divide it by the time step.
You need to use a scale value of the time because if you use the same dt of the simulation then it will over shoot
Alpha = W * ( 1.0/dt * K))
K can be 2, 3, … I find the 3 is a nice value for smotth steering.
That will take care of the direction, you still need to steer the, the idea is the same.
You can get the direction vector form the missile to the target,
Dir = normalize (missile.position – targetPosition)
You can decompose the missile velocity alone that direction vectors
Velc_tanget = dotproduct (MissileVelociti, dir)
Veloc_Lateral = MissileVelociti - dotproduct (MissileVelociti, dir)
Now you need to drive Veloc_Lateral by adding an velocity to counter act it
That is;
Correction_Vel = -Veloc_Lateral
Then you can convert Correction_Vel to an acceleration
Accel = Correction_Vel * (1.0 / (dt * k));
Again k is a scale of the time step
teh you mutiply thiose values by teh Inertia and the mass, and you add then to the body.