AI improved entry into parking (heading and postition)
This commit is contained in:
parent
49eeb6627c
commit
b216658ba1
1 changed files with 89 additions and 76 deletions
|
@ -52,7 +52,7 @@ using std::string;
|
||||||
|
|
||||||
/* FGAIFlightPlan::create()
|
/* FGAIFlightPlan::create()
|
||||||
* dynamically create a flight plan for AI traffic, based on data provided by the
|
* dynamically create a flight plan for AI traffic, based on data provided by the
|
||||||
* Traffic Manager, when reading a filed flightplan fails. (DT, 2004/07/10)
|
* Traffic Manager, when reading a filed flightplan fails. (DT, 2004/07/10)
|
||||||
*
|
*
|
||||||
* This is the top-level function, and the only one that is publicly available.
|
* This is the top-level function, and the only one that is publicly available.
|
||||||
*
|
*
|
||||||
|
@ -68,11 +68,11 @@ bool FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep,
|
||||||
const string & aircraftType,
|
const string & aircraftType,
|
||||||
const string & airline, double distance)
|
const string & airline, double distance)
|
||||||
{
|
{
|
||||||
if( legNr <= 3 )
|
if( legNr <= 3 )
|
||||||
SG_LOG(SG_AI, SG_BULK, "Create Leg " << legNr << " " << (firstFlight?"First":"") << " Old Leg " << getLeg() << " At Airport : " << dep->getId());
|
SG_LOG(SG_AI, SG_BULK, "Create Leg " << legNr << " " << (firstFlight?"First":"") << " Old Leg " << getLeg() << " At Airport : " << dep->getId());
|
||||||
else if( legNr<= 6 )
|
else if( legNr<= 6 )
|
||||||
SG_LOG(SG_AI, SG_BULK, "Create Leg " << legNr << " " << (firstFlight?"First":"") << " Old Leg " << getLeg() << " Departure Airport : " << dep->getId() << " Arrival Airport : " << arr->getId());
|
SG_LOG(SG_AI, SG_BULK, "Create Leg " << legNr << " " << (firstFlight?"First":"") << " Old Leg " << getLeg() << " Departure Airport : " << dep->getId() << " Arrival Airport : " << arr->getId());
|
||||||
else
|
else
|
||||||
SG_LOG(SG_AI, SG_BULK, "Create Leg " << legNr << " " << (firstFlight?"First":"") << " Old Leg " << getLeg() << " At Airport : " << arr->getId());
|
SG_LOG(SG_AI, SG_BULK, "Create Leg " << legNr << " " << (firstFlight?"First":"") << " Old Leg " << getLeg() << " At Airport : " << arr->getId());
|
||||||
|
|
||||||
bool retVal = true;
|
bool retVal = true;
|
||||||
|
@ -107,7 +107,7 @@ bool FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep,
|
||||||
retVal = createLandingTaxi(ac, arr, radius, fltType, aircraftType, airline);
|
retVal = createLandingTaxi(ac, arr, radius, fltType, aircraftType, airline);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
retVal = createParking(ac, arr, radius);
|
retVal = createParking(ac, arr, radius);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//exit(1);
|
//exit(1);
|
||||||
|
@ -120,7 +120,7 @@ bool FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep,
|
||||||
//don't increment leg right away, but only once we pass the actual last waypoint that was created.
|
//don't increment leg right away, but only once we pass the actual last waypoint that was created.
|
||||||
// to do so, mark the last waypoint with a special status flag
|
// to do so, mark the last waypoint with a special status flag
|
||||||
if (retVal) {
|
if (retVal) {
|
||||||
waypoints.back()->setName( waypoints.back()->getName() + string("legend"));
|
waypoints.back()->setName( waypoints.back()->getName() + string("legend"));
|
||||||
// "It's pronounced Leg-end" (Roger Glover (Deep Purple): come Hell or High Water DvD, 1993)
|
// "It's pronounced Leg-end" (Roger Glover (Deep Purple): come Hell or High Water DvD, 1993)
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -199,7 +199,7 @@ FGAIWaypoint * FGAIFlightPlan::createInAir(FGAIAircraft * ac,
|
||||||
wpt->setSpeedBrakes(0.0f );
|
wpt->setSpeedBrakes(0.0f );
|
||||||
wpt->setOn_ground (false );
|
wpt->setOn_ground (false );
|
||||||
wpt->setCrossat (aElev );
|
wpt->setCrossat (aElev );
|
||||||
|
|
||||||
if (aPos.getElevationFt() < 10000.0f) {
|
if (aPos.getElevationFt() < 10000.0f) {
|
||||||
wpt->setApproachLights();
|
wpt->setApproachLights();
|
||||||
} else {
|
} else {
|
||||||
|
@ -222,9 +222,9 @@ FGAIWaypoint * FGAIFlightPlan::clone(FGAIWaypoint * aWpt)
|
||||||
wpt->setFinished ( aWpt->isFinished() );
|
wpt->setFinished ( aWpt->isFinished() );
|
||||||
wpt->setOn_ground ( aWpt->getOn_ground() );
|
wpt->setOn_ground ( aWpt->getOn_ground() );
|
||||||
wpt->setLandingLight (aWpt->getLandingLight() );
|
wpt->setLandingLight (aWpt->getLandingLight() );
|
||||||
wpt->setNavLight (aWpt->getNavLight() );
|
wpt->setNavLight (aWpt->getNavLight() );
|
||||||
wpt->setStrobeLight (aWpt->getStrobeLight() );
|
wpt->setStrobeLight (aWpt->getStrobeLight() );
|
||||||
wpt->setTaxiLight (aWpt->getTaxiLight() );
|
wpt->setTaxiLight (aWpt->getTaxiLight() );
|
||||||
wpt->setRouteIndex ( 0 );
|
wpt->setRouteIndex ( 0 );
|
||||||
|
|
||||||
return wpt;
|
return wpt;
|
||||||
|
@ -322,7 +322,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 in this case is a bit of a hack
|
// Starting from gate 0 in this case is a bit of a hack
|
||||||
// which requires a more proper solution later on.
|
// which requires a more proper solution later on.
|
||||||
// delete taxiRoute;
|
// delete taxiRoute;
|
||||||
|
@ -347,7 +347,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_AI, SG_WARN, "Taxiroute could not be constructed no parking." << (apt?apt->getId():"????"));
|
SG_LOG(SG_AI, SG_WARN, "Taxiroute could not be constructed no parking." << (apt?apt->getId():"????"));
|
||||||
}
|
}
|
||||||
|
|
||||||
FGTaxiRoute taxiRoute;
|
FGTaxiRoute taxiRoute;
|
||||||
if (runwayNode && node) {
|
if (runwayNode && node) {
|
||||||
taxiRoute = gn->findShortestRoute(node, runwayNode);
|
taxiRoute = gn->findShortestRoute(node, runwayNode);
|
||||||
|
@ -375,7 +375,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
||||||
for (int i = 0; i < nrWaypointsToSkip - 3; i++) {
|
for (int i = 0; i < nrWaypointsToSkip - 3; i++) {
|
||||||
taxiRoute.next(skipNode, &route);
|
taxiRoute.next(skipNode, &route);
|
||||||
}
|
}
|
||||||
|
|
||||||
gate.release(); // free up our gate as required
|
gate.release(); // free up our gate as required
|
||||||
} else {
|
} else {
|
||||||
if (taxiRoute.size() > 1) {
|
if (taxiRoute.size() > 1) {
|
||||||
|
@ -384,12 +384,12 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
||||||
}
|
}
|
||||||
|
|
||||||
// push each node on the taxi route as a waypoint
|
// push each node on the taxi route as a waypoint
|
||||||
|
|
||||||
//cerr << "Building taxi route" << endl;
|
//cerr << "Building taxi route" << endl;
|
||||||
|
|
||||||
// Note that the line wpt->setRouteIndex was commented out by revision [afcdbd] 2012-01-01,
|
// Note that the line wpt->setRouteIndex was commented out by revision [afcdbd] 2012-01-01,
|
||||||
// which breaks the rendering functions.
|
// which breaks the rendering functions.
|
||||||
// These can probably be generated on the fly however.
|
// These can probably be generated on the fly however.
|
||||||
while (taxiRoute.next(node, &route)) {
|
while (taxiRoute.next(node, &route)) {
|
||||||
char buffer[10];
|
char buffer[10];
|
||||||
snprintf(buffer, sizeof(buffer), "%d", node->getIndex());
|
snprintf(buffer, sizeof(buffer), "%d", node->getIndex());
|
||||||
|
@ -464,7 +464,7 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac,
|
||||||
{
|
{
|
||||||
int route;
|
int route;
|
||||||
gate = apt->getDynamics()->getAvailableParking(radius, fltType,
|
gate = apt->getDynamics()->getAvailableParking(radius, fltType,
|
||||||
acType, airline);
|
acType, airline);
|
||||||
SGGeod lastWptPos = waypoints.back()->getPos();
|
SGGeod lastWptPos = waypoints.back()->getPos();
|
||||||
FGGroundNetwork *gn = apt->groundNetwork();
|
FGGroundNetwork *gn = apt->groundNetwork();
|
||||||
|
|
||||||
|
@ -483,7 +483,7 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac,
|
||||||
}
|
}
|
||||||
//cerr << "Using network node " << runwayId << endl;
|
//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 doesn't work, so don't try it
|
// Starting from gate 0 doesn't work, so don't try it
|
||||||
FGTaxiRoute taxiRoute;
|
FGTaxiRoute taxiRoute;
|
||||||
if (runwayNode && gate.isValid()) {
|
if (runwayNode && gate.isValid()) {
|
||||||
|
@ -509,7 +509,7 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac,
|
||||||
FGAIWaypoint *wpt =
|
FGAIWaypoint *wpt =
|
||||||
createOnGround(ac, buffer, node->geod(), apt->getElevation(),
|
createOnGround(ac, buffer, node->geod(), apt->getElevation(),
|
||||||
ac->getPerformance()->vTaxi());
|
ac->getPerformance()->vTaxi());
|
||||||
|
|
||||||
wpt->setRouteIndex(route);
|
wpt->setRouteIndex(route);
|
||||||
// next WPT must be far enough
|
// next WPT must be far enough
|
||||||
if (!waypoints.back() || SGGeodesy::distanceM(waypoints.back()->getPos(), wpt->getPos()) > 0 ) {
|
if (!waypoints.back() || SGGeodesy::distanceM(waypoints.back()->getPos(), wpt->getPos()) > 0 ) {
|
||||||
|
@ -546,15 +546,15 @@ static double pitchDistance(double pitchAngleDeg, double altGainM)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* CreateTakeOff
|
* CreateTakeOff
|
||||||
* A note on units:
|
* A note on units:
|
||||||
* - Speed -> knots -> nm/hour
|
* - Speed -> knots -> nm/hour
|
||||||
* - distance along runway =-> meters
|
* - distance along runway =-> meters
|
||||||
* - accel / decel -> is given as knots/hour, but this is highly questionable:
|
* - accel / decel -> is given as knots/hour, but this is highly questionable:
|
||||||
* for a jet_transport performance class, a accel / decel rate of 5 / 2 is
|
* for a jet_transport performance class, a accel / decel rate of 5 / 2 is
|
||||||
* given respectively. According to performance data.cxx, a value of kts / second seems
|
* given respectively. According to performance data.cxx, a value of kts / second seems
|
||||||
* more likely however.
|
* more likely however.
|
||||||
*
|
*
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac,
|
bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac,
|
||||||
bool firstFlight,
|
bool firstFlight,
|
||||||
|
@ -568,7 +568,7 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac,
|
||||||
// climb-out angle in degrees. could move this to the perf-db but this
|
// climb-out angle in degrees. could move this to the perf-db but this
|
||||||
// value is pretty sane
|
// value is pretty sane
|
||||||
const double INITIAL_PITCH_ANGLE = 10.0;
|
const double INITIAL_PITCH_ANGLE = 10.0;
|
||||||
|
|
||||||
double accel = ac->getPerformance()->acceleration();
|
double accel = ac->getPerformance()->acceleration();
|
||||||
double vTaxi = ac->getPerformance()->vTaxi();
|
double vTaxi = ac->getPerformance()->vTaxi();
|
||||||
double vRotate = ac->getPerformance()->vRotate();
|
double vRotate = ac->getPerformance()->vRotate();
|
||||||
|
@ -578,12 +578,12 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac,
|
||||||
double vTaxiMetric = vTaxi * SG_KT_TO_MPS;
|
double vTaxiMetric = vTaxi * SG_KT_TO_MPS;
|
||||||
double vRotateMetric = vRotate * SG_KT_TO_MPS;
|
double vRotateMetric = vRotate * SG_KT_TO_MPS;
|
||||||
double vTakeoffMetric = vTakeoff * SG_KT_TO_MPS;
|
double vTakeoffMetric = vTakeoff * SG_KT_TO_MPS;
|
||||||
|
|
||||||
FGAIWaypoint *wpt;
|
FGAIWaypoint *wpt;
|
||||||
// Get the current active runway, based on code from David Luff
|
// Get the current active runway, based on code from David Luff
|
||||||
// This should actually be unified and extended to include
|
// This should actually be unified and extended to include
|
||||||
// Preferential runway use schema's
|
// Preferential runway use schema's
|
||||||
// NOTE: DT (2009-01-18: IIRC, this is currently already the case,
|
// NOTE: DT (2009-01-18: IIRC, this is currently already the case,
|
||||||
// because the getActive runway function takes care of that.
|
// because the getActive runway function takes care of that.
|
||||||
if (firstFlight) {
|
if (firstFlight) {
|
||||||
const string& rwyClass = getRunwayClassFromTrafficType(fltType);
|
const string& rwyClass = getRunwayClassFromTrafficType(fltType);
|
||||||
|
@ -599,11 +599,11 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SG_LOG(SG_AI, SG_BULK, "Takeoff from airport " << apt->getId() << "/" << activeRunway);
|
SG_LOG(SG_AI, SG_BULK, "Takeoff from airport " << apt->getId() << "/" << activeRunway);
|
||||||
|
|
||||||
FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
|
FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
|
||||||
if (!rwy)
|
if (!rwy)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
double airportElev = apt->getElevation();
|
double airportElev = apt->getElevation();
|
||||||
|
|
||||||
if (pos.isValid()) {
|
if (pos.isValid()) {
|
||||||
|
@ -633,18 +633,18 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac,
|
||||||
double vRef = vTakeoff + 20; // climb-out at v2 + 20kts
|
double vRef = vTakeoff + 20; // climb-out at v2 + 20kts
|
||||||
|
|
||||||
// We want gear-up to take place at ~400ft AGL. However, the flightplan
|
// We want gear-up to take place at ~400ft AGL. However, the flightplan
|
||||||
// will move onto the next leg once it gets within 2xspeed of the next waypoint.
|
// will move onto the next leg once it gets within 2xspeed of the next waypoint.
|
||||||
// With closely spaced waypoints on climb-out this can occur almost immediately,
|
// With closely spaced waypoints on climb-out this can occur almost immediately,
|
||||||
// so we put the waypoint further away.
|
// so we put the waypoint further away.
|
||||||
double gearUpDist = t + 2*vRef*SG_FEET_TO_METER + pitchDistance(INITIAL_PITCH_ANGLE, 400 * SG_FEET_TO_METER);
|
double gearUpDist = t + 2*vRef*SG_FEET_TO_METER + pitchDistance(INITIAL_PITCH_ANGLE, 400 * SG_FEET_TO_METER);
|
||||||
SGGeod gearUpPoint = rwy->pointOnCenterlineDisplaced(gearUpDist);
|
SGGeod gearUpPoint = rwy->pointOnCenterlineDisplaced(gearUpDist);
|
||||||
wpt = createInAir(ac, "gear-up", gearUpPoint, airportElev + 400, vRef);
|
wpt = createInAir(ac, "gear-up", gearUpPoint, airportElev + 400, vRef);
|
||||||
wpt->setFlaps(0.5f);
|
wpt->setFlaps(0.5f);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
// limit climbout speed to 240kts below 10000'
|
// limit climbout speed to 240kts below 10000'
|
||||||
double vClimbBelow10000 = std::min(240.0, ac->getPerformance()->vClimb());
|
double vClimbBelow10000 = std::min(240.0, ac->getPerformance()->vClimb());
|
||||||
|
|
||||||
// create two climb-out points. This is important becuase the first climb point will
|
// create two climb-out points. This is important becuase the first climb point will
|
||||||
// be a (sometimes large) turn towards the destination, and we don't want to
|
// be a (sometimes large) turn towards the destination, and we don't want to
|
||||||
// commence that turn below 2000'
|
// commence that turn below 2000'
|
||||||
|
@ -652,7 +652,7 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac,
|
||||||
SGGeod climbOutPoint = rwy->pointOnCenterlineDisplaced(climbOut);
|
SGGeod climbOutPoint = rwy->pointOnCenterlineDisplaced(climbOut);
|
||||||
wpt = createInAir(ac, "2000'", climbOutPoint, airportElev + 2000, vClimbBelow10000);
|
wpt = createInAir(ac, "2000'", climbOutPoint, airportElev + 2000, vClimbBelow10000);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
climbOut = t + 2*vClimbBelow10000*SG_FEET_TO_METER + pitchDistance(INITIAL_PITCH_ANGLE, 2500 * SG_FEET_TO_METER);
|
climbOut = t + 2*vClimbBelow10000*SG_FEET_TO_METER + pitchDistance(INITIAL_PITCH_ANGLE, 2500 * SG_FEET_TO_METER);
|
||||||
SGGeod climbOutPoint2 = rwy->pointOnCenterlineDisplaced(climbOut);
|
SGGeod climbOutPoint2 = rwy->pointOnCenterlineDisplaced(climbOut);
|
||||||
wpt = createInAir(ac, "2500'", climbOutPoint2, airportElev + 2500, vClimbBelow10000);
|
wpt = createInAir(ac, "2500'", climbOutPoint2, airportElev + 2500, vClimbBelow10000);
|
||||||
|
@ -671,7 +671,7 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
||||||
const string & fltType)
|
const string & fltType)
|
||||||
{
|
{
|
||||||
double vClimb = ac->getPerformance()->vClimb();
|
double vClimb = ac->getPerformance()->vClimb();
|
||||||
|
|
||||||
if (firstFlight) {
|
if (firstFlight) {
|
||||||
const string& rwyClass = getRunwayClassFromTrafficType(fltType);
|
const string& rwyClass = getRunwayClassFromTrafficType(fltType);
|
||||||
double heading = ac->getTrafficRef()->getCourse();
|
double heading = ac->getTrafficRef()->getCourse();
|
||||||
|
@ -692,10 +692,10 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
||||||
if (!waypoints.empty()) {
|
if (!waypoints.empty()) {
|
||||||
cur = waypoints.back()->getPos();
|
cur = waypoints.back()->getPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute course towards destination
|
// compute course towards destination
|
||||||
double course = SGGeodesy::courseDeg(cur, arrival->geod());
|
double course = SGGeodesy::courseDeg(cur, arrival->geod());
|
||||||
|
|
||||||
SGGeod climb1 = SGGeodesy::direct(cur, course, 10 * SG_NM_TO_METER);
|
SGGeod climb1 = SGGeodesy::direct(cur, course, 10 * SG_NM_TO_METER);
|
||||||
FGAIWaypoint *wpt = createInAir(ac, "10000ft climb", climb1, 10000, vClimb);
|
FGAIWaypoint *wpt = createInAir(ac, "10000ft climb", climb1, 10000, vClimb);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
@ -710,7 +710,7 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* CreateDescent
|
* CreateDescent
|
||||||
* Generate a flight path from the last waypoint of the cruise to
|
* Generate a flight path from the last waypoint of the cruise to
|
||||||
* the permission to land point
|
* the permission to land point
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
||||||
|
@ -724,7 +724,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
||||||
double vDescent = ac->getPerformance()->vDescent();
|
double vDescent = ac->getPerformance()->vDescent();
|
||||||
double vApproach = ac->getPerformance()->vApproach();
|
double vApproach = ac->getPerformance()->vApproach();
|
||||||
|
|
||||||
//Beginning of Descent
|
//Beginning of Descent
|
||||||
const string& rwyClass = getRunwayClassFromTrafficType(fltType);
|
const string& rwyClass = getRunwayClassFromTrafficType(fltType);
|
||||||
double heading = ac->getTrafficRef()->getCourse();
|
double heading = ac->getTrafficRef()->getCourse();
|
||||||
apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway,
|
apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway,
|
||||||
|
@ -773,13 +773,13 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
||||||
if (apt->groundNetwork()) {
|
if (apt->groundNetwork()) {
|
||||||
tn = apt->groundNetwork()->findNearestNode(refPoint);
|
tn = apt->groundNetwork()->findNearestNode(refPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tn) {
|
if (tn) {
|
||||||
dAlt = alt - ((tn->getElevationFt()) + 2000);
|
dAlt = alt - ((tn->getElevationFt()) + 2000);
|
||||||
} else {
|
} else {
|
||||||
dAlt = alt - (apt->getElevation() + 2000);
|
dAlt = alt - (apt->getElevation() + 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
double nPoints = 100;
|
double nPoints = 100;
|
||||||
char buffer[16];
|
char buffer[16];
|
||||||
|
|
||||||
|
@ -824,7 +824,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the ETA at final, based on remaining distance, and approach speed.
|
// Calculate the ETA at final, based on remaining distance, and approach speed.
|
||||||
// distance should really consist of flying time to terniary target, plus circle
|
// distance should really consist of flying time to terniary target, plus circle
|
||||||
// but the distance to secondary target should work as a reasonable approximation
|
// but the distance to secondary target should work as a reasonable approximation
|
||||||
// aditionally add the amount of distance covered by making a turn of "side"
|
// aditionally add the amount of distance covered by making a turn of "side"
|
||||||
double turnDistance = (2 * M_PI * initialTurnRadius) * (side / 360.0);
|
double turnDistance = (2 * M_PI * initialTurnRadius) * (side / 360.0);
|
||||||
|
@ -942,7 +942,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
||||||
} else {
|
} else {
|
||||||
currentAltitude = apt->getElevation() + 2000;
|
currentAltitude = apt->getElevation() + 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Length of
|
// Length of
|
||||||
if (holdsPatterns>0) {
|
if (holdsPatterns>0) {
|
||||||
|
@ -962,9 +962,9 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The approach leg should bring the aircraft to approximately 4-6 nm out, after which the landing phase should take over.
|
// The approach leg should bring the aircraft to approximately 4-6 nm out, after which the landing phase should take over.
|
||||||
//cerr << "Phase 3: Approach" << endl;
|
//cerr << "Phase 3: Approach" << endl;
|
||||||
|
|
||||||
//cerr << "Done" << endl;
|
//cerr << "Done" << endl;
|
||||||
|
|
||||||
// Erase the two bogus BOD points: Note check for conflicts with scripted AI flightPlans
|
// Erase the two bogus BOD points: Note check for conflicts with scripted AI flightPlans
|
||||||
|
@ -991,7 +991,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
||||||
}
|
}
|
||||||
|
|
||||||
SG_LOG(SG_AI, SG_BULK, "Setting Node " << waypoints[1]->getName() << " to a leg end");
|
SG_LOG(SG_AI, SG_BULK, "Setting Node " << waypoints[1]->getName() << " to a leg end");
|
||||||
waypoints[1]->setName( (waypoints[1]->getName() + string("legend")));
|
waypoints[1]->setName( (waypoints[1]->getName() + string("legend")));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1006,12 +1006,12 @@ static double runwayGlideslopeTouchdownDistance(FGRunway* rwy)
|
||||||
if (!gs) {
|
if (!gs) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SGVec3d runwayPosCart = SGVec3d::fromGeod(rwy->pointOnCenterline(0.0));
|
SGVec3d runwayPosCart = SGVec3d::fromGeod(rwy->pointOnCenterline(0.0));
|
||||||
// compute a unit vector in ECF cartesian space, from the runway beginning to the end
|
// compute a unit vector in ECF cartesian space, from the runway beginning to the end
|
||||||
SGVec3d runwayDirectionVec = normalize(SGVec3d::fromGeod(rwy->end()) - runwayPosCart);
|
SGVec3d runwayDirectionVec = normalize(SGVec3d::fromGeod(rwy->end()) - runwayPosCart);
|
||||||
SGVec3d gsTransmitterVec = gs->cart() - runwayPosCart;
|
SGVec3d gsTransmitterVec = gs->cart() - runwayPosCart;
|
||||||
|
|
||||||
// project the gsTransmitterVec along the runwayDirctionVec to get out
|
// project the gsTransmitterVec along the runwayDirctionVec to get out
|
||||||
// final value (in metres)
|
// final value (in metres)
|
||||||
double dist = dot(runwayDirectionVec, gsTransmitterVec);
|
double dist = dot(runwayDirectionVec, gsTransmitterVec);
|
||||||
|
@ -1022,7 +1022,7 @@ static double runwayGlideslopeTouchdownDistance(FGRunway* rwy)
|
||||||
* CreateLanding (Leg 7)
|
* CreateLanding (Leg 7)
|
||||||
* Create a flight path from the "permision to land" point (currently
|
* Create a flight path from the "permision to land" point (currently
|
||||||
hardcoded at 5000 meters from the threshold) to the threshold, at
|
hardcoded at 5000 meters from the threshold) to the threshold, at
|
||||||
a standard glide slope angle of 3 degrees.
|
a standard glide slope angle of 3 degrees.
|
||||||
Position : 50.0354 8.52592 384 364 11112
|
Position : 50.0354 8.52592 384 364 11112
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
|
@ -1032,7 +1032,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
double vTaxi = ac->getPerformance()->vTaxi();
|
double vTaxi = ac->getPerformance()->vTaxi();
|
||||||
double decel = ac->getPerformance()->decelerationOnGround();
|
double decel = ac->getPerformance()->decelerationOnGround();
|
||||||
double vApproach = ac->getPerformance()->vApproach();
|
double vApproach = ac->getPerformance()->vApproach();
|
||||||
|
|
||||||
double vTouchdownMetric = vTouchdown * SG_KT_TO_MPS;
|
double vTouchdownMetric = vTouchdown * SG_KT_TO_MPS;
|
||||||
double vTaxiMetric = vTaxi * SG_KT_TO_MPS;
|
double vTaxiMetric = vTaxi * SG_KT_TO_MPS;
|
||||||
double decelMetric = decel * SG_KT_TO_MPS;
|
double decelMetric = decel * SG_KT_TO_MPS;
|
||||||
|
@ -1046,17 +1046,17 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
|
FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
|
||||||
if (!rwy)
|
if (!rwy)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SGGeod threshold = rwy->threshold();
|
SGGeod threshold = rwy->threshold();
|
||||||
double currElev = threshold.getElevationFt();
|
double currElev = threshold.getElevationFt();
|
||||||
|
|
||||||
double touchdownDistance = runwayGlideslopeTouchdownDistance(rwy);
|
double touchdownDistance = runwayGlideslopeTouchdownDistance(rwy);
|
||||||
if (touchdownDistance < 0.0) {
|
if (touchdownDistance < 0.0) {
|
||||||
double landingLength = rwy->lengthM() - (rwy->displacedThresholdM());
|
double landingLength = rwy->lengthM() - (rwy->displacedThresholdM());
|
||||||
// touchdown 25% of the way along the landing area
|
// touchdown 25% of the way along the landing area
|
||||||
touchdownDistance = rwy->displacedThresholdM() + (landingLength * 0.25);
|
touchdownDistance = rwy->displacedThresholdM() + (landingLength * 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
SGGeod coord;
|
SGGeod coord;
|
||||||
// find glideslope entry point, 2000' above touchdown elevation
|
// find glideslope entry point, 2000' above touchdown elevation
|
||||||
double glideslopeEntry = -((2000 * SG_FEET_TO_METER) / tan(3.0)) + touchdownDistance;
|
double glideslopeEntry = -((2000 * SG_FEET_TO_METER) / tan(3.0)) + touchdownDistance;
|
||||||
|
@ -1066,7 +1066,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
wpt->setFlaps(1.0f);
|
wpt->setFlaps(1.0f);
|
||||||
wpt->setSpeedBrakes(1.0f);
|
wpt->setSpeedBrakes(1.0f);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
// deceleration point, 500' above touchdown elevation - slow from approach speed
|
// deceleration point, 500' above touchdown elevation - slow from approach speed
|
||||||
// to touchdown speed
|
// to touchdown speed
|
||||||
double decelPoint = -((500 * SG_FEET_TO_METER) / tan(3.0)) + touchdownDistance;
|
double decelPoint = -((500 * SG_FEET_TO_METER) / tan(3.0)) + touchdownDistance;
|
||||||
|
@ -1076,7 +1076,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
wpt->setFlaps(1.0f);
|
wpt->setFlaps(1.0f);
|
||||||
wpt->setSpeedBrakes(1.0f);
|
wpt->setSpeedBrakes(1.0f);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
// compute elevation above the runway start, based on a 3-degree glideslope
|
// compute elevation above the runway start, based on a 3-degree glideslope
|
||||||
double heightAboveRunwayStart = touchdownDistance *
|
double heightAboveRunwayStart = touchdownDistance *
|
||||||
tan(3.0 * SG_DEGREES_TO_RADIANS) * SG_METER_TO_FEET;
|
tan(3.0 * SG_DEGREES_TO_RADIANS) * SG_METER_TO_FEET;
|
||||||
|
@ -1086,9 +1086,9 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
wpt->setFlaps(1.0f);
|
wpt->setFlaps(1.0f);
|
||||||
wpt->setSpeedBrakes(1.0f);
|
wpt->setSpeedBrakes(1.0f);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
double rolloutDistance = accelDistance(vTouchdownMetric, vTaxiMetric, decelMetric);
|
double rolloutDistance = accelDistance(vTouchdownMetric, vTaxiMetric, decelMetric);
|
||||||
|
|
||||||
int nPoints = (int)(rolloutDistance/60);
|
int nPoints = (int)(rolloutDistance/60);
|
||||||
for (int i = 1; i <= nPoints; i++) {
|
for (int i = 1; i <= nPoints; i++) {
|
||||||
snprintf(buffer, sizeof(buffer), "rollout%03d", i);
|
snprintf(buffer, sizeof(buffer), "rollout%03d", i);
|
||||||
|
@ -1102,7 +1102,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
wpt->setCrossat(currElev);
|
wpt->setCrossat(currElev);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
}
|
}
|
||||||
|
|
||||||
wpt->setSpeed(vTaxi);
|
wpt->setSpeed(vTaxi);
|
||||||
double mindist = (1.1 * rolloutDistance) + touchdownDistance;
|
double mindist = (1.1 * rolloutDistance) + touchdownDistance;
|
||||||
|
|
||||||
|
@ -1111,7 +1111,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
SG_LOG(SG_AI, SG_DEBUG, "No groundnet " << apt->getId() << " no landing created.");
|
SG_LOG(SG_AI, SG_DEBUG, "No groundnet " << apt->getId() << " no landing created.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
coord = rwy->pointOnCenterline(mindist);
|
coord = rwy->pointOnCenterline(mindist);
|
||||||
FGTaxiNodeRef tn;
|
FGTaxiNodeRef tn;
|
||||||
if (gn->getVersion() > 0) {
|
if (gn->getVersion() > 0) {
|
||||||
|
@ -1119,7 +1119,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
} else {
|
} else {
|
||||||
tn = gn->findNearestNode(coord);
|
tn = gn->findNearestNode(coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tn) {
|
if (tn) {
|
||||||
wpt = createOnRunway(ac, buffer, tn->geod(), currElev, vTaxi);
|
wpt = createOnRunway(ac, buffer, tn->geod(), currElev, vTaxi);
|
||||||
wpt->setFlaps(1.0f);
|
wpt->setFlaps(1.0f);
|
||||||
|
@ -1148,35 +1148,48 @@ bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt,
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGParking* parking = gate.parking();
|
FGParking* parking = gate.parking();
|
||||||
double reverseHeading = SGMiscd::normalizePeriodic(0, 360, parking->getHeading() + 180.0);
|
double reverseHeading = SGMiscd::normalizePeriodic(0, 360, parking->getHeading() + 180.0);
|
||||||
double az; // unused
|
double az; // unused
|
||||||
SGGeod pos;
|
SGGeod pos;
|
||||||
|
|
||||||
SGGeodesy::direct(parking->geod(), reverseHeading, 2 * parking->getRadius(),
|
SGGeodesy::direct(parking->geod(), reverseHeading, 2 * parking->getRadius(),
|
||||||
pos, az);
|
pos, az);
|
||||||
|
|
||||||
wpt = createOnGround(ac, "parking", pos, aptElev, vTaxiReduced/2);
|
wpt = createOnGround(ac, "parking1", pos, aptElev, vTaxiReduced/3);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
SGGeodesy::direct(parking->geod(), reverseHeading, 1.5 * parking->getRadius(),
|
SGGeodesy::direct(parking->geod(), reverseHeading, 1 * parking->getRadius(),
|
||||||
pos, az);
|
pos, az);
|
||||||
wpt = createOnGround(ac, "parking2", pos, aptElev, vTaxiReduced/3);
|
wpt = createOnGround(ac, "parking2", pos, aptElev, vTaxiReduced/3);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
SGGeodesy::direct(parking->geod(), reverseHeading, parking->getRadius(),
|
SGGeodesy::direct(parking->geod(), reverseHeading, 0.6 * parking->getRadius(),
|
||||||
pos, az);
|
pos, az);
|
||||||
wpt = createOnGround(ac, "parking3", pos, aptElev, vTaxiReduced/3);
|
wpt = createOnGround(ac, "parking3", pos, aptElev, vTaxiReduced/3);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
char buffer[30];
|
SGGeodesy::direct(parking->geod(), reverseHeading, 0.3 * parking->getRadius(),
|
||||||
snprintf(buffer, 30, "Parking%s", parking->getName().c_str());
|
pos, az);
|
||||||
|
wpt = createOnGround(ac, "parking4", pos, aptElev, vTaxiReduced/3);
|
||||||
wpt = createOnGround(ac, buffer, parking->geod(), aptElev,
|
|
||||||
2);
|
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
SGGeodesy::direct(parking->geod(), parking->getHeading(), 1,
|
|
||||||
|
SGGeodesy::direct(parking->geod(), reverseHeading, 0.2 * parking->getRadius(),
|
||||||
|
pos, az);
|
||||||
|
wpt = createOnGround(ac, "parking5", pos, aptElev, vTaxiReduced/3);
|
||||||
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
|
char buffer[30];
|
||||||
|
snprintf(buffer, sizeof(buffer), "Parking%s", parking->getName().c_str());
|
||||||
|
|
||||||
|
wpt = createOnGround(ac, buffer, parking->geod(), aptElev, vTaxiReduced/3);
|
||||||
|
pushBackWaypoint(wpt);
|
||||||
|
SGGeodesy::direct(parking->geod(), parking->getHeading(), 2,
|
||||||
|
pos, az);
|
||||||
|
wpt = createOnGround(ac, "Beyond-Parking", pos, aptElev, vTaxiReduced/3);
|
||||||
|
pushBackWaypoint(wpt);
|
||||||
|
SGGeodesy::direct(parking->geod(), parking->getHeading(), 3,
|
||||||
pos, az);
|
pos, az);
|
||||||
wpt = createOnGround(ac, "END-Parking", pos, aptElev, vTaxiReduced/3);
|
wpt = createOnGround(ac, "END-Parking", pos, aptElev, vTaxiReduced/3);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
@ -1191,7 +1204,7 @@ bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt,
|
||||||
* preference schedule to be used at aircraft having
|
* preference schedule to be used at aircraft having
|
||||||
* a preferential runway schedule implemented (i.e.
|
* a preferential runway schedule implemented (i.e.
|
||||||
* having a rwyprefs.xml file
|
* having a rwyprefs.xml file
|
||||||
*
|
*
|
||||||
* Currently valid traffic types for gate assignment:
|
* Currently valid traffic types for gate assignment:
|
||||||
* - gate (commercial gate)
|
* - gate (commercial gate)
|
||||||
* - cargo (commercial gargo),
|
* - cargo (commercial gargo),
|
||||||
|
|
Loading…
Reference in a new issue