mirror of
https://github.com/deepmodeling/Uni-Lab-OS
synced 2026-05-25 09:58:13 +00:00
fix: 物料系统标准化重构 + 多轮运行期 Bug 修复 (2026-03-12)
- MagazineHolder: klasses=None,解耦极片子节点初始化 - Magazine: 重写 serialize/deserialize,截断旧极片脏数据 - bottle_carriers: 移除 YIHUA_Electrolyte_12VialCarrier 初始化填瓶 - decks.py: BIOYOND_YB_Deck→BioyondElectrolyteDeck,移除 setup 参数 - YB_YH_materials.py: CoincellDeck→YihuaCoinCellDeck,新增 electrolyte_buffer 槽位 - resource_tracker.py: Container 状态键预填 + 重复 UUID 自动修复 + 树级名称去重 - itemized_carrier.py: XY 近似坐标匹配,修复 Z 偏移问题 - bioyond_cell_workstation.py: 跨站转运改用真实资源 + 类型映射双模式查找 - station.py: sync_to_external 属性访问路径修复 - coin_cell_assembly.py: 新增 10 个 Modbus 余量属性 - CSV/JSON/YAML 配置同步更新(类名重命名 + 移除 setup) - 新增 changelog_2026-03-12.md
This commit is contained in:
@@ -130,20 +130,14 @@ class MaterialPlate(ItemizedResource[MaterialHole]):
|
||||
ordering: Optional[OrderedDict[str, str]] = None,
|
||||
category: str = "material_plate",
|
||||
model: Optional[str] = None,
|
||||
fill: bool = False
|
||||
):
|
||||
"""初始化料板
|
||||
"""初始化料板(不主动填充洞位,由工厂方法或反序列化恢复)
|
||||
|
||||
Args:
|
||||
name: 料板名称
|
||||
size_x: 长度 (mm)
|
||||
size_y: 宽度 (mm)
|
||||
size_z: 高度 (mm)
|
||||
hole_diameter: 洞直径 (mm)
|
||||
hole_depth: 洞深度 (mm)
|
||||
hole_spacing_x: X方向洞位间距 (mm)
|
||||
hole_spacing_y: Y方向洞位间距 (mm)
|
||||
number: 编号
|
||||
category: 类别
|
||||
model: 型号
|
||||
"""
|
||||
@@ -153,42 +147,45 @@ class MaterialPlate(ItemizedResource[MaterialHole]):
|
||||
hole_diameter=20.0,
|
||||
info="",
|
||||
)
|
||||
# 创建4x4的洞位
|
||||
# TODO: 这里要改,对应不同形状
|
||||
super().__init__(
|
||||
name=name,
|
||||
size_x=size_x,
|
||||
size_y=size_y,
|
||||
size_z=size_z,
|
||||
ordered_items=ordered_items,
|
||||
ordering=ordering,
|
||||
category=category,
|
||||
model=model,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def create_with_holes(
|
||||
cls,
|
||||
name: str,
|
||||
size_x: float,
|
||||
size_y: float,
|
||||
size_z: float,
|
||||
category: str = "material_plate",
|
||||
model: Optional[str] = None,
|
||||
) -> "MaterialPlate":
|
||||
"""工厂方法:创建带 4x4 洞位的料板(仅用于初始 setup,不在反序列化路径调用)"""
|
||||
plate = cls(name=name, size_x=size_x, size_y=size_y, size_z=size_z, category=category, model=model)
|
||||
holes = create_ordered_items_2d(
|
||||
klass=MaterialHole,
|
||||
num_items_x=4,
|
||||
num_items_y=4,
|
||||
dx=(size_x - 4 * self._unilabos_state["hole_spacing_x"]) / 2, # 居中
|
||||
dy=(size_y - 4 * self._unilabos_state["hole_spacing_y"]) / 2, # 居中
|
||||
dx=(size_x - 4 * plate._unilabos_state["hole_spacing_x"]) / 2,
|
||||
dy=(size_y - 4 * plate._unilabos_state["hole_spacing_y"]) / 2,
|
||||
dz=size_z,
|
||||
item_dx=self._unilabos_state["hole_spacing_x"],
|
||||
item_dy=self._unilabos_state["hole_spacing_y"],
|
||||
size_x = 16,
|
||||
size_y = 16,
|
||||
size_z = 16,
|
||||
item_dx=plate._unilabos_state["hole_spacing_x"],
|
||||
item_dy=plate._unilabos_state["hole_spacing_y"],
|
||||
size_x=16,
|
||||
size_y=16,
|
||||
size_z=16,
|
||||
)
|
||||
if fill:
|
||||
super().__init__(
|
||||
name=name,
|
||||
size_x=size_x,
|
||||
size_y=size_y,
|
||||
size_z=size_z,
|
||||
ordered_items=holes,
|
||||
category=category,
|
||||
model=model,
|
||||
)
|
||||
else:
|
||||
super().__init__(
|
||||
name=name,
|
||||
size_x=size_x,
|
||||
size_y=size_y,
|
||||
size_z=size_z,
|
||||
ordered_items=ordered_items,
|
||||
ordering=ordering,
|
||||
category=category,
|
||||
model=model,
|
||||
)
|
||||
for hole_name, hole in holes.items():
|
||||
plate.assign_child_resource(hole, location=hole.location)
|
||||
return plate
|
||||
|
||||
def update_locations(self):
|
||||
# TODO:调多次相加
|
||||
@@ -534,30 +531,18 @@ class WasteTipBox(Trash):
|
||||
return data
|
||||
|
||||
|
||||
class CoincellDeck(Deck):
|
||||
"""纽扣电池组装工作站台面类"""
|
||||
class YihuaCoinCellDeck(Deck):
|
||||
"""依华纽扣电池组装工作站台面类"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str = "coin_cell_deck",
|
||||
size_x: float = 1450.0, # 1m
|
||||
size_y: float = 1450.0, # 1m
|
||||
size_z: float = 100.0, # 0.9m
|
||||
size_x: float = 1450.0,
|
||||
size_y: float = 1450.0,
|
||||
size_z: float = 100.0,
|
||||
origin: Coordinate = Coordinate(-2200, 0, 0),
|
||||
category: str = "coin_cell_deck",
|
||||
setup: bool = False, # 是否自动执行 setup
|
||||
):
|
||||
"""初始化纽扣电池组装工作站台面
|
||||
|
||||
Args:
|
||||
name: 台面名称
|
||||
size_x: 长度 (mm) - 1m
|
||||
size_y: 宽度 (mm) - 1m
|
||||
size_z: 高度 (mm) - 0.9m
|
||||
origin: 原点坐标
|
||||
category: 类别
|
||||
setup: 是否自动执行 setup 配置标准布局
|
||||
"""
|
||||
super().__init__(
|
||||
name=name,
|
||||
size_x=1450.0,
|
||||
@@ -565,8 +550,6 @@ class CoincellDeck(Deck):
|
||||
size_z=100.0,
|
||||
origin=origin,
|
||||
)
|
||||
if setup:
|
||||
self.setup()
|
||||
|
||||
def setup(self) -> None:
|
||||
"""设置工作站的标准布局 - 包含子弹夹、料盘、瓶架等完整配置"""
|
||||
@@ -591,14 +574,11 @@ class CoincellDeck(Deck):
|
||||
# ====================================== 物料板 ============================================
|
||||
# 创建物料板(料盘carrier)- 4x4布局
|
||||
# 负极料盘
|
||||
fujiliaopan = MaterialPlate(name="负极料盘", size_x=120, size_y=100, size_z=10.0, fill=True)
|
||||
fujiliaopan = MaterialPlate.create_with_holes(name="负极料盘", size_x=120, size_y=100, size_z=10.0)
|
||||
self.assign_child_resource(fujiliaopan, Coordinate(x=708.0, y=794.0, z=0))
|
||||
# for i in range(16):
|
||||
# fujipian = ElectrodeSheet(name=f"{fujiliaopan.name}_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
||||
# fujiliaopan.children[i].assign_child_resource(fujipian, location=None)
|
||||
|
||||
# 隔膜料盘
|
||||
gemoliaopan = MaterialPlate(name="隔膜料盘", size_x=120, size_y=100, size_z=10.0, fill=True)
|
||||
gemoliaopan = MaterialPlate.create_with_holes(name="隔膜料盘", size_x=120, size_y=100, size_z=10.0)
|
||||
self.assign_child_resource(gemoliaopan, Coordinate(x=718.0, y=918.0, z=0))
|
||||
# for i in range(16):
|
||||
# gemopian = ElectrodeSheet(name=f"{gemoliaopan.name}_jipian_{i}", size_x=12, size_y=12, size_z=0.1)
|
||||
@@ -633,11 +613,27 @@ class CoincellDeck(Deck):
|
||||
waste_tip_box = WasteTipBox(name="waste_tip_box")
|
||||
self.assign_child_resource(waste_tip_box, Coordinate(x=778.0, y=622.0, z=0))
|
||||
|
||||
# 分液瓶板接驳区 - 接收来自 BioyondElectrolyte 侧的完整 Vial Carrier 板
|
||||
# 命名 electrolyte_buffer 与 bioyond_cell_workstation.py 中 sites=["electrolyte_buffer"] 对应
|
||||
electrolyte_buffer = ResourceStack(
|
||||
name="electrolyte_buffer",
|
||||
direction="z",
|
||||
resources=[],
|
||||
)
|
||||
self.assign_child_resource(electrolyte_buffer, Coordinate(x=1050.0, y=700.0, z=0))
|
||||
|
||||
def YH_Deck(name=""):
|
||||
cd = CoincellDeck(name=name)
|
||||
cd.setup()
|
||||
return cd
|
||||
|
||||
def yihua_coin_cell_deck(name: str = "coin_cell_deck") -> YihuaCoinCellDeck:
|
||||
deck = YihuaCoinCellDeck(name=name)
|
||||
deck.setup()
|
||||
return deck
|
||||
|
||||
|
||||
# 向后兼容别名,日后废弃
|
||||
CoincellDeck = YihuaCoinCellDeck
|
||||
|
||||
def YH_Deck(name: str = "") -> YihuaCoinCellDeck:
|
||||
return yihua_coin_cell_deck(name=name or "coin_cell_deck")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -17,7 +17,7 @@ from unilabos.device_comms.modbus_plc.modbus import DeviceType, Base as ModbusNo
|
||||
from unilabos.devices.workstation.coin_cell_assembly.YB_YH_materials import *
|
||||
from unilabos.ros.nodes.base_device_node import ROS2DeviceNode, BaseROS2DeviceNode
|
||||
from unilabos.ros.nodes.presets.workstation import ROS2WorkstationNode
|
||||
from unilabos.devices.workstation.coin_cell_assembly.YB_YH_materials import CoincellDeck
|
||||
from unilabos.devices.workstation.coin_cell_assembly.YB_YH_materials import YihuaCoinCellDeck, yihua_coin_cell_deck
|
||||
from unilabos.resources.graphio import convert_resources_to_type
|
||||
from unilabos.utils.log import logger
|
||||
import struct
|
||||
@@ -623,12 +623,28 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
return vol
|
||||
|
||||
@property
|
||||
def data_coin_num(self) -> int:
|
||||
"""当前电池数量 (INT16)"""
|
||||
def data_coin_type(self) -> int:
|
||||
"""电池类型 - 7种或8种组装物料 (INT16)"""
|
||||
if self.debug_mode:
|
||||
return 7
|
||||
coin_type, read_err = self.client.use_node('REG_DATA_COIN_TYPE').read(1)
|
||||
return coin_type
|
||||
|
||||
@property
|
||||
def data_current_assembling_count(self) -> int:
|
||||
"""当前进行组装的电池数量 - Current assembling battery count (INT16)"""
|
||||
if self.debug_mode:
|
||||
return 0
|
||||
num, read_err = self.client.use_node('REG_DATA_COIN_NUM').read(1)
|
||||
return num
|
||||
count, read_err = self.client.use_node('REG_DATA_CURRENT_ASSEMBLING_COUNT').read(1)
|
||||
return count
|
||||
|
||||
@property
|
||||
def data_current_completed_count(self) -> int:
|
||||
"""当前完成组装的电池数量 - Current completed battery count (INT16)"""
|
||||
if self.debug_mode:
|
||||
return 0
|
||||
count, read_err = self.client.use_node('REG_DATA_CURRENT_COMPLETED_COUNT').read(1)
|
||||
return count
|
||||
|
||||
@property
|
||||
def data_coin_cell_code(self) -> str:
|
||||
@@ -726,6 +742,116 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_10mm_positive_plate_remaining(self) -> float:
|
||||
"""10mm正极片剩余物料数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_10MM_POSITIVE_PLATE_REMAINING_COUNT').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取10mm正极片余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_12mm_positive_plate_remaining(self) -> float:
|
||||
"""12mm正极片剩余物料数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_12MM_POSITIVE_PLATE_REMAINING_COUNT').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取12mm正极片余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_16mm_positive_plate_remaining(self) -> float:
|
||||
"""16mm正极片剩余物料数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_16MM_POSITIVE_PLATE_REMAINING_COUNT').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取16mm正极片余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_aluminum_foil_remaining(self) -> float:
|
||||
"""铝箔剩余物料数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_ALUMINUM_FOIL_REMAINING_COUNT').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取铝箔余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_positive_shell_remaining(self) -> float:
|
||||
"""正极壳剩余物料数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_POSITIVE_SHELL_REMAINING_COUNT').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取正极壳余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_flat_washer_remaining(self) -> float:
|
||||
"""平垫剩余物料数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_FLAT_WASHER_REMAINING_COUNT').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取平垫余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_negative_shell_remaining(self) -> float:
|
||||
"""负极壳剩余物料数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_NEGATIVE_SHELL_REMAINING_COUNT').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取负极壳余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_spring_washer_remaining(self) -> float:
|
||||
"""弹垫剩余物料数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_SPRING_WASHER_REMAINING_COUNT').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取弹垫余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_finished_battery_remaining_capacity(self) -> float:
|
||||
"""成品电池剩余可容纳数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_FINISHED_BATTERY_REMAINING_CAPACITY').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取成品电池余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
@property
|
||||
def data_finished_battery_ng_remaining_capacity(self) -> float:
|
||||
"""成品电池NG槽剩余可容纳数量 (FLOAT32)"""
|
||||
if self.debug_mode:
|
||||
return 0.0
|
||||
result = self.client.client.read_holding_registers(address=self.client.use_node('REG_DATA_FINISHED_BATTERY_NG_REMAINING_CAPACITY').address, count=2)
|
||||
if result.isError():
|
||||
logger.error("读取成品电池NG槽余量失败")
|
||||
return 0.0
|
||||
return _decode_float32_correct(result.registers)
|
||||
|
||||
# @property
|
||||
# def data_stack_vision_code(self) -> int:
|
||||
# """物料堆叠复检图片编码 (INT16)"""
|
||||
@@ -1158,7 +1284,8 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
lvbodian: bool = True,
|
||||
battery_pressure_mode: bool = True,
|
||||
battery_clean_ignore: bool = False,
|
||||
file_path: str = "/Users/sml/work"
|
||||
file_path: str = "/Users/sml/work",
|
||||
formulations: List[Dict] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
发送瓶数+简化组装函数(适用于第二批次及后续批次)
|
||||
@@ -1185,17 +1312,44 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
battery_pressure_mode: 是否启用压力模式
|
||||
battery_clean_ignore: 是否忽略电池清洁
|
||||
file_path: 实验记录保存路径
|
||||
formulations: 配方信息列表(从 create_orders.mass_ratios 获取)
|
||||
包含 orderCode, target_mass_ratio, real_mass_ratio 等
|
||||
用于CSV数据追溯,可选参数
|
||||
|
||||
Returns:
|
||||
dict: 包含组装结果的字典
|
||||
|
||||
注意:
|
||||
注意:
|
||||
- 第一次启动需先调用 func_pack_device_init_auto_start_combined()
|
||||
- 后续批次直接调用此函数即可
|
||||
"""
|
||||
logger.info("=" * 60)
|
||||
logger.info("开始发送瓶数+简化组装流程...")
|
||||
logger.info(f"电解液瓶数: {elec_num}, 每瓶电池数: {elec_use_num}")
|
||||
|
||||
# 存储配方信息到设备状态(供 CSV 写入使用)
|
||||
if formulations:
|
||||
logger.info(f"接收到配方信息: {len(formulations)} 条")
|
||||
# 将配方信息按 orderCode 索引,方便后续查找
|
||||
self._formulations_map = {
|
||||
f["orderCode"]: f for f in formulations
|
||||
} if formulations else {}
|
||||
# ✅ 新增:存储配方列表(按接收顺序),用于索引访问
|
||||
self._formulations_list = formulations
|
||||
else:
|
||||
logger.warning("未接收到配方信息,CSV将不包含配方字段")
|
||||
self._formulations_map = {}
|
||||
self._formulations_list = []
|
||||
|
||||
# ✅ 新增:存储每瓶电池数,用于计算当前使用的瓶号
|
||||
# ⚠️ 确保转换为整数(前端可能传递字符串)
|
||||
self._elec_use_num = int(elec_use_num) if elec_use_num else 0
|
||||
logger.info(f"已存储参数: 每瓶电池数={self._elec_use_num}, 配方数={len(self._formulations_list)}")
|
||||
|
||||
# ✅ 新增:软件层电池计数器(防止硬件计数器不准确)
|
||||
self._software_battery_counter = 0 # 从0开始,每写入一次CSV递增
|
||||
logger.info("软件层电池计数器已初始化")
|
||||
|
||||
logger.info("=" * 60)
|
||||
|
||||
# 步骤1: 发送电解液瓶数(触发物料搬运)
|
||||
@@ -1331,7 +1485,8 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
data_assembly_time = self.data_assembly_time
|
||||
data_assembly_pressure = self.data_assembly_pressure
|
||||
data_electrolyte_volume = self.data_electrolyte_volume
|
||||
data_coin_num = self.data_coin_num
|
||||
data_coin_type = self.data_coin_type # 电池类型(7或8种物料)
|
||||
data_battery_number = self.data_current_assembling_count # ✅ 真正的电池编号
|
||||
|
||||
# 处理电解液二维码 - 确保是字符串类型
|
||||
try:
|
||||
@@ -1361,28 +1516,32 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
logger.debug(f"data_assembly_time: {data_assembly_time}")
|
||||
logger.debug(f"data_assembly_pressure: {data_assembly_pressure}")
|
||||
logger.debug(f"data_electrolyte_volume: {data_electrolyte_volume}")
|
||||
logger.debug(f"data_coin_num: {data_coin_num}")
|
||||
logger.debug(f"data_coin_type: {data_coin_type}") # 电池类型
|
||||
logger.debug(f"data_battery_number: {data_battery_number}") # ✅ 电池编号
|
||||
logger.debug(f"data_electrolyte_code: {data_electrolyte_code}")
|
||||
logger.debug(f"data_coin_cell_code: {data_coin_cell_code}")
|
||||
#接收完信息后,读取完毕标志位置True
|
||||
liaopan3 = self.deck.get_resource("成品弹夹")
|
||||
finished_battery_magazine = self.deck.get_resource("成品弹夹")
|
||||
|
||||
# 计算电池应该放在哪个洞,以及洞内的堆叠位置
|
||||
# 成品弹夹有6个洞,每个洞可堆叠20颗电池
|
||||
# 前5个洞(索引0-4)放正常电池,第6个洞(索引5)放NG电池
|
||||
BATTERIES_PER_HOLE = 20
|
||||
MAX_NORMAL_BATTERIES = 100 # 5个洞 × 20颗/洞
|
||||
|
||||
hole_index = self.coin_num_N // BATTERIES_PER_HOLE # 第几个洞(0-4为正常电池)
|
||||
in_hole_position = self.coin_num_N % BATTERIES_PER_HOLE # 洞内的堆叠序号
|
||||
|
||||
if hole_index >= 5:
|
||||
logger.error(f"电池数量超出正常容量范围: {self.coin_num_N + 1} > {MAX_NORMAL_BATTERIES}")
|
||||
raise ValueError(f"成品弹夹正常洞位已满(最多{MAX_NORMAL_BATTERIES}颗),当前尝试放置第{self.coin_num_N + 1}颗")
|
||||
|
||||
target_hole = finished_battery_magazine.children[hole_index] # 获取目标洞
|
||||
|
||||
# 生成唯一的电池名称(使用时间戳确保唯一性)
|
||||
timestamp_suffix = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
|
||||
battery_name = f"battery_{self.coin_num_N}_{timestamp_suffix}"
|
||||
|
||||
# 检查目标位置是否已有资源,如果有则先卸载
|
||||
target_slot = liaopan3.children[self.coin_num_N]
|
||||
if target_slot.children:
|
||||
logger.warning(f"位置 {self.coin_num_N} 已有资源,将先卸载旧资源")
|
||||
try:
|
||||
# 卸载所有现有子资源
|
||||
for child in list(target_slot.children):
|
||||
target_slot.unassign_child_resource(child)
|
||||
logger.info(f"已卸载旧资源: {child.name}")
|
||||
except Exception as e:
|
||||
logger.error(f"卸载旧资源时出错: {e}")
|
||||
|
||||
# 创建新的电池资源
|
||||
battery = ElectrodeSheet(name=battery_name, size_x=14, size_y=14, size_z=2)
|
||||
battery._unilabos_state = {
|
||||
@@ -1393,13 +1552,12 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
"electrolyte_volume": data_electrolyte_volume
|
||||
}
|
||||
|
||||
# 分配新资源到目标位置
|
||||
# 将电池堆叠到目标洞中
|
||||
try:
|
||||
target_slot.assign_child_resource(battery, location=None)
|
||||
logger.info(f"成功分配电池 {battery_name} 到位置 {self.coin_num_N}")
|
||||
target_hole.assign_child_resource(battery, location=None)
|
||||
logger.info(f"成功放置电池 {battery_name} 到弹夹洞{hole_index}的第{in_hole_position + 1}层 (总计第{self.coin_num_N + 1}颗)")
|
||||
except Exception as e:
|
||||
logger.error(f"分配电池资源失败: {e}")
|
||||
# 如果分配失败,尝试使用更简单的方法
|
||||
logger.error(f"放置电池资源失败: {e}")
|
||||
raise
|
||||
|
||||
#print(jipian2.parent)
|
||||
@@ -1430,17 +1588,72 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
writer.writerow([
|
||||
'Time', 'open_circuit_voltage', 'pole_weight',
|
||||
'assembly_time', 'assembly_pressure', 'electrolyte_volume',
|
||||
'coin_num', 'electrolyte_code', 'coin_cell_code'
|
||||
'coin_num', 'electrolyte_code', 'coin_cell_code',
|
||||
'formulation_order_code', 'formulation_ratio' # ← 新增配方列
|
||||
])
|
||||
#立刻写入磁盘
|
||||
csvfile.flush()
|
||||
#开始追加电池信息
|
||||
with open(self.csv_export_file, 'a', newline='', encoding='utf-8') as csvfile:
|
||||
writer = csv.writer(csvfile)
|
||||
|
||||
# ========== 提取配方信息 ==========
|
||||
formulation_order_code = ""
|
||||
formulation_ratio_str = ""
|
||||
|
||||
# 从 self._formulations_list 获取配方信息
|
||||
if hasattr(self, '_formulations_list') and self._formulations_list:
|
||||
# ✅ 新方案:根据电池编号和每瓶电池数计算当前瓶号
|
||||
# 例如:elec_use_num=2时,电池1-2用瓶0,电池3-4用瓶1
|
||||
if hasattr(self, '_elec_use_num') and self._elec_use_num:
|
||||
# ⚠️ 确保转换为整数(防御性编程)
|
||||
elec_use_num_int = int(self._elec_use_num) if self._elec_use_num else 1
|
||||
if elec_use_num_int > 0:
|
||||
current_bottle_index = (data_battery_number - 1) // elec_use_num_int
|
||||
else:
|
||||
current_bottle_index = 0
|
||||
|
||||
logger.debug(
|
||||
f"[CSV写入] 电池 {data_battery_number}: 计算瓶号索引={current_bottle_index} "
|
||||
f"(每瓶{self._elec_use_num}颗电池)"
|
||||
)
|
||||
else:
|
||||
# 降级方案:尝试从二维码解析(仅当参数未设置时)
|
||||
current_bottle_index = int(data_electrolyte_code.split('-')[-1]) if '-' in str(data_electrolyte_code) else 0
|
||||
logger.debug(
|
||||
f"[CSV写入] 电池 {data_battery_number}: 从二维码解析瓶号索引={current_bottle_index}"
|
||||
)
|
||||
|
||||
# 从配方列表中获取对应配方
|
||||
if 0 <= current_bottle_index < len(self._formulations_list):
|
||||
formulation = self._formulations_list[current_bottle_index]
|
||||
formulation_order_code = formulation.get("orderCode", "")
|
||||
# ✅ 优先使用实际质量比(real_mass_ratio),如果不存在则使用目标质量比
|
||||
real_ratio = formulation.get("real_mass_ratio", {})
|
||||
target_ratio = formulation.get("target_mass_ratio", {})
|
||||
mass_ratio = real_ratio if real_ratio else target_ratio
|
||||
|
||||
# 将配方比例转为JSON字符串
|
||||
import json
|
||||
formulation_ratio_str = json.dumps(mass_ratio, ensure_ascii=False) if mass_ratio else ""
|
||||
|
||||
logger.info(
|
||||
f"[CSV写入] 电池 {data_battery_number}: 使用配方[{current_bottle_index}] "
|
||||
f"orderCode={formulation_order_code}, 比例={formulation_ratio_str}"
|
||||
)
|
||||
else:
|
||||
logger.warning(
|
||||
f"[CSV写入] 电池 {data_battery_number}: 瓶号索引 {current_bottle_index} "
|
||||
f"超出配方列表范围 (共{len(self._formulations_list)}个配方)"
|
||||
)
|
||||
else:
|
||||
logger.debug(f"[CSV写入] 电池 {data_battery_number}: 未找到配方信息数据")
|
||||
|
||||
writer.writerow([
|
||||
timestamp, data_open_circuit_voltage, data_pole_weight,
|
||||
data_assembly_time, data_assembly_pressure, data_electrolyte_volume,
|
||||
data_coin_num, data_electrolyte_code, data_coin_cell_code
|
||||
data_coin_type, data_electrolyte_code, data_coin_cell_code,
|
||||
formulation_order_code, formulation_ratio_str # ← 新增配方数据
|
||||
])
|
||||
#立刻写入磁盘
|
||||
csvfile.flush()
|
||||
@@ -1667,8 +1880,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
file_path: str = "/Users/sml/work"
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
简化版电池组装函数,整合了原 qiming_coin_cell_code 的参数设置和双滴模式
|
||||
|
||||
|
||||
此函数是 func_allpack_cmd 的增强版本,自动处理以下配置:
|
||||
- 负极片和隔膜的盘数及矩阵点位
|
||||
- 枪头盒矩阵点位
|
||||
@@ -1922,7 +2134,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
|
||||
def fun_wuliao_test(self) -> bool:
|
||||
#找到data_init中构建的2个物料盘
|
||||
liaopan3 = self.deck.get_resource("\u7535\u6c60\u6599\u76d8")
|
||||
test_battery_plate = self.deck.get_resource("\u7535\u6c60\u6599\u76d8")
|
||||
for i in range(16):
|
||||
battery = ElectrodeSheet(name=f"battery_{i}", size_x=16, size_y=16, size_z=2)
|
||||
battery._unilabos_state = {
|
||||
@@ -1932,7 +2144,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
"electrolyte_volume": 20.0,
|
||||
"electrolyte_name": f"DP{i}"
|
||||
}
|
||||
liaopan3.children[i].assign_child_resource(battery, location=None)
|
||||
test_battery_plate.children[i].assign_child_resource(battery, location=None)
|
||||
|
||||
ROS2DeviceNode.run_async_func(self._ros_node.update_resource, True, **{
|
||||
"resources": [self.deck]
|
||||
@@ -1975,7 +2187,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
data_assembly_time = self.data_assembly_time
|
||||
data_assembly_pressure = self.data_assembly_pressure
|
||||
data_electrolyte_volume = self.data_electrolyte_volume
|
||||
data_coin_num = self.data_coin_num
|
||||
data_coin_type = self.data_coin_type # 电池类型(7或8种物料)
|
||||
data_electrolyte_code = self.data_electrolyte_code
|
||||
data_coin_cell_code = self.data_coin_cell_code
|
||||
# 电解液瓶位置
|
||||
@@ -2089,7 +2301,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
writer.writerow([
|
||||
timestamp, data_open_circuit_voltage, data_pole_weight,
|
||||
data_assembly_time, data_assembly_pressure, data_electrolyte_volume,
|
||||
data_coin_num, data_electrolyte_code, data_coin_cell_code
|
||||
data_coin_type, data_electrolyte_code, data_coin_cell_code # ✅ 已修正
|
||||
])
|
||||
#立刻写入磁盘
|
||||
csvfile.flush()
|
||||
@@ -2140,7 +2352,7 @@ class CoinCellAssemblyWorkstation(WorkstationBase):
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 简单测试
|
||||
workstation = CoinCellAssemblyWorkstation(deck=CoincellDeck(setup=True, name="coin_cell_deck"))
|
||||
workstation = CoinCellAssemblyWorkstation(deck=yihua_coin_cell_deck(name="coin_cell_deck"))
|
||||
# workstation.qiming_coin_cell_code(fujipian_panshu=1, fujipian_juzhendianwei=2, gemopanshu=3, gemo_juzhendianwei=4, lvbodian=False, battery_pressure_mode=False, battery_pressure=4200, battery_clean_ignore=False)
|
||||
# print(f"工作站创建成功: {workstation.deck.name}")
|
||||
# print(f"料盘数量: {len(workstation.deck.children)}")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Name,DataType,InitValue,Comment,Attribute,DeviceType,Address,
|
||||
Name,DataType,InitValue,Comment,Attribute,DeviceType,Address,
|
||||
COIL_SYS_START_CMD,BOOL,,,,coil,8010,
|
||||
COIL_SYS_STOP_CMD,BOOL,,,,coil,8020,
|
||||
COIL_SYS_RESET_CMD,BOOL,,,,coil,8030,
|
||||
@@ -29,7 +29,9 @@ REG_DATA_POLE_WEIGHT,FLOAT32,,,,hold_register,10010,data_pole_weight
|
||||
REG_DATA_ASSEMBLY_PER_TIME,FLOAT32,,,,hold_register,10012,data_assembly_time
|
||||
REG_DATA_ASSEMBLY_PRESSURE,INT16,,,,hold_register,10014,data_assembly_pressure
|
||||
REG_DATA_ELECTROLYTE_VOLUME,INT16,,,,hold_register,10016,data_electrolyte_volume
|
||||
REG_DATA_COIN_NUM,INT16,,,,hold_register,10018,data_coin_num
|
||||
REG_DATA_COIN_TYPE,INT16,,,,hold_register,10018,data_coin_type
|
||||
REG_DATA_CURRENT_ASSEMBLING_COUNT,INT16,,,,hold_register,10072,data_current_assembling_count
|
||||
REG_DATA_CURRENT_COMPLETED_COUNT,INT16,,,,hold_register,10074,data_current_completed_count
|
||||
REG_DATA_ELECTROLYTE_CODE,STRING,,,,hold_register,10020,data_electrolyte_code()
|
||||
REG_DATA_COIN_CELL_CODE,STRING,,,,hold_register,10030,data_coin_cell_code()
|
||||
REG_DATA_STACK_VISON_CODE,STRING,,,,hold_register,12004,data_stack_vision_code()
|
||||
@@ -69,65 +71,75 @@ REG_MSG_BATTERY_CLEAN_IGNORE,BOOL,,,,coil,8460,
|
||||
COIL_MATERIAL_SEARCH_DIALOG_APPEAR,BOOL,,,,coil,6470,
|
||||
COIL_MATERIAL_SEARCH_CONFIRM_YES,BOOL,,,,coil,6480,
|
||||
COIL_MATERIAL_SEARCH_CONFIRM_NO,BOOL,,,,coil,6490,
|
||||
COIL_ALARM_100_SYSTEM_ERROR,BOOL,,,,coil,1000,异常100-系统异常
|
||||
COIL_ALARM_101_EMERGENCY_STOP,BOOL,,,,coil,1010,异常101-急停
|
||||
COIL_ALARM_111_GLOVEBOX_EMERGENCY_STOP,BOOL,,,,coil,1110,异常111-手套箱急停
|
||||
COIL_ALARM_112_GLOVEBOX_GRATING_BLOCKED,BOOL,,,,coil,1120,异常112-手套箱内光栅遮挡
|
||||
COIL_ALARM_160_PIPETTE_TIP_SHORTAGE,BOOL,,,,coil,1600,异常160-移液枪头缺料
|
||||
COIL_ALARM_161_POSITIVE_SHELL_SHORTAGE,BOOL,,,,coil,1610,异常161-正极壳缺料
|
||||
COIL_ALARM_162_ALUMINUM_FOIL_SHORTAGE,BOOL,,,,coil,1620,异常162-铝箔垫缺料
|
||||
COIL_ALARM_163_POSITIVE_PLATE_SHORTAGE,BOOL,,,,coil,1630,异常163-正极片缺料
|
||||
COIL_ALARM_164_SEPARATOR_SHORTAGE,BOOL,,,,coil,1640,异常164-隔膜缺料
|
||||
COIL_ALARM_165_NEGATIVE_PLATE_SHORTAGE,BOOL,,,,coil,1650,异常165-负极片缺料
|
||||
COIL_ALARM_166_FLAT_WASHER_SHORTAGE,BOOL,,,,coil,1660,异常166-平垫缺料
|
||||
COIL_ALARM_167_SPRING_WASHER_SHORTAGE,BOOL,,,,coil,1670,异常167-弹垫缺料
|
||||
COIL_ALARM_168_NEGATIVE_SHELL_SHORTAGE,BOOL,,,,coil,1680,异常168-负极壳缺料
|
||||
COIL_ALARM_169_FINISHED_BATTERY_FULL,BOOL,,,,coil,1690,异常169-成品电池满料
|
||||
COIL_ALARM_201_SERVO_AXIS_01_ERROR,BOOL,,,,coil,2010,异常201-伺服轴01异常
|
||||
COIL_ALARM_202_SERVO_AXIS_02_ERROR,BOOL,,,,coil,2020,异常202-伺服轴02异常
|
||||
COIL_ALARM_203_SERVO_AXIS_03_ERROR,BOOL,,,,coil,2030,异常203-伺服轴03异常
|
||||
COIL_ALARM_204_SERVO_AXIS_04_ERROR,BOOL,,,,coil,2040,异常204-伺服轴04异常
|
||||
COIL_ALARM_205_SERVO_AXIS_05_ERROR,BOOL,,,,coil,2050,异常205-伺服轴05异常
|
||||
COIL_ALARM_206_SERVO_AXIS_06_ERROR,BOOL,,,,coil,2060,异常206-伺服轴06异常
|
||||
COIL_ALARM_207_SERVO_AXIS_07_ERROR,BOOL,,,,coil,2070,异常207-伺服轴07异常
|
||||
COIL_ALARM_208_SERVO_AXIS_08_ERROR,BOOL,,,,coil,2080,异常208-伺服轴08异常
|
||||
COIL_ALARM_209_SERVO_AXIS_09_ERROR,BOOL,,,,coil,2090,异常209-伺服轴09异常
|
||||
COIL_ALARM_210_SERVO_AXIS_10_ERROR,BOOL,,,,coil,2100,异常210-伺服轴10异常
|
||||
COIL_ALARM_211_SERVO_AXIS_11_ERROR,BOOL,,,,coil,2110,异常211-伺服轴11异常
|
||||
COIL_ALARM_212_SERVO_AXIS_12_ERROR,BOOL,,,,coil,2120,异常212-伺服轴12异常
|
||||
COIL_ALARM_213_SERVO_AXIS_13_ERROR,BOOL,,,,coil,2130,异常213-伺服轴13异常
|
||||
COIL_ALARM_214_SERVO_AXIS_14_ERROR,BOOL,,,,coil,2140,异常214-伺服轴14异常
|
||||
COIL_ALARM_250_OTHER_COMPONENT_ERROR,BOOL,,,,coil,2500,异常250-其他元件异常
|
||||
COIL_ALARM_251_PIPETTE_COMM_ERROR,BOOL,,,,coil,2510,异常251-移液枪通讯异常
|
||||
COIL_ALARM_252_PIPETTE_ALARM,BOOL,,,,coil,2520,异常252-移液枪报警
|
||||
COIL_ALARM_256_ELECTRIC_GRIPPER_ERROR,BOOL,,,,coil,2560,异常256-电爪异常
|
||||
COIL_ALARM_262_RB_UNKNOWN_POSITION_ERROR,BOOL,,,,coil,2620,异常262-RB报警:未知点位错误
|
||||
COIL_ALARM_263_RB_XYZ_PARAM_LIMIT_ERROR,BOOL,,,,coil,2630,异常263-RB报警:X、Y、Z参数超限制
|
||||
COIL_ALARM_264_RB_VISION_PARAM_ERROR,BOOL,,,,coil,2640,异常264-RB报警:视觉参数误差过大
|
||||
COIL_ALARM_265_RB_NOZZLE_1_PICK_FAIL,BOOL,,,,coil,2650,异常265-RB报警:1#吸嘴取料失败
|
||||
COIL_ALARM_266_RB_NOZZLE_2_PICK_FAIL,BOOL,,,,coil,2660,异常266-RB报警:2#吸嘴取料失败
|
||||
COIL_ALARM_267_RB_NOZZLE_3_PICK_FAIL,BOOL,,,,coil,2670,异常267-RB报警:3#吸嘴取料失败
|
||||
COIL_ALARM_268_RB_NOZZLE_4_PICK_FAIL,BOOL,,,,coil,2680,异常268-RB报警:4#吸嘴取料失败
|
||||
COIL_ALARM_269_RB_TRAY_PICK_FAIL,BOOL,,,,coil,2690,异常269-RB报警:取物料盘失败
|
||||
COIL_ALARM_280_RB_COLLISION_ERROR,BOOL,,,,coil,2800,异常280-RB碰撞异常
|
||||
COIL_ALARM_290_VISION_SYSTEM_COMM_ERROR,BOOL,,,,coil,2900,异常290-视觉系统通讯异常
|
||||
COIL_ALARM_291_VISION_ALIGNMENT_NG,BOOL,,,,coil,2910,异常291-视觉对位NG异常
|
||||
COIL_ALARM_292_BARCODE_SCANNER_COMM_ERROR,BOOL,,,,coil,2920,异常292-扫码枪通讯异常
|
||||
COIL_ALARM_310_OCV_TRANSFER_NOZZLE_SUCTION_ERROR,BOOL,,,,coil,3100,异常310-开电移载吸嘴吸真空异常
|
||||
COIL_ALARM_311_OCV_TRANSFER_NOZZLE_BREAK_ERROR,BOOL,,,,coil,3110,异常311-开电移载吸嘴破真空异常
|
||||
COIL_ALARM_312_WEIGHT_TRANSFER_NOZZLE_SUCTION_ERROR,BOOL,,,,coil,3120,异常312-称重移载吸嘴吸真空异常
|
||||
COIL_ALARM_313_WEIGHT_TRANSFER_NOZZLE_BREAK_ERROR,BOOL,,,,coil,3130,异常313-称重移载吸嘴破真空异常
|
||||
COIL_ALARM_340_OCV_NOZZLE_TRANSFER_CYLINDER_ERROR,BOOL,,,,coil,3400,异常340-开路电压吸嘴移载气缸异常
|
||||
COIL_ALARM_342_OCV_NOZZLE_LIFT_CYLINDER_ERROR,BOOL,,,,coil,3420,异常342-开路电压吸嘴升降气缸异常
|
||||
COIL_ALARM_344_OCV_CRIMPING_CYLINDER_ERROR,BOOL,,,,coil,3440,异常344-开路电压旋压气缸异常
|
||||
COIL_ALARM_350_WEIGHT_NOZZLE_TRANSFER_CYLINDER_ERROR,BOOL,,,,coil,3500,异常350-称重吸嘴移载气缸异常
|
||||
COIL_ALARM_352_WEIGHT_NOZZLE_LIFT_CYLINDER_ERROR,BOOL,,,,coil,3520,异常352-称重吸嘴升降气缸异常
|
||||
COIL_ALARM_354_CLEANING_CLOTH_TRANSFER_CYLINDER_ERROR,BOOL,,,,coil,3540,异常354-清洗无尘布移载气缸异常
|
||||
COIL_ALARM_356_CLEANING_CLOTH_PRESS_CYLINDER_ERROR,BOOL,,,,coil,3560,异常356-清洗无尘布压紧气缸异常
|
||||
COIL_ALARM_360_ELECTROLYTE_BOTTLE_POSITION_CYLINDER_ERROR,BOOL,,,,coil,3600,异常360-电解液瓶定位气缸异常
|
||||
COIL_ALARM_362_PIPETTE_TIP_BOX_POSITION_CYLINDER_ERROR,BOOL,,,,coil,3620,异常362-移液枪头盒定位气缸异常
|
||||
COIL_ALARM_364_REAGENT_BOTTLE_GRIPPER_LIFT_CYLINDER_ERROR,BOOL,,,,coil,3640,异常364-试剂瓶夹爪升降气缸异常
|
||||
COIL_ALARM_366_REAGENT_BOTTLE_GRIPPER_CYLINDER_ERROR,BOOL,,,,coil,3660,异常366-试剂瓶夹爪气缸异常
|
||||
COIL_ALARM_370_PRESS_MODULE_BLOW_CYLINDER_ERROR,BOOL,,,,coil,3700,异常370-压制模块吹气气缸异常
|
||||
COIL_ALARM_151_ELECTROLYTE_BOTTLE_POSITION_ERROR,BOOL,,,,coil,1510,异常151-电解液瓶定位在籍异常
|
||||
COIL_ALARM_152_ELECTROLYTE_BOTTLE_CAP_ERROR,BOOL,,,,coil,1520,异常152-电解液瓶盖在籍异常
|
||||
COIL_ALARM_100_SYSTEM_ERROR,BOOL,,,,coil,1000,??100-????
|
||||
COIL_ALARM_101_EMERGENCY_STOP,BOOL,,,,coil,1010,??101-??
|
||||
COIL_ALARM_111_GLOVEBOX_EMERGENCY_STOP,BOOL,,,,coil,1110,??111-?????
|
||||
COIL_ALARM_112_GLOVEBOX_GRATING_BLOCKED,BOOL,,,,coil,1120,??112-????????
|
||||
COIL_ALARM_160_PIPETTE_TIP_SHORTAGE,BOOL,,,,coil,1600,??160-??????
|
||||
COIL_ALARM_161_POSITIVE_SHELL_SHORTAGE,BOOL,,,,coil,1610,??161-?????
|
||||
COIL_ALARM_162_ALUMINUM_FOIL_SHORTAGE,BOOL,,,,coil,1620,??162-?????
|
||||
COIL_ALARM_163_POSITIVE_PLATE_SHORTAGE,BOOL,,,,coil,1630,??163-?????
|
||||
COIL_ALARM_164_SEPARATOR_SHORTAGE,BOOL,,,,coil,1640,??164-????
|
||||
COIL_ALARM_165_NEGATIVE_PLATE_SHORTAGE,BOOL,,,,coil,1650,??165-?????
|
||||
COIL_ALARM_166_FLAT_WASHER_SHORTAGE,BOOL,,,,coil,1660,??166-????
|
||||
COIL_ALARM_167_SPRING_WASHER_SHORTAGE,BOOL,,,,coil,1670,??167-????
|
||||
COIL_ALARM_168_NEGATIVE_SHELL_SHORTAGE,BOOL,,,,coil,1680,??168-?????
|
||||
COIL_ALARM_169_FINISHED_BATTERY_FULL,BOOL,,,,coil,1690,??169-??????
|
||||
COIL_ALARM_201_SERVO_AXIS_01_ERROR,BOOL,,,,coil,2010,??201-???01??
|
||||
COIL_ALARM_202_SERVO_AXIS_02_ERROR,BOOL,,,,coil,2020,??202-???02??
|
||||
COIL_ALARM_203_SERVO_AXIS_03_ERROR,BOOL,,,,coil,2030,??203-???03??
|
||||
COIL_ALARM_204_SERVO_AXIS_04_ERROR,BOOL,,,,coil,2040,??204-???04??
|
||||
COIL_ALARM_205_SERVO_AXIS_05_ERROR,BOOL,,,,coil,2050,??205-???05??
|
||||
COIL_ALARM_206_SERVO_AXIS_06_ERROR,BOOL,,,,coil,2060,??206-???06??
|
||||
COIL_ALARM_207_SERVO_AXIS_07_ERROR,BOOL,,,,coil,2070,??207-???07??
|
||||
COIL_ALARM_208_SERVO_AXIS_08_ERROR,BOOL,,,,coil,2080,??208-???08??
|
||||
COIL_ALARM_209_SERVO_AXIS_09_ERROR,BOOL,,,,coil,2090,??209-???09??
|
||||
COIL_ALARM_210_SERVO_AXIS_10_ERROR,BOOL,,,,coil,2100,??210-???10??
|
||||
COIL_ALARM_211_SERVO_AXIS_11_ERROR,BOOL,,,,coil,2110,??211-???11??
|
||||
COIL_ALARM_212_SERVO_AXIS_12_ERROR,BOOL,,,,coil,2120,??212-???12??
|
||||
COIL_ALARM_213_SERVO_AXIS_13_ERROR,BOOL,,,,coil,2130,??213-???13??
|
||||
COIL_ALARM_214_SERVO_AXIS_14_ERROR,BOOL,,,,coil,2140,??214-???14??
|
||||
COIL_ALARM_250_OTHER_COMPONENT_ERROR,BOOL,,,,coil,2500,??250-??????
|
||||
COIL_ALARM_251_PIPETTE_COMM_ERROR,BOOL,,,,coil,2510,??251-???????
|
||||
COIL_ALARM_252_PIPETTE_ALARM,BOOL,,,,coil,2520,??252-?????
|
||||
COIL_ALARM_256_ELECTRIC_GRIPPER_ERROR,BOOL,,,,coil,2560,??256-????
|
||||
COIL_ALARM_262_RB_UNKNOWN_POSITION_ERROR,BOOL,,,,coil,2620,??262-RB?????????
|
||||
COIL_ALARM_263_RB_XYZ_PARAM_LIMIT_ERROR,BOOL,,,,coil,2630,??263-RB???X?Y?Z?????
|
||||
COIL_ALARM_264_RB_VISION_PARAM_ERROR,BOOL,,,,coil,2640,??264-RB???????????
|
||||
COIL_ALARM_265_RB_NOZZLE_1_PICK_FAIL,BOOL,,,,coil,2650,??265-RB???1#??????
|
||||
COIL_ALARM_266_RB_NOZZLE_2_PICK_FAIL,BOOL,,,,coil,2660,??266-RB???2#??????
|
||||
COIL_ALARM_267_RB_NOZZLE_3_PICK_FAIL,BOOL,,,,coil,2670,??267-RB???3#??????
|
||||
COIL_ALARM_268_RB_NOZZLE_4_PICK_FAIL,BOOL,,,,coil,2680,??268-RB???4#??????
|
||||
COIL_ALARM_269_RB_TRAY_PICK_FAIL,BOOL,,,,coil,2690,??269-RB?????????
|
||||
COIL_ALARM_280_RB_COLLISION_ERROR,BOOL,,,,coil,2800,??280-RB????
|
||||
COIL_ALARM_290_VISION_SYSTEM_COMM_ERROR,BOOL,,,,coil,2900,??290-????????
|
||||
COIL_ALARM_291_VISION_ALIGNMENT_NG,BOOL,,,,coil,2910,??291-????NG??
|
||||
COIL_ALARM_292_BARCODE_SCANNER_COMM_ERROR,BOOL,,,,coil,2920,??292-???????
|
||||
COIL_ALARM_310_OCV_TRANSFER_NOZZLE_SUCTION_ERROR,BOOL,,,,coil,3100,??310-???????????
|
||||
COIL_ALARM_311_OCV_TRANSFER_NOZZLE_BREAK_ERROR,BOOL,,,,coil,3110,??311-???????????
|
||||
COIL_ALARM_312_WEIGHT_TRANSFER_NOZZLE_SUCTION_ERROR,BOOL,,,,coil,3120,??312-???????????
|
||||
COIL_ALARM_313_WEIGHT_TRANSFER_NOZZLE_BREAK_ERROR,BOOL,,,,coil,3130,??313-???????????
|
||||
COIL_ALARM_340_OCV_NOZZLE_TRANSFER_CYLINDER_ERROR,BOOL,,,,coil,3400,??340-????????????
|
||||
COIL_ALARM_342_OCV_NOZZLE_LIFT_CYLINDER_ERROR,BOOL,,,,coil,3420,??342-????????????
|
||||
COIL_ALARM_344_OCV_CRIMPING_CYLINDER_ERROR,BOOL,,,,coil,3440,??344-??????????
|
||||
COIL_ALARM_350_WEIGHT_NOZZLE_TRANSFER_CYLINDER_ERROR,BOOL,,,,coil,3500,??350-??????????
|
||||
COIL_ALARM_352_WEIGHT_NOZZLE_LIFT_CYLINDER_ERROR,BOOL,,,,coil,3520,??352-??????????
|
||||
COIL_ALARM_354_CLEANING_CLOTH_TRANSFER_CYLINDER_ERROR,BOOL,,,,coil,3540,??354-???????????
|
||||
COIL_ALARM_356_CLEANING_CLOTH_PRESS_CYLINDER_ERROR,BOOL,,,,coil,3560,??356-???????????
|
||||
COIL_ALARM_360_ELECTROLYTE_BOTTLE_POSITION_CYLINDER_ERROR,BOOL,,,,coil,3600,??360-??????????
|
||||
COIL_ALARM_362_PIPETTE_TIP_BOX_POSITION_CYLINDER_ERROR,BOOL,,,,coil,3620,??362-???????????
|
||||
COIL_ALARM_364_REAGENT_BOTTLE_GRIPPER_LIFT_CYLINDER_ERROR,BOOL,,,,coil,3640,??364-???????????
|
||||
COIL_ALARM_366_REAGENT_BOTTLE_GRIPPER_CYLINDER_ERROR,BOOL,,,,coil,3660,??366-?????????
|
||||
COIL_ALARM_370_PRESS_MODULE_BLOW_CYLINDER_ERROR,BOOL,,,,coil,3700,??370-??????????
|
||||
COIL_ALARM_151_ELECTROLYTE_BOTTLE_POSITION_ERROR,BOOL,,,,coil,1510,??151-??????????
|
||||
COIL_ALARM_152_ELECTROLYTE_BOTTLE_CAP_ERROR,BOOL,,,,coil,1520,??152-?????????
|
||||
REG_DATA_10MM_POSITIVE_PLATE_REMAINING_COUNT,FLOAT32,,,,hold_register,520,10mm??????????R?
|
||||
REG_DATA_12MM_POSITIVE_PLATE_REMAINING_COUNT,FLOAT32,,,,hold_register,522,12mm??????????R?
|
||||
REG_DATA_16MM_POSITIVE_PLATE_REMAINING_COUNT,FLOAT32,,,,hold_register,524,16mm??????????R?
|
||||
REG_DATA_ALUMINUM_FOIL_REMAINING_COUNT,FLOAT32,,,,hold_register,526,?????????R?
|
||||
REG_DATA_POSITIVE_SHELL_REMAINING_COUNT,FLOAT32,,,,hold_register,528,??????????R?
|
||||
REG_DATA_FLAT_WASHER_REMAINING_COUNT,FLOAT32,,,,hold_register,530,?????????R?
|
||||
REG_DATA_NEGATIVE_SHELL_REMAINING_COUNT,FLOAT32,,,,hold_register,532,??????????R?
|
||||
REG_DATA_SPRING_WASHER_REMAINING_COUNT,FLOAT32,,,,hold_register,534,?????????R?
|
||||
REG_DATA_FINISHED_BATTERY_REMAINING_CAPACITY,FLOAT32,,,,hold_register,536,????????????R?
|
||||
REG_DATA_FINISHED_BATTERY_NG_REMAINING_CAPACITY,FLOAT32,,,,hold_register,538,????NG?????????R?
|
||||
|
||||
|
Reference in New Issue
Block a user