1
0
Fork 0
* Better runway exit
* Bug in approach
* Test east/west approach downwind
This commit is contained in:
portree_kid 2023-01-28 20:48:11 +01:00
parent 20fc979a52
commit 78797e28aa
7 changed files with 289 additions and 139 deletions

View file

@ -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")) {
if (speed_diff > 0 && tgt_speed >= 5) {
fp->setLeadDistance(speed, tgt_heading, curr, next);
} else {
fp->setLeadDistance(tgt_speed, tgt_heading, curr, next);
}
}
}
}

View file

@ -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;
}
@ -475,9 +477,12 @@ void FGAIFlightPlan::setLeadDistance(double speed,
if ((int)leadInAngle==0) {
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);
}
}

View file

@ -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");
}
} 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,29 +890,12 @@ 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");
}
}
} else if (fabs(headingDiffRunway)>=150 ) {
// We are entering downwind
if (distance < (2*initialTurnRadius)) {
@ -955,63 +921,28 @@ 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);
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");
}
}
} else {
SG_LOG(SG_AI, SG_BULK, ac->getCallSign() << "| Enter far straight");
// Entering "straight" into runway so only one turn
@ -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);

View file

@ -299,42 +299,49 @@ FGTaxiNodeRef FGGroundNetwork::findNearestNodeOnRunwayExit(const SGGeod & aGeod,
SGVec3d cartPos = SGVec3d::fromGeod(aGeod);
FGTaxiNodeRef result = 0;
FGTaxiNodeVector::const_iterator it;
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());
if (aRunway) {
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());
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;
}
}
} 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

View file

@ -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();
remainingWaitTime = flight->getDepartureTime() - now;
if (remainingWaitTime<600) {
SG_LOG (SG_AI, SG_BULK, "Traffic Manager: " << flight->getCallSign() << " is pending, departure in "
<< flight->getDepartureTime() - now << " seconds ");
<< 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.
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.
}

View file

@ -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());

View file

@ -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();