mirror of https://codeberg.org/topola/topola.git
router: step on successful probes
This commit is contained in:
parent
b48ce70aad
commit
fd23be7a8a
|
|
@ -104,11 +104,12 @@ where
|
||||||
K: Measure + Copy,
|
K: Measure + Copy,
|
||||||
{
|
{
|
||||||
fn is_goal(&mut self, graph: &G, node: G::NodeId, tracker: &PathTracker<G>) -> Option<R>;
|
fn is_goal(&mut self, graph: &G, node: G::NodeId, tracker: &PathTracker<G>) -> Option<R>;
|
||||||
fn probe<'a>(
|
fn place_probe<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
graph: &'a G,
|
graph: &'a G,
|
||||||
edge: <&'a G as IntoEdgeReferences>::EdgeRef,
|
edge: <&'a G as IntoEdgeReferences>::EdgeRef,
|
||||||
) -> Option<K>;
|
) -> Option<K>;
|
||||||
|
fn remove_probe<'a>(&mut self, graph: &'a G);
|
||||||
fn estimate_cost(&mut self, graph: &G, node: G::NodeId) -> K;
|
fn estimate_cost(&mut self, graph: &G, node: G::NodeId) -> K;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,6 +132,8 @@ where
|
||||||
pub maybe_curr_node: Option<G::NodeId>,
|
pub maybe_curr_node: Option<G::NodeId>,
|
||||||
// FIXME: To work around edge references borrowing from the graph we collect then reiterate over tem.
|
// FIXME: To work around edge references borrowing from the graph we collect then reiterate over tem.
|
||||||
pub edge_ids: VecDeque<G::EdgeId>,
|
pub edge_ids: VecDeque<G::EdgeId>,
|
||||||
|
// TODO: Rewrite this to be a well-designed state machine.
|
||||||
|
pub is_probing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, Clone)]
|
#[derive(Error, Debug, Clone)]
|
||||||
|
|
@ -147,6 +150,7 @@ where
|
||||||
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + MakeEdgeRef,
|
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + MakeEdgeRef,
|
||||||
K: Measure + Copy,
|
K: Measure + Copy,
|
||||||
{
|
{
|
||||||
|
Probing,
|
||||||
Probed,
|
Probed,
|
||||||
Visited,
|
Visited,
|
||||||
Finished(K, Vec<G::NodeId>, R),
|
Finished(K, Vec<G::NodeId>, R),
|
||||||
|
|
@ -168,6 +172,7 @@ where
|
||||||
path_tracker: PathTracker::<G>::new(),
|
path_tracker: PathTracker::<G>::new(),
|
||||||
maybe_curr_node: None,
|
maybe_curr_node: None,
|
||||||
edge_ids: VecDeque::new(),
|
edge_ids: VecDeque::new(),
|
||||||
|
is_probing: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let zero_score = K::default();
|
let zero_score = K::default();
|
||||||
|
|
@ -184,13 +189,18 @@ where
|
||||||
strategy: &mut impl AstarStrategy<G, K, R>,
|
strategy: &mut impl AstarStrategy<G, K, R>,
|
||||||
) -> Result<AstarStatus<G, K, R>, AstarError> {
|
) -> Result<AstarStatus<G, K, R>, AstarError> {
|
||||||
if let Some(curr_node) = self.maybe_curr_node {
|
if let Some(curr_node) = self.maybe_curr_node {
|
||||||
|
if self.is_probing {
|
||||||
|
strategy.remove_probe(&self.graph);
|
||||||
|
self.is_probing = false;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(edge_id) = self.edge_ids.pop_front() {
|
if let Some(edge_id) = self.edge_ids.pop_front() {
|
||||||
// This lookup can be unwrapped without fear of panic since the node was
|
// This lookup can be unwrapped without fear of panic since the node was
|
||||||
// necessarily scored before adding it to `visit_next`.
|
// necessarily scored before adding it to `visit_next`.
|
||||||
let node_score = self.scores[&curr_node];
|
let node_score = self.scores[&curr_node];
|
||||||
let edge = (&self.graph).edge_ref(edge_id);
|
let edge = (&self.graph).edge_ref(edge_id);
|
||||||
|
|
||||||
if let Some(edge_cost) = strategy.probe(&self.graph, edge) {
|
if let Some(edge_cost) = strategy.place_probe(&self.graph, edge) {
|
||||||
let next = edge.target();
|
let next = edge.target();
|
||||||
let next_score = node_score + edge_cost;
|
let next_score = node_score + edge_cost;
|
||||||
|
|
||||||
|
|
@ -212,6 +222,9 @@ where
|
||||||
let next_estimate_score =
|
let next_estimate_score =
|
||||||
next_score + strategy.estimate_cost(&self.graph, next);
|
next_score + strategy.estimate_cost(&self.graph, next);
|
||||||
self.visit_next.push(MinScored(next_estimate_score, next));
|
self.visit_next.push(MinScored(next_estimate_score, next));
|
||||||
|
|
||||||
|
self.is_probing = true;
|
||||||
|
return Ok(AstarStatus::Probing);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(AstarStatus::Probed);
|
return Ok(AstarStatus::Probed);
|
||||||
|
|
|
||||||
|
|
@ -85,12 +85,14 @@ impl Route {
|
||||||
let mut strategy = RouterAstarStrategy::new(tracer, &mut self.trace, target);
|
let mut strategy = RouterAstarStrategy::new(tracer, &mut self.trace, target);
|
||||||
|
|
||||||
let result = match self.astar.step(&mut strategy)? {
|
let result = match self.astar.step(&mut strategy)? {
|
||||||
AstarStatus::Probed | AstarStatus::Visited => Ok(RouterStatus::Running),
|
AstarStatus::Probing | AstarStatus::Probed | AstarStatus::Visited => {
|
||||||
|
Ok(RouterStatus::Running)
|
||||||
|
}
|
||||||
AstarStatus::Finished(_cost, _path, band) => Ok(RouterStatus::Finished(band)),
|
AstarStatus::Finished(_cost, _path, band) => Ok(RouterStatus::Finished(band)),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.ghosts = strategy.last_ghosts;
|
self.ghosts = strategy.probe_ghosts;
|
||||||
self.obstacles = strategy.last_obstacles;
|
self.obstacles = strategy.probe_obstacles;
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,8 @@ pub struct RouterAstarStrategy<'a, R: AccessRules> {
|
||||||
pub tracer: Tracer<'a, R>,
|
pub tracer: Tracer<'a, R>,
|
||||||
pub trace: &'a mut Trace,
|
pub trace: &'a mut Trace,
|
||||||
pub target: FixedDotIndex,
|
pub target: FixedDotIndex,
|
||||||
pub last_ghosts: Vec<PrimitiveShape>,
|
pub probe_ghosts: Vec<PrimitiveShape>,
|
||||||
pub last_obstacles: Vec<PrimitiveIndex>,
|
pub probe_obstacles: Vec<PrimitiveIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: AccessRules> RouterAstarStrategy<'a, R> {
|
impl<'a, R: AccessRules> RouterAstarStrategy<'a, R> {
|
||||||
|
|
@ -57,8 +57,8 @@ impl<'a, R: AccessRules> RouterAstarStrategy<'a, R> {
|
||||||
tracer,
|
tracer,
|
||||||
trace,
|
trace,
|
||||||
target,
|
target,
|
||||||
last_ghosts: vec![],
|
probe_ghosts: vec![],
|
||||||
last_obstacles: vec![],
|
probe_obstacles: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandFirstSegIndex>
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn probe(&mut self, navmesh: &Navmesh, edge: NavmeshEdgeReference) -> Option<f64> {
|
fn place_probe(&mut self, navmesh: &Navmesh, edge: NavmeshEdgeReference) -> Option<f64> {
|
||||||
if edge.target().petgraph_index() == self.target.petgraph_index() {
|
if edge.target().petgraph_index() == self.target.petgraph_index() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
@ -114,10 +114,7 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandFirstSegIndex>
|
||||||
let probe_length = self.bihead_length() - prev_bihead_length;
|
let probe_length = self.bihead_length() - prev_bihead_length;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(..) => {
|
Ok(..) => Some(probe_length),
|
||||||
self.trace.undo_step(&mut self.tracer);
|
|
||||||
Some(probe_length)
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if let TracerException::CannotDraw(draw_err) = err {
|
if let TracerException::CannotDraw(draw_err) = err {
|
||||||
let layout_err = match draw_err {
|
let layout_err = match draw_err {
|
||||||
|
|
@ -135,14 +132,18 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandFirstSegIndex>
|
||||||
LayoutException::AlreadyConnected(..) => return None,
|
LayoutException::AlreadyConnected(..) => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.last_ghosts = vec![ghost];
|
self.probe_ghosts = vec![ghost];
|
||||||
self.last_obstacles = vec![obstacle];
|
self.probe_obstacles = vec![obstacle];
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_probe(&mut self, _navmesh: &Navmesh) {
|
||||||
|
self.trace.undo_step(&mut self.tracer);
|
||||||
|
}
|
||||||
|
|
||||||
fn estimate_cost(&mut self, navmesh: &Navmesh, vertex: NavvertexIndex) -> f64 {
|
fn estimate_cost(&mut self, navmesh: &Navmesh, vertex: NavvertexIndex) -> f64 {
|
||||||
let start_point = PrimitiveIndex::from(navmesh.node_weight(vertex).unwrap().node)
|
let start_point = PrimitiveIndex::from(navmesh.node_weight(vertex).unwrap().node)
|
||||||
.primitive(self.tracer.layout.drawing())
|
.primitive(self.tracer.layout.drawing())
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue