#include "AIFlightPlan.hxx"
#include <simgear/math/sg_geodesy.hxx>
+#include <simgear/props/props.hxx>
+#include <simgear/props/props_io.hxx>
+
#include <Airports/runways.hxx>
#include <Airports/dynamics.hxx>
-#include <AIAircraft.hxx>
-#include <performancedata.hxx>
+#include "AIAircraft.hxx"
+#include "performancedata.hxx"
#include <Environment/environment_mgr.hxx>
#include <Environment/environment.hxx>
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);
}
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;
}
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;
}
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;
return wpt;
}
-void FGAIFlightPlan::createDefaultTakeoffTaxi(FGAirport* aAirport, FGRunway* aRunway)
+FGAIFlightPlan::waypoint*
+FGAIFlightPlan::clone(waypoint* aWpt)
+{
+ waypoint* wpt = new waypoint;
+ wpt->name = aWpt->name;
+ wpt->longitude = aWpt->longitude;
+ wpt->latitude = aWpt->latitude;
+
+ wpt->altitude = aWpt->altitude;
+ wpt->speed = aWpt->speed;
+ wpt->crossat = aWpt->crossat;
+ wpt->gear_down = aWpt->gear_down;
+ wpt->flaps_down= aWpt->flaps_down;
+ wpt->finished = aWpt->finished;
+ wpt->on_ground = aWpt->on_ground;
+ wpt->routeIndex = 0;
+
+ return wpt;
+}
+
+
+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, ac->getPerformance()->vTaxi());
waypoints.push_back(wpt);
- wpt = createOnGround("Runway Takeoff", runwayTakeoff, airportElev, 15);
+ wpt = createOnGround(ac, "Runway Takeoff", runwayTakeoff, airportElev, ac->getPerformance()->vTaxi());
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)
}
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;
}
intVecIterator i;
if (taxiRoute->empty()) {
- createDefaultTakeoffTaxi(apt, rwy);
+ createDefaultTakeoffTaxi(ac, apt, rwy);
return;
}
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->getGeod(), apt->getElevation(), ac->getPerformance()->vTaxi());
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, ac->getPerformance()->vTaxi());
waypoints.push_back(wpt);
- wpt = createOnGround("Airport Center", aAirport->geod(), airportElev, 15);
+ wpt = createOnGround(ac, "Airport Center", aAirport->geod(), airportElev, ac->getPerformance()->vTaxi());
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, ac->getPerformance()->vTaxi());
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)
{
// Find a route from runway end to parking/gate.
if (!gn->exists()) {
- createDefaultLandingTaxi(apt);
+ createDefaultLandingTaxi(ac, apt);
return;
}
intVecIterator i;
if (taxiRoute->empty()) {
- createDefaultLandingTaxi(apt);
+ createDefaultLandingTaxi(ac, apt);
return;
}
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->getGeod(), apt->getElevation(), ac->getPerformance()->vTaxi());
wpt->routeIndex = route;
waypoints.push_back(wpt);
}
******************************************************************/
void FGAIFlightPlan::createTakeOff(FGAIAircraft *ac, bool firstFlight, FGAirport *apt, double speed, const string &fltType)
{
- double accel = ac->getPerformance()->acceleration();
- double vRotate = ac->getPerformance()->vRotate();
+ double accel = ac->getPerformance()->acceleration();
+ double vTaxi = ac->getPerformance()->vTaxi();
+ double vRotate = ac->getPerformance()->vRotate();
+// double vTakeoff = ac->getPerformance()->vTakeoff();
+ double vClimb = ac->getPerformance()->vClimb();
// Acceleration = dV / dT
// Acceleration X dT = dV
// dT = dT / Acceleration
//d = (Vf^2 - Vo^2) / (2*a)
- double accelTime = (vRotate - 15) / accel;
+// double accelTime = (vRotate - vTaxi) / accel;
//cerr << "Using " << accelTime << " as total acceleration time" << endl;
- double accelDistance = (vRotate*vRotate - 15*15) / (2*accel);
+ double accelDistance = (vRotate*vRotate - vTaxi*vTaxi) / (2*accel);
//cerr << "Using " << accelDistance << " " << accel << " " << vRotate << endl;
waypoint *wpt;
// Get the current active runway, based on code from David Luff
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);
- waypoints.push_back(wpt);
-
+ wpt = createOnGround(ac, "accel", accelPoint, airportElev, vClimb);
+ 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);
}
* 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;
+// bool planLoaded = false;
+ string fPLName;
+ double vClimb = ac->getPerformance()->vClimb();
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->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->altitude = 18000;
- waypoints.push_back(wpt);
+ if (sid) {
+ for (wpt_vector_iterator i = sid->getFirstWayPoint();
+ i != sid->getLastWayPoint();
+ i++) {
+ waypoints.push_back(clone(*(i)));
+ //cerr << " Cloning waypoint " << endl;
+ }
+ } else {
+ SGGeod climb1 = rwy->pointOnCenterline(10*SG_NM_TO_METER);
+ wpt = createInAir(ac, "10000ft climb", climb1, vClimb, 10000);
+ wpt->gear_down = true;
+ wpt->flaps_down= true;
+ waypoints.push_back(wpt);
+
+ SGGeod climb2 = rwy->pointOnCenterline(20*SG_NM_TO_METER);
+ wpt = cloneWithPos(ac, wpt, "18000ft climb", climb2);
+ wpt->altitude = 18000;
+ waypoints.push_back(wpt);
+ }
}
+
/*******************************************************************
* 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;
+double vDecent = ac->getPerformance()->vDescent();
+ double vApproach = ac->getPerformance()->vApproach();
//Beginning of Decent
//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(), vDecent);
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(), vApproach);
wpt->crossat = 3000;
wpt->gear_down = true;
wpt->flaps_down= true;
* 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
+ double vTouchdown = ac->getPerformance()->vTouchdown();
+ double vTaxi = ac->getPerformance()->vTaxi();
+
waypoint *wpt;
double aptElev = apt->getElevation();
//Runway Threshold
- wpt = createOnGround("Threshold", rwy->threshold(), aptElev, 150);
+ wpt = createOnGround(ac, "Threshold", rwy->threshold(), aptElev, vTouchdown);
wpt->crossat = apt->getElevation();
waypoints.push_back(wpt);
// Roll-out
- wpt = createOnGround("Center", rwy->geod(), aptElev, 30);
+ wpt = createOnGround(ac, "Center", rwy->geod(), aptElev, vTaxi*2);
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, vTaxi);
wpt->crossat = apt->getElevation();
waypoints.push_back(wpt);
}
* 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();
- double lat, lat2;
- double lon, lon2;
- double az2;
- double heading;
+ double lat = 0.0, lat2 = 0.0;
+ double lon = 0.0, lon2 = 0.0;
+ double az2 = 0.0;
+ double heading = 0.0;
+
+ double vTaxi = ac->getPerformance()->vTaxi();
+ double vTaxiReduced = vTaxi * (2.0/3.0);
apt->getDynamics()->getParking(gateId, &lat, &lon, &heading);
heading += 180.0;
if (heading > 360)
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, vTaxiReduced);
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, vTaxiReduced);
waypoints.push_back(wpt);
- wpt = createOnGround("END", SGGeod::fromDeg(lon, lat), aptElev, 10);
+ wpt = createOnGround(ac, "END", SGGeod::fromDeg(lon, lat), aptElev, vTaxiReduced);
waypoints.push_back(wpt);
}