[SOLVED] Solving for torque req to correct orientation

Van

22-05-2009 02:34:21

We have a 3D Space combat simulator game. I am working on some AI items.
I have my Agent and I want to align it's orientation to it's target using torque.
I want to derive a scalar between 0.0 (none required) - 1.0 (max required) for each torque axis ( x=yaw, y=pitch, z=roll) to supply to newton.
I need some help in dissecting what information I need to use and how to apply it. I think it has to be something like this:



Ogre::Quaternion mAgentOri, mTargetOri, mDiffOri;
Orge::Vector3 mAgentPos, mTargetPos;
..
// Solve for agent rotation to the target rotation.
mDiffOri = mTargetOri - mAgentOri; // A-B = B->A



OK, now I am lost. How do I get this data to just a vector3 that I then use to supply to Newton?
Is it as simple as:



Ogre::Vector3 mTorque = mDiffOri * Ogre::Vector3::UNIT_Y; // common up
mTorque.normalize();
mTorque.x = mYawRate * mTorque.x;
mTorque.y = mPitchRate * mTorque.y;
mTorque.z = mRollRate * mTorque.z;
...
NewtonBodySetOmega( mNewtonBody, &mTorque.x );

Van

24-05-2009 01:40:06

Also See: Ogre forums post here

Thank you all for your assistance. I finally got it to work. Here is the code for those who visit this thread later.
Realize that we are using a physics engine (newton) and are trying to utilize the same input controls that humans use. We use a scalar, -1.0 to +1.0 for torque and 0.0 to +1.0 for thrust, to determine how much of the "engine controls" to apply. Therefore it doesn't matter if the the input is keyboard, mouse, joystick or computed (i.e. AI) the input to our physics system is always a scalar that represents the amount power/torque to apply. For example:


void SetThrust(float Scalar)
{
float mMaxEngineThrust = 400.00;
float mThrustToUse = mScalar * mMaxEngineThrust;
..// make call to physics engine
} // SetThrust


Here is the agent Seek() and Flee() functions that we use.



//------------------------------- Seek -----------------------------------
//
// Given a target, this behavior returns a steering force which will
// direct the agent towards the target
//------------------------------------------------------------------------
void clsScripting::Seek(Ogre::Vector3 TargetPosition, Ogre::Quaternion TargetOrientation)
{
Ogre::Vector3 mAgentPosition = mGlobalResource->LocalPlayerObjectScene->getInventoryPosition();
Ogre::Quaternion mAgentOrientation = mGlobalResource->LocalPlayerObjectScene->getInventoryOrientation();
Ogre::Vector3 mVectorToTarget = TargetPosition - mAgentPosition; // A-B = B->A
mAgentPosition.normalise();
mAgentOrientation.normalise();

Ogre::Vector3 mAgentHeading = mAgentOrientation * mAgentPosition;
Ogre::Vector3 mTargetHeading = TargetOrientation * TargetPosition;
mAgentHeading.normalise();
mTargetHeading.normalise();

// Orientation control - Ogre::Vector3::UNIT_Y is common up vector.
Ogre::Vector3 mAgentVO = mAgentOrientation.Inverse() * Ogre::Vector3::UNIT_Y;
Ogre::Vector3 mTargetVO = TargetOrientation * Ogre::Vector3::UNIT_Y;

// Compute new torque scalar (-1.0 to 1.0) based on heading vector to target.
Ogre::Vector3 mSteeringForce = mAgentOrientation.Inverse() * mVectorToTarget;
mSteeringForce.normalise();

float mYaw = mSteeringForce.x;
float mPitch = mSteeringForce.y;
float mRoll = mTargetVO.getRotationTo( mAgentVO ).getRoll().valueRadians();

clsSystemControls::getSingleton().setPitchControl( mPitch );
clsSystemControls::getSingleton().setYawControl( mYaw );
clsSystemControls::getSingleton().setRollControl( mRoll );

} // Seek


//----------------------------- Flee -------------------------------------
//
// Does the opposite of Seek
//------------------------------------------------------------------------
void clsScripting::Flee(Ogre::Vector3 TargetPosition, Ogre::Quaternion TargetOrientation)
{
Ogre::Vector3 mAgentPosition = mGlobalResource->LocalPlayerObjectScene->getInventoryPosition();
Ogre::Quaternion mAgentOrientation = mGlobalResource->LocalPlayerObjectScene->getInventoryOrientation();
Ogre::Vector3 mVectorToTarget = TargetPosition - mAgentPosition; // A-B = B->A
mAgentPosition.normalise();
mAgentOrientation.normalise();

Ogre::Vector3 mAgentHeading = mAgentOrientation * mAgentPosition;
Ogre::Vector3 mTargetHeading = TargetOrientation * TargetPosition;
mAgentHeading.normalise();
mTargetHeading.normalise();

// Orientation control - Ogre::Vector3::UNIT_Y is common up vector.
Ogre::Vector3 mAgentVO = mAgentOrientation.Inverse() * Ogre::Vector3::UNIT_Y;
Ogre::Vector3 mTargetVO = TargetOrientation * Ogre::Vector3::UNIT_Y;

// Compute new torque scalar (-1.0 to 1.0) based on heading vector to target.
Ogre::Vector3 mSteeringForce = mAgentOrientation * mVectorToTarget;
mSteeringForce.normalise();

float mYaw = mSteeringForce.x;
float mPitch = mSteeringForce.y;
float mRoll = mTargetVO.getRotationTo( mAgentVO ).getRoll().valueRadians();

clsSystemControls::getSingleton().setPitchControl( mPitch );
clsSystemControls::getSingleton().setYawControl( mYaw );
clsSystemControls::getSingleton().setRollControl( mRoll );

} // Flee