Backlash correction as global, more comments

This commit is contained in:
jaknapper 2025-06-16 17:03:50 +01:00
parent 712f524414
commit 0671f2d1be

View file

@ -33,6 +33,7 @@ from .capture import CaptureThing
CaptureDep = direct_thing_client_dependency(CaptureThing, "/capture/") CaptureDep = direct_thing_client_dependency(CaptureThing, "/capture/")
SETTLING_TIME = 0.3 SETTLING_TIME = 0.3
BACKLASH_CORRECTION = 250
class JPEGSharpnessMonitor: class JPEGSharpnessMonitor:
@ -294,8 +295,8 @@ class AutofocusThing(Thing):
logger: InvocationLogger, logger: InvocationLogger,
metadata_getter: GetThingStates, metadata_getter: GetThingStates,
capture: CaptureDep, capture: CaptureDep,
images_dir: str,
sharpness_monitor: SharpnessMonitorDep, sharpness_monitor: SharpnessMonitorDep,
images_dir: str,
) -> None: ) -> None:
"""Run a z stack, saving all images to stack_dir and copying the """Run a z stack, saving all images to stack_dir and copying the
central image to stack_dir""" central image to stack_dir"""
@ -312,10 +313,11 @@ class AutofocusThing(Thing):
stack_z_range = stack_dz * (images_to_test - 1) stack_z_range = stack_dz * (images_to_test - 1)
overshoot = stack_dz * 5 overshoot = stack_dz * 5
backlash_correction = 250
stage.move_relative(z=-(overshoot + backlash_correction + stack_z_range / 2)) # Move down by the height of the z stack, plus an overshoot
stage.move_relative(z=backlash_correction) # Better to start too low and take too many images than too high and need to refocus
stage.move_relative(z=-(overshoot + BACKLASH_CORRECTION + stack_z_range / 2))
stage.move_relative(z=BACKLASH_CORRECTION)
continue_stack = True continue_stack = True
captures = [] captures = []
@ -326,7 +328,6 @@ class AutofocusThing(Thing):
while continue_stack: while continue_stack:
time.sleep(SETTLING_TIME) time.sleep(SETTLING_TIME)
stage_location = stage.position stage_location = stage.position
jpeg_path = os.path.join( jpeg_path = os.path.join(
@ -344,11 +345,12 @@ class AutofocusThing(Thing):
# If the stack isn't complete yet, move # If the stack isn't complete yet, move
if capture_count >= images_to_test: if capture_count >= images_to_test:
logger.info(sharpnesses[-images_to_test:])
stack_result = self.test_stack(sharpnesses[-images_to_test:]) stack_result = self.test_stack(sharpnesses[-images_to_test:])
if stack_result == "success": if stack_result == "success":
continue_stack = False continue_stack = False
# These are signs of overshooting. Autofocus and retry
elif stack_result == "restart" or capture_count > 20: elif stack_result == "restart" or capture_count > 20:
captures = [] captures = []
sharpnesses = [] sharpnesses = []
@ -361,12 +363,13 @@ class AutofocusThing(Thing):
dz=2000, dz=2000,
) )
stage.move_relative( stage.move_relative(
z=-(overshoot + backlash_correction + stack_z_range / 2) z=-(overshoot + BACKLASH_CORRECTION + stack_z_range / 2)
) )
stage.move_relative(z=backlash_correction) stage.move_relative(z=BACKLASH_CORRECTION)
stage.move_relative(z=stack_dz) stage.move_relative(z=stack_dz)
sharpest_index = np.argmax(sharpnesses[-images_to_test:]) sharpest_index = np.argmax(sharpnesses[-images_to_test:])
capture._save_capture( capture._save_capture(
jpeg_path=captures[-images_to_test:][sharpest_index][0], jpeg_path=captures[-images_to_test:][sharpest_index][0],
image=captures[-images_to_test:][sharpest_index][1], image=captures[-images_to_test:][sharpest_index][1],
@ -377,20 +380,24 @@ class AutofocusThing(Thing):
return heights[-images_to_test:][sharpest_index] return heights[-images_to_test:][sharpest_index]
def test_stack(self, sharpnesses: list): def test_stack(self, sharpnesses: list):
"""Test a list of sharpnesses, to decide whether the focal plane is within them""" """Test a list of sharpnesses, to decide whether the sharpest image from a stack is within them"""
sharpest_index = np.argmax(sharpnesses) sharpest_index = np.argmax(sharpnesses)
sharpness_length = len(sharpnesses) sharpness_length = len(sharpnesses)
# If only testing one image, assume focus succeeded
if sharpness_length == 1: if sharpness_length == 1:
return "success" return "success"
# If testing three images, test if the centre is the sharpest
if sharpness_length == 3: if sharpness_length == 3:
if sharpest_index == 1: if sharpest_index == 1:
return "success" return "success"
exclusion_range = 3 # For larger stacks, test if the best image is not within two of the edge of the stack
# ie for a stack of 7 images, best image must be between 3rd and and 5th
exclusion_range = 2
if sharpest_index < exclusion_range: if sharpest_index < exclusion_range:
return "restart" return "restart"
if sharpest_index >= len(sharpnesses) - exclusion_range: if sharpest_index >= sharpness_length - exclusion_range:
return "continue" return "continue"
return "success" return "success"