-// // FGAIAircraft - FGAIBase-derived class creates an AI airplane
+// FGAIAircraft - FGAIBase-derived class creates an AI airplane
//
// Written by David Culp, started October 2003.
//
#include "performancedata.hxx"
#include "performancedb.hxx"
+
+#define TGT_VS_CUTOFF 10000
//#include <Airports/trafficcontroller.hxx>
static string tempReg;
void FGAIAircraft::Run(double dt) {
+
FGAIAircraft::dt = dt;
bool outOfSight = false,
tgt_altitude_ft = prev->getAltitude();
if (curr->getCrossat() > -1000.0) {
use_perf_vs = false;
- tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
- / 6076.0 / speed*60.0);
- checkTcas();
+// tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
+// / 6076.0 / speed*60.0);
+// if (fabs(tgt_vs) > TGT_VS_CUTOFF) { SG_LOG(SG_GENERAL, SG_ALERT, "Rediculously high vertical speed caculated at " << SG_ORIGIN << ". Corresponding to " << (tgt_vs * .005) << "degrees of pitch angle" << prev->getName()); };
+// if (tgt_vs < -1500)
+// tgt_vs = -1500;
+// if (tgt_vs > 1500)
+// tgt_vs = 1500;
+// checkTcas();
tgt_altitude_ft = curr->getCrossat();
} else {
use_perf_vs = true;
void FGAIAircraft::doGroundAltitude() {
+
if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)||
(isStationary()))
altitude_ft = (tgt_altitude_ft + groundOffset);
if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate
{
use_perf_vs = false;
- tgt_vs = (curr->getCrossat() - prev->getAltitude())
+/* tgt_vs = (curr->getCrossat() - prev->getAltitude())
/ (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
/ 6076.0 / prev->getSpeed()*60.0);
- checkTcas();
+ if (fabs(tgt_vs) > TGT_VS_CUTOFF) { SG_LOG(SG_GENERAL, SG_ALERT, "Rediculously high vertical speed caculated at " << SG_ORIGIN); };
+ checkTcas();*/
tgt_altitude_ft = curr->getCrossat();
} else {
use_perf_vs = true;
elevationStart = ((i)->getAircraft()->_getAltitude());
}
double elevationEnd = segment->getEnd()->getElevation();
- if (elevationEnd == 0) {
+ if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
SGGeod center2 = end;
center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
//elevation_meters += 0.5;
}
else {
- elevationEnd = parent->getElevation()+8+dx;
+ elevationEnd = parent->getElevation();
}
segment->getEnd()->setElevation(elevationEnd);
}
double elevationStart = segment->getStart()->getElevation();
double elevationEnd = segment->getEnd ()->getElevation();
- if (elevationStart == 0) {
+ if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
SGGeod center2 = segment->getStart()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
//elevation_meters += 0.5;
}
else {
- elevationStart = parent->getElevation()+8+dx;
+ elevationStart = parent->getElevation();
}
segment->getStart()->setElevation(elevationStart);
}
- if (elevationEnd == 0) {
+ if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
SGGeod center2 = segment->getEnd()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
//elevation_meters += 0.5;
}
else {
- elevationEnd = parent->getElevation()+8+dx;
+ elevationEnd = parent->getElevation();
}
segment->getEnd()->setElevation(elevationEnd);
}
-
// groundnet.cxx - Implimentation of the FlightGear airport ground handling code
//
// Written by Durk Talsma, started June 2005.
saveData = true;
}
}
+ cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
for (FGTaxiNodeVectorIterator node = nodes.begin();
node != nodes.end(); node++) {
if (saveData) {
saveData = true;
}
}
+ cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
for (FGTaxiNodeVectorIterator node = nodes.begin();
node != nodes.end(); node++) {
if (saveData) {
cacheData.append(airport + "-groundnet-cache.txt");
if (cacheData.exists()) {
ifstream data(cacheData.c_str());
- for (FGTaxiNodeVectorIterator i = nodes.begin();
- i != nodes.end();
- i++) {
- (*i)->setElevation(parent->getElevation() * SG_FEET_TO_METER);
- data >> index >> elev;
- if (data.eof())
- break;
- if (index != (*i)->getIndex()) {
- SG_LOG(SG_GENERAL, SG_ALERT, "Index read from ground network cache at airport " << airport << " does not match index in the network itself");
- } else {
- (*i)->setElevation(elev);
+ string revisionStr;
+ data >> revisionStr;
+ if (revisionStr != "[GroundNetcachedata:ref:2011:09:04]") {
+ SG_LOG(SG_GENERAL, SG_ALERT,"GroundNetwork Warning: discarding outdated cachefile " <<
+ cacheData.c_str() << " for Airport " << airport);
+ } else {
+ for (FGTaxiNodeVectorIterator i = nodes.begin();
+ i != nodes.end();
+ i++) {
+ (*i)->setElevation(parent->getElevation() * SG_FEET_TO_METER);
+ data >> index >> elev;
+ if (data.eof())
+ break;
+ if (index != (*i)->getIndex()) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Index read from ground network cache at airport " << airport << " does not match index in the network itself");
+ } else {
+ (*i)->setElevation(elev);
+ }
}
}
}
double elevationEnd = segments[pos]->getEnd()->getElevation();
//cerr << "Using elevation " << elevationEnd << endl;
- if (elevationEnd == 0) {
+ if ((elevationEnd == 0) || (elevationEnd = parent->getElevation())) {
SGGeod center2 = end;
center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
//elevation_meters += 0.5;
}
else {
- elevationEnd = parent->getElevation()+8+dx;
+ elevationEnd = parent->getElevation();
}
segments[pos]->getEnd()->setElevation(elevationEnd);
}
// Experimental: Calculate slope here, based on length, and the individual elevations
double elevationStart = segments[k]->getStart()->getElevation();
double elevationEnd = segments[k]->getEnd ()->getElevation();
- if (elevationStart == 0) {
+ if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
SGGeod center2 = segments[k]->getStart()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
//elevation_meters += 0.5;
}
else {
- elevationStart = parent->getElevation()+8+dx;
+ elevationStart = parent->getElevation();
}
segments[k]->getStart()->setElevation(elevationStart);
}
- if (elevationEnd == 0) {
+ if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
SGGeod center2 = segments[k]->getEnd()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
//elevation_meters += 0.5;
}
else {
- elevationEnd = parent->getElevation()+8+dx;
+ elevationEnd = parent->getElevation();
}
segments[k]->getEnd()->setElevation(elevationEnd);
}
groundOffset = 0;
distanceToUser = 0;
valid = true;
+ lastRun = 0;
//score = 0;
}
firstRun = true;
runCount = 0;
hits = 0;
+ lastRun = 0;
initialized = false;
valid = true;
}
firstRun = other.firstRun;
runCount = other.runCount;
hits = other.hits;
+ lastRun = other.lastRun;
initialized = other.initialized;
valid = other.valid;
}
if (!flights.empty()) {
return;
}
-
- SG_LOG(SG_GENERAL, SG_BULK, "Scheduling for : " << modelPath << " " << registration << " " << homePort);
+ SG_LOG(SG_GENERAL, SG_BULK, "Scheduling Flights for : " << modelPath << " " << registration << " " << homePort);
FGScheduledFlight *flight = NULL;
do {
flight = findAvailableFlight(currentDestination, flightIdentifier);
depT = depT.substr(0,24);
arrT = arrT.substr(0,24);
- SG_LOG(SG_GENERAL, SG_BULK, " " << flight->getCallSign() << ":"
- << " " << flight->getDepartureAirport()->getId() << ":"
- << " " << depT << ":"
- << " \"" << flight->getArrivalAirport()->getId() << "\"" << ":"
- << " " << arrT << ":");
+ SG_LOG(SG_GENERAL, SG_BULK, " Flight " << flight->getCallSign() << ":"
+ << " " << flight->getDepartureAirport()->getId() << ":"
+ << " " << depT << ":"
+ << " \"" << flight->getArrivalAirport()->getId() << "\"" << ":"
+ << " " << arrT << ":");
flights.push_back(flight);
- } while (currentDestination != homePort);
+ } while (1); //while (currentDestination != homePort);
SG_LOG(SG_GENERAL, SG_BULK, " Done ");
}
continue;
}
}
- //TODO: check time
+ if (flights.size()) {
+ time_t arrival = flights.back()->getArrivalTime();
+ if ((*i)->getDepartureTime() < arrival)
+ continue;
+ }
+
// So, if we actually get here, we have a winner
//cerr << "found flight: " << req << " : " << currentDestination << " : " <<
// (*i)->getArrivalAirport()->getId() << endl;
return (*a) < (*b);
}
-
-// void FGAISchedule::setClosestDistanceToUser()
-// {
-
-
-// double course;
-// double dist;
-
-// time_t
-// totalTimeEnroute,
-// elapsedTimeEnroute;
-
-// double userLatitude = fgGetDouble("/position/latitude-deg");
-// double userLongitude = fgGetDouble("/position/longitude-deg");
-
-// FGAirport *dep;
-
-// #if defined( __CYGWIN__) || defined( __MINGW32__)
-// #define HUGE HUGE_VAL
-// #endif
-// distanceToUser = HUGE;
-// FGScheduledFlightVecIterator i = flights.begin();
-// while (i != flights.end())
-// {
-// dep = i->getDepartureAirport();
-// //if (!(dep))
-// //return HUGE;
-
-// SGWayPoint user ( userLongitude,
-// userLatitude,
-// i->getCruiseAlt());
-// SGWayPoint current (dep->getLongitude(),
-// dep->getLatitude(),
-// 0);
-// user.CourseAndDistance(current, &course, &dist);
-// if (dist < distanceToUser)
-// {
-// distanceToUser = dist;
-// //cerr << "Found closest distance to user for " << registration << " to be " << distanceToUser << " at airport " << dep->getId() << endl;
-// }
-// i++;
-// }
-// //return distToUser;
-// }
+bool FGAISchedule::operator< (const FGAISchedule &other) const
+{
+ //cerr << "Sorting " << registration << " and " << other.registration << endl;
+ double currentScore = score * (1.5 - lastRun);
+ double otherScore = other.score * (1.5 - other.lastRun);
+ return currentScore > otherScore;
+}
double score;
unsigned int runCount;
unsigned int hits;
+ unsigned int lastRun;
bool firstRun;
double courseToDest;
bool initialized;
FGScheduledFlight*findAvailableFlight (const string ¤tDestination, const string &req);
// used to sort in decending order of score: I've probably found a better way to
// decending order sorting, but still need to test that.
- bool operator< (const FGAISchedule &other) const { return (score > other.score); };
+ bool operator< (const FGAISchedule &other) const;
void taint() { valid = false; };
+ int getLastUsed() { return (int) valid;};
+ void setLastUsed(unsigned int val) {lastRun = val; };
//void * getAiRef () { return AIManagerRef; };
//FGAISchedule* getAddress () { return this;};
//cerr << "Saving AI traffic heuristics" << endl;
saveData = true;
cachefile.open(cacheData.str().c_str());
+ cachefile << "[TrafficManagerCachedata:ref:2011:09:04]" << endl;
}
}
for (ScheduleVectorIterator sched = scheduledAircraft.begin();
if (saveData) {
cachefile << (*sched)->getRegistration() << " "
<< (*sched)->getRunCount() << " "
- << (*sched)->getHits() << endl;
+ << (*sched)->getHits() << " "
+ << (*sched)->getLastUsed() << endl;
}
delete(*sched);
}
airport[0], airport[1], airport[2]);
cacheData.append(buffer);
cacheData.append(airport + "-cache.txt");
+ string revisionStr;
if (cacheData.exists()) {
ifstream data(cacheData.c_str());
- while (1) {
- Heuristic h; // = new Heuristic;
- data >> h.registration >> h.runCount >> h.hits;
- if (data.eof())
- break;
- HeuristicMapIterator itr = heurMap.find(h.registration);
- if (itr != heurMap.end()) {
- SG_LOG(SG_GENERAL, SG_WARN,"Traffic Manager Warning: found duplicate tailnumber " <<
- h.registration << " for AI aircraft");
+ data >> revisionStr;
+ if (revisionStr != "[TrafficManagerCachedata:ref:2011:09:04]") {
+ SG_LOG(SG_GENERAL, SG_ALERT,"Traffic Manager Warning: discarding outdated cachefile " <<
+ cacheData.c_str() << " for Airport " << airport);
+ } else {
+ while (1) {
+ Heuristic h; // = new Heuristic;
+ data >> h.registration >> h.runCount >> h.hits >> h.lastRun;
+ if (data.eof())
+ break;
+ HeuristicMapIterator itr = heurMap.find(h.registration);
+ if (itr != heurMap.end()) {
+ SG_LOG(SG_GENERAL, SG_WARN,"Traffic Manager Warning: found duplicate tailnumber " <<
+ h.registration << " for AI aircraft");
+ } else {
+ heurMap[h.registration] = h;
+ heuristics.push_back(h);
+ }
}
- heurMap[h.registration] = h;
- heuristics.push_back(h);
}
}
- }
+ }
for (currAircraft = scheduledAircraft.begin();
currAircraft != scheduledAircraft.end(); currAircraft++) {
string registration = (*currAircraft)->getRegistration();
} else {
(*currAircraft)->setrunCount(itr->second.runCount);
(*currAircraft)->setHits(itr->second.hits);
- //cerr <<"Runcount " << itr->second->runCount << ".Hits " << itr->second->hits << endl;
+ (*currAircraft)->setLastUsed(itr->second.lastRun);
+ //cerr <<"Runcount " << itr->second.runCount << ". Hits " << itr->second.hits << ". Last run " << itr->second.lastRun<< endl;
}
}
//cerr << "Done" << endl;
//for (heuristicsVectorIterator hvi = heuristics.begin();
// hvi != heuristics.end(); hvi++) {
// delete(*hvi);
- //}
+ //}
}
// Do sorting and scoring separately, to take advantage of the "homeport| variable
for (currAircraft = scheduledAircraft.begin();
currAircraft != scheduledAircraft.end(); currAircraft++) {
(*currAircraft)->setScore();
}
+
sort(scheduledAircraft.begin(), scheduledAircraft.end(),
compareSchedules);
currAircraft = scheduledAircraft.begin();
currAircraftClosest = scheduledAircraft.begin();
-
inited = true;
}
std::string registration;
unsigned int runCount;
unsigned int hits;
+ unsigned int lastRun;
};
typedef std::vector<Heuristic> heuristicsVector;