AITraffic exits the runway as soon as possible (in theory; the code still needs some fine tuning).
This commit is contained in:
parent
ed30b0c9a3
commit
da3c098a4b
10 changed files with 152 additions and 17 deletions
|
@ -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;
|
||||
|
@ -817,8 +817,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
|||
} else {
|
||||
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
|
||||
|
|
|
@ -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{
|
||||
|
@ -545,4 +554,12 @@ double FGAIFlightPlan::checkTrackLength(string wptName) {
|
|||
trackDistance = 0; // name not found
|
||||
}
|
||||
return trackDistance;
|
||||
}
|
||||
}
|
||||
|
||||
void FGAIFlightPlan::shortenToFirst(unsigned int number, string name)
|
||||
{
|
||||
while (waypoints.size() > number + 3) {
|
||||
eraseLastWaypoint();
|
||||
}
|
||||
(waypoints.back())->setName((waypoints.back())->getName() + name);
|
||||
}
|
||||
|
|
|
@ -164,6 +164,8 @@ public:
|
|||
FGAIFlightPlan* getSID() { return sid; };
|
||||
FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; };
|
||||
FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
|
||||
|
||||
void shortenToFirst(unsigned int number, std::string name);
|
||||
|
||||
private:
|
||||
FGAIFlightPlan *sid;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}*/
|
||||
|
||||
for (int i = 1; i < 10; i++) {
|
||||
snprintf(buffer, 12, "wpt%d", i);
|
||||
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);
|
||||
|
||||
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
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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; };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 ¤tDesti
|
|||
}
|
||||
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 ¤tDesti
|
|||
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();
|
||||
|
|
|
@ -63,6 +63,7 @@ class FGAISchedule
|
|||
bool valid;
|
||||
|
||||
void scheduleFlights(time_t now);
|
||||
int groundTimeFromRadius();
|
||||
|
||||
/**
|
||||
* Transition this schedule from distant mode to AI mode;
|
||||
|
|
Loading…
Reference in a new issue