Measure distortion

This commit is contained in:
Aaron Fenyes 2025-08-31 11:16:34 +02:00
parent 48a640605a
commit 0de32f5e11
3 changed files with 60 additions and 1 deletions

View file

@ -227,6 +227,10 @@ details[open]:has(li) .element-switch::after {
border-radius: 8px;
}
#distortion-gauge {
margin-top: 8px;
}
/* display */
#display {

View file

@ -3,6 +3,7 @@ use std::{
cell::Cell,
cmp::Ordering,
collections::{BTreeMap, BTreeSet},
f64::consts::SQRT_2,
fmt,
fmt::{Debug, Formatter},
hash::{Hash, Hasher},
@ -122,6 +123,11 @@ pub trait Element: Serial + ProblemPoser + DisplayItem {
// be used carefully to preserve invariant (1), described in the comment on
// the `tangent` field of the `Assembly` structure
fn set_column_index(&self, index: usize);
/* KLUDGE */
fn has_distortion(&self) -> bool {
false
}
}
impl Debug for dyn Element {
@ -334,6 +340,10 @@ impl Element for Point {
fn set_column_index(&self, index: usize) {
self.column_index.set(Some(index));
}
fn has_distortion(&self) -> bool {
true
}
}
impl Serial for Point {
@ -357,6 +367,9 @@ pub trait Regulator: Serial + ProblemPoser + OutlineItem {
fn subjects(&self) -> Vec<Rc<dyn Element>>;
fn measurement(&self) -> ReadSignal<f64>;
fn set_point(&self) -> Signal<SpecifiedValue>;
fn distortion(&self) -> Option<ReadSignal<f64>> { /* KLUDGE */
None
}
}
impl Hash for dyn Regulator {
@ -389,6 +402,7 @@ pub struct InversiveDistanceRegulator {
pub subjects: [Rc<dyn Element>; 2],
pub measurement: ReadSignal<f64>,
pub set_point: Signal<SpecifiedValue>,
distortion: Option<ReadSignal<f64>>, /* KLUDGE */
serial: u64,
}
@ -404,9 +418,23 @@ impl InversiveDistanceRegulator {
});
let set_point = create_signal(SpecifiedValue::from_empty_spec());
let distortion = if subjects.iter().all(|subj| subj.has_distortion()) {
Some(create_memo(move || {
let set_point_opt = set_point.with(|set_pt| set_pt.value);
let measurement_val = measurement.get();
match set_point_opt {
None => 0.0,
Some(set_point_val) => SQRT_2 * (
(-set_point_val).sqrt() - (-measurement_val).sqrt()
).abs(),
}
}))
} else {
None
};
let serial = Self::next_serial();
Self { subjects, measurement, set_point, serial }
Self { subjects, measurement, set_point, distortion, serial }
}
}
@ -422,6 +450,10 @@ impl Regulator for InversiveDistanceRegulator {
fn set_point(&self) -> Signal<SpecifiedValue> {
self.set_point
}
fn distortion(&self) -> Option<ReadSignal<f64>> {
self.distortion
}
}
impl Serial for InversiveDistanceRegulator {

View file

@ -111,6 +111,28 @@ fn StepInput() -> View {
}
}
#[component]
fn DistortionGauge() -> View {
let state = use_context::<AppState>();
let total_distortion = create_memo(move || {
state.assembly.regulators.with(|regs| {
let mut total = 0.0;
for reg in regs {
if let Some(distortion) = reg.distortion() {
total += distortion.get();
}
}
total
})
});
view! {
div(id = "distortion-gauge") {
"Distortion: " (total_distortion.with(|distort| distort.to_string()))
}
}
}
fn into_log10_time_point((step, value): (usize, f64)) -> Vec<Option<f64>> {
vec![
Some(step as f64),
@ -315,6 +337,7 @@ pub fn Diagnostics() -> View {
}
DiagnosticsPanel(name = "loss") { LossHistory {} }
DiagnosticsPanel(name = "spectrum") { SpectrumHistory {} }
DistortionGauge {}
}
}
}