1
0
Fork 0

AITraffic exits the runway as soon as possible (in theory; the code still needs some fine tuning).

This commit is contained in:
Durk Talsma 2011-10-09 23:44:42 +02:00
parent ed30b0c9a3
commit da3c098a4b
10 changed files with 152 additions and 17 deletions

View file

@ -805,7 +805,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
// << lead_dist << " " << curr->name // << lead_dist << " " << curr->name
// << " Ground target speed " << groundTargetSpeed << endl; // << " Ground target speed " << groundTargetSpeed << endl;
double bearing = 0; double bearing = 0;
if (speed > 50) { // don't do bearing calculations for ground traffic // don't do bearing calculations for ground traffic
bearing = getBearing(fp->getBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)); bearing = getBearing(fp->getBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr));
if (bearing < minBearing) { if (bearing < minBearing) {
minBearing = bearing; minBearing = bearing;
@ -817,8 +817,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
} else { } else {
speedFraction = 1.0; speedFraction = 1.0;
} }
} }
}
if (trafficRef) { if (trafficRef) {
//cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl; //cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
/* if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) { /* if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
@ -826,11 +825,14 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
<< _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl; << _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl;
}*/ }*/
} }
if ((dist_to_go < lead_dist) || (bearing > (minBearing * 1.1))) { if ((dist_to_go < lead_dist) ||
((dist_to_go > prev_dist_to_go) && (bearing > (minBearing * 1.1))) ) {
minBearing = 360; minBearing = 360;
speedFraction = 1.0; speedFraction = 1.0;
prev_dist_to_go = HUGE_VAL;
return true; return true;
} else { } else {
prev_dist_to_go = dist_to_go;
return false; return false;
} }
} }
@ -880,6 +882,11 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIWaypoint* prev, time_t now) {
if (prev->contains(string("Accel"))) { if (prev->contains(string("Accel"))) {
takeOffStatus = 3; takeOffStatus = 3;
} }
//if (prev->contains(string("landing"))) {
// if (speed < _performance->vTaxi() * 2) {
// fp->shortenToFirst(2, "legend");
// }
//}
/*if (prev->contains(string("final"))) { /*if (prev->contains(string("final"))) {
cerr << getCallSign() << " " cerr << getCallSign() << " "
@ -1114,6 +1121,9 @@ void FGAIAircraft::updateHeading() {
// << hdg << ". Target " << tgt_heading << ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << "Heading change rate : " << headingChangeRate << " bacnk sence " << bank_sense << endl; // << hdg << ". Target " << tgt_heading << ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << "Heading change rate : " << headingChangeRate << " bacnk sence " << bank_sense << endl;
hdg += headingChangeRate * dt * sqrt(fabs(speed) / 15); hdg += headingChangeRate * dt * sqrt(fabs(speed) / 15);
headingError = headingDiff; headingError = headingDiff;
if (fabs(headingError) < 1.0) {
hdg = tgt_heading;
}
} else { } else {
if (fabs(speed) > 1.0) { if (fabs(speed) > 1.0) {
turn_radius_ft = 0.088362 * speed * speed turn_radius_ft = 0.088362 * speed * speed

View file

@ -409,9 +409,18 @@ void FGAIFlightPlan::DecrementWaypoint(bool eraseWaypoints )
} }
else else
wpt_iterator--; wpt_iterator--;
} }
void FGAIFlightPlan::eraseLastWaypoint()
{
delete (waypoints.back());
waypoints.pop_back();;
wpt_iterator = waypoints.begin();
wpt_iterator++;
}
// gives distance in feet from a position to a waypoint // gives distance in feet from a position to a waypoint
double FGAIFlightPlan::getDistanceToGo(double lat, double lon, FGAIWaypoint* wp) const{ double FGAIFlightPlan::getDistanceToGo(double lat, double lon, FGAIWaypoint* wp) const{
@ -545,4 +554,12 @@ double FGAIFlightPlan::checkTrackLength(string wptName) {
trackDistance = 0; // name not found trackDistance = 0; // name not found
} }
return trackDistance; return trackDistance;
} }
void FGAIFlightPlan::shortenToFirst(unsigned int number, string name)
{
while (waypoints.size() > number + 3) {
eraseLastWaypoint();
}
(waypoints.back())->setName((waypoints.back())->getName() + name);
}

View file

@ -164,6 +164,8 @@ public:
FGAIFlightPlan* getSID() { return sid; }; FGAIFlightPlan* getSID() { return sid; };
FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; }; FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; };
FGAIWaypoint *getLastWaypoint() { return waypoints.back(); }; FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
void shortenToFirst(unsigned int number, std::string name);
private: private:
FGAIFlightPlan *sid; FGAIFlightPlan *sid;
@ -195,6 +197,7 @@ private:
bool createParking(FGAIAircraft *, FGAirport *, double radius); bool createParking(FGAIAircraft *, FGAirport *, double radius);
void deleteWaypoints(); void deleteWaypoints();
void resetWaypoints(); void resetWaypoints();
void eraseLastWaypoint();
bool createLandingTaxi(FGAIAircraft *, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline); bool createLandingTaxi(FGAIAircraft *, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline);
void createDefaultLandingTaxi(FGAIAircraft *, FGAirport* aAirport); void createDefaultLandingTaxi(FGAIAircraft *, FGAirport* aAirport);

View file

@ -36,6 +36,7 @@
#include <Environment/environment_mgr.hxx> #include <Environment/environment_mgr.hxx>
#include <Environment/environment.hxx> #include <Environment/environment.hxx>
#include <FDM/LaRCsim/basic_aero.h>
/* FGAIFlightPlan::create() /* FGAIFlightPlan::create()
@ -242,7 +243,12 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
} }
intVec ids; intVec ids;
int runwayId = gn->findNearestNode(runwayTakeoff); int runwayId = 0;
if (gn->getVersion() > 0) {
runwayId = gn->findNearestNodeOnRunway(runwayTakeoff);
} else {
runwayId = gn->findNearestNode(runwayTakeoff);
}
// A negative gateId indicates an overflow parking, use a // A negative gateId indicates an overflow parking, use a
// fallback mechanism for this. // fallback mechanism for this.
@ -379,7 +385,13 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
} }
intVec ids; intVec ids;
int runwayId = gn->findNearestNode(lastWptPos); int runwayId = 0;
if (gn->getVersion() == 1) {
runwayId = gn->findNearestNodeOnRunway(lastWptPos);
} else {
runwayId = gn->findNearestNode(lastWptPos);
}
//cerr << "Using network node " << runwayId << endl;
// A negative gateId indicates an overflow parking, use a // A negative gateId indicates an overflow parking, use a
// fallback mechanism for this. // fallback mechanism for this.
// Starting from gate 0 is a bit of a hack... // Starting from gate 0 is a bit of a hack...
@ -878,7 +890,12 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
const string & fltType) const string & fltType)
{ {
double vTouchdown = ac->getPerformance()->vTouchdown(); double vTouchdown = ac->getPerformance()->vTouchdown();
//double vTaxi = ac->getPerformance()->vTaxi(); double vTaxi = ac->getPerformance()->vTaxi();
double decel = ac->getPerformance()->deceleration() * 1.5;
double vTouchdownMetric = (vTouchdown * SG_NM_TO_METER) / 3600;
double vTaxiMetric = (vTaxi * SG_NM_TO_METER) / 3600;
double decelMetric = (decel * SG_NM_TO_METER) / 3600;
//string rwyClass = getRunwayClassFromTrafficType(fltType); //string rwyClass = getRunwayClassFromTrafficType(fltType);
//double heading = ac->getTrafficRef()->getCourse(); //double heading = ac->getTrafficRef()->getCourse();
@ -917,15 +934,50 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
coord = rwy->pointOnCenterline((currentDist * (i / nPoints))); coord = rwy->pointOnCenterline((currentDist * (i / nPoints)));
wpt = createInAir(ac, buffer, coord, currentAltitude, (vTouchdown)); wpt = createInAir(ac, buffer, coord, currentAltitude, (vTouchdown));
}*/ }*/
double rolloutDistance =
for (int i = 1; i < 10; i++) { (vTouchdownMetric * vTouchdownMetric - vTaxiMetric * vTaxiMetric) / (2 * decelMetric);
snprintf(buffer, 12, "wpt%d", i); //cerr << " touchdown speed = " << vTouchdown << ". Rollout distance " << rolloutDistance << endl;
int nPoints = 50;
for (int i = 1; i < nPoints; i++) {
snprintf(buffer, 12, "landing03%d", i);
coord = rwy->pointOnCenterline((rwy->lengthM() * 0.9) * (i / 10.0)); coord = rwy->pointOnCenterline((rolloutDistance * ((double) i / (double) nPoints)));
wpt = createOnGround(ac, buffer, coord, currElev, (vTouchdown / i)); wpt = createOnGround(ac, buffer, coord, currElev, vTaxi);
wpt->setCrossat(apt->getElevation()); wpt->setCrossat(currElev);
waypoints.push_back(wpt); waypoints.push_back(wpt);
} }
double mindist = 1.1 * rolloutDistance;
double maxdist = rwy->lengthM();
//cerr << "Finding nearest exit" << endl;
FGGroundNetwork *gn = apt->getDynamics()->getGroundNetwork();
if (gn) {
double min = 0;
for (int i = ceil(mindist); i < floor(maxdist); i++) {
coord = rwy->pointOnCenterline(mindist);
int nodeId = 0;
if (gn->getVersion() > 0) {
nodeId = gn->findNearestNodeOnRunway(coord);
} else {
nodeId = gn->findNearestNode(coord);
}
if (tn)
tn = gn->findNode(nodeId);
else {
break;
}
double dist = SGGeodesy::distanceM(coord, tn->getGeod());
if (dist < (min + 0.75)) {
break;
}
min = dist;
}
if (tn) {
wpt = createOnGround(ac, buffer, tn->getGeod(), currElev, vTaxi);
waypoints.push_back(wpt);
}
}
cerr << "Done. " << endl;
/* /*
//Runway Threshold //Runway Threshold

View file

@ -43,6 +43,7 @@ public:
inline double vRotate () { return _vRotate; }; inline double vRotate () { return _vRotate; };
inline double maximumBankAngle () { return _maxbank; }; inline double maximumBankAngle () { return _maxbank; };
inline double acceleration () { return _acceleration; }; inline double acceleration () { return _acceleration; };
inline double deceleration () { return _deceleration; };
inline double vTaxi () { return _vTaxi; }; inline double vTaxi () { return _vTaxi; };
inline double vTakeoff () { return _vTakeOff; }; inline double vTakeoff () { return _vTakeOff; };
inline double vClimb () { return _vClimb; }; inline double vClimb () { return _vClimb; };

View file

@ -146,6 +146,10 @@ void FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttr
void FGAirportDynamicsXMLLoader::endElement (const char * name) { void FGAirportDynamicsXMLLoader::endElement (const char * name) {
//cout << "End element " << name << endl; //cout << "End element " << name << endl;
if (name == string("version")) {
_dynamics->getGroundNetwork()->addVersion(atoi(value.c_str()));
//std::cerr << "version" << value<< std::endl;
}
if (name == string("AWOS")) { if (name == string("AWOS")) {
_dynamics->addAwosFreq(atoi(value.c_str())); _dynamics->addAwosFreq(atoi(value.c_str()));
//cerr << "Adding AWOS" << value<< endl; //cerr << "Adding AWOS" << value<< endl;

View file

@ -220,6 +220,7 @@ FGGroundNetwork::FGGroundNetwork()
count = 0; count = 0;
currTraffic = activeTraffic.begin(); currTraffic = activeTraffic.begin();
group = 0; group = 0;
version = 0;
networkInitialized = false; networkInitialized = false;
} }
@ -452,6 +453,28 @@ int FGGroundNetwork::findNearestNode(const SGGeod & aGeod)
return index; return index;
} }
int FGGroundNetwork::findNearestNodeOnRunway(const SGGeod & aGeod)
{
double minDist = HUGE_VAL;
int index = -1;
for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
itr++) {
if (!((*itr)->getIsOnRunway())) {
continue;
}
double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
if (d < minDist) {
minDist = d;
index = (*itr)->getIndex();
//cerr << "Minimum distance of " << minDist << " for index " << index << endl;
}
}
return index;
}
int FGGroundNetwork::findNearestNode(double lat, double lon) int FGGroundNetwork::findNearestNode(double lat, double lon)
{ {
return findNearestNode(SGGeod::fromDeg(lon, lat)); return findNearestNode(SGGeod::fromDeg(lon, lat));

View file

@ -292,6 +292,7 @@ private:
time_t nextSave; time_t nextSave;
//int maxDepth; //int maxDepth;
int count; int count;
int version;
FGTaxiNodeVector nodes; FGTaxiNodeVector nodes;
FGTaxiNodeVector pushBackNodes; FGTaxiNodeVector pushBackNodes;
FGTaxiSegmentVector segments; FGTaxiSegmentVector segments;
@ -324,6 +325,9 @@ public:
void addNode (const FGTaxiNode& node); void addNode (const FGTaxiNode& node);
void addNodes (FGParkingVec *parkings); void addNodes (FGParkingVec *parkings);
void addSegment(const FGTaxiSegment& seg); void addSegment(const FGTaxiSegment& seg);
void setVersion (int v) { version = v;};
int getVersion() { return version; };
void init(); void init();
bool exists() { bool exists() {
@ -335,6 +339,7 @@ public:
int findNearestNode(double lat, double lon); int findNearestNode(double lat, double lon);
int findNearestNode(const SGGeod& aGeod); int findNearestNode(const SGGeod& aGeod);
int findNearestNodeOnRunway(const SGGeod& aGeod);
FGTaxiNode *findNode(unsigned idx); FGTaxiNode *findNode(unsigned idx);
FGTaxiSegment *findSegment(unsigned idx); FGTaxiSegment *findSegment(unsigned idx);
@ -365,6 +370,7 @@ public:
virtual void update(double dt); virtual void update(double dt);
void saveElevationCache(); void saveElevationCache();
void addVersion(int v) {version = v; };
}; };

View file

@ -423,7 +423,7 @@ void FGAISchedule::scheduleFlights(time_t now)
<< " " << arrT << ":"); << " " << arrT << ":");
flights.push_back(flight); flights.push_back(flight);
} while (1); //(currentDestination != startingPort); } while (currentDestination != startingPort);
SG_LOG(SG_GENERAL, SG_BULK, " Done "); SG_LOG(SG_GENERAL, SG_BULK, " Done ");
} }
@ -507,7 +507,8 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
} }
if (flights.size()) { if (flights.size()) {
time_t arrival = flights.back()->getArrivalTime(); time_t arrival = flights.back()->getArrivalTime();
if ((*i)->getDepartureTime() < (arrival+(20*60))) int groundTime = groundTimeFromRadius();
if ((*i)->getDepartureTime() < (arrival+(groundTime)))
continue; continue;
} }
if (min != 0) { if (min != 0) {
@ -531,6 +532,23 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
return NULL; return NULL;
} }
int FGAISchedule::groundTimeFromRadius()
{
if (radius < 10)
return 15 * 60;
else if (radius < 15)
return 20 * 60;
else if (radius < 20)
return 30 * 60;
else if (radius < 25)
return 50 * 60;
else if (radius < 30)
return 90 * 60;
else
return 120 * 60;
}
double FGAISchedule::getSpeed() double FGAISchedule::getSpeed()
{ {
FGScheduledFlightVecIterator i = flights.begin(); FGScheduledFlightVecIterator i = flights.begin();

View file

@ -63,6 +63,7 @@ class FGAISchedule
bool valid; bool valid;
void scheduleFlights(time_t now); void scheduleFlights(time_t now);
int groundTimeFromRadius();
/** /**
* Transition this schedule from distant mode to AI mode; * Transition this schedule from distant mode to AI mode;