|
|
|
@ -3,19 +3,16 @@
|
|
|
|
|
#include "routing_common/car_model_coefs.hpp"
|
|
|
|
|
#include "routing_common/maxspeed_conversion.hpp"
|
|
|
|
|
#include "routing_common/vehicle_model.hpp"
|
|
|
|
|
#include "routing_common/car_model.hpp"
|
|
|
|
|
|
|
|
|
|
#include "indexer/classificator.hpp"
|
|
|
|
|
#include "indexer/classificator_loader.hpp"
|
|
|
|
|
#include "indexer/feature.hpp"
|
|
|
|
|
#include "indexer/feature_data.hpp"
|
|
|
|
|
|
|
|
|
|
#include "platform/measurement_utils.hpp"
|
|
|
|
|
|
|
|
|
|
#include "base/macros.hpp"
|
|
|
|
|
#include "base/math.hpp"
|
|
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
namespace vehicle_model_test
|
|
|
|
|
{
|
|
|
|
|
using namespace routing;
|
|
|
|
@ -54,52 +51,53 @@ VehicleModel::SurfaceInitList const kCarSurface = {
|
|
|
|
|
class VehicleModelTest
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
VehicleModelTest() { classificator::Load(); }
|
|
|
|
|
VehicleModelTest()
|
|
|
|
|
{
|
|
|
|
|
classificator::Load();
|
|
|
|
|
auto const & c = classif();
|
|
|
|
|
|
|
|
|
|
primary = c.GetTypeByPath({"highway", "primary"});
|
|
|
|
|
secondary = c.GetTypeByPath({"highway", "secondary"});
|
|
|
|
|
secondaryBridge = c.GetTypeByPath({"highway", "secondary", "bridge"});
|
|
|
|
|
secondaryTunnel = c.GetTypeByPath({"highway", "secondary", "tunnel"});
|
|
|
|
|
residential = c.GetTypeByPath({"highway", "residential"});
|
|
|
|
|
|
|
|
|
|
oneway = c.GetTypeByPath({"hwtag", "oneway"});
|
|
|
|
|
pavedGood = c.GetTypeByPath({"psurface", "paved_good"});
|
|
|
|
|
pavedBad = c.GetTypeByPath({"psurface", "paved_bad"});
|
|
|
|
|
unpavedGood = c.GetTypeByPath({"psurface", "unpaved_good"});
|
|
|
|
|
unpavedBad = c.GetTypeByPath({"psurface", "unpaved_bad"});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t primary, secondary, secondaryTunnel, secondaryBridge, residential;
|
|
|
|
|
uint32_t oneway, pavedGood, pavedBad, unpavedGood, unpavedBad;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class TestVehicleModel : public VehicleModel
|
|
|
|
|
class VehicleModelStub : public VehicleModel
|
|
|
|
|
{
|
|
|
|
|
friend void CheckOneWay(initializer_list<uint32_t> const & types, bool expectedValue);
|
|
|
|
|
friend void CheckPassThroughAllowed(initializer_list<uint32_t> const & types, bool expectedValue);
|
|
|
|
|
friend void CheckSpeedWithParams(initializer_list<uint32_t> const & types,
|
|
|
|
|
SpeedParams const & params, SpeedKMpH const & expectedSpeed);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
TestVehicleModel()
|
|
|
|
|
VehicleModelStub()
|
|
|
|
|
: VehicleModel(classif(), kTestLimits, kCarSurface, {kDefaultSpeeds, kDefaultFactors})
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We are not going to use offroad routing in these tests.
|
|
|
|
|
SpeedKMpH const & GetOffroadSpeed() const override { return kDummy; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
static SpeedKMpH const kDummy;
|
|
|
|
|
SpeedKMpH const & GetOffroadSpeed() const override
|
|
|
|
|
{
|
|
|
|
|
static SpeedKMpH offroad{0.0 /* weight */, 0.0 /* eta */};
|
|
|
|
|
return offroad;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
SpeedKMpH const TestVehicleModel::kDummy = {0.0 /* weight */, 0.0 /* eta */};
|
|
|
|
|
|
|
|
|
|
uint32_t GetType(char const * s0, char const * s1 = 0, char const * s2 = 0)
|
|
|
|
|
{
|
|
|
|
|
char const * const t[] = {s0, s1, s2};
|
|
|
|
|
size_t const size = (s0 != 0) + size_t(s1 != 0) + size_t(s2 != 0);
|
|
|
|
|
return classif().GetTypeByPath(vector<string>(t, t + size));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t GetOnewayType()
|
|
|
|
|
{
|
|
|
|
|
return GetType("hwtag", "oneway");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CheckSpeedWithParams(initializer_list<uint32_t> const & types, SpeedParams const & params,
|
|
|
|
|
SpeedKMpH const & expectedSpeed)
|
|
|
|
|
{
|
|
|
|
|
TestVehicleModel vehicleModel;
|
|
|
|
|
VehicleModelStub model;
|
|
|
|
|
feature::TypesHolder h;
|
|
|
|
|
for (uint32_t t : types)
|
|
|
|
|
h.Add(t);
|
|
|
|
|
|
|
|
|
|
TEST_EQUAL(vehicleModel.GetTypeSpeed(h, params), expectedSpeed, ());
|
|
|
|
|
TEST_EQUAL(model.GetTypeSpeed(h, params), expectedSpeed, ());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CheckSpeed(initializer_list<uint32_t> const & types, InOutCitySpeedKMpH const & expectedSpeed)
|
|
|
|
@ -112,98 +110,81 @@ void CheckSpeed(initializer_list<uint32_t> const & types, InOutCitySpeedKMpH con
|
|
|
|
|
|
|
|
|
|
void CheckOneWay(initializer_list<uint32_t> const & types, bool expectedValue)
|
|
|
|
|
{
|
|
|
|
|
TestVehicleModel vehicleModel;
|
|
|
|
|
VehicleModelStub model;
|
|
|
|
|
feature::TypesHolder h;
|
|
|
|
|
for (uint32_t t : types)
|
|
|
|
|
h.Add(t);
|
|
|
|
|
|
|
|
|
|
TEST_EQUAL(vehicleModel.HasOneWayType(h), expectedValue, ());
|
|
|
|
|
TEST_EQUAL(model.HasOneWayType(h), expectedValue, ());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CheckPassThroughAllowed(initializer_list<uint32_t> const & types, bool expectedValue)
|
|
|
|
|
{
|
|
|
|
|
TestVehicleModel vehicleModel;
|
|
|
|
|
VehicleModelStub model;
|
|
|
|
|
feature::TypesHolder h;
|
|
|
|
|
for (uint32_t t : types)
|
|
|
|
|
h.Add(t);
|
|
|
|
|
|
|
|
|
|
TEST_EQUAL(vehicleModel.HasPassThroughType(h), expectedValue, ());
|
|
|
|
|
TEST_EQUAL(model.HasPassThroughType(h), expectedValue, ());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxSpeed)
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelStub, MaxSpeed)
|
|
|
|
|
{
|
|
|
|
|
TestVehicleModel vehicleModel;
|
|
|
|
|
TEST_EQUAL(vehicleModel.GetMaxWeightSpeed(), 150.0, ());
|
|
|
|
|
TEST_EQUAL(GetMaxWeightSpeed(), 150.0, ());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed)
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, Speed)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
CheckSpeed({GetType("highway", "secondary", "bridge")}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({GetType("highway", "secondary", "tunnel")}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({GetType("highway", "secondary")}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({secondaryBridge}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({secondaryTunnel}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({secondary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CheckSpeed({GetType("highway", "trunk")},
|
|
|
|
|
CheckSpeed({classif().GetTypeByPath({"highway", "trunk"})},
|
|
|
|
|
{SpeedKMpH(100.0 /* weight */, 100.0 /* eta */) /* in city */,
|
|
|
|
|
SpeedKMpH(150.0 /* weight */, 150.0 /* eta */) /* out of city */});
|
|
|
|
|
CheckSpeed({GetType("highway", "primary")}, {SpeedKMpH(90.0, 90.0), SpeedKMpH(120.0, 120.0)});
|
|
|
|
|
CheckSpeed({GetType("highway", "residential")}, {SpeedKMpH(22.5, 27.5), SpeedKMpH(25.0, 30.0)});
|
|
|
|
|
CheckSpeed({primary}, {SpeedKMpH(90.0, 90.0), SpeedKMpH(120.0, 120.0)});
|
|
|
|
|
CheckSpeed({residential}, {SpeedKMpH(22.5, 27.5), SpeedKMpH(25.0, 30.0)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed_MultiTypes)
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, Speed_MultiTypes)
|
|
|
|
|
{
|
|
|
|
|
uint32_t const typeTunnel = GetType("highway", "secondary", "tunnel");
|
|
|
|
|
uint32_t const typeSecondary = GetType("highway", "secondary");
|
|
|
|
|
uint32_t const typeHighway = GetType("highway");
|
|
|
|
|
uint32_t const typeHighway = classif().GetTypeByPath({"highway"});
|
|
|
|
|
|
|
|
|
|
CheckSpeed({typeTunnel, typeSecondary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({typeTunnel, typeHighway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({typeHighway, typeTunnel}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({secondaryTunnel, secondary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({secondaryTunnel, typeHighway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({typeHighway, secondaryTunnel}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_OneWay)
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, OneWay)
|
|
|
|
|
{
|
|
|
|
|
uint32_t const typeBridge = GetType("highway", "secondary", "bridge");
|
|
|
|
|
uint32_t const typeOneway = GetOnewayType();
|
|
|
|
|
CheckSpeed({secondaryBridge, oneway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckOneWay({secondaryBridge, oneway}, true);
|
|
|
|
|
CheckSpeed({oneway, secondaryBridge}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckOneWay({oneway, secondaryBridge}, true);
|
|
|
|
|
|
|
|
|
|
CheckSpeed({typeBridge, typeOneway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckOneWay({typeBridge, typeOneway}, true);
|
|
|
|
|
CheckSpeed({typeOneway, typeBridge}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckOneWay({typeOneway, typeBridge}, true);
|
|
|
|
|
|
|
|
|
|
CheckOneWay({typeOneway}, true);
|
|
|
|
|
CheckOneWay({oneway}, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_DifferentSpeeds)
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, DifferentSpeeds)
|
|
|
|
|
{
|
|
|
|
|
uint32_t const typeSecondary = GetType("highway", "secondary");
|
|
|
|
|
uint32_t const typePrimary = GetType("highway", "primary");
|
|
|
|
|
uint32_t const typeOneway = GetOnewayType();
|
|
|
|
|
|
|
|
|
|
CheckSpeed({typeSecondary, typePrimary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
|
|
|
|
|
CheckSpeed({typeSecondary, typePrimary, typeOneway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckOneWay({typePrimary, typeOneway, typeSecondary}, true);
|
|
|
|
|
// What is the purpose of this artificial test with several highway types? To show that order is important?
|
|
|
|
|
CheckSpeed({secondary, primary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
|
|
|
|
CheckSpeed({oneway, primary, secondary}, kDefaultSpeeds.Get(HighwayType::HighwayPrimary));
|
|
|
|
|
CheckOneWay({primary, oneway, secondary}, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_PassThroughAllowed)
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, PassThroughAllowed)
|
|
|
|
|
{
|
|
|
|
|
CheckPassThroughAllowed({GetType("highway", "secondary")}, true);
|
|
|
|
|
CheckPassThroughAllowed({GetType("highway", "primary")}, true);
|
|
|
|
|
CheckPassThroughAllowed({GetType("highway", "service")}, false);
|
|
|
|
|
CheckPassThroughAllowed({secondary}, true);
|
|
|
|
|
CheckPassThroughAllowed({primary}, true);
|
|
|
|
|
CheckPassThroughAllowed({classif().GetTypeByPath({"highway", "service"})}, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_SpeedFactor)
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, SpeedFactor)
|
|
|
|
|
{
|
|
|
|
|
uint32_t const secondary = GetType("highway", "secondary");
|
|
|
|
|
uint32_t const residential = GetType("highway", "residential");
|
|
|
|
|
uint32_t const pavedGood = GetType("psurface", "paved_good");
|
|
|
|
|
uint32_t const pavedBad = GetType("psurface", "paved_bad");
|
|
|
|
|
uint32_t const unpavedGood = GetType("psurface", "unpaved_good");
|
|
|
|
|
uint32_t const unpavedBad = GetType("psurface", "unpaved_bad");
|
|
|
|
|
|
|
|
|
|
CheckSpeed({secondary, pavedGood},
|
|
|
|
|
{SpeedKMpH(64.0 /* weight */, 63.0 /* eta */) /* in city */,
|
|
|
|
|
SpeedKMpH(64.0 /* weight */, 63.0 /* eta */) /* out of city */});
|
|
|
|
@ -217,14 +198,8 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_SpeedFactor)
|
|
|
|
|
CheckSpeed({residential, unpavedBad}, {SpeedKMpH(4.5, 5.5), SpeedKMpH(5.0, 6.0)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxspeedFactor)
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, MaxspeedFactor)
|
|
|
|
|
{
|
|
|
|
|
uint32_t const secondary = GetType("highway", "secondary");
|
|
|
|
|
uint32_t const residential = GetType("highway", "residential");
|
|
|
|
|
uint32_t const primary = GetType("highway", "primary");
|
|
|
|
|
uint32_t const pavedGood = GetType("psurface", "paved_good");
|
|
|
|
|
uint32_t const unpavedBad = GetType("psurface", "unpaved_bad");
|
|
|
|
|
|
|
|
|
|
Maxspeed const maxspeed90 =
|
|
|
|
|
Maxspeed(measurement_utils::Units::Metric, 90 /* forward speed */, kInvalidSpeed);
|
|
|
|
|
CheckSpeedWithParams({secondary, unpavedBad},
|
|
|
|
@ -251,6 +226,46 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxspeedFactor)
|
|
|
|
|
SpeedKMpH(24.0, 27.0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
bool LessSpeed(SpeedKMpH const & l, SpeedKMpH const & r)
|
|
|
|
|
{
|
|
|
|
|
TEST(l.IsValid() && r.IsValid(), (l, r));
|
|
|
|
|
return l.m_weight < r.m_weight && l.m_eta < r.m_eta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define TEST_LESS_SPEED(l, r) TEST(LessSpeed(l, r), (l, r))
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
UNIT_CLASS_TEST(VehicleModelTest, CarModel_TrackVsGravelTertiary)
|
|
|
|
|
{
|
|
|
|
|
auto const & model = CarModel::AllLimitsInstance();
|
|
|
|
|
|
|
|
|
|
auto const & c = classif();
|
|
|
|
|
feature::TypesHolder h1;
|
|
|
|
|
h1.Add(c.GetTypeByPath({"highway", "track"}));
|
|
|
|
|
|
|
|
|
|
feature::TypesHolder h2;
|
|
|
|
|
h2.Add(c.GetTypeByPath({"highway", "tertiary"}));
|
|
|
|
|
h2.Add(unpavedBad); // from OSM surface=gravel
|
|
|
|
|
|
|
|
|
|
// https://www.openstreetmap.org/#map=19/45.43640/36.39689
|
|
|
|
|
// Obvious that gravel tertiary (moreover with maxspeed=60kmh) should be better than track.
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
SpeedParams p1({}, kInvalidSpeed, false /* inCity */);
|
|
|
|
|
SpeedParams p2({measurement_utils::Units::Metric, 60, 60}, kInvalidSpeed, false /* inCity */);
|
|
|
|
|
TEST_LESS_SPEED(model.GetTypeSpeed(h1, p1), model.GetTypeSpeed(h2, p2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
SpeedParams p({}, kInvalidSpeed, false /* inCity */);
|
|
|
|
|
TEST_LESS_SPEED(model.GetTypeSpeed(h1, p), model.GetTypeSpeed(h2, p));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef TEST_LESS_SPEED
|
|
|
|
|
|
|
|
|
|
UNIT_TEST(VehicleModel_MultiplicationOperatorTest)
|
|
|
|
|
{
|
|
|
|
|
SpeedKMpH const speed(90 /* weight */, 100 /* eta */);
|
|
|
|
@ -258,13 +273,13 @@ UNIT_TEST(VehicleModel_MultiplicationOperatorTest)
|
|
|
|
|
SpeedKMpH const lResult = speed * factor;
|
|
|
|
|
SpeedKMpH const rResult = factor * speed;
|
|
|
|
|
TEST_EQUAL(lResult, rResult, ());
|
|
|
|
|
TEST(base::AlmostEqualAbs(lResult.m_weight, 90.0, 1e-7), ());
|
|
|
|
|
TEST(base::AlmostEqualAbs(lResult.m_eta, 110.0, 1e-7), ());
|
|
|
|
|
TEST(base::AlmostEqualULPs(lResult.m_weight, 90.0), ());
|
|
|
|
|
TEST(base::AlmostEqualULPs(lResult.m_eta, 110.0), ());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UNIT_TEST(VehicleModel_CarModelValidation)
|
|
|
|
|
{
|
|
|
|
|
vector<HighwayType> const carRoadTypes = {
|
|
|
|
|
HighwayType const carRoadTypes[] = {
|
|
|
|
|
HighwayType::HighwayLivingStreet, HighwayType::HighwayMotorway,
|
|
|
|
|
HighwayType::HighwayMotorwayLink, HighwayType::HighwayPrimary,
|
|
|
|
|
HighwayType::HighwayPrimaryLink, HighwayType::HighwayResidential,
|
|
|
|
|