From 38e60dc71ba5b9032b1c3b61a565fd7f5cd128c2 Mon Sep 17 00:00:00 2001 From: Martin Morin <martin.morin@control.lth.se> Date: Tue, 6 Dec 2022 01:09:09 +0100 Subject: [PATCH] Add second order pole dragging --- src/lib.rs | 16 +--------------- src/transfer_functions.rs | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2a585d2..8878e8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,21 +161,7 @@ mod pole_position_app { // Handle dragging if dragged { - let (re_off, im_off) = match self.pole_drag_offset { - Some((x, y)) => (x, y), - None => { - // We have just started to drag, find offset to closest pole so we don't jump - // - // For now, just assume we want to place the pole where we click - self.pole_drag_offset = Some((0.0, 0.0)); - (0.0, 0.0) - } - }; - - if let Some((re,im)) = pointer_coordinate { - // This should never fail - let (re, im) = (re + re_off, im + im_off); - + if let Some((re,im)) = pointer_coordinate { // This should never fail match self.order { Order::First => self.fo.adjust_poles_to(re, im), Order::Second => self.so.adjust_poles_to(re, im), diff --git a/src/transfer_functions.rs b/src/transfer_functions.rs index e1772af..4cf45f9 100644 --- a/src/transfer_functions.rs +++ b/src/transfer_functions.rs @@ -127,5 +127,38 @@ impl TransferFunction for SecondOrderSystem { } } - fn adjust_poles_to(&mut self, _re: f64, _im: f64) {} + fn adjust_poles_to(&mut self, re: f64, im: f64) { + if re >= 0.0 { + return + } + + let mut d_new = self.d; + let w_new; + + if self.d < 1.0 { + // two complex poles + let (re2, im2) = (re.powi(2), im.powi(2)); + d_new = (re2/(re2+im2)).sqrt(); + w_new = -re/d_new; + } else if self.d == 1.0 { + w_new = -re; + // real double pole + } else { + // two real poles + let d2 = self.d.powi(2); + let fast = -self.d*self.w + self.w*(d2 - 1.0).sqrt(); + let slow = -self.d*self.w - self.w*(d2 - 1.0).sqrt(); + + if (re - fast).abs() < (re - slow).abs() { + w_new = re/( -self.d + (d2-1.0).sqrt() ); + } else { + w_new = re/( -self.d - (d2-1.0).sqrt() ); + } + } + + if self.d_lower <= d_new && self.d_upper >= d_new && self.w_lower <= w_new && self.w_upper >= w_new { + self.d = d_new; + self.w = w_new; + } + } } -- GitLab