From cc3b537b5c2a2932049ac6928ae7522dbd71aa1b Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Tue, 10 Oct 2023 21:09:21 +0000 Subject: [PATCH] debug: Visualize A* running during interactive routing --- src/layout.rs | 15 ++- src/main.rs | 361 ++++++++++++++++++++++++-------------------------- src/mesh.rs | 2 + src/route.rs | 4 +- src/router.rs | 9 +- 5 files changed, 189 insertions(+), 202 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index fe2851e..3e01da8 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -99,7 +99,8 @@ impl Layout { Ok(seg) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] pub fn add_bend( &mut self, from: DotIndex, @@ -114,8 +115,10 @@ impl Layout { } } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 3))] + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] + #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3))] + #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] pub fn add_core_bend( &mut self, from: DotIndex, @@ -134,8 +137,10 @@ impl Layout { Ok(bend) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))] + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] + #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] pub fn add_outer_bend( &mut self, from: DotIndex, diff --git a/src/main.rs b/src/main.rs index f4698ba..e94691e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,8 @@ mod shape; use geo::point; use graph::{DotIndex, SegWeight, Tag, TaggedIndex}; use layout::Layout; -use mesh::{MeshEdgeReference, VertexIndex}; +use mesh::{Mesh, MeshEdgeReference, VertexIndex}; +use petgraph::visit::{EdgeRef, IntoEdgeReferences}; use route::Route; use router::{DefaultRouteStrategy, RouteStrategy}; use sdl2::event::Event; @@ -79,7 +80,9 @@ impl<'a, RS: RouteStrategy> RouteStrategy for DebugRouteStrategy<'a, RS> { RouterOrLayout::Layout(route.layout), None, None, - 25, + Some(route.mesh.clone()), + path, + 10, ); self.strategy.route_cost(route, path) } @@ -113,7 +116,7 @@ fn main() { let _i = 0; let mut router = Router::new(); - let dot1_1 = router + let dot1 = router .layout .add_dot(DotWeight { net: 1, @@ -123,168 +126,128 @@ fn main() { }, }) .unwrap(); - let _dot2_1 = router - .layout - .add_dot(DotWeight { - net: 2, - circle: Circle { - pos: (130.5, 430.5).into(), - r: 8.0, - }, - }) - .unwrap(); - let _dot3_1 = router - .layout - .add_dot(DotWeight { - net: 3, - circle: Circle { - pos: (160.5, 460.5).into(), - r: 8.0, - }, - }) - .unwrap(); - let _dot4_1 = router - .layout - .add_dot(DotWeight { - net: 4, - circle: Circle { - pos: (190.5, 490.5).into(), - r: 8.0, - }, - }) - .unwrap(); - let dot1_2 = router + let dot2 = router .layout .add_dot(DotWeight { net: 1, circle: Circle { - pos: (700.5, 400.5).into(), + pos: (500.5, 430.5).into(), r: 8.0, }, }) .unwrap(); - let _dot2_2 = router + + let dot1_1 = router .layout .add_dot(DotWeight { net: 2, circle: Circle { - pos: (670.5, 430.5).into(), - r: 8.0, - }, - }) - .unwrap(); - let _dot3_2 = router - .layout - .add_dot(DotWeight { - net: 3, - circle: Circle { - pos: (640.5, 460.5).into(), - r: 8.0, - }, - }) - .unwrap(); - let _dot4_2 = router - .layout - .add_dot(DotWeight { - net: 4, - circle: Circle { - pos: (610.5, 490.5).into(), + pos: (200.5, 200.5).into(), r: 8.0, }, }) .unwrap(); - let _dot5 = router + let dot2_1 = router .layout .add_dot(DotWeight { - net: 5, + net: 2, circle: Circle { - pos: (150.5, 100.5).into(), + pos: (200.5, 500.5).into(), r: 8.0, }, }) .unwrap(); - let _dot6 = router - .layout - .add_dot(DotWeight { - net: 6, - circle: Circle { - pos: (190.5, 200.5).into(), - r: 8.0, - }, - }) - .unwrap(); - - let _dot7 = router - .layout - .add_dot(DotWeight { - net: 5, - circle: Circle { - pos: (230.5, 70.5).into(), - r: 8.0, - }, - }) - .unwrap(); - - let barrier1_dot1 = router - .layout - .add_dot(DotWeight { - net: 10, - circle: Circle { - pos: (250.5, 250.5).into(), - r: 8.0, - }, - }) - .unwrap(); - - let barrier2_dot1 = router - .layout - .add_dot(DotWeight { - net: 20, - circle: Circle { - pos: (420.5, 200.5).into(), - r: 8.0, - }, - }) - .unwrap(); - let barrier2_dot2 = router - .layout - .add_dot(DotWeight { - net: 20, - circle: Circle { - pos: (480.5, 550.5).into(), - r: 8.0, - }, - }) - .unwrap(); let _ = router.layout.add_seg( - barrier2_dot1, - barrier2_dot2, + dot1_1, + dot2_1, SegWeight { net: 20, width: 16.0, }, ); - /*let head = router.draw_start(dot5); - let head = router.draw_around_dot(head, dot6, false, 5.0).unwrap(); - let _ = router.draw_finish(head, dot7, 5.0);*/ + let dot2_2 = router + .layout + .add_dot(DotWeight { + net: 2, + circle: Circle { + pos: (600.5, 500.5).into(), + r: 8.0, + }, + }) + .unwrap(); - /*let _ = router.enroute( - dot1_1, - dot1_2, - DebugRouteStrategy::new(DefaultRouteStrategy::new(), &mut event_pump, &mut canvas), + let _ = router.layout.add_seg( + dot2_1, + dot2_2, + SegWeight { + net: 20, + width: 16.0, + }, + ); + + let dot3 = router + .layout + .add_dot(DotWeight { + net: 2, + circle: Circle { + pos: (400.5, 200.5).into(), + r: 8.0, + }, + }) + .unwrap(); + + let dot4 = router + .layout + .add_dot(DotWeight { + net: 2, + circle: Circle { + pos: (400.5, 400.5).into(), + r: 8.0, + }, + }) + .unwrap(); + + let _ = router.layout.add_seg( + dot3, + dot4, + SegWeight { + net: 20, + width: 16.0, + }, + ); + + let dot1_2 = router + .layout + .add_dot(DotWeight { + net: 2, + circle: Circle { + pos: (600.5, 200.5).into(), + r: 8.0, + }, + }) + .unwrap(); + + let _ = router.layout.add_seg( + dot3, + dot1_2, + SegWeight { + net: 20, + width: 16.0, + }, ); - render_times(&mut event_pump, &mut canvas, &router.layout, None, -1);*/ render_times( &mut event_pump, &mut canvas, RouterOrLayout::Router(&mut router), - Some(dot1_1), - Some(dot1_2), + Some(dot1), + Some(dot2), + None, + &[], -1, ); render_times( @@ -293,6 +256,8 @@ fn main() { RouterOrLayout::Layout(&router.layout), None, None, + None, + &[], -1, ); } @@ -303,6 +268,8 @@ fn render_times( mut router_or_layout: RouterOrLayout, from: Option, follower: Option, + mut mesh: Option, + path: &[VertexIndex], times: i64, ) { let mut i = 0; @@ -333,11 +300,17 @@ fn render_times( );*/ if let Some(from) = from { - router.reroute( - from, - point! {x: state.x() as f64, y: state.y() as f64}, - &mut DefaultRouteStrategy::new(), - ); + mesh = router + .reroute( + from, + point! {x: state.x() as f64, y: state.y() as f64}, + &mut DebugRouteStrategy::new( + DefaultRouteStrategy::new(), + event_pump, + canvas, + ), + ) + .ok(); } } @@ -346,74 +319,80 @@ fn render_times( RouterOrLayout::Layout(layout) => layout, }; - let result = panic::catch_unwind(|| { - for shape in layout.shapes() { - match shape { - Shape::Dot(dot) => { - let _ = canvas.filled_circle( - dot.c.pos.x() as i16, - dot.c.pos.y() as i16, - dot.c.r as i16, + //let result = panic::catch_unwind(|| { + for shape in layout.shapes() { + match shape { + Shape::Dot(dot) => { + let _ = canvas.filled_circle( + dot.c.pos.x() as i16, + dot.c.pos.y() as i16, + dot.c.r as i16, + Color::RGB(200, 52, 52), + ); + } + Shape::Seg(seg) => { + let _ = canvas.thick_line( + seg.from.x() as i16, + seg.from.y() as i16, + seg.to.x() as i16, + seg.to.y() as i16, + seg.width as u8, + Color::RGB(200, 52, 52), + ); + } + Shape::Bend(bend) => { + let delta1 = bend.from - bend.c.pos; + let delta2 = bend.to - bend.c.pos; + + let angle1 = delta1.y().atan2(delta1.x()); + let angle2 = delta2.y().atan2(delta2.x()); + + for d in -2..3 { + let _ = canvas.arc( + //around_circle.pos.x() as i16, + //around_circle.pos.y() as i16, + bend.c.pos.x() as i16, + bend.c.pos.y() as i16, + //(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16, + (bend.circle().r + (d as f64)) as i16, + angle1.to_degrees() as i16, + angle2.to_degrees() as i16, Color::RGB(200, 52, 52), ); } - Shape::Seg(seg) => { - let _ = canvas.thick_line( - seg.from.x() as i16, - seg.from.y() as i16, - seg.to.x() as i16, - seg.to.y() as i16, - seg.width as u8, - Color::RGB(200, 52, 52), - ); - } - Shape::Bend(bend) => { - let delta1 = bend.from - bend.c.pos; - let delta2 = bend.to - bend.c.pos; - - let angle1 = delta1.y().atan2(delta1.x()); - let angle2 = delta2.y().atan2(delta2.x()); - - for d in -2..3 { - let _ = canvas.arc( - //around_circle.pos.x() as i16, - //around_circle.pos.y() as i16, - bend.c.pos.x() as i16, - bend.c.pos.y() as i16, - //(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16, - (bend.circle().r + (d as f64)) as i16, - angle1.to_degrees() as i16, - angle2.to_degrees() as i16, - Color::RGB(200, 52, 52), - ); - } - } } - /*let envelope = shape.envelope(); - let _ = canvas.rectangle( - envelope.lower()[0] as i16, - envelope.lower()[1] as i16, - envelope.upper()[0] as i16, - envelope.upper()[1] as i16, - Color::RGB(100, 100, 100), - );*/ } - - /*for edge in router.routeedges() { - let _ = canvas.line( - edge.0.x() as i16, - edge.0.y() as i16, - edge.1.x() as i16, - edge.1.y() as i16, - Color::RGB(250, 250, 250), - ); - }*/ - }); - - if let Err(err) = result { - dbg!(err); + /*let envelope = shape.envelope(); + let _ = canvas.rectangle( + envelope.lower()[0] as i16, + envelope.lower()[1] as i16, + envelope.upper()[0] as i16, + envelope.upper()[1] as i16, + Color::RGB(100, 100, 100), + );*/ } + if let Some(ref mesh) = mesh { + for edge in mesh.edge_references() { + let endpoints = (mesh.position(edge.source()), mesh.position(edge.target())); + + let color = if path.contains(&edge.source()) && path.contains(&edge.target()) { + Color::RGB(250, 250, 0) + } else { + Color::RGB(125, 125, 125) + }; + + let _ = canvas.line( + endpoints.0.x() as i16, + endpoints.0.y() as i16, + endpoints.1.x() as i16, + endpoints.1.y() as i16, + color, + ); + } + } + //}); + canvas.present(); i += 1; diff --git a/src/mesh.rs b/src/mesh.rs index 5c1b175..5de3d66 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -9,6 +9,7 @@ use spade::{ use crate::{graph::DotIndex, layout::Layout}; +#[derive(Debug, Clone)] struct Vertex { pub dot: DotIndex, x: f64, @@ -27,6 +28,7 @@ impl HasPosition for Vertex { } } +#[derive(Debug, Clone)] pub struct Mesh { triangulation: DelaunayTriangulation, dot_to_vertex: Vec>, diff --git a/src/route.rs b/src/route.rs index 6aab2db..671bbc3 100644 --- a/src/route.rs +++ b/src/route.rs @@ -15,8 +15,8 @@ pub struct Trace { pub struct Route<'a> { pub layout: &'a mut Layout, - rules: &'a Rules, - mesh: &'a Mesh, + pub rules: &'a Rules, + pub mesh: &'a Mesh, } impl<'a> Route<'a> { diff --git a/src/router.rs b/src/router.rs index 9b58214..2537491 100644 --- a/src/router.rs +++ b/src/router.rs @@ -71,7 +71,7 @@ impl<'a, RS: RouteStrategy> AstarStrategy<&Mesh, u64> for RouterAstarStrategy<'a fn reroute(&mut self, vertex: VertexIndex, tracker: &PathTracker<&Mesh>) -> Option { let new_path = tracker.reconstruct_path_to(vertex); - self.route.rework_path(&mut self.trace, &new_path, 5.0).ok(); + self.route.rework_path(&mut self.trace, &new_path, 5.0); if self.route.finish(&mut self.trace, self.to, 5.0).is_ok() { return None; @@ -102,7 +102,7 @@ impl Router { from: DotIndex, to: DotIndex, strategy: &mut impl RouteStrategy, - ) -> Result<(), InsertionError> { + ) -> Result { // XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look // right. //self.mesh.triangulate(&self.layout)?; @@ -118,7 +118,8 @@ impl Router { &mut RouterAstarStrategy::new(route, trace, mesh.vertex(to), strategy), ) .unwrap(); // TODO. - Ok(()) + + Ok(mesh) } pub fn reroute( @@ -126,7 +127,7 @@ impl Router { from: DotIndex, to: Point, strategy: &mut impl RouteStrategy, - ) -> Result<(), InsertionError> { + ) -> Result { let to_dot = if let Some(band) = self.layout.next_band(from) { let to_dot = band.ends().1;