Add Trigger functionality to Basler backend#81
Draft
C-Achard wants to merge 8 commits into
Draft
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the Basler camera backend with trigger configuration support (hardware trigger input + master output + early software-trigger hooks), and updates the trigger configuration UI to be backend-aware (Basler vs GenTL). It also attempts to reduce log spam when follower/external cameras are waiting for trigger pulses.
Changes:
- Added Basler backend trigger configuration parsing and GenICam/pypylon feature configuration (plus timeout handling and best-effort restore on close).
- Updated trigger settings dialog to use backend-specific UI profiles (show/hide relevant fields and provide backend-appropriate suggestions).
- Introduced throttled logging for “waiting for hardware trigger” timeouts (currently implemented incorrectly; see comments).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
dlclivegui/services/multi_camera_controller.py |
Adds throttled logging for trigger-wait timeouts (but currently breaks at runtime due to method placement/state). |
dlclivegui/gui/main_window.py |
Removes in-file pypylon emulation env var snippet from the main window module. |
dlclivegui/gui/camera_config/trigger_config_dialog.py |
Makes the trigger dialog backend-aware via TriggerUiProfile and hides irrelevant fields for Basler/GenTL. |
dlclivegui/gui/camera_config/camera_config_dialog.py |
Ensures default trigger config is created for Basler as well as GenTL. |
dlclivegui/cameras/backends/basler_backend.py |
Implements Basler trigger settings parsing and configuration, adds trigger capabilities, and adjusts read timeouts for trigger-wait mode. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
122
to
+126
| # In hardware-trigger mode, a timeout usually means: | ||
| # "no trigger pulse arrived during this poll interval". | ||
| # This is expected and should not count as a camera failure. | ||
| if bool(getattr(self._backend, "waits_for_hardware_trigger", False)): | ||
| LOGGER.debug( | ||
| "[Worker %s] waiting for hardware trigger: %s", | ||
| self._camera_id, | ||
| exc, | ||
| ) | ||
| self._log_trigger_wait_throttled(exc) |
Comment on lines
+282
to
+286
| now = time.monotonic() | ||
|
|
||
| if now - self._last_trigger_wait_log < self._trigger_wait_log_interval: | ||
| self._trigger_wait_suppressed_count += 1 | ||
| return |
Comment on lines
+18
to
+26
| # NOTE @C-Achard: This could be added in settings eventually | ||
| # Forces pypylon to create N emulation virtual cameras, | ||
| # mostly for testing. This should not be enabled for release. | ||
| ENABLE_PYLON_EMU = True | ||
| if ENABLE_PYLON_EMU: | ||
| import os | ||
|
|
||
| os.environ["PYLON_CAMEMU"] = "4" | ||
|
|
Comment on lines
+447
to
+449
| self._debug_trigger_nodes(context="before configuration") | ||
| self._configure_trigger() | ||
| self._debug_trigger_nodes(context="after configuration") |
Comment on lines
552
to
555
| except Exception as exc: | ||
| if self.waits_for_hardware_trigger: | ||
| raise TimeoutError(f"Basler timeout while waiting for hardware trigger: {exc}") from exc | ||
| raise RuntimeError("Failed to retrieve image from Basler camera.") from exc |
b1337ba to
732f5fd
Compare
Implement comprehensive trigger support for the Basler backend: import CameraTriggerSettings, parse trigger config (roles: off, external/follower, software, master), and persist trigger_actual into the namespace. Add trigger configuration helpers (_configure_trigger*, _resolve_trigger_source, _restore_trigger_idle), software trigger execution (trigger_once), and many feature/enum/numeric helper methods with debug logging. Make RetrieveResult use a configurable _retrieve_timeout_ms (derived from trigger.timeout) and limit it for hardware-triggered cameras to allow prompt shutdown; raise a TimeoutError when waiting for hardware triggers. Expose hardware_trigger capability as BEST_EFFORT and add an env var-based pylon emulation toggle for testing. Misc: add debug dumps of trigger-related nodes and best-effort restore of trigger state on close.
Delete commented-out code that forced pypylon to create emulation virtual cameras (PYLON_CAMEMU), which was only intended for testing and should not be enabled for release. Also remove an extraneous blank line to tidy up the file.
Introduce a TriggerUiProfile dataclass and trigger_ui_profile_for_backend() to drive dialog presentation per backend. Replace free-text source field with an editable QComboBox providing backend suggestions and defaults. Add profile-driven visibility/enabling for input, master, software and strobe/line output fields, plus helper methods to manage form rows and combo text. Only include strobe-related payload fields when the backend profile exposes them. Misc: expand info/help text, show backend in group title, increase dialog min-width, refine tooltips, and improve model↔UI mapping and payload construction.
Previously the default trigger configuration was only applied for backend 'gentl' and always stored under the 'gentl' properties key. This change treats the backend name dynamically (accepting both 'gentl' and 'basler'), and stores the default trigger settings under the actual backend key in cam.properties. Also preserves behavior when cam.properties or the backend namespace is not a dict.
Reduce log flooding when waiting for hardware triggers by adding throttled logging. Changes in dlclivegui/services/multi_camera_controller.py: - Import time. - Add a new _log_interval_while_waiting_for_trigger_s attribute to SingleCameraWorker. - Replace the direct LOGGER.debug call for expected trigger wait timeouts with a call to _log_trigger_wait_throttled. - Implement _log_trigger_wait_throttled to suppress repeated timeout messages, emit a consolidated debug message, and report how many repeated logs were suppressed. This prevents high-frequency expected poll-timeout logs (common in trigger-waiting modes) from overwhelming the logs.
Extend the test conftest FakePylon to better emulate pypylon: add FakePylonTimeoutException, richer _Feature (symbolics, min/max/inc, read/write checks, call tracking), _EnumEntry, expanded _DeviceInfo, GrabResult.release tracking, and a more complete InstantCamera (timeouts, software trigger, trigger/line features, buffer and grab controls, test knobs). Reset the fake factory and provide default fake devices and a basler_settings_factory fixture. Patch the basler SDK fixture to use FakePylon. Add new test suite tests/cameras/backends/test_basler_backend.py covering lifecycle (open/read/close, fast-start, idempotent close), discovery/rebind, resolution/exposure/gain/fps handling, and comprehensive trigger behavior (follower/master/software/external) to validate backend logic.
cc59691 to
ab3d764
Compare
Add throttled logging for hardware-trigger wait timeouts in SingleCameraWorker to avoid noisy repeated timeout messages. Introduce _trigger_wait_log_interval, _last_trigger_wait_log and _trigger_wait_suppressed_count and move _log_trigger_wait_throttled into the worker; remove the duplicate implementation from MultiCameraController. Also mark the Basler software-trigger test as xfail because software trigger support is not implemented yet.
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.
Scope
Motivation
Adds the possibility to setup master/follower or software-controlled camera schemes to the Basler backend so as to obtain viable files for DLC3D or other experimental work.