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:
parent
80c4bbd1eb
commit
d24fe19914
10 changed files with 142 additions and 83 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -195,7 +195,7 @@ bool FGAISchedule::update(time_t now)
|
|||
FGAIManager *aimgr;
|
||||
string airport;
|
||||
|
||||
double courseToUser, courseToDest;
|
||||
double courseToUser;
|
||||
double distanceToDest;
|
||||
double speed;
|
||||
|
||||
|
|
|
@ -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 ¤tDestination, 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.
|
||||
|
|
Loading…
Add table
Reference in a new issue