1
0
Fork 0

Add David Culp's AI model manager code which is derived from David Luff's AI/ATC code.

This commit is contained in:
ehofman 2003-11-28 15:48:05 +00:00
parent 06ce7ae928
commit cd0c447b43
17 changed files with 1044 additions and 0 deletions

View file

@ -505,6 +505,7 @@ AC_CONFIG_FILES([ \
src/Main/runfgfs \
src/Main/runfgfs.bat \
src/Model/Makefile \
src/AIModel/Makefile \
src/MultiPlayer/Makefile \
src/Navaids/Makefile \
src/Network/Makefile \

3
src/AIModel/.cvsignore Normal file
View file

@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in

202
src/AIModel/AIAircraft.cxx Normal file
View file

@ -0,0 +1,202 @@
// FGAIAircraft - FGAIBase-derived class creates an AI airplane
//
// Written by David Culp, started October 2003.
//
// Copyright (C) 2003 David P. Culp - davidculp2@comcast.net
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/math/point3d.hxx>
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
#include <string>
#include <math.h>
SG_USING_STD(string);
#include "AIAircraft.hxx"
FGAIAircraft::FGAIAircraft() {
// set heading and altitude locks
hdg_lock = false;
alt_lock = false;
}
FGAIAircraft::~FGAIAircraft() {
}
bool FGAIAircraft::init() {
return FGAIBase::init();
}
void FGAIAircraft::update(double dt) {
Run(dt);
Transform();
FGAIBase::update(dt);
}
void FGAIAircraft::SetPerformance(PERF_STRUCT ps) {
performance = ps;
}
void FGAIAircraft::Run(double dt) {
FGAIAircraft::dt = dt;
double turn_radius_ft;
double turn_circum_ft;
double speed_north_deg_sec;
double speed_east_deg_sec;
double ft_per_deg_lon;
double ft_per_deg_lat;
double dist_covered_ft;
double alpha;
// get size of a degree at this latitude
ft_per_deg_lat = 366468.96 - 3717.12 * cos(pos.lat() / 57.2958 );
ft_per_deg_lon = 365228.16 * cos(pos.lat() / 57.2958);
// adjust speed
double speed_diff = tgt_speed - speed;
if (fabs(speed_diff) > 0.2) {
if (speed_diff > 0.0) speed += performance.accel * dt;
if (speed_diff < 0.0) speed -= performance.decel * dt;
}
// convert speed to degrees per second
speed_north_deg_sec = cos( hdg / 57.29577951 ) * speed * 1.686 / ft_per_deg_lat;
speed_east_deg_sec = sin( hdg / 57.29577951 ) * speed * 1.686 / ft_per_deg_lon;
// set new position
pos.setlat( pos.lat() + speed_north_deg_sec * dt);
pos.setlon( pos.lon() + speed_east_deg_sec * dt);
// adjust heading based on current bank angle
if (roll != 0.0) {
turn_radius_ft = 0.088362 * speed * speed / tan( fabs(roll) / 57.2958 );
turn_circum_ft = 6.2831853 * turn_radius_ft;
dist_covered_ft = speed * 1.686 * dt;
alpha = dist_covered_ft / turn_circum_ft * 360.0;
hdg += alpha * sign( roll );
if ( hdg > 360.0 ) hdg -= 360.0;
if ( hdg < 0.0) hdg += 360.0;
}
// adjust target bank angle if heading lock engaged
if (hdg_lock) {
double bank_sense = 0.0;
double diff = fabs(hdg - tgt_heading);
if (diff > 180) diff = fabs(diff - 360);
double sum = hdg + diff;
if (sum > 360.0) sum -= 360.0;
if (fabs(sum - tgt_heading) < 1.0) {
bank_sense = 1.0;
} else {
bank_sense = -1.0;
}
if (diff < 30) tgt_roll = diff * bank_sense;
}
// adjust bank angle
double bank_diff = tgt_roll - roll;
if (fabs(bank_diff) > 0.2) {
if (bank_diff > 0.0) roll += 5.0 * dt;
if (bank_diff < 0.0) roll -= 5.0 * dt;
}
// adjust altitude (meters) based on current vertical speed (fpm)
altitude += vs * 0.0166667 * dt * 0.3048;
// find target vertical speed if altitude lock engaged
if (alt_lock) {
double altitude_ft = altitude * 3.28084;
if (altitude_ft < tgt_altitude) {
tgt_vs = tgt_altitude - altitude_ft;
if (tgt_vs > performance.climb_rate) tgt_vs = performance.climb_rate;
} else {
tgt_vs = tgt_altitude - altitude_ft;
if (tgt_vs < (-performance.descent_rate)) tgt_vs = -performance.descent_rate;
}
}
// adjust vertical speed
double vs_diff = tgt_vs - vs;
if (fabs(vs_diff) > 1.0) {
if (vs_diff > 0.0) {
vs += 400.0 * dt;
if (vs > tgt_vs) vs = tgt_vs;
} else {
vs -= 300.0 * dt;
if (vs < tgt_vs) vs = tgt_vs;
}
}
// match pitch angle to vertical speed
pitch = vs * 0.005;
}
void FGAIAircraft::AccelTo(double speed) {
tgt_speed = speed;
}
void FGAIAircraft::PitchTo(double angle) {
tgt_pitch = angle;
alt_lock = false;
}
void FGAIAircraft::RollTo(double angle) {
tgt_roll = angle;
hdg_lock = false;
}
void FGAIAircraft::YawTo(double angle) {
tgt_yaw = angle;
}
void FGAIAircraft::ClimbTo(double altitude) {
tgt_altitude = altitude;
alt_lock = true;
}
void FGAIAircraft::TurnTo(double heading) {
tgt_heading = heading;
hdg_lock = true;
}
double FGAIAircraft::sign(double x) {
if ( x < 0.0 ) { return -1.0; }
else { return 1.0; }
}

View file

@ -0,0 +1,62 @@
// FGAIAircraft - AIBase derived class creates an AI aircraft
//
// Written by David Culp, started October 2003.
//
// Copyright (C) 2003 David P. Culp - davidculp2@comcast.net
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifndef _FG_AIAircraft_HXX
#define _FG_AIAircraft_HXX
#include "AIManager.hxx"
#include "AIBase.hxx"
#include <string>
SG_USING_STD(string);
class FGAIAircraft : public FGAIBase {
public:
FGAIAircraft();
~FGAIAircraft();
bool init();
void update(double dt);
void SetPerformance(PERF_STRUCT ps);
void AccelTo(double speed);
void PitchTo(double angle);
void RollTo(double angle);
void YawTo(double angle);
void ClimbTo(double altitude);
void TurnTo(double heading);
private:
bool hdg_lock;
bool alt_lock;
double dt;
PERF_STRUCT performance;
void Run(double dt);
double sign(double x);
};
#endif // _FG_AIAircraft_HXX

117
src/AIModel/AIBallistic.cxx Normal file
View file

@ -0,0 +1,117 @@
// FGAIBallistic - FGAIBase-derived class creates a ballistic object
//
// Written by David Culp, started November 2003.
// - davidculp2@comcast.net
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/math/point3d.hxx>
#include <math.h>
#include "AIBallistic.hxx"
FGAIBallistic::FGAIBallistic() {
}
FGAIBallistic::~FGAIBallistic() {
}
bool FGAIBallistic::init() {
FGAIBase::init();
vs = sin( elevation * 0.017453293 ) * speed;
hs = cos( elevation * 0.017453293 ) * speed;
aero_stabilized = true;
hdg = azimuth;
pitch = elevation;
return true;
}
void FGAIBallistic::update(double dt) {
Run(dt);
Transform();
FGAIBase::update(dt);
}
void FGAIBallistic::setAzimuth(double az) {
azimuth = az;
}
void FGAIBallistic::setElevation(double el) {
elevation = el;
}
void FGAIBallistic::setStabilization(bool val) {
aero_stabilized = val;
}
void FGAIBallistic::Run(double dt) {
double speed_north_deg_sec;
double speed_east_deg_sec;
double ft_per_deg_lon;
double ft_per_deg_lat;
// get size of a degree at this latitude
ft_per_deg_lat = 366468.96 - 3717.12 * cos(pos.lat() / 57.2958 );
ft_per_deg_lon = 365228.16 * cos(pos.lat() / 57.2958);
// the two drag calculations below assume sea-level density,
// mass of 0.03 slugs, drag coeff of 0.295, frontal area of 0.007 ft2
// adjust horizontal speed due to drag
hs -= 0.000082 * hs * hs * dt;
if ( hs < 0.0 ) hs = 0.0;
// adjust vertical speed due to drag
if (vs > 0.0) {
vs -= 0.000082 * vs * vs * dt;
} else {
vs += 0.000082 * vs * vs * dt;
}
// convert horizontal speed (fps) to degrees per second
speed_north_deg_sec = cos( hdg / 57.29577951 ) * hs / ft_per_deg_lat;
speed_east_deg_sec = sin( hdg / 57.29577951 ) * hs / ft_per_deg_lon;
// set new position
pos.setlat( pos.lat() + speed_north_deg_sec * dt);
pos.setlon( pos.lon() + speed_east_deg_sec * dt);
// adjust vertical speed for acceleration of gravity
vs -= 32.17 * dt;
// adjust altitude (meters)
altitude += vs * dt * 0.3048;
pos.setelev(altitude);
// adjust pitch if aerostabilized
if (aero_stabilized) pitch = atan2( vs, hs ) * 57.29577951;
// set destruction flag if altitude less than sea level -1000
if (altitude < -1000.0) setDie(true);
}

View file

@ -0,0 +1,51 @@
// FGAIBallistic - AIBase derived class creates an AI ballistic object
//
// Written by David Culp, started November 2003.
// - davidculp2@comcast.net
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifndef _FG_AIBALLISTIC_HXX
#define _FG_AIBALLISTIC_HXX
#include "AIManager.hxx"
#include "AIBase.hxx"
class FGAIBallistic : public FGAIBase {
public:
FGAIBallistic();
~FGAIBallistic();
bool init();
void update(double dt);
void setAzimuth( double az );
void setElevation( double el );
void setStabilization( bool val );
private:
double azimuth; // degrees true
double elevation; // degrees
double hs; // horizontal speed (fps)
bool aero_stabilized; // if true, object will point where it's going
void Run(double dt);
};
#endif // _FG_AIBALLISTIC_HXX

97
src/AIModel/AIBase.cxx Normal file
View file

@ -0,0 +1,97 @@
// FGAIBase - abstract base class for AI objects
// Written by David Culp, started Nov 2003, based on
// David Luff's FGAIEntity class.
// - davidculp2@comcast.net
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <plib/sg.h>
#include <plib/ssg.h>
#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
#include <simgear/math/point3d.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/scene/model/location.hxx>
#include <simgear/scene/model/model.hxx>
#include <simgear/debug/logstream.hxx>
#include <string>
#include "AIBase.hxx"
FGAIBase::~FGAIBase() {
}
void FGAIBase::update(double dt) {
}
void FGAIBase::Transform() {
aip.setPosition(pos.lon(), pos.lat(), pos.elev() * SG_METER_TO_FEET);
aip.setOrientation(roll, pitch, hdg);
aip.update( globals->get_scenery()->get_center() );
}
bool FGAIBase::init() {
ssgBranch *model = sgLoad3DModel( globals->get_fg_root(),
model_path.c_str(),
globals->get_props(),
globals->get_sim_time_sec() );
if (model) {
aip.init( model );
aip.setVisible(true);
globals->get_scenery()->get_scene_graph()->addKid(aip.getSceneGraph());
} else {
SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load aircraft model.");
}
tgt_roll = tgt_pitch = tgt_yaw = tgt_vs = vs = roll = pitch = 0.0;
}
void FGAIBase::setPath( const char* model ) {
model_path.append(model);
}
void FGAIBase::setSpeed( double speed_KTAS ) {
speed = tgt_speed = speed_KTAS;
}
void FGAIBase::setAltitude( double altitude_ft ) {
altitude = tgt_altitude = altitude_ft;
pos.setelev(altitude * 0.3048);
}
void FGAIBase::setLongitude( double longitude ) {
pos.setlon(longitude);
}
void FGAIBase::setLatitude( double latitude ) {
pos.setlat(latitude);
}
void FGAIBase::setHeading( double heading ) {
hdg = tgt_heading = heading;
}
void FGAIBase::setDie( bool die ) {
delete_me = die;
}

74
src/AIModel/AIBase.hxx Normal file
View file

@ -0,0 +1,74 @@
// FGAIBase - abstract base class for AI objects
// Written by David Culp, started Nov 2003, based on
// David Luff's FGAIEntity class.
// - davidculp2@comcast.net
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifndef _FG_AIBASE_HXX
#define _FG_AIBASE_HXX
#include <simgear/math/point3d.hxx>
#include <simgear/scene/model/placement.hxx>
#include <string>
SG_USING_STD(string);
class FGAIBase {
public:
virtual ~FGAIBase();
virtual void update(double dt);
inline Point3D GetPos() { return(pos); }
virtual bool init();
void setPath( const char* model );
void setSpeed( double speed_KTAS );
void setAltitude( double altitude_ft );
void setLongitude( double longitude );
void setLatitude( double latitude );
void setHeading( double heading );
void setDie( bool die );
inline bool getDie() { return delete_me; }
protected:
Point3D pos; // WGS84 lat & lon in degrees, elev above sea-level in meters
double hdg; // True heading in degrees
double roll; // degrees, left is negative
double pitch; // degrees, nose-down is negative
double speed; // knots true airspeed
double altitude; // meters above sea level
double vs; // vertical speed, feet per minute
double tgt_heading; // target heading, degrees true
double tgt_altitude; // target altitude, *feet* above sea level
double tgt_speed; // target speed, KTAS
double tgt_roll;
double tgt_pitch;
double tgt_yaw;
double tgt_vs;
string model_path; //Path to the 3D model
SGModelPlacement aip;
bool delete_me;
void Transform();
};
#endif // _FG_AIBASE_HXX

127
src/AIModel/AIManager.cxx Normal file
View file

@ -0,0 +1,127 @@
// AIManager.cxx Based on David Luff's AIMgr:
// - a global management class for AI objects
//
// Written by David Culp, started October 2003.
// - davidculp2@comcast.net
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <simgear/misc/sg_path.hxx>
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <list>
#include "AIManager.hxx"
#include "AIAircraft.hxx"
#include "AIShip.hxx"
#include "AIBallistic.hxx"
SG_USING_STD(list);
FGAIManager::FGAIManager() {
initDone = false;
}
FGAIManager::~FGAIManager() {
ai_list.clear();
}
void FGAIManager::init() {
SGPropertyNode * node = fgGetNode("sim/ai", true);
for (int i = 0; i < node->nChildren(); i++) {
const SGPropertyNode * entry = node->getChild(i);
if (!strcmp(entry->getName(), "entry")) {
if (!strcmp(entry->getStringValue("type", ""), "aircraft")) {
FGAIAircraft* ai_plane = new FGAIAircraft;
ai_list.push_back(ai_plane);
if (!strcmp(entry->getStringValue("class", ""), "light")) {
PERF_STRUCT ps = {2.0, 2.0, 450.0, 1000.0, 70.0, 80.0, 100.0, 80.0, 60.0};
ai_plane->SetPerformance(ps);
} else if (!strcmp(entry->getStringValue("class", ""), "ww2_fighter")) {
PERF_STRUCT ps = {4.0, 2.0, 3000.0, 1500.0, 110.0, 180.0, 250.0, 200.0, 100.0};
ai_plane->SetPerformance(ps);
} else if (!strcmp(entry->getStringValue("class", ""), "jet_transport")) {
PERF_STRUCT ps = {5.0, 2.0, 3000.0, 1500.0, 140.0, 300.0, 430.0, 300.0, 130.0};
ai_plane->SetPerformance(ps);
} else if (!strcmp(entry->getStringValue("class", ""), "jet_fighter")) {
PERF_STRUCT ps = {7.0, 3.0, 4000.0, 2000.0, 150.0, 350.0, 500.0, 350.0, 150.0};
ai_plane->SetPerformance(ps);
}
ai_plane->setHeading(entry->getDoubleValue("heading"));
ai_plane->setSpeed(entry->getDoubleValue("speed-KTAS"));
ai_plane->setPath(entry->getStringValue("path"));
ai_plane->setAltitude(entry->getDoubleValue("altitude-ft"));
ai_plane->setLongitude(entry->getDoubleValue("longitude"));
ai_plane->setLatitude(entry->getDoubleValue("latitude"));
ai_plane->init();
} else if (!strcmp(entry->getStringValue("type", ""), "ship")) {
FGAIShip* ai_ship = new FGAIShip;
ai_list.push_back(ai_ship);
ai_ship->setHeading(entry->getDoubleValue("heading"));
ai_ship->setSpeed(entry->getDoubleValue("speed-KTAS"));
ai_ship->setPath(entry->getStringValue("path"));
ai_ship->setAltitude(entry->getDoubleValue("altitude-ft"));
ai_ship->setLongitude(entry->getDoubleValue("longitude"));
ai_ship->setLatitude(entry->getDoubleValue("latitude"));
ai_ship->init();
} else if (!strcmp(entry->getStringValue("type", ""), "ballistic")) {
FGAIBallistic* ai_ballistic = new FGAIBallistic;
ai_list.push_back(ai_ballistic);
ai_ballistic->setAzimuth(entry->getDoubleValue("azimuth"));
ai_ballistic->setElevation(entry->getDoubleValue("elevation"));
ai_ballistic->setSpeed(entry->getDoubleValue("speed-fps"));
ai_ballistic->setPath(entry->getStringValue("path"));
ai_ballistic->setAltitude(entry->getDoubleValue("altitude-ft"));
ai_ballistic->setLongitude(entry->getDoubleValue("longitude"));
ai_ballistic->setLatitude(entry->getDoubleValue("latitude"));
ai_ballistic->init();
}
}
}
initDone = true;
}
void FGAIManager::bind() {
}
void FGAIManager::unbind() {
}
void FGAIManager::update(double dt) {
#if 0
if(!initDone) {
init();
SG_LOG(SG_ATC, SG_WARN, "Warning - AIManager::update(...) called before AIManager::init()");
}
#endif
ai_list_itr = ai_list.begin();
while(ai_list_itr != ai_list.end()) {
if ((*ai_list_itr)->getDie()) {
ai_list.erase(ai_list_itr, ai_list_itr);
} else {
(*ai_list_itr)->update(dt);
}
++ai_list_itr;
}
}

80
src/AIModel/AIManager.hxx Normal file
View file

@ -0,0 +1,80 @@
// AIManager.hxx - experimental! - David Culp - based on:
// AIMgr.hxx - definition of FGAIMgr
// - a global management class for FlightGear generated AI traffic
//
// Written by David Luff, started March 2002.
//
// Copyright (C) 2002 David C Luff - david.luff@nottingham.ac.uk
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifndef _FG_AIMANAGER_HXX
#define _FG_AIMANAGER_HXX
#include <simgear/structure/subsystem_mgr.hxx>
#include <Main/fg_props.hxx>
#include <list>
#include "AIBase.hxx"
SG_USING_STD(list);
struct PERF_STRUCT {
double accel;
double decel;
double climb_rate;
double descent_rate;
double takeoff_speed;
double climb_speed;
double cruise_speed;
double descent_speed;
double land_speed;
};
class FGAIManager : public SGSubsystem
{
private:
// A list of pointers to AI objects
typedef list <FGAIBase*> ai_list_type;
typedef ai_list_type::iterator ai_list_iterator;
typedef ai_list_type::const_iterator ai_list_const_iterator;
// Everything put in this list should be created dynamically
// on the heap and ***DELETED WHEN REMOVED!!!!!***
ai_list_type ai_list;
ai_list_iterator ai_list_itr;
public:
enum object_type { otAircraft, otShip, otBallistic, otRocket };
FGAIManager();
~FGAIManager();
void init();
void bind();
void unbind();
void update(double dt);
private:
bool initDone;
};
#endif // _FG_AIMANAGER_HXX

153
src/AIModel/AIShip.cxx Normal file
View file

@ -0,0 +1,153 @@
// FGAIShip - FGAIBase-derived class creates an AI ship
//
// Written by David Culp, started October 2003.
// - davidculp2@comcast.net
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/math/point3d.hxx>
#include <math.h>
#include "AIShip.hxx"
FGAIShip::FGAIShip() {
hdg_lock = false;
rudder = 0.0;
}
FGAIShip::~FGAIShip() {
}
bool FGAIShip::init() {
return FGAIBase::init();
}
void FGAIShip::update(double dt) {
Run(dt);
Transform();
FGAIBase::update(dt);
}
void FGAIShip::Run(double dt) {
double turn_radius_ft;
double turn_circum_ft;
double speed_north_deg_sec;
double speed_east_deg_sec;
double ft_per_deg_lon;
double ft_per_deg_lat;
double dist_covered_ft;
double alpha;
// get size of a degree at this latitude
ft_per_deg_lat = 366468.96 - 3717.12 * cos(pos.lat() / 57.2958 );
ft_per_deg_lon = 365228.16 * cos(pos.lat() / 57.2958);
// adjust speed
double speed_diff = tgt_speed - speed;
if (fabs(speed_diff) > 0.1) {
if (speed_diff > 0.0) speed += 0.1 * dt;
if (speed_diff < 0.0) speed -= 0.1 * dt;
}
// convert speed to degrees per second
speed_north_deg_sec = cos( hdg / 57.29577951 ) * speed * 1.686 / ft_per_deg_lat;
speed_east_deg_sec = sin( hdg / 57.29577951 ) * speed * 1.686 / ft_per_deg_lon;
// set new position
pos.setlat( pos.lat() + speed_north_deg_sec * dt);
pos.setlon( pos.lon() + speed_east_deg_sec * dt);
// adjust heading based on current rudder angle
if (rudder != 0.0) {
turn_radius_ft = 0.088362 * speed * speed / tan( fabs(rudder) / 57.2958 );
turn_circum_ft = 6.2831853 * turn_radius_ft;
dist_covered_ft = speed * 1.686 * dt;
alpha = dist_covered_ft / turn_circum_ft * 360.0;
hdg += alpha * sign( rudder );
if ( hdg > 360.0 ) hdg -= 360.0;
if ( hdg < 0.0) hdg += 360.0;
}
// adjust target rudder angle if heading lock engaged
if (hdg_lock) {
double rudder_sense = 0.0;
double diff = fabs(hdg - tgt_heading);
if (diff > 180) diff = fabs(diff - 360);
double sum = hdg + diff;
if (sum > 360.0) sum -= 360.0;
if (fabs(sum - tgt_heading) < 1.0) {
rudder_sense = 1.0;
} else {
rudder_sense = -1.0;
}
if (diff < 30) tgt_roll = diff * rudder_sense;
}
// adjust rudder angle
double rudder_diff = tgt_roll - rudder;
if (fabs(rudder_diff) > 0.1) {
if (rudder_diff > 0.0) rudder += 5.0 * dt;
if (rudder_diff < 0.0) rudder -= 5.0 * dt;
}
}
void FGAIShip::AccelTo(double speed) {
tgt_speed = speed;
}
void FGAIShip::PitchTo(double angle) {
tgt_pitch = angle;
}
void FGAIShip::RollTo(double angle) {
tgt_roll = angle;
}
void FGAIShip::YawTo(double angle) {
}
void FGAIShip::ClimbTo(double altitude) {
}
void FGAIShip::TurnTo(double heading) {
tgt_heading = heading;
hdg_lock = true;
}
double FGAIShip::sign(double x) {
if ( x < 0.0 ) { return -1.0; }
else { return 1.0; }
}

54
src/AIModel/AIShip.hxx Normal file
View file

@ -0,0 +1,54 @@
// FGAIShip - AIBase derived class creates an AI ship
//
// Written by David Culp, started November 2003.
//
// Copyright (C) 2003 David P. Culp - davidculp2@comcast.net
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifndef _FG_AISHIP_HXX
#define _FG_AISHIP_HXX
#include "AIManager.hxx"
#include "AIBase.hxx"
class FGAIShip : public FGAIBase {
public:
FGAIShip();
~FGAIShip();
bool init();
void update(double dt);
void AccelTo(double speed);
void PitchTo(double angle);
void RollTo(double angle);
void YawTo(double angle);
void ClimbTo(double altitude);
void TurnTo(double heading);
private:
bool hdg_lock;
double rudder;
void Run(double dt);
double sign(double x);
};
#endif // _FG_AISHIP_HXX

10
src/AIModel/Makefile.am Normal file
View file

@ -0,0 +1,10 @@
noinst_LIBRARIES = libAIModel.a
libAIModel_a_SOURCES = \
AIManager.hxx AIManager.cxx \
AIBase.hxx AIBase.cxx \
AIAircraft.hxx AIAircraft.cxx \
AIShip.hxx AIShip.cxx \
AIBallistic.hxx AIBallistic.cxx
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src

View file

@ -1,3 +1,5 @@
#include <string.h> // strncpy()
#include <Main/globals.hxx>
#include <Airports/simple.hxx>

View file

@ -71,6 +71,7 @@ fgfs_LDADD = \
$(top_builddir)/src/Input/libInput.a \
$(top_builddir)/src/Instrumentation/libInstrumentation.a \
$(top_builddir)/src/Model/libModel.a \
$(top_builddir)/src/AIModel/libAIModel.a \
$(top_builddir)/src/Network/libNetwork.a \
$(top_builddir)/src/Navaids/libNavaids.a \
$(top_builddir)/src/Scenery/libScenery.a \

View file

@ -95,6 +95,7 @@
#include <Input/input.hxx>
#include <Instrumentation/instrument_mgr.hxx>
#include <Model/acmodel.hxx>
#include <AIModel/AIManager.hxx>
#include <Navaids/fixlist.hxx>
#include <Navaids/ilslist.hxx>
#include <Navaids/mkrbeacons.hxx>
@ -1654,6 +1655,14 @@ bool fgInitSubsystems() {
globals->get_AI_mgr()->init();
////////////////////////////////////////////////////////////////////
// Initialise the AI Model Manager
////////////////////////////////////////////////////////////////////
SG_LOG(SG_GENERAL, SG_INFO, " AI Model Manager");
globals->add_subsystem("ai_model", new FGAIManager);
#ifdef ENABLE_AUDIO_SUPPORT
////////////////////////////////////////////////////////////////////
// Initialize the sound subsystem.

View file

@ -23,6 +23,7 @@ SUBDIRS = \
Input \
Instrumentation \
Model \
AIModel \
Navaids \
Network \
$(MPLAYER_DIRS) \