Open
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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/)CameraBackendbase class (log +raise NotImplementedError)LensConnectionGenICam nodeget_lens_status()returns a data dict (no exception) even for cameras without a lensexport_config/import_configextended with lens parametersCore (
cameras/core/)AsyncCamera(lock-protected for setters)Cameraconfigure()acceptsoptical_power;supports_featurereportsliquid_lensService (
services/cameras/)cameras/lens/andcameras/focus/OpticalPowerRequest,TriggerAutofocusRequest,FocusConfigRequestLensStatus,LensStatusResponse/cameras/capabilitiesnow includessupports_liquid_lensDocumentation
How It Works
Via REST: