<feed xmlns='http://www.w3.org/2005/Atom'>
<title>labUI.git/plugins/motion_capture/device.py, branch main</title>
<subtitle>Data acquisition program written in Python for use with serial communication devices.
</subtitle>
<id>https://git.kolset.xyz/labUI.git/atom?h=main</id>
<link rel='self' href='https://git.kolset.xyz/labUI.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.kolset.xyz/labUI.git/'/>
<updated>2026-07-29T19:03:24Z</updated>
<entry>
<title>Add editable device display name, persist it across profile save/load</title>
<updated>2026-07-29T19:03:24Z</updated>
<author>
<name>Christian Kolset</name>
<email>ckolset@colostate.edu</email>
</author>
<published>2026-07-29T19:03:24Z</published>
<link rel='alternate' type='text/html' href='https://git.kolset.xyz/labUI.git/commit/?id=d9ca58e48cf92438087ac24ee261c2c4911316b1'/>
<id>urn:sha1:d9ca58e48cf92438087ac24ee261c2c4911316b1</id>
<content type='text'>
DeviceInfo.name existed but was hardcoded per device type and never
operator-editable. Adds a Display Name field to Add Device and makes
the Info-tab Name field in the device config dialog editable, and
threads the name through get_save_config()/ProfileManager.apply() so
a custom name survives a .labdaq save/reload instead of reverting to
the type default. Name is applied post-construction rather than as a
constructor kwarg, since no device factory declares a "name" param.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Motion capture: profile support, FPS config, persistent tracking, window state</title>
<updated>2026-06-10T01:39:35Z</updated>
<author>
<name>Christian Kolset</name>
<email>christian.kolset@gmail.com</email>
</author>
<published>2026-06-10T01:39:35Z</published>
<link rel='alternate' type='text/html' href='https://git.kolset.xyz/labUI.git/commit/?id=b776e70b4cd94c5d1f53dde39b2e46f6447cac3e'/>
<id>urn:sha1:b776e70b4cd94c5d1f53dde39b2e46f6447cac3e</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Upgrade motion capture: template matching, frame-freeze selection, resolution</title>
<updated>2026-06-10T00:47:49Z</updated>
<author>
<name>Christian Kolset</name>
<email>christian.kolset@gmail.com</email>
</author>
<published>2026-06-10T00:47:49Z</published>
<link rel='alternate' type='text/html' href='https://git.kolset.xyz/labUI.git/commit/?id=898fde4dc286517cb27590b2f9cd7406d9922bd4'/>
<id>urn:sha1:898fde4dc286517cb27590b2f9cd7406d9922bd4</id>
<content type='text'>
Tracking:
- Add "template" mode (default) using snapshot + shape-masked matchTemplate
- Add "csrt" mode as alternative for texture-rich targets
- set_roi_rect(x, y, w, h, frame_rgb) initialises from exact selection rect
- set_roi() delegates to set_roi_rect (centred square, backwards-compat)
- start() accepts resolution=(w, h) to set camera capture resolution

Selection UX:
- Replace QLabel feed with FrameSelector widget (custom QWidget)
- "Click to Track" freezes frame; user scrolls to zoom (anchored to cursor),
  right-drags to pan, left-drags to draw rubber-band selection
- Shape preview: rectangle or inscribed ellipse depending on mode
- "Confirm Selection" extracts template from frozen frame and starts tracking
- "Clear" cancels selection or clears active tracking

Configuration:
- CameraPanel adds Resolution combo (Default / 640×480 / 720p / 1080p / 1440p)
- CameraDevice stores and forwards resolution to tracker.start()
- Template Match listed first in Mode combo; shape combo hidden for CSRT

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Redesign motion capture plugin as Camera device type</title>
<updated>2026-06-04T18:41:14Z</updated>
<author>
<name>Christian Kolset</name>
<email>christian.kolset@gmail.com</email>
</author>
<published>2026-06-04T18:29:24Z</published>
<link rel='alternate' type='text/html' href='https://git.kolset.xyz/labUI.git/commit/?id=864642a84d8e93cc4971c7915e39a60740cdd6fa'/>
<id>urn:sha1:864642a84d8e93cc4971c7915e39a60740cdd6fa</id>
<content type='text'>
Plugin now registers a "Camera" option in the Add Device dialog on load
(removes it on unload) instead of auto-creating a single device.

- camera_panel.py (new): CameraPanel with CameraScanThread that probes
  OpenCV indices 0–5, lists found cameras with resolution, shows
  "No cameras detected" when none available, simulation checkbox.
  build_device() returns CameraDevice for the selected index.

- device.py: rewrite MotionCaptureDevice → CameraDevice. Each instance
  owns its own CameraTracker created in connect(). Status is CONNECTED
  or SIMULATED based on tracker.simulated. get_config_widget() shows
  source/status and an "Open Camera View" button that launches the
  existing MotionCaptureWindow for that device's tracker. Backward-compat
  alias MotionCaptureDevice = CameraDevice kept for saved profiles.

- plugin.py: simplified to on_load/_PANELS registration + pixel_to_mm
  filter. No auto-devices, no toolbar button, no settings widget.

Camera data flows through the standard Device → Signal → Channel → Plot
pipeline like any other device.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Added Motion Capture plugin</title>
<updated>2026-06-03T15:50:17Z</updated>
<author>
<name>Christian Kolset</name>
<email>christian.kolset@gmail.com</email>
</author>
<published>2026-05-07T19:42:30Z</published>
<link rel='alternate' type='text/html' href='https://git.kolset.xyz/labUI.git/commit/?id=8e5d0aec942fb9c49040fc525f0d697fd24d7c2f'/>
<id>urn:sha1:8e5d0aec942fb9c49040fc525f0d697fd24d7c2f</id>
<content type='text'>
Tracks a user-selected point via webcam (OpenCV CSRT tracker) and
streams x_pos / y_pos pixel coordinates as live channels into the
acquisition pipeline. Falls back to a Lissajous figure simulation
when opencv-python is not installed, so the plugin works immediately
without hardware.

- tracker.py: background thread, real camera + sim modes, thread-safe API
- device.py: BaseDevice reading x/y from tracker, wires into engine
- filter.py: custom pixel_to_mm filter (registered in FILTER_CLASSES)
- window.py: floating tool window, live feed, click-to-track ROI selection
- plugin.py: LabPlugin wiring all pieces together, toolbar button,
  settings widget, profile save/restore

Also: PluginAction.button_ref_callback lets plugins store a ref to their
toolbar button so they can uncheck it when their window closes.

opencv-python install note added to requirements.txt.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
