Add David Culp's AI model manager code which is derived from David Luff's AI/ATC code.
This commit is contained in:
parent
06ce7ae928
commit
cd0c447b43
17 changed files with 1044 additions and 0 deletions
|
@ -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
3
src/AIModel/.cvsignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
202
src/AIModel/AIAircraft.cxx
Normal file
202
src/AIModel/AIAircraft.cxx
Normal 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; }
|
||||
}
|
62
src/AIModel/AIAircraft.hxx
Normal file
62
src/AIModel/AIAircraft.hxx
Normal 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
117
src/AIModel/AIBallistic.cxx
Normal 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);
|
||||
|
||||
}
|
||||
|
51
src/AIModel/AIBallistic.hxx
Normal file
51
src/AIModel/AIBallistic.hxx
Normal 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
97
src/AIModel/AIBase.cxx
Normal 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
74
src/AIModel/AIBase.hxx
Normal 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
127
src/AIModel/AIManager.cxx
Normal 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
80
src/AIModel/AIManager.hxx
Normal 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
153
src/AIModel/AIShip.cxx
Normal 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
54
src/AIModel/AIShip.hxx
Normal 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
10
src/AIModel/Makefile.am
Normal 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
|
|
@ -1,3 +1,5 @@
|
|||
#include <string.h> // strncpy()
|
||||
|
||||
#include <Main/globals.hxx>
|
||||
#include <Airports/simple.hxx>
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -23,6 +23,7 @@ SUBDIRS = \
|
|||
Input \
|
||||
Instrumentation \
|
||||
Model \
|
||||
AIModel \
|
||||
Navaids \
|
||||
Network \
|
||||
$(MPLAYER_DIRS) \
|
||||
|
|
Loading…
Add table
Reference in a new issue