feat(topola-egui): Add sliders to set autorouting timeouts (not fully translated yet)

This commit is contained in:
Mikolaj Wielgus 2025-11-04 20:02:34 +01:00
parent 9afe862edc
commit 8216d3a907
8 changed files with 72 additions and 12 deletions

View File

@ -335,6 +335,38 @@ impl RouteActions {
&mut multilayer_autorouter_options.planar.router.wrap_around_bands, &mut multilayer_autorouter_options.planar.router.wrap_around_bands,
tr.text("tr-menu-route-options-wrap-around-bands"), tr.text("tr-menu-route-options-wrap-around-bands"),
); );
ui.label(tr.text("tr-menu-route-options-multilayer-timeout"));
ui.add(
egui::widgets::Slider::new(
&mut multilayer_autorouter_options.timeout.initial,
0.0..=1000.0,
).text("initial")
.suffix(" s"),
);
ui.add(
egui::widgets::Slider::new(
&mut multilayer_autorouter_options.timeout.progress_bonus,
0.0..=100.0,
).text("progress bonus")
.suffix(" s/ratline"),
);
ui.label(tr.text("tr-menu-route-options-planar-timeout"));
ui.add(
egui::widgets::Slider::new(
&mut multilayer_autorouter_options.planar.timeout.initial,
0.0..=1000.0,
).text("initial")
.suffix(" s"),
);
ui.add(
egui::widgets::Slider::new(
&mut multilayer_autorouter_options.planar.timeout.progress_bonus,
0.0..=100.0,
).text("progress bonus")
.suffix(" s/length units"),
);
}); });
}) })
} }

View File

@ -14,6 +14,7 @@ use topola::{
interactor::{interaction::InteractionStepper, route_plan::RoutePlan}, interactor::{interaction::InteractionStepper, route_plan::RoutePlan},
router::RouterOptions, router::RouterOptions,
specctra::{design::SpecctraDesign, ParseError, ParseErrorContext as SpecctraLoadingError}, specctra::{design::SpecctraDesign, ParseError, ParseErrorContext as SpecctraLoadingError},
stepper::TimeoutOptions,
}; };
use crate::{ use crate::{
@ -62,6 +63,14 @@ impl MenuBar {
wrap_around_bands: true, wrap_around_bands: true,
squeeze_through_under_bends: true, squeeze_through_under_bends: true,
}, },
timeout: TimeoutOptions {
initial: 1.0,
progress_bonus: 0.005,
},
},
timeout: TimeoutOptions {
initial: 5.0,
progress_bonus: 0.5,
}, },
}, },
is_placing_via: false, is_placing_via: false,

View File

@ -73,6 +73,9 @@ tr-menu-route-options-wrap-around-bands = Wrap around Bands
## ##
tr-menu-route-options-multilayer-timeout = Multilayer Timeout
tr-menu-route-options-planar-timeout = Planar Timeout
tr-menu-inspect = Inspect tr-menu-inspect = Inspect
tr-menu-inspect-measure-length = Measure Length tr-menu-inspect-measure-length = Measure Length

View File

@ -24,6 +24,7 @@ use crate::{
graph::MakeRef, graph::MakeRef,
layout::{via::ViaWeight, LayoutEdit, LayoutException}, layout::{via::ViaWeight, LayoutEdit, LayoutException},
router::{navmesh::NavmeshError, ng, thetastar::ThetastarError, RouterOptions}, router::{navmesh::NavmeshError, ng, thetastar::ThetastarError, RouterOptions},
stepper::TimeoutOptions,
triangulation::GetTrianvertexNodeIndex, triangulation::GetTrianvertexNodeIndex,
}; };
@ -49,6 +50,7 @@ pub struct PlanarAutorouteOptions {
pub presort_by: PresortBy, pub presort_by: PresortBy,
pub permutate: bool, pub permutate: bool,
pub router: RouterOptions, pub router: RouterOptions,
pub timeout: TimeoutOptions,
} }
#[derive(Error, Debug, Clone)] #[derive(Error, Debug, Clone)]

View File

@ -22,7 +22,10 @@ use crate::{
drawing::graph::PrimitiveIndex, drawing::graph::PrimitiveIndex,
geometry::{edit::Edit, primitive::PrimitiveShape}, geometry::{edit::Edit, primitive::PrimitiveShape},
router::{navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper}, router::{navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper},
stepper::{Abort, EstimateProgress, LinearScale, ReconfiguratorStatus, Reconfigure, Step}, stepper::{
Abort, EstimateProgress, LinearScale, ReconfiguratorStatus, Reconfigure, Step,
TimeoutOptions,
},
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -35,6 +38,7 @@ pub struct MultilayerAutorouteConfiguration {
pub struct MultilayerAutorouteOptions { pub struct MultilayerAutorouteOptions {
pub anterouter: AnterouterOptions, pub anterouter: AnterouterOptions,
pub planar: PlanarAutorouteOptions, pub planar: PlanarAutorouteOptions,
pub timeout: TimeoutOptions,
} }
#[derive(Getters)] #[derive(Getters)]

View File

@ -73,7 +73,7 @@ impl MultilayerAutorouteReconfigurator {
preconfiguration, preconfiguration,
options, options,
)?, )?,
timeout: TimeVsProgressAccumulatorTimeout::new(10.0, 1.0), timeout: TimeVsProgressAccumulatorTimeout::new_from_options(options.timeout),
reconfigurer, reconfigurer,
options, options,
}) })
@ -85,7 +85,7 @@ impl MultilayerAutorouteReconfigurator {
) -> Result<ControlFlow<Option<BoardEdit>, MultilayerReconfiguratorStatus>, AutorouterError> ) -> Result<ControlFlow<Option<BoardEdit>, MultilayerReconfiguratorStatus>, AutorouterError>
{ {
// Reset the reconfiguration trigger. // Reset the reconfiguration trigger.
self.timeout = TimeVsProgressAccumulatorTimeout::new(10.0, 5.0); self.timeout = TimeVsProgressAccumulatorTimeout::new_from_options(self.options.timeout);
loop { loop {
let Some(configuration) = self.reconfigurer.next_configuration(autorouter) else { let Some(configuration) = self.reconfigurer.next_configuration(autorouter) else {

View File

@ -65,7 +65,7 @@ impl PlanarAutorouteReconfigurator {
Ok(Self { Ok(Self {
stepper: PlanarAutorouteExecutionStepper::new(autorouter, preconfiguration, options)?, stepper: PlanarAutorouteExecutionStepper::new(autorouter, preconfiguration, options)?,
timeout: TimeVsProgressAccumulatorTimeout::new(3.0, 1.0), timeout: TimeVsProgressAccumulatorTimeout::new_from_options(options.timeout),
// Note: I assume here that the first permutation is the same as the original order. // Note: I assume here that the first permutation is the same as the original order.
reconfigurer, reconfigurer,
options, options,
@ -77,7 +77,7 @@ impl PlanarAutorouteReconfigurator {
autorouter: &mut Autorouter<impl AccessMesadata>, autorouter: &mut Autorouter<impl AccessMesadata>,
) -> Result<ControlFlow<Option<BoardEdit>, PlanarAutorouteReconfiguratorStatus>, AutorouterError> ) -> Result<ControlFlow<Option<BoardEdit>, PlanarAutorouteReconfiguratorStatus>, AutorouterError>
{ {
self.timeout = TimeVsProgressAccumulatorTimeout::new(3.0, 1.0); self.timeout = TimeVsProgressAccumulatorTimeout::new_from_options(self.options.timeout);
loop { loop {
let Some(configuration) = self let Some(configuration) = self
@ -112,7 +112,7 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarAutorouteRe
{ {
if !self if !self
.timeout .timeout
.update(*self.estimate_progress().value() as f64) .update(*self.estimate_progress().subscale().value() as f64)
{ {
return self.reconfigure(autorouter); return self.reconfigure(autorouter);
} }
@ -134,7 +134,6 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarAutorouteRe
impl<M: AccessMesadata> Abort<Autorouter<M>> for PlanarAutorouteReconfigurator { impl<M: AccessMesadata> Abort<Autorouter<M>> for PlanarAutorouteReconfigurator {
fn abort(&mut self, autorouter: &mut Autorouter<M>) { fn abort(&mut self, autorouter: &mut Autorouter<M>) {
//self.permutations_iter.all(|_| true); // Why did I add this code here???
self.stepper.abort(autorouter); self.stepper.abort(autorouter);
} }
} }

View File

@ -6,6 +6,7 @@ use core::ops::ControlFlow;
use std::time::Instant; use std::time::Instant;
use derive_getters::Getters; use derive_getters::Getters;
use serde::{Deserialize, Serialize};
/// This trait represents a linearly advanceable state whose advancement may /// This trait represents a linearly advanceable state whose advancement may
/// break or fail with many different return values, and to which part of /// break or fail with many different return values, and to which part of
@ -115,6 +116,12 @@ pub trait GetTimeoutProgress {
fn timeout_progress(&self) -> Option<LinearScale<f64, Self::Subscale>>; fn timeout_progress(&self) -> Option<LinearScale<f64, Self::Subscale>>;
} }
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct TimeoutOptions {
pub initial: f64,
pub progress_bonus: f64,
}
#[derive(Clone, Debug, Getters)] #[derive(Clone, Debug, Getters)]
pub struct TimeVsProgressAccumulatorTimeout { pub struct TimeVsProgressAccumulatorTimeout {
start_instant: Instant, start_instant: Instant,
@ -122,22 +129,26 @@ pub struct TimeVsProgressAccumulatorTimeout {
last_max_value: f64, last_max_value: f64,
progress_accumulator: f64, progress_accumulator: f64,
#[getter(skip)] #[getter(skip)]
progress_bonus_s: f64, progress_time_bonus_s: f64,
} }
impl TimeVsProgressAccumulatorTimeout { impl TimeVsProgressAccumulatorTimeout {
pub fn new(initial_timeout_s: f64, progress_bonus_s: f64) -> Self { pub fn new(initial_timeout_value_s: f64, progress_bonus_s: f64) -> Self {
Self { Self {
start_instant: Instant::now(), start_instant: Instant::now(),
last_max_value: 0.0, last_max_value: 0.0,
progress_accumulator: initial_timeout_s, progress_accumulator: initial_timeout_value_s,
progress_bonus_s, progress_time_bonus_s: progress_bonus_s,
} }
} }
pub fn new_from_options(options: TimeoutOptions) -> Self {
Self::new(options.initial, options.progress_bonus)
}
pub fn update(&mut self, value: f64) -> bool { pub fn update(&mut self, value: f64) -> bool {
if value > self.last_max_value { if value > self.last_max_value {
self.progress_accumulator += (value - self.last_max_value) * self.progress_bonus_s; self.progress_accumulator += (value - self.last_max_value) * self.progress_time_bonus_s;
self.last_max_value = value; self.last_max_value = value;
} }