Swamy
09-22-2010, 08:49 AM
AI controlling a spaceship – How to handle quaternion rotation by AI
Hi, community. And again I'm struggling with the rotations of the UDK. Actually I'm programming an AI which should fly a spaceship. I want that the AI has the same freedom in moving its spaceship as the player has, so it should be able to rotate freely and not be limited by euclidean rotation. But again I have the same problem like I had before, with the player controlled space ship. So I posted my problem here:
http://forums.epicgames.com/showthread.php?t=743407
So basically the AI-Spaceship should had onto a target and pursuit it if it's moving (in my case my AI dummy is heading for the player).
My first approach was to calculate the direction from the the AI-Ship to its target and convert it to an Rotator which would hold the desired direction where the ship should aim. Next I converted the actual Rotation of the AI-Ship and the desired rotation to a quaternion. With QuatSlerp I smoothly rotate the ship's rotation towards the desired rotation. Then convert it back to an Rotator which will be set as the pawns new rotation via SetDesiredRotation().
//out_ViewRot - actual rotation of the pawn
//DesDir - Rotator which points in direction of the target
function CalcRotation (out Rotator out_ViewRot, Rotator DesDir, float DeltaTime)
{
local Quat CurrQuat, AimQuat, NewQuat;
CurrQuat = QuatFromRotator(out_ViewRot);
AimQuat = QuatFromRotator(DesDir);
NewQuat = QuatSlerp(CurrQuat, AimQuat, 50*DeltaTime, true);
out_ViewRot = QuatToRotator(NewQuat);
}
But for some reason, the ship still doesn't freely rotate and describes the same behavior as the player-ship did before you guys helped me solving the problem.
So I tried another approach. This time I tried to simulate the player input and treat it the same way I did for the player. To do so I've written a function to calculate the rotation difference between to vectors. The quaternion between the two vectors is calculated with the built-in QuatFindBetween function and than converted in a Rotator.
**
* RotBetweenVect
*
* This function returns a rotator with pitch and yaw values which
* would be needed to rotate the first passed vector to the second one
*
* @param A - First vector
* @param B - Second vector
* @return DeltaRot - Pitch and Yaw rotation between vector A and B
*/
function Rotator RotBetweenVect(Vector A, Vector B)
{
local Rotator DeltaRot;
local Quat RotBetween;
RotBetween = QuatFindBetween(A,B);
DeltaRot = QuatToRotator(RotBetween);
return DeltaRot;
}
I pass the actual direction of the ship and the aiming direction to calculate a delta rotation which holds the values the AI needs to rotate the ship to aim it's target. Then I use a modified version of ProcessRotation to simulate the AI rotation behavior and apply it to the rotation of the ship.
function ProcRotation ( float DeltaTime, out rotator out_ViewRotation, out Rotator out_DeltaRot )
{
//Apply a rotation rate to simulate humanlike aiming behaviour
out_DeltaRot.Pitch *= (10*DeltaTime);
out_DeltaRot.Roll *= (10*DeltaTime);
out_DeltaRot.Yaw *= (10*DeltaTime);
out_ViewRotation = RTransform(out_DeltaRot, out_ViewRotation);
out_DeltaRot = rot(0,0,0);
}
But this way the rotations sometimes totally messes up especially at the poles, it suddenly starts spinning around randomly or uses not the shortest path to get to the desired rotation.
I've tried many other things too but these two seemed to be the most promising one. I've searched Object and Actor class for useful function but actually I wasn't able to find them. Actually I'm stuck and have no idea where to look for new opportunities and it seems that AI simply isn't able to deal with quaternion rotation... Hope you guys can help me again - thanking you in anticipation
Hi, community. And again I'm struggling with the rotations of the UDK. Actually I'm programming an AI which should fly a spaceship. I want that the AI has the same freedom in moving its spaceship as the player has, so it should be able to rotate freely and not be limited by euclidean rotation. But again I have the same problem like I had before, with the player controlled space ship. So I posted my problem here:
http://forums.epicgames.com/showthread.php?t=743407
So basically the AI-Spaceship should had onto a target and pursuit it if it's moving (in my case my AI dummy is heading for the player).
My first approach was to calculate the direction from the the AI-Ship to its target and convert it to an Rotator which would hold the desired direction where the ship should aim. Next I converted the actual Rotation of the AI-Ship and the desired rotation to a quaternion. With QuatSlerp I smoothly rotate the ship's rotation towards the desired rotation. Then convert it back to an Rotator which will be set as the pawns new rotation via SetDesiredRotation().
//out_ViewRot - actual rotation of the pawn
//DesDir - Rotator which points in direction of the target
function CalcRotation (out Rotator out_ViewRot, Rotator DesDir, float DeltaTime)
{
local Quat CurrQuat, AimQuat, NewQuat;
CurrQuat = QuatFromRotator(out_ViewRot);
AimQuat = QuatFromRotator(DesDir);
NewQuat = QuatSlerp(CurrQuat, AimQuat, 50*DeltaTime, true);
out_ViewRot = QuatToRotator(NewQuat);
}
But for some reason, the ship still doesn't freely rotate and describes the same behavior as the player-ship did before you guys helped me solving the problem.
So I tried another approach. This time I tried to simulate the player input and treat it the same way I did for the player. To do so I've written a function to calculate the rotation difference between to vectors. The quaternion between the two vectors is calculated with the built-in QuatFindBetween function and than converted in a Rotator.
**
* RotBetweenVect
*
* This function returns a rotator with pitch and yaw values which
* would be needed to rotate the first passed vector to the second one
*
* @param A - First vector
* @param B - Second vector
* @return DeltaRot - Pitch and Yaw rotation between vector A and B
*/
function Rotator RotBetweenVect(Vector A, Vector B)
{
local Rotator DeltaRot;
local Quat RotBetween;
RotBetween = QuatFindBetween(A,B);
DeltaRot = QuatToRotator(RotBetween);
return DeltaRot;
}
I pass the actual direction of the ship and the aiming direction to calculate a delta rotation which holds the values the AI needs to rotate the ship to aim it's target. Then I use a modified version of ProcessRotation to simulate the AI rotation behavior and apply it to the rotation of the ship.
function ProcRotation ( float DeltaTime, out rotator out_ViewRotation, out Rotator out_DeltaRot )
{
//Apply a rotation rate to simulate humanlike aiming behaviour
out_DeltaRot.Pitch *= (10*DeltaTime);
out_DeltaRot.Roll *= (10*DeltaTime);
out_DeltaRot.Yaw *= (10*DeltaTime);
out_ViewRotation = RTransform(out_DeltaRot, out_ViewRotation);
out_DeltaRot = rot(0,0,0);
}
But this way the rotations sometimes totally messes up especially at the poles, it suddenly starts spinning around randomly or uses not the shortest path to get to the desired rotation.
I've tried many other things too but these two seemed to be the most promising one. I've searched Object and Actor class for useful function but actually I wasn't able to find them. Actually I'm stuck and have no idea where to look for new opportunities and it seems that AI simply isn't able to deal with quaternion rotation... Hope you guys can help me again - thanking you in anticipation