+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include "performancedb.hxx"
+#include <boost/foreach.hpp>
+
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/props/props.hxx>
+#include <simgear/props/props_io.hxx>
+#include <simgear/xml/easyxml.hxx>
+
+#include <Main/globals.hxx>
+#include <iostream>
+#include <fstream>
+
+#include "performancedata.hxx"
+
+using std::string;
+using std::cerr;
+
PerformanceDB::PerformanceDB()
{
- // these are the 6 classes originally defined in the PERFSTRUCT
- 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));
- registerPerformanceData("ww2_fighter", new PerformanceData(
- 4.0, 2.0, 3000.0, 1500.0, 110.0, 110.0, 180.0, 250.0, 200.0, 130.0, 100.0, 15.0));
- registerPerformanceData("jet_fighter", new PerformanceData(
- 7.0, 3.0, 4000.0, 2000.0, 120.0, 150.0, 350.0, 500.0, 350.0, 170.0, 150.0, 15.0));
- registerPerformanceData("jet_transport", new PerformanceData(
- 5.0, 2.0, 3000.0, 1500.0, 100.0, 140.0, 300.0, 430.0, 300.0, 170.0, 130.0, 15.0));
- registerPerformanceData("tanker", new PerformanceData(
- 5.0, 2.0, 3000.0, 1500.0, 100.0, 140.0, 300.0, 430.0, 300.0, 170.0, 130.0, 15.0));
- registerPerformanceData("ufo", new PerformanceData(
- 30.0, 30.0, 6000.0, 6000.0, 150.0, 150.0, 300.0, 430.0, 300.0, 170.0, 130.0, 15.0));
+ SGPath dbpath( globals->get_fg_root() );
+
+ dbpath.append( "/AI/Aircraft/" );
+ dbpath.append( "performancedb.xml");
+ load(dbpath);
}
registerPerformanceData(id, new PerformanceData(filename));
}
-PerformanceData* PerformanceDB::getDataFor(const std::string& id) {
- if (_db.find(id) == _db.end()) // id not found -> return jet_transport data
+PerformanceData* PerformanceDB::getDataFor(const string& acType, const string& acClass)
+{
+ // first, try with the specific aircraft type, such as 738 or A322
+ if (_db.find(acType) != _db.end()) {
+ return _db[acType];
+ }
+
+ string alias = findAlias(acType);
+ if (_db.find(alias) != _db.end()) {
+ return _db[alias];
+ }
+
+ SG_LOG(SG_AI, SG_INFO, "no performance data for " << acType);
+
+ if (_db.find(acClass) == _db.end()) {
return _db["jet_transport"];
+ }
+
+ return _db[acClass];
+}
- return _db[id];
+void PerformanceDB::load(const SGPath& filename) {
+ string name;
+ double acceleration;
+ double deceleration;
+ double climbRate;
+ double descentRate;
+ double vRotate;
+ double vTakeOff;
+ double vClimb;
+ double vCruise;
+ double vDescent;
+ double vApproach;
+ double vTouchdown;
+ double vTaxi;
+ SGPropertyNode root;
+ try {
+ readProperties(filename.str(), &root);
+ } catch (const sg_exception &) {
+ SG_LOG(SG_AI, SG_ALERT,
+ "Error reading AI aircraft performance database: " << filename.str());
+ return;
+ }
+
+ SGPropertyNode * node = root.getNode("performancedb");
+ for (int i = 0; i < node->nChildren(); i++) {
+ SGPropertyNode * db_node = node->getChild(i);
+ if (!strcmp(db_node->getName(), "aircraft")) {
+ name = db_node->getStringValue("type", "heavy_jet");
+ acceleration = db_node->getDoubleValue("acceleration-kts-hour", 4.0);
+ deceleration = db_node->getDoubleValue("deceleration-kts-hour", 2.0);
+ climbRate = db_node->getDoubleValue("climbrate-fpm", 3000.0);
+ descentRate = db_node->getDoubleValue("decentrate-fpm", 1500.0);
+ vRotate = db_node->getDoubleValue("rotate-speed-kts", 150.0);
+ vTakeOff = db_node->getDoubleValue("takeoff-speed-kts", 160.0);
+ vClimb = db_node->getDoubleValue("climb-speed-kts", 300.0);
+ vCruise = db_node->getDoubleValue("cruise-speed-kts", 430.0);
+ vDescent = db_node->getDoubleValue("decent-speed-kts", 300.0);
+ vApproach = db_node->getDoubleValue("approach-speed-kts", 170.0);
+ vTouchdown = db_node->getDoubleValue("touchdown-speed-kts", 150.0);
+ vTaxi = db_node->getDoubleValue("taxi-speed-kts", 15.0);
+
+ registerPerformanceData(name, new PerformanceData(
+ acceleration, deceleration, climbRate, descentRate, vRotate, vTakeOff, vClimb, vCruise, vDescent, vApproach, vTouchdown, vTaxi));
+ } else if (!strcmp(db_node->getName(), "alias")) {
+ string alias(db_node->getStringValue("alias"));
+ if (alias.empty()) {
+ SG_LOG(SG_AI, SG_ALERT, "performance DB alias entry with no <alias> definition");
+ continue;
+ }
+
+ BOOST_FOREACH(SGPropertyNode* matchNode, db_node->getChildren("match")) {
+ string match(matchNode->getStringValue());
+ _aliases.push_back(StringPair(match, alias));
+ }
+ } else {
+ SG_LOG(SG_AI, SG_ALERT, "unrecognized performance DB entry:" << db_node->getName());
+ }
+ } // of nodes iteration
}
+
+string PerformanceDB::findAlias(const string& acType) const
+{
+ BOOST_FOREACH(const StringPair& alias, _aliases) {
+ if (acType.find(alias.first) == 0) { // matched!
+ return alias.second;
+ }
+ } // of alias iteration
+
+ return string();
+}
+
+