1
0
Fork 0

Merge branch 'next' into radio-att

This commit is contained in:
adrian 2011-09-05 05:26:24 +03:00
commit 6a4272be14
7 changed files with 103 additions and 100 deletions

View file

@ -1,4 +1,4 @@
// // FGAIAircraft - FGAIBase-derived class creates an AI airplane // FGAIAircraft - FGAIBase-derived class creates an AI airplane
// //
// Written by David Culp, started October 2003. // Written by David Culp, started October 2003.
// //
@ -48,6 +48,8 @@ using std::string;
#include "performancedata.hxx" #include "performancedata.hxx"
#include "performancedb.hxx" #include "performancedb.hxx"
#define TGT_VS_CUTOFF 10000
//#include <Airports/trafficcontroller.hxx> //#include <Airports/trafficcontroller.hxx>
static string tempReg; static string tempReg;
@ -155,6 +157,7 @@ void FGAIAircraft::setPerformance(const std::string& acclass) {
void FGAIAircraft::Run(double dt) { void FGAIAircraft::Run(double dt) {
FGAIAircraft::dt = dt; FGAIAircraft::dt = dt;
bool outOfSight = false, bool outOfSight = false,
@ -355,9 +358,14 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
tgt_altitude_ft = prev->getAltitude(); tgt_altitude_ft = prev->getAltitude();
if (curr->getCrossat() > -1000.0) { if (curr->getCrossat() > -1000.0) {
use_perf_vs = false; use_perf_vs = false;
tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr) // tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
/ 6076.0 / speed*60.0); // / 6076.0 / speed*60.0);
checkTcas(); // 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(); tgt_altitude_ft = curr->getCrossat();
} else { } else {
use_perf_vs = true; use_perf_vs = true;
@ -497,6 +505,7 @@ void FGAIAircraft::getGroundElev(double dt) {
void FGAIAircraft::doGroundAltitude() { void FGAIAircraft::doGroundAltitude() {
if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)|| if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)||
(isStationary())) (isStationary()))
altitude_ft = (tgt_altitude_ft + groundOffset); altitude_ft = (tgt_altitude_ft + groundOffset);
@ -676,10 +685,11 @@ void FGAIAircraft::handleFirstWaypoint() {
if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate
{ {
use_perf_vs = false; use_perf_vs = false;
tgt_vs = (curr->getCrossat() - prev->getAltitude()) /* tgt_vs = (curr->getCrossat() - prev->getAltitude())
/ (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
/ 6076.0 / prev->getSpeed()*60.0); / 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(); tgt_altitude_ft = curr->getCrossat();
} else { } else {
use_perf_vs = true; use_perf_vs = true;

View file

@ -1503,7 +1503,7 @@ void FGStartupController::render(bool visible)
elevationStart = ((i)->getAircraft()->_getAltitude()); elevationStart = ((i)->getAircraft()->_getAltitude());
} }
double elevationEnd = segment->getEnd()->getElevation(); double elevationEnd = segment->getEnd()->getElevation();
if (elevationEnd == 0) { if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
SGGeod center2 = end; SGGeod center2 = end;
center2.setElevationM(SG_MAX_ELEVATION_M); center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) { if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
@ -1511,7 +1511,7 @@ void FGStartupController::render(bool visible)
//elevation_meters += 0.5; //elevation_meters += 0.5;
} }
else { else {
elevationEnd = parent->getElevation()+8+dx; elevationEnd = parent->getElevation();
} }
segment->getEnd()->setElevation(elevationEnd); segment->getEnd()->setElevation(elevationEnd);
} }
@ -1561,7 +1561,7 @@ void FGStartupController::render(bool visible)
double elevationStart = segment->getStart()->getElevation(); double elevationStart = segment->getStart()->getElevation();
double elevationEnd = segment->getEnd ()->getElevation(); double elevationEnd = segment->getEnd ()->getElevation();
if (elevationStart == 0) { if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
SGGeod center2 = segment->getStart()->getGeod(); SGGeod center2 = segment->getStart()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M); center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) { if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
@ -1569,11 +1569,11 @@ void FGStartupController::render(bool visible)
//elevation_meters += 0.5; //elevation_meters += 0.5;
} }
else { else {
elevationStart = parent->getElevation()+8+dx; elevationStart = parent->getElevation();
} }
segment->getStart()->setElevation(elevationStart); segment->getStart()->setElevation(elevationStart);
} }
if (elevationEnd == 0) { if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
SGGeod center2 = segment->getEnd()->getGeod(); SGGeod center2 = segment->getEnd()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M); center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) { if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
@ -1581,7 +1581,7 @@ void FGStartupController::render(bool visible)
//elevation_meters += 0.5; //elevation_meters += 0.5;
} }
else { else {
elevationEnd = parent->getElevation()+8+dx; elevationEnd = parent->getElevation();
} }
segment->getEnd()->setElevation(elevationEnd); segment->getEnd()->setElevation(elevationEnd);
} }

View file

@ -1,4 +1,3 @@
// groundnet.cxx - Implimentation of the FlightGear airport ground handling code // groundnet.cxx - Implimentation of the FlightGear airport ground handling code
// //
// Written by Durk Talsma, started June 2005. // Written by Durk Talsma, started June 2005.
@ -243,6 +242,7 @@ FGGroundNetwork::~FGGroundNetwork()
saveData = true; saveData = true;
} }
} }
cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
for (FGTaxiNodeVectorIterator node = nodes.begin(); for (FGTaxiNodeVectorIterator node = nodes.begin();
node != nodes.end(); node++) { node != nodes.end(); node++) {
if (saveData) { if (saveData) {
@ -286,6 +286,7 @@ void FGGroundNetwork::saveElevationCache() {
saveData = true; saveData = true;
} }
} }
cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
for (FGTaxiNodeVectorIterator node = nodes.begin(); for (FGTaxiNodeVectorIterator node = nodes.begin();
node != nodes.end(); node++) { node != nodes.end(); node++) {
if (saveData) { if (saveData) {
@ -401,17 +402,24 @@ void FGGroundNetwork::init()
cacheData.append(airport + "-groundnet-cache.txt"); cacheData.append(airport + "-groundnet-cache.txt");
if (cacheData.exists()) { if (cacheData.exists()) {
ifstream data(cacheData.c_str()); ifstream data(cacheData.c_str());
for (FGTaxiNodeVectorIterator i = nodes.begin(); string revisionStr;
i != nodes.end(); data >> revisionStr;
i++) { if (revisionStr != "[GroundNetcachedata:ref:2011:09:04]") {
(*i)->setElevation(parent->getElevation() * SG_FEET_TO_METER); SG_LOG(SG_GENERAL, SG_ALERT,"GroundNetwork Warning: discarding outdated cachefile " <<
data >> index >> elev; cacheData.c_str() << " for Airport " << airport);
if (data.eof()) } else {
break; for (FGTaxiNodeVectorIterator i = nodes.begin();
if (index != (*i)->getIndex()) { i != nodes.end();
SG_LOG(SG_GENERAL, SG_ALERT, "Index read from ground network cache at airport " << airport << " does not match index in the network itself"); i++) {
} else { (*i)->setElevation(parent->getElevation() * SG_FEET_TO_METER);
(*i)->setElevation(elev); 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);
}
} }
} }
} }
@ -1308,7 +1316,7 @@ void FGGroundNetwork::render(bool visible)
double elevationEnd = segments[pos]->getEnd()->getElevation(); double elevationEnd = segments[pos]->getEnd()->getElevation();
//cerr << "Using elevation " << elevationEnd << endl; //cerr << "Using elevation " << elevationEnd << endl;
if (elevationEnd == 0) { if ((elevationEnd == 0) || (elevationEnd = parent->getElevation())) {
SGGeod center2 = end; SGGeod center2 = end;
center2.setElevationM(SG_MAX_ELEVATION_M); center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) { if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
@ -1316,7 +1324,7 @@ void FGGroundNetwork::render(bool visible)
//elevation_meters += 0.5; //elevation_meters += 0.5;
} }
else { else {
elevationEnd = parent->getElevation()+8+dx; elevationEnd = parent->getElevation();
} }
segments[pos]->getEnd()->setElevation(elevationEnd); segments[pos]->getEnd()->setElevation(elevationEnd);
} }
@ -1363,7 +1371,7 @@ void FGGroundNetwork::render(bool visible)
// Experimental: Calculate slope here, based on length, and the individual elevations // Experimental: Calculate slope here, based on length, and the individual elevations
double elevationStart = segments[k]->getStart()->getElevation(); double elevationStart = segments[k]->getStart()->getElevation();
double elevationEnd = segments[k]->getEnd ()->getElevation(); double elevationEnd = segments[k]->getEnd ()->getElevation();
if (elevationStart == 0) { if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
SGGeod center2 = segments[k]->getStart()->getGeod(); SGGeod center2 = segments[k]->getStart()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M); center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) { if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
@ -1371,11 +1379,11 @@ void FGGroundNetwork::render(bool visible)
//elevation_meters += 0.5; //elevation_meters += 0.5;
} }
else { else {
elevationStart = parent->getElevation()+8+dx; elevationStart = parent->getElevation();
} }
segments[k]->getStart()->setElevation(elevationStart); segments[k]->getStart()->setElevation(elevationStart);
} }
if (elevationEnd == 0) { if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
SGGeod center2 = segments[k]->getEnd()->getGeod(); SGGeod center2 = segments[k]->getEnd()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M); center2.setElevationM(SG_MAX_ELEVATION_M);
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) { if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
@ -1383,7 +1391,7 @@ void FGGroundNetwork::render(bool visible)
//elevation_meters += 0.5; //elevation_meters += 0.5;
} }
else { else {
elevationEnd = parent->getElevation()+8+dx; elevationEnd = parent->getElevation();
} }
segments[k]->getEnd()->setElevation(elevationEnd); segments[k]->getEnd()->setElevation(elevationEnd);
} }

View file

@ -69,6 +69,7 @@ FGAISchedule::FGAISchedule()
groundOffset = 0; groundOffset = 0;
distanceToUser = 0; distanceToUser = 0;
valid = true; valid = true;
lastRun = 0;
//score = 0; //score = 0;
} }
@ -120,6 +121,7 @@ FGAISchedule::FGAISchedule(string model,
firstRun = true; firstRun = true;
runCount = 0; runCount = 0;
hits = 0; hits = 0;
lastRun = 0;
initialized = false; initialized = false;
valid = true; valid = true;
} }
@ -147,6 +149,7 @@ FGAISchedule::FGAISchedule(const FGAISchedule &other)
firstRun = other.firstRun; firstRun = other.firstRun;
runCount = other.runCount; runCount = other.runCount;
hits = other.hits; hits = other.hits;
lastRun = other.lastRun;
initialized = other.initialized; initialized = other.initialized;
valid = other.valid; valid = other.valid;
} }
@ -371,8 +374,7 @@ void FGAISchedule::scheduleFlights()
if (!flights.empty()) { if (!flights.empty()) {
return; return;
} }
SG_LOG(SG_GENERAL, SG_BULK, "Scheduling Flights for : " << modelPath << " " << registration << " " << homePort);
SG_LOG(SG_GENERAL, SG_BULK, "Scheduling for : " << modelPath << " " << registration << " " << homePort);
FGScheduledFlight *flight = NULL; FGScheduledFlight *flight = NULL;
do { do {
flight = findAvailableFlight(currentDestination, flightIdentifier); flight = findAvailableFlight(currentDestination, flightIdentifier);
@ -400,14 +402,14 @@ void FGAISchedule::scheduleFlights()
depT = depT.substr(0,24); depT = depT.substr(0,24);
arrT = arrT.substr(0,24); arrT = arrT.substr(0,24);
SG_LOG(SG_GENERAL, SG_BULK, " " << flight->getCallSign() << ":" SG_LOG(SG_GENERAL, SG_BULK, " Flight " << flight->getCallSign() << ":"
<< " " << flight->getDepartureAirport()->getId() << ":" << " " << flight->getDepartureAirport()->getId() << ":"
<< " " << depT << ":" << " " << depT << ":"
<< " \"" << flight->getArrivalAirport()->getId() << "\"" << ":" << " \"" << flight->getArrivalAirport()->getId() << "\"" << ":"
<< " " << arrT << ":"); << " " << arrT << ":");
flights.push_back(flight); flights.push_back(flight);
} while (currentDestination != homePort); } while (1); //while (currentDestination != homePort);
SG_LOG(SG_GENERAL, SG_BULK, " Done "); SG_LOG(SG_GENERAL, SG_BULK, " Done ");
} }
@ -488,7 +490,12 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
continue; 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 // So, if we actually get here, we have a winner
//cerr << "found flight: " << req << " : " << currentDestination << " : " << //cerr << "found flight: " << req << " : " << currentDestination << " : " <<
// (*i)->getArrivalAirport()->getId() << endl; // (*i)->getArrivalAirport()->getId() << endl;
@ -537,48 +544,11 @@ bool compareSchedules(FGAISchedule*a, FGAISchedule*b)
return (*a) < (*b); return (*a) < (*b);
} }
bool FGAISchedule::operator< (const FGAISchedule &other) const
// void FGAISchedule::setClosestDistanceToUser() {
// { //cerr << "Sorting " << registration << " and " << other.registration << endl;
double currentScore = score * (1.5 - lastRun);
double otherScore = other.score * (1.5 - other.lastRun);
// double course; return currentScore > otherScore;
// 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;
// }

View file

@ -56,6 +56,7 @@ class FGAISchedule
double score; double score;
unsigned int runCount; unsigned int runCount;
unsigned int hits; unsigned int hits;
unsigned int lastRun;
bool firstRun; bool firstRun;
double courseToDest; double courseToDest;
bool initialized; bool initialized;
@ -124,8 +125,10 @@ class FGAISchedule
FGScheduledFlight*findAvailableFlight (const string &currentDestination, const string &req); FGScheduledFlight*findAvailableFlight (const string &currentDestination, const string &req);
// used to sort in decending order of score: I've probably found a better way to // 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. // 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; }; void taint() { valid = false; };
int getLastUsed() { return (int) valid;};
void setLastUsed(unsigned int val) {lastRun = val; };
//void * getAiRef () { return AIManagerRef; }; //void * getAiRef () { return AIManagerRef; };
//FGAISchedule* getAddress () { return this;}; //FGAISchedule* getAddress () { return this;};

View file

@ -109,6 +109,7 @@ FGTrafficManager::~FGTrafficManager()
//cerr << "Saving AI traffic heuristics" << endl; //cerr << "Saving AI traffic heuristics" << endl;
saveData = true; saveData = true;
cachefile.open(cacheData.str().c_str()); cachefile.open(cacheData.str().c_str());
cachefile << "[TrafficManagerCachedata:ref:2011:09:04]" << endl;
} }
} }
for (ScheduleVectorIterator sched = scheduledAircraft.begin(); for (ScheduleVectorIterator sched = scheduledAircraft.begin();
@ -116,7 +117,8 @@ FGTrafficManager::~FGTrafficManager()
if (saveData) { if (saveData) {
cachefile << (*sched)->getRegistration() << " " cachefile << (*sched)->getRegistration() << " "
<< (*sched)->getRunCount() << " " << (*sched)->getRunCount() << " "
<< (*sched)->getHits() << endl; << (*sched)->getHits() << " "
<< (*sched)->getLastUsed() << endl;
} }
delete(*sched); delete(*sched);
} }
@ -182,23 +184,31 @@ void FGTrafficManager::init()
airport[0], airport[1], airport[2]); airport[0], airport[1], airport[2]);
cacheData.append(buffer); cacheData.append(buffer);
cacheData.append(airport + "-cache.txt"); cacheData.append(airport + "-cache.txt");
string revisionStr;
if (cacheData.exists()) { if (cacheData.exists()) {
ifstream data(cacheData.c_str()); ifstream data(cacheData.c_str());
while (1) { data >> revisionStr;
Heuristic h; // = new Heuristic; if (revisionStr != "[TrafficManagerCachedata:ref:2011:09:04]") {
data >> h.registration >> h.runCount >> h.hits; SG_LOG(SG_GENERAL, SG_ALERT,"Traffic Manager Warning: discarding outdated cachefile " <<
if (data.eof()) cacheData.c_str() << " for Airport " << airport);
break; } else {
HeuristicMapIterator itr = heurMap.find(h.registration); while (1) {
if (itr != heurMap.end()) { Heuristic h; // = new Heuristic;
SG_LOG(SG_GENERAL, SG_WARN,"Traffic Manager Warning: found duplicate tailnumber " << data >> h.registration >> h.runCount >> h.hits >> h.lastRun;
h.registration << " for AI aircraft"); 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(); for (currAircraft = scheduledAircraft.begin();
currAircraft != scheduledAircraft.end(); currAircraft++) { currAircraft != scheduledAircraft.end(); currAircraft++) {
string registration = (*currAircraft)->getRegistration(); string registration = (*currAircraft)->getRegistration();
@ -209,25 +219,26 @@ void FGTrafficManager::init()
} else { } else {
(*currAircraft)->setrunCount(itr->second.runCount); (*currAircraft)->setrunCount(itr->second.runCount);
(*currAircraft)->setHits(itr->second.hits); (*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; //cerr << "Done" << endl;
//for (heuristicsVectorIterator hvi = heuristics.begin(); //for (heuristicsVectorIterator hvi = heuristics.begin();
// hvi != heuristics.end(); hvi++) { // hvi != heuristics.end(); hvi++) {
// delete(*hvi); // delete(*hvi);
//} //}
} }
// Do sorting and scoring separately, to take advantage of the "homeport| variable // Do sorting and scoring separately, to take advantage of the "homeport| variable
for (currAircraft = scheduledAircraft.begin(); for (currAircraft = scheduledAircraft.begin();
currAircraft != scheduledAircraft.end(); currAircraft++) { currAircraft != scheduledAircraft.end(); currAircraft++) {
(*currAircraft)->setScore(); (*currAircraft)->setScore();
} }
sort(scheduledAircraft.begin(), scheduledAircraft.end(), sort(scheduledAircraft.begin(), scheduledAircraft.end(),
compareSchedules); compareSchedules);
currAircraft = scheduledAircraft.begin(); currAircraft = scheduledAircraft.begin();
currAircraftClosest = scheduledAircraft.begin(); currAircraftClosest = scheduledAircraft.begin();
inited = true; inited = true;
} }

View file

@ -64,6 +64,7 @@ public:
std::string registration; std::string registration;
unsigned int runCount; unsigned int runCount;
unsigned int hits; unsigned int hits;
unsigned int lastRun;
}; };
typedef std::vector<Heuristic> heuristicsVector; typedef std::vector<Heuristic> heuristicsVector;