1
0
Fork 0

One step further toward better integration of AI and ATC systems.

* Changed the runway XX. ATC message to actually report the real
   designated departure runway
 * In case of multiple active runways, select the one with a heading that is
   closest to the direction of the ultimate departure destination / lines up
   with the arrival path.
This commit is contained in:
durk 2009-02-15 15:29:56 +00:00 committed by Tim Moore
parent 80c4bbd1eb
commit d24fe19914
10 changed files with 142 additions and 83 deletions

View file

@ -42,6 +42,7 @@
#include <Environment/environment.hxx>
#include "AIFlightPlan.hxx"
#include "AIAircraft.hxx"
using std::cerr;
@ -201,7 +202,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
if (timeDiff >= 2000)
leg = 5;
SG_LOG(SG_GENERAL, SG_INFO, "Route from " << dep->getId() << " to " << arr->getId() << ". Set leg to : " << leg);
SG_LOG(SG_GENERAL, SG_INFO, "Route from " << dep->getId() << " to " << arr->getId() << ". Set leg to : " << leg << " " << ac->getTrafficRef()->getCallSign());
wpt_iterator = waypoints.begin();
create(ac, dep,arr, leg, alt, speed, lat, lon,
firstLeg, radius, fltType, acType, airline);

View file

@ -110,6 +110,9 @@ public:
string getRunway() { return activeRunway; }
bool isActive(time_t time) {return time >= this->getStartTime();}
void setRunway(string rwy) { activeRunway = rwy; };
string getRunwayClassFromTrafficType(string fltType);
private:
FGRunway* rwy;
typedef vector <waypoint*> wpt_vector_type;
@ -129,30 +132,30 @@ private:
FGAirRoute airRoute;
FGTaxiRoute *taxiRoute;
void createPushBack(bool, FGAirport*, double, double, double, const string&, const string&, const string&);
void createPushBackFallBack(bool, FGAirport*, double, double, double, const string&, const string&, const string&);
void createPushBack(FGAIAircraft *, bool, FGAirport*, double, double, double, const string&, const string&, const string&);
void createPushBackFallBack(FGAIAircraft *, bool, FGAirport*, double, double, double, const string&, const string&, const string&);
void createTakeOff(FGAIAircraft *, bool, FGAirport *, double, const string&);
void createClimb(bool, FGAirport *, double, double, const string&);
void createCruise(bool, FGAirport*, FGAirport*, double, double, double, double, const string&);
void createDecent(FGAirport *, const string&);
void createLanding(FGAirport *);
void createParking(FGAirport *, double radius);
void createClimb(FGAIAircraft *, bool, FGAirport *, double, double, const string&);
void createCruise(FGAIAircraft *, bool, FGAirport*, FGAirport*, double, double, double, double, const string&);
void createDecent(FGAIAircraft *, FGAirport *, const string&);
void createLanding(FGAIAircraft *, FGAirport *);
void createParking(FGAIAircraft *, FGAirport *, double radius);
void deleteWaypoints();
void resetWaypoints();
void createLandingTaxi(FGAirport *apt, double radius, const string& fltType, const string& acType, const string& airline);
void createDefaultLandingTaxi(FGAirport* aAirport);
void createDefaultTakeoffTaxi(FGAirport* aAirport, FGRunway* aRunway);
void createTakeoffTaxi(bool firstFlight, FGAirport *apt, double radius, const string& fltType, const string& acType, const string& airline);
void createLandingTaxi(FGAIAircraft *, FGAirport *apt, double radius, const string& fltType, const string& acType, const string& airline);
void createDefaultLandingTaxi(FGAIAircraft *, FGAirport* aAirport);
void createDefaultTakeoffTaxi(FGAIAircraft *, FGAirport* aAirport, FGRunway* aRunway);
void createTakeoffTaxi(FGAIAircraft *, bool firstFlight, FGAirport *apt, double radius, const string& fltType, const string& acType, const string& airline);
waypoint* createOnGround(const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
waypoint* createInAir(const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
waypoint* cloneWithPos(waypoint* aWpt, const std::string& aName, const SGGeod& aPos);
waypoint* createOnGround(FGAIAircraft *, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
waypoint* createInAir(FGAIAircraft *, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
waypoint* cloneWithPos(FGAIAircraft *, waypoint* aWpt, const std::string& aName, const SGGeod& aPos);
string getRunwayClassFromTrafficType(string fltType);
//void createCruiseFallback(bool, FGAirport*, FGAirport*, double, double, double, double);
void evaluateRoutePart(double deplat, double deplon, double arrlat, double arrlon);
};
#endif // _FG_AIFLIGHTPLAN_HXX

View file

@ -53,32 +53,32 @@ void FGAIFlightPlan::create(FGAIAircraft *ac, FGAirport *dep, FGAirport *arr, in
switch(legNr)
{
case 1:
createPushBack(firstFlight,dep, latitude, longitude,
createPushBack(ac, firstFlight,dep, latitude, longitude,
radius, fltType, aircraftType, airline);
break;
case 2:
createTakeoffTaxi(firstFlight, dep, radius, fltType, aircraftType, airline);
createTakeoffTaxi(ac, firstFlight, dep, radius, fltType, aircraftType, airline);
break;
case 3:
createTakeOff(ac, firstFlight, dep, speed, fltType);
break;
case 4:
createClimb(firstFlight, dep, speed, alt, fltType);
createClimb(ac, firstFlight, dep, speed, alt, fltType);
break;
case 5:
createCruise(firstFlight, dep,arr, latitude, longitude, speed, alt, fltType);
createCruise(ac, firstFlight, dep,arr, latitude, longitude, speed, alt, fltType);
break;
case 6:
createDecent(arr, fltType);
createDecent(ac, arr, fltType);
break;
case 7:
createLanding(arr);
createLanding(ac, arr);
break;
case 8:
createLandingTaxi(arr, radius, fltType, aircraftType, airline);
createLandingTaxi(ac, arr, radius, fltType, aircraftType, airline);
break;
case 9:
createParking(arr, radius);
createParking(ac, arr, radius);
break;
default:
//exit(1);
@ -90,7 +90,7 @@ void FGAIFlightPlan::create(FGAIAircraft *ac, FGAirport *dep, FGAirport *arr, in
}
FGAIFlightPlan::waypoint*
FGAIFlightPlan::createOnGround(const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed)
FGAIFlightPlan::createOnGround(FGAIAircraft *ac, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed)
{
waypoint* wpt = new waypoint;
wpt->name = aName;
@ -108,7 +108,7 @@ FGAIFlightPlan::createOnGround(const std::string& aName, const SGGeod& aPos, dou
}
FGAIFlightPlan::waypoint*
FGAIFlightPlan::createInAir(const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed)
FGAIFlightPlan::createInAir(FGAIAircraft *ac, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed)
{
waypoint* wpt = new waypoint;
wpt->name = aName;
@ -126,7 +126,7 @@ FGAIFlightPlan::createInAir(const std::string& aName, const SGGeod& aPos, double
}
FGAIFlightPlan::waypoint*
FGAIFlightPlan::cloneWithPos(waypoint* aWpt, const std::string& aName, const SGGeod& aPos)
FGAIFlightPlan::cloneWithPos(FGAIAircraft *ac, waypoint* aWpt, const std::string& aName, const SGGeod& aPos)
{
waypoint* wpt = new waypoint;
wpt->name = aName;
@ -145,19 +145,19 @@ FGAIFlightPlan::cloneWithPos(waypoint* aWpt, const std::string& aName, const SGG
return wpt;
}
void FGAIFlightPlan::createDefaultTakeoffTaxi(FGAirport* aAirport, FGRunway* aRunway)
void FGAIFlightPlan::createDefaultTakeoffTaxi(FGAIAircraft *ac, FGAirport* aAirport, FGRunway* aRunway)
{
SGGeod runwayTakeoff = aRunway->pointOnCenterline(5.0);
double airportElev = aAirport->getElevation();
waypoint* wpt;
wpt = createOnGround("Airport Center", aAirport->geod(), airportElev, 15);
wpt = createOnGround(ac, "Airport Center", aAirport->geod(), airportElev, 15);
waypoints.push_back(wpt);
wpt = createOnGround("Runway Takeoff", runwayTakeoff, airportElev, 15);
wpt = createOnGround(ac, "Runway Takeoff", runwayTakeoff, airportElev, 15);
waypoints.push_back(wpt);
}
void FGAIFlightPlan::createTakeoffTaxi(bool firstFlight,
void FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft *ac, bool firstFlight,
FGAirport *apt,
double radius, const string& fltType,
const string& acType, const string& airline)
@ -182,13 +182,19 @@ void FGAIFlightPlan::createTakeoffTaxi(bool firstFlight,
}
string rwyClass = getRunwayClassFromTrafficType(fltType);
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
// Only set this if it hasn't been set by ATC already.
if (activeRunway.empty()) {
//cerr << "Getting runway for " << ac->getTrafficRef()->getCallSign() << " at " << apt->getId() << endl;
double depHeading = ac->getTrafficRef()->getCourse();
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, depHeading);
}
rwy = apt->getRunwayByIdent(activeRunway);
SGGeod runwayTakeoff = rwy->pointOnCenterline(5.0);
FGGroundNetwork* gn = apt->getDynamics()->getGroundNetwork();
if (!gn->exists()) {
createDefaultTakeoffTaxi(apt, rwy);
createDefaultTakeoffTaxi(ac, apt, rwy);
return;
}
@ -227,7 +233,7 @@ void FGAIFlightPlan::createTakeoffTaxi(bool firstFlight,
intVecIterator i;
if (taxiRoute->empty()) {
createDefaultTakeoffTaxi(apt, rwy);
createDefaultTakeoffTaxi(ac, apt, rwy);
return;
}
@ -256,31 +262,31 @@ void FGAIFlightPlan::createTakeoffTaxi(bool firstFlight,
char buffer[10];
snprintf (buffer, 10, "%d", node);
FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
waypoint* wpt = createOnGround(buffer, tn->geod(), apt->getElevation(), 15);
waypoint* wpt = createOnGround(ac, buffer, tn->geod(), apt->getElevation(), 15);
wpt->routeIndex = route;
waypoints.push_back(wpt);
}
}
void FGAIFlightPlan::createDefaultLandingTaxi(FGAirport* aAirport)
void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft *ac, FGAirport* aAirport)
{
SGGeod lastWptPos =
SGGeod::fromDeg(waypoints.back()->longitude, waypoints.back()->latitude);
double airportElev = aAirport->getElevation();
waypoint* wpt;
wpt = createOnGround("Runway Exit", lastWptPos, airportElev, 15);
wpt = createOnGround(ac, "Runway Exit", lastWptPos, airportElev, 15);
waypoints.push_back(wpt);
wpt = createOnGround("Airport Center", aAirport->geod(), airportElev, 15);
wpt = createOnGround(ac, "Airport Center", aAirport->geod(), airportElev, 15);
waypoints.push_back(wpt);
double heading, lat, lon;
aAirport->getDynamics()->getParking(gateId, &lat, &lon, &heading);
wpt = createOnGround("END", SGGeod::fromDeg(lon, lat), airportElev, 15);
wpt = createOnGround(ac, "END", SGGeod::fromDeg(lon, lat), airportElev, 15);
waypoints.push_back(wpt);
}
void FGAIFlightPlan::createLandingTaxi(FGAirport *apt,
void FGAIFlightPlan::createLandingTaxi(FGAIAircraft *ac, FGAirport *apt,
double radius, const string& fltType,
const string& acType, const string& airline)
{
@ -294,7 +300,7 @@ void FGAIFlightPlan::createLandingTaxi(FGAirport *apt,
// Find a route from runway end to parking/gate.
if (!gn->exists()) {
createDefaultLandingTaxi(apt);
createDefaultLandingTaxi(ac, apt);
return;
}
@ -313,7 +319,7 @@ void FGAIFlightPlan::createLandingTaxi(FGAirport *apt,
intVecIterator i;
if (taxiRoute->empty()) {
createDefaultLandingTaxi(apt);
createDefaultLandingTaxi(ac, apt);
return;
}
@ -328,7 +334,7 @@ void FGAIFlightPlan::createLandingTaxi(FGAirport *apt,
char buffer[10];
snprintf (buffer, 10, "%d", node);
FGTaxiNode *tn = gn->findNode(node);
waypoint* wpt = createOnGround(buffer, tn->geod(), apt->getElevation(), 15);
waypoint* wpt = createOnGround(ac, buffer, tn->geod(), apt->getElevation(), 15);
wpt->routeIndex = route;
waypoints.push_back(wpt);
}
@ -359,32 +365,33 @@ void FGAIFlightPlan::createTakeOff(FGAIAircraft *ac, bool firstFlight, FGAirport
if (firstFlight)
{
string rwyClass = getRunwayClassFromTrafficType(fltType);
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
double heading = ac->getTrafficRef()->getCourse();
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, heading);
rwy = apt->getRunwayByIdent(activeRunway);
}
double airportElev = apt->getElevation();
// Acceleration point, 105 meters into the runway,
SGGeod accelPoint = rwy->pointOnCenterline(105.0);
wpt = createOnGround("accel", accelPoint, airportElev, speed);
wpt = createOnGround(ac, "accel", accelPoint, airportElev, speed);
waypoints.push_back(wpt);
//Start Climbing to 3000 ft. Let's do this
// at the center of the runway for now:
SGGeod rotate = rwy->pointOnCenterline(105.0+accelDistance);
wpt = cloneWithPos(wpt, "SOC", rotate);
wpt = cloneWithPos(ac, wpt, "SOC", rotate);
wpt->altitude = airportElev+1000;
wpt->on_ground = false;
waypoints.push_back(wpt);
wpt = cloneWithPos(wpt, "3000 ft", rwy->end());
wpt = cloneWithPos(ac, wpt, "3000 ft", rwy->end());
wpt->altitude = airportElev+3000;
waypoints.push_back(wpt);
// Finally, add two more waypoints, so that aircraft will remain under
// Tower control until they have reached the 3000 ft climb point
SGGeod pt = rwy->pointOnCenterline(5000 + rwy->lengthM() * 0.5);
wpt = cloneWithPos(wpt, "5000 ft", pt);
wpt = cloneWithPos(ac, wpt, "5000 ft", pt);
wpt->altitude = airportElev+5000;
waypoints.push_back(wpt);
}
@ -393,24 +400,25 @@ void FGAIFlightPlan::createTakeOff(FGAIAircraft *ac, bool firstFlight, FGAirport
* CreateClimb
* initialize the Aircraft at the parking location
******************************************************************/
void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, double alt, const string &fltType)
void FGAIFlightPlan::createClimb(FGAIAircraft *ac, bool firstFlight, FGAirport *apt, double speed, double alt, const string &fltType)
{
waypoint *wpt;
if (firstFlight) {
string rwyClass = getRunwayClassFromTrafficType(fltType);
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
double heading = ac->getTrafficRef()->getCourse();
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, heading);
rwy = apt->getRunwayByIdent(activeRunway);
}
SGGeod climb1 = rwy->pointOnCenterline(10*SG_NM_TO_METER);
wpt = createInAir("10000ft climb", climb1, speed, 10000);
wpt = createInAir(ac, "10000ft climb", climb1, speed, 10000);
wpt->gear_down = true;
wpt->flaps_down= true;
waypoints.push_back(wpt);
SGGeod climb2 = rwy->pointOnCenterline(20*SG_NM_TO_METER);
wpt = cloneWithPos(wpt, "18000ft climb", climb2);
wpt = cloneWithPos(ac, wpt, "18000ft climb", climb2);
wpt->altitude = 18000;
waypoints.push_back(wpt);
}
@ -420,7 +428,7 @@ void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed,
* CreateDecent
* initialize the Aircraft at the parking location
******************************************************************/
void FGAIFlightPlan::createDecent(FGAirport *apt, const string &fltType)
void FGAIFlightPlan::createDecent(FGAIAircraft *ac, FGAirport *apt, const string &fltType)
{
// Ten thousand ft. Slowing down to 240 kts
waypoint *wpt;
@ -429,17 +437,18 @@ void FGAIFlightPlan::createDecent(FGAirport *apt, const string &fltType)
//string name;
// allow "mil" and "gen" as well
string rwyClass = getRunwayClassFromTrafficType(fltType);
apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway);
double heading = ac->getTrafficRef()->getCourse();
apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway, heading);
rwy = apt->getRunwayByIdent(activeRunway);
SGGeod descent1 = rwy->pointOnCenterline(-100000); // 100km out
wpt = createInAir("Dec 10000ft", descent1, apt->getElevation(), 240);
wpt = createInAir(ac, "Dec 10000ft", descent1, apt->getElevation(), 240);
wpt->crossat = 10000;
waypoints.push_back(wpt);
// Three thousand ft. Slowing down to 160 kts
SGGeod descent2 = rwy->pointOnCenterline(-8*SG_NM_TO_METER); // 8nm out
wpt = createInAir("DEC 3000ft", descent2, apt->getElevation(), 160);
wpt = createInAir(ac, "DEC 3000ft", descent2, apt->getElevation(), 160);
wpt->crossat = 3000;
wpt->gear_down = true;
wpt->flaps_down= true;
@ -449,22 +458,22 @@ void FGAIFlightPlan::createDecent(FGAirport *apt, const string &fltType)
* CreateLanding
* initialize the Aircraft at the parking location
******************************************************************/
void FGAIFlightPlan::createLanding(FGAirport *apt)
void FGAIFlightPlan::createLanding(FGAIAircraft *ac, FGAirport *apt)
{
// Ten thousand ft. Slowing down to 150 kts
waypoint *wpt;
double aptElev = apt->getElevation();
//Runway Threshold
wpt = createOnGround("Threshold", rwy->threshold(), aptElev, 150);
wpt = createOnGround(ac, "Threshold", rwy->threshold(), aptElev, 150);
wpt->crossat = apt->getElevation();
waypoints.push_back(wpt);
// Roll-out
wpt = createOnGround("Center", rwy->geod(), aptElev, 30);
wpt = createOnGround(ac, "Center", rwy->geod(), aptElev, 30);
waypoints.push_back(wpt);
SGGeod rollOut = rwy->pointOnCenterline(rwy->lengthM() * 0.9);
wpt = createOnGround("Roll Out", rollOut, aptElev, 15);
wpt = createOnGround(ac, "Roll Out", rollOut, aptElev, 15);
wpt->crossat = apt->getElevation();
waypoints.push_back(wpt);
}
@ -473,7 +482,7 @@ void FGAIFlightPlan::createLanding(FGAirport *apt)
* CreateParking
* initialize the Aircraft at the parking location
******************************************************************/
void FGAIFlightPlan::createParking(FGAirport *apt, double radius)
void FGAIFlightPlan::createParking(FGAIAircraft *ac, FGAirport *apt, double radius)
{
waypoint* wpt;
double aptElev = apt->getElevation();
@ -488,17 +497,17 @@ void FGAIFlightPlan::createParking(FGAirport *apt, double radius)
geo_direct_wgs_84 ( 0, lat, lon, heading,
2.2*radius,
&lat2, &lon2, &az2 );
wpt = createOnGround("taxiStart", SGGeod::fromDeg(lon2, lat2), aptElev, 10);
wpt = createOnGround(ac, "taxiStart", SGGeod::fromDeg(lon2, lat2), aptElev, 10);
waypoints.push_back(wpt);
geo_direct_wgs_84 ( 0, lat, lon, heading,
0.1 *radius,
&lat2, &lon2, &az2 );
wpt = createOnGround("taxiStart2", SGGeod::fromDeg(lon2, lat2), aptElev, 10);
wpt = createOnGround(ac, "taxiStart2", SGGeod::fromDeg(lon2, lat2), aptElev, 10);
waypoints.push_back(wpt);
wpt = createOnGround("END", SGGeod::fromDeg(lon, lat), aptElev, 10);
wpt = createOnGround(ac, "END", SGGeod::fromDeg(lon, lat), aptElev, 10);
waypoints.push_back(wpt);
}

View file

@ -26,6 +26,7 @@
#include <fstream>
#include <iostream>
#include "AIFlightPlan.hxx"
#include "AIAircraft.hxx"
#include <simgear/math/polar3d.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/route/waypoint.hxx>
@ -310,21 +311,22 @@ void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep,
* Note that this is the original version that does not
* do any dynamic route computation.
******************************************************************/
void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep,
void FGAIFlightPlan::createCruise(FGAIAircraft *ac, bool firstFlight, FGAirport *dep,
FGAirport *arr, double latitude,
double longitude, double speed,
double alt, const string& fltType)
{
waypoint *wpt;
wpt = createInAir("Cruise", SGGeod::fromDeg(longitude, latitude), alt, speed);
wpt = createInAir(ac, "Cruise", SGGeod::fromDeg(longitude, latitude), alt, speed);
waypoints.push_back(wpt);
string rwyClass = getRunwayClassFromTrafficType(fltType);
arr->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway);
double heading = ac->getTrafficRef()->getCourse();
arr->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway, heading);
rwy = arr->getRunwayByIdent(activeRunway);
// begin descent 110km out
SGGeod beginDescentPoint = rwy->pointOnCenterline(-110000);
wpt = createInAir("BOD", beginDescentPoint, alt, speed);
wpt = createInAir(ac, "BOD", beginDescentPoint, alt, speed);
waypoints.push_back(wpt);
}

View file

@ -31,7 +31,8 @@
#include <Environment/environment.hxx>
void FGAIFlightPlan::createPushBack(bool firstFlight, FGAirport *dep,
void FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
bool firstFlight, FGAirport *dep,
double latitude,
double longitude,
double radius,
@ -41,9 +42,13 @@ void FGAIFlightPlan::createPushBack(bool firstFlight, FGAirport *dep,
{
double lat, lon, heading;
FGTaxiRoute *pushBackRoute;
// Active runway can be conditionally set by ATC, so at the start of a new flight, this
// must be reset.
activeRunway.clear();
if (!(dep->getDynamics()->getGroundNetwork()->exists())) {
//cerr << "Push Back fallback" << endl;
createPushBackFallBack(firstFlight, dep, latitude, longitude,
createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
radius, fltType, aircraftType, airline);
} else {
if (firstFlight) {
@ -88,7 +93,7 @@ void FGAIFlightPlan::createPushBack(bool firstFlight, FGAirport *dep,
dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
}
if (gateId < 0) {
createPushBackFallBack(firstFlight, dep, latitude, longitude,
createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
radius, fltType, aircraftType, airline);
return;
@ -223,7 +228,7 @@ void FGAIFlightPlan::createPushBack(bool firstFlight, FGAirport *dep,
* This is the backup function for airports that don't have a
* network yet.
******************************************************************/
void FGAIFlightPlan::createPushBackFallBack(bool firstFlight, FGAirport *dep,
void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep,
double latitude,
double longitude,
double radius,

View file

@ -380,6 +380,10 @@ void FGATCController::transmit(FGTrafficRecord *rec, AtcMsgId msgId, AtcMsgDir m
string text;
string taxiFreqStr;
char buffer[7];
double heading = 0;
string activeRunway;
string fltType;
string rwyClass;
switch (msgId) {
case MSG_ANNOUNCE_ENGINE_START:
text = sender + ". Ready to Start up";
@ -390,9 +394,21 @@ void FGATCController::transmit(FGTrafficRecord *rec, AtcMsgId msgId, AtcMsgDir m
rec->getAircraft()->getTrafficRef()->getFlightRules() + " to " +
rec->getAircraft()->getTrafficRef()->getArrivalAirport()->getName() + ". Request start-up";
break;
// Acknowledge engine startup permission
// Assign departure runway
// Assign SID, if necessery (TODO)
case MSG_PERMIT_ENGINE_START:
taxiFreqStr = formatATCFrequency3_2(taxiFreq);
text = receiver + ". Start-up approved. " + atisInformation + " correct, runway ZZ, AAA departure, squawk BBBB. " +
heading = rec->getAircraft()->getTrafficRef()->getCourse();
fltType = rec->getAircraft()->getTrafficRef()->getFlightType();
rwyClass= rec->getAircraft()->GetFlightPlan()->getRunwayClassFromTrafficType(fltType);
rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, heading);
rec->getAircraft()->GetFlightPlan()->setRunway(activeRunway);
//snprintf(buffer, 7, "%3.2f", heading);
text = receiver + ". Start-up approved. " + atisInformation + " correct, runway " + activeRunway
+ ", AAA departure, squawk BBBB. " +
"For push-back and taxi clearance call " + taxiFreqStr + ". " + sender + " control.";
break;
case MSG_DENY_ENGINE_START:
@ -400,7 +416,9 @@ void FGATCController::transmit(FGTrafficRecord *rec, AtcMsgId msgId, AtcMsgDir m
break;
case MSG_ACKNOWLEDGE_ENGINE_START:
taxiFreqStr = formatATCFrequency3_2(taxiFreq);
text = receiver + ". Start-up approved. " + atisInformation + " correct, runway ZZ, AAA departure, squawk BBBB. " +
activeRunway = rec->getAircraft()->GetFlightPlan()->getRunway();
text = receiver + ". Start-up approved. " + atisInformation + " correct, runway " +
activeRunway + ", AAA departure, squawk BBBB. " +
"For push-back and taxi clearance call " + taxiFreqStr + ". " + sender;
break;
default:

View file

@ -343,7 +343,7 @@ void FGAirportDynamics::setRwyUse(const FGRunwayPreference& ref)
//exit(1);
}
bool FGAirportDynamics::innerGetActiveRunway(const string &trafficType, int action, string &runway)
bool FGAirportDynamics::innerGetActiveRunway(const string &trafficType, int action, string &runway, double heading)
{
double windSpeed;
double windHeading;
@ -452,7 +452,7 @@ double windSpeed;
// Note that the randomization below, is just a placeholder to choose between
// multiple active runways for this action. This should be
// under ATC control.
runway = takeoff[(rand() % nr)];
runway = chooseRwyByHeading (takeoff, heading);
}
else
{ // Fallback
@ -465,7 +465,7 @@ double windSpeed;
int nr = landing.size();
if (nr)
{
runway = landing[(rand() % nr)];
runway = chooseRwyByHeading (landing, heading);
}
else
{ //fallback
@ -476,9 +476,28 @@ double windSpeed;
return true;
}
void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, string &runway)
string FGAirportDynamics::chooseRwyByHeading(stringVec rwys, double heading) {
double bestError = 360.0;
double rwyHeading, headingError;
string runway;
for (stringVecIterator i = rwys.begin(); i != rwys.end(); i++) {
FGRunway *rwy = _ap->getRunwayByIdent((*i));
rwyHeading = rwy->headingDeg();
headingError = fabs(heading - rwyHeading);
if (headingError > 180)
headingError = fabs(headingError - 360);
if (headingError < bestError) {
runway = (*i);
bestError = headingError;
}
}
//cerr << "Using active runway " << runway << " for heading " << heading << endl;
return runway;
}
void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, string &runway, double heading)
{
bool ok = innerGetActiveRunway(trafficType, action, runway);
bool ok = innerGetActiveRunway(trafficType, action, runway, heading);
if (!ok) {
runway = chooseRunwayFallback();
}

View file

@ -67,7 +67,8 @@ private:
string atisInformation;
string chooseRunwayFallback();
bool innerGetActiveRunway(const string &trafficType, int action, string &runway);
bool innerGetActiveRunway(const string &trafficType, int action, string &runway, double heading);
string chooseRwyByHeading(stringVec rwys, double heading);
public:
FGAirportDynamics(FGAirport* ap);
FGAirportDynamics(const FGAirportDynamics &other);
@ -88,7 +89,7 @@ public:
double getElevation() const;
const string& getId() const;
void getActiveRunway(const string& trafficType, int action, string& runway);
void getActiveRunway(const string& trafficType, int action, string& runway, double heading);
void addParking(FGParking& park);
bool getAvailableParking(double *lat, double *lon,

View file

@ -195,7 +195,7 @@ bool FGAISchedule::update(time_t now)
FGAIManager *aimgr;
string airport;
double courseToUser, courseToDest;
double courseToUser;
double distanceToDest;
double speed;

View file

@ -56,7 +56,7 @@ class FGAISchedule
int AIManagerRef;
//int score;
bool firstRun;
double courseToDest;
public:
@ -100,6 +100,7 @@ class FGAISchedule
const string& getRegistration () { return registration;};
const string& getFlightRules () { return (*flights.begin())->getFlightRules (); };
bool getHeavy () { return heavy; };
double getCourse () { return courseToDest; };
FGScheduledFlight*findAvailableFlight (const string &currentDestination, const string &req);
// 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.