AI Agent Control         Seek and Flee using a physics engine
Print

Programming Game AI by Example - Resource Page(external link)

ai-junkie(external link)

 

Seek and Flee

Using a physics engine

Author:' Van'

Discussion: Computing course correction (steering)

Discussion: Solving for rotation difference with quaternions

Also see: Ogre wiki on Newton Game Dynamics

We use the newton physics engine(external link). We 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 into the physics engine. 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 are the Seek() and Flee() functions. These functions solve for a torque scalar.

//------------------------------- Seek -----------------------------------
//
//  Given a target, this behavior returns a steering force which will
//  direct the agent towards the target
//------------------------------------------------------------------------
void 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 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

 


Alias: AI_Agent_Control


Contributors to this page: spacegaier3733 points  , OgreWikiBot and jacmoe111451 points  .
Page last modified on Monday 07 of March, 2011 18:16:46 GMT by spacegaier3733 points .


The content on this page is licensed under the terms of the Creative Commons Attribution-ShareAlike License.
As an exception, any source code contributed within the content is released into the Public Domain.