From a20c1950c6ca6a40f6330b5f4e8514d59dc31943 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sun, 3 Apr 2022 12:39:06 +0300 Subject: [PATCH] [routing] Better VehicleModel::GetTypeSpeed function. Signed-off-by: Viktor Govako --- routing/geometry.cpp | 11 +- .../vehicle_model_test.cpp | 10 +- routing_common/vehicle_model.cpp | 104 ++++++++---------- routing_common/vehicle_model.hpp | 24 ++-- 4 files changed, 75 insertions(+), 74 deletions(-) diff --git a/routing/geometry.cpp b/routing/geometry.cpp index 07414a8ba3..80623fa648 100644 --- a/routing/geometry.cpp +++ b/routing/geometry.cpp @@ -187,9 +187,14 @@ void RoadGeometry::Load(VehicleModelInterface const & vehicleModel, FeatureType uint32_t const fID = feature.GetID().m_index; m_inCity = attrs.m_cityRoads.IsCityRoad(fID); - Maxspeed const maxSpeed = attrs.m_maxSpeeds.GetMaxspeed(fID); - m_forwardSpeed = vehicleModel.GetSpeed(feature, {true /* forward */, m_inCity, maxSpeed}); - m_backwardSpeed = vehicleModel.GetSpeed(feature, {false /* forward */, m_inCity, maxSpeed}); + + SpeedParams params(attrs.m_maxSpeeds.GetMaxspeed(fID), + m_highwayType ? attrs.m_maxSpeeds.GetDefaultSpeed(m_inCity, *m_highwayType) : kInvalidSpeed, + m_inCity); + params.m_forward = true; + m_forwardSpeed = vehicleModel.GetSpeed(feature, params); + params.m_forward = false; + m_backwardSpeed = vehicleModel.GetSpeed(feature, params); feature::TypesHolder types(feature); auto const & optionsClassfier = RoutingOptionsClassifier::Instance(); diff --git a/routing_common/routing_common_tests/vehicle_model_test.cpp b/routing_common/routing_common_tests/vehicle_model_test.cpp index dd815eb0f4..b5f419dacd 100644 --- a/routing_common/routing_common_tests/vehicle_model_test.cpp +++ b/routing_common/routing_common_tests/vehicle_model_test.cpp @@ -149,7 +149,7 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed) {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(45, 27.5), SpeedKMpH(50.0, 30.0)}); + CheckSpeed({GetType("highway", "residential")}, {SpeedKMpH(22.5, 27.5), SpeedKMpH(25.0, 30.0)}); } UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed_MultiTypes) @@ -211,10 +211,10 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_SpeedFactor) CheckSpeed({secondary, unpavedGood}, {SpeedKMpH(48.0, 56.0), SpeedKMpH(48.0, 56.0)}); CheckSpeed({secondary, unpavedBad}, {SpeedKMpH(16.0, 14.0), SpeedKMpH(16.0, 14.0)}); - CheckSpeed({residential, pavedGood}, {SpeedKMpH(36.0, 24.75), SpeedKMpH(40.0, 27.0)}); - CheckSpeed({residential, pavedBad}, {SpeedKMpH(18.0, 13.75), SpeedKMpH(20.0, 15.0)}); - CheckSpeed({residential, unpavedGood}, {SpeedKMpH(27, 22.0), SpeedKMpH(30.0, 24.0)}); - CheckSpeed({residential, unpavedBad}, {SpeedKMpH(9, 5.5), SpeedKMpH(10.0, 6.0)}); + CheckSpeed({residential, pavedGood}, {SpeedKMpH(18.0, 24.75), SpeedKMpH(20.0, 27.0)}); + CheckSpeed({residential, pavedBad}, {SpeedKMpH(9.0, 13.75), SpeedKMpH(10.0, 15.0)}); + CheckSpeed({residential, unpavedGood}, {SpeedKMpH(13.5, 22.0), SpeedKMpH(15.0, 24.0)}); + CheckSpeed({residential, unpavedBad}, {SpeedKMpH(4.5, 5.5), SpeedKMpH(5.0, 6.0)}); } UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxspeedFactor) diff --git a/routing_common/vehicle_model.cpp b/routing_common/vehicle_model.cpp index 2a9d1f8c28..a31654a752 100644 --- a/routing_common/vehicle_model.cpp +++ b/routing_common/vehicle_model.cpp @@ -166,53 +166,9 @@ void VehicleModel::GetAdditionalRoadSpeed(uint32_t type, bool isCityRoad, } } -SpeedKMpH VehicleModel::GetSpeedOnFeatureWithMaxspeed(HighwayType const & type, - SpeedParams const & speedParams) const +SpeedKMpH VehicleModel::GetTypeSpeed(feature::TypesHolder const & types, SpeedParams const & params) const { - ASSERT(speedParams.m_maxspeed.IsValid(), ()); - - auto const featureMaxSpeedKmPH = speedParams.m_maxspeed.GetSpeedKmPH(speedParams.m_forward); - ASSERT(featureMaxSpeedKmPH != kInvalidSpeed, (type, speedParams.m_forward, speedParams.m_maxspeed)); - - auto const typeKey = GetHighwayTypeKey(type); - auto const * factor = m_highwayBasedInfo.m_factors.Find(typeKey); - ASSERT(factor, ("Key:", typeKey, "is not found.")); - - bool const isCityRoad = speedParams.m_inCity; - return Pick(SpeedKMpH(static_cast(featureMaxSpeedKmPH)) * factor->GetFactor(isCityRoad), - m_maxModelSpeed.GetSpeed(isCityRoad)); -} - -SpeedKMpH VehicleModel::GetSpeedOnFeatureWithoutMaxspeed(HighwayType const & type, - SpeedParams const & speedParams) const -{ - ASSERT(!speedParams.m_maxspeed.IsValid(), ()); - - auto const * s = m_highwayBasedInfo.m_speeds.Find(type); - ASSERT(s, ("Key:", type, "is not found.")); - - auto const typeKey = GetHighwayTypeKey(type); - auto const * factor = m_highwayBasedInfo.m_factors.Find(typeKey); - ASSERT(factor, ("Key:", typeKey, "is not found.")); - - auto const isCityRoad = speedParams.m_inCity; - SpeedKMpH const speed = s->GetSpeed(isCityRoad); - ASSERT(speed.IsValid(), (speed)); - - SpeedKMpH const & maxModelSpeed = m_maxModelSpeed.GetSpeed(isCityRoad); - - /// @todo Hm, well this is not obvious for me and should be revised. - // Speeds from the m_highwayBasedInfo are taken from the former code and should not - // be multiplied to the factor. On the contrary, ETA speed should be multiplied. - return SpeedKMpH( - min(speed.m_weight, maxModelSpeed.m_weight), - min(factor->GetFactor(isCityRoad).m_eta * speed.m_eta, maxModelSpeed.m_eta)); -} - -SpeedKMpH VehicleModel::GetTypeSpeed(feature::TypesHolder const & types, - SpeedParams const & speedParams) const -{ - bool const isCityRoad = speedParams.m_inCity; + bool const isCityRoad = params.m_inCity; optional hwType; SpeedFactor surfaceFactor; optional additionalRoadSpeed; @@ -227,21 +183,57 @@ SpeedKMpH VehicleModel::GetTypeSpeed(feature::TypesHolder const & types, GetAdditionalRoadSpeed(t, isCityRoad, additionalRoadSpeed); } - if (additionalRoadSpeed) - return *additionalRoadSpeed * surfaceFactor; + SpeedKMpH speed; + if (hwType) + { + if (params.m_maxspeed.IsValid()) + { + MaxspeedType const s = params.m_maxspeed.GetSpeedKmPH(params.m_forward); + ASSERT(s != kInvalidSpeed, (*hwType, params.m_forward, params.m_maxspeed)); + speed = {static_cast(s)}; + } + else if (additionalRoadSpeed) + { + speed = *additionalRoadSpeed; + } + else + { + auto const * s = m_highwayBasedInfo.m_speeds.Find(*hwType); + ASSERT(s, ("Key:", *hwType, "is not found.")); + speed = s->GetSpeed(isCityRoad); - ASSERT(hwType, ()); - auto const resultHwType = *hwType; - if (speedParams.m_maxspeed.IsValid()) - return GetSpeedOnFeatureWithMaxspeed(resultHwType, speedParams) * surfaceFactor; + // Override 'default' speed from params, but take into account ETA/Weight factor. + if (params.m_defSpeedKmPH != kInvalidSpeed) + { + double const factor = speed.m_eta / speed.m_weight; + speed.m_weight = params.m_defSpeedKmPH; + speed.m_eta = speed.m_weight * factor; + } + } - return GetSpeedOnFeatureWithoutMaxspeed(resultHwType, speedParams) * surfaceFactor; + auto const typeKey = GetHighwayTypeKey(*hwType); + auto const * factor = m_highwayBasedInfo.m_factors.Find(typeKey); + ASSERT(factor, ("Key:", typeKey, "is not found.")); + auto const & f = factor->GetFactor(isCityRoad); + speed.m_weight *= f.m_weight; + speed.m_eta *= f.m_eta; + } + else + { + ASSERT(additionalRoadSpeed, ()); + speed = *additionalRoadSpeed; + } + + return Pick(speed, m_maxModelSpeed.GetSpeed(isCityRoad)) * surfaceFactor; } -SpeedKMpH VehicleModel::GetSpeedWihtoutMaxspeed(FeatureType & f, - SpeedParams const & speedParams) const +SpeedKMpH VehicleModel::GetSpeedWihtoutMaxspeed(FeatureType & f, SpeedParams params) const { - return VehicleModel::GetSpeed(f, {speedParams.m_forward, speedParams.m_inCity, Maxspeed()}); + // This function used for bicyle and pedestring GetSpeed implementation, so saved speeds are not applyable here. + params.m_maxspeed = {}; + params.m_defSpeedKmPH = kInvalidSpeed; + + return VehicleModel::GetSpeed(f, params); } bool VehicleModel::IsOneWay(FeatureType & f) const diff --git a/routing_common/vehicle_model.hpp b/routing_common/vehicle_model.hpp index 5af075b8d1..3db98867a8 100644 --- a/routing_common/vehicle_model.hpp +++ b/routing_common/vehicle_model.hpp @@ -68,16 +68,25 @@ using HighwayBasedSpeeds = base::SmallMap; /// \brief Params for calculation of an approximate speed on a feature. struct SpeedParams { + /// For unit tests compatibility. SpeedParams(bool forward, bool inCity, Maxspeed const & maxspeed) - : m_maxspeed(maxspeed), m_forward(forward), m_inCity(inCity) + : m_maxspeed(maxspeed), m_defSpeedKmPH(kInvalidSpeed), m_inCity(inCity), m_forward(forward) { } + SpeedParams(Maxspeed const & maxspeed, MaxspeedType defSpeedKmPH, bool inCity) + : m_maxspeed(maxspeed), m_defSpeedKmPH(defSpeedKmPH), m_inCity(inCity) + { + } + + // Maxspeed stored for feature, if any. Maxspeed m_maxspeed; - // Retrieve forward (true) or backward (false) speed. - bool m_forward; + // Default speed for this feature type in MWM, if any (kInvalidSpeed otherwise). + MaxspeedType m_defSpeedKmPH; // If a corresponding feature lies inside a city of a town. bool m_inCity; + // Retrieve forward (true) or backward (false) speed. + bool m_forward; }; /// \brief Speeds which are used for edge weight and ETA estimations. @@ -297,7 +306,7 @@ public: return false; } - SpeedKMpH GetTypeSpeed(feature::TypesHolder const & types, SpeedParams const & speedParams) const; + SpeedKMpH GetTypeSpeed(feature::TypesHolder const & types, SpeedParams const & params) const; bool EqualsForTests(VehicleModel const & rhs) const { @@ -322,7 +331,7 @@ protected: bool HasPassThroughType(feature::TypesHolder const & types) const; - SpeedKMpH GetSpeedWihtoutMaxspeed(FeatureType & f, SpeedParams const & speedParams) const; + SpeedKMpH GetSpeedWihtoutMaxspeed(FeatureType & f, SpeedParams params) const; /// \brief Maximum within all the speed limits set in a model (car model, bicycle model and so on). /// Do not mix with maxspeed value tag, which defines maximum legal speed on a feature. @@ -334,11 +343,6 @@ private: void GetAdditionalRoadSpeed(uint32_t type, bool isCityRoad, std::optional & speed) const; - SpeedKMpH GetSpeedOnFeatureWithoutMaxspeed(HighwayType const & type, - SpeedParams const & speedParams) const; - SpeedKMpH GetSpeedOnFeatureWithMaxspeed(HighwayType const & type, - SpeedParams const & speedParams) const; - // HW type -> speed and factor. HighwayBasedInfo m_highwayBasedInfo; uint32_t m_onewayType;