add example for 2-axis piezo controller in device_configs/user_template.yaml #204

Merged
diaz merged 5 commits from 2axis_npoint_controller into main 2026-05-13 17:21:45 +02:00
2 changed files with 44 additions and 7 deletions
+23 -2
View File
@@ -50,7 +50,7 @@ rotx:
############################################################
npx:
description: nPoint x axis on the big npoint controller
description: nPoint x axis on the big (3-axis) npoint controller
deviceClass: csaxs_bec.devices.npoint.npoint.NPointAxis
deviceConfig:
axis_Id: A
@@ -60,6 +60,7 @@ npx:
- 50
port: 23
sign: 1
settle_time: 0.1
enabled: true
onFailure: buffer
readOnly: false
@@ -68,7 +69,7 @@ npx:
deviceTags:
- npoint
npy:
description: nPoint y axis on the big npoint controller
description: nPoint y axis on the big (3-axis) npoint controller
deviceClass: csaxs_bec.devices.npoint.npoint.NPointAxis
deviceConfig:
axis_Id: B
@@ -78,6 +79,26 @@ npy:
- 50
port: 23
sign: 1
settle_time: 0.1
enabled: true
onFailure: buffer
readOnly: false
readoutPriority: baseline
connectionTimeout: 20
deviceTags:
- npoint
np2x:
description: nPoint x axis on the small (2-axis) npoint controller
deviceClass: csaxs_bec.devices.npoint.npoint.NPointAxis
deviceConfig:
axis_Id: A
host: "nPoint219026.psi.ch"
limits:
- -25
- 25
port: 23
sign: 1
settle_time: 0.08
enabled: true
onFailure: buffer
readOnly: false
+21 -5
View File
@@ -3,6 +3,7 @@ import threading
import time
import numpy as np
from bec_lib.logger import bec_logger
from ophyd import Component as Cpt
from ophyd import Device, PositionerBase, Signal, SignalRO
from ophyd.status import wait as status_wait
@@ -11,6 +12,8 @@ from ophyd_devices.utils.controller import Controller, threadlocked
from ophyd_devices.utils.socket import SocketIO, SocketSignal, raise_if_disconnected
from prettytable import PrettyTable
logger = bec_logger.logger
def channel_checked(fcn):
"""Decorator to catch attempted access to channels that are not available."""
@@ -390,7 +393,7 @@ class NPointAxis(Device, PositionerBase):
user_setpoint = Cpt(NpointSetpointSignal, signal_name="setpoint")
motor_is_moving = Cpt(NpointMotorIsMoving, value=0, kind="normal")
settling_time = Cpt(Signal, value=0.1, kind="config")
settle_time: Cpt[Signal] = Cpt(Signal, value=0.1, kind="config")
high_limit_travel = Cpt(Signal, value=0, kind="omitted")
low_limit_travel = Cpt(Signal, value=0, kind="omitted")
@@ -445,9 +448,22 @@ class NPointAxis(Device, PositionerBase):
self.high_limit_travel.put(limits[1])
def wait_for_connection(self, timeout: float = 30.0) -> bool:
self.controller.on(timeout=timeout)
self._update_setpoint_from_readback()
for _ in range(5):
try:
self.controller.on(timeout=timeout)
self._update_setpoint_from_readback()
except TimeoutError:
self.controller.off(update_config=False)
time.sleep(1)
else:
break
else:
raise TimeoutError(
f"NPointAxis {self.name}: Failed to update the setpoint from the readback value after 5 attempts during startup. This may happen occasionally. "
f"Try to reload the config and if the problem persists, check the connection to the nPoint controller "
f"and ensure that it is powered on and accessible at {self.controller._socket_host}:{self.controller._socket_port}."
)
def _update_setpoint_from_readback(self):
"""
The setpoint is only stored locally. After a restart,
@@ -522,7 +538,7 @@ class NPointAxis(Device, PositionerBase):
self.motor_is_moving.set_motor_is_moving(1)
val = self.readback.read()
self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time())
time.sleep(self.settling_time.get())
time.sleep(max(self.settle_time.get(), 0))
self.motor_is_moving.set_motor_is_moving(0)
val = self.readback.read()
self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time())