From 299696ab33d8058a492f52646524f58fed62f8ba Mon Sep 17 00:00:00 2001 From: ykcheungab Date: Tue, 1 Sep 2026 16:46:00 +0800 Subject: [PATCH] fixed normal force negative display scale problem --- src/sensor_bench/exhibition_app.py | 36 +++++++++++++++++++++++---- src/sensor_bench/force_calibration.py | 6 +++-- tests/test_smoke.py | 18 +++++++++++--- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/sensor_bench/exhibition_app.py b/src/sensor_bench/exhibition_app.py index cdcc74f..83a9930 100644 --- a/src/sensor_bench/exhibition_app.py +++ b/src/sensor_bench/exhibition_app.py @@ -47,8 +47,10 @@ from .acquisition import ( from .camera_discovery import list_cameras, pick_default_camera from .dd06_acquisition import Dd06AcquisitionWorker from .force_calibration import ( - CALIBRATED_FORCE_Y_MAX, - CALIBRATED_FORCE_Y_MIN, + CALIBRATED_NORMAL_FORCE_Y_MAX, + CALIBRATED_NORMAL_FORCE_Y_MIN, + CALIBRATED_SHEAR_FORCE_Y_MAX, + CALIBRATED_SHEAR_FORCE_Y_MIN, FORCE_SAMPLE_RATE_HZ, PLOT_BUFFER_POINTS, PLOT_WINDOW_SEC, @@ -896,20 +898,44 @@ class ExhibitionWindow(QMainWindow): ) self.image_label.setPixmap(scaled) + def _calibrated_y_range(self, channel_index: int) -> tuple[float, float]: + if channel_index == 0: + return CALIBRATED_NORMAL_FORCE_Y_MIN, CALIBRATED_NORMAL_FORCE_Y_MAX + return CALIBRATED_SHEAR_FORCE_Y_MIN, CALIBRATED_SHEAR_FORCE_Y_MAX + + def _apply_calibrated_y_axis(self, plot, channel_index: int) -> None: + axis = plot.getAxis("left") + if channel_index == 0: + ticks = [(0, "0"), (5, "5"), (10, "10"), (15, "15"), (20, "20")] + else: + ticks = [ + (-20, "-20"), + (-10, "-10"), + (0, "0"), + (10, "10"), + (20, "20"), + ] + axis.setTicks([ticks]) + def _update_plots(self) -> None: state = self.force_history.state() if state is None: return for i, curve in enumerate(self.curves): x = state.times - y = state.values[:, i] + y = state.values[:, i].copy() + if self._force_calibrated and i == 0: + y = np.maximum(y, 0.0) curve.setData(x, y) if self._force_calibrated: - ymin, ymax = CALIBRATED_FORCE_Y_MIN, CALIBRATED_FORCE_Y_MAX + ymin, ymax = self._calibrated_y_range(i) + self._apply_calibrated_y_axis(self.plots[i], i) else: ymin, ymax = state.y_ranges[i] + self.plots[i].getAxis("left").setTicks(None) self.plots[i].setYRange(ymin, ymax, padding=0) - self.dot_cores[i].setData(x[-1:], y[-1:]) + dot_y = y[-1:] + self.dot_cores[i].setData(x[-1:], dot_y) x0, x1 = state.x_range for plot in self.plots: plot.setXRange(x0, x1, padding=0) diff --git a/src/sensor_bench/force_calibration.py b/src/sensor_bench/force_calibration.py index aee1c58..a36ea19 100644 --- a/src/sensor_bench/force_calibration.py +++ b/src/sensor_bench/force_calibration.py @@ -11,8 +11,10 @@ FORCE_SAMPLE_RATE_HZ = 30.0 PLOT_BUFFER_POINTS = 120 PLOT_WINDOW_SEC = PLOT_BUFFER_POINTS / FORCE_SAMPLE_RATE_HZ Y_AXIS_MIN_SPAN = 20000.0 -CALIBRATED_FORCE_Y_MIN = -20.0 -CALIBRATED_FORCE_Y_MAX = 20.0 +CALIBRATED_NORMAL_FORCE_Y_MIN = 0.0 +CALIBRATED_NORMAL_FORCE_Y_MAX = 20.0 +CALIBRATED_SHEAR_FORCE_Y_MIN = -20.0 +CALIBRATED_SHEAR_FORCE_Y_MAX = 20.0 Y_RANGE_ALPHA = 0.5 LOWPASS_CUTOFF_HZ = 10.0 diff --git a/tests/test_smoke.py b/tests/test_smoke.py index 60a4308..54c58e6 100644 --- a/tests/test_smoke.py +++ b/tests/test_smoke.py @@ -337,14 +337,24 @@ def test_exhibition_window_offscreen() -> None: assert "FN" in title0 assert "raw" in title0 - from sensor_bench.force_calibration import CALIBRATED_FORCE_Y_MAX, CALIBRATED_FORCE_Y_MIN + from sensor_bench.force_calibration import ( + CALIBRATED_NORMAL_FORCE_Y_MAX, + CALIBRATED_NORMAL_FORCE_Y_MIN, + CALIBRATED_SHEAR_FORCE_Y_MAX, + CALIBRATED_SHEAR_FORCE_Y_MIN, + ) win._force_calibrated = True win.force_history.push(time.time(), 1.0, -2.0, 3.0) win._update_plots() - ymin, ymax = win.plots[0].viewRange()[1] - assert abs(ymin - CALIBRATED_FORCE_Y_MIN) < 1e-6 - assert abs(ymax - CALIBRATED_FORCE_Y_MAX) < 1e-6 + fn_ymin, fn_ymax = win.plots[0].viewRange()[1] + assert abs(fn_ymin - CALIBRATED_NORMAL_FORCE_Y_MIN) < 1e-6 + assert abs(fn_ymax - CALIBRATED_NORMAL_FORCE_Y_MAX) < 1e-6 + fx_ymin, fx_ymax = win.plots[1].viewRange()[1] + assert abs(fx_ymin - CALIBRATED_SHEAR_FORCE_Y_MIN) < 1e-6 + assert abs(fx_ymax - CALIBRATED_SHEAR_FORCE_Y_MAX) < 1e-6 + axis = win.plots[0].getAxis("left") + assert "20" in axis.tickStrings([20.0], 1.0, 20.0) win.view_combo.setCurrentIndex(1) assert win._view_mode == "captured"