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);
|
||||
return;
|
||||
}
|
||||
fp->IncrementWaypoint(false);
|
||||
fp->IncrementWaypoint(false);
|
||||
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();
|
||||
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();
|
||||
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) {
|
||||
|
@ -606,7 +608,7 @@ bool FGAIAircraft::loadNextLeg(double distance) {
|
|||
|
||||
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,
|
||||
dep,
|
||||
arr,
|
||||
|
@ -879,7 +881,7 @@ void FGAIAircraft::handleFirstWaypoint() {
|
|||
// Make sure lead distance is initialized otherwise
|
||||
// If we are ending in a parking
|
||||
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
|
||||
|
@ -1147,7 +1149,11 @@ void FGAIAircraft::controlSpeed(FGAIWaypoint* curr, FGAIWaypoint* next) {
|
|||
prevSpeed = speed;
|
||||
if (next) {
|
||||
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());
|
||||
}
|
||||
|
||||
// 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,
|
||||
double bearing,
|
||||
FGAIWaypoint* current,
|
||||
|
@ -447,11 +449,11 @@ void FGAIFlightPlan::setLeadDistance(double speed,
|
|||
// we travel on. Get the turn radius by dividing by PI (*2).
|
||||
// FIXME Why when going backwards? No fabs
|
||||
if (speed < 0.5) {
|
||||
lead_distance_ft = 0.5;
|
||||
setLeadDistance(0.5);
|
||||
return;
|
||||
}
|
||||
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));
|
||||
return;
|
||||
}
|
||||
|
@ -473,11 +475,14 @@ void FGAIFlightPlan::setLeadDistance(double speed,
|
|||
//lead_distance_ft = turn_radius * sin(leadInAngle * SG_DEGREES_TO_RADIANS);
|
||||
|
||||
if ((int)leadInAngle==0) {
|
||||
double lead_distance_m = fabs(2*speed) * SG_FEET_TO_METER;
|
||||
setLeadDistance(lead_distance_m * SG_METER_TO_FEET);
|
||||
double lead_distance_m = fabs(2*speed) * SG_FEET_TO_METER;
|
||||
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 {
|
||||
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);
|
||||
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);
|
||||
|
@ -499,6 +504,9 @@ void FGAIFlightPlan::setLeadDistance(double speed,
|
|||
|
||||
void FGAIFlightPlan::setLeadDistance(double 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");
|
||||
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");
|
||||
int holdsPatterns = 0;
|
||||
// Length of
|
||||
if (holdsPatterns>0) {
|
||||
// Turn into hold
|
||||
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 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");
|
||||
}
|
||||
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 {
|
||||
SG_LOG(SG_AI, SG_BULK, ac->getCallSign() << "| Enter far 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");
|
||||
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");
|
||||
int holdsPatterns = 0;
|
||||
// Length of
|
||||
if (holdsPatterns>0) {
|
||||
// Turn into hold
|
||||
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 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");
|
||||
}
|
||||
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 ) {
|
||||
// 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");
|
||||
//outer
|
||||
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");
|
||||
int holdsPatterns = 0;
|
||||
// Length of
|
||||
if (holdsPatterns>0) {
|
||||
// Turn into hold
|
||||
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");
|
||||
}
|
||||
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 {
|
||||
SG_LOG(SG_AI, SG_BULK, ac->getCallSign() << "| Enter far S downrunway");
|
||||
// Entering not "straight" into runway so we do a s-curve
|
||||
int rightAngle = azimuth<0?90:-90;
|
||||
int firstTurnIncrement = azimuth<0?2:-2;
|
||||
int rightAngle = headingDiffRunway>0?90:-90;
|
||||
int firstTurnIncrement = headingDiffRunway>0?2:-2;
|
||||
int innerTangent = headingDiffRunway<0?0:1;
|
||||
SGGeod firstTurnCenter = SGGeodesy::direct(current, ac->getTrueHeadingDeg() + rightAngle, initialTurnRadius);
|
||||
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");
|
||||
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");
|
||||
int holdsPatterns = 0;
|
||||
// Length of
|
||||
if (holdsPatterns>0) {
|
||||
// Turn into hold
|
||||
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 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");
|
||||
}
|
||||
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 {
|
||||
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);
|
||||
int firstTurnIncrement = headingDiffRunway>0?-2:2;
|
||||
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();
|
||||
|
@ -1174,10 +1105,10 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
wpt->setSpeedBrakes(1.0f);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
SG_LOG(SG_AI, SG_BULK, "Landing " << glideslopeEntry << "\t" << decelPoint);
|
||||
|
||||
double rolloutDistance = accelDistance(vTouchdownMetric, vTaxiMetric, decelMetric);
|
||||
|
||||
SG_LOG(SG_AI, SG_BULK, "Landing " << glideslopeEntry << "\t" << decelPoint << " Rollout " << rolloutDistance);
|
||||
|
||||
int nPoints = (int)(rolloutDistance/60);
|
||||
for (int i = 1; i <= nPoints; i++) {
|
||||
snprintf(buffer, sizeof(buffer), "rollout%03d", i);
|
||||
|
|
|
@ -299,42 +299,49 @@ FGTaxiNodeRef FGGroundNetwork::findNearestNodeOnRunwayExit(const SGGeod & aGeod,
|
|||
SGVec3d cartPos = SGVec3d::fromGeod(aGeod);
|
||||
FGTaxiNodeRef result = 0;
|
||||
FGTaxiNodeVector::const_iterator it;
|
||||
for (it = m_nodes.begin(); it != m_nodes.end(); ++it) {
|
||||
if (!(*it)->getIsOnRunway())
|
||||
continue;
|
||||
double localDistanceSqr = distSqr(cartPos, (*it)->cart());
|
||||
if (aRunway) {
|
||||
if (aRunway) {
|
||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit " << aRunway->ident() << " " << aRunway->headingDeg() );
|
||||
for (it = m_nodes.begin(); it != m_nodes.end(); ++it) {
|
||||
if (!(*it)->getIsOnRunway())
|
||||
continue;
|
||||
double localDistanceSqr = distSqr(cartPos, (*it)->cart());
|
||||
double headingTowardsExit = SGGeodesy::courseDeg(aGeod, (*it)->geod());
|
||||
double diff = fabs(aRunway->headingDeg() - headingTowardsExit);
|
||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit " << aRunway->headingDeg() << " "
|
||||
<< " Diff : " << diff << " " << (*it)->getIndex());
|
||||
double diff = fabs(SGMiscd::normalizePeriodic(-180, 180, aRunway->headingDeg() - headingTowardsExit));
|
||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit Diff : " << diff << " Id : " << (*it)->getIndex());
|
||||
if (diff > 10) {
|
||||
// Only ahead
|
||||
continue;
|
||||
}
|
||||
FGTaxiNodeVector exitSegments = findSegmentsFrom((*it));
|
||||
// Only ends
|
||||
if (exitSegments.size() != 1) {
|
||||
// Some kind of star
|
||||
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;
|
||||
}
|
||||
double exitHeading = SGGeodesy::courseDeg((*it)->geod(),
|
||||
(exitSegments.back())->geod());
|
||||
diff = fabs(aRunway->headingDeg() - exitHeading);
|
||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit2 " << diff << " " << (*it)->getIndex());
|
||||
(exitSegments.back())->geod());
|
||||
diff = fabs(SGMiscd::normalizePeriodic(-180, 180, aRunway->headingDeg() - exitHeading));
|
||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit2 Diff :" << diff << " Id : " << (*it)->getIndex());
|
||||
if (diff > 70) {
|
||||
// Only exits going in our direction
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
SG_LOG(SG_AI, SG_BULK, "No Runway findNearestNodeOnRunwayExit");
|
||||
}
|
||||
if (localDistanceSqr < d) {
|
||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit3 " << localDistanceSqr << " " << (*it)->getIndex());
|
||||
d = localDistanceSqr;
|
||||
result = *it;
|
||||
if (localDistanceSqr < d) {
|
||||
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) {
|
||||
SG_LOG(SG_AI, SG_BULK, "findNearestNodeOnRunwayExit found :" << result->getIndex());
|
||||
return result;
|
||||
}
|
||||
// Ok then fallback only exits ahead
|
||||
|
|
|
@ -271,6 +271,7 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart)
|
|||
}
|
||||
|
||||
double speed = 450.0;
|
||||
int remainingWaitTime = 0;
|
||||
if (dep != arr) {
|
||||
totalTimeEnroute = flight->getArrivalTime() - flight->getDepartureTime();
|
||||
if (flight->getDepartureTime() < now) {
|
||||
|
@ -295,8 +296,11 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart)
|
|||
remainingTimeEnroute = totalTimeEnroute;
|
||||
elapsedTimeEnroute = 0;
|
||||
position = dep->geod();
|
||||
SG_LOG (SG_AI, SG_BULK, "Traffic Manager: " << flight->getCallSign() << " is pending, departure in "
|
||||
<< flight->getDepartureTime() - now << " seconds ");
|
||||
remainingWaitTime = flight->getDepartureTime() - now;
|
||||
if (remainingWaitTime<600) {
|
||||
SG_LOG (SG_AI, SG_BULK, "Traffic Manager: " << flight->getCallSign() << " is pending, departure in "
|
||||
<< remainingWaitTime << " seconds ");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 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
|
||||
// one hour flight time, so that would be a good approximate point
|
||||
// to start a more detailed simulation of this aircraft.
|
||||
SG_LOG (SG_AI, SG_BULK, "Traffic manager: " << registration << " is scheduled for a flight from "
|
||||
<< dep->getId() << " to " << arr->getId() << ". Current distance to user: "
|
||||
<< distanceToUser);
|
||||
if (remainingWaitTime<600) {
|
||||
SG_LOG (SG_AI, SG_BULK, "Traffic manager: " << registration << " is scheduled for a flight from "
|
||||
<< dep->getId() << " to " << arr->getId() << ". Current distance to user: "
|
||||
<< distanceToUser);
|
||||
}
|
||||
if (distanceToUser >= TRAFFICTOAIDISTTOSTART) {
|
||||
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));
|
||||
}
|
||||
|
||||
void TrafficTests::testPushbackCargoInProgressDownWind()
|
||||
void TrafficTests::testPushbackCargoInProgressDownWindEast()
|
||||
{
|
||||
FGAirportRef egph = FGAirport::getByIdent("EGPH");
|
||||
|
||||
|
@ -308,12 +308,12 @@ void TrafficTests::testPushbackCargoInProgressDownWind()
|
|||
|
||||
FGAISchedule* schedule = new FGAISchedule(
|
||||
"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);
|
||||
|
||||
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
|
||||
ParkingAssignment parking = egph->getDynamics()->getParkingByName("north-cargo208");
|
||||
|
||||
|
@ -351,7 +351,68 @@ void TrafficTests::testPushbackCargoInProgressDownWind()
|
|||
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
|
||||
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()
|
||||
|
@ -416,6 +477,68 @@ void TrafficTests::testPushbackCargoInProgressNotBeyond()
|
|||
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()
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
FGAirportRef departureAirport = FGAirport::getByIdent("EGPH");
|
||||
|
@ -875,7 +1061,7 @@ void TrafficTests::testPushforwardParkYBBNRepeatGaDelayed()
|
|||
ActiveRunway* activeDepartureRunway = departureDynamics->getApproachController()->getRunway("01");
|
||||
time_t newDeparture = activeDepartureRunway->requestTimeSlot(aiAircraft->GetFlightPlan()->getStartTime());
|
||||
// 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);
|
||||
}
|
||||
|
@ -890,7 +1076,7 @@ void TrafficTests::testPushforwardParkYBBNRepeatGaDelayed()
|
|||
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;
|
||||
const FGParkingList& parkings(arrivalAirport->groundNetwork()->allParkings());
|
||||
|
|
|
@ -38,9 +38,12 @@ class TrafficTests : public CppUnit::TestFixture
|
|||
CPPUNIT_TEST(testPushback);
|
||||
CPPUNIT_TEST(testPushbackCargo);
|
||||
CPPUNIT_TEST(testPushbackCargoInProgress);
|
||||
CPPUNIT_TEST(testPushbackCargoInProgressDownWind);
|
||||
CPPUNIT_TEST(testPushbackCargoInProgressDownWindEast);
|
||||
CPPUNIT_TEST(testPushbackCargoInProgressDownWindWest);
|
||||
CPPUNIT_TEST(testPushbackCargoInProgressNotBeyond);
|
||||
CPPUNIT_TEST(testPushbackCargoInProgressNotBeyondNorth);
|
||||
CPPUNIT_TEST(testPushbackCargoInProgressBeyond);
|
||||
CPPUNIT_TEST(testPushbackCargoInProgressBeyondNorth);
|
||||
CPPUNIT_TEST(testChangeRunway);
|
||||
CPPUNIT_TEST(testPushforward);
|
||||
CPPUNIT_TEST(testPushforwardSpeedy);
|
||||
|
@ -60,9 +63,12 @@ public:
|
|||
void testPushback();
|
||||
void testPushbackCargo();
|
||||
void testPushbackCargoInProgress();
|
||||
void testPushbackCargoInProgressDownWind();
|
||||
void testPushbackCargoInProgressDownWindEast();
|
||||
void testPushbackCargoInProgressDownWindWest();
|
||||
void testPushbackCargoInProgressNotBeyond();
|
||||
void testPushbackCargoInProgressNotBeyondNorth();
|
||||
void testPushbackCargoInProgressBeyond();
|
||||
void testPushbackCargoInProgressBeyondNorth();
|
||||
void testChangeRunway();
|
||||
//GA Tests with forward push
|
||||
void testPushforward();
|
||||
|
|
Loading…
Add table
Reference in a new issue