From 21a8e89a0a3ec28e6918aeedcdc0f51bb9a898ec Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Tue, 23 Apr 2019 18:10:39 +0100
Subject: [PATCH] Basic flight-plan/leg tests for GPS

---
 test_suite/FGTestApi/TestPilot.cxx            |  21 ++-
 test_suite/FGTestApi/TestPilot.hxx            |   1 +
 test_suite/FGTestApi/globals.cxx              |  36 +++++
 test_suite/FGTestApi/globals.hxx              |  12 ++
 .../unit_tests/Instrumentation/test_gps.cxx   | 151 +++++++++++++++++-
 .../unit_tests/Instrumentation/test_gps.hxx   |   7 +-
 .../unit_tests/Navaids/test_flightplan.cxx    |  75 +++++----
 .../unit_tests/Navaids/test_flightplan.hxx    |   2 +
 8 files changed, 273 insertions(+), 32 deletions(-)

diff --git a/test_suite/FGTestApi/TestPilot.cxx b/test_suite/FGTestApi/TestPilot.cxx
index 44461c754..aa4e32695 100644
--- a/test_suite/FGTestApi/TestPilot.cxx
+++ b/test_suite/FGTestApi/TestPilot.cxx
@@ -50,7 +50,7 @@ void TestPilot::resetAtPosition(const SGGeod& pos)
 
 void TestPilot::init()
 {
-        
+    _vspeedFPM = 1200;
 }
 
 void TestPilot::update(double dt)
@@ -98,6 +98,18 @@ void TestPilot::updateValues(double dt)
     double d = _speedKnots * SG_KT_TO_MPS * dt;
     SGGeod newPos = SGGeodesy::direct(currentPos, _trueCourseDeg, d);
     
+    if (_altActive) {
+        if (fabs(_targetAltitudeFt - currentPos.getElevationFt()) < 1) {
+            _altActive = false;
+            newPos.setElevationFt(_targetAltitudeFt);
+        } else {
+            double errorFt = _targetAltitudeFt - currentPos.getElevationFt();
+            double vspeed = std::min(fabs(errorFt),_vspeedFPM * dt / 60.0);
+            double dv = copysign(vspeed, errorFt);
+            newPos.setElevationFt(currentPos.getElevationFt() + dv);
+        }
+    }
+    
     setPosition(newPos);
 }
 
@@ -109,7 +121,14 @@ void TestPilot::setPosition(const SGGeod& pos)
     
     _propRoot->setDoubleValue("orientation/heading-deg", _trueCourseDeg);
     _propRoot->setDoubleValue("velocities/speed-knots", _speedKnots);
+    _propRoot->setDoubleValue("velocities/vertical-fpm", _vspeedFPM);
 
 }
+    
+void TestPilot::setTargetAltitudeFtMSL(double altFt)
+{
+    _targetAltitudeFt = altFt;
+    _altActive = true;
+}
 
 } // of namespace
diff --git a/test_suite/FGTestApi/TestPilot.hxx b/test_suite/FGTestApi/TestPilot.hxx
index 0ec3eebf1..c15b443c7 100644
--- a/test_suite/FGTestApi/TestPilot.hxx
+++ b/test_suite/FGTestApi/TestPilot.hxx
@@ -65,6 +65,7 @@ private:
     double _vspeedFPM = 0.0;
 
     bool _turnActive = false;
+    bool _altActive = false;
     double _targetCourseDeg = 0.0;
     double _targetAltitudeFt = 0.0;
 };
diff --git a/test_suite/FGTestApi/globals.cxx b/test_suite/FGTestApi/globals.cxx
index a6333a918..d66da0d47 100644
--- a/test_suite/FGTestApi/globals.cxx
+++ b/test_suite/FGTestApi/globals.cxx
@@ -17,6 +17,12 @@
 #include <simgear/timing/timestamp.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 
+#include <Airports/airport.hxx>
+#include <Navaids/FlightPlan.hxx>
+#include <Navaids/waypoint.hxx>
+
+using namespace flightgear;
+
 namespace FGTestApi {
 
 namespace setUp {
@@ -57,6 +63,36 @@ void initTestGlobals(const std::string& testName)
     globals->add_subsystem("events", globals->get_event_mgr(), SGSubsystemMgr::DISPLAY);
 }
 
+void populateFP(flightgear::FlightPlanRef f,
+                 const std::string& depICAO, const std::string& depRunway,
+                 const std::string& destICAO, const std::string& destRunway,
+                 const std::string& waypoints)
+{
+    FGAirportRef depApt = FGAirport::getByIdent(depICAO);
+    f->setDeparture(depApt->getRunwayByIdent(depRunway));
+
+
+    FGAirportRef destApt = FGAirport::getByIdent(destICAO);
+    f->setDestination(destApt->getRunwayByIdent(destRunway));
+
+    // since we don't have the Nasal route-manager delegate, insert the
+    // runway waypoints manually
+    
+    f->insertWayptAtIndex(new RunwayWaypt(f->departureRunway(), f), -1);
+    
+    for (auto ws : simgear::strutils::split(waypoints)) {
+        WayptRef wpt = f->waypointFromString(ws);
+        f->insertWayptAtIndex(wpt, -1);
+    }
+    
+  
+    auto destRwy = f->destinationRunway();
+    f->insertWayptAtIndex(new BasicWaypt(destRwy->pointOnCenterline(-8 * SG_NM_TO_METER),
+                                         destRwy->ident() + "-8", f), -1);
+    f->insertWayptAtIndex(new RunwayWaypt(destRwy, f), -1);
+}
+
+
 }  // End of namespace setUp.
 
 void setPosition(const SGGeod& g)
diff --git a/test_suite/FGTestApi/globals.hxx b/test_suite/FGTestApi/globals.hxx
index e3d36489a..933cdaf05 100644
--- a/test_suite/FGTestApi/globals.hxx
+++ b/test_suite/FGTestApi/globals.hxx
@@ -2,15 +2,27 @@
 #define FG_TEST_GLOBALS_HELPERS_HXX
 
 #include <string>
+#include <simgear/structure/SGSharedPtr.hxx>
 
 class SGGeod;
 
+namespace flightgear
+{
+    class FlightPlan;
+    typedef SGSharedPtr<FlightPlan> FlightPlanRef;
+}
+
 namespace FGTestApi {
 
 namespace setUp {
 
 void initTestGlobals(const std::string& testName);
 
+    void populateFP(flightgear::FlightPlanRef f,
+                const std::string& depICAO, const std::string& depRunway,
+                const std::string& destICAO, const std::string& destRunway,
+                const std::string& waypoints);
+    
 }  // End of namespace setUp.
 
 void setPosition(const SGGeod& g);
diff --git a/test_suite/unit_tests/Instrumentation/test_gps.cxx b/test_suite/unit_tests/Instrumentation/test_gps.cxx
index fd118db03..39f180361 100644
--- a/test_suite/unit_tests/Instrumentation/test_gps.cxx
+++ b/test_suite/unit_tests/Instrumentation/test_gps.cxx
@@ -29,10 +29,42 @@
 #include <Navaids/NavDataCache.hxx>
 #include <Navaids/navrecord.hxx>
 #include <Navaids/navlist.hxx>
+#include <Navaids/FlightPlan.hxx>
 
 #include <Instrumentation/gps.hxx>
 #include <Instrumentation/navradio.hxx>
 
+#include <Autopilot/route_mgr.hxx>
+
+using namespace flightgear;
+
+/////////////////////////////////////////////////////////////////////////////
+
+class TestFPDelegate : public FlightPlan::Delegate
+{
+public:
+    FlightPlanRef thePlan;
+    int sequenceCount = 0;
+    
+    void sequence() override
+    {
+        ++sequenceCount;
+        int newIndex = thePlan->currentIndex() + 1;
+        if (newIndex >= thePlan->numLegs()) {
+            thePlan->finish();
+            return;
+        }
+        
+        thePlan->setCurrentIndex(newIndex);
+    }
+    
+    void currentWaypointChanged() override
+    {
+    }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
 // Set up function for each test.
 void GPSTests::setUp()
 {
@@ -75,6 +107,16 @@ GPS* GPSTests::setupStandardGPS(SGPropertyNode_ptr config,
     return gps;
 }
 
+void GPSTests::setupRouteManager()
+{
+    auto rm = globals->add_new_subsystem<FGRouteMgr>();
+    rm->bind();
+    rm->init();
+    rm->postinit();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
 void GPSTests::testBasic()
 {
     auto gps = setupStandardGPS();
@@ -187,8 +229,115 @@ void GPSTests::testNavRadioSlave()
     std::unique_ptr<FGNavRadio> r(new FGNavRadio(radioConfigNode));
 }
 
-void GPSTests::testConfigAutopilotDrive()
+void GPSTests::testLegMode()
 {
+    setupRouteManager();
+    auto rm = globals->get_subsystem<FGRouteMgr>();
+    
+    auto fp = new FlightPlan;
+    rm->setFlightPlan(fp);
+    FGTestApi::setUp::populateFP(fp, "EBBR", "07L", "EGGD", "27",
+                                   "NIK COA DVR TAWNY WOD");
+    
+    // takes the place of the Nasal delegates
+    auto testDelegate = new TestFPDelegate;
+    testDelegate->thePlan = fp;
+    
+    CPPUNIT_ASSERT(rm->activate());
+    
+    fp->addDelegate(testDelegate);
+    auto gps = setupStandardGPS();
+    
+    setPositionAndStabilise(gps, fp->departureRunway()->pointOnCenterline(0.0));
+
+    auto gpsNode = globals->get_props()->getNode("instrumentation/gps");
+    gpsNode->setStringValue("command", "leg");
+
+    CPPUNIT_ASSERT_EQUAL(std::string{"leg"}, std::string{gpsNode->getStringValue("mode")});
+    CPPUNIT_ASSERT_EQUAL(std::string{"EBBR-07L"}, std::string{gpsNode->getStringValue("wp/wp[1]/ID")});
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(65.0, gpsNode->getDoubleValue("wp/wp[1]/bearing-true-deg"), 0.5);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(65.0, gpsNode->getDoubleValue("desired-course-deg"), 0.5);
+    
+    auto pilot = SGSharedPtr<FGTestApi::TestPilot>(new FGTestApi::TestPilot);
+    pilot->setSpeedKts(200);
+    pilot->setCourseTrue(65.0);
+    pilot->setTargetAltitudeFtMSL(6000);
+    FGTestApi::runForTime(60.0);
+
+    // check we sequenced to NIK
+    CPPUNIT_ASSERT_EQUAL(1, testDelegate->sequenceCount);
+    CPPUNIT_ASSERT_EQUAL(1, fp->currentIndex());
+
+    CPPUNIT_ASSERT_EQUAL(std::string{"EBBR-07L"}, std::string{gpsNode->getStringValue("wp/wp[0]/ID")});
+    CPPUNIT_ASSERT_EQUAL(std::string{"NIK"}, std::string{gpsNode->getStringValue("wp/wp[1]/ID")});
+    
+    // reposition along the leg, closer to NIK
+    // and fly to COA
+    
+    SGGeod nikPos = fp->currentLeg()->waypoint()->position();
+    SGGeod p2 = SGGeodesy::direct(nikPos, 90, 5 * SG_NM_TO_METER); // due east of NIK
+    setPositionAndStabilise(gps, p2);
+    
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(270, gpsNode->getDoubleValue("wp/wp[1]/bearing-true-deg"), 0.5);
+
+    auto depRwy = fp->departureRunway();
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(SGGeodesy::distanceNm(nikPos, depRwy->end()), gpsNode->getDoubleValue("wp/leg-distance-nm"), 0.1);
+    const double legCourse = SGGeodesy::courseDeg(depRwy->end(), nikPos);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(legCourse, gpsNode->getDoubleValue("wp/leg-true-course-deg"), 0.5);
+    
+    //CPPUNIT_ASSERT_DOUBLES_EQUAL(legCourse - 270, gpsNode->getDoubleValue("wp/wp[1]/course-deviation-deg"), 0.5);
+
+    
+    pilot->setSpeedKts(200);
+    pilot->setCourseTrue(270);
+    FGTestApi::runForTime(120.0);
+
+    
+    CPPUNIT_ASSERT_EQUAL(2, testDelegate->sequenceCount);
+    CPPUNIT_ASSERT_EQUAL(2, fp->currentIndex());
+    CPPUNIT_ASSERT_EQUAL(std::string{"NIK"}, std::string{gpsNode->getStringValue("wp/wp[0]/ID")});
+    CPPUNIT_ASSERT_EQUAL(std::string{"COA"}, std::string{gpsNode->getStringValue("wp/wp[1]/ID")});
+    
+    SGGeod coaPos = fp->currentLeg()->waypoint()->position();
+    
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(SGGeodesy::distanceNm(nikPos, coaPos), gpsNode->getDoubleValue("wp/leg-distance-nm"), 0.1);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(SGGeodesy::courseDeg(nikPos, coaPos), gpsNode->getDoubleValue("wp/leg-true-course-deg"), 0.5);
+    
+    // check manual sequencing
+    fp->setCurrentIndex(3);
+    CPPUNIT_ASSERT_EQUAL(std::string{"COA"}, std::string{gpsNode->getStringValue("wp/wp[0]/ID")});
+    CPPUNIT_ASSERT_EQUAL(std::string{"DVR"}, std::string{gpsNode->getStringValue("wp/wp[1]/ID")});
+    
+    // check course deviation / cross-track error
+    SGGeod doverPos = fp->currentLeg()->waypoint()->position();
+    double course = SGGeodesy::courseDeg(coaPos, doverPos);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(course, gpsNode->getDoubleValue("wp/leg-true-course-deg"), 0.5);
+    
+    SGGeod off1 = SGGeodesy::direct(coaPos, course + 5.0, 8 * SG_NM_TO_METER);
+    setPositionAndStabilise(gps, off1);
+    
+    double courseToDover = SGGeodesy::courseDeg(off1, doverPos);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(courseToDover, gpsNode->getDoubleValue("wp/wp[1]/bearing-true-deg"), 0.5);
+
+    // right of the desired course, negative sign, ho hum
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(-5.0, gpsNode->getDoubleValue("wp/wp[1]/course-deviation-deg"), 0.5);
+    CPPUNIT_ASSERT_EQUAL(true, gpsNode->getBoolValue("wp/wp[1]/to-flag"));
+    CPPUNIT_ASSERT_EQUAL(false, gpsNode->getBoolValue("wp/wp[1]/from-flag"));
+    
+    SGGeod off2 = SGGeodesy::direct(doverPos, course - 5.0, -18 * SG_NM_TO_METER);
+    setPositionAndStabilise(gps, off2);
+    
+    courseToDover = SGGeodesy::courseDeg(off2, doverPos);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(courseToDover, gpsNode->getDoubleValue("wp/wp[1]/bearing-true-deg"), 0.5);
+    // disabled becuase GPS course deviation is using from the FROM wp, when
+    // it should be using the TO point (DVR in this case)
+#if 0
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0, gpsNode->getDoubleValue("wp/wp[1]/course-deviation-deg"), 0.5);
+#endif
+    CPPUNIT_ASSERT_EQUAL(true, gpsNode->getBoolValue("wp/wp[1]/to-flag"));
+    CPPUNIT_ASSERT_EQUAL(false, gpsNode->getBoolValue("wp/wp[1]/from-flag"));
 }
 
 void GPSTests::testTurnAnticipation()
diff --git a/test_suite/unit_tests/Instrumentation/test_gps.hxx b/test_suite/unit_tests/Instrumentation/test_gps.hxx
index fe039e64a..4e51b485c 100644
--- a/test_suite/unit_tests/Instrumentation/test_gps.hxx
+++ b/test_suite/unit_tests/Instrumentation/test_gps.hxx
@@ -39,10 +39,10 @@ class GPSTests : public CppUnit::TestFixture
     CPPUNIT_TEST_SUITE(GPSTests);
     CPPUNIT_TEST(testBasic);
     CPPUNIT_TEST(testNavRadioSlave);
-    CPPUNIT_TEST(testConfigAutopilotDrive);
     CPPUNIT_TEST(testTurnAnticipation);
     CPPUNIT_TEST(testOBSMode);
     CPPUNIT_TEST(testDirectTo);
+    CPPUNIT_TEST(testLegMode);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -50,7 +50,8 @@ class GPSTests : public CppUnit::TestFixture
 
     GPS* setupStandardGPS(SGPropertyNode_ptr config = {},
                                           const std::string name = "gps", const int index = 0);
-
+    void setupRouteManager();
+    
 public:
     // Set up function for each test.
     void setUp();
@@ -61,10 +62,10 @@ public:
     // The tests.
     void testBasic();
     void testNavRadioSlave();
-    void testConfigAutopilotDrive();
     void testTurnAnticipation();
     void testOBSMode();
     void testDirectTo();
+    void testLegMode();
 };
 
 #endif  // _FG_GPS_UNIT_TESTS_HXX
diff --git a/test_suite/unit_tests/Navaids/test_flightplan.cxx b/test_suite/unit_tests/Navaids/test_flightplan.cxx
index 70ae082dc..0e3571c71 100644
--- a/test_suite/unit_tests/Navaids/test_flightplan.cxx
+++ b/test_suite/unit_tests/Navaids/test_flightplan.cxx
@@ -33,25 +33,12 @@ void FlightplanTests::tearDown()
     FGTestApi::tearDown::shutdownTestGlobals();
 }
 
-
-FlightPlanRef makeTestFP(const std::string& depICAO, const std::string& depRunway,
+static FlightPlanRef makeTestFP(const std::string& depICAO, const std::string& depRunway,
                          const std::string& destICAO, const std::string& destRunway,
                          const std::string& waypoints)
 {
     FlightPlanRef f = new FlightPlan;
-
-    FGAirportRef depApt = FGAirport::getByIdent(depICAO);
-    f->setDeparture(depApt->getRunwayByIdent(depRunway));
-
-
-    FGAirportRef destApt = FGAirport::getByIdent(destICAO);
-    f->setDestination(destApt->getRunwayByIdent(destRunway));
-
-    for (auto ws : simgear::strutils::split(waypoints)) {
-        WayptRef wpt = f->waypointFromString(ws);
-        f->insertWayptAtIndex(wpt, -1);
-    }
-
+    FGTestApi::setUp::populateFPWithoutNasal(f, depICAO, depRunway, destICAO, destRunway, waypoints);
     return f;
 }
 
@@ -67,13 +54,18 @@ void FlightplanTests::testBasic()
     CPPUNIT_ASSERT(fp1->destinationAirport()->ident() == "EHAM");
     CPPUNIT_ASSERT(fp1->destinationRunway()->ident() == "24");
 
-    CPPUNIT_ASSERT_EQUAL(fp1->numLegs(), 2);
+    CPPUNIT_ASSERT_EQUAL(fp1->numLegs(), 5);
 
-    CPPUNIT_ASSERT(fp1->legAtIndex(0)->waypoint()->source()->ident() == "TNT");
-    CPPUNIT_ASSERT(fp1->legAtIndex(0)->waypoint()->source()->name() == "TRENT VOR-DME");
+    CPPUNIT_ASSERT(fp1->legAtIndex(0)->waypoint()->source()->ident() == "23L");
+    
+    CPPUNIT_ASSERT(fp1->legAtIndex(1)->waypoint()->source()->ident() == "TNT");
+    CPPUNIT_ASSERT(fp1->legAtIndex(1)->waypoint()->source()->name() == "TRENT VOR-DME");
+
+    CPPUNIT_ASSERT(fp1->legAtIndex(2)->waypoint()->source()->ident() == "CLN");
+    CPPUNIT_ASSERT(fp1->legAtIndex(2)->waypoint()->source()->name() == "CLACTON VOR-DME");
+    
+    CPPUNIT_ASSERT(fp1->legAtIndex(4)->waypoint()->source()->ident() == "24");
 
-    CPPUNIT_ASSERT(fp1->legAtIndex(1)->waypoint()->source()->ident() == "CLN");
-    CPPUNIT_ASSERT(fp1->legAtIndex(1)->waypoint()->source()->name() == "CLACTON VOR-DME");
 }
 
 void FlightplanTests::testRoutePathBasic()
@@ -103,8 +95,8 @@ void FlightplanTests::testRoutePathBasic()
     double distM = SGGeodesy::distanceM(bne->geod(), civ->geod());
     double trackDeg = SGGeodesy::courseDeg(bne->geod(), civ->geod());
 
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(trackDeg, rtepath.trackForIndex(3), 0.5);
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(distM, rtepath.distanceForIndex(3), 2000); // 2km precision, allow for turns
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(trackDeg, rtepath.trackForIndex(4), 0.5);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(distM, rtepath.distanceForIndex(4), 2000); // 2km precision, allow for turns
 
 }
 
@@ -120,16 +112,16 @@ void FlightplanTests::testRoutePathSkipped()
     RoutePath rtepath(fp1);
 
     // skipped point uses inbound track
-    CPPUNIT_ASSERT_EQUAL(rtepath.trackForIndex(3), rtepath.trackForIndex(4));
+    CPPUNIT_ASSERT_EQUAL(rtepath.trackForIndex(4), rtepath.trackForIndex(5));
 
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, rtepath.distanceForIndex(4), 1e-9);
     CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, rtepath.distanceForIndex(5), 1e-9);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, rtepath.distanceForIndex(6), 1e-9);
 
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(101000, rtepath.distanceForIndex(6), 1000);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(101000, rtepath.distanceForIndex(7), 1000);
 
 
     // this tests skipping two preceeding points works as it should
-    SGGeodVec vec = rtepath.pathForIndex(6);
+    SGGeodVec vec = rtepath.pathForIndex(7);
     CPPUNIT_ASSERT(vec.size() == 9);
 }
 
@@ -147,7 +139,33 @@ void FlightplanTests::testRoutePathTrivialFlightPlan()
         rtepath.distanceForIndex(leg);
     }
 
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, fp1->totalDistanceNm(), 1e-9);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(19.68, fp1->totalDistanceNm(), 0.1);
+}
+
+void FlightplanTests::testRoutePathVec()
+{
+    FlightPlanRef fp1 = makeTestFP("KNUQ", "14L", "PHNL", "22R",
+                                   "ROKME WOVAB");
+    RoutePath rtepath(fp1);
+    
+    SGGeodVec vec = rtepath.pathForIndex(0);
+    
+    FGAirportRef ksfo = FGAirport::findByIdent("KSFO");
+    FGFixRef rokme = fgpositioned_cast<FGFix>(FGPositioned::findClosestWithIdent("ROKME", ksfo->geod()));
+    auto depRwy = fp1->departureRunway();
+    
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(depRwy->geod().getLongitudeDeg(), vec.front().getLongitudeDeg(), 0.01);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(depRwy->geod().getLatitudeDeg(), vec.front().getLatitudeDeg(), 0.01);
+    
+    SGGeodVec vec1 = rtepath.pathForIndex(1);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(rokme->geod().getLongitudeDeg(), vec1.back().getLongitudeDeg(), 0.01);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(rokme->geod().getLatitudeDeg(), vec1.back().getLatitudeDeg(), 0.01);
+    
+    SGGeodVec vec2 = rtepath.pathForIndex(2);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(rokme->geod().getLongitudeDeg(), vec2.front().getLongitudeDeg(), 0.01);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(rokme->geod().getLatitudeDeg(), vec2.front().getLatitudeDeg(), 0.01);
+    
+    //CPPUNIT_ASSERT(vec.front()
 }
 
 void FlightplanTests::testRoutPathWpt0Midflight()
@@ -157,6 +175,9 @@ void FlightplanTests::testRoutPathWpt0Midflight()
     
     FlightPlanRef fp1 = makeTestFP("KNUQ", "14L", "PHNL", "22R",
                                    "ROKME WOVAB");
+    // actually delete leg 0 so we start at ROKME
+    fp1->deleteIndex(0);
+    
     RoutePath rtepath(fp1);
     
     SGGeodVec vec = rtepath.pathForIndex(0);
diff --git a/test_suite/unit_tests/Navaids/test_flightplan.hxx b/test_suite/unit_tests/Navaids/test_flightplan.hxx
index 80153a749..a52df3fb8 100644
--- a/test_suite/unit_tests/Navaids/test_flightplan.hxx
+++ b/test_suite/unit_tests/Navaids/test_flightplan.hxx
@@ -39,6 +39,7 @@ class FlightplanTests : public CppUnit::TestFixture
     CPPUNIT_TEST(testAirwayNetworkRoute);
     CPPUNIT_TEST(testBug1814);
     CPPUNIT_TEST(testRoutPathWpt0Midflight);
+    CPPUNIT_TEST(testRoutePathVec);
     
   //  CPPUNIT_TEST(testParseICAORoute);
    // CPPUNIT_TEST(testParseICANLowLevelRoute);
@@ -62,6 +63,7 @@ public:
     void testParseICANLowLevelRoute();
     void testBug1814();
     void testRoutPathWpt0Midflight();
+    void testRoutePathVec();
 };
 
 #endif  // FG_FLIGHTPLAN_UNIT_TESTS_HXX