From fba751f28286f9611256f6c7b2d2c017fba26e45 Mon Sep 17 00:00:00 2001 From: Vladimir Byko-Ianko Date: Wed, 19 Sep 2018 16:06:14 +0300 Subject: [PATCH] Keeping max speed for roads in city and for roads outside. --- routing/edge_estimator.cpp | 4 +- routing/features_road_graph.cpp | 5 +- routing/features_road_graph.hpp | 4 +- routing/index_router.cpp | 2 +- routing/routing_helpers.cpp | 1 + routing_common/bicycle_model.cpp | 2 +- routing_common/pedestrian_model.cpp | 2 +- .../vehicle_model_test.cpp | 30 ++++++------ routing_common/vehicle_model.cpp | 48 ++++++++++++++++--- routing_common/vehicle_model.hpp | 16 +++---- 10 files changed, 75 insertions(+), 39 deletions(-) diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index 2ae9fc61a4..e9fce9196d 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -253,7 +253,7 @@ shared_ptr EdgeEstimator::Create(VehicleType vehicleType, VehicleModelInterface const & vehicleModel, shared_ptr trafficStash) { - return Create(vehicleType, vehicleModel.GetMaxSpeed().m_weight, vehicleModel.GetOffroadSpeed(), - trafficStash); + return Create(vehicleType, GetMaxWeight(vehicleModel.GetMaxSpeed()), + vehicleModel.GetOffroadSpeed(), trafficStash); } } // namespace routing diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index fd872fef23..4556e81d08 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -82,8 +82,7 @@ VehicleModelInterface * FeaturesRoadGraph::CrossCountryVehicleModel::GetVehicleM featureId.m_mwmId.GetInfo()->GetCountryName()); ASSERT(nullptr != vehicleModel, ()); - ASSERT_EQUAL(m_maxSpeed.m_weight, vehicleModel->GetMaxSpeed().m_weight, ()); - ASSERT_EQUAL(m_maxSpeed.m_eta, vehicleModel->GetMaxSpeed().m_eta, ()); + ASSERT_EQUAL(m_maxSpeed, vehicleModel->GetMaxSpeed(), ()); itr = m_cache.insert(make_pair(featureId.m_mwmId, move(vehicleModel))).first; return itr->second.get(); @@ -156,7 +155,7 @@ double FeaturesRoadGraph::GetSpeedKMpH(FeatureID const & featureId) const return speedKMPH; } -double FeaturesRoadGraph::GetMaxSpeedKMpH() const { return m_vehicleModel.GetMaxSpeed().m_weight; } +double FeaturesRoadGraph::GetMaxSpeedKMpH() const { return GetMaxWeight(m_vehicleModel.GetMaxSpeed()); } void FeaturesRoadGraph::ForEachFeatureClosestToCross(m2::PointD const & cross, ICrossEdgesLoader & edgesLoader) const diff --git a/routing/features_road_graph.hpp b/routing/features_road_graph.hpp index 0708566315..312ad416e4 100644 --- a/routing/features_road_graph.hpp +++ b/routing/features_road_graph.hpp @@ -31,7 +31,7 @@ private: // VehicleModelInterface overrides: VehicleModelInterface::SpeedKMpH GetSpeed(FeatureType & f) const override; - VehicleModelInterface::SpeedKMpH GetMaxSpeed() const override { return m_maxSpeed; }; + VehicleModelInterface::InOutCitySpeedKMpH GetMaxSpeed() const override { return m_maxSpeed; }; double GetOffroadSpeed() const override; bool IsOneWay(FeatureType & f) const override; bool IsRoad(FeatureType & f) const override; @@ -43,7 +43,7 @@ private: VehicleModelInterface * GetVehicleModel(FeatureID const & featureId) const; shared_ptr const m_vehicleModelFactory; - VehicleModelInterface::SpeedKMpH const m_maxSpeed; + VehicleModelInterface::InOutCitySpeedKMpH const m_maxSpeed; double const m_offroadSpeedKMpH; mutable map> m_cache; diff --git a/routing/index_router.cpp b/routing/index_router.cpp index 7fdd0a38b6..b24285597b 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -72,7 +72,7 @@ double CalcMaxSpeed(NumMwmIds const & numMwmIds, numMwmIds.ForEachId([&](NumMwmId id) { string const & country = numMwmIds.GetFile(id).GetName(); double const mwmMaxSpeed = - vehicleModelFactory.GetVehicleModelForCountry(country)->GetMaxSpeed().m_weight; + GetMaxWeight(vehicleModelFactory.GetVehicleModelForCountry(country)->GetMaxSpeed()); maxSpeed = max(maxSpeed, mwmMaxSpeed); }); CHECK_GREATER(maxSpeed, 0.0, ()); diff --git a/routing/routing_helpers.cpp b/routing/routing_helpers.cpp index 7a31eec665..09ac8fa738 100644 --- a/routing/routing_helpers.cpp +++ b/routing/routing_helpers.cpp @@ -166,6 +166,7 @@ void CalculateMaxSpeedTimes(RoadGraphBase const & graph, vector const // is set in pedestrian_model (bicycle_model) for big roads. On the other hand // the most likely a pedestrian (a cyclist) will go along big roads with average // speed (graph.GetMaxSpeedKMpH()). + // @TODO Eta part of speed should be used here. double const speedMpS = KMPH2MPS(graph.GetMaxSpeedKMpH()); CHECK_GREATER(speedMpS, 0.0, ()); diff --git a/routing_common/bicycle_model.cpp b/routing_common/bicycle_model.cpp index 725445f837..96d7813650 100644 --- a/routing_common/bicycle_model.cpp +++ b/routing_common/bicycle_model.cpp @@ -456,7 +456,7 @@ void BicycleModel::Init() m_bidirBicycleType = classif().GetTypeByPath({"hwtag", "bidir_bicycle"}); vector const additionalTags = { - {hwtagYesBicycle, InOutCitySpeedKMpH(m_maxSpeed, m_maxSpeed)}, + {hwtagYesBicycle, m_maxSpeed}, {{"route", "ferry"}, kSpeedFerryKMpH}, {{"man_made", "pier"}, kSpeedPierKMpH} }; diff --git a/routing_common/pedestrian_model.cpp b/routing_common/pedestrian_model.cpp index cc186c80dd..63c70697d7 100644 --- a/routing_common/pedestrian_model.cpp +++ b/routing_common/pedestrian_model.cpp @@ -308,7 +308,7 @@ void PedestrianModel::Init() m_yesFootType = classif().GetTypeByPath(hwtagYesFoot); vector const additionalTags = { - {hwtagYesFoot, InOutCitySpeedKMpH(m_maxSpeed, m_maxSpeed)}, + {hwtagYesFoot, m_maxSpeed}, {{"route", "ferry"}, kSpeedFerryKMpH}, {{"man_made", "pier"}, kSpeedPierKMpH} }; diff --git a/routing_common/routing_common_tests/vehicle_model_test.cpp b/routing_common/routing_common_tests/vehicle_model_test.cpp index 9a1916e6df..e897cf0dae 100644 --- a/routing_common/routing_common_tests/vehicle_model_test.cpp +++ b/routing_common/routing_common_tests/vehicle_model_test.cpp @@ -15,12 +15,12 @@ namespace using SpeedKMpH = routing::VehicleModel::SpeedKMpH; routing::VehicleModel::LimitsInitList const s_testLimits = { - // Out of city weight and eta speeds. In city weight and eta speeds. - {{"highway", "trunk"}, {SpeedKMpH(150.0, 150.0), SpeedKMpH(100.0, 100.0)}, true}, - {{"highway", "primary"}, {SpeedKMpH(120.0, 120.0), SpeedKMpH(90.0, 90.0)}, true}, + // In city weight and eta speeds. Out of city weight and eta speeds. + {{"highway", "trunk"}, {SpeedKMpH(100.0, 100.0), SpeedKMpH(150.0, 150.0)}, true}, + {{"highway", "primary"}, {SpeedKMpH(90.0, 90.0), SpeedKMpH(120.0, 120.0)}, true}, {{"highway", "secondary"}, {SpeedKMpH(80.0, 70.0), SpeedKMpH(80.0, 70.0)}, true}, - {{"highway", "residential"}, {SpeedKMpH(50.0, 60.0), SpeedKMpH(45.0, 55.0)}, true}, - {{"highway", "service"}, {SpeedKMpH(50.0, 40.0), SpeedKMpH(47.0, 36.0)}, false}}; + {{"highway", "residential"}, {SpeedKMpH(45.0, 55.0), SpeedKMpH(50.0, 60.0)}, true}, + {{"highway", "service"}, {SpeedKMpH(47.0, 36.0), SpeedKMpH(50.0, 40.0)}, false}}; routing::VehicleModel::SurfaceInitList const g_carSurface = { {{"psurface", "paved_good"}, {0.8 /* weightFactor */, 0.9 /* etaFactor */}}, @@ -94,8 +94,10 @@ void CheckPassThroughAllowed(initializer_list const & types, bool expe UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxSpeed) { TestVehicleModel vehicleModel; - TEST_EQUAL(vehicleModel.GetMaxSpeed().m_weight, 150, ()); - TEST_EQUAL(vehicleModel.GetMaxSpeed().m_eta, 150, ()); + TEST_EQUAL(vehicleModel.GetMaxSpeed().m_inCity.m_weight, 100, ()); + TEST_EQUAL(vehicleModel.GetMaxSpeed().m_inCity.m_eta, 100, ()); + TEST_EQUAL(vehicleModel.GetMaxSpeed().m_outCity.m_weight, 150, ()); + TEST_EQUAL(vehicleModel.GetMaxSpeed().m_outCity.m_eta, 150, ()); } UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed) @@ -104,9 +106,9 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed) CheckSpeed({GetType("highway", "secondary", "tunnel")}, {80.0, 70.0}); CheckSpeed({GetType("highway", "secondary")}, {80.0, 70.0}); - CheckSpeed({GetType("highway", "trunk")}, {100.0, 100.0}); - CheckSpeed({GetType("highway", "primary")}, {90.0, 90.0}); - CheckSpeed({GetType("highway", "residential")}, {45.0, 55.0}); + CheckSpeed({GetType("highway", "trunk")}, {150.0, 150.0}); + CheckSpeed({GetType("highway", "primary")}, {120.0, 120.0}); + CheckSpeed({GetType("highway", "residential")}, {50.0, 60.0}); } UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed_MultiTypes) @@ -167,8 +169,8 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_SpeedFactor) CheckSpeed({secondary, unpavedGood}, {48.0, 56.0}); CheckSpeed({secondary, unpavedBad}, {16.0, 14.0}); - CheckSpeed({residential, pavedGood}, {36.0, 49.5}); - CheckSpeed({residential, pavedBad}, {18.0, 27.5}); - CheckSpeed({residential, unpavedGood}, {27.0, 44.0}); - CheckSpeed({residential, unpavedBad}, {9.0, 11.0}); + CheckSpeed({residential, pavedGood}, {40.0, 54.0}); + CheckSpeed({residential, pavedBad}, {20.0, 30.0}); + CheckSpeed({residential, unpavedGood}, {30.0, 48.0}); + CheckSpeed({residential, unpavedBad}, {10.0, 12.0}); } diff --git a/routing_common/vehicle_model.cpp b/routing_common/vehicle_model.cpp index 905f6ee309..2a0d80fef3 100644 --- a/routing_common/vehicle_model.cpp +++ b/routing_common/vehicle_model.cpp @@ -10,6 +10,7 @@ #include #include +using namespace routing; using namespace std; namespace @@ -19,6 +20,12 @@ WeightAndETA Pick(WeightAndETA const & lhs, WeightAndETA const & rhs) { return {F(lhs.m_weight, rhs.m_weight), F(lhs.m_eta, rhs.m_eta)}; }; + +VehicleModel::InOutCitySpeedKMpH Max(VehicleModel::InOutCitySpeedKMpH const & lhs, + VehicleModel::InOutCitySpeedKMpH const & rhs) +{ + return {Pick(lhs.m_inCity, rhs.m_inCity), Pick(lhs.m_outCity, rhs.m_outCity)}; +} } // namespace namespace routing @@ -42,7 +49,7 @@ VehicleModel::RoadLimits::RoadLimits(VehicleModel::InOutCitySpeedKMpH const & sp VehicleModel::VehicleModel(Classificator const & c, LimitsInitList const & featureTypeLimits, SurfaceInitList const & featureTypeSurface) - : m_onewayType(c.GetTypeByPath({"hwtag", "oneway"})) + : m_maxSpeed({}, {}), m_onewayType(c.GetTypeByPath({"hwtag", "oneway"})) { CHECK_EQUAL(m_surfaceFactors.size(), 4, ("If you want to change the size of the container please take into account that it's " @@ -51,7 +58,7 @@ VehicleModel::VehicleModel(Classificator const & c, LimitsInitList const & featu for (auto const & v : featureTypeLimits) { - m_maxSpeed = Pick(m_maxSpeed, Pick(v.m_speed.m_outCity, v.m_speed.m_inCity)); + m_maxSpeed = Max(m_maxSpeed, v.m_speed); m_highwayTypes.emplace(c.GetTypeByPath(v.m_types), RoadLimits(v.m_speed, v.m_isPassThroughAllowed)); } @@ -78,7 +85,7 @@ void VehicleModel::SetAdditionalRoadTypes(Classificator const & c, for (auto const & tag : additionalTags) { m_addRoadTypes.emplace_back(c, tag); - m_maxSpeed = Pick(m_maxSpeed, Pick(tag.m_speed.m_outCity, tag.m_speed.m_inCity)); + m_maxSpeed = Max(m_maxSpeed, tag.m_speed); } } @@ -90,7 +97,7 @@ VehicleModel::SpeedKMpH VehicleModel::GetSpeed(FeatureType & f) const // TODO(bykoianko) If a road is available, a speed according to city status (CityRoads) // should be returned. if (restriction == RoadAvailability::Available) - return GetMaxSpeed(); + return GetMaxSpeed().m_outCity; if (restriction != RoadAvailability::NotAvailable && HasRoadType(types)) return GetMinTypeSpeed(types); @@ -99,7 +106,8 @@ VehicleModel::SpeedKMpH VehicleModel::GetSpeed(FeatureType & f) const VehicleModel::SpeedKMpH VehicleModel::GetMinTypeSpeed(feature::TypesHolder const & types) const { - VehicleModel::SpeedKMpH speed{m_maxSpeed.m_weight * 2.0, m_maxSpeed.m_eta * 2.0}; + // @TODO(bykoianko) Check if there's a feature in city or not and use correct speed. + VehicleModel::SpeedKMpH speed{m_maxSpeed.m_outCity.m_weight * 2.0, m_maxSpeed.m_outCity.m_eta * 2.0}; // Decreasing speed factor based on road surface (cover). VehicleModel::SpeedFactor factor; for (uint32_t t : types) @@ -127,10 +135,12 @@ VehicleModel::SpeedKMpH VehicleModel::GetMinTypeSpeed(feature::TypesHolder const CHECK_GREATER_OR_EQUAL(factor.m_eta, 0.0, ()); VehicleModel::SpeedKMpH ret; - if (speed.m_weight <= m_maxSpeed.m_weight) + // @TODO(bykoianko) Check if there's a feature in city or not and use correct speed. + if (speed.m_weight <= m_maxSpeed.m_outCity.m_weight) ret.m_weight = speed.m_weight * factor.m_weight; - if (speed.m_eta <= m_maxSpeed.m_eta) + // @TODO(bykoianko) Check if there's a feature in city or not and use correct speed. + if (speed.m_eta <= m_maxSpeed.m_outCity.m_eta) ret.m_eta = speed.m_eta * factor.m_eta; return ret; @@ -252,6 +262,21 @@ string VehicleModelFactory::GetParent(string const & country) const return m_countryParentNameGetterFn(country); } +double GetMaxWeight(VehicleModel::InOutCitySpeedKMpH const & speed) +{ + return max(speed.m_inCity.m_weight, speed.m_outCity.m_weight); +} + +double GetMaxEta(VehicleModel::InOutCitySpeedKMpH const & speed) +{ + return max(speed.m_inCity.m_eta, speed.m_outCity.m_eta); +} + +VehicleModel::SpeedKMpH GetMax(VehicleModel::InOutCitySpeedKMpH const & speed) +{ + return {GetMaxWeight(speed), GetMaxEta(speed)}; +} + string DebugPrint(VehicleModelInterface::RoadAvailability const l) { switch (l) @@ -274,4 +299,13 @@ std::string DebugPrint(VehicleModelInterface::SpeedKMpH const & speed) oss << "eta:" << speed.m_eta << " ]"; return oss.str(); } + +std::string DebugPrint(VehicleModelInterface::InOutCitySpeedKMpH const & speed) +{ + ostringstream oss; + oss << "InOutCitySpeedKMpH [ "; + oss << "inCity:" << DebugPrint(speed.m_inCity) << ", "; + oss << "outCity:" << DebugPrint(speed.m_outCity) << " ]"; + return oss.str(); +} } // namespace routing diff --git a/routing_common/vehicle_model.hpp b/routing_common/vehicle_model.hpp index 3b262f59e5..969d89d463 100644 --- a/routing_common/vehicle_model.hpp +++ b/routing_common/vehicle_model.hpp @@ -71,12 +71,10 @@ public: /// @return Allowed weight and ETA speed in KMpH. /// 0 means that it's forbidden to move on this feature or it's not a road at all. + // @TODO(bykoianko) A param if feature in city or not should be added. virtual SpeedKMpH GetSpeed(FeatureType & f) const = 0; - // @TODO(bykoianko) Method for getting speed in city and outside should be added. - - /// @returns Max weight and ETA speed in KMpH for this model - virtual SpeedKMpH GetMaxSpeed() const = 0; + virtual InOutCitySpeedKMpH GetMaxSpeed() const = 0; /// @return Offroad speed in KMpH for vehicle. This speed should be used for non-feature routing /// e.g. to connect start point to nearest feature. @@ -161,7 +159,7 @@ public: /// VehicleModelInterface overrides: SpeedKMpH GetSpeed(FeatureType & f) const override; - SpeedKMpH GetMaxSpeed() const override { return m_maxSpeed; } + InOutCitySpeedKMpH GetMaxSpeed() const override { return m_maxSpeed; } bool IsOneWay(FeatureType & f) const override; bool IsRoad(FeatureType & f) const override; bool IsPassThroughAllowed(FeatureType & f) const override; @@ -206,9 +204,7 @@ protected: SpeedKMpH GetMinTypeSpeed(feature::TypesHolder const & types) const; - // @TODO(bykoianko) |m_maxSpeed| should be kept for in city and out city roads. - // Use InOutCitySpeedKMpH structure. - SpeedKMpH m_maxSpeed; + InOutCitySpeedKMpH m_maxSpeed; private: struct AdditionalRoadType final @@ -280,6 +276,10 @@ protected: CountryParentNameGetterFn m_countryParentNameGetterFn; }; +VehicleModel::SpeedKMpH GetMax(VehicleModel::InOutCitySpeedKMpH const & speed); +double GetMaxWeight(VehicleModel::InOutCitySpeedKMpH const & speed); + std::string DebugPrint(VehicleModelInterface::RoadAvailability const l); std::string DebugPrint(VehicleModelInterface::SpeedKMpH const & speed); +std::string DebugPrint(VehicleModelInterface::InOutCitySpeedKMpH const & speed); } // namespace routing