Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some bug fixes ported over from #4638 #4642

Merged
merged 6 commits into from Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion src/sif/pedestriancost.cc
Expand Up @@ -550,7 +550,6 @@ class PedestrianCost : public DynamicCost {
(edge->use() == baldr::Use::kRailFerry && pred->use() != baldr::Use::kRailFerry);

// Additional penalties without any time cost
c.cost += destination_only_penalty_ * (edge->destonly() && !pred->destonly());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ped with destonly penalty sounds weird:)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, maybe it has a point since we also turn private roads into destination_only and even pedestrian shouldn't take those..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a bit unfortunate though, "residents only" is pointless for ped but we can't distinguish

c.cost +=
alley_penalty_ * (edge->use() == baldr::Use::kAlley && pred->use() != baldr::Use::kAlley);
c.cost +=
Expand Down
2 changes: 1 addition & 1 deletion src/sif/recost.cc
Expand Up @@ -91,7 +91,7 @@ void recost_forward(baldr::GraphReader& reader,
// TODO: if this edge begins a restriction, we need to start popping off edges into queue
// so that we can find if we reach the end of the restriction. then we need to replay the
// queued edges as normal
uint8_t time_restrictions_TODO = -1;
uint8_t time_restrictions_TODO = baldr::kInvalidRestriction;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this you'll see a lot, why not use it if it already exists.

// if its not time dependent set to 0 for Allowed method below
const uint64_t localtime = offset_time.valid ? offset_time.local_time : 0;
// we should call 'Allowed' method even if 'ignore_access' flag is true in order to
Expand Down
4 changes: 2 additions & 2 deletions src/thor/astar_bss.cc
Expand Up @@ -221,7 +221,7 @@ void AStarBSSAlgorithm::ExpandForward(GraphReader& graphreader,
// Add to the adjacency list and edge labels.
uint32_t idx = edgelabels_.size();
edgelabels_.emplace_back(pred_idx, edgeid, GraphId(), directededge, newcost, sortcost, dist, mode,
transition_cost, false, true, false, InternalTurn::kNoTurn,
transition_cost, false, false, false, InternalTurn::kNoTurn,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also this you'll see a lot: this flag is setting closure_pruning which is not smth we want for lots of algos (not that it matters at all, but it's again more explicit IMO to set false here)

baldr::kInvalidRestriction);
*current_es = {EdgeSet::kTemporary, idx};
adjacencylist_.add(idx);
Expand Down Expand Up @@ -446,7 +446,7 @@ void AStarBSSAlgorithm::SetOrigin(GraphReader& graphreader,
// of the path.
uint32_t d = static_cast<uint32_t>(directededge->length() * (1.0f - edge.percent_along()));
BDEdgeLabel edge_label(kInvalidLabel, edgeid, directededge, cost, sortcost, dist,
travel_mode_t::kPedestrian, baldr::kInvalidRestriction, true, false,
travel_mode_t::kPedestrian, baldr::kInvalidRestriction, false, false,
sif::InternalTurn::kNoTurn);
// Set the origin flag and path distance
edge_label.set_origin();
Expand Down
44 changes: 23 additions & 21 deletions src/thor/bidirectional_astar.cc
Expand Up @@ -237,7 +237,7 @@ inline bool BidirectionalAStar::ExpandInner(baldr::GraphReader& graphreader,
// or if a complex restriction prevents transition onto this edge.
// if its not time dependent set to 0 for Allowed and Restricted methods below
const uint64_t localtime = time_info.valid ? time_info.local_time : 0;
uint8_t restriction_idx = -1;
uint8_t restriction_idx = kInvalidRestriction;
if (FORWARD) {
// Why is is_dest false?
// We have to consider next cases:
Expand Down Expand Up @@ -309,7 +309,9 @@ inline bool BidirectionalAStar::ExpandInner(baldr::GraphReader& graphreader,
: astarheuristic_reverse_.Get(t2->get_node_ll(meta.edge->endnode()), dist));

// not_thru_pruning_ is only set to false on the 2nd pass in route_action.
bool thru = not_thru_pruning_ ? (pred.not_thru_pruning() || !meta.edge->not_thru()) : false;
// We allow settling not_thru edges so we can connect both trees on them.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment is what eventually wasted a good 2 days of work on #4638 when I discovered that at the very end. very subtle..

bool not_thru_pruning =
not_thru_pruning_ ? (pred.not_thru_pruning() || !meta.edge->not_thru()) : false;

// Add edge label, add to the adjacency list and set edge status
uint32_t idx = 0;
Expand All @@ -321,7 +323,7 @@ inline bool BidirectionalAStar::ExpandInner(baldr::GraphReader& graphreader,
dist = astarheuristic_reverse_.GetDistance(t2->get_node_ll(meta.edge->endnode()));
}
edgelabels_forward_.emplace_back(pred_idx, meta.edge_id, opp_edge_id, meta.edge, newcost,
sortcost, dist, mode_, transition_cost, thru,
sortcost, dist, mode_, transition_cost, not_thru_pruning,
(pred.closure_pruning() || !costing_->IsClosed(meta.edge, tile)),
static_cast<bool>(flow_sources & kDefaultFlowMask),
costing_->TurnType(pred.opp_local_idx(), nodeinfo, meta.edge),
Expand All @@ -337,8 +339,8 @@ inline bool BidirectionalAStar::ExpandInner(baldr::GraphReader& graphreader,
dist = astarheuristic_forward_.GetDistance(t2->get_node_ll(meta.edge->endnode()));
}
edgelabels_reverse_.emplace_back(pred_idx, meta.edge_id, opp_edge_id, meta.edge, newcost,
sortcost, dist, mode_, transition_cost, thru,
(pred.closure_pruning() || !costing_->IsClosed(meta.edge, tile)),
sortcost, dist, mode_, transition_cost, not_thru_pruning,
(pred.closure_pruning() || !costing_->IsClosed(opp_edge, t2)),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm 100% sure now that we need to look at the opposing edge here because we're expanding on the reverse tree. case in point: AllowedReverse will prune on the opposing edge as well, not the one that gets expanded. it's really just common sense, though easy to miss..

you'll see that in a lot of ExpandInner functions throughout the PR

static_cast<bool>(flow_sources & kDefaultFlowMask),
costing_->TurnType(meta.edge->localedgeidx(), nodeinfo, opp_edge,
opp_pred_edge),
Expand Down Expand Up @@ -422,14 +424,14 @@ void BidirectionalAStar::Expand(baldr::GraphReader& graphreader,
// If so, it means we are attempting a u-turn. In that case, lets wait with evaluating
// this edge until last. If any other edges were emplaced, it means we should not
// even try to evaluate a u-turn since u-turns should only happen for deadends
uturn_meta = pred.opp_local_idx() == meta.edge->localedgeidx() ? meta : uturn_meta;
bool is_uturn = pred.opp_local_idx() == meta.edge->localedgeidx();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just putting this in a variable to make it clearer

uturn_meta = is_uturn ? meta : uturn_meta;

// Expand but only if this isnt the uturn, we'll try that later if nothing else works out
disable_uturn =
(pred.opp_local_idx() != meta.edge->localedgeidx() &&
ExpandInner<expansion_direction>(graphreader, pred, opp_pred_edge, nodeinfo, pred_idx, meta,
shortcuts, tile, offset_time)) ||
disable_uturn;
disable_uturn = (!is_uturn && ExpandInner<expansion_direction>(graphreader, pred, opp_pred_edge,
nodeinfo, pred_idx, meta,
shortcuts, tile, offset_time)) ||
disable_uturn;
}

// Handle transitions - expand from the end node of each transition
Expand Down Expand Up @@ -1011,7 +1013,7 @@ void BidirectionalAStar::SetOrigin(GraphReader& graphreader,
dist = astarheuristic_reverse_.GetDistance(nodeinfo->latlng(endtile->header()->base_ll()));
}
edgelabels_forward_.emplace_back(kInvalidLabel, edgeid, directededge, cost, sortcost, dist, mode_,
-1, !(costing_->IsClosed(directededge, tile)),
kInvalidRestriction, !(costing_->IsClosed(directededge, tile)),
static_cast<bool>(flow_sources & kDefaultFlowMask),
sif::InternalTurn::kNoTurn, 0,
directededge->destonly() ||
Expand All @@ -1028,9 +1030,9 @@ void BidirectionalAStar::SetOrigin(GraphReader& graphreader,
// flags on small loops. Set this to false here to override this for now.
edgelabels_forward_.back().set_not_thru(false);

pruning_disabled_at_origin_ = pruning_disabled_at_origin_ ||
!edgelabels_forward_.back().closure_pruning() ||
!edgelabels_forward_.back().not_thru_pruning();
pruning_disabled_at_origin_ =
pruning_disabled_at_origin_ || !edgelabels_forward_.back().closure_pruning() ||
!edgelabels_forward_.back().not_thru_pruning() || edgelabels_forward_.back().destonly();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the destination/origin projects on destonly edge, it's also a reason to extend expansion in the opposite direction.

}

// Set the origin timezone
Expand Down Expand Up @@ -1109,9 +1111,9 @@ void BidirectionalAStar::SetDestination(GraphReader& graphreader,
dist, mode_, c, !opp_dir_edge->not_thru(),
!(costing_->IsClosed(directededge, tile)),
static_cast<bool>(flow_sources & kDefaultFlowMask),
sif::InternalTurn::kNoTurn, -1,
opp_dir_edge->destonly() ||
(costing_->is_hgv() && opp_dir_edge->destonly_hgv()));
sif::InternalTurn::kNoTurn, kInvalidRestriction,
directededge->destonly() ||
(costing_->is_hgv() && directededge->destonly_hgv()));
Comment on lines +1115 to +1116
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

however, in SetDestination functions we enqueue the opposing edge, so really we need to look at the correlated edge here

adjacencylist_reverse_.add(idx);

// setting this edge as reached, sending the opposing because this is the reverse tree
Expand All @@ -1124,9 +1126,9 @@ void BidirectionalAStar::SetDestination(GraphReader& graphreader,
// flags on small loops. Set this to false here to override this for now.
edgelabels_reverse_.back().set_not_thru(false);

pruning_disabled_at_destination_ = pruning_disabled_at_destination_ ||
!edgelabels_reverse_.back().closure_pruning() ||
!edgelabels_reverse_.back().not_thru_pruning();
pruning_disabled_at_destination_ =
pruning_disabled_at_destination_ || !edgelabels_reverse_.back().closure_pruning() ||
!edgelabels_reverse_.back().not_thru_pruning() || edgelabels_reverse_.back().destonly();
}
}

Expand Down
30 changes: 16 additions & 14 deletions src/thor/costmatrix.cc
Expand Up @@ -461,7 +461,7 @@ bool CostMatrix::ExpandInner(baldr::GraphReader& graphreader,
auto& edgelabels = edgelabel_[FORWARD][index];
// Skip this edge if no access is allowed (based on costing method)
// or if a complex restriction prevents transition onto this edge.
uint8_t restriction_idx = -1;
uint8_t restriction_idx = kInvalidRestriction;
if (FORWARD) {
if (!costing_->Allowed(meta.edge, false, pred, tile, meta.edge_id, time_info.local_time,
time_info.timezone_index, restriction_idx) ||
Expand Down Expand Up @@ -512,16 +512,16 @@ bool CostMatrix::ExpandInner(baldr::GraphReader& graphreader,
}

// not_thru_pruning_ is only set to false on the 2nd pass in matrix_action.
// TODO(nils): one of these cases where I think reverse tree should look at the opposing edge,
// not the expanding one, same for quite some attributes below (and same in bidir a*)
bool thru = not_thru_pruning_ ? (pred.not_thru_pruning() || !meta.edge->not_thru()) : false;
// We allow settling not_thru edges so we can connect both trees on them.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes in CostMatrix are basically the exact same as in bidir A*

bool not_thru_pruning =
not_thru_pruning_ ? (pred.not_thru_pruning() || !meta.edge->not_thru()) : false;

// Add edge label, add to the adjacency list and set edge status
uint32_t idx = edgelabels.size();
*meta.edge_status = {EdgeSet::kTemporary, idx};
if (FORWARD) {
edgelabels.emplace_back(pred_idx, meta.edge_id, opp_edge_id, meta.edge, newcost, mode_, tc,
pred_dist, thru,
pred_dist, not_thru_pruning,
(pred.closure_pruning() || !costing_->IsClosed(meta.edge, tile)),
static_cast<bool>(flow_sources & kDefaultFlowMask),
costing_->TurnType(pred.opp_local_idx(), nodeinfo, meta.edge),
Expand All @@ -530,8 +530,8 @@ bool CostMatrix::ExpandInner(baldr::GraphReader& graphreader,
(costing_->is_hgv() && meta.edge->destonly_hgv()));
} else {
edgelabels.emplace_back(pred_idx, meta.edge_id, opp_edge_id, meta.edge, newcost, mode_, tc,
pred_dist, thru,
(pred.closure_pruning() || !costing_->IsClosed(meta.edge, tile)),
pred_dist, not_thru_pruning,
(pred.closure_pruning() || !costing_->IsClosed(opp_edge, t2)),
static_cast<bool>(flow_sources & kDefaultFlowMask),
costing_->TurnType(meta.edge->localedgeidx(), nodeinfo, opp_edge,
opp_pred_edge),
Expand Down Expand Up @@ -1024,9 +1024,10 @@ void CostMatrix::SetSources(GraphReader& graphreader,
// - "transition_cost" is used to store the traversed secs & length
// - "path_id" is used to store whether the edge is even allowed (e.g. no oneway)
Cost ec(std::round(edgecost.secs), static_cast<uint32_t>(directededge->length()));
BDEdgeLabel edge_label(kInvalidLabel, edgeid, oppedge, directededge, cost, mode_, ec, d, false,
true, static_cast<bool>(flow_sources & kDefaultFlowMask),
InternalTurn::kNoTurn, -1,
BDEdgeLabel edge_label(kInvalidLabel, edgeid, oppedge, directededge, cost, mode_, ec, d,
!directededge->not_thru(), !(costing_->IsClosed(directededge, tile)),
static_cast<bool>(flow_sources & kDefaultFlowMask),
InternalTurn::kNoTurn, kInvalidRestriction,
static_cast<uint8_t>(costing_->Allowed(directededge, tile)),
directededge->destonly() ||
(costing_->is_hgv() && directededge->destonly_hgv()));
Expand Down Expand Up @@ -1108,11 +1109,12 @@ void CostMatrix::SetTargets(baldr::GraphReader& graphreader,
// - "path_id" is used to store whether the opp edge is even allowed (e.g. no oneway)
Cost ec(std::round(edgecost.secs), static_cast<uint32_t>(directededge->length()));
BDEdgeLabel edge_label(kInvalidLabel, opp_edge_id, edgeid, opp_dir_edge, cost, mode_, ec, d,
false, true, static_cast<bool>(flow_sources & kDefaultFlowMask),
InternalTurn::kNoTurn, -1,
!opp_dir_edge->not_thru(), !(costing_->IsClosed(directededge, tile)),
static_cast<bool>(flow_sources & kDefaultFlowMask),
InternalTurn::kNoTurn, kInvalidRestriction,
static_cast<uint8_t>(costing_->Allowed(opp_dir_edge, opp_tile)),
opp_dir_edge->destonly() ||
(costing_->is_hgv() && opp_dir_edge->destonly_hgv()));
directededge->destonly() ||
(costing_->is_hgv() && directededge->destonly_hgv()));
edge_label.set_not_thru(false);

// Add EdgeLabel to the adjacency list (but do not set its status).
Expand Down
9 changes: 4 additions & 5 deletions src/thor/dijkstras.cc
Expand Up @@ -178,7 +178,7 @@ void Dijkstras::ExpandInner(baldr::GraphReader& graphreader,

// Check if the edge is allowed or if a restriction occurs
EdgeStatus* todo = nullptr;
uint8_t restriction_idx = -1;
uint8_t restriction_idx = kInvalidRestriction;
// is_dest is false, because it is a traversal algorithm in this context, not a path search
// algorithm. In other words, destination edges are not defined for this Dijkstra's algorithm.
const bool is_dest = false;
Expand Down Expand Up @@ -259,7 +259,7 @@ void Dijkstras::ExpandInner(baldr::GraphReader& graphreader,
} else {
bdedgelabels_.emplace_back(pred_idx, edgeid, oppedgeid, directededge, newcost, mode_,
transition_cost, path_dist, false,
(pred.closure_pruning() || !costing_->IsClosed(directededge, tile)),
(pred.closure_pruning() || !costing_->IsClosed(opp_edge, t2)),
static_cast<bool>(flow_sources & kDefaultFlowMask),
costing_->TurnType(directededge->localedgeidx(), nodeinfo, opp_edge,
opp_pred_edge),
Expand Down Expand Up @@ -524,7 +524,7 @@ void Dijkstras::ExpandForwardMultiModal(GraphReader& graphreader,
// costing - assume if you get a transit edge you walked to the transit stop
uint32_t tripid = 0;
uint32_t blockid = 0;
uint8_t restriction_idx = -1;
uint8_t restriction_idx = kInvalidRestriction;
const bool is_dest = false;
if (directededge->IsTransitLine()) {
// Check if transit costing allows this edge
Expand Down Expand Up @@ -818,11 +818,10 @@ void Dijkstras::SetOriginLocations(GraphReader& graphreader,
// Construct the edge label. Set the predecessor edge index to invalid
// to indicate the origin of the path.
uint32_t idx = bdedgelabels_.size();
int restriction_idx = -1;
bdedgelabels_.emplace_back(kInvalidLabel, edgeid, opp_edge_id, directededge, cost, mode_,
Cost{}, path_dist, false, !(costing_->IsClosed(directededge, tile)),
static_cast<bool>(flow_sources & kDefaultFlowMask),
InternalTurn::kNoTurn, restriction_idx, multipath_ ? path_id : 0,
InternalTurn::kNoTurn, kInvalidRestriction, multipath_ ? path_id : 0,
directededge->destonly() ||
(costing_->is_hgv() && directededge->destonly_hgv()));
// Set the origin flag
Expand Down
4 changes: 2 additions & 2 deletions src/thor/multimodal.cc
Expand Up @@ -751,7 +751,7 @@ bool MultiModalPathAlgorithm::ExpandFromNode(baldr::GraphReader& graphreader,
// Add edge label, add to the adjacency list and set edge status
uint32_t idx = edgelabels.size();
edgelabels.emplace_back(pred_idx, edgeid, directededge, newcost, newcost.cost, mode_,
walking_distance, baldr::kInvalidRestriction, true, false,
walking_distance, baldr::kInvalidRestriction, false, false,
InternalTurn::kNoTurn);
*es = {EdgeSet::kTemporary, idx};
adjlist.add(idx);
Expand Down Expand Up @@ -809,7 +809,7 @@ bool MultiModalPathAlgorithm::CanReachDestination(const valhalla::Location& dest
// we cannot do transition_cost on this label yet because we have no predecessor, but when we find
// it, we will do an update on it and set the real transition cost based on the path to it
edgelabels.emplace_back(kInvalidLabel, oppedge, diredge, cost, cost.cost, mode_, length,
baldr::kInvalidRestriction, true, false, InternalTurn::kNoTurn);
baldr::kInvalidRestriction, false, false, InternalTurn::kNoTurn);
adjlist.add(label_idx);
edgestatus.Set(oppedge, EdgeSet::kTemporary, label_idx, tile);
label_idx++;
Expand Down
1 change: 1 addition & 0 deletions src/thor/route_action.cc
Expand Up @@ -305,6 +305,7 @@ std::vector<std::vector<thor::PathInfo>> thor_worker_t::get_path(PathAlgorithm*
// If bidirectional A* disable use of destination-only edges on the
// first pass. If there is a failure, we allow them on the second pass.
// Other path algorithms can use destination-only edges on the first pass.
// TODO(nils): why not others with destonly pruning? it gets a 2nd pass as well
cost->set_allow_destination_only(path_algorithm == &bidir_astar ? false : true);

cost->set_pass(0);
Expand Down