1
0
Fork 0

Development for two new features:

* Some support for geometry information provided by the custom scenery
   project. Current support is for AI groundnets and runway use files only
   since this is a switch that involves a lot of data verification and
   updating, during the transistion the actual path where the data can be
   read from is user configurable. setting the property

   /sim/traffic-manager/use-custom-scenery-data to true

  will cause flightgear to read the ground networks from the scenery
  directory (--{fg-scenery}/Airports/[I]/[C]/[A]/[ICAO].groundnet.xml to be
  precise). Setting this property to false will retain the original
  behvior.
* For departing aircraft, runway takeoff calculations will be done on the
  basis of the performance database. For testing purposes, a performance
 estimate for a heavy jet has been added.
This commit is contained in:
durk 2009-01-30 18:48:44 +00:00 committed by Tim Moore
parent 5efca258c1
commit c6f88e5b9b
11 changed files with 160 additions and 83 deletions

View file

@ -353,7 +353,6 @@ bool FGAIAircraft::loadNextLeg() {
return false; return false;
} }
setCallSign(trafficRef->getCallSign()); setCallSign(trafficRef->getCallSign());
//props->setStringValue("callsign", callsign.c_str());
leg = 1; leg = 1;
fp->setLeg(leg); fp->setLeg(leg);
} }
@ -366,10 +365,11 @@ bool FGAIAircraft::loadNextLeg() {
} else { } else {
double cruiseAlt = trafficRef->getCruiseAlt() * 100; double cruiseAlt = trafficRef->getCruiseAlt() * 100;
fp->create (dep, fp->create (this,
dep,
arr, arr,
leg, leg,
cruiseAlt, //(trafficRef->getCruiseAlt() * 100), // convert from FL to feet cruiseAlt,
trafficRef->getSpeed(), trafficRef->getSpeed(),
_getLatitude(), _getLatitude(),
_getLongitude(), _getLongitude(),

View file

@ -76,6 +76,7 @@ public:
virtual const char* getTypeString(void) const { return "aircraft"; } virtual const char* getTypeString(void) const { return "aircraft"; }
// included as performance data needs them, who else? // included as performance data needs them, who else?
inline PerformanceData* getPerformance() { return _performance; };
inline bool onGround() const { return no_roll; }; inline bool onGround() const { return no_roll; };
inline double getSpeed() const { return speed; }; inline double getSpeed() const { return speed; };
inline double getRoll() const { return roll; }; inline double getRoll() const { return roll; };

View file

@ -101,7 +101,8 @@ FGAIFlightPlan::FGAIFlightPlan(const string& filename)
// Position computed by the traffic manager, as well // Position computed by the traffic manager, as well
// as setting speeds and altitude computed by the // as setting speeds and altitude computed by the
// traffic manager. // traffic manager.
FGAIFlightPlan::FGAIFlightPlan(const std::string& p, FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
const std::string& p,
double course, double course,
time_t start, time_t start,
FGAirport *dep, FGAirport *dep,
@ -202,7 +203,7 @@ FGAIFlightPlan::FGAIFlightPlan(const std::string& p,
SG_LOG(SG_GENERAL, SG_INFO, "Route from " << dep->getId() << " to " << arr->getId() << ". Set leg to : " << leg); SG_LOG(SG_GENERAL, SG_INFO, "Route from " << dep->getId() << " to " << arr->getId() << ". Set leg to : " << leg);
wpt_iterator = waypoints.begin(); wpt_iterator = waypoints.begin();
create(dep,arr, leg, alt, speed, lat, lon, create(ac, dep,arr, leg, alt, speed, lat, lon,
firstLeg, radius, fltType, acType, airline); firstLeg, radius, fltType, acType, airline);
wpt_iterator = waypoints.begin(); wpt_iterator = waypoints.begin();
//cerr << "after create: " << (*wpt_iterator)->name << endl; //cerr << "after create: " << (*wpt_iterator)->name << endl;

View file

@ -23,16 +23,20 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <Airports/simple.hxx> #include <Airports/simple.hxx>
#include <Navaids/awynet.hxx> #include <Navaids/awynet.hxx>
#include "AIBase.hxx" #include "AIBase.hxx"
using std::vector; using std::vector;
using std::string; using std::string;
class FGTaxiRoute; class FGTaxiRoute;
class FGRunway; class FGRunway;
class FGAIAircraft;
class FGAIFlightPlan { class FGAIFlightPlan {
@ -56,7 +60,8 @@ public:
} waypoint; } waypoint;
FGAIFlightPlan(const string& filename); FGAIFlightPlan(const string& filename);
FGAIFlightPlan(const std::string& p, FGAIFlightPlan(FGAIAircraft *,
const std::string& p,
double course, double course,
time_t start, time_t start,
FGAirport *dep, FGAirport *dep,
@ -86,7 +91,7 @@ public:
double getBearing(double lat, double lon, waypoint* next) const; double getBearing(double lat, double lon, waypoint* next) const;
time_t getStartTime() const { return start_time; } time_t getStartTime() const { return start_time; }
void create(FGAirport *dep, FGAirport *arr, int leg, double alt, double speed, double lat, double lon, void create(FGAIAircraft *, FGAirport *dep, FGAirport *arr, int leg, double alt, double speed, double lat, double lon,
bool firstLeg, double radius, const string& fltType, const string& aircraftType, const string& airline); bool firstLeg, double radius, const string& fltType, const string& aircraftType, const string& airline);
void setLeg(int val) { leg = val;} void setLeg(int val) { leg = val;}
@ -126,7 +131,7 @@ private:
void createPushBack(bool, FGAirport*, double, double, double, const string&, const string&, const string&); void createPushBack(bool, FGAirport*, double, double, double, const string&, const string&, const string&);
void createPushBackFallBack(bool, FGAirport*, double, double, double, const string&, const string&, const string&); void createPushBackFallBack(bool, FGAirport*, double, double, double, const string&, const string&, const string&);
void createTakeOff(bool, FGAirport *, double, const string&); void createTakeOff(FGAIAircraft *, bool, FGAirport *, double, const string&);
void createClimb(bool, FGAirport *, double, double, const string&); void createClimb(bool, FGAirport *, double, double, const string&);
void createCruise(bool, FGAirport*, FGAirport*, double, double, double, double, const string&); void createCruise(bool, FGAirport*, FGAirport*, double, double, double, double, const string&);
void createDecent(FGAirport *, const string&); void createDecent(FGAirport *, const string&);

View file

@ -26,6 +26,8 @@
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <Airports/runways.hxx> #include <Airports/runways.hxx>
#include <Airports/dynamics.hxx> #include <Airports/dynamics.hxx>
#include <AIAircraft.hxx>
#include <performancedata.hxx>
#include <Environment/environment_mgr.hxx> #include <Environment/environment_mgr.hxx>
#include <Environment/environment.hxx> #include <Environment/environment.hxx>
@ -41,7 +43,7 @@
// Check lat/lon values during initialization; // Check lat/lon values during initialization;
void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, int legNr, void FGAIFlightPlan::create(FGAIAircraft *ac, FGAirport *dep, FGAirport *arr, int legNr,
double alt, double speed, double latitude, double alt, double speed, double latitude,
double longitude, bool firstFlight,double radius, double longitude, bool firstFlight,double radius,
const string& fltType, const string& aircraftType, const string& fltType, const string& aircraftType,
@ -58,7 +60,7 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, int legNr,
createTakeoffTaxi(firstFlight, dep, radius, fltType, aircraftType, airline); createTakeoffTaxi(firstFlight, dep, radius, fltType, aircraftType, airline);
break; break;
case 3: case 3:
createTakeOff(firstFlight, dep, speed, fltType); createTakeOff(ac, firstFlight, dep, speed, fltType);
break; break;
case 4: case 4:
createClimb(firstFlight, dep, speed, alt, fltType); createClimb(firstFlight, dep, speed, alt, fltType);
@ -336,43 +338,55 @@ void FGAIFlightPlan::createLandingTaxi(FGAirport *apt,
* CreateTakeOff * CreateTakeOff
* initialize the Aircraft at the parking location * initialize the Aircraft at the parking location
******************************************************************/ ******************************************************************/
void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double speed, const string &fltType) void FGAIFlightPlan::createTakeOff(FGAIAircraft *ac, bool firstFlight, FGAirport *apt, double speed, const string &fltType)
{ {
waypoint *wpt; double accel = ac->getPerformance()->acceleration();
double vRotate = ac->getPerformance()->vRotate();
// Get the current active runway, based on code from David Luff // Acceleration = dV / dT
// This should actually be unified and extended to include // Acceleration X dT = dV
// Preferential runway use schema's // dT = dT / Acceleration
if (firstFlight) //d = (Vf^2 - Vo^2) / (2*a)
{ double accelTime = (vRotate - 15) / accel;
string rwyClass = getRunwayClassFromTrafficType(fltType); cerr << "Using " << accelTime << " as total acceleration time" << endl;
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway); double accelDistance = (vRotate*vRotate - 15*15) / (2*accel);
rwy = apt->getRunwayByIdent(activeRunway); cerr << "Using " << accelDistance << " " << accel << " " << vRotate << endl;
} waypoint *wpt;
// Get the current active runway, based on code from David Luff
double airportElev = apt->getElevation(); // This should actually be unified and extended to include
// Acceleration point, 105 meters into the runway, // Preferential runway use schema's
SGGeod accelPoint = rwy->pointOnCenterline(105.0); // NOTE: DT (2009-01-18: IIRC, this is currently already the case,
wpt = createOnGround("accel", accelPoint, airportElev, speed); // because the getActive runway function takes care of that.
waypoints.push_back(wpt); if (firstFlight)
{
string rwyClass = getRunwayClassFromTrafficType(fltType);
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
rwy = apt->getRunwayByIdent(activeRunway);
}
double airportElev = apt->getElevation();
// Acceleration point, 105 meters into the runway,
SGGeod accelPoint = rwy->pointOnCenterline(105.0);
wpt = createOnGround("accel", accelPoint, airportElev, speed);
waypoints.push_back(wpt);
//Start Climbing to 3000 ft. Let's do this //Start Climbing to 3000 ft. Let's do this
// at the center of the runway for now: // at the center of the runway for now:
wpt = cloneWithPos(wpt, "SOC", rwy->geod()); SGGeod rotate = rwy->pointOnCenterline(105.0+accelDistance);
wpt->altitude = airportElev+1000; wpt = cloneWithPos(wpt, "SOC", rotate);
wpt->on_ground = false; wpt->altitude = airportElev+1000;
waypoints.push_back(wpt); wpt->on_ground = false;
waypoints.push_back(wpt);
wpt = cloneWithPos(wpt, "3000 ft", rwy->end()); wpt = cloneWithPos(wpt, "3000 ft", rwy->end());
wpt->altitude = airportElev+3000; wpt->altitude = airportElev+3000;
waypoints.push_back(wpt); waypoints.push_back(wpt);
// Finally, add two more waypoints, so that aircraft will remain under // Finally, add two more waypoints, so that aircraft will remain under
// Tower control until they have reached the 3000 ft climb point // Tower control until they have reached the 3000 ft climb point
SGGeod pt = rwy->pointOnCenterline(5000 + rwy->lengthM() * 0.5); SGGeod pt = rwy->pointOnCenterline(5000 + rwy->lengthM() * 0.5);
wpt = cloneWithPos(wpt, "5000 ft", pt); wpt = cloneWithPos(wpt, "5000 ft", pt);
wpt->altitude = airportElev+5000; wpt->altitude = airportElev+5000;
waypoints.push_back(wpt); waypoints.push_back(wpt);
} }
/******************************************************************* /*******************************************************************

View file

@ -9,7 +9,7 @@ class FGAIAircraft;
/** /**
Data storage for aircraft performance data. This is used to properly simulate the flight of AIAircrafts. Data storage for aircraft performance data. This is used to properly simulate the flight of AIAircrafts.
@author Thomas Förster <t.foerster@biologie.hu-berlin.de> @author Thomas F<EFBFBD>rster <t.foerster@biologie.hu-berlin.de>
*/ */
class PerformanceData class PerformanceData
{ {
@ -38,10 +38,11 @@ public:
bool gearExtensible(const FGAIAircraft* ac); bool gearExtensible(const FGAIAircraft* ac);
inline double climbRate() { return _climbRate; }; inline double climbRate () { return _climbRate; };
inline double descentRate() { return _descentRate; }; inline double descentRate () { return _descentRate; };
inline double vRotate() { return _vRotate; }; inline double vRotate () { return _vRotate; };
inline double maximumBankAngle() { return _maxbank; }; inline double maximumBankAngle () { return _maxbank; };
inline double acceleration () { return _acceleration; };
private: private:
double _acceleration; double _acceleration;

View file

@ -3,6 +3,9 @@
PerformanceDB::PerformanceDB() PerformanceDB::PerformanceDB()
{ {
// these are the 6 classes originally defined in the PERFSTRUCT // these are the 6 classes originally defined in the PERFSTRUCT
// Plus a few more for testing
registerPerformanceData("heavy_jet", new PerformanceData(
4.0, 2.0, 3000.0, 1500.0, 150.0, 160.0, 300.0, 430.0, 300.0, 170.0, 150.0, 15.0));
registerPerformanceData("light", new PerformanceData( registerPerformanceData("light", new PerformanceData(
2.0, 2.0, 450.0, 1000.0, 70.0, 70.0, 80.0, 100.0, 80.0, 70.0, 60.0, 15.0)); 2.0, 2.0, 450.0, 1000.0, 70.0, 70.0, 80.0, 100.0, 80.0, 70.0, 60.0, 15.0));
registerPerformanceData("ww2_fighter", new PerformanceData( registerPerformanceData("ww2_fighter", new PerformanceData(

View file

@ -26,40 +26,89 @@
XMLLoader::XMLLoader() {} XMLLoader::XMLLoader() {}
XMLLoader::~XMLLoader() {} XMLLoader::~XMLLoader() {}
string XMLLoader::expandICAODirs(const string in){
cerr << "Expanding " << in << endl;
if (in.size() == 4) {
char buffer[11];
snprintf(buffer, 11, "%c/%c/%c", in[0], in[1], in[2]);
cerr << "result: " << buffer << endl;
return string(buffer);
} else {
return in;
}
//exit(1);
}
void XMLLoader::load(FGAirportDynamics* d) { void XMLLoader::load(FGAirportDynamics* d) {
FGAirportDynamicsXMLLoader visitor(d); FGAirportDynamicsXMLLoader visitor(d);
if (fgGetBool("/sim/traffic-manager/use-custom-scenery-data") == false) {
SGPath parkpath( globals->get_fg_root() ); SGPath parkpath( globals->get_fg_root() );
parkpath.append( "/AI/Airports/" ); parkpath.append( "/AI/Airports/" );
parkpath.append( d->getId() ); parkpath.append( d->getId() );
parkpath.append( "parking.xml" ); parkpath.append( "parking.xml" );
if (parkpath.exists()) {
if (parkpath.exists()) { try {
try { readXML(parkpath.str(), visitor);
readXML(parkpath.str(), visitor); d->init();
d->init(); }
} catch (const sg_exception &e) { catch (const sg_exception &e) {
//cerr << "unable to read " << parkpath.str() << endl; }
} else {
string_list sc = globals->get_fg_scenery();
char buffer[32];
snprintf(buffer, 32, "%s.groundnet.xml", d->getId().c_str() );
string airportDir = XMLLoader::expandICAODirs(d->getId());
for (string_list_iterator i = sc.begin(); i != sc.end(); i++) {
SGPath parkpath( *i );
parkpath.append( "Airports" );
parkpath.append ( airportDir );
parkpath.append( string (buffer) );
if (parkpath.exists()) {
try {
readXML(parkpath.str(), visitor);
d->init();
}
catch (const sg_exception &e) {
}
return;
}
}
} }
}
} }
void XMLLoader::load(FGRunwayPreference* p) { void XMLLoader::load(FGRunwayPreference* p) {
FGRunwayPreferenceXMLLoader visitor(p); FGRunwayPreferenceXMLLoader visitor(p);
if (fgGetBool("/sim/traffic-manager/use-custom-scenery-data") == false) {
SGPath rwyPrefPath( globals->get_fg_root() ); SGPath rwyPrefPath( globals->get_fg_root() );
rwyPrefPath.append( "AI/Airports/" ); rwyPrefPath.append( "AI/Airports/" );
rwyPrefPath.append( p->getId() ); rwyPrefPath.append( p->getId() );
rwyPrefPath.append( "rwyuse.xml" ); rwyPrefPath.append( "rwyuse.xml" );
if (rwyPrefPath.exists()) {
//if (ai_dirs.find(id.c_str()) != ai_dirs.end() try {
// && rwyPrefPath.exists()) readXML(rwyPrefPath.str(), visitor);
if (rwyPrefPath.exists()) { }
try { catch (const sg_exception &e) {
readXML(rwyPrefPath.str(), visitor); }
} catch (const sg_exception &e) { }
//cerr << "unable to read " << rwyPrefPath.str() << endl; } else {
string_list sc = globals->get_fg_scenery();
char buffer[32];
snprintf(buffer, 32, "%s.rwyuse.xml", p->getId().c_str() );
string airportDir = expandICAODirs(p->getId());
for (string_list_iterator i = sc.begin(); i != sc.end(); i++) {
SGPath rwypath( *i );
rwypath.append( "Airports" );
rwypath.append ( airportDir );
rwypath.append( string(buffer) );
if (rwypath.exists()) {
try {
readXML(rwypath.str(), visitor);
}
catch (const sg_exception &e) {
}
return;
}
}
} }
}
} }

View file

@ -22,11 +22,12 @@ class FGAirportDynamics;
class FGRunwayPreference; class FGRunwayPreference;
class XMLLoader { class XMLLoader {
public: public:
XMLLoader(); XMLLoader();
~XMLLoader(); ~XMLLoader();
static string expandICAODirs(const string in);
static void load(FGRunwayPreference* p); static void load(FGRunwayPreference* p);
static void load(FGAirportDynamics* d); static void load(FGAirportDynamics* d);

View file

@ -208,9 +208,11 @@ void FGGlobals::set_fg_scenery (const string &scenery) {
ulDir *td = ulOpenDir( pt.c_str() ); ulDir *td = ulOpenDir( pt.c_str() );
ulDir *od = ulOpenDir( po.c_str() ); ulDir *od = ulOpenDir( po.c_str() );
if (td == NULL && od == NULL) // "Terrain" and "Airports" directory don't exist. add directory as is
// otherwise, automatically append either Terrain, Objects, or both
//if (td == NULL && od == NULL)
fg_scenery.push_back( path_list[i] ); fg_scenery.push_back( path_list[i] );
else { //else {
if (td != NULL) { if (td != NULL) {
fg_scenery.push_back( pt.str() ); fg_scenery.push_back( pt.str() );
ulCloseDir( td ); ulCloseDir( td );
@ -219,7 +221,7 @@ void FGGlobals::set_fg_scenery (const string &scenery) {
fg_scenery.push_back( po.str() ); fg_scenery.push_back( po.str() );
ulCloseDir( od ); ulCloseDir( od );
} }
} //}
// insert a marker for FGTileEntry::load(), so that // insert a marker for FGTileEntry::load(), so that
// FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "", // FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
// "B/Terrain", "B/Objects", ""] // "B/Terrain", "B/Objects", ""]

View file

@ -427,7 +427,7 @@ bool FGAISchedule::update(time_t now)
aircraft->setAltitude((*i)->getCruiseAlt()*100); // convert from FL to feet aircraft->setAltitude((*i)->getCruiseAlt()*100); // convert from FL to feet
aircraft->setSpeed(speed); aircraft->setSpeed(speed);
aircraft->setBank(0); aircraft->setBank(0);
aircraft->SetFlightPlan(new FGAIFlightPlan(flightPlanName, courseToDest, deptime, aircraft->SetFlightPlan(new FGAIFlightPlan(aircraft, flightPlanName, courseToDest, deptime,
dep, arr,true, radius, dep, arr,true, radius,
(*i)->getCruiseAlt()*100, (*i)->getCruiseAlt()*100,
lat, lon, speed, flightType, acType, lat, lon, speed, flightType, acType,