update plot to force units
This commit is contained in:
+130
-3
@@ -44,6 +44,45 @@ def test_translator_chinese_default() -> None:
|
||||
assert tr._lookup("en_US", "workflow.title") is None
|
||||
|
||||
|
||||
def test_read_forces_from_sensor() -> None:
|
||||
from sensor_bench.acquisition import read_forces_from_sensor, sensor_force_calibrated
|
||||
|
||||
class RawSensor:
|
||||
info = SimpleNamespace(
|
||||
FNORMAL=1,
|
||||
FSHEARX=2,
|
||||
FSHEARY=3,
|
||||
FNORMAL_RAW=4,
|
||||
FSHEARX_RAW=5,
|
||||
FSHEARY_RAW=6,
|
||||
VRAW=7,
|
||||
)
|
||||
_force_cal_sensor_name = "box"
|
||||
|
||||
def read_info(self, *args):
|
||||
return 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, None
|
||||
|
||||
forces = read_forces_from_sensor(RawSensor())
|
||||
assert sensor_force_calibrated(RawSensor())
|
||||
assert forces.force_calibrated is True
|
||||
assert forces.force_unit == "N"
|
||||
assert forces.normal_force == 1.1
|
||||
assert forces.normal_force_raw == 4.4
|
||||
|
||||
class LegacySensor:
|
||||
info = SimpleNamespace(FNORMAL=1, FSHEARX=2, FSHEARY=3, VRAW=4)
|
||||
|
||||
def read_info(self, *args):
|
||||
if len(args) == 4:
|
||||
return 10.0, 20.0, 30.0, None
|
||||
return 10.0, 20.0, 30.0
|
||||
|
||||
legacy = read_forces_from_sensor(LegacySensor())
|
||||
assert legacy.force_calibrated is False
|
||||
assert legacy.force_unit == "raw"
|
||||
assert legacy.normal_force_raw == 10.0
|
||||
|
||||
|
||||
def test_sdk_worker_packet_mapping() -> None:
|
||||
from sensor_bench.acquisition import SdkAcquisitionWorker
|
||||
|
||||
@@ -104,6 +143,9 @@ def test_sdk_worker_packet_mapping() -> None:
|
||||
assert packet.normal_force == 1.0
|
||||
assert packet.shear_x == 2.0
|
||||
assert packet.shear_y == 3.0
|
||||
assert packet.normal_force_raw == 1.0
|
||||
assert packet.force_unit == "raw"
|
||||
assert packet.force_calibrated is False
|
||||
assert packet.raw_frame.shape[:2] == (1080, 1920)
|
||||
assert packet.processed_frame.shape[:2] == (365, 365)
|
||||
|
||||
@@ -137,6 +179,7 @@ def test_force_calibration_and_plot_min_span() -> None:
|
||||
def test_list_orisys_configs_excludes_options() -> None:
|
||||
from sensor_bench.paths import (
|
||||
config_display_name,
|
||||
list_local_sensor_bundle_names,
|
||||
list_local_sensor_config_files,
|
||||
list_orisys_configs,
|
||||
local_sensor_configs_dir,
|
||||
@@ -147,11 +190,76 @@ def test_list_orisys_configs_excludes_options() -> None:
|
||||
assert "options" not in labels
|
||||
assert all(Path(e).stem.lower() != "options" for e in entries if Path(e).suffix.lower() == ".json")
|
||||
|
||||
bundles = list_local_sensor_bundle_names()
|
||||
if bundles:
|
||||
assert labels[0] in bundles
|
||||
|
||||
local_ddjx = local_sensor_configs_dir() / "ddjx01.json"
|
||||
if local_ddjx.exists():
|
||||
local_files = list_local_sensor_config_files()
|
||||
assert any(p.name == "ddjx01.json" for p in local_files)
|
||||
assert any(config_display_name(e).lower() == "ddjx01" for e in entries)
|
||||
if "box" not in bundles:
|
||||
assert any(config_display_name(e).lower() == "ddjx01" for e in entries)
|
||||
else:
|
||||
assert not any(config_display_name(e).lower() == "ddjx01" for e in entries)
|
||||
|
||||
|
||||
def test_default_config_prefers_box_bundle() -> None:
|
||||
from sensor_bench.paths import (
|
||||
config_display_name,
|
||||
default_config_name,
|
||||
default_ddjx01_config,
|
||||
list_local_sensor_bundle_names,
|
||||
)
|
||||
|
||||
bundles = list_local_sensor_bundle_names()
|
||||
if not bundles:
|
||||
return
|
||||
|
||||
assert default_config_name("orisys") == "box"
|
||||
default = default_ddjx01_config()
|
||||
assert config_display_name(default).lower() == "box"
|
||||
|
||||
|
||||
def test_legacy_config_force_calibration_fallback() -> None:
|
||||
from sensor_bench.acquisition import sensor_force_calibrated
|
||||
from sensor_bench.paths import (
|
||||
bundle_has_force_calibration,
|
||||
local_sensor_configs_dir,
|
||||
resolve_force_bundle_from_config,
|
||||
)
|
||||
|
||||
if not bundle_has_force_calibration("box"):
|
||||
return
|
||||
|
||||
class LegacySensor:
|
||||
pass
|
||||
|
||||
legacy_path = local_sensor_configs_dir() / "ddjx01.json"
|
||||
if legacy_path.exists():
|
||||
assert resolve_force_bundle_from_config(legacy_path) == "box"
|
||||
assert sensor_force_calibrated(LegacySensor(), config_ref=legacy_path) is True
|
||||
|
||||
assert resolve_force_bundle_from_config("ddjx01") == "box"
|
||||
assert resolve_force_bundle_from_config("prototype") == "box"
|
||||
assert sensor_force_calibrated(LegacySensor(), config_ref="ddjx01") is True
|
||||
|
||||
|
||||
def test_normalize_sensor_config_ref_prefers_bundle() -> None:
|
||||
from sensor_bench.paths import (
|
||||
bundle_has_force_calibration,
|
||||
local_sensor_bundle_sensor_json,
|
||||
normalize_sensor_config_ref,
|
||||
)
|
||||
|
||||
if not bundle_has_force_calibration("box"):
|
||||
return
|
||||
|
||||
local_json = local_sensor_bundle_sensor_json("box")
|
||||
assert local_json is not None
|
||||
normalized = normalize_sensor_config_ref("ddjx01")
|
||||
assert Path(normalized).resolve() == local_json.resolve()
|
||||
assert normalize_sensor_config_ref("box") == str(local_json.resolve())
|
||||
|
||||
|
||||
def test_roi_geometry_helpers() -> None:
|
||||
@@ -209,10 +317,13 @@ def test_exhibition_window_offscreen() -> None:
|
||||
assert win.sensor_combo.count() == 2
|
||||
assert win.config_combo is not None
|
||||
assert win.config_combo.count() >= 1
|
||||
from sensor_bench.paths import list_orisys_configs
|
||||
from sensor_bench.paths import config_display_name, default_ddjx01_config, list_orisys_configs
|
||||
|
||||
installed = list_orisys_configs()
|
||||
if "ddjx01" in installed:
|
||||
default = default_ddjx01_config()
|
||||
if config_display_name(default).lower() == "box":
|
||||
assert config_display_name(win._selected_config()).lower() == "box"
|
||||
elif "ddjx01" in installed:
|
||||
assert win.config_combo.currentData() == "ddjx01" or win._selected_config() == "ddjx01"
|
||||
|
||||
win.language_combo.setCurrentIndex(1)
|
||||
@@ -222,6 +333,18 @@ def test_exhibition_window_offscreen() -> None:
|
||||
assert win.btn_reset.text() == "Reset"
|
||||
assert win.show_log_check.text() == "Show log panel"
|
||||
assert "About" in win.about_action.text()
|
||||
title0 = win.plots[0].titleLabel.text
|
||||
assert "FN" in title0
|
||||
assert "raw" in title0
|
||||
|
||||
from sensor_bench.force_calibration import CALIBRATED_FORCE_Y_MAX, CALIBRATED_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
|
||||
|
||||
win.view_combo.setCurrentIndex(1)
|
||||
assert win._view_mode == "captured"
|
||||
@@ -235,9 +358,13 @@ def test_exhibition_window_offscreen() -> None:
|
||||
if __name__ == "__main__":
|
||||
test_load_fixed_mode()
|
||||
test_translator_chinese_default()
|
||||
test_read_forces_from_sensor()
|
||||
test_sdk_worker_packet_mapping()
|
||||
test_force_calibration_and_plot_min_span()
|
||||
test_list_orisys_configs_excludes_options()
|
||||
test_default_config_prefers_box_bundle()
|
||||
test_legacy_config_force_calibration_fallback()
|
||||
test_normalize_sensor_config_ref_prefers_bundle()
|
||||
test_roi_geometry_helpers()
|
||||
test_exhibition_window_offscreen()
|
||||
print("ok")
|
||||
|
||||
Reference in New Issue
Block a user