From b776e70b4cd94c5d1f53dde39b2e46f6447cac3e Mon Sep 17 00:00:00 2001 From: Christian Kolset Date: Tue, 9 Jun 2026 19:39:35 -0600 Subject: Motion capture: profile support, FPS config, persistent tracking, window state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Profile integration: - CameraDevice.get_save_config() serialises camera_index, simulate, resolution, fps — cameras now persist in .labdaq profiles - ProfileManager.register/unregister_device_factory() lets plugins register their device classes for profile restoration without core → plugin dependency - MotionCapturePlugin registers CameraDevice factory on load/unload Camera configuration: - Add Frame Rate combo to CameraPanel (Default/15/24/30/60/120 fps) defaults to 30 fps; flows through to CAP_PROP_FPS on connect - tracker.start() accepts fps param alongside existing resolution Tracking persistence: - CameraTracker.is_running() — checks thread alive state - MotionCaptureWindow initialises _connected from tracker.is_running() so reopening the window resumes the live feed without restarting the camera or losing the active tracking state Window state: - Plugin saves px_per_mm + camera_idx when window closes - Reopened window restores saved values and syncs mode/shape UI from tracker state via restore_ui_state() (signals blocked to avoid resetting tracker) - Window type changed to Qt.WindowType.Window for independent close button on all Linux WMs Co-Authored-By: Claude Sonnet 4.6 --- plugins/motion_capture/tracker.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'plugins/motion_capture/tracker.py') diff --git a/plugins/motion_capture/tracker.py b/plugins/motion_capture/tracker.py index ffc9f25..8dc89f1 100644 --- a/plugins/motion_capture/tracker.py +++ b/plugins/motion_capture/tracker.py @@ -128,7 +128,8 @@ class CameraTracker: # ── Start / stop ────────────────────────────────────────────────────── def start(self, camera_index: int = 0, - resolution: Optional[Tuple[int, int]] = None) -> bool: + resolution: Optional[Tuple[int, int]] = None, + fps: Optional[int] = None) -> bool: self.stop() self._running = True @@ -145,6 +146,8 @@ class CameraTracker: if resolution: cap.set(cv2.CAP_PROP_FRAME_WIDTH, resolution[0]) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, resolution[1]) + if fps: + cap.set(cv2.CAP_PROP_FPS, fps) if cap.isOpened(): with self._lock: self._cap = cap @@ -271,6 +274,9 @@ class CameraTracker: with self._lock: return self._lost + def is_running(self) -> bool: + return self._running and self._thread is not None and self._thread.is_alive() + @property def fps(self) -> float: return self._fps -- cgit v1.2.3