You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
4.5 KiB

// Copyright (C) 2009 - 2012 Mathias Froehlich
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef AIPhysics_hxx
#define AIPhysics_hxx
#include <simgear/math/SGMath.hxx>
#include "AISubsystem.hxx"
namespace fgai {
class AIPhysics : public AISubsystem {
public:
/// Initial conditions need to be set at creation time.
/// Just setting the position underway will result in unphysical motion.
AIPhysics(const AIPhysics& physics);
AIPhysics(const SGLocationd& location, const SGVec3d& linearBodyVelocity = SGVec3d::zeros(),
const SGVec3d& angularBodyVelocity = SGVec3d::zeros());
virtual ~AIPhysics();
/// The default is unaccelerated movement
virtual void update(AIObject& object, const SGTimeStamp& dt);
/// The current state
const SGLocationd& getLocation() const
{ return _location; }
const SGVec3d& getPosition() const
{ return _location.getPosition(); }
const SGQuatd& getOrientation() const
{ return _location.getOrientation(); }
const SGGeod& getGeodPosition() const
{ return _geodPosition; }
const SGQuatd& getHorizontalLocalOrientation() const
{ return _horizontalLocalOrientation; }
/// The orientation of the body wrt the geodetic ned coordinate system
SGQuatd getGeodOrientation() const
{ return inverse(_horizontalLocalOrientation)*_location.getOrientation(); }
const SGVec3d& getLinearBodyVelocity() const
{ return _linearBodyVelocity; }
const SGVec3d& getAngularBodyVelocity() const
{ return _angularBodyVelocity; }
/// The velocity in global cartesian coordinates
SGVec3d getLinearVelocity() const
{ return _location.getOrientation().backTransform(_linearBodyVelocity); }
/// The velocity in the north east down coordinate system
/// Note that this gets undefined at the poles.
SGVec3d getGeodVelocity() const
{ return getGeodOrientation().backTransform(getLinearBodyVelocity()); }
double getDownVelocity() const
{ return getGeodVelocity()[2]; }
SGVec2d getHorizontalVelocity() const
{ SGVec3d v = getGeodVelocity(); return SGVec2d(v[0], v[1]); }
protected:
/// The below methods change the position and velocity of the vehicle
/// in a way that is consistent in that it matches position, velocity
/// values to keep the velocity a numerical derivative of the position.
/// Given the accelerations at the current simulation time mSimTime,
/// update the position and velocity to mSimTime + dt.
/// This is the primary advance mode for physically simulated motion.
/// Compute the forces on the single body, compute the accelerations
/// from the forces by newtons law and accelerate by this amount.
void advanceByBodyAcceleration(const double& dt,
const SGVec3d& linearAcceleration,
const SGVec3d& angularAcceleration);
/// Given the velocities at the next simulation time mSimTime,
/// update the position and velocity to mSimTime + dt.
void advanceByBodyVelocity(const double& dt,
const SGVec3d& linearVelocity,
const SGVec3d& angularVelocity);
/// Given the desired position and orientation, a pair of velocities
/// is computed to reach that position and orientation in the
/// next advance step. This one advance step latency is important
/// for other participants to correctly extrapolate the position
/// and orientation based on the velocities.
/// Note that this only works when the next update is called with
/// the same time increment.
void advanceToLocation(const double& dt, const SGLocationd& location);
private:
AIPhysics& operator=(const AIPhysics& physics);
SGLocationd _location;
SGVec3d _linearBodyVelocity;
SGVec3d _angularBodyVelocity;
SGGeod _geodPosition;
SGQuatd _horizontalLocalOrientation;
};
} // namespace fgai
#endif