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
// << " Ground target speed " << groundTargetSpeed << endl;
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));
if (bearing < minBearing) {
minBearing = bearing;
@ -818,7 +818,6 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
speedFraction = 1.0;
}
}
}
if (trafficRef) {
//cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
/* 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;
}*/
}
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;
speedFraction = 1.0;
prev_dist_to_go = HUGE_VAL;
return true;
} else {
prev_dist_to_go = dist_to_go;
return false;
}
}
@ -880,6 +882,11 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIWaypoint* prev, time_t now) {
if (prev->contains(string("Accel"))) {
takeOffStatus = 3;
}
//if (prev->contains(string("landing"))) {
// if (speed < _performance->vTaxi() * 2) {
// fp->shortenToFirst(2, "legend");
// }
//}
/*if (prev->contains(string("final"))) {
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 += headingChangeRate * dt * sqrt(fabs(speed) / 15);
headingError = headingDiff;
if (fabs(headingError) < 1.0) {
hdg = tgt_heading;
}
} else {
if (fabs(speed) > 1.0) {
turn_radius_ft = 0.088362 * speed * speed

View file

@ -409,9 +409,18 @@ void FGAIFlightPlan::DecrementWaypoint(bool eraseWaypoints )
}
else
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
double FGAIFlightPlan::getDistanceToGo(double lat, double lon, FGAIWaypoint* wp) const{
@ -546,3 +555,11 @@ double FGAIFlightPlan::checkTrackLength(string wptName) {
}
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

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

View file

@ -36,6 +36,7 @@
#include <Environment/environment_mgr.hxx>
#include <Environment/environment.hxx>
#include <FDM/LaRCsim/basic_aero.h>
/* FGAIFlightPlan::create()
@ -242,7 +243,12 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
}
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
// fallback mechanism for this.
@ -379,7 +385,13 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
}
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
// fallback mechanism for this.
// Starting from gate 0 is a bit of a hack...
@ -878,7 +890,12 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
const string & fltType)
{
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);
//double heading = ac->getTrafficRef()->getCourse();
@ -917,15 +934,50 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
coord = rwy->pointOnCenterline((currentDist * (i / nPoints)));
wpt = createInAir(ac, buffer, coord, currentAltitude, (vTouchdown));
}*/
double rolloutDistance =
(vTouchdownMetric * vTouchdownMetric - vTaxiMetric * vTaxiMetric) / (2 * decelMetric);
//cerr << " touchdown speed = " << vTouchdown << ". Rollout distance " << rolloutDistance << endl;
int nPoints = 50;
for (int i = 1; i < nPoints; i++) {
snprintf(buffer, 12, "landing03%d", i);
for (int i = 1; i < 10; i++) {
snprintf(buffer, 12, "wpt%d", i);
coord = rwy->pointOnCenterline((rwy->lengthM() * 0.9) * (i / 10.0));
wpt = createOnGround(ac, buffer, coord, currElev, (vTouchdown / i));
wpt->setCrossat(apt->getElevation());
coord = rwy->pointOnCenterline((rolloutDistance * ((double) i / (double) nPoints)));
wpt = createOnGround(ac, buffer, coord, currElev, vTaxi);
wpt->setCrossat(currElev);
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

View file

@ -43,6 +43,7 @@ public:
inline double vRotate () { return _vRotate; };
inline double maximumBankAngle () { return _maxbank; };
inline double acceleration () { return _acceleration; };
inline double deceleration () { return _deceleration; };
inline double vTaxi () { return _vTaxi; };
inline double vTakeoff () { return _vTakeOff; };
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) {
//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")) {
_dynamics->addAwosFreq(atoi(value.c_str()));
//cerr << "Adding AWOS" << value<< endl;

View file

@ -220,6 +220,7 @@ FGGroundNetwork::FGGroundNetwork()
count = 0;
currTraffic = activeTraffic.begin();
group = 0;
version = 0;
networkInitialized = false;
}
@ -452,6 +453,28 @@ int FGGroundNetwork::findNearestNode(const SGGeod & aGeod)
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)
{
return findNearestNode(SGGeod::fromDeg(lon, lat));

View file

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

View file

@ -423,7 +423,7 @@ void FGAISchedule::scheduleFlights(time_t now)
<< " " << arrT << ":");
flights.push_back(flight);
} while (1); //(currentDestination != startingPort);
} while (currentDestination != startingPort);
SG_LOG(SG_GENERAL, SG_BULK, " Done ");
}
@ -507,7 +507,8 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
}
if (flights.size()) {
time_t arrival = flights.back()->getArrivalTime();
if ((*i)->getDepartureTime() < (arrival+(20*60)))
int groundTime = groundTimeFromRadius();
if ((*i)->getDepartureTime() < (arrival+(groundTime)))
continue;
}
if (min != 0) {
@ -531,6 +532,23 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
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()
{
FGScheduledFlightVecIterator i = flights.begin();

View file

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