From 4d9027a2a50bca085e8b9a009fa542e0b74181fa Mon Sep 17 00:00:00 2001 From: Yourself Date: Fri, 15 Nov 2019 18:38:26 -0800 Subject: [PATCH 1/4] RV PF penalizes vehicles destined for same stop --- src/pathfinder/yapf/yapf_road.cpp | 66 +++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 99ebc92235..1fb8f96f7d 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -11,6 +11,7 @@ #include "yapf.hpp" #include "yapf_node_road.hpp" #include "../../roadstop_base.h" +#include "../../vehicle_func.h" #include "../../safeguards.h" @@ -23,6 +24,8 @@ */ const uint MAX_RV_PF_TILES = 1 << 11; +const int MAX_TARGETS = 4; + template class CYapfCostRoadT { @@ -68,6 +71,15 @@ protected: inline int OneTileCost(TileIndex tile, Trackdir trackdir) { int cost = 0; + + bool predictedOccupied = false; + for (int i = 0; i < MAX_TARGETS && Yapf().leaderTargets[i] != 0xFFFF; ++i) { + if (Yapf().leaderTargets[i] != tile) continue; + cost += Yapf().PfGetSettings().road_curve_penalty; + predictedOccupied = true; + break; + } + /* set base cost */ if (IsDiagonalTrackdir(trackdir)) { cost += YAPF_TILE_LENGTH; @@ -91,10 +103,18 @@ protected: const RoadStop::Entry *entry = rs->GetEntry(dir); cost += entry->GetOccupied() * Yapf().PfGetSettings().road_stop_occupied_penalty / entry->GetLength(); } + + if (predictedOccupied) { + cost += Yapf().PfGetSettings().road_stop_occupied_penalty; + } } else { /* Increase cost for filled road stops */ cost += Yapf().PfGetSettings().road_stop_bay_occupied_penalty * (!rs->IsFreeBay(0) + !rs->IsFreeBay(1)) / 2; + if (predictedOccupied) { + cost += Yapf().PfGetSettings().road_stop_bay_occupied_penalty; + } } + break; } @@ -326,7 +346,31 @@ public: } }; +struct FindVehiclesOnTileProcData { + const Vehicle *originVehicle; + TileIndex (*targets)[MAX_TARGETS]; +}; +static Vehicle * FindVehiclesOnTileProc(Vehicle *v, void *_data) +{ + FindVehiclesOnTileProcData *data = (FindVehiclesOnTileProcData*)(_data); + + if (data->originVehicle == v) + return nullptr; + + TileIndex ti = v->tile + TileOffsByDir(v->direction); + + for (int i = 0; i < MAX_TARGETS; i++) { + if ((*data->targets)[i] == 0xFFFF) { + (*data->targets)[i] = ti; + break; + } + if ((*data->targets)[i] == ti) + return nullptr; + } + + return nullptr; +} template class CYapfFollowRoadT @@ -391,6 +435,15 @@ public: /* set origin and destination nodes */ Yapf().SetOrigin(src_tile, src_trackdirs); Yapf().SetDestination(v); + + for (int i = 0; i < MAX_TARGETS; ++i) { + Yapf().leaderTargets[i] = 0xFFFF; + } + FindVehiclesOnTileProcData data; + data.originVehicle = v; + data.targets = &Yapf().leaderTargets; + TileIndex ti = v->tile + TileOffsByDir(v->direction); + FindVehicleOnPos(ti, &data, &FindVehiclesOnTileProc); /* find the best path */ path_found = Yapf().FindPath(v); @@ -537,11 +590,16 @@ struct CYapfRoad_TypesT typedef CYapfCostRoadT PfCost; }; -struct CYapfRoad1 : CYapfT > {}; -struct CYapfRoad2 : CYapfT > {}; +template +struct CYapfRoadCommon : CYapfT { + TileIndex leaderTargets[MAX_TARGETS]; ///< the tiles targeted by vehicles in front of the current vehicle +}; -struct CYapfRoadAnyDepot1 : CYapfT > {}; -struct CYapfRoadAnyDepot2 : CYapfT > {}; +struct CYapfRoad1 : CYapfRoadCommon > {}; +struct CYapfRoad2 : CYapfRoadCommon > {}; + +struct CYapfRoadAnyDepot1 : CYapfRoadCommon > {}; +struct CYapfRoadAnyDepot2 : CYapfRoadCommon > {}; Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache) From 2935c6d036e2fbb1edd6ac38c33a3746136352e6 Mon Sep 17 00:00:00 2001 From: Yourself Date: Thu, 21 Nov 2019 19:43:18 -0800 Subject: [PATCH 2/4] Fix: Code quality Use INVALID_TILE instead of 0xFFFF Don't recompute next vehicle tile --- src/pathfinder/yapf/yapf_road.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 1fb8f96f7d..1661c5e7d2 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -73,7 +73,7 @@ protected: int cost = 0; bool predictedOccupied = false; - for (int i = 0; i < MAX_TARGETS && Yapf().leaderTargets[i] != 0xFFFF; ++i) { + for (int i = 0; i < MAX_TARGETS && Yapf().leaderTargets[i] != INVALID_TILE; ++i) { if (Yapf().leaderTargets[i] != tile) continue; cost += Yapf().PfGetSettings().road_curve_penalty; predictedOccupied = true; @@ -361,7 +361,7 @@ static Vehicle * FindVehiclesOnTileProc(Vehicle *v, void *_data) TileIndex ti = v->tile + TileOffsByDir(v->direction); for (int i = 0; i < MAX_TARGETS; i++) { - if ((*data->targets)[i] == 0xFFFF) { + if ((*data->targets)[i] == INVALID_TILE) { (*data->targets)[i] = ti; break; } @@ -437,13 +437,12 @@ public: Yapf().SetDestination(v); for (int i = 0; i < MAX_TARGETS; ++i) { - Yapf().leaderTargets[i] = 0xFFFF; + Yapf().leaderTargets[i] = INVALID_TILE; } FindVehiclesOnTileProcData data; data.originVehicle = v; data.targets = &Yapf().leaderTargets; - TileIndex ti = v->tile + TileOffsByDir(v->direction); - FindVehicleOnPos(ti, &data, &FindVehiclesOnTileProc); + FindVehicleOnPos(tile, &data, &FindVehiclesOnTileProc); /* find the best path */ path_found = Yapf().FindPath(v); From 04b8e2f8a9487fcb42c4044ce9e6ad58eb361551 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Tue, 31 Mar 2020 12:52:54 -0400 Subject: [PATCH 3/4] Fix: Road vehicles should only penalize traffic going to the same station --- src/pathfinder/yapf/yapf_road.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 50fba32ae2..4286da19a0 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -358,6 +358,10 @@ static Vehicle * FindVehiclesOnTileProc(Vehicle *v, void *_data) if (data->originVehicle == v) return nullptr; + /* only consider vehicles going to the same station as us */ + if(data->originVehicle->current_order.GetDestination() != v->current_order.GetDestination()) + return nullptr; + TileIndex ti = v->tile + TileOffsByDir(v->direction); for (int i = 0; i < MAX_TARGETS; i++) { @@ -442,7 +446,7 @@ public: FindVehiclesOnTileProcData data; data.originVehicle = v; data.targets = &Yapf().leaderTargets; - FindVehicleOnPos(tile, &data, &FindVehiclesOnTileProc); + FindVehicleOnPos(tile, VEH_ROAD, &data, &FindVehiclesOnTileProc); /* find the best path */ path_found = Yapf().FindPath(v); From c93cffed647afe0793f002eef56e6d665a8a2046 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 11 Jul 2020 22:02:32 +0100 Subject: [PATCH 4/4] Tidy up PR #138 --- src/pathfinder/yapf/yapf_road.cpp | 49 +++++++++++++++++-------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 4286da19a0..58b7d74b9d 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -24,7 +24,7 @@ */ const uint MAX_RV_PF_TILES = 1 << 11; -const int MAX_TARGETS = 4; +const int MAX_RV_LEADER_TARGETS = 4; template class CYapfCostRoadT @@ -72,11 +72,11 @@ protected: { int cost = 0; - bool predictedOccupied = false; - for (int i = 0; i < MAX_TARGETS && Yapf().leaderTargets[i] != INVALID_TILE; ++i) { - if (Yapf().leaderTargets[i] != tile) continue; + bool predicted_occupied = false; + for (int i = 0; i < MAX_RV_LEADER_TARGETS && Yapf().leader_targets[i] != INVALID_TILE; ++i) { + if (Yapf().leader_targets[i] != tile) continue; cost += Yapf().PfGetSettings().road_curve_penalty; - predictedOccupied = true; + predicted_occupied = true; break; } @@ -104,13 +104,13 @@ protected: cost += entry->GetOccupied() * Yapf().PfGetSettings().road_stop_occupied_penalty / entry->GetLength(); } - if (predictedOccupied) { + if (predicted_occupied) { cost += Yapf().PfGetSettings().road_stop_occupied_penalty; } } else { /* Increase cost for filled road stops */ cost += Yapf().PfGetSettings().road_stop_bay_occupied_penalty * (!rs->IsFreeBay(0) + !rs->IsFreeBay(1)) / 2; - if (predictedOccupied) { + if (predicted_occupied) { cost += Yapf().PfGetSettings().road_stop_bay_occupied_penalty; } } @@ -347,30 +347,33 @@ public: }; struct FindVehiclesOnTileProcData { - const Vehicle *originVehicle; - TileIndex (*targets)[MAX_TARGETS]; + const Vehicle *origin_vehicle; + TileIndex (*targets)[MAX_RV_LEADER_TARGETS]; }; static Vehicle * FindVehiclesOnTileProc(Vehicle *v, void *_data) { FindVehiclesOnTileProcData *data = (FindVehiclesOnTileProcData*)(_data); - if (data->originVehicle == v) + if (data->origin_vehicle == v) { return nullptr; + } /* only consider vehicles going to the same station as us */ - if(data->originVehicle->current_order.GetDestination() != v->current_order.GetDestination()) + if (!v->current_order.IsType(OT_GOTO_STATION) || data->origin_vehicle->current_order.GetDestination() != v->current_order.GetDestination()) { return nullptr; + } TileIndex ti = v->tile + TileOffsByDir(v->direction); - for (int i = 0; i < MAX_TARGETS; i++) { + for (int i = 0; i < MAX_RV_LEADER_TARGETS; i++) { if ((*data->targets)[i] == INVALID_TILE) { (*data->targets)[i] = ti; break; } - if ((*data->targets)[i] == ti) - return nullptr; + if ((*data->targets)[i] == ti) { + break; + } } return nullptr; @@ -439,14 +442,16 @@ public: /* set origin and destination nodes */ Yapf().SetOrigin(src_tile, src_trackdirs); Yapf().SetDestination(v); - - for (int i = 0; i < MAX_TARGETS; ++i) { - Yapf().leaderTargets[i] = INVALID_TILE; + + for (int i = 0; i < MAX_RV_LEADER_TARGETS; ++i) { + Yapf().leader_targets[i] = INVALID_TILE; + } + if (v->current_order.IsType(OT_GOTO_STATION)) { + FindVehiclesOnTileProcData data; + data.origin_vehicle = v; + data.targets = &Yapf().leader_targets; + FindVehicleOnPos(tile, VEH_ROAD, &data, &FindVehiclesOnTileProc); } - FindVehiclesOnTileProcData data; - data.originVehicle = v; - data.targets = &Yapf().leaderTargets; - FindVehicleOnPos(tile, VEH_ROAD, &data, &FindVehiclesOnTileProc); /* find the best path */ path_found = Yapf().FindPath(v); @@ -595,7 +600,7 @@ struct CYapfRoad_TypesT template struct CYapfRoadCommon : CYapfT { - TileIndex leaderTargets[MAX_TARGETS]; ///< the tiles targeted by vehicles in front of the current vehicle + TileIndex leader_targets[MAX_RV_LEADER_TARGETS]; ///< the tiles targeted by vehicles in front of the current vehicle }; struct CYapfRoad1 : CYapfRoadCommon > {};