David Culp:
I added an AIStatic object to my OV-10 sim for use in putting city signs, vehicles, or anything else that will be static, but that I don't want to put in the scenery files. It's inexpensive. Before, I was making such things from AIShip. I also added the ability to set flight plans to repeat, so that when an airplane reaches the end it just starts over at the beginning. This is useful for my OV-10 sim. I have C-141 and KC-135 traffic flying approaches to Ramstein, and I only have to define two AI objects to do this. Also, I found an inefficiency in AIBase, where every AI object was calculating Mach number at every dt. Now only AIBallistic objects do this.
This commit is contained in:
parent
36929535d7
commit
ab83702c16
11 changed files with 215 additions and 48 deletions
|
@ -584,7 +584,12 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now )
|
||||||
// Current waypoint's elevation according to Terrain Elevation
|
// Current waypoint's elevation according to Terrain Elevation
|
||||||
if (curr->finished) { //end of the flight plan
|
if (curr->finished) { //end of the flight plan
|
||||||
{
|
{
|
||||||
setDie(true);
|
if (fp->getRepeat()) {
|
||||||
|
fp->restart();
|
||||||
|
} else {
|
||||||
|
setDie(true);
|
||||||
|
}
|
||||||
|
|
||||||
//cerr << "Done die end of fp" << endl;
|
//cerr << "Done die end of fp" << endl;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
|
|
||||||
void SetPerformance(const PERF_STRUCT *ps);
|
void SetPerformance(const PERF_STRUCT *ps);
|
||||||
void SetFlightPlan(FGAIFlightPlan *f);
|
void SetFlightPlan(FGAIFlightPlan *f);
|
||||||
|
FGAIFlightPlan* GetFlightPlan() { return fp; };
|
||||||
void AccelTo(double speed);
|
void AccelTo(double speed);
|
||||||
void PitchTo(double angle);
|
void PitchTo(double angle);
|
||||||
void RollTo(double angle);
|
void RollTo(double angle);
|
||||||
|
|
|
@ -81,41 +81,11 @@ FGAIBase::~FGAIBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIBase::update(double dt) {
|
void FGAIBase::update(double dt) {
|
||||||
|
if (_otype == otStatic) return;
|
||||||
|
if (_otype == otBallistic) CalculateMach();
|
||||||
|
|
||||||
ft_per_deg_lat = 366468.96 - 3717.12 * cos(pos.lat()*SGD_DEGREES_TO_RADIANS);
|
ft_per_deg_lat = 366468.96 - 3717.12 * cos(pos.lat()*SGD_DEGREES_TO_RADIANS);
|
||||||
ft_per_deg_lon = 365228.16 * cos(pos.lat()*SGD_DEGREES_TO_RADIANS);
|
ft_per_deg_lon = 365228.16 * cos(pos.lat()*SGD_DEGREES_TO_RADIANS);
|
||||||
|
|
||||||
// Calculate rho at altitude, using standard atmosphere
|
|
||||||
// For the temperature T and the pressure p,
|
|
||||||
|
|
||||||
if (altitude < 36152) { // curve fits for the troposphere
|
|
||||||
T = 59 - 0.00356 * altitude;
|
|
||||||
p = 2116 * pow( ((T + 459.7) / 518.6) , 5.256);
|
|
||||||
|
|
||||||
} else if ( 36152 < altitude && altitude < 82345 ) { // lower stratosphere
|
|
||||||
T = -70;
|
|
||||||
p = 473.1 * pow( e , 1.73 - (0.000048 * altitude) );
|
|
||||||
|
|
||||||
} else { // upper stratosphere
|
|
||||||
T = -205.05 + (0.00164 * altitude);
|
|
||||||
p = 51.97 * pow( ((T + 459.7) / 389.98) , -11.388);
|
|
||||||
}
|
|
||||||
|
|
||||||
rho = p / (1718 * (T + 459.7));
|
|
||||||
|
|
||||||
// calculate the speed of sound at altitude
|
|
||||||
// a = sqrt ( g * R * (T + 459.7))
|
|
||||||
// where:
|
|
||||||
// a = speed of sound [ft/s]
|
|
||||||
// g = specific heat ratio, which is usually equal to 1.4
|
|
||||||
// R = specific gas constant, which equals 1716 ft-lb/slug/°R
|
|
||||||
|
|
||||||
a = sqrt ( 1.4 * 1716 * (T + 459.7));
|
|
||||||
|
|
||||||
// calculate Mach number
|
|
||||||
|
|
||||||
Mach = speed/a;
|
|
||||||
|
|
||||||
// cout << "Speed(ft/s) "<< speed <<" Altitude(ft) "<< altitude << " Mach " << Mach;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIBase::Transform() {
|
void FGAIBase::Transform() {
|
||||||
|
@ -393,3 +363,39 @@ bool FGAIBase::_isNight() {
|
||||||
int FGAIBase::_getID() const {
|
int FGAIBase::_getID() const {
|
||||||
return (int)(this);
|
return (int)(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGAIBase::CalculateMach() {
|
||||||
|
// Calculate rho at altitude, using standard atmosphere
|
||||||
|
// For the temperature T and the pressure p,
|
||||||
|
|
||||||
|
if (altitude < 36152) { // curve fits for the troposphere
|
||||||
|
T = 59 - 0.00356 * altitude;
|
||||||
|
p = 2116 * pow( ((T + 459.7) / 518.6) , 5.256);
|
||||||
|
|
||||||
|
} else if ( 36152 < altitude && altitude < 82345 ) { // lower stratosphere
|
||||||
|
T = -70;
|
||||||
|
p = 473.1 * pow( e , 1.73 - (0.000048 * altitude) );
|
||||||
|
|
||||||
|
} else { // upper stratosphere
|
||||||
|
T = -205.05 + (0.00164 * altitude);
|
||||||
|
p = 51.97 * pow( ((T + 459.7) / 389.98) , -11.388);
|
||||||
|
}
|
||||||
|
|
||||||
|
rho = p / (1718 * (T + 459.7));
|
||||||
|
|
||||||
|
// calculate the speed of sound at altitude
|
||||||
|
// a = sqrt ( g * R * (T + 459.7))
|
||||||
|
// where:
|
||||||
|
// a = speed of sound [ft/s]
|
||||||
|
// g = specific heat ratio, which is usually equal to 1.4
|
||||||
|
// R = specific gas constant, which equals 1716 ft-lb/slug/°R
|
||||||
|
|
||||||
|
a = sqrt ( 1.4 * 1716 * (T + 459.7));
|
||||||
|
|
||||||
|
// calculate Mach number
|
||||||
|
|
||||||
|
Mach = speed/a;
|
||||||
|
|
||||||
|
// cout << "Speed(ft/s) "<< speed <<" Altitude(ft) "<< altitude << " Mach " << Mach;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class FGAIFlightPlan;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
string callsign;
|
string callsign;
|
||||||
|
|
||||||
// can be aircraft, ship, storm, thermal or ballistic
|
// can be aircraft, ship, storm, thermal, static or ballistic
|
||||||
string m_type;
|
string m_type;
|
||||||
string m_class;
|
string m_class;
|
||||||
string path;
|
string path;
|
||||||
|
@ -93,7 +93,7 @@ public:
|
||||||
inline Point3D GetPos() { return(pos); }
|
inline Point3D GetPos() { return(pos); }
|
||||||
|
|
||||||
enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic,
|
enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic,
|
||||||
otRocket, otStorm, otThermal,
|
otRocket, otStorm, otThermal, otStatic,
|
||||||
MAX_OBJECTS }; // Needs to be last!!!
|
MAX_OBJECTS }; // Needs to be last!!!
|
||||||
|
|
||||||
virtual bool init();
|
virtual bool init();
|
||||||
|
@ -167,7 +167,7 @@ protected:
|
||||||
FGAIFlightPlan *fp;
|
FGAIFlightPlan *fp;
|
||||||
|
|
||||||
void Transform();
|
void Transform();
|
||||||
|
void CalculateMach();
|
||||||
double UpdateRadar(FGAIManager* manager);
|
double UpdateRadar(FGAIManager* manager);
|
||||||
|
|
||||||
string _type_str;
|
string _type_str;
|
||||||
|
|
|
@ -50,6 +50,7 @@ FGAIFlightPlan::FGAIFlightPlan(string filename)
|
||||||
SGPath path( globals->get_fg_root() );
|
SGPath path( globals->get_fg_root() );
|
||||||
path.append( ("/Data/AI/FlightPlans/" + filename).c_str() );
|
path.append( ("/Data/AI/FlightPlans/" + filename).c_str() );
|
||||||
SGPropertyNode root;
|
SGPropertyNode root;
|
||||||
|
repeat = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
readProperties(path.str(), &root);
|
readProperties(path.str(), &root);
|
||||||
|
@ -472,3 +473,9 @@ void FGAIFlightPlan::resetWaypoints()
|
||||||
waypoints.push_back(wpt);
|
waypoints.push_back(wpt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start flightplan over from the beginning
|
||||||
|
void FGAIFlightPlan::restart()
|
||||||
|
{
|
||||||
|
wpt_iterator = waypoints.begin();
|
||||||
|
}
|
||||||
|
|
|
@ -85,18 +85,23 @@ public:
|
||||||
double getLeadInAngle() { return leadInAngle; };
|
double getLeadInAngle() { return leadInAngle; };
|
||||||
string getRunway() { return rwy._rwy_no; };
|
string getRunway() { return rwy._rwy_no; };
|
||||||
string getRunwayId() { return rwy._id; };
|
string getRunwayId() { return rwy._id; };
|
||||||
|
void setRepeat(bool r) { repeat = r; };
|
||||||
|
bool getRepeat(void) { return repeat; };
|
||||||
|
void restart(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGRunway rwy;
|
FGRunway rwy;
|
||||||
typedef vector <waypoint*> wpt_vector_type;
|
typedef vector <waypoint*> wpt_vector_type;
|
||||||
typedef wpt_vector_type::iterator wpt_vector_iterator;
|
typedef wpt_vector_type::iterator wpt_vector_iterator;
|
||||||
|
|
||||||
wpt_vector_type waypoints;
|
wpt_vector_type waypoints;
|
||||||
wpt_vector_iterator wpt_iterator;
|
wpt_vector_iterator wpt_iterator;
|
||||||
|
|
||||||
double distance_to_go;
|
bool repeat;
|
||||||
double lead_distance;
|
double distance_to_go;
|
||||||
|
double lead_distance;
|
||||||
double leadInAngle;
|
double leadInAngle;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
int leg;
|
int leg;
|
||||||
int gateId;
|
int gateId;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "AIStorm.hxx"
|
#include "AIStorm.hxx"
|
||||||
#include "AIThermal.hxx"
|
#include "AIThermal.hxx"
|
||||||
#include "AICarrier.hxx"
|
#include "AICarrier.hxx"
|
||||||
|
#include "AIStatic.hxx"
|
||||||
|
|
||||||
SG_USING_STD(list);
|
SG_USING_STD(list);
|
||||||
|
|
||||||
|
@ -176,7 +177,9 @@ FGAIManager::createAircraft( FGAIModelEntity *entity, FGAISchedule *ref) {
|
||||||
if ( entity->fp ) {
|
if ( entity->fp ) {
|
||||||
ai_plane->SetFlightPlan(entity->fp);
|
ai_plane->SetFlightPlan(entity->fp);
|
||||||
}
|
}
|
||||||
|
if (entity->repeat) {
|
||||||
|
ai_plane->GetFlightPlan()->setRepeat(true);
|
||||||
|
}
|
||||||
ai_plane->init();
|
ai_plane->init();
|
||||||
ai_plane->bind();
|
ai_plane->bind();
|
||||||
return ai_plane;
|
return ai_plane;
|
||||||
|
@ -310,6 +313,25 @@ FGAIManager::createThermal( FGAIModelEntity *entity ) {
|
||||||
return ai_thermal;
|
return ai_thermal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
FGAIManager::createStatic( FGAIModelEntity *entity ) {
|
||||||
|
|
||||||
|
// cout << "creating static object" << endl;
|
||||||
|
|
||||||
|
FGAIStatic* ai_static = new FGAIStatic(this);
|
||||||
|
ai_list.push_back(ai_static);
|
||||||
|
++numObjects[0];
|
||||||
|
++numObjects[FGAIBase::otStatic];
|
||||||
|
ai_static->setHeading(entity->heading);
|
||||||
|
ai_static->setPath(entity->path.c_str());
|
||||||
|
ai_static->setAltitude(entity->altitude);
|
||||||
|
ai_static->setLongitude(entity->longitude);
|
||||||
|
ai_static->setLatitude(entity->latitude);
|
||||||
|
ai_static->init();
|
||||||
|
ai_static->bind();
|
||||||
|
return ai_static;
|
||||||
|
}
|
||||||
|
|
||||||
void FGAIManager::destroyObject( void* ID ) {
|
void FGAIManager::destroyObject( void* ID ) {
|
||||||
ai_list_iterator ai_list_itr = ai_list.begin();
|
ai_list_iterator ai_list_itr = ai_list.begin();
|
||||||
while(ai_list_itr != ai_list.end()) {
|
while(ai_list_itr != ai_list.end()) {
|
||||||
|
@ -371,7 +393,10 @@ void FGAIManager::processScenario( string &filename ) {
|
||||||
|
|
||||||
} else if ( en->m_type == "ballistic") {
|
} else if ( en->m_type == "ballistic") {
|
||||||
createBallistic( en );
|
createBallistic( en );
|
||||||
}
|
|
||||||
|
} else if ( en->m_type == "static") {
|
||||||
|
createStatic( en );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// AIManager.hxx - experimental! - David Culp - based on:
|
// AIManager.hxx - David Culp - based on:
|
||||||
// AIMgr.hxx - definition of FGAIMgr
|
// AIMgr.hxx - definition of FGAIMgr
|
||||||
// - a global management class for FlightGear generated AI traffic
|
// - a global management class for FlightGear generated AI traffic
|
||||||
//
|
//
|
||||||
|
@ -87,6 +87,7 @@ public:
|
||||||
void* createStorm( FGAIModelEntity *entity );
|
void* createStorm( FGAIModelEntity *entity );
|
||||||
void* createShip( FGAIModelEntity *entity );
|
void* createShip( FGAIModelEntity *entity );
|
||||||
void* createCarrier( FGAIModelEntity *entity );
|
void* createCarrier( FGAIModelEntity *entity );
|
||||||
|
void* createStatic( FGAIModelEntity *entity );
|
||||||
|
|
||||||
void destroyObject( void* ID );
|
void destroyObject( void* ID );
|
||||||
|
|
||||||
|
|
65
src/AIModel/AIStatic.cxx
Normal file
65
src/AIModel/AIStatic.cxx
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// FGAIStatic - FGAIBase-derived class creates an AI static object
|
||||||
|
//
|
||||||
|
// Written by David Culp, started Jun 2005.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2005 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 "AIStatic.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
FGAIStatic::FGAIStatic(FGAIManager* mgr) {
|
||||||
|
manager = mgr;
|
||||||
|
_type_str = "static";
|
||||||
|
_otype = otStatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FGAIStatic::~FGAIStatic() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FGAIStatic::init() {
|
||||||
|
return FGAIBase::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGAIStatic::bind() {
|
||||||
|
FGAIBase::bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGAIStatic::unbind() {
|
||||||
|
FGAIBase::unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FGAIStatic::update(double dt) {
|
||||||
|
FGAIBase::update(dt);
|
||||||
|
Transform();
|
||||||
|
}
|
||||||
|
|
51
src/AIModel/AIStatic.hxx
Normal file
51
src/AIModel/AIStatic.hxx
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// FGAIStatic - AIBase derived class creates AI static object
|
||||||
|
//
|
||||||
|
// Written by David Culp, started Jun 2005.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2005 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_AIStatic_HXX
|
||||||
|
#define _FG_AIStatic_HXX
|
||||||
|
|
||||||
|
#include "AIManager.hxx"
|
||||||
|
#include "AIBase.hxx"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
SG_USING_STD(string);
|
||||||
|
|
||||||
|
|
||||||
|
class FGAIStatic : public FGAIBase {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGAIStatic(FGAIManager* mgr);
|
||||||
|
~FGAIStatic();
|
||||||
|
|
||||||
|
bool init();
|
||||||
|
virtual void bind();
|
||||||
|
virtual void unbind();
|
||||||
|
void update(double dt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
double dt;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _FG_AISTATIC_HXX
|
|
@ -11,6 +11,7 @@ libAIModel_a_SOURCES = \
|
||||||
AIThermal.hxx AIThermal.cxx \
|
AIThermal.hxx AIThermal.cxx \
|
||||||
AIFlightPlan.hxx AIFlightPlan.cxx AIFlightPlanCreate.cxx \
|
AIFlightPlan.hxx AIFlightPlan.cxx AIFlightPlanCreate.cxx \
|
||||||
AIScenario.hxx AIScenario.cxx \
|
AIScenario.hxx AIScenario.cxx \
|
||||||
AICarrier.hxx AICarrier.cxx
|
AICarrier.hxx AICarrier.cxx \
|
||||||
|
AIStatic.hxx AIStatic.cxx
|
||||||
|
|
||||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
||||||
|
|
Loading…
Add table
Reference in a new issue