Skip to content

Commit

Permalink
impl: callbacks, move hw func to init, more plumb
Browse files Browse the repository at this point in the history
  • Loading branch information
ianohara committed Feb 24, 2025
1 parent c24697e commit 31e8a7b
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 31 deletions.
17 changes: 9 additions & 8 deletions software/control/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ def on_new_frame(self, frame: squid.abc.CameraFrame):
self.handler_busy = False
camera.image_locked = False


class ImageSaver(QObject):

stop_recording = Signal()
Expand Down Expand Up @@ -597,7 +598,7 @@ def start_live(self):
if self.trigger_mode == TriggerMode.SOFTWARE or (
self.trigger_mode == TriggerMode.HARDWARE and self.use_internal_timer_for_hardware_trigger
):
self.camera.enable_callback() # in case it's disabled e.g. by the laser AF controller
self.camera.enable_callbacks(True) # in case it's disabled e.g. by the laser AF controller
self._start_triggerred_acquisition()
# if controlling the laser displacement measurement camera
if self.for_displacement_measurement:
Expand Down Expand Up @@ -1120,7 +1121,7 @@ def autofocus(self, focus_map_override=False):
# temporarily disable call back -> image does not go through streamHandler
if self.camera.callback_is_enabled:
self.callback_was_enabled_before_autofocus = True
self.camera.disable_callback()
self.camera.enable_callbacks(False)
else:
self.callback_was_enabled_before_autofocus = False

Expand Down Expand Up @@ -1153,7 +1154,7 @@ def autofocus(self, focus_map_override=False):
def _on_autofocus_completed(self):
# re-enable callback
if self.callback_was_enabled_before_autofocus:
self.camera.enable_callback()
self.camera.enable_callbacks(True)

# re-enable live if it's previously on
if self.was_live_before_autofocus:
Expand Down Expand Up @@ -2323,7 +2324,7 @@ def run_acquisition(self):
# disable callback
if self.camera.callback_is_enabled:
self.camera_callback_was_enabled_before_multipoint = True
self.camera.disable_callback()
self.camera.enable_callbacks(False)
else:
self.camera_callback_was_enabled_before_multipoint = False

Expand Down Expand Up @@ -2488,7 +2489,7 @@ def _on_acquisition_completed(self):

# re-enable callback
if self.camera_callback_was_enabled_before_multipoint:
self.camera.enable_callback()
self.camera.enable_callbacks(True)
self.camera_callback_was_enabled_before_multipoint = False

# re-enable live if it's previously on
Expand Down Expand Up @@ -2617,7 +2618,7 @@ def start_tracking(self):
# disable callback
if self.camera.callback_is_enabled:
self.camera_callback_was_enabled_before_tracking = True
self.camera.disable_callback()
self.camera.enable_callbacs(False)
else:
self.camera_callback_was_enabled_before_tracking = False

Expand Down Expand Up @@ -2662,7 +2663,7 @@ def _on_tracking_stopped(self):

# re-enable callback
if self.camera_callback_was_enabled_before_tracking:
self.camera.enable_callback()
self.camera.enable_callbacks(True)
self.camera_callback_was_enabled_before_tracking = False

# re-enable live if it's previously on
Expand Down Expand Up @@ -4976,7 +4977,7 @@ def _get_laser_spot_centroid(self) -> Optional[Tuple[float, float]]:
Optional[Tuple[float, float]]: (x,y) coordinates of spot centroid, or None if detection fails
"""
# disable camera callback
self.camera.disable_callback()
self.camera.enable_callbacks(False)

successful_detections = 0
tmp_x = 0
Expand Down
34 changes: 18 additions & 16 deletions software/control/core_PDAF.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,25 @@
import os

os.environ["QT_API"] = "pyqt5"
import qtpy

# qt libraries
from qtpy.QtCore import *
from qtpy.QtWidgets import *
from qtpy.QtGui import *

import control.utils as utils
from control._def import *
from control.core import *
import control.tracking as tracking

from queue import Queue
from threading import Thread, Lock
import time
import numpy as np
import pyqtgraph as pg
import cv2
from datetime import datetime

import skimage # pip3 install -U scikit-image
import skimage.registration

import squid.camera.utils
from squid.abc import AbstractCamera


class PDAFController(QObject):

Expand Down Expand Up @@ -112,12 +108,18 @@ class TwoCamerasPDAFCalibrationController(QObject):
z_pos = Signal(float)

def __init__(
self, camera1, camera2, navigationController, liveController1, liveController2, configurationManager=None
self,
camera1: AbstractCamera,
camera2: AbstractCamera,
navigationController,
liveController1,
liveController2,
configurationManager=None,
):
QObject.__init__(self)

self.camera1 = camera1
self.camera2 = camera2
self.camera1: AbstractCamera = camera1
self.camera2: AbstractCamera = camera2
self.navigationController = navigationController
self.liveController1 = liveController1
self.liveController2 = liveController2
Expand Down Expand Up @@ -210,18 +212,18 @@ def run_acquisition(self): # @@@ to do: change name to run_experiment
self.liveController2.was_live_before_multipoint = False

# disable callback
if self.camera1.callback_is_enabled:
if self.camera1.get_callbacks_enabled():
self.camera1.callback_was_enabled_before_multipoint = True
self.camera1.stop_streaming()
self.camera1.disable_callback()
self.camera1.enable_callbacks(False)
self.camera1.start_streaming() # @@@ to do: absorb stop/start streaming into enable/disable callback - add a flag is_streaming to the camera class
else:
self.camera1.callback_was_enabled_before_multipoint = False
# disable callback
if self.camera2.callback_is_enabled:
if self.camera2.get_callbacks_enabled():
self.camera2.callback_was_enabled_before_multipoint = True
self.camera2.stop_streaming()
self.camera2.disable_callback()
self.camera2.enable_callbacks(False)
self.camera2.start_streaming() # @@@ to do: absorb stop/start streaming into enable/disable callback - add a flag is_streaming to the camera class
else:
self.camera2.callback_was_enabled_before_multipoint = False
Expand All @@ -232,13 +234,13 @@ def run_acquisition(self): # @@@ to do: change name to run_experiment
# re-enable callback
if self.camera1.callback_was_enabled_before_multipoint:
self.camera1.stop_streaming()
self.camera1.enable_callback()
self.camera1.enable_callbacks(True)
self.camera1.start_streaming()
self.camera1.callback_was_enabled_before_multipoint = False
# re-enable callback
if self.camera2.callback_was_enabled_before_multipoint:
self.camera2.stop_streaming()
self.camera2.enable_callback()
self.camera2.enable_callbacks(True)
self.camera2.start_streaming()
self.camera2.callback_was_enabled_before_multipoint = False

Expand Down
35 changes: 28 additions & 7 deletions software/control/gui_hcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os

import control.lighting
from squid.abc import CameraAcquisitionMode

os.environ["QT_API"] = "pyqt5"
import serial
Expand Down Expand Up @@ -104,8 +105,26 @@ class HighContentScreeningGui(QMainWindow):
def __init__(self, is_simulation=False, live_only_mode=False, *args, **kwargs):
super().__init__(*args, **kwargs)
self.microcontroller: Optional[microcontroller.Microcontroller] = None

def acquisition_camera_hw_trigger_fn(illumination_time: Optional[float]) -> bool:
# NOTE(imo): If this succeeds, it means means we sent the request,
# but we didn't necessarily get confirmation of success.
self.microcontroller.send_hardware_trigger(
True if illumination_time else False, 1000.0 * illumination_time if illumination_time else 0
)
return True

def acquisition_camera_hw_strobe_delay_fn(strobe_delay_ms: float) -> bool:
self.microcontroller.set_strobe_delay_us(1000 * strobe_delay_ms)
self.microcontroller.wait_till_operation_is_completed()

return True

self.camera: squid.abc.AbstractCamera = squid.camera.utils.get_camera(
squid.config.get_camera_config(), simulated=is_simulation
squid.config.get_camera_config(),
simulated=is_simulation,
hw_trigger_fn=acquisition_camera_hw_trigger_fn,
hw_set_strobe_delay_ms_fn=acquisition_camera_hw_strobe_delay_fn,
)
self.camera_focus: Optional[squid.abc.AbstractCamera] = None
if SUPPORT_LASER_AUTOFOCUS:
Expand Down Expand Up @@ -452,17 +471,19 @@ def setupHardware(self):
self.log.error("Setup timed out, resetting microcontroller before failing gui setup")
self.microcontroller.reset()
raise e
self.camera.set_software_triggered_acquisition()
self.camera.set_callback(self.streamHandler.on_new_frame)
self.camera.enable_callback()
self.camera.set_acquisition_mode(CameraAcquisitionMode.SOFTWARE_TRIGGER)
self.camera.add_frame_callback(self.streamHandler.on_new_frame)
self.camera.enable_callbacks(enabled=True)

if CAMERA_TYPE == "Toupcam":
self.camera.set_reset_strobe_delay_function(self.liveController.reset_strobe_arugment)

if SUPPORT_LASER_AUTOFOCUS:
self.camera_focus.set_software_triggered_acquisition() # self.camera.set_continuous_acquisition()
self.camera_focus.set_callback(self.streamHandler_focus_camera.on_new_frame)
self.camera_focus.enable_callback()
self.camera_focus.set_acquisition_mode(
CameraAcquisitionMode.SOFTWARE_TRIGGER
) # self.camera.set_continuous_acquisition()
self.camera_focus.add_frame_callback(self.streamHandler_focus_camera.on_new_frame)
self.camera_focus.enable_callbacks(enabled=True)
self.camera_focus.start_streaming()

if USE_SQUID_FILTERWHEEL:
Expand Down

0 comments on commit 31e8a7b

Please sign in to comment.