]> git.mxchange.org Git - flightgear.git/commitdiff
Add David Culp's AI model manager code which is derived from David Luff's AI/ATC...
authorehofman <ehofman>
Fri, 28 Nov 2003 15:48:05 +0000 (15:48 +0000)
committerehofman <ehofman>
Fri, 28 Nov 2003 15:48:05 +0000 (15:48 +0000)
17 files changed:
configure.ac
src/AIModel/.cvsignore [new file with mode: 0644]
src/AIModel/AIAircraft.cxx [new file with mode: 0644]
src/AIModel/AIAircraft.hxx [new file with mode: 0644]
src/AIModel/AIBallistic.cxx [new file with mode: 0644]
src/AIModel/AIBallistic.hxx [new file with mode: 0644]
src/AIModel/AIBase.cxx [new file with mode: 0644]
src/AIModel/AIBase.hxx [new file with mode: 0644]
src/AIModel/AIManager.cxx [new file with mode: 0644]
src/AIModel/AIManager.hxx [new file with mode: 0644]
src/AIModel/AIShip.cxx [new file with mode: 0644]
src/AIModel/AIShip.hxx [new file with mode: 0644]
src/AIModel/Makefile.am [new file with mode: 0644]
src/GUI/AirportList.cxx
src/Main/Makefile.am
src/Main/fg_init.cxx
src/Makefile.am

index aa39e3591f3d5c950e40bcad0aaaa87ed2ffe4f8..21050c09c4ba2f842dc9f3064ca17f7f44f2df37 100644 (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 \
diff --git a/src/AIModel/.cvsignore b/src/AIModel/.cvsignore
new file mode 100644 (file)
index 0000000..e995588
--- /dev/null
@@ -0,0 +1,3 @@
+.deps
+Makefile
+Makefile.in
diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx
new file mode 100644 (file)
index 0000000..010eaff
--- /dev/null
@@ -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; }
+}
diff --git a/src/AIModel/AIAircraft.hxx b/src/AIModel/AIAircraft.hxx
new file mode 100644 (file)
index 0000000..759cca9
--- /dev/null
@@ -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
diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx
new file mode 100644 (file)
index 0000000..2d96b7c
--- /dev/null
@@ -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);
+
+}
+
diff --git a/src/AIModel/AIBallistic.hxx b/src/AIModel/AIBallistic.hxx
new file mode 100644 (file)
index 0000000..71951d2
--- /dev/null
@@ -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
diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx
new file mode 100644 (file)
index 0000000..7c47618
--- /dev/null
@@ -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;
+}
+
diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx
new file mode 100644 (file)
index 0000000..8e56262
--- /dev/null
@@ -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
+
diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx
new file mode 100644 (file)
index 0000000..2d68fc3
--- /dev/null
@@ -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;
+       }
+}
diff --git a/src/AIModel/AIManager.hxx b/src/AIModel/AIManager.hxx
new file mode 100644 (file)
index 0000000..032cc01
--- /dev/null
@@ -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
diff --git a/src/AIModel/AIShip.cxx b/src/AIModel/AIShip.cxx
new file mode 100644 (file)
index 0000000..4a81972
--- /dev/null
@@ -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; }
+}
diff --git a/src/AIModel/AIShip.hxx b/src/AIModel/AIShip.hxx
new file mode 100644 (file)
index 0000000..c366862
--- /dev/null
@@ -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
diff --git a/src/AIModel/Makefile.am b/src/AIModel/Makefile.am
new file mode 100644 (file)
index 0000000..ba103fc
--- /dev/null
@@ -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
index 3f97342dee4707a1b554b425d8770b8b0af161dc..2057e520f519a8ecfef0685c145ed227cc5acbac 100644 (file)
@@ -1,3 +1,5 @@
+#include <string.h>    // strncpy()
+
 #include <Main/globals.hxx>
 #include <Airports/simple.hxx>
 
index 73986c829acdba1f57bf22481dcbe800c5465118..e47142095f426e32963c7ae80455ff807c74e6ac 100644 (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 \
index 5be3d3bce01990309626fe199f474f1c5251ffbf..873e82aac22f3a4e5424726fdf02c34c323abce9 100644 (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.
index d324d32e165822b6e4a94fb9c35664cf4a0c706f..74a44e7f9c19e75d341a9132cc0893cbdf03af02 100644 (file)
@@ -23,6 +23,7 @@ SUBDIRS = \
         Input \
        Instrumentation \
         Model \
+       AIModel \
         Navaids \
         Network \
        $(MPLAYER_DIRS) \