5 #include "performancedb.hxx"
7 #include <boost/foreach.hpp>
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>
14 #include <Main/globals.hxx>
18 #include "performancedata.hxx"
23 PerformanceDB::PerformanceDB()
25 SGPath dbpath( globals->get_fg_root() );
28 dbpath.append( "/AI/Aircraft/" );
29 dbpath.append( "performancedb.xml");
34 PerformanceDB::~PerformanceDB()
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.
43 void PerformanceDB::registerPerformanceData(const std::string& id, const std::string& filename) {
44 registerPerformanceData(id, new PerformanceData(filename));
47 PerformanceData* PerformanceDB::getDataFor(const string& acType, const string& acClass)
49 // first, try with the specific aircraft type, such as 738 or A322
50 if (_db.find(acType) != _db.end()) {
54 string alias = findAlias(acType);
55 if (_db.find(alias) != _db.end()) {
59 SG_LOG(SG_AI, SG_INFO, "no performance data for " << acType);
61 if (_db.find(acClass) == _db.end()) {
62 return _db["jet_transport"];
68 void PerformanceDB::load(const SGPath& filename) {
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());
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);
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"));
114 SG_LOG(SG_AI, SG_ALERT, "performance DB alias entry with no <alias> definition");
118 BOOST_FOREACH(SGPropertyNode* matchNode, db_node->getChildren("match")) {
119 string match(matchNode->getStringValue());
120 _aliases.push_back(StringPair(match, alias));
123 SG_LOG(SG_AI, SG_ALERT, "unrecognized performance DB entry:" << db_node->getName());
125 } // of nodes iteration
128 string PerformanceDB::findAlias(const string& acType) const
130 BOOST_FOREACH(const StringPair& alias, _aliases) {
131 if (acType.find(alias.first) == 0) { // matched!
134 } // of alias iteration