Merge pull request #485 from gardster/routing_rebuild_fix

Routing rebuild fix
This commit is contained in:
Viktor Govako 2015-11-10 13:35:10 +03:00
commit 6c0b2ad25e
7 changed files with 125 additions and 10 deletions

View file

@ -2325,7 +2325,8 @@ void Framework::CheckLocationForRouting(GpsInfo const & info)
GetPlatform().RunOnGuiThread(bind(&Framework::InsertRoute, this, route));
};
m_routingSession.RebuildRoute(position, readyCallback, m_progressCallback, 0 /* timeoutSec */);
m_routingSession.RebuildRoute(MercatorBounds::FromLatLon(info.m_latitude, info.m_longitude),
readyCallback, m_progressCallback, 0 /* timeoutSec */);
}
}

View file

@ -228,12 +228,6 @@ bool Route::MoveIterator(location::GpsInfo const & info) const
return res.IsValid();
}
double Route::GetCurrentSqDistance(m2::PointD const & pt) const
{
ASSERT(m_poly.IsValid(), ());
return pt.SquareLength(m_poly.GetCurrentIter().m_pt);
}
double Route::GetPolySegAngle(size_t ind) const
{
size_t const polySz = m_poly.GetPolyline().GetSize();

View file

@ -94,8 +94,6 @@ public:
/// @return true If position was updated successfully (projection within gps error radius).
bool MoveIterator(location::GpsInfo const & info) const;
/// Square distance to current projection in mercator.
double GetCurrentSqDistance(m2::PointD const & pt) const;
void MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo) const;
bool IsCurrentOnEnd() const;

View file

@ -200,7 +200,8 @@ RoutingSession::State RoutingSession::OnLocationPositionChanged(m2::PointD const
{
// Distance from the last known projection on route
// (check if we are moving far from the last known projection).
double const dist = m_route.GetCurrentSqDistance(position);
double const dist = MercatorBounds::DistanceOnEarth(m_route.GetFollowedPolyline().GetCurrentIter().m_pt,
MercatorBounds::FromLatLon(info.m_latitude, info.m_longitude));
if (my::AlmostEqualAbs(dist, m_lastDistance, kRunawayDistanceSensitivityMeters))
return m_state;
if (dist > m_lastDistance)

View file

@ -0,0 +1,119 @@
#include "testing/testing.hpp"
#include "routing/route.hpp"
#include "routing/router.hpp"
#include "routing/routing_session.hpp"
#include "geometry/point2d.hpp"
#include "base/logging.hpp"
#include "std/chrono.hpp"
#include "std/mutex.hpp"
#include "std/string.hpp"
#include "std/vector.hpp"
namespace routing
{
// Simple router. It returns route given to him on creation.
class DummyRouter : public IRouter
{
private:
Route & m_route;
ResultCode m_code;
size_t & m_buildCount;
public:
DummyRouter(Route & route, ResultCode code, size_t & buildCounter)
: m_route(route), m_code(code), m_buildCount(buildCounter)
{
}
string GetName() const override { return "dummy"; }
void ClearState() override {}
ResultCode CalculateRoute(m2::PointD const & /* startPoint */,
m2::PointD const & /* startDirection */,
m2::PointD const & /* finalPoint */,
RouterDelegate const & /* delegate */, Route & route) override
{
++m_buildCount;
route = m_route;
return m_code;
}
};
static vector<m2::PointD> kTestRoute = {{0., 1.}, {0., 2.}, {0., 3.}, {0., 4.}};
static auto kRouteBuildingMaxDuration = seconds(30);
UNIT_TEST(TestRouteBuilding)
{
RoutingSession session;
session.Init(nullptr, nullptr);
vector<m2::PointD> routePoints = kTestRoute;
Route masterRoute("dummy", routePoints.begin(), routePoints.end());
size_t counter = 0;
timed_mutex routeBuilded;
routeBuilded.lock();
unique_ptr<DummyRouter> router = make_unique<DummyRouter>(masterRoute, DummyRouter::NoError, counter);
session.SetRouter(move(router), nullptr);
session.BuildRoute(kTestRoute.front(), kTestRoute.back(),
[&routeBuilded](Route const &, IRouter::ResultCode)
{
routeBuilded.unlock();
},
nullptr, 0);
TEST(routeBuilded.try_lock_for(kRouteBuildingMaxDuration), ());
TEST_EQUAL(counter, 1, ());
}
UNIT_TEST(TestRouteRebuilding)
{
Index index;
RoutingSession session;
session.Init(nullptr, nullptr);
vector<m2::PointD> routePoints = kTestRoute;
Route masterRoute("dummy", routePoints.begin(), routePoints.end());
size_t counter = 0;
timed_mutex routeBuilded;
auto fn = [&routeBuilded](Route const &, IRouter::ResultCode)
{
routeBuilded.unlock();
};
routeBuilded.lock();
unique_ptr<DummyRouter> router = make_unique<DummyRouter>(masterRoute, DummyRouter::NoError, counter);
session.SetRouter(move(router), nullptr);
// Go along the route.
session.BuildRoute(kTestRoute.front(), kTestRoute.back(), fn, nullptr, 0);
TEST(routeBuilded.try_lock_for(kRouteBuildingMaxDuration), ());
location::GpsInfo info;
info.m_horizontalAccuracy = 0.01;
info.m_verticalAccuracy = 0.01;
info.m_longitude = 0.;
info.m_latitude = 1.;
RoutingSession::State code;
while (info.m_latitude < kTestRoute.back().y)
{
code = session.OnLocationPositionChanged(
MercatorBounds::FromLatLon(info.m_latitude, info.m_longitude), info, index);
TEST_EQUAL(code, RoutingSession::State::OnRoute, ());
info.m_latitude += 0.01;
}
TEST_EQUAL(counter, 1, ());
// Rebuild route and go in opposite direction. So initiate a route rebuilding flag.
counter = 0;
session.BuildRoute(kTestRoute.front(), kTestRoute.back(), fn, nullptr, 0);
TEST(routeBuilded.try_lock_for(kRouteBuildingMaxDuration), ());
info.m_longitude = 0.;
info.m_latitude = 1.;
for (size_t i = 0; i < 10; ++i)
{
code = session.OnLocationPositionChanged(
MercatorBounds::FromLatLon(info.m_latitude, info.m_longitude), info, index);
info.m_latitude -= 0.1;
}
TEST_EQUAL(code, RoutingSession::State::RouteNeedRebuild, ());
}
} // namespace routing

View file

@ -34,6 +34,7 @@ SOURCES += \
road_graph_nearest_edges_test.cpp \
route_tests.cpp \
routing_mapping_test.cpp \
routing_session_test.cpp \
turns_generator_test.cpp \
turns_sound_test.cpp \
turns_tts_text_tests.cpp \

View file

@ -8,6 +8,7 @@
using std::lock_guard;
using std::mutex;
using std::timed_mutex;
using std::unique_lock;
#ifdef DEBUG_NEW