]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/performancedb.cxx
Make traffic take-off roll look a little better.
[flightgear.git] / src / AIModel / performancedb.cxx
1 #ifdef HAVE_CONFIG_H
2   #include "config.h"
3 #endif
4
5 #include "performancedb.hxx"
6
7 #include <boost/foreach.hpp>
8
9 #include <simgear/misc/sg_path.hxx>
10 #include <simgear/props/props.hxx>
11 #include <simgear/props/props_io.hxx>
12 #include <simgear/xml/easyxml.hxx>
13
14 #include <Main/globals.hxx>
15 #include <iostream>
16 #include <fstream>
17
18 #include "performancedata.hxx"
19
20 using std::string;
21 using std::cerr;
22
23 PerformanceDB::PerformanceDB()
24 {
25     SGPath dbpath( globals->get_fg_root() );
26     
27
28     dbpath.append( "/AI/Aircraft/" );
29     dbpath.append( "performancedb.xml"); 
30     load(dbpath);
31 }
32
33
34 PerformanceDB::~PerformanceDB()
35 {}
36
37 void PerformanceDB::registerPerformanceData(const std::string& id, PerformanceData* data) {
38     //TODO if key exists already replace data "inplace", i.e. copy to existing PerfData instance
39     // this updates all aircraft currently using the PerfData instance.
40     _db[id] = data;
41 }
42
43 void PerformanceDB::registerPerformanceData(const std::string& id, const std::string& filename) {
44     registerPerformanceData(id, new PerformanceData(filename));
45 }
46
47 PerformanceData* PerformanceDB::getDataFor(const string& acType, const string& acClass)
48 {
49   // first, try with the specific aircraft type, such as 738 or A322
50     if (_db.find(acType) != _db.end()) {
51         return _db[acType];
52     }
53     
54     string alias = findAlias(acType);
55     if (_db.find(alias) != _db.end()) {
56       return _db[alias];
57     }
58   
59     SG_LOG(SG_AI, SG_INFO, "no performance data for " << acType);
60   
61     if (_db.find(acClass) == _db.end()) {
62         return _db["jet_transport"];
63     }
64   
65     return _db[acClass];
66 }
67
68 void PerformanceDB::load(const SGPath& filename) {
69     string name;
70     double acceleration;
71     double deceleration;
72     double climbRate;
73     double descentRate;
74     double vRotate;
75     double vTakeOff;
76     double vClimb;
77     double vCruise;
78     double vDescent;
79     double vApproach;
80     double vTouchdown;
81     double vTaxi;
82     SGPropertyNode root;
83     try {
84         readProperties(filename.str(), &root);
85     } catch (const sg_exception &) {
86         SG_LOG(SG_AI, SG_ALERT,
87             "Error reading AI aircraft performance database: " << filename.str());
88         return;
89     }
90
91     SGPropertyNode * node = root.getNode("performancedb");
92     for (int i = 0; i < node->nChildren(); i++) {
93         SGPropertyNode * db_node = node->getChild(i);
94         if (!strcmp(db_node->getName(), "aircraft")) {
95             name         = db_node->getStringValue("type", "heavy_jet");
96             acceleration = db_node->getDoubleValue("acceleration-kts-hour", 4.0);
97             deceleration = db_node->getDoubleValue("deceleration-kts-hour", 2.0);
98             climbRate    = db_node->getDoubleValue("climbrate-fpm", 3000.0);
99             descentRate  = db_node->getDoubleValue("decentrate-fpm", 1500.0);
100             vRotate      = db_node->getDoubleValue("rotate-speed-kts", 150.0);
101             vTakeOff     = db_node->getDoubleValue("takeoff-speed-kts", 160.0);
102             vClimb       = db_node->getDoubleValue("climb-speed-kts", 300.0);
103             vCruise      = db_node->getDoubleValue("cruise-speed-kts", 430.0);
104             vDescent     = db_node->getDoubleValue("decent-speed-kts", 300.0);
105             vApproach    = db_node->getDoubleValue("approach-speed-kts", 170.0);
106             vTouchdown   = db_node->getDoubleValue("touchdown-speed-kts", 150.0);
107             vTaxi        = db_node->getDoubleValue("taxi-speed-kts", 15.0);
108
109             registerPerformanceData(name, new PerformanceData(
110                 acceleration, deceleration, climbRate, descentRate, vRotate, vTakeOff, vClimb, vCruise, vDescent, vApproach, vTouchdown, vTaxi));
111         } else if (!strcmp(db_node->getName(), "alias")) {
112             string alias(db_node->getStringValue("alias"));
113             if (alias.empty()) {
114                 SG_LOG(SG_AI, SG_ALERT, "performance DB alias entry with no <alias> definition");
115                 continue;
116             }
117           
118             BOOST_FOREACH(SGPropertyNode* matchNode, db_node->getChildren("match")) {
119                 string match(matchNode->getStringValue());
120                 _aliases.push_back(StringPair(match, alias));
121             }
122         } else {
123             SG_LOG(SG_AI, SG_ALERT, "unrecognized performance DB entry:" << db_node->getName());
124         }
125     } // of nodes iteration
126 }
127
128 string PerformanceDB::findAlias(const string& acType) const
129 {
130     BOOST_FOREACH(const StringPair& alias, _aliases) {
131         if (acType.find(alias.first) == 0) { // matched!
132             return alias.second;
133         }
134     } // of alias iteration
135   
136     return string();
137 }
138
139