mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-04 21:35:09 +00:00
对laiyu移液站进行部分修改,取消多次初始化的问题
This commit is contained in:
@@ -153,7 +153,7 @@ class UniLiquidHandlerLaiyuBackend(LiquidHandlerBackend):
|
|||||||
if self.hardware_interface.tip_status == TipStatus.TIP_ATTACHED:
|
if self.hardware_interface.tip_status == TipStatus.TIP_ATTACHED:
|
||||||
print("已有枪头,无需重复拾取")
|
print("已有枪头,无需重复拾取")
|
||||||
return
|
return
|
||||||
self.hardware_interface.xyz_controller.move_to_work_coord_safe(x=x, y=-y, z=z,speed=100)
|
self.hardware_interface.xyz_controller.move_to_work_coord_safe(x=x, y=-y, z=z,speed=200)
|
||||||
self.hardware_interface.xyz_controller.move_to_work_coord_safe(z=self.hardware_interface.xyz_controller.machine_config.safe_z_height,speed=100)
|
self.hardware_interface.xyz_controller.move_to_work_coord_safe(z=self.hardware_interface.xyz_controller.machine_config.safe_z_height,speed=100)
|
||||||
# self.joint_state_publisher.send_resource_action(ops[0].resource.name, x, y, z, "pick",channels=use_channels)
|
# self.joint_state_publisher.send_resource_action(ops[0].resource.name, x, y, z, "pick",channels=use_channels)
|
||||||
# goback()
|
# goback()
|
||||||
@@ -202,7 +202,7 @@ class UniLiquidHandlerLaiyuBackend(LiquidHandlerBackend):
|
|||||||
if self.hardware_interface.tip_status == TipStatus.NO_TIP:
|
if self.hardware_interface.tip_status == TipStatus.NO_TIP:
|
||||||
print("无枪头,无需丢弃")
|
print("无枪头,无需丢弃")
|
||||||
return
|
return
|
||||||
self.hardware_interface.xyz_controller.move_to_work_coord_safe(x=x, y=-y, z=z)
|
self.hardware_interface.xyz_controller.move_to_work_coord_safe(x=x, y=-y, z=z,speed=200)
|
||||||
self.hardware_interface.eject_tip
|
self.hardware_interface.eject_tip
|
||||||
self.hardware_interface.xyz_controller.move_to_work_coord_safe(z=self.hardware_interface.xyz_controller.machine_config.safe_z_height)
|
self.hardware_interface.xyz_controller.move_to_work_coord_safe(z=self.hardware_interface.xyz_controller.machine_config.safe_z_height)
|
||||||
|
|
||||||
@@ -267,7 +267,7 @@ class UniLiquidHandlerLaiyuBackend(LiquidHandlerBackend):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# 移动到吸液位置
|
# 移动到吸液位置
|
||||||
self.hardware_interface.xyz_controller.move_to_work_coord_safe(x=x, y=-y, z=z)
|
self.hardware_interface.xyz_controller.move_to_work_coord_safe(x=x, y=-y, z=z,speed=200)
|
||||||
self.pipette_aspirate(volume=ops[0].volume, flow_rate=flow_rate)
|
self.pipette_aspirate(volume=ops[0].volume, flow_rate=flow_rate)
|
||||||
|
|
||||||
|
|
||||||
@@ -340,7 +340,7 @@ class UniLiquidHandlerLaiyuBackend(LiquidHandlerBackend):
|
|||||||
|
|
||||||
|
|
||||||
# 移动到排液位置
|
# 移动到排液位置
|
||||||
self.hardware_interface.xyz_controller.move_to_work_coord_safe(x=x, y=-y, z=z)
|
self.hardware_interface.xyz_controller.move_to_work_coord_safe(x=x, y=-y, z=z,speed=200)
|
||||||
self.pipette_dispense(volume=ops[0].volume, flow_rate=flow_rate)
|
self.pipette_dispense(volume=ops[0].volume, flow_rate=flow_rate)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ class PipetteController:
|
|||||||
baudrate=115200
|
baudrate=115200
|
||||||
)
|
)
|
||||||
self.pipette = SOPAPipette(self.config)
|
self.pipette = SOPAPipette(self.config)
|
||||||
|
self.pipette_port = port
|
||||||
self.tip_status = TipStatus.NO_TIP
|
self.tip_status = TipStatus.NO_TIP
|
||||||
self.current_volume = 0.0
|
self.current_volume = 0.0
|
||||||
self.max_volume = 1000.0 # 默认1000ul
|
self.max_volume = 1000.0 # 默认1000ul
|
||||||
@@ -154,7 +155,7 @@ class PipetteController:
|
|||||||
logger.info("移液器连接成功")
|
logger.info("移液器连接成功")
|
||||||
|
|
||||||
# 连接XYZ步进电机控制器(如果提供了端口)
|
# 连接XYZ步进电机控制器(如果提供了端口)
|
||||||
if self.xyz_port:
|
if self.xyz_port != self.pipette_port:
|
||||||
try:
|
try:
|
||||||
self.xyz_controller = XYZController(self.xyz_port)
|
self.xyz_controller = XYZController(self.xyz_port)
|
||||||
if self.xyz_controller.connect():
|
if self.xyz_controller.connect():
|
||||||
@@ -168,7 +169,12 @@ class PipetteController:
|
|||||||
self.xyz_controller = None
|
self.xyz_controller = None
|
||||||
self.xyz_connected = False
|
self.xyz_connected = False
|
||||||
else:
|
else:
|
||||||
logger.info("未配置XYZ步进电机端口,跳过运动控制器连接")
|
try:
|
||||||
|
self.xyz_controller = XYZController(self.xyz_port, auto_connect=False)
|
||||||
|
self.xyz_controller.serial_conn = self.pipette.serial_port
|
||||||
|
self.xyz_controller.is_connected = True
|
||||||
|
except Exception as e:
|
||||||
|
logger.info("未配置XYZ步进电机端口,跳过运动控制器连接")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -581,16 +581,51 @@ class LiquidHandlerAbstract(LiquidHandlerMiddleware):
|
|||||||
support_touch_tip = True
|
support_touch_tip = True
|
||||||
_ros_node: BaseROS2DeviceNode
|
_ros_node: BaseROS2DeviceNode
|
||||||
|
|
||||||
def __init__(self, backend: LiquidHandlerBackend, deck: Deck, simulator: bool=False, channel_num:int = 8):
|
def __init__(self, backend: LiquidHandlerBackend, deck: Deck, simulator: bool=False, channel_num:int = 8, total_height:float = 310):
|
||||||
"""Initialize a LiquidHandler.
|
"""Initialize a LiquidHandler.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
backend: Backend to use.
|
backend: Backend to use.
|
||||||
deck: Deck to use.
|
deck: Deck to use.
|
||||||
"""
|
"""
|
||||||
|
backend_type = None
|
||||||
|
if isinstance(backend, dict) and "type" in backend:
|
||||||
|
backend_dict = backend.copy()
|
||||||
|
type_str = backend_dict.pop("type")
|
||||||
|
try:
|
||||||
|
# Try to get class from string using globals (current module), or fallback to pylabrobot or unilabos namespaces
|
||||||
|
backend_cls = None
|
||||||
|
if type_str in globals():
|
||||||
|
backend_cls = globals()[type_str]
|
||||||
|
else:
|
||||||
|
# Try resolving dotted notation, e.g. "xxx.yyy.ClassName"
|
||||||
|
components = type_str.split(".")
|
||||||
|
mod = None
|
||||||
|
if len(components) > 1:
|
||||||
|
module_name = ".".join(components[:-1])
|
||||||
|
try:
|
||||||
|
import importlib
|
||||||
|
mod = importlib.import_module(module_name)
|
||||||
|
except ImportError:
|
||||||
|
mod = None
|
||||||
|
if mod is not None:
|
||||||
|
backend_cls = getattr(mod, components[-1], None)
|
||||||
|
if backend_cls is None:
|
||||||
|
# Try pylabrobot style import (if available)
|
||||||
|
try:
|
||||||
|
import pylabrobot
|
||||||
|
backend_cls = getattr(pylabrobot, type_str, None)
|
||||||
|
except Exception:
|
||||||
|
backend_cls = None
|
||||||
|
if backend_cls is not None and isinstance(backend_cls, type):
|
||||||
|
backend_type = backend_cls(**backend_dict) # pass the rest of dict as kwargs
|
||||||
|
except Exception as exc:
|
||||||
|
raise RuntimeError(f"Failed to convert backend type '{type_str}' to class: {exc}")
|
||||||
|
else:
|
||||||
|
backend_type = backend
|
||||||
self._simulator = simulator
|
self._simulator = simulator
|
||||||
self.group_info = dict()
|
self.group_info = dict()
|
||||||
super().__init__(backend, deck, simulator, channel_num)
|
super().__init__(backend_type, deck, simulator, channel_num)
|
||||||
|
|
||||||
def post_init(self, ros_node: BaseROS2DeviceNode):
|
def post_init(self, ros_node: BaseROS2DeviceNode):
|
||||||
self._ros_node = ros_node
|
self._ros_node = ros_node
|
||||||
|
|||||||
Reference in New Issue
Block a user