fix(flomni): Fix logic for flomni scan, avoid resetting positions.
CI for csaxs_bec / test (push) Failing after 1m54s
CI for csaxs_bec / test (pull_request) Failing after 1m51s

This commit is contained in:
2026-03-13 14:02:07 +01:00
parent 97731e658a
commit 757c4e3dc1
2 changed files with 31 additions and 18 deletions
+17 -13
View File
@@ -92,7 +92,8 @@ class RtFlomniController(Controller):
parent._min_scan_buffer_reached = False
start_time = time.time()
for pos_index, pos in enumerate(positions):
parent.socket_put_and_receive(f"s{pos[0]:.05f},{pos[1]:.05f},{pos[2]:.05f}")
cmd = f"s{pos[0]:.05f},{pos[1]:.05f},{pos[2]:.05f}"
parent.socket_put_and_receive(cmd)
if pos_index > 100:
parent._min_scan_buffer_reached = True
parent._min_scan_buffer_reached = True
@@ -174,11 +175,12 @@ class RtFlomniController(Controller):
self.set_device_read_write("foptx", False)
self.set_device_read_write("fopty", False)
def move_samx_to_scan_region(self, fovx: float, cenx: float):
#new routine not using fovx anymore
self.device_manager.devices.rtx.obj.move(cenx, wait=True)
def move_samx_to_scan_region(self, cenx: float, move_in_this_routine: bool = False):
# attention. a movement will clear all positions in the rt trajectory generator!
if move_in_this_routine == True:
self.device_manager.devices.rtx.obj.move(cenx, wait=True)
time.sleep(0.05)
#at cenx we expect the PID to be close to zero for a good fsamx position
# at cenx we expect the PID to be close to zero for a good fsamx position
if self.rt_pid_voltage is None:
rtx = self.device_manager.devices.rtx
self.rt_pid_voltage = rtx.user_parameter.get("rt_pid_voltage")
@@ -188,29 +190,31 @@ class RtFlomniController(Controller):
)
logger.info(f"Using PID voltage from rtx user parameter: {self.rt_pid_voltage}")
expected_voltage = self.rt_pid_voltage
#logger.info(f"Expected PID voltage: {expected_voltage}")
# logger.info(f"Expected PID voltage: {expected_voltage}")
logger.info(f"Current PID voltage: {self.get_pid_x()}")
wait_on_exit = False
#we allow 2V range from center, this corresponds to 30 microns
# we allow 2V range from center, this corresponds to 30 microns
if np.abs(self.get_pid_x() - expected_voltage) < 2:
logger.info("No correction of fsamx needed")
else:
fsamx = self.device_manager.devices.fsamx
fsamx.obj.controller.socket_put_confirmed("axspeed[4]=0.1*stppermm[4]")
while True:
#when we correct, then to 1 V, within 15 microns
# when we correct, then to 1 V, within 15 microns
if np.abs(self.get_pid_x() - expected_voltage) < 1:
logger.info("No further correction needed")
break
wait_on_exit = True
#disable FZP piezo feedback
# disable FZP piezo feedback
self.socket_put("v0")
fsamx.read_only = False
logger.info(f"Current PID voltage: {self.get_pid_x()}")
#here we accumulate the correction
# here we accumulate the correction
fsamx.obj.pid_x_correction -= (self.get_pid_x() - expected_voltage) * 0.006
fsamx_in = fsamx.user_parameter.get("in")
logger.info(f"Moving fsamx to {cenx / 1000 * 0.7 + fsamx.obj.pid_x_correction}, PID portion of that {fsamx.obj.pid_x_correction}")
logger.info(
f"Moving fsamx to {cenx / 1000 * 0.7 + fsamx.obj.pid_x_correction}, PID portion of that {fsamx.obj.pid_x_correction}"
)
fsamx.obj.move(fsamx_in + cenx / 1000 * 0.7 + fsamx.obj.pid_x_correction, wait=True)
fsamx.read_only = True
time.sleep(0.1)
@@ -219,7 +223,7 @@ class RtFlomniController(Controller):
if wait_on_exit:
time.sleep(1)
#enable fast FZP feedback again
# enable fast FZP feedback again
self.socket_put("v1")
@threadlocked
@@ -510,7 +514,7 @@ class RtFlomniController(Controller):
# while scan is running
while mode > 0:
#TODO here?: scan abortion if no progress in scan *raise error
# TODO here?: scan abortion if no progress in scan *raise error
# logger.info(f"Current scan position {current_position_in_scan} out of {number_of_positions_planned}")
mode, number_of_positions_planned, current_position_in_scan = self.get_scan_status()
+14 -5
View File
@@ -159,7 +159,8 @@ class FlomniFermatScan(SyncFlyScanBase):
if self.flomni_rotation_status:
self.flomni_rotation_status.wait()
rtx_status = yield from self.stubs.set(device="rtx", value=self.positions[0][0], wait=False)
#rtx_status = yield from self.stubs.set(device="rtx", value=self.positions[0][0], wait=False)
rtx_status = yield from self.stubs.set(device="rtx", value=self.cenx, wait=False)
rtz_status = yield from self.stubs.set(device="rtz", value=self.positions[0][2], wait=False)
yield from self.stubs.send_rpc_and_wait("rtx", "controller.laser_tracker_on")
@@ -167,13 +168,17 @@ class FlomniFermatScan(SyncFlyScanBase):
rtx_status.wait()
rtz_status.wait()
#status = yield from self.stubs.send_rpc("rtx", "move", self.cenx)
#status.wait()
yield from self._transfer_positions_to_flomni()
yield from self.stubs.send_rpc_and_wait(
"rtx", "controller.move_samx_to_scan_region", self.fovx, self.cenx
)
tracker_signal_status = yield from self.stubs.send_rpc_and_wait(
"rtx", "controller.laser_tracker_check_signalstrength"
)
yield from self.stubs.send_rpc_and_wait(
"rtx", "controller.move_samx_to_scan_region", self.cenx
)
#self.device_manager.connector.send_client_info(tracker_signal_status)
if tracker_signal_status == "low":
self.device_manager.connector.raise_alarm(
@@ -307,7 +312,11 @@ class FlomniFermatScan(SyncFlyScanBase):
# in flomni, we need to move to the start position of the next scan, which is the end position of the current scan
# this method is called in finalize and overwrites the default move_to_start()
if isinstance(self.positions, np.ndarray) and len(self.positions[-1]) == 3:
yield from self.stubs.set(device=["rtx", "rty", "rtz"], value=self.positions[-1])
#yield from self.stubs.set(device=["rtx", "rty", "rtz"], value=self.positions[-1])
#in x we move to cenx, then we avoid jumps in centering routine
value=self.positions[-1]
value[0]=self.cenx
yield from self.stubs.set(device=["rtx", "rty", "rtz"], value=value)
return
logger.warning("No positions found to return to start")