AI Fixes
* Better runway exit * Bug in approach * Test east/west approach downwind
This commit is contained in:
parent
20fc979a52
commit
78797e28aa
7 changed files with 289 additions and 139 deletions
src
AIModel
Airports
Traffic
test_suite/unit_tests/AI
|
@ -348,13 +348,15 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
|
||||||
setDie(true);
|
setDie(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
fp->IncrementWaypoint(false);
|
||||||
|
fp->IncrementWaypoint(false);
|
||||||
prev = fp->getPreviousWaypoint();
|
prev = fp->getPreviousWaypoint();
|
||||||
SG_LOG(SG_AI, SG_BULK, getCallSign() << "|Previous WP \t" << prev->getName());
|
SG_LOG(SG_AI, SG_BULK, getCallSign() << "|EndofCruise Previous WP \t" << prev->getName());
|
||||||
curr = fp->getCurrentWaypoint();
|
curr = fp->getCurrentWaypoint();
|
||||||
SG_LOG(SG_AI, SG_BULK, getCallSign() << "|Current WP \t" << curr->getName());
|
SG_LOG(SG_AI, SG_BULK, getCallSign() << "|EndofCruise Current WP \t" << curr->getName());
|
||||||
next = fp->getNextWaypoint();
|
next = fp->getNextWaypoint();
|
||||||
if( next ) {
|
if( next ) {
|
||||||
SG_LOG(SG_AI, SG_BULK, getCallSign() << "|Next WP \t" << next->getName());
|
SG_LOG(SG_AI, SG_BULK, getCallSign() << "|EndofCruise Next WP \t" << next->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!curr) {
|
if (!curr) {
|
||||||
|
@ -606,7 +608,7 @@ bool FGAIAircraft::loadNextLeg(double distance) {
|
||||||
|
|
||||||
int nextLeg = determineNextLeg(leg);
|
int nextLeg = determineNextLeg(leg);
|
||||||
|
|
||||||
SG_LOG(SG_AI, SG_BULK, getCallSign() << "|Loading Leg " << nextLeg);
|
SG_LOG(SG_AI, SG_BULK, getCallSign() << "|Loading Leg:" << leg << " Next: " << nextLeg);
|
||||||
bool ok = fp->create (this,
|
bool ok = fp->create (this,
|
||||||
dep,
|
dep,
|
||||||
arr,
|
arr,
|
||||||
|
@ -879,7 +881,7 @@ void FGAIAircraft::handleFirstWaypoint() {
|
||||||
// Make sure lead distance is initialized otherwise
|
// Make sure lead distance is initialized otherwise
|
||||||
// If we are ending in a parking
|
// If we are ending in a parking
|
||||||
if (next && !curr->contains("END") && !curr->contains("PushBackPointlegend")) {
|
if (next && !curr->contains("END") && !curr->contains("PushBackPointlegend")) {
|
||||||
fp->setLeadDistance(speed, hdg, curr, next);
|
fp->setLeadDistance(tgt_speed, hdg, curr, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate
|
if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate
|
||||||
|
@ -1147,7 +1149,11 @@ void FGAIAircraft::controlSpeed(FGAIWaypoint* curr, FGAIWaypoint* next) {
|
||||||
prevSpeed = speed;
|
prevSpeed = speed;
|
||||||
if (next) {
|
if (next) {
|
||||||
if (!curr->contains("END") && !curr->contains("PushBackPointlegend")) {
|
if (!curr->contains("END") && !curr->contains("PushBackPointlegend")) {
|
||||||
fp->setLeadDistance(speed, tgt_heading, curr, next);
|
if (speed_diff > 0 && tgt_speed >= 5) {
|
||||||
|
fp->setLeadDistance(speed, tgt_heading, curr, next);
|
||||||
|
} else {
|
||||||
|
fp->setLeadDistance(tgt_speed, tgt_heading, curr, next);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -434,8 +434,10 @@ double FGAIFlightPlan::getDistanceToGo(double lat, double lon, FGAIWaypoint* wp)
|
||||||
return SGGeodesy::distanceM(SGGeod::fromDeg(lon, lat), wp->getPos());
|
return SGGeodesy::distanceM(SGGeod::fromDeg(lon, lat), wp->getPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets distance in feet from a lead point to the current waypoint
|
/**
|
||||||
// basically a catch radius, that triggers the advancement of WPs
|
sets distance in feet from a lead point to the current waypoint
|
||||||
|
basically a catch radius, that triggers the advancement of WPs
|
||||||
|
*/
|
||||||
void FGAIFlightPlan::setLeadDistance(double speed,
|
void FGAIFlightPlan::setLeadDistance(double speed,
|
||||||
double bearing,
|
double bearing,
|
||||||
FGAIWaypoint* current,
|
FGAIWaypoint* current,
|
||||||
|
@ -447,11 +449,11 @@ void FGAIFlightPlan::setLeadDistance(double speed,
|
||||||
// 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_ft = 0.5;
|
setLeadDistance(0.5);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (speed > 0 && speed < 0.5) {
|
if (speed > 0 && speed < 0.5) {
|
||||||
lead_distance_ft = 5 * SG_FEET_TO_METER;
|
setLeadDistance(5 * SG_METER_TO_FEET);
|
||||||
SG_LOG(SG_AI, SG_BULK, "Setting Leaddistance fixed " << (lead_distance_ft*SG_FEET_TO_METER));
|
SG_LOG(SG_AI, SG_BULK, "Setting Leaddistance fixed " << (lead_distance_ft*SG_FEET_TO_METER));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -473,11 +475,14 @@ void FGAIFlightPlan::setLeadDistance(double speed,
|
||||||
//lead_distance_ft = turn_radius * sin(leadInAngle * SG_DEGREES_TO_RADIANS);
|
//lead_distance_ft = turn_radius * sin(leadInAngle * SG_DEGREES_TO_RADIANS);
|
||||||
|
|
||||||
if ((int)leadInAngle==0) {
|
if ((int)leadInAngle==0) {
|
||||||
double lead_distance_m = fabs(2*speed) * SG_FEET_TO_METER;
|
double lead_distance_m = fabs(2*speed) * SG_FEET_TO_METER;
|
||||||
setLeadDistance(lead_distance_m * SG_METER_TO_FEET);
|
setLeadDistance(lead_distance_m * SG_METER_TO_FEET);
|
||||||
|
if (lead_distance_ft > 1000) {
|
||||||
|
SG_LOG(SG_AI, SG_BULK, "Excessive leaddistance leadin 0 " << lead_distance_ft << " leadInAngle " << leadInAngle << " inbound " << inbound << " outbound " << outbound);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
double lead_distance_m = turn_radius_m * tan((leadInAngle * SG_DEGREES_TO_RADIANS)/2);
|
double lead_distance_m = turn_radius_m * tan((leadInAngle * SG_DEGREES_TO_RADIANS)/2);
|
||||||
lead_distance_ft = lead_distance_m * SG_METER_TO_FEET;
|
setLeadDistance(lead_distance_m * SG_METER_TO_FEET);
|
||||||
SG_LOG(SG_AI, SG_BULK, "Setting Leaddistance " << (lead_distance_ft*SG_FEET_TO_METER) << " Turnradius " << turn_radius_m << " Speed " << speed_mps << " Half turn Angle " << (leadInAngle)/2);
|
SG_LOG(SG_AI, SG_BULK, "Setting Leaddistance " << (lead_distance_ft*SG_FEET_TO_METER) << " Turnradius " << turn_radius_m << " Speed " << speed_mps << " Half turn Angle " << (leadInAngle)/2);
|
||||||
if (lead_distance_ft > 1000) {
|
if (lead_distance_ft > 1000) {
|
||||||
SG_LOG(SG_AI, SG_BULK, "Excessive leaddistance possible direction change " << lead_distance_ft << " 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);
|
||||||
|
@ -499,6 +504,9 @@ void FGAIFlightPlan::setLeadDistance(double speed,
|
||||||
|
|
||||||
void FGAIFlightPlan::setLeadDistance(double distance_ft){
|
void FGAIFlightPlan::setLeadDistance(double distance_ft){
|
||||||
lead_distance_ft = distance_ft;
|
lead_distance_ft = distance_ft;
|
||||||
|
if (lead_distance_ft>10000) {
|
||||||
|
SG_LOG(SG_AI, SG_DEBUG, "Excessive Leaddistance " << distance_ft);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -870,28 +870,11 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac,
|
||||||
createArc(ac, firstTurnCenter, ac->_getHeading()-rightAngle, heading-rightAngle, firstTurnIncrement, initialTurnRadius, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "near-initialturn%03d");
|
createArc(ac, firstTurnCenter, ac->_getHeading()-rightAngle, heading-rightAngle, firstTurnIncrement, initialTurnRadius, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "near-initialturn%03d");
|
||||||
double length = VectorMath::innerTangentsLength(firstTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius );
|
double length = VectorMath::innerTangentsLength(firstTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius );
|
||||||
createLine(ac, waypoints.back()->getPos(), heading, length, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/2, vDescent, "descent%03d");
|
createLine(ac, waypoints.back()->getPos(), heading, length, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/2, vDescent, "descent%03d");
|
||||||
int holdsPatterns = 0;
|
int startVal = SGMiscd::normalizePeriodic(0, 360, heading-rightAngle);
|
||||||
// Length of
|
int endVal = SGMiscd::normalizePeriodic(0, 360, rwy->headingDeg()-rightAngle);
|
||||||
if (holdsPatterns>0) {
|
// Turn into runway
|
||||||
// Turn into hold
|
createArc(ac, secondaryTarget, startVal ,endVal , firstTurnIncrement, initialTurnRadius,
|
||||||
createArc(ac, secondaryTarget, heading+rightAngle, rwy->headingDeg()+rightAngle, firstTurnIncrement*-1, initialTurnRadius,
|
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "turn%03d");
|
||||||
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "turnintohold%03d");
|
|
||||||
for (int t = 0; t < holdsPatterns; t++)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
createArc(ac, secondaryTarget, endval, endval+180, increment, initialTurnRadius,
|
|
||||||
currentAltitude, vDescent, "hold_1_%03d");
|
|
||||||
createArc(ac, secondHoldCenter, endval+180, endval, increment, initialTurnRadius,
|
|
||||||
currentAltitude, vDescent, "hold_2_%03d");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int startVal = SGMiscd::normalizePeriodic(0, 360, heading-rightAngle);
|
|
||||||
int endVal = SGMiscd::normalizePeriodic(0, 360, rwy->headingDeg()-rightAngle);
|
|
||||||
// Turn into runway
|
|
||||||
createArc(ac, secondaryTarget, startVal ,endVal , firstTurnIncrement, initialTurnRadius,
|
|
||||||
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "turn%03d");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_AI, SG_BULK, ac->getCallSign() << "| Enter far S curve");
|
SG_LOG(SG_AI, SG_BULK, ac->getCallSign() << "| Enter far S curve");
|
||||||
// Entering not "straight" into runway so we do a s-curve
|
// Entering not "straight" into runway so we do a s-curve
|
||||||
|
@ -907,28 +890,11 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac,
|
||||||
createArc(ac, firstTurnCenter, ac->_getHeading()-rightAngle, heading-rightAngle, firstTurnIncrement, initialTurnRadius, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/8, vDescent, "far-initialturn%03d");
|
createArc(ac, firstTurnCenter, ac->_getHeading()-rightAngle, heading-rightAngle, firstTurnIncrement, initialTurnRadius, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/8, vDescent, "far-initialturn%03d");
|
||||||
double length = VectorMath::innerTangentsLength(firstTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius );
|
double length = VectorMath::innerTangentsLength(firstTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius );
|
||||||
createLine(ac, waypoints.back()->getPos(), heading, length, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff*0.75, vDescent, "descent%03d");
|
createLine(ac, waypoints.back()->getPos(), heading, length, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff*0.75, vDescent, "descent%03d");
|
||||||
int holdsPatterns = 0;
|
int startVal = SGMiscd::normalizePeriodic(0, 360, heading+rightAngle);
|
||||||
// Length of
|
int endVal = SGMiscd::normalizePeriodic(0, 360, rwy->headingDeg()+rightAngle);
|
||||||
if (holdsPatterns>0) {
|
// Turn into runway
|
||||||
// Turn into hold
|
createArc(ac, secondaryTarget, startVal, endVal, firstTurnIncrement*-1, initialTurnRadius,
|
||||||
createArc(ac, secondaryTarget, heading+rightAngle, rwy->headingDeg()+rightAngle, firstTurnIncrement*-1, initialTurnRadius,
|
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/8, vDescent, "s-turn%03d");
|
||||||
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "turnintohold%03d");
|
|
||||||
for (int t = 0; t < holdsPatterns; t++)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
createArc(ac, secondaryTarget, endval, endval+180, increment, initialTurnRadius,
|
|
||||||
currentAltitude, vDescent, "hold_1_%03d");
|
|
||||||
createArc(ac, secondHoldCenter, endval+180, endval, increment, initialTurnRadius,
|
|
||||||
currentAltitude, vDescent, "hold_2_%03d");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int startVal = SGMiscd::normalizePeriodic(0, 360, heading+rightAngle);
|
|
||||||
int endVal = SGMiscd::normalizePeriodic(0, 360, rwy->headingDeg()+rightAngle);
|
|
||||||
// Turn into runway
|
|
||||||
createArc(ac, secondaryTarget, startVal, endVal, firstTurnIncrement*-1, initialTurnRadius,
|
|
||||||
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/8, vDescent, "s-turn%03d");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (fabs(headingDiffRunway)>=150 ) {
|
} else if (fabs(headingDiffRunway)>=150 ) {
|
||||||
// We are entering downwind
|
// We are entering downwind
|
||||||
|
@ -955,62 +921,27 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac,
|
||||||
createArc(ac, secondTurnCenter, endVal, endVal2+rightAngle, -firstTurnIncrement, initialTurnRadius, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "secondturn%03d");
|
createArc(ac, secondTurnCenter, endVal, endVal2+rightAngle, -firstTurnIncrement, initialTurnRadius, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "secondturn%03d");
|
||||||
//outer
|
//outer
|
||||||
double length = VectorMath::outerTangentsLength(secondTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius );
|
double length = VectorMath::outerTangentsLength(secondTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius );
|
||||||
int reverseRwyHeading = SGMiscd::normalizePeriodic(0, 360, rwy->headingDeg() - 180);
|
|
||||||
createLine(ac, waypoints.back()->getPos(), endVal2, length, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "descent%03d");
|
createLine(ac, waypoints.back()->getPos(), endVal2, length, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "descent%03d");
|
||||||
int holdsPatterns = 0;
|
endVal = SGMiscd::normalizePeriodic(0, 360, rwy->headingDeg()+rightAngle);
|
||||||
// Length of
|
// Turn into runway
|
||||||
if (holdsPatterns>0) {
|
createArc(ac, secondaryTarget, endVal2+rightAngle, endVal, -firstTurnIncrement, initialTurnRadius,
|
||||||
// Turn into hold
|
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "turn%03d");
|
||||||
createArc(ac, secondaryTarget, heading+rightAngle, rwy->headingDeg()+rightAngle, firstTurnIncrement*-1, initialTurnRadius,
|
|
||||||
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "turnintohold%03d");
|
|
||||||
for (int t = 0; t < holdsPatterns; t++)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
createArc(ac, secondaryTarget, endval, endval+180, increment, initialTurnRadius,
|
|
||||||
currentAltitude, vDescent, "hold_1_%03d");
|
|
||||||
createArc(ac, secondHoldCenter, endval+180, endval, increment, initialTurnRadius,
|
|
||||||
currentAltitude, vDescent, "hold_2_%03d");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int endVal = SGMiscd::normalizePeriodic(0, 360, rwy->headingDeg()+rightAngle);
|
|
||||||
// Turn into runway
|
|
||||||
createArc(ac, secondaryTarget, endVal2+rightAngle, endVal, -firstTurnIncrement, initialTurnRadius,
|
|
||||||
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/4, vDescent, "turn%03d");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_AI, SG_BULK, ac->getCallSign() << "| Enter far S downrunway");
|
SG_LOG(SG_AI, SG_BULK, ac->getCallSign() << "| Enter far S downrunway");
|
||||||
// Entering not "straight" into runway so we do a s-curve
|
// Entering not "straight" into runway so we do a s-curve
|
||||||
int rightAngle = azimuth<0?90:-90;
|
int rightAngle = headingDiffRunway>0?90:-90;
|
||||||
int firstTurnIncrement = azimuth<0?2:-2;
|
int firstTurnIncrement = headingDiffRunway>0?2:-2;
|
||||||
int innerTangent = headingDiffRunway<0?0:1;
|
int innerTangent = headingDiffRunway<0?0:1;
|
||||||
SGGeod firstTurnCenter = SGGeodesy::direct(current, ac->getTrueHeadingDeg() + rightAngle, initialTurnRadius);
|
SGGeod firstTurnCenter = SGGeodesy::direct(current, ac->getTrueHeadingDeg() + rightAngle, initialTurnRadius);
|
||||||
const double heading = VectorMath::innerTangentsAngle(firstTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius )[innerTangent];
|
const double heading = VectorMath::innerTangentsAngle(firstTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius )[innerTangent];
|
||||||
createArc(ac, firstTurnCenter, ac->_getHeading()-rightAngle, heading-rightAngle, firstTurnIncrement, initialTurnRadius, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "d-far-initialturn%03d");
|
createArc(ac, firstTurnCenter, ac->_getHeading()-rightAngle, heading-rightAngle, firstTurnIncrement, initialTurnRadius, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "d-far-initialturn%03d");
|
||||||
double length = VectorMath::innerTangentsLength(firstTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius );
|
double length = VectorMath::innerTangentsLength(firstTurnCenter, secondaryTarget, initialTurnRadius, initialTurnRadius );
|
||||||
createLine(ac, waypoints.back()->getPos(), heading, length, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "descent%03d");
|
createLine(ac, waypoints.back()->getPos(), heading, length, waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "descent%03d");
|
||||||
int holdsPatterns = 0;
|
int startVal = SGMiscd::normalizePeriodic(0, 360, heading+rightAngle);
|
||||||
// Length of
|
int endVal = SGMiscd::normalizePeriodic(0, 360, rwy->headingDeg()+rightAngle);
|
||||||
if (holdsPatterns>0) {
|
// Turn into runway
|
||||||
// Turn into hold
|
createArc(ac, secondaryTarget, startVal, endVal, -firstTurnIncrement, initialTurnRadius,
|
||||||
createArc(ac, secondaryTarget, heading+rightAngle, rwy->headingDeg()+rightAngle, firstTurnIncrement*-1, initialTurnRadius,
|
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "d-s-turn%03d");
|
||||||
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "turnintohold%03d");
|
|
||||||
for (int t = 0; t < holdsPatterns; t++)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
createArc(ac, secondaryTarget, endval, endval+180, increment, initialTurnRadius,
|
|
||||||
currentAltitude, vDescent, "hold_1_%03d");
|
|
||||||
createArc(ac, secondHoldCenter, endval+180, endval, increment, initialTurnRadius,
|
|
||||||
currentAltitude, vDescent, "hold_2_%03d");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int startVal = SGMiscd::normalizePeriodic(0, 360, heading+rightAngle);
|
|
||||||
int endVal = SGMiscd::normalizePeriodic(0, 360, rwy->headingDeg()+rightAngle);
|
|
||||||
// Turn into runway
|
|
||||||
createArc(ac, secondaryTarget, startVal, endVal, -firstTurnIncrement, initialTurnRadius,
|
|
||||||
waypoints.size()>0?waypoints.back()->getAltitude():alt, altDiff/3, vDescent, "d-s-turn%03d");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_AI, SG_BULK, ac->getCallSign() << "| Enter far straight");
|
SG_LOG(SG_AI, SG_BULK, ac->getCallSign() << "| Enter far straight");
|
||||||
|
@ -1019,7 +950,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac,
|
||||||
SGGeod firstTurnCenter = SGGeodesy::direct(current, ac->getTrueHeadingDeg() - rightAngle, initialTurnRadius);
|
SGGeod firstTurnCenter = SGGeodesy::direct(current, ac->getTrueHeadingDeg() - rightAngle, initialTurnRadius);
|
||||||
int firstTurnIncrement = headingDiffRunway>0?-2:2;
|
int firstTurnIncrement = headingDiffRunway>0?-2:2;
|
||||||
const double heading = rwy->headingDeg();
|
const double heading = rwy->headingDeg();
|
||||||
createArc(ac, secondaryTarget, ac->_getHeading()+rightAngle, heading+rightAngle, firstTurnIncrement, initialTurnRadius, ac->getAltitude(), altDiff/3, vDescent, "straight_turn_%03d");
|
createArc(ac, firstTurnCenter, ac->_getHeading()+rightAngle, heading+rightAngle, firstTurnIncrement, initialTurnRadius, ac->getAltitude(), altDiff/3, vDescent, "straight_turn_%03d");
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t now = globals->get_time_params()->get_cur_time();
|
time_t now = globals->get_time_params()->get_cur_time();
|
||||||
|
@ -1174,10 +1105,10 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
wpt->setSpeedBrakes(1.0f);
|
wpt->setSpeedBrakes(1.0f);
|
||||||
pushBackWaypoint(wpt);
|
pushBackWaypoint(wpt);
|
||||||
|
|
||||||
SG_LOG(SG_AI, SG_BULK, "Landing " << glideslopeEntry << "\t" << decelPoint);
|
|
||||||
|
|
||||||
double rolloutDistance = accelDistance(vTouchdownMetric, vTaxiMetric, decelMetric);
|
double rolloutDistance = accelDistance(vTouchdownMetric, vTaxiMetric, decelMetric);
|
||||||
|
|
||||||
|
SG_LOG(SG_AI, SG_BULK, "Landing " << glideslopeEntry << "\t" << decelPoint << " Rollout " << rolloutDistance);
|
||||||
|
|
||||||
int nPoints = (int)(rolloutDistance/60);
|
int nPoints = (int)(rolloutDistance/60);
|
||||||
for (int i = 1; i <= nPoints; i++) {
|
for (int i = 1; i <= nPoints; i++) {
|
||||||
snprintf(buffer, sizeof(buffer), "rollout%03d", i);
|
snprintf(buffer, sizeof(buffer), "rollout%03d", i);
|
||||||
|
|
|
@ -299,42 +299,49 @@ FGTaxiNodeRef FGGroundNetwork::findNearestNodeOnRunwayExit(const SGGeod & aGeod,
|
||||||
SGVec3d cartPos = SGVec3d::fromGeod(aGeod);
|
SGVec3d cartPos = SGVec3d::fromGeod(aGeod);
|
||||||
FGTaxiNodeRef result = 0;
|
FGTaxiNodeRef result = 0;
|
||||||
FGTaxiNodeVector::const_iterator it;
|
FGTaxiNodeVector::const_iterator it;
|
||||||
for (it = m_nodes.begin(); it != m_nodes.end(); ++it) {
|
if (aRunway) {
|
||||||
if (!(*it)->getIsOnRunway())
|
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit " << aRunway->ident() << " " << aRunway->headingDeg() );
|
||||||
continue;
|
for (it = m_nodes.begin(); it != m_nodes.end(); ++it) {
|
||||||
double localDistanceSqr = distSqr(cartPos, (*it)->cart());
|
if (!(*it)->getIsOnRunway())
|
||||||
if (aRunway) {
|
continue;
|
||||||
|
double localDistanceSqr = distSqr(cartPos, (*it)->cart());
|
||||||
double headingTowardsExit = SGGeodesy::courseDeg(aGeod, (*it)->geod());
|
double headingTowardsExit = SGGeodesy::courseDeg(aGeod, (*it)->geod());
|
||||||
double diff = fabs(aRunway->headingDeg() - headingTowardsExit);
|
double diff = fabs(SGMiscd::normalizePeriodic(-180, 180, aRunway->headingDeg() - headingTowardsExit));
|
||||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit " << aRunway->headingDeg() << " "
|
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit Diff : " << diff << " Id : " << (*it)->getIndex());
|
||||||
<< " Diff : " << diff << " " << (*it)->getIndex());
|
|
||||||
if (diff > 10) {
|
if (diff > 10) {
|
||||||
// Only ahead
|
// Only ahead
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
FGTaxiNodeVector exitSegments = findSegmentsFrom((*it));
|
FGTaxiNodeVector exitSegments = findSegmentsFrom((*it));
|
||||||
// Only ends
|
// Some kind of star
|
||||||
if (exitSegments.size() != 1) {
|
if (exitSegments.size() > 2 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// two segments and next points are on runway, too. Must be a segment before end
|
||||||
|
// single runway point not at end is ok
|
||||||
|
if (exitSegments.size() == 2 &&
|
||||||
|
((*exitSegments.at(0)).getIsOnRunway() || (*exitSegments.at(0)).getIsOnRunway() )) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double exitHeading = SGGeodesy::courseDeg((*it)->geod(),
|
double exitHeading = SGGeodesy::courseDeg((*it)->geod(),
|
||||||
(exitSegments.back())->geod());
|
(exitSegments.back())->geod());
|
||||||
diff = fabs(aRunway->headingDeg() - exitHeading);
|
diff = fabs(SGMiscd::normalizePeriodic(-180, 180, aRunway->headingDeg() - exitHeading));
|
||||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit2 " << diff << " " << (*it)->getIndex());
|
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit2 Diff :" << diff << " Id : " << (*it)->getIndex());
|
||||||
if (diff > 70) {
|
if (diff > 70) {
|
||||||
// Only exits going in our direction
|
// Only exits going in our direction
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
if (localDistanceSqr < d) {
|
||||||
SG_LOG(SG_AI, SG_BULK, "No Runway findNearestNodeOnRunwayExit");
|
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit3 " << localDistanceSqr << " " << (*it)->getIndex());
|
||||||
}
|
d = localDistanceSqr;
|
||||||
if (localDistanceSqr < d) {
|
result = *it;
|
||||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit3 " << localDistanceSqr << " " << (*it)->getIndex());
|
}
|
||||||
d = localDistanceSqr;
|
|
||||||
result = *it;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_AI, SG_BULK, "No Runway findNearestNodeOnRunwayExit");
|
||||||
}
|
}
|
||||||
if(result) {
|
if(result) {
|
||||||
|
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit found :" << result->getIndex());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
// Ok then fallback only exits ahead
|
// Ok then fallback only exits ahead
|
||||||
|
|
|
@ -271,6 +271,7 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart)
|
||||||
}
|
}
|
||||||
|
|
||||||
double speed = 450.0;
|
double speed = 450.0;
|
||||||
|
int remainingWaitTime = 0;
|
||||||
if (dep != arr) {
|
if (dep != arr) {
|
||||||
totalTimeEnroute = flight->getArrivalTime() - flight->getDepartureTime();
|
totalTimeEnroute = flight->getArrivalTime() - flight->getDepartureTime();
|
||||||
if (flight->getDepartureTime() < now) {
|
if (flight->getDepartureTime() < now) {
|
||||||
|
@ -295,8 +296,11 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart)
|
||||||
remainingTimeEnroute = totalTimeEnroute;
|
remainingTimeEnroute = totalTimeEnroute;
|
||||||
elapsedTimeEnroute = 0;
|
elapsedTimeEnroute = 0;
|
||||||
position = dep->geod();
|
position = dep->geod();
|
||||||
SG_LOG (SG_AI, SG_BULK, "Traffic Manager: " << flight->getCallSign() << " is pending, departure in "
|
remainingWaitTime = flight->getDepartureTime() - now;
|
||||||
<< flight->getDepartureTime() - now << " seconds ");
|
if (remainingWaitTime<600) {
|
||||||
|
SG_LOG (SG_AI, SG_BULK, "Traffic Manager: " << flight->getCallSign() << " is pending, departure in "
|
||||||
|
<< remainingWaitTime << " seconds ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// departure / arrival coincident
|
// departure / arrival coincident
|
||||||
|
@ -314,9 +318,11 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart)
|
||||||
// then 500nm, create this flight. At jet speeds 500 nm is roughly
|
// then 500nm, create this flight. At jet speeds 500 nm is roughly
|
||||||
// one hour flight time, so that would be a good approximate point
|
// one hour flight time, so that would be a good approximate point
|
||||||
// to start a more detailed simulation of this aircraft.
|
// to start a more detailed simulation of this aircraft.
|
||||||
SG_LOG (SG_AI, SG_BULK, "Traffic manager: " << registration << " is scheduled for a flight from "
|
if (remainingWaitTime<600) {
|
||||||
<< dep->getId() << " to " << arr->getId() << ". Current distance to user: "
|
SG_LOG (SG_AI, SG_BULK, "Traffic manager: " << registration << " is scheduled for a flight from "
|
||||||
<< distanceToUser);
|
<< dep->getId() << " to " << arr->getId() << ". Current distance to user: "
|
||||||
|
<< distanceToUser);
|
||||||
|
}
|
||||||
if (distanceToUser >= TRAFFICTOAIDISTTOSTART) {
|
if (distanceToUser >= TRAFFICTOAIDISTTOSTART) {
|
||||||
return true; // out of visual range, for the moment.
|
return true; // out of visual range, for the moment.
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,7 +293,7 @@ void TrafficTests::testPushbackCargoInProgress()
|
||||||
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_EGPH_EGPF_" + std::to_string(departureTime));
|
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_EGPH_EGPF_" + std::to_string(departureTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrafficTests::testPushbackCargoInProgressDownWind()
|
void TrafficTests::testPushbackCargoInProgressDownWindEast()
|
||||||
{
|
{
|
||||||
FGAirportRef egph = FGAirport::getByIdent("EGPH");
|
FGAirportRef egph = FGAirport::getByIdent("EGPH");
|
||||||
|
|
||||||
|
@ -308,12 +308,12 @@ void TrafficTests::testPushbackCargoInProgressDownWind()
|
||||||
|
|
||||||
FGAISchedule* schedule = new FGAISchedule(
|
FGAISchedule* schedule = new FGAISchedule(
|
||||||
"B737", "KLM", "EGPH", "G-BLA", "ID", false, "B737", "KLM", "N", "cargo", 24, 8);
|
"B737", "KLM", "EGPH", "G-BLA", "ID", false, "B737", "KLM", "N", "cargo", 24, 8);
|
||||||
FGScheduledFlight* flight = new FGScheduledFlight("testPushbackCargoInProgressDownWind", "", "EGPH", "EGPF", 24, dep, arr, "WEEK", "HBR_BN_2");
|
FGScheduledFlight* flight = new FGScheduledFlight("testPushbackCargoInProgressDownWindEast", "", "EGPH", "EGPF", 24, dep, arr, "WEEK", "HBR_BN_2");
|
||||||
schedule->assign(flight);
|
schedule->assign(flight);
|
||||||
|
|
||||||
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
|
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
|
||||||
|
|
||||||
const SGGeod position = SGGeodesy::direct(egph->geod(), 0, 50000);
|
const SGGeod position = SGGeodesy::direct(egph->geod(), 30, 50000);
|
||||||
const double crs = SGGeodesy::courseDeg(position, egpf->geod()); // direct course
|
const double crs = SGGeodesy::courseDeg(position, egpf->geod()); // direct course
|
||||||
ParkingAssignment parking = egph->getDynamics()->getParkingByName("north-cargo208");
|
ParkingAssignment parking = egph->getDynamics()->getParkingByName("north-cargo208");
|
||||||
|
|
||||||
|
@ -351,7 +351,68 @@ void TrafficTests::testPushbackCargoInProgressDownWind()
|
||||||
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
|
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
|
||||||
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
|
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
|
||||||
|
|
||||||
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_downwind_EGPH_EGPF_" + std::to_string(departureTime));
|
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_downwind_east_EGPH_EGPF_" + std::to_string(departureTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrafficTests::testPushbackCargoInProgressDownWindWest()
|
||||||
|
{
|
||||||
|
FGAirportRef egph = FGAirport::getByIdent("EGPH");
|
||||||
|
|
||||||
|
FGAirportRef egpf = FGAirport::getByIdent("EGPF");
|
||||||
|
fgSetString("/sim/presets/airport-id", "EGPH");
|
||||||
|
|
||||||
|
// Time to depart
|
||||||
|
std::string dep = getTimeString(-100);
|
||||||
|
// Time to arrive
|
||||||
|
std::string arr = getTimeString(190);
|
||||||
|
|
||||||
|
|
||||||
|
FGAISchedule* schedule = new FGAISchedule(
|
||||||
|
"B737", "KLM", "EGPH", "G-BLA", "ID", false, "B737", "KLM", "N", "cargo", 24, 8);
|
||||||
|
FGScheduledFlight* flight = new FGScheduledFlight("testPushbackCargoInProgressDownWindWest", "", "EGPH", "EGPF", 24, dep, arr, "WEEK", "HBR_BN_2");
|
||||||
|
schedule->assign(flight);
|
||||||
|
|
||||||
|
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
|
||||||
|
|
||||||
|
const SGGeod position = SGGeodesy::direct(egph->geod(), 300, 50000);
|
||||||
|
const double crs = SGGeodesy::courseDeg(position, egpf->geod()); // direct course
|
||||||
|
ParkingAssignment parking = egph->getDynamics()->getParkingByName("north-cargo208");
|
||||||
|
|
||||||
|
FGTestApi::setPositionAndStabilise(egph->getDynamics()->getParkingByName("ga206").parking()->geod());
|
||||||
|
|
||||||
|
aiAircraft->setPerformance("jet_transport", "");
|
||||||
|
aiAircraft->setCompany("KLM");
|
||||||
|
aiAircraft->setAcType("B737");
|
||||||
|
aiAircraft->setSpeed(0);
|
||||||
|
aiAircraft->setBank(0);
|
||||||
|
aiAircraft->setHeading(crs);
|
||||||
|
|
||||||
|
const string flightPlanName = egph->getId() + "-" + egpf->getId() + ".xml";
|
||||||
|
|
||||||
|
const int radius = 16.0;
|
||||||
|
const int cruiseAltFt = 32000;
|
||||||
|
const int cruiseSpeedKnots = 80;
|
||||||
|
|
||||||
|
time_t departureTime = globals->get_time_params()->get_cur_time();
|
||||||
|
departureTime = departureTime - 6000;
|
||||||
|
|
||||||
|
|
||||||
|
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
|
||||||
|
flightPlanName, crs,
|
||||||
|
departureTime, 100,
|
||||||
|
egph, egpf, true, radius,
|
||||||
|
cruiseAltFt, // cruise alt
|
||||||
|
position.getLatitudeDeg(),
|
||||||
|
position.getLongitudeDeg(),
|
||||||
|
cruiseSpeedKnots, "cargo",
|
||||||
|
aiAircraft->getAcType(),
|
||||||
|
aiAircraft->getCompany()));
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
|
||||||
|
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
|
||||||
|
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
|
||||||
|
|
||||||
|
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_downwind_west_EGPH_EGPF_" + std::to_string(departureTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrafficTests::testPushbackCargoInProgressNotBeyond()
|
void TrafficTests::testPushbackCargoInProgressNotBeyond()
|
||||||
|
@ -416,6 +477,68 @@ void TrafficTests::testPushbackCargoInProgressNotBeyond()
|
||||||
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_not_beyond_EGPH_EGPF_" + std::to_string(departureTime));
|
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_not_beyond_EGPH_EGPF_" + std::to_string(departureTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrafficTests::testPushbackCargoInProgressNotBeyondNorth()
|
||||||
|
{
|
||||||
|
FGAirportRef egph = FGAirport::getByIdent("EGPH");
|
||||||
|
|
||||||
|
FGAirportRef egpf = FGAirport::getByIdent("EGPF");
|
||||||
|
fgSetString("/sim/presets/airport-id", "EGPH");
|
||||||
|
|
||||||
|
// Time to depart
|
||||||
|
std::string dep = getTimeString(-100);
|
||||||
|
// Time to arrive
|
||||||
|
std::string arr = getTimeString(190);
|
||||||
|
|
||||||
|
|
||||||
|
FGAISchedule* schedule = new FGAISchedule(
|
||||||
|
"B737", "KLM", "EGPH", "G-BLA", "ID", false, "B737", "KLM", "N", "cargo", 24, 8);
|
||||||
|
FGScheduledFlight* flight = new FGScheduledFlight("testPushbackCargo", "", "EGPH", "EGPF", 24, dep, arr, "WEEK", "HBR_BN_2");
|
||||||
|
schedule->assign(flight);
|
||||||
|
|
||||||
|
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
|
||||||
|
|
||||||
|
// Position west of runway
|
||||||
|
const SGGeod position = SGGeodesy::direct(egpf->geod(), 270, 5000);
|
||||||
|
const double crs = 0; // direct course
|
||||||
|
ParkingAssignment parking = egph->getDynamics()->getParkingByName("north-cargo208");
|
||||||
|
|
||||||
|
FGTestApi::setPositionAndStabilise(egph->getDynamics()->getParkingByName("ga206").parking()->geod());
|
||||||
|
|
||||||
|
aiAircraft->setPerformance("jet_transport", "");
|
||||||
|
aiAircraft->setCompany("KLM");
|
||||||
|
aiAircraft->setAcType("B737");
|
||||||
|
aiAircraft->setSpeed(0);
|
||||||
|
aiAircraft->setBank(0);
|
||||||
|
aiAircraft->setHeading(crs);
|
||||||
|
|
||||||
|
const string flightPlanName = egph->getId() + "-" + egpf->getId() + ".xml";
|
||||||
|
|
||||||
|
const int radius = 16.0;
|
||||||
|
const int cruiseAltFt = 32000;
|
||||||
|
const int cruiseSpeedKnots = 80;
|
||||||
|
|
||||||
|
time_t departureTime = globals->get_time_params()->get_cur_time();
|
||||||
|
departureTime = departureTime - 6000;
|
||||||
|
|
||||||
|
|
||||||
|
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
|
||||||
|
flightPlanName, crs,
|
||||||
|
departureTime, 100,
|
||||||
|
egph, egpf, true, radius,
|
||||||
|
cruiseAltFt, // cruise alt
|
||||||
|
position.getLatitudeDeg(),
|
||||||
|
position.getLongitudeDeg(),
|
||||||
|
cruiseSpeedKnots, "cargo",
|
||||||
|
aiAircraft->getAcType(),
|
||||||
|
aiAircraft->getCompany()));
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
|
||||||
|
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
|
||||||
|
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
|
||||||
|
|
||||||
|
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_not_beyond_north_EGPH_EGPF_" + std::to_string(departureTime));
|
||||||
|
}
|
||||||
|
|
||||||
void TrafficTests::testPushbackCargoInProgressBeyond()
|
void TrafficTests::testPushbackCargoInProgressBeyond()
|
||||||
{
|
{
|
||||||
FGAirportRef egph = FGAirport::getByIdent("EGPH");
|
FGAirportRef egph = FGAirport::getByIdent("EGPH");
|
||||||
|
@ -479,6 +602,69 @@ void TrafficTests::testPushbackCargoInProgressBeyond()
|
||||||
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_beyond_EGPH_EGPF_" + std::to_string(departureTime));
|
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_beyond_EGPH_EGPF_" + std::to_string(departureTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrafficTests::testPushbackCargoInProgressBeyondNorth()
|
||||||
|
{
|
||||||
|
FGAirportRef egph = FGAirport::getByIdent("EGPH");
|
||||||
|
|
||||||
|
FGAirportRef egpf = FGAirport::getByIdent("EGPF");
|
||||||
|
fgSetString("/sim/presets/airport-id", "EGPH");
|
||||||
|
|
||||||
|
// Time to depart
|
||||||
|
std::string dep = getTimeString(-100);
|
||||||
|
// Time to arrive
|
||||||
|
std::string arr = getTimeString(190);
|
||||||
|
|
||||||
|
|
||||||
|
FGAISchedule* schedule = new FGAISchedule(
|
||||||
|
"B737", "KLM", "EGPH", "G-BLA", "ID", false, "B737", "KLM", "N", "cargo", 24, 8);
|
||||||
|
FGScheduledFlight* flight = new FGScheduledFlight("testPushbackCargo", "", "EGPH", "EGPF", 24, dep, arr, "WEEK", "HBR_BN_2");
|
||||||
|
schedule->assign(flight);
|
||||||
|
|
||||||
|
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
|
||||||
|
|
||||||
|
// Position east of runway pointing away from runway
|
||||||
|
const SGGeod position = SGGeodesy::direct(egpf->geod(), 90, 5000);
|
||||||
|
|
||||||
|
const double crs = 300;
|
||||||
|
ParkingAssignment parking = egph->getDynamics()->getParkingByName("north-cargo208");
|
||||||
|
|
||||||
|
FGTestApi::setPositionAndStabilise(egph->getDynamics()->getParkingByName("ga206").parking()->geod());
|
||||||
|
|
||||||
|
aiAircraft->setPerformance("jet_transport", "");
|
||||||
|
aiAircraft->setCompany("KLM");
|
||||||
|
aiAircraft->setAcType("B737");
|
||||||
|
aiAircraft->setSpeed(0);
|
||||||
|
aiAircraft->setBank(0);
|
||||||
|
aiAircraft->setHeading(crs);
|
||||||
|
|
||||||
|
const string flightPlanName = egph->getId() + "-" + egpf->getId() + ".xml";
|
||||||
|
|
||||||
|
const int radius = 16.0;
|
||||||
|
const int cruiseAltFt = 32000;
|
||||||
|
const int cruiseSpeedKnots = 80;
|
||||||
|
|
||||||
|
time_t departureTime = globals->get_time_params()->get_cur_time();
|
||||||
|
departureTime = departureTime - 6000;
|
||||||
|
|
||||||
|
|
||||||
|
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
|
||||||
|
flightPlanName, crs,
|
||||||
|
departureTime, 100,
|
||||||
|
egph, egpf, true, radius,
|
||||||
|
cruiseAltFt, // cruise alt
|
||||||
|
position.getLatitudeDeg(),
|
||||||
|
position.getLongitudeDeg(),
|
||||||
|
cruiseSpeedKnots, "cargo",
|
||||||
|
aiAircraft->getAcType(),
|
||||||
|
aiAircraft->getCompany()));
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
|
||||||
|
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
|
||||||
|
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
|
||||||
|
|
||||||
|
aiAircraft = flyAI(aiAircraft, "flight_cargo_in_progress_beyond_north_EGPH_EGPF_" + std::to_string(departureTime));
|
||||||
|
}
|
||||||
|
|
||||||
void TrafficTests::testChangeRunway()
|
void TrafficTests::testChangeRunway()
|
||||||
{
|
{
|
||||||
FGAirportRef departureAirport = FGAirport::getByIdent("EGPH");
|
FGAirportRef departureAirport = FGAirport::getByIdent("EGPH");
|
||||||
|
@ -875,7 +1061,7 @@ void TrafficTests::testPushforwardParkYBBNRepeatGaDelayed()
|
||||||
ActiveRunway* activeDepartureRunway = departureDynamics->getApproachController()->getRunway("01");
|
ActiveRunway* activeDepartureRunway = departureDynamics->getApproachController()->getRunway("01");
|
||||||
time_t newDeparture = activeDepartureRunway->requestTimeSlot(aiAircraft->GetFlightPlan()->getStartTime());
|
time_t newDeparture = activeDepartureRunway->requestTimeSlot(aiAircraft->GetFlightPlan()->getStartTime());
|
||||||
// See that the wait queue is filled
|
// See that the wait queue is filled
|
||||||
for (size_t i = 0; i < 100; i++)
|
for (size_t i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
newDeparture = activeDepartureRunway->requestTimeSlot(newDeparture);
|
newDeparture = activeDepartureRunway->requestTimeSlot(newDeparture);
|
||||||
}
|
}
|
||||||
|
@ -890,7 +1076,7 @@ void TrafficTests::testPushforwardParkYBBNRepeatGaDelayed()
|
||||||
newArrival = activeYSSYRunway->requestTimeSlot(newArrival);
|
newArrival = activeYSSYRunway->requestTimeSlot(newArrival);
|
||||||
}
|
}
|
||||||
|
|
||||||
aiAircraft = flyAI(aiAircraft, "flight_ga_YSSY_YBBN_park_repeat" + std::to_string(departureTime));
|
aiAircraft = flyAI(aiAircraft, "flight_ga_YSSY_YBBN_park_repeatdelayed" + std::to_string(departureTime));
|
||||||
|
|
||||||
int shortestDistance = 10000;
|
int shortestDistance = 10000;
|
||||||
const FGParkingList& parkings(arrivalAirport->groundNetwork()->allParkings());
|
const FGParkingList& parkings(arrivalAirport->groundNetwork()->allParkings());
|
||||||
|
|
|
@ -38,9 +38,12 @@ class TrafficTests : public CppUnit::TestFixture
|
||||||
CPPUNIT_TEST(testPushback);
|
CPPUNIT_TEST(testPushback);
|
||||||
CPPUNIT_TEST(testPushbackCargo);
|
CPPUNIT_TEST(testPushbackCargo);
|
||||||
CPPUNIT_TEST(testPushbackCargoInProgress);
|
CPPUNIT_TEST(testPushbackCargoInProgress);
|
||||||
CPPUNIT_TEST(testPushbackCargoInProgressDownWind);
|
CPPUNIT_TEST(testPushbackCargoInProgressDownWindEast);
|
||||||
|
CPPUNIT_TEST(testPushbackCargoInProgressDownWindWest);
|
||||||
CPPUNIT_TEST(testPushbackCargoInProgressNotBeyond);
|
CPPUNIT_TEST(testPushbackCargoInProgressNotBeyond);
|
||||||
|
CPPUNIT_TEST(testPushbackCargoInProgressNotBeyondNorth);
|
||||||
CPPUNIT_TEST(testPushbackCargoInProgressBeyond);
|
CPPUNIT_TEST(testPushbackCargoInProgressBeyond);
|
||||||
|
CPPUNIT_TEST(testPushbackCargoInProgressBeyondNorth);
|
||||||
CPPUNIT_TEST(testChangeRunway);
|
CPPUNIT_TEST(testChangeRunway);
|
||||||
CPPUNIT_TEST(testPushforward);
|
CPPUNIT_TEST(testPushforward);
|
||||||
CPPUNIT_TEST(testPushforwardSpeedy);
|
CPPUNIT_TEST(testPushforwardSpeedy);
|
||||||
|
@ -60,9 +63,12 @@ public:
|
||||||
void testPushback();
|
void testPushback();
|
||||||
void testPushbackCargo();
|
void testPushbackCargo();
|
||||||
void testPushbackCargoInProgress();
|
void testPushbackCargoInProgress();
|
||||||
void testPushbackCargoInProgressDownWind();
|
void testPushbackCargoInProgressDownWindEast();
|
||||||
|
void testPushbackCargoInProgressDownWindWest();
|
||||||
void testPushbackCargoInProgressNotBeyond();
|
void testPushbackCargoInProgressNotBeyond();
|
||||||
|
void testPushbackCargoInProgressNotBeyondNorth();
|
||||||
void testPushbackCargoInProgressBeyond();
|
void testPushbackCargoInProgressBeyond();
|
||||||
|
void testPushbackCargoInProgressBeyondNorth();
|
||||||
void testChangeRunway();
|
void testChangeRunway();
|
||||||
//GA Tests with forward push
|
//GA Tests with forward push
|
||||||
void testPushforward();
|
void testPushforward();
|
||||||
|
|
Loading…
Add table
Reference in a new issue