Skip to content

Hardware/feature/liquid lense#363

Open
Yasserelhaddar wants to merge 11 commits intodevfrom
hardware/feature/liquid_lense
Open

Hardware/feature/liquid lense#363
Yasserelhaddar wants to merge 11 commits intodevfrom
hardware/feature/liquid_lense

Conversation

@Yasserelhaddar
Copy link
Collaborator

Liquid Lens & Autofocus Control

Summary

Adds hardware-level liquid lens and autofocus control for Basler cameras with connected Optotune ECC controllers. The feature spans all architecture layers — backend, core wrappers, service endpoints, and documentation — following the existing optional-capability pattern.

Changes by Layer

Backend (cameras/backends/)

  • 7 optional methods added to CameraBackend base class (log + raise NotImplementedError)
  • Full Basler implementation: auto-detects lens via LensConnection GenICam node
  • get_lens_status() returns a data dict (no exception) even for cameras without a lens
  • Optical power get/set with range validation, one-shot autofocus with accuracy selection and polling
  • Focus config mapping to GenICam nodes (ROI, stepper, edge detection, source)
  • export_config / import_config extended with lens parameters

Core (cameras/core/)

  • 7 async methods on AsyncCamera (lock-protected for setters)
  • 7 sync wrappers on Camera
  • configure() accepts optical_power; supports_feature reports liquid_lens

Service (services/cameras/)

  • 6 REST endpoints under cameras/lens/ and cameras/focus/
  • Request models: OpticalPowerRequest, TriggerAutofocusRequest, FocusConfigRequest
  • Response models: LensStatus, LensStatusResponse
  • TaskSchemas for MCP tool exposure
  • /cameras/capabilities now includes supports_liquid_lens

Documentation

  • Camera service README: focus control endpoints, MCP tools, configuration parameters
  • Hardware README: usage example, auto-detection notes

How It Works

from mindtrace.hardware.cameras.core.camera import Camera

camera = Camera(name="Basler:ace2_001")

# Auto-detection — no exception for unsupported cameras
status = camera.get_lens_status()
if status["connected"]:
    # Manual focus control
    camera.set_optical_power(5.0)  # diopters

    # One-shot autofocus (contrast-based)
    camera.trigger_autofocus(accuracy="Accurate")

    # Fine-tune AF behavior
    camera.set_focus_config(roi_size="Size64", edge_detection=True)

camera.close()

Via REST:

curl -X POST http://localhost:8002/cameras/focus/autofocus \
  -H "Content-Type: application/json" \
  -d '{"camera": "Basler:ace2_001", "accuracy": "Normal"}'

Add 7 optional methods to CameraBackend base class for liquid lens
support: get_lens_status, get/set_optical_power, get_optical_power_range,
trigger_autofocus, get/set_focus_config. Follows the existing pattern
where base methods log error and raise NotImplementedError.
Add full liquid lens support for Basler cameras with Optotune ECC
controllers. Auto-detects lens capability via LensConnection node.

- _has_liquid_lens / _is_lens_connected helpers for auto-detection
- get_lens_status returns data dict (no exception) for any camera
- get/set_optical_power with range validation
- trigger_autofocus with accuracy selection and polling
- get/set_focus_config mapping to GenICam focus nodes
- export_config / import_config extended with lens parameters
Add 7 delegating methods to AsyncCamera (with lock for setters) and
7 sync wrappers to Camera. Update configure() to handle optical_power
and supports_feature dict to report liquid_lens capability.
Add 6 service endpoints under cameras/lens/ and cameras/focus/:
- get_lens_status, get/set_optical_power, trigger_autofocus,
  get/set_focus_config

Includes request models (OpticalPowerRequest, TriggerAutofocusRequest,
FocusConfigRequest), response models (LensStatus, LensStatusResponse),
TaskSchemas, and capability/configuration reporting updates.
28 tests covering lens detection, optical power get/set with range
validation, autofocus polling, focus config read/write, and graceful
handling of cameras without liquid lens support.

Adds MockPylonCameraWithLens with simulated GenICam lens/focus nodes
and _AutofocusMockParam that simulates AF completion behavior.
…autofocus

- _has_liquid_lens: pypylon raises LogicalErrorException (not
  AttributeError) for missing nodes in __getattr__, so hasattr()
  is unreliable. Use try/except around direct node access instead.
- trigger_autofocus: ensure camera is grabbing before triggering AF,
  as contrast-based autofocus requires live image frames. Restore
  previous grab state after AF completes.
- get_optical_power_range: catch CameraConfigurationError in core
  wrapper for cameras without lens support.
Add focus control endpoints, MCP tools, and configuration parameters
to the camera service README. Add usage example and auto-detection
notes to the hardware README.
@Yasserelhaddar Yasserelhaddar self-assigned this Feb 11, 2026
@Yasserelhaddar Yasserelhaddar added enhancement New feature or request mindtrace-hardware Issues raised from hardware module in mindtrace package labels Feb 11, 2026
Base automatically changed from hardware/feature/photoneo to dev February 26, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request mindtrace-hardware Issues raised from hardware module in mindtrace package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants