* Improved lead distance & handling of sharp turns
* Takeoff leg respects displaced threshold
This commit is contained in:
parent
d783008c08
commit
cf4801e11c
7 changed files with 109 additions and 68 deletions
|
@ -308,7 +308,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Initialize the flightplan
|
// Initialize the flightplan
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
if (!prev) {
|
if (!prev||repositioned) {
|
||||||
handleFirstWaypoint();
|
handleFirstWaypoint();
|
||||||
return;
|
return;
|
||||||
} // end of initialization
|
} // end of initialization
|
||||||
|
@ -534,10 +534,18 @@ bool FGAIAircraft::loadNextLeg(double distance) {
|
||||||
|
|
||||||
int leg;
|
int leg;
|
||||||
if ((leg = fp->getLeg()) == 9) {
|
if ((leg = fp->getLeg()) == 9) {
|
||||||
|
FGAirport *oldArr = trafficRef->getArrivalAirport();
|
||||||
if (!trafficRef->next()) {
|
if (!trafficRef->next()) {
|
||||||
//FIXME I'm on leg 9 and don't even reach parking.
|
//FIXME I'm on leg 9 and don't even reach parking.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
FGAirport *dep = trafficRef->getDepartureAirport();
|
||||||
|
if (oldArr!=dep) {
|
||||||
|
// as though we are first leg
|
||||||
|
repositioned = true;
|
||||||
|
} else {
|
||||||
|
repositioned = false;
|
||||||
|
}
|
||||||
setCallSign(trafficRef->getCallSign());
|
setCallSign(trafficRef->getCallSign());
|
||||||
leg = 0;
|
leg = 0;
|
||||||
fp->setLeg(leg);
|
fp->setLeg(leg);
|
||||||
|
@ -865,7 +873,7 @@ bool FGAIAircraft::fpExecutable(time_t now) {
|
||||||
bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr, FGAIWaypoint* next, int nextTurnAngle) {
|
bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr, FGAIWaypoint* next, int nextTurnAngle) {
|
||||||
double dist_to_go_m = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
double dist_to_go_m = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
||||||
// Leaddistance should be ft
|
// Leaddistance should be ft
|
||||||
double lead_dist = fp->getLeadDistance();
|
double lead_distance_m = fp->getLeadDistance() * SG_FEET_TO_METER;
|
||||||
const double arrivalDist = fabs(10.0*fp->getCurrentWaypoint()->getSpeed());
|
const double arrivalDist = fabs(10.0*fp->getCurrentWaypoint()->getSpeed());
|
||||||
// arrive at pushback end
|
// arrive at pushback end
|
||||||
if ((dist_to_go_m < arrivalDist) && (speed < 0) && (tgt_speed < 0) && fp->getCurrentWaypoint()->contains("PushBackPoint")) {
|
if ((dist_to_go_m < arrivalDist) && (speed < 0) && (tgt_speed < 0) && fp->getCurrentWaypoint()->contains("PushBackPoint")) {
|
||||||
|
@ -896,9 +904,11 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr, FGAIWaypoint* next, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lead_dist < fabs(2*speed)) {
|
if (lead_distance_m < fabs(2*speed) * SG_FEET_TO_METER) {
|
||||||
//don't skip over the waypoint
|
//don't skip over the waypoint
|
||||||
lead_dist = fabs(2*speed);
|
SG_LOG(SG_AI, SG_BULK, "Set lead_distance_m due to speed " << lead_distance_m << " to " << fabs(2*speed) * SG_FEET_TO_METER);
|
||||||
|
lead_distance_m = fabs(2*speed) * SG_FEET_TO_METER;
|
||||||
|
fp->setLeadDistance(lead_distance_m * SG_METER_TO_FEET);
|
||||||
}
|
}
|
||||||
|
|
||||||
double bearing = 0;
|
double bearing = 0;
|
||||||
|
@ -908,14 +918,12 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr, FGAIWaypoint* next, int
|
||||||
if (next) {
|
if (next) {
|
||||||
nextBearing = getBearing(fp->getBearing(pos, next));
|
nextBearing = getBearing(fp->getBearing(pos, next));
|
||||||
}
|
}
|
||||||
double bearingDiff = fabs(bearing-nextBearing);
|
if (onGround() && fabs(nextTurnAngle) > 50 ) {
|
||||||
if (onGround() && nextTurnAngle > 30 && bearingDiff > 50) {
|
//don't skip over the waypoint
|
||||||
// Next turn is pretty sharp so we do a preturn
|
const int multiplicator = 4;
|
||||||
SG_LOG(SG_AI, SG_BULK, "Leadpoint reached due to excessive heading diff " << bearingDiff);
|
SG_LOG(SG_AI, SG_BULK, "Set lead_distance_m due to next turn angle " << lead_distance_m << " to " << fabs(multiplicator*speed) * SG_FEET_TO_METER << " dist_to_go_m " << dist_to_go_m << " Next turn angle : " << fabs(nextTurnAngle) );
|
||||||
minBearing = 360;
|
lead_distance_m = fabs(multiplicator*speed) * SG_FEET_TO_METER;
|
||||||
speedFraction = 1.0;
|
fp->setLeadDistance(lead_distance_m * SG_METER_TO_FEET);
|
||||||
prev_dist_to_go = HUGE_VAL;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (bearing < minBearing) {
|
if (bearing < minBearing) {
|
||||||
minBearing = bearing;
|
minBearing = bearing;
|
||||||
|
@ -929,9 +937,9 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr, FGAIWaypoint* next, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dist_to_go_m < lead_dist) ||
|
if ((dist_to_go_m < lead_distance_m) ||
|
||||||
((dist_to_go_m > prev_dist_to_go) && (bearing > (minBearing * 1.1))) ) {
|
((dist_to_go_m > prev_dist_to_go) && (bearing > (minBearing * 1.1))) ) {
|
||||||
SG_LOG(SG_AI, SG_BULK, "Leadpoint reached Bearing : " << bearing << "\tNext Bearing : " << nextBearing);
|
SG_LOG(SG_AI, SG_BULK, "Leadpoint reached Bearing : " << bearing << "\tNext Bearing : " << nextBearing << " Next Turn Angle : " << fabs(nextTurnAngle));
|
||||||
minBearing = 360;
|
minBearing = 360;
|
||||||
speedFraction = 1.0;
|
speedFraction = 1.0;
|
||||||
prev_dist_to_go = HUGE_VAL;
|
prev_dist_to_go = HUGE_VAL;
|
||||||
|
@ -1565,13 +1573,15 @@ void FGAIAircraft::dumpCSVHeader(std::ofstream& o) {
|
||||||
o << "WP Lat\t";
|
o << "WP Lat\t";
|
||||||
o << "WP Lon\t";
|
o << "WP Lon\t";
|
||||||
o << "Dist\t";
|
o << "Dist\t";
|
||||||
|
o << "Next Lat\t";
|
||||||
|
o << "Next Lon\t";
|
||||||
o << "Departuretime\t";
|
o << "Departuretime\t";
|
||||||
o << "Time\t";
|
o << "Time\t";
|
||||||
o << "Startup diff\t";
|
o << "Startup diff\t";
|
||||||
o << "dist_to_go_m\t";
|
o << "dist_to_go_m\t";
|
||||||
|
o << "Leaddistance\t";
|
||||||
o << "Leg\t";
|
o << "Leg\t";
|
||||||
o << "Num WP\t";
|
o << "Num WP\t";
|
||||||
o << "Leaddistance\t";
|
|
||||||
o << "no_roll\t";
|
o << "no_roll\t";
|
||||||
o << "roll\t";
|
o << "roll\t";
|
||||||
o << "stuckCounter";
|
o << "stuckCounter";
|
||||||
|
@ -1602,11 +1612,20 @@ void FGAIAircraft::dumpCSV(std::ofstream& o, int lineIndex) {
|
||||||
o << this->getTrueHeadingDeg() << "\t";
|
o << this->getTrueHeadingDeg() << "\t";
|
||||||
FGAIFlightPlan* fp = this->GetFlightPlan();
|
FGAIFlightPlan* fp = this->GetFlightPlan();
|
||||||
FGAIWaypoint* currentWP = this->GetFlightPlan()->getCurrentWaypoint();
|
FGAIWaypoint* currentWP = this->GetFlightPlan()->getCurrentWaypoint();
|
||||||
|
FGAIWaypoint* nextWP = this->GetFlightPlan()->getNextWaypoint();
|
||||||
if (currentWP) {
|
if (currentWP) {
|
||||||
o << this->GetFlightPlan()->getBearing(this->getGeodPos(), this->GetFlightPlan()->getCurrentWaypoint()) << "\t";
|
o << this->GetFlightPlan()->getBearing(this->getGeodPos(), this->GetFlightPlan()->getCurrentWaypoint()) << "\t";
|
||||||
o << currentWP->getName() << "\t";
|
o << currentWP->getName() << "\t";
|
||||||
o << this->GetFlightPlan()->getCurrentWaypoint()->getPos().getLatitudeDeg() << "\t";
|
o << currentWP->getPos().getLatitudeDeg() << "\t";
|
||||||
o << this->GetFlightPlan()->getCurrentWaypoint()->getPos().getLongitudeDeg() << "\t";
|
o << currentWP->getPos().getLongitudeDeg() << "\t";
|
||||||
|
}
|
||||||
|
if (nextWP) {
|
||||||
|
o << nextWP->getPos().getLatitudeDeg() << "\t";
|
||||||
|
o << nextWP->getPos().getLongitudeDeg() << "\t";
|
||||||
|
} else {
|
||||||
|
o << "\t\t";
|
||||||
|
}
|
||||||
|
if (currentWP) {
|
||||||
o << SGGeodesy::distanceM(this->getGeodPos(), currentWP->getPos()) << "\t";
|
o << SGGeodesy::distanceM(this->getGeodPos(), currentWP->getPos()) << "\t";
|
||||||
o << this->GetFlightPlan()->getStartTime() << "\t";
|
o << this->GetFlightPlan()->getStartTime() << "\t";
|
||||||
o << globals->get_time_params()->get_cur_time() << "\t";
|
o << globals->get_time_params()->get_cur_time() << "\t";
|
||||||
|
@ -1617,9 +1636,9 @@ void FGAIAircraft::dumpCSV(std::ofstream& o, int lineIndex) {
|
||||||
o << "No WP\t\t\t\t\t\t\t\t";
|
o << "No WP\t\t\t\t\t\t\t\t";
|
||||||
}
|
}
|
||||||
if (fp->isValidPlan()) {
|
if (fp->isValidPlan()) {
|
||||||
|
o << fp->getLeadDistance() * SG_FEET_TO_METER << "\t";
|
||||||
o << fp->getLeg() << "\t";
|
o << fp->getLeg() << "\t";
|
||||||
o << fp->getNrOfWayPoints() << "\t";
|
o << fp->getNrOfWayPoints() << "\t";
|
||||||
o << fp->getLeadDistance() << "\t";
|
|
||||||
} else {
|
} else {
|
||||||
o << "FP NotValid\t\t";
|
o << "FP NotValid\t\t";
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,6 +176,11 @@ private:
|
||||||
/**Kills a flight when it's stuck */
|
/**Kills a flight when it's stuck */
|
||||||
const int AI_STUCK_LIMIT = 100;
|
const int AI_STUCK_LIMIT = 100;
|
||||||
int stuckCounter;
|
int stuckCounter;
|
||||||
|
/**
|
||||||
|
* Signals a reset to leg 1 at a different airport.
|
||||||
|
* The leg loading happens at a different place than the parking loading.
|
||||||
|
* */
|
||||||
|
bool repositioned;
|
||||||
double prevSpeed;
|
double prevSpeed;
|
||||||
double prev_dist_to_go;
|
double prev_dist_to_go;
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ FGAIFlightPlan::FGAIFlightPlan() :
|
||||||
sid(NULL),
|
sid(NULL),
|
||||||
repeat(false),
|
repeat(false),
|
||||||
distance_to_go(0),
|
distance_to_go(0),
|
||||||
lead_distance(0),
|
lead_distance_ft(0),
|
||||||
leadInAngle(0),
|
leadInAngle(0),
|
||||||
start_time(0),
|
start_time(0),
|
||||||
arrivalTime(0),
|
arrivalTime(0),
|
||||||
|
@ -120,7 +120,7 @@ FGAIFlightPlan::FGAIFlightPlan(const string& filename) :
|
||||||
sid(NULL),
|
sid(NULL),
|
||||||
repeat(false),
|
repeat(false),
|
||||||
distance_to_go(0),
|
distance_to_go(0),
|
||||||
lead_distance(0),
|
lead_distance_ft(0),
|
||||||
leadInAngle(0),
|
leadInAngle(0),
|
||||||
start_time(0),
|
start_time(0),
|
||||||
arrivalTime(0),
|
arrivalTime(0),
|
||||||
|
@ -155,7 +155,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
|
||||||
sid(NULL),
|
sid(NULL),
|
||||||
repeat(false),
|
repeat(false),
|
||||||
distance_to_go(0),
|
distance_to_go(0),
|
||||||
lead_distance(0),
|
lead_distance_ft(0),
|
||||||
leadInAngle(0),
|
leadInAngle(0),
|
||||||
start_time(start),
|
start_time(start),
|
||||||
arrivalTime(0),
|
arrivalTime(0),
|
||||||
|
@ -360,24 +360,7 @@ FGAIWaypoint* FGAIFlightPlan::getNextWaypoint( void ) const
|
||||||
|
|
||||||
int FGAIFlightPlan::getNextTurnAngle( void ) const
|
int FGAIFlightPlan::getNextTurnAngle( void ) const
|
||||||
{
|
{
|
||||||
if (wpt_iterator == waypoints.end())
|
return nextTurnAngle;
|
||||||
return 0;
|
|
||||||
if (wpt_iterator+1 == waypoints.end())
|
|
||||||
return 0;
|
|
||||||
if (wpt_iterator+2 == waypoints.end())
|
|
||||||
return 0;
|
|
||||||
FGAIWaypoint* currentWP = *(wpt_iterator);
|
|
||||||
FGAIWaypoint* nextWP = *(wpt_iterator + 1);
|
|
||||||
FGAIWaypoint* afterNextWP = *(wpt_iterator + 2);
|
|
||||||
int currentBearing = this->getBearing(currentWP, nextWP);
|
|
||||||
int nextBearing = this->getBearing(nextWP, afterNextWP);
|
|
||||||
|
|
||||||
int turnAngle = nextBearing - currentBearing;
|
|
||||||
if (turnAngle>180) {
|
|
||||||
turnAngle -= 180;
|
|
||||||
}
|
|
||||||
|
|
||||||
return turnAngle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -402,6 +385,26 @@ void FGAIFlightPlan::IncrementWaypoint(bool eraseWaypoints )
|
||||||
else {
|
else {
|
||||||
wpt_iterator++;
|
wpt_iterator++;
|
||||||
}
|
}
|
||||||
|
// Calculate the angle of the next turn.
|
||||||
|
if (wpt_iterator == waypoints.end())
|
||||||
|
return;
|
||||||
|
if (wpt_iterator == waypoints.begin())
|
||||||
|
return;
|
||||||
|
if (wpt_iterator+1 == waypoints.end())
|
||||||
|
return;
|
||||||
|
FGAIWaypoint* previousWP = *(wpt_iterator -1);
|
||||||
|
FGAIWaypoint* currentWP = *(wpt_iterator);
|
||||||
|
FGAIWaypoint* nextWP = *(wpt_iterator + 1);
|
||||||
|
int currentBearing = this->getBearing(previousWP, currentWP);
|
||||||
|
int nextBearing = this->getBearing(currentWP, nextWP);
|
||||||
|
|
||||||
|
nextTurnAngle = SGMiscd::normalizePeriodic(-180, 180, nextBearing - currentBearing);
|
||||||
|
if (previousWP->getSpeed()>0&&nextWP->getSpeed()<0 ||
|
||||||
|
previousWP->getSpeed()<0&&nextWP->getSpeed()>0) {
|
||||||
|
nextTurnAngle += 180;
|
||||||
|
SG_LOG(SG_AI, SG_BULK, "Add 180 to turn angle pushback end");
|
||||||
|
}
|
||||||
|
SG_LOG(SG_AI, SG_BULK, "Calculated next turn angle " << nextTurnAngle << " " << previousWP->getName() << " " << currentWP->getName() << " Previous Speed " << previousWP->getSpeed() << " Next Speed " << nextWP->getSpeed());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIFlightPlan::DecrementWaypoint()
|
void FGAIFlightPlan::DecrementWaypoint()
|
||||||
|
@ -438,7 +441,7 @@ void FGAIFlightPlan::setLeadDistance(double speed, double bearing,
|
||||||
// we travel on. Get the turn radius by dividing by PI (*2).
|
// we travel on. Get the turn radius by dividing by PI (*2).
|
||||||
// FIXME Why when going backwards? No fabs
|
// FIXME Why when going backwards? No fabs
|
||||||
if (speed < 0.5) {
|
if (speed < 0.5) {
|
||||||
lead_distance = 0.5;
|
lead_distance_ft = 0.5;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,26 +458,26 @@ void FGAIFlightPlan::setLeadDistance(double speed, double bearing,
|
||||||
//if (leadInAngle < 30.0) // To prevent lead_dist from getting so small it is skipped
|
//if (leadInAngle < 30.0) // To prevent lead_dist from getting so small it is skipped
|
||||||
// leadInAngle = 30.0;
|
// leadInAngle = 30.0;
|
||||||
|
|
||||||
//lead_distance = turn_radius * sin(leadInAngle * SG_DEGREES_TO_RADIANS);
|
//lead_distance_ft = turn_radius * sin(leadInAngle * SG_DEGREES_TO_RADIANS);
|
||||||
lead_distance = turn_radius * tan((leadInAngle * SG_DEGREES_TO_RADIANS)/2);
|
lead_distance_ft = turn_radius * tan((leadInAngle * SG_DEGREES_TO_RADIANS)/2);
|
||||||
if (lead_distance > 1000) {
|
if (lead_distance_ft > 1000) {
|
||||||
SG_LOG(SG_AI, SG_BULK, "Excessive leaddistance possible direction change " << lead_distance << " leadInAngle " << leadInAngle << " inbound " << inbound << " outbound " << outbound);
|
SG_LOG(SG_AI, SG_BULK, "Excessive leaddistance possible direction change " << lead_distance_ft << " leadInAngle " << leadInAngle << " inbound " << inbound << " outbound " << outbound);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if ((lead_distance > (3*turn_radius)) && (current->on_ground == false)) {
|
if ((lead_distance_ft > (3*turn_radius)) && (current->on_ground == false)) {
|
||||||
SG_LOG(SG_AI, SG_ALERT, "Warning: Lead-in distance is large. Inbound = " << inbound
|
SG_LOG(SG_AI, SG_ALERT, "Warning: Lead-in distance is large. Inbound = " << inbound
|
||||||
<< ". Outbound = " << outbound << ". Lead in angle = " << leadInAngle << ". Turn radius = " << turn_radius);
|
<< ". Outbound = " << outbound << ". Lead in angle = " << leadInAngle << ". Turn radius = " << turn_radius);
|
||||||
lead_distance = 3 * turn_radius;
|
lead_distance_ft = 3 * turn_radius;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((leadInAngle > 90) && (current->on_ground == true)) {
|
if ((leadInAngle > 90) && (current->on_ground == true)) {
|
||||||
lead_distance = turn_radius * tan((90 * SG_DEGREES_TO_RADIANS)/2);
|
lead_distance_ft = turn_radius * tan((90 * SG_DEGREES_TO_RADIANS)/2);
|
||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIFlightPlan::setLeadDistance(double distance_ft){
|
void FGAIFlightPlan::setLeadDistance(double distance_ft){
|
||||||
lead_distance = distance_ft;
|
lead_distance_ft = distance_ft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ public:
|
||||||
|
|
||||||
void setLeadDistance(double speed, double bearing, FGAIWaypoint* current, FGAIWaypoint* next);
|
void setLeadDistance(double speed, double bearing, FGAIWaypoint* current, FGAIWaypoint* next);
|
||||||
void setLeadDistance(double distance_ft);
|
void setLeadDistance(double distance_ft);
|
||||||
double getLeadDistance( void ) const {return lead_distance;}
|
double getLeadDistance( void ) const {return lead_distance_ft;}
|
||||||
double getBearing(FGAIWaypoint* previous, FGAIWaypoint* next) const;
|
double getBearing(FGAIWaypoint* previous, FGAIWaypoint* next) const;
|
||||||
double getBearing(const SGGeod& aPos, FGAIWaypoint* next) const;
|
double getBearing(const SGGeod& aPos, FGAIWaypoint* next) const;
|
||||||
|
|
||||||
|
@ -246,12 +246,14 @@ private:
|
||||||
wpt_vector_iterator wpt_iterator;
|
wpt_vector_iterator wpt_iterator;
|
||||||
|
|
||||||
bool repeat;
|
bool repeat;
|
||||||
double distance_to_go;
|
double distance_to_go = 0;
|
||||||
double lead_distance;
|
//FIXME ft
|
||||||
double leadInAngle;
|
double lead_distance_ft = 0;
|
||||||
|
double leadInAngle = 0;
|
||||||
|
double nextTurnAngle = 0;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
time_t arrivalTime; // For AI/ATC purposes.
|
time_t arrivalTime; // For AI/ATC purposes.
|
||||||
int leg;
|
int leg = 0;
|
||||||
ParkingAssignment gate;
|
ParkingAssignment gate;
|
||||||
FGTaxiNodeRef lastNodeVisited;
|
FGTaxiNodeRef lastNodeVisited;
|
||||||
std::string activeRunway;
|
std::string activeRunway;
|
||||||
|
|
|
@ -69,11 +69,11 @@ bool FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep,
|
||||||
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() << " 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() << " 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;
|
||||||
int currWpt = wpt_iterator - waypoints.begin();
|
int currWpt = wpt_iterator - waypoints.begin();
|
||||||
|
@ -281,7 +281,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
||||||
FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
|
FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
|
||||||
SG_LOG(SG_AI, SG_BULK, "Taxi to " << apt->getId() << "/" << activeRunway);
|
SG_LOG(SG_AI, SG_BULK, "Taxi to " << apt->getId() << "/" << activeRunway);
|
||||||
assert( rwy != NULL );
|
assert( rwy != NULL );
|
||||||
SGGeod runwayTakeoff = rwy->pointOnCenterline(5.0);
|
SGGeod runwayTakeoff = rwy->pointOnCenterlineDisplaced(5.0);
|
||||||
|
|
||||||
FGGroundNetwork *gn = apt->groundNetwork();
|
FGGroundNetwork *gn = apt->groundNetwork();
|
||||||
if (!gn->exists()) {
|
if (!gn->exists()) {
|
||||||
|
@ -389,7 +389,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
}
|
}
|
||||||
// Acceleration point, 105 meters into the runway,
|
// Acceleration point, 105 meters into the runway,
|
||||||
SGGeod accelPoint = rwy->pointOnCenterline(105.0);
|
SGGeod accelPoint = rwy->pointOnCenterlineDisplaced(105.0);
|
||||||
FGAIWaypoint *wpt = createOnRunway(ac, "Accel", accelPoint, apt->getElevation(), ac->getPerformance()->vRotate());
|
FGAIWaypoint *wpt = createOnRunway(ac, "Accel", accelPoint, apt->getElevation(), ac->getPerformance()->vRotate());
|
||||||
wpt->setFlaps(0.5f);
|
wpt->setFlaps(0.5f);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
@ -468,8 +468,8 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
|
||||||
// int route;
|
// int route;
|
||||||
for (int i = 0; i < size - 2; i++) {
|
for (int i = 0; i < size - 2; i++) {
|
||||||
taxiRoute.next(node, &route);
|
taxiRoute.next(node, &route);
|
||||||
char buffer[16];
|
char buffer[20];
|
||||||
snprintf(buffer, 16, "landingtaxi-%d", node->getIndex());
|
snprintf(buffer, 20, "landingtaxi-%d-%d", node->getIndex(), i);
|
||||||
FGAIWaypoint *wpt =
|
FGAIWaypoint *wpt =
|
||||||
createOnGround(ac, buffer, node->geod(), apt->getElevation(),
|
createOnGround(ac, buffer, node->geod(), apt->getElevation(),
|
||||||
ac->getPerformance()->vTaxi());
|
ac->getPerformance()->vTaxi());
|
||||||
|
@ -560,14 +560,14 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
||||||
|
|
||||||
// distance from the runway threshold to accelerate to rotation speed.
|
// distance from the runway threshold to accelerate to rotation speed.
|
||||||
double d = accelDistance(vTaxiMetric, vRotateMetric, accelMetric) + ACCEL_POINT;
|
double d = accelDistance(vTaxiMetric, vRotateMetric, accelMetric) + ACCEL_POINT;
|
||||||
SGGeod rotatePoint = rwy->pointOnCenterline(d);
|
SGGeod rotatePoint = rwy->pointOnCenterlineDisplaced(d);
|
||||||
wpt = createOnRunway(ac, "rotate", rotatePoint, airportElev, vRotate);
|
wpt = createOnRunway(ac, "rotate", rotatePoint, airportElev, vRotate);
|
||||||
wpt->setFlaps(0.5f);
|
wpt->setFlaps(0.5f);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
// After rotation, we still need to accelerate to the take-off speed.
|
// After rotation, we still need to accelerate to the take-off speed.
|
||||||
double t = d + accelDistance(vRotateMetric, vTakeoffMetric, accelMetric);
|
double t = d + accelDistance(vRotateMetric, vTakeoffMetric, accelMetric);
|
||||||
SGGeod takeoffPoint = rwy->pointOnCenterline(t);
|
SGGeod takeoffPoint = rwy->pointOnCenterlineDisplaced(t);
|
||||||
wpt = createOnRunway(ac, "takeoff", takeoffPoint, airportElev, vTakeoff);
|
wpt = createOnRunway(ac, "takeoff", takeoffPoint, airportElev, vTakeoff);
|
||||||
wpt->setGear_down(true);
|
wpt->setGear_down(true);
|
||||||
wpt->setFlaps(0.5f);
|
wpt->setFlaps(0.5f);
|
||||||
|
@ -580,7 +580,7 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
||||||
// 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->pointOnCenterline(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);
|
||||||
|
@ -592,12 +592,12 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
||||||
// 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'
|
||||||
double climbOut = t + 2*vClimbBelow10000*SG_FEET_TO_METER + pitchDistance(INITIAL_PITCH_ANGLE, 2000 * SG_FEET_TO_METER);
|
double climbOut = t + 2*vClimbBelow10000*SG_FEET_TO_METER + pitchDistance(INITIAL_PITCH_ANGLE, 2000 * SG_FEET_TO_METER);
|
||||||
SGGeod climbOutPoint = rwy->pointOnCenterline(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->pointOnCenterline(climbOut);
|
SGGeod climbOutPoint2 = rwy->pointOnCenterlineDisplaced(climbOut);
|
||||||
wpt = createInAir(ac, "2500'", climbOutPoint2, airportElev + 2500, vClimbBelow10000);
|
wpt = createInAir(ac, "2500'", climbOutPoint2, airportElev + 2500, vClimbBelow10000);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,11 @@ SGGeod FGRunway::threshold() const
|
||||||
return pointOnCenterline(_displ_thresh);
|
return pointOnCenterline(_displ_thresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SGGeod FGRunway::pointOnCenterlineDisplaced(double aOffset) const
|
||||||
|
{
|
||||||
|
return pointOnCenterline(_displ_thresh+aOffset);
|
||||||
|
}
|
||||||
|
|
||||||
void FGRunway::setReciprocalRunway(PositionedID other)
|
void FGRunway::setReciprocalRunway(PositionedID other)
|
||||||
{
|
{
|
||||||
assert(_reciprocal == 0);
|
assert(_reciprocal == 0);
|
||||||
|
|
|
@ -73,6 +73,13 @@ public:
|
||||||
*/
|
*/
|
||||||
SGGeod threshold() const;
|
SGGeod threshold() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a position on the extended centerline. Positive values
|
||||||
|
* are in the direction of the runway heading, negative values are in the
|
||||||
|
* opposited direction. 0.0 corresponds to the possibly threshold
|
||||||
|
*/
|
||||||
|
SGGeod pointOnCenterlineDisplaced(double aOffset) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the 'far' end - this is equivalent to calling
|
* Get the 'far' end - this is equivalent to calling
|
||||||
* pointOnCenterline(lengthFt());
|
* pointOnCenterline(lengthFt());
|
||||||
|
|
Loading…
Reference in a new issue