1
0
Fork 0

Some initial tests for route discontinuities.

Probably many more to add, but this is some basic testing at least of
inserting, querying and removing discontinuities.
This commit is contained in:
James Turner 2020-04-15 16:11:33 +01:00
parent fa898e7cd6
commit 4c0965e3c1
4 changed files with 98 additions and 15 deletions

View file

@ -287,7 +287,8 @@ public:
// compute leg courses for all static legs (both ends are fixed)
void initPass1(const WayptData& previous, WayptData* next)
{
if (wpt->type() == "vectors") {
const auto ty = wpt->type();
if ((ty == "vectors") || (ty == "discontinuity")) {
// relying on the fact vectors will be followed by a static fix/wpt
if (next && next->posValid) {
posValid = true;
@ -295,7 +296,7 @@ public:
}
}
if (wpt->type() == "via") {
if (ty == "via") {
// even though both ends may be known, we don't
// want to compute a leg course for a VIA
} else if (posValid && !legCourseValid && previous.posValid) {
@ -309,7 +310,11 @@ public:
// use the runway departure end pos
FGRunway* rwy = static_cast<RunwayWaypt*>(previous.wpt.get())->runway();
legCourseTrue = SGGeodesy::courseDeg(rwy->end(), pos);
} else if (wpt->type() != "runway") {
} else if (ty == "discontinuity") {
// we want to keep the path across DISCONs sharp (no turn entry/exit)
// so we keep the leg course invalid, even though we actually
// could compute it
} else if (ty != "runway") {
// need to wait to compute runway leg course
legCourseTrue = SGGeodesy::courseDeg(previous.pos, pos);
legCourseValid = true;
@ -323,7 +328,7 @@ public:
return;
}
if ((wpt->type() == "discontinuity") || (wpt->type() == "via"))
if ((wpt->type() == "via") || (wpt->type() == "discontinuty"))
{
// do nothing, we can't compute a valid leg course for these types
// we'll generate sharp turns in the path but that's no problem.
@ -792,14 +797,13 @@ public:
WayptDataVec::iterator previousValidWaypoint(unsigned int index)
{
do {
if (index == 0) {
return waypoints.end();
}
while (waypoints[--index].skipped) {
// waypoint zero should be unskippable, this assert verified that
assert(index > 0);
}
--index;
} while (waypoints.at(index).skipped || (waypoints.at(index).wpt->type() == "discontinuity"));
return waypoints.begin() + index;
}
@ -822,7 +826,7 @@ public:
}
++it;
while ((it != waypoints.end()) && it->skipped) {
while ((it != waypoints.end()) && (it->skipped || (it->wpt->type() == "discontinuity"))) {
++it;
}
return it;
@ -870,7 +874,8 @@ void RoutePath::commonInit()
for (unsigned int i=1; i<d->waypoints.size(); ++i) {
WayptData* nextPtr = ((i + 1) < d->waypoints.size()) ? &d->waypoints[i+1] : nullptr;
d->waypoints[i].initPass1(d->waypoints[i-1], nextPtr);
auto prev = d->previousValidWaypoint(i);
d->waypoints[i].initPass1(*prev, nextPtr);
}
for (unsigned int i=0; i<d->waypoints.size(); ++i) {
@ -1073,10 +1078,15 @@ double RoutePath::computeDistanceForIndex(int index) const
return 0.0;
}
if (it->wpt->type() == "via") {
const auto ty = it->wpt->type();
if (ty == "via") {
return distanceForVia(static_cast<Via*>(it->wpt.get()), index);
}
if (ty == "discontinuity") {
return 0.0;
}
auto prevIt = d->previousValidWaypoint(index);
assert(prevIt != d->waypoints.end());

View file

@ -156,6 +156,10 @@ void populateFPWithoutNasal(flightgear::FlightPlanRef f,
for (auto ws : simgear::strutils::split(waypoints)) {
WayptRef wpt = f->waypointFromString(ws);
if (!wpt) {
SG_LOG(SG_NAVAID, SG_ALERT, "No waypoint created for:" << ws);
continue;
}
f->insertWayptAtIndex(wpt, -1);
}

View file

@ -394,3 +394,68 @@ void FlightplanTests::testLoadSaveMachRestriction()
CPPUNIT_ASSERT_EQUAL(8, f2->legAtIndex(2)->holdCount());
}
void FlightplanTests::testBasicDiscontinuity()
{
FlightPlanRef fp1 = makeTestFP("LIRF", "34L", "LEBL", "25R",
"ESINO GITRI BALEN MUREN TOSNU");
const auto tdBefore = fp1->totalDistanceNm();
const SGGeod balenPos = fp1->legAtIndex(3)->waypoint()->position();
const SGGeod murenPos = fp1->legAtIndex(4)->waypoint()->position();
// total distance should not change
fp1->insertWayptAtIndex(new Discontinuity(fp1), 4); // betwee BALEN and MUREN
CPPUNIT_ASSERT_DOUBLES_EQUAL(tdBefore, fp1->totalDistanceNm(), 1.0);
CPPUNIT_ASSERT_DOUBLES_EQUAL(fp1->legAtIndex(4)->courseDeg(),
SGGeodesy::courseDeg(balenPos, murenPos), 0.1);
CPPUNIT_ASSERT_DOUBLES_EQUAL(fp1->legAtIndex(4)->distanceNm(), 0.0, 0.1);
CPPUNIT_ASSERT_DOUBLES_EQUAL(fp1->legAtIndex(5)->courseDeg(),
SGGeodesy::courseDeg(balenPos, murenPos), 0.1);
CPPUNIT_ASSERT_DOUBLES_EQUAL(fp1->legAtIndex(5)->distanceNm(),
SGGeodesy::distanceNm(balenPos, murenPos), 0.1);
// remove the discontinuity
fp1->deleteIndex(4);
CPPUNIT_ASSERT_DOUBLES_EQUAL(fp1->legAtIndex(4)->courseDeg(),
SGGeodesy::courseDeg(balenPos, murenPos), 0.1);
CPPUNIT_ASSERT_DOUBLES_EQUAL(fp1->legAtIndex(4)->distanceNm(),
SGGeodesy::distanceNm(balenPos, murenPos), 0.1);
CPPUNIT_ASSERT_DOUBLES_EQUAL(tdBefore, fp1->totalDistanceNm(), 1.0);
}
void FlightplanTests::testOnlyDiscontinuityRoute()
{
FlightPlanRef f = new FlightPlan;
FGAirportRef depApt = FGAirport::getByIdent("LFBD");
f->setDeparture(depApt);
FGAirportRef destApt = FGAirport::getByIdent("EHAM");
f->setDestination(destApt);
f->insertWayptAtIndex(new Discontinuity(f), 0);
RoutePath rp1(f);
// discontinuity should act like a straight segment between preceeding and following
const double d = SGGeodesy::distanceNm(depApt->geod(), destApt->geod());
// CPPUNIT_ASSERT_DOUBLES_EQUAL(rp1.distanceForIndex(0), d, 0.5);
// start inserting waypoints ahead of the DISCON, Boeing FPL style
WayptRef wpt = f->waypointFromString("LMG");
f->insertWayptAtIndex(wpt, 0);
wpt = f->waypointFromString("KUKOR");
f->insertWayptAtIndex(wpt, 1);
wpt = f->waypointFromString("EPL");
f->insertWayptAtIndex(wpt, 2);
}

View file

@ -41,6 +41,8 @@ class FlightplanTests : public CppUnit::TestFixture
CPPUNIT_TEST(testRoutPathWpt0Midflight);
CPPUNIT_TEST(testRoutePathVec);
CPPUNIT_TEST(testLoadSaveMachRestriction);
CPPUNIT_TEST(testOnlyDiscontinuityRoute);
CPPUNIT_TEST(testBasicDiscontinuity);
// CPPUNIT_TEST(testParseICAORoute);
// CPPUNIT_TEST(testParseICANLowLevelRoute);
@ -66,6 +68,8 @@ public:
void testRoutPathWpt0Midflight();
void testRoutePathVec();
void testLoadSaveMachRestriction();
void testBasicDiscontinuity();
void testOnlyDiscontinuityRoute();
};
#endif // FG_FLIGHTPLAN_UNIT_TESTS_HXX