From 748326857137a93524bdebc7f51118ae7dc822ba Mon Sep 17 00:00:00 2001 From: zhaohe Date: Tue, 24 Sep 2024 15:20:50 +0800 Subject: [PATCH] update --- app.db | Bin 225280 -> 225280 bytes .../extapi/pagecontrol/ExtApiTabConfig.java | 4 +- .../service/app/AppDeviceInitializationModule.java | 10 + .../a8k/service/app/AppProjIDCardMgrService.java | 136 +++++++ .../service/app/appstate/AppStateMgrService.java | 2 +- .../java/a8k/service/appbase/A8kDeviceState.java | 28 -- .../appbase/progress/EmergencySampleProgress.java | 8 - .../appbase/progress/ReactionPlateProgress.java | 17 - .../appbase/progress/TubeHolderProgress.java | 7 - .../appbase/progress/TubeProcessProgress.java | 18 - .../a8k/service/appbase/result/ReactionResult.java | 13 - .../appbase/runstate/EmergencyPosRunState.java | 14 - .../appbase/runstate/ReactingPlateRunState.java | 22 -- .../appbase/runstate/TubeHolderRunState.java | 20 -- .../a8k/service/appbase/runstate/TubeRunState.java | 9 - .../a8k/service/bak_appbase/A8kDeviceState.java | 28 ++ .../progress/EmergencySampleProgress.java | 8 + .../progress/ReactionPlateProgress.java | 17 + .../bak_appbase/progress/TubeHolderProgress.java | 7 + .../bak_appbase/progress/TubeProcessProgress.java | 18 + .../service/bak_appbase/result/ReactionResult.java | 13 + .../bak_appbase/runstate/EmergencyPosRunState.java | 14 + .../runstate/ReactingPlateRunState.java | 22 ++ .../bak_appbase/runstate/TubeHolderRunState.java | 20 ++ .../service/bak_appbase/runstate/TubeRunState.java | 9 + .../calibration/PositionCalibration.java | 119 +++++++ .../commonctrl/HardwareCommonCtrl.java | 395 +++++++++++++++++++++ .../bak_devicectrl/ctrl/HbotControlService.java | 353 ++++++++++++++++++ .../bak_devicectrl/ctrl/PipetteGunCtrlService.java | 32 ++ .../ctrl/ReactionPlatesTransmitCtrl.java | 210 +++++++++++ .../bak_devicectrl/ctrl/SamplesPreProcesCtrl.java | 268 ++++++++++++++ .../bak_devicectrl/ctrl/TubeRackMoveCtrl.java | 298 ++++++++++++++++ .../service/bak_devicectrl/param/DebugParam.java | 29 ++ .../a8k/service/bak_devicectrl/param/PosParam.java | 392 ++++++++++++++++++++ .../service/bak_devicectrl/param/TimeParam.java | 52 +++ .../bak_devicectrl/status/DeviceStatus.java | 87 +++++ .../bak_devicectrl/testscript/TestScript.java | 250 +++++++++++++ .../calibration/PositionCalibration.java | 119 ------- .../devicectrl/commonctrl/HardwareCommonCtrl.java | 395 --------------------- .../devicectrl/ctrl/HbotControlService.java | 353 ------------------ .../devicectrl/ctrl/PipetteGunCtrlService.java | 32 -- .../ctrl/ReactionPlatesTransmitCtrl.java | 210 ----------- .../devicectrl/ctrl/SamplesPreProcesCtrl.java | 268 -------------- .../service/devicectrl/ctrl/TubeRackMoveCtrl.java | 298 ---------------- .../a8k/service/devicectrl/param/DebugParam.java | 29 -- .../a8k/service/devicectrl/param/PosParam.java | 392 -------------------- .../a8k/service/devicectrl/param/TimeParam.java | 52 --- .../service/devicectrl/status/DeviceStatus.java | 87 ----- .../service/devicectrl/testscript/TestScript.java | 250 ------------- .../project_mgr/AppProjIDCardMgrService.java | 137 ------- 50 files changed, 2790 insertions(+), 2781 deletions(-) create mode 100644 src/main/java/a8k/service/app/AppDeviceInitializationModule.java create mode 100644 src/main/java/a8k/service/app/AppProjIDCardMgrService.java delete mode 100644 src/main/java/a8k/service/appbase/A8kDeviceState.java delete mode 100644 src/main/java/a8k/service/appbase/progress/EmergencySampleProgress.java delete mode 100644 src/main/java/a8k/service/appbase/progress/ReactionPlateProgress.java delete mode 100644 src/main/java/a8k/service/appbase/progress/TubeHolderProgress.java delete mode 100644 src/main/java/a8k/service/appbase/progress/TubeProcessProgress.java delete mode 100644 src/main/java/a8k/service/appbase/result/ReactionResult.java delete mode 100644 src/main/java/a8k/service/appbase/runstate/EmergencyPosRunState.java delete mode 100644 src/main/java/a8k/service/appbase/runstate/ReactingPlateRunState.java delete mode 100644 src/main/java/a8k/service/appbase/runstate/TubeHolderRunState.java delete mode 100644 src/main/java/a8k/service/appbase/runstate/TubeRunState.java create mode 100644 src/main/java/a8k/service/bak_appbase/A8kDeviceState.java create mode 100644 src/main/java/a8k/service/bak_appbase/progress/EmergencySampleProgress.java create mode 100644 src/main/java/a8k/service/bak_appbase/progress/ReactionPlateProgress.java create mode 100644 src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java create mode 100644 src/main/java/a8k/service/bak_appbase/progress/TubeProcessProgress.java create mode 100644 src/main/java/a8k/service/bak_appbase/result/ReactionResult.java create mode 100644 src/main/java/a8k/service/bak_appbase/runstate/EmergencyPosRunState.java create mode 100644 src/main/java/a8k/service/bak_appbase/runstate/ReactingPlateRunState.java create mode 100644 src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java create mode 100644 src/main/java/a8k/service/bak_appbase/runstate/TubeRunState.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/calibration/PositionCalibration.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/commonctrl/HardwareCommonCtrl.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/ctrl/HbotControlService.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/ctrl/PipetteGunCtrlService.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/ctrl/ReactionPlatesTransmitCtrl.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/ctrl/SamplesPreProcesCtrl.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/ctrl/TubeRackMoveCtrl.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/param/DebugParam.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/param/PosParam.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/param/TimeParam.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/status/DeviceStatus.java create mode 100644 src/main/java/a8k/service/bak_devicectrl/testscript/TestScript.java delete mode 100644 src/main/java/a8k/service/devicectrl/calibration/PositionCalibration.java delete mode 100644 src/main/java/a8k/service/devicectrl/commonctrl/HardwareCommonCtrl.java delete mode 100644 src/main/java/a8k/service/devicectrl/ctrl/HbotControlService.java delete mode 100644 src/main/java/a8k/service/devicectrl/ctrl/PipetteGunCtrlService.java delete mode 100644 src/main/java/a8k/service/devicectrl/ctrl/ReactionPlatesTransmitCtrl.java delete mode 100644 src/main/java/a8k/service/devicectrl/ctrl/SamplesPreProcesCtrl.java delete mode 100644 src/main/java/a8k/service/devicectrl/ctrl/TubeRackMoveCtrl.java delete mode 100644 src/main/java/a8k/service/devicectrl/param/DebugParam.java delete mode 100644 src/main/java/a8k/service/devicectrl/param/PosParam.java delete mode 100644 src/main/java/a8k/service/devicectrl/param/TimeParam.java delete mode 100644 src/main/java/a8k/service/devicectrl/status/DeviceStatus.java delete mode 100644 src/main/java/a8k/service/devicectrl/testscript/TestScript.java delete mode 100644 src/main/java/a8k/service/project_mgr/AppProjIDCardMgrService.java diff --git a/app.db b/app.db index d3687f4e7815ae21a6cbe619a3931a6586e29c69..16fd3fcee3decdd1dc37de3b2451b4b28309c721 100644 GIT binary patch delta 613 zcma)&ze+BSC& z)XF&NYZG|N$QYyO_h*yw9vg~mkU^nRKvZk6q%_D@)+|(L+q#`v6DbkBEg?BtjVwTM zswbc79TO$YED5=8f|Pz5V<1LRZV?PkI?jQPmVq3m4+igmj6{s8Y0C<|7!*LLBCr-3n1gf%(PC`VMj}w;Tf(w#E=*bh@7pvY6oHrAfUbi^)QX}N39+ep zKg+T~HOi`o>be?L9~D*4>(i6ZgXMWS%Xg7D=z_br>vzFFl>Hj(b;0E>rphk4i=g7H boDDlK|7jT~AK78L>*3|s@mueu_Q_+^l?@$pN_7|<=yIjRlcrzH@A(jq=*Lu45&aw6LJ+2h>(=m zQJ{}Bx7_lS*l@U*P4}XvL{fQh!m&)`$}*ck3ZfcWjh6HrO;VW{bObtwR+&rzp@n)NzDc&Ta= z2x9&N#q%{*X${eNLo6C+qRlfh!CBc6-V1S|jd6esIb=HbcgcYYBm)ZONr;S~K)GKO z#i*JT)k8I@o~!HXqf(pGlh1?ZyuT=SkvM9DySN*+!9SG!8XL61W*1ZaZpj@4_0IZ> aaqHzjEz|6yILvP|zWh3V8@%+s-+urd6q(Hc diff --git a/src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java b/src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java index 911bbed..f96973a 100644 --- a/src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java +++ b/src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java @@ -2,14 +2,14 @@ package a8k.controler.extapi.pagecontrol; public enum ExtApiTabConfig { AppFrontEndEventRouter("基础组件.前端事件路由", true), - AppUserMgrService("应用.用户管理", true), //Ok AppSettingsMgr("应用.设备配置管理", true), //OK - AppProjectItemMgrService("应用.项目信息管理", true), + AppProjectItemMgrService("应用.ID卡状态管理", true), AppConsumablesMgrService("应用.耗材扫描", true), AppStateMgrService("应用.设备状态管理", true), SampleFormulaMgrService("应用.配方管理", true), AppCtrlService("应用.设备控制", true), + AppDeviceInitializationModule("应用.初始化", true), //底层硬件 A8kPipetteCtrlModule("A8kPipetteCtrlModule", true), diff --git a/src/main/java/a8k/service/app/AppDeviceInitializationModule.java b/src/main/java/a8k/service/app/AppDeviceInitializationModule.java new file mode 100644 index 0000000..614af9a --- /dev/null +++ b/src/main/java/a8k/service/app/AppDeviceInitializationModule.java @@ -0,0 +1,10 @@ +package a8k.service.app; + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.controler.extapi.utils.ExtApiTab; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.AppDeviceInitializationModule) +public class AppDeviceInitializationModule { +} diff --git a/src/main/java/a8k/service/app/AppProjIDCardMgrService.java b/src/main/java/a8k/service/app/AppProjIDCardMgrService.java new file mode 100644 index 0000000..4632a8f --- /dev/null +++ b/src/main/java/a8k/service/app/AppProjIDCardMgrService.java @@ -0,0 +1,136 @@ +package a8k.service.app; + + +import a8k.baseservice.appeventbus.appevent.*; +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.controler.extapi.utils.*; +import a8k.baseservice.appeventbus.AppEventListener; +import a8k.dbservice.A8kProjIdCardDBService; +import a8k.dbservice.type.A8kProjIdCardDBIterm; +import a8k.hardware.type.regindex.RegIndex; +import a8k.type.HardwareException; +import a8k.type.appret.AppRet; +import a8k.baseservice.appeventbus.AppEventBusService; +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.*; +import a8k.type.projecttype.a8kidcard.A8kIdCardInfo; +import a8k.utils.A8kIdCardDataParser; +import a8k.utils.wq.ZWorkQueue; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.AppProjectItemMgrService) +public class AppProjIDCardMgrService implements AppEventListener { + static Logger logger = org.slf4j.LoggerFactory.getLogger(AppProjIDCardMgrService.class); + + static class ORDER { + static final int readIDCardInfo = 1; + static final int saveIDCardInfo = 2; + static final int getProjectInfoList = 3; + } + + @Resource + A8kCanBusService canBus; + + @Resource + AppEventBusService eventBus; + + @Resource + A8kProjIdCardDBService a8kProjIdCardDBService; + + + A8kIdCardInfo mountedIdCardInfo; + + ZWorkQueue workQueue = new ZWorkQueue(2, 1); + + @PostConstruct + public void init() { + eventBus.regListener(this); + } + + /** + * 事件总线事件处理 + * @param event e + */ + @Override public void onAppEvent(AppEvent event) { + if (event instanceof A8kHardwareReport canPacket) { + A8kPacket packet = canPacket.getReportPacket(); + CmdId cmdId = CmdId.valueOf(packet.getCmdId()); + if (CmdId.event_a8000_idcard_online.equals(cmdId)) { + logger.info("插入ID卡"); + workQueue.addTask(this::readIDCard); + } else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) { + eventBus.pushEvent(new AppIDCardUnmountEvent()); + logger.info("拔出ID卡"); + } + } else if (event instanceof A8kCanBusOnConnectEvent canPacket) { + if (idCardStatus()) { + logger.info("ID卡读卡器在线"); + workQueue.addTask(this::readIDCard); + } + } + } + + + void readIDCard() { + //读取ID卡信息 + byte[] data = null; + try { + data = canBus.a8kIdcardReaderReadRaw(); + logger.info("ID卡信息:\n{}", A8kIdCardDataParser.dumpByte(data, 10)); + + A8kIdCardDataParser parser = new A8kIdCardDataParser(data); + mountedIdCardInfo = parser.parse(); + + + // + //TODO: + //检查解析结果,如果解析结果存在异常,则抛出错误事件给前端 + if (mountedIdCardInfo.lotName.isEmpty()) { + eventBus.pushEvent(new A8kErrorPromptEvent(A8kEcode.A8kIdCardLotIdIsEmpty.index)); + return; + } + + //如果检查结果,如果解析结果正常,则抛出新ID卡上限事件 + eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo)); + } catch (HardwareException ignored) { + } + } + + + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // EXT + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @ExtApiFn(name = "读取挂载的ID卡信息", order = ORDER.readIDCardInfo) + public AppRet readMountedIDCardInfo() { + return AppRet.success(mountedIdCardInfo); + } + + @ExtApiFn(name = "获取ID卡信息列表", order = ORDER.getProjectInfoList) + public AppRet> getProjectInfoList() { + return AppRet.success(a8kProjIdCardDBService.getAllIdCards()); + } + + @ExtApiFn(name = "保存挂载ID卡信息", order = ORDER.saveIDCardInfo) + public void saveIDCardInfo() { + a8kProjIdCardDBService.addIdCard(mountedIdCardInfo); + } + + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // STATUS + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + @ExtApiFn(name = "ID卡状态") + public Boolean idCardStatus() { + try { + return canBus.moduleGetReg(MId.A8kIdCardReader, RegIndex.kreg_id_card_reader_is_online) == 1; + } catch (HardwareException ignored) { + } + return false; + } +} diff --git a/src/main/java/a8k/service/app/appstate/AppStateMgrService.java b/src/main/java/a8k/service/app/appstate/AppStateMgrService.java index 8aa0d3c..ab1e4b3 100644 --- a/src/main/java/a8k/service/app/appstate/AppStateMgrService.java +++ b/src/main/java/a8k/service/app/appstate/AppStateMgrService.java @@ -5,7 +5,7 @@ import a8k.controler.extapi.utils.ExtApiFn; import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; import a8k.olddbservice.ProjectInfo; import a8k.type.appconsumable.Consumables; -import a8k.service.appbase.A8kDeviceState; +import a8k.service.bak_appbase.A8kDeviceState; import jakarta.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/a8k/service/appbase/A8kDeviceState.java b/src/main/java/a8k/service/appbase/A8kDeviceState.java deleted file mode 100644 index 4cee5e5..0000000 --- a/src/main/java/a8k/service/appbase/A8kDeviceState.java +++ /dev/null @@ -1,28 +0,0 @@ -package a8k.service.appbase; - -import a8k.olddbservice.ProjectInfo; -import a8k.type.appconsumable.Consumables; -import a8k.service.appbase.runstate.ReactingPlateRunState; -import a8k.service.appbase.runstate.EmergencyPosRunState; -import a8k.service.appbase.runstate.TubeHolderRunState; - -import java.util.List; - -public class A8kDeviceState { - //耗材状态 - public Consumables consumable = new Consumables(); - //急诊为状态 - public EmergencyPosRunState emergencyPosRunState = new EmergencyPosRunState(); - //正在孵育的任务状态 - public List incubatingPlateStates = null; - //当前正在被处理的试管架状态 - public TubeHolderRunState tubeHolderRunState = new TubeHolderRunState(); - //温度 - public Integer temperature = 25; - //当前ID卡信息 - public ProjectInfo curIdCardInfo = null; - - Boolean deviceInited = false; //设备是否初始化过 - Boolean devicePoweredOffNormally = false; //设备是否正常关机 - -} diff --git a/src/main/java/a8k/service/appbase/progress/EmergencySampleProgress.java b/src/main/java/a8k/service/appbase/progress/EmergencySampleProgress.java deleted file mode 100644 index a7206e5..0000000 --- a/src/main/java/a8k/service/appbase/progress/EmergencySampleProgress.java +++ /dev/null @@ -1,8 +0,0 @@ -package a8k.service.appbase.progress; - -public enum EmergencySampleProgress { - IDLE,// - WAITING_SAMPLE,// - PROCESSING,// - PROCESS_COMPLETE,// -} diff --git a/src/main/java/a8k/service/appbase/progress/ReactionPlateProgress.java b/src/main/java/a8k/service/appbase/progress/ReactionPlateProgress.java deleted file mode 100644 index 59384e2..0000000 --- a/src/main/java/a8k/service/appbase/progress/ReactionPlateProgress.java +++ /dev/null @@ -1,17 +0,0 @@ -package a8k.service.appbase.progress; - -//反应板条状态 -public enum ReactionPlateProgress { - //板夹仓中 - InThePlateBox, - //等待滴液 - WaitingForDrip, - //赋予中 - Incubating, - //孵育完成 - Incubated, - //孵育异常 - IncubateError, - //板条码异常 - PlateCodeError, -} diff --git a/src/main/java/a8k/service/appbase/progress/TubeHolderProgress.java b/src/main/java/a8k/service/appbase/progress/TubeHolderProgress.java deleted file mode 100644 index 261cef5..0000000 --- a/src/main/java/a8k/service/appbase/progress/TubeHolderProgress.java +++ /dev/null @@ -1,7 +0,0 @@ -package a8k.service.appbase.progress; - -public enum TubeHolderProgress { - TubeHolderStateIdle, //空闲 - TubeHolderStateProcessing, //处理中 - TubeHolderStateProcessed, //处理完成 -} diff --git a/src/main/java/a8k/service/appbase/progress/TubeProcessProgress.java b/src/main/java/a8k/service/appbase/progress/TubeProcessProgress.java deleted file mode 100644 index 4e739ba..0000000 --- a/src/main/java/a8k/service/appbase/progress/TubeProcessProgress.java +++ /dev/null @@ -1,18 +0,0 @@ -package a8k.service.appbase.progress; - -public enum TubeProcessProgress { - //空 - EMPTY, - //待处理 - READY, - //预处理中 - PRE_PROCESSING, - //待采样 - TO_BE_SAMPLED, - //采样中 - SAMPLING, - //采样完成 - SAMPLED, - //处理完成 - PROCESS_COMPLETE, -} diff --git a/src/main/java/a8k/service/appbase/result/ReactionResult.java b/src/main/java/a8k/service/appbase/result/ReactionResult.java deleted file mode 100644 index 33dacad..0000000 --- a/src/main/java/a8k/service/appbase/result/ReactionResult.java +++ /dev/null @@ -1,13 +0,0 @@ -package a8k.service.appbase.result; - -public class ReactionResult { - - public Boolean result0Error; - public Boolean result1Error; - public Boolean result2Error; - - public String result0; - public String result1; - public String result2; - -} diff --git a/src/main/java/a8k/service/appbase/runstate/EmergencyPosRunState.java b/src/main/java/a8k/service/appbase/runstate/EmergencyPosRunState.java deleted file mode 100644 index 9e6eafe..0000000 --- a/src/main/java/a8k/service/appbase/runstate/EmergencyPosRunState.java +++ /dev/null @@ -1,14 +0,0 @@ -package a8k.service.appbase.runstate; - -import a8k.type.sampleinfo.SampleInfo; -import a8k.service.appbase.result.ReactionResult; -import a8k.service.appbase.progress.EmergencySampleProgress; - -public class EmergencyPosRunState { - //急诊位状态 - public EmergencySampleProgress emergencySampleProgress = EmergencySampleProgress.IDLE; - // - SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态 - //急诊位反应结果 - public ReactionResult emergencyResult = new ReactionResult(); -} diff --git a/src/main/java/a8k/service/appbase/runstate/ReactingPlateRunState.java b/src/main/java/a8k/service/appbase/runstate/ReactingPlateRunState.java deleted file mode 100644 index 3d59ba6..0000000 --- a/src/main/java/a8k/service/appbase/runstate/ReactingPlateRunState.java +++ /dev/null @@ -1,22 +0,0 @@ -package a8k.service.appbase.runstate; - -import a8k.service.appbase.result.ReactionResult; -import a8k.type.sampleinfo.SampleInfo; -import a8k.service.appbase.progress.ReactionPlateProgress; - -import java.util.Date; - -public class ReactingPlateRunState { - ReactionPlateProgress progress; //孵育盘状态 - - String sampleUUID; //样本UUID 系统自动生成 - String projectId; //项目id - - SampleInfo bindSample; //绑定的样本运行状态 - - Integer incubationPos; //孵育盘中的位置 0->19 - Date startIncubatedTime; //开始孵育时间 - Integer targetIncubatedTimeS; //目标孵育时间 - - ReactionResult reactionResult; //反应结果 -} diff --git a/src/main/java/a8k/service/appbase/runstate/TubeHolderRunState.java b/src/main/java/a8k/service/appbase/runstate/TubeHolderRunState.java deleted file mode 100644 index 47528e5..0000000 --- a/src/main/java/a8k/service/appbase/runstate/TubeHolderRunState.java +++ /dev/null @@ -1,20 +0,0 @@ -package a8k.service.appbase.runstate; - -import a8k.type.type.A8kTubeType; -import a8k.type.type.BloodType; -import a8k.service.appbase.progress.TubeHolderProgress; - -public class TubeHolderRunState { - public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 - public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //管子类型 - public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.TubeHolderStateIdle; //管子状态 - public TubeRunState[] tubeRunStates = new TubeRunState[10]; //管子 - public Integer processingTubeIndex = -1; //当前正在被处理的试管索引 - - public TubeHolderRunState() { - for (int i = 0; i < tubeRunStates.length; i++) { - tubeRunStates[i] = new TubeRunState(); - } - processingTubeIndex = 1; - } -} diff --git a/src/main/java/a8k/service/appbase/runstate/TubeRunState.java b/src/main/java/a8k/service/appbase/runstate/TubeRunState.java deleted file mode 100644 index eeb162e..0000000 --- a/src/main/java/a8k/service/appbase/runstate/TubeRunState.java +++ /dev/null @@ -1,9 +0,0 @@ -package a8k.service.appbase.runstate; - -import a8k.type.sampleinfo.SampleInfo; -import a8k.service.appbase.progress.TubeProcessProgress; - -public class TubeRunState { - public TubeProcessProgress tubeProcessProgress = TubeProcessProgress.EMPTY; //样本运行状态 - public SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态 -} diff --git a/src/main/java/a8k/service/bak_appbase/A8kDeviceState.java b/src/main/java/a8k/service/bak_appbase/A8kDeviceState.java new file mode 100644 index 0000000..a811638 --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/A8kDeviceState.java @@ -0,0 +1,28 @@ +package a8k.service.bak_appbase; + +import a8k.olddbservice.ProjectInfo; +import a8k.type.appconsumable.Consumables; +import a8k.service.bak_appbase.runstate.ReactingPlateRunState; +import a8k.service.bak_appbase.runstate.EmergencyPosRunState; +import a8k.service.bak_appbase.runstate.TubeHolderRunState; + +import java.util.List; + +public class A8kDeviceState { + //耗材状态 + public Consumables consumable = new Consumables(); + //急诊为状态 + public EmergencyPosRunState emergencyPosRunState = new EmergencyPosRunState(); + //正在孵育的任务状态 + public List incubatingPlateStates = null; + //当前正在被处理的试管架状态 + public TubeHolderRunState tubeHolderRunState = new TubeHolderRunState(); + //温度 + public Integer temperature = 25; + //当前ID卡信息 + public ProjectInfo curIdCardInfo = null; + + Boolean deviceInited = false; //设备是否初始化过 + Boolean devicePoweredOffNormally = false; //设备是否正常关机 + +} diff --git a/src/main/java/a8k/service/bak_appbase/progress/EmergencySampleProgress.java b/src/main/java/a8k/service/bak_appbase/progress/EmergencySampleProgress.java new file mode 100644 index 0000000..e3dc41e --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/progress/EmergencySampleProgress.java @@ -0,0 +1,8 @@ +package a8k.service.bak_appbase.progress; + +public enum EmergencySampleProgress { + IDLE,// + WAITING_SAMPLE,// + PROCESSING,// + PROCESS_COMPLETE,// +} diff --git a/src/main/java/a8k/service/bak_appbase/progress/ReactionPlateProgress.java b/src/main/java/a8k/service/bak_appbase/progress/ReactionPlateProgress.java new file mode 100644 index 0000000..d450b86 --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/progress/ReactionPlateProgress.java @@ -0,0 +1,17 @@ +package a8k.service.bak_appbase.progress; + +//反应板条状态 +public enum ReactionPlateProgress { + //板夹仓中 + InThePlateBox, + //等待滴液 + WaitingForDrip, + //赋予中 + Incubating, + //孵育完成 + Incubated, + //孵育异常 + IncubateError, + //板条码异常 + PlateCodeError, +} diff --git a/src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java b/src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java new file mode 100644 index 0000000..9fe0fc0 --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java @@ -0,0 +1,7 @@ +package a8k.service.bak_appbase.progress; + +public enum TubeHolderProgress { + TubeHolderStateIdle, //空闲 + TubeHolderStateProcessing, //处理中 + TubeHolderStateProcessed, //处理完成 +} diff --git a/src/main/java/a8k/service/bak_appbase/progress/TubeProcessProgress.java b/src/main/java/a8k/service/bak_appbase/progress/TubeProcessProgress.java new file mode 100644 index 0000000..8ee4d96 --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/progress/TubeProcessProgress.java @@ -0,0 +1,18 @@ +package a8k.service.bak_appbase.progress; + +public enum TubeProcessProgress { + //空 + EMPTY, + //待处理 + READY, + //预处理中 + PRE_PROCESSING, + //待采样 + TO_BE_SAMPLED, + //采样中 + SAMPLING, + //采样完成 + SAMPLED, + //处理完成 + PROCESS_COMPLETE, +} diff --git a/src/main/java/a8k/service/bak_appbase/result/ReactionResult.java b/src/main/java/a8k/service/bak_appbase/result/ReactionResult.java new file mode 100644 index 0000000..1c7026f --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/result/ReactionResult.java @@ -0,0 +1,13 @@ +package a8k.service.bak_appbase.result; + +public class ReactionResult { + + public Boolean result0Error; + public Boolean result1Error; + public Boolean result2Error; + + public String result0; + public String result1; + public String result2; + +} diff --git a/src/main/java/a8k/service/bak_appbase/runstate/EmergencyPosRunState.java b/src/main/java/a8k/service/bak_appbase/runstate/EmergencyPosRunState.java new file mode 100644 index 0000000..4589382 --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/runstate/EmergencyPosRunState.java @@ -0,0 +1,14 @@ +package a8k.service.bak_appbase.runstate; + +import a8k.type.sampleinfo.SampleInfo; +import a8k.service.bak_appbase.result.ReactionResult; +import a8k.service.bak_appbase.progress.EmergencySampleProgress; + +public class EmergencyPosRunState { + //急诊位状态 + public EmergencySampleProgress emergencySampleProgress = EmergencySampleProgress.IDLE; + // + SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态 + //急诊位反应结果 + public ReactionResult emergencyResult = new ReactionResult(); +} diff --git a/src/main/java/a8k/service/bak_appbase/runstate/ReactingPlateRunState.java b/src/main/java/a8k/service/bak_appbase/runstate/ReactingPlateRunState.java new file mode 100644 index 0000000..e121b4d --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/runstate/ReactingPlateRunState.java @@ -0,0 +1,22 @@ +package a8k.service.bak_appbase.runstate; + +import a8k.service.bak_appbase.result.ReactionResult; +import a8k.type.sampleinfo.SampleInfo; +import a8k.service.bak_appbase.progress.ReactionPlateProgress; + +import java.util.Date; + +public class ReactingPlateRunState { + ReactionPlateProgress progress; //孵育盘状态 + + String sampleUUID; //样本UUID 系统自动生成 + String projectId; //项目id + + SampleInfo bindSample; //绑定的样本运行状态 + + Integer incubationPos; //孵育盘中的位置 0->19 + Date startIncubatedTime; //开始孵育时间 + Integer targetIncubatedTimeS; //目标孵育时间 + + ReactionResult reactionResult; //反应结果 +} diff --git a/src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java b/src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java new file mode 100644 index 0000000..8b27288 --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java @@ -0,0 +1,20 @@ +package a8k.service.bak_appbase.runstate; + +import a8k.type.type.A8kTubeType; +import a8k.type.type.BloodType; +import a8k.service.bak_appbase.progress.TubeHolderProgress; + +public class TubeHolderRunState { + public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型 + public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //管子类型 + public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.TubeHolderStateIdle; //管子状态 + public TubeRunState[] tubeRunStates = new TubeRunState[10]; //管子 + public Integer processingTubeIndex = -1; //当前正在被处理的试管索引 + + public TubeHolderRunState() { + for (int i = 0; i < tubeRunStates.length; i++) { + tubeRunStates[i] = new TubeRunState(); + } + processingTubeIndex = 1; + } +} diff --git a/src/main/java/a8k/service/bak_appbase/runstate/TubeRunState.java b/src/main/java/a8k/service/bak_appbase/runstate/TubeRunState.java new file mode 100644 index 0000000..c116959 --- /dev/null +++ b/src/main/java/a8k/service/bak_appbase/runstate/TubeRunState.java @@ -0,0 +1,9 @@ +package a8k.service.bak_appbase.runstate; + +import a8k.type.sampleinfo.SampleInfo; +import a8k.service.bak_appbase.progress.TubeProcessProgress; + +public class TubeRunState { + public TubeProcessProgress tubeProcessProgress = TubeProcessProgress.EMPTY; //样本运行状态 + public SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态 +} diff --git a/src/main/java/a8k/service/bak_devicectrl/calibration/PositionCalibration.java b/src/main/java/a8k/service/bak_devicectrl/calibration/PositionCalibration.java new file mode 100644 index 0000000..0047aea --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/calibration/PositionCalibration.java @@ -0,0 +1,119 @@ +package a8k.service.bak_devicectrl.calibration; + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.type.HardwareException; +import a8k.type.appret.AppRet; +import a8k.type.cfg.Pos2d; +import a8k.controler.extapi.utils.*; +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.MId; +import a8k.service.bak_devicectrl.param.DebugParam; +import a8k.service.bak_devicectrl.param.PosParam; +import a8k.service.bak_devicectrl.param.TimeParam; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.PositionCalibration) +public class PositionCalibration { + + @Resource + A8kCanBusService canBus; + @Resource + TimeParam timep; + @Resource + PosParam pp; + @Resource + DebugParam dp; + + @ExtApiFn(name = "试管夹平移电机-使能", group = "电机使能") + public void FeedingModXMEnable(Boolean enable) throws HardwareException { + canBus.stepMotorEnable(MId.FeedingModXM, enable ? 1 : 0); + } + + @ExtApiFn(name = "板夹仓Y轴-使能", group = "电机使能") + public void platesBoxYMEndble(Boolean enable) throws HardwareException { + canBus.stepMotorEnable(MId.PlatesBoxYM, enable ? 1 : 0); + } + + @ExtApiFn(name = "板夹仓推杆-使能", group = "电机使能") + public void platesBoxPusherMEndble(Boolean enable) throws HardwareException { + canBus.stepMotorEnable(MId.PlatesBoxPusherM, enable ? 1 : 0); + } + + @ExtApiFn(name = "拉杆-使能", group = "电机使能") + public void optModPullMEndble(Boolean enable) throws HardwareException { + canBus.stepMotorEnable(MId.OptModPullM, enable ? 1 : 0); + } + + @ExtApiFn(name = "光学模组扫描器-使能", group = "电机使能") + public void optModScannerMEndble(Boolean enable) throws HardwareException { + canBus.stepMotorEnable(MId.OptModScannerM, enable ? 1 : 0); + } + + @ExtApiFn(name = "转盘-使能", group = "电机使能") + public void incubatorRotateCtrlMEndble(Boolean enable) throws HardwareException { + canBus.stepMotorEnable(MId.IncubatorRotateCtrlM, enable ? 1 : 0); + + } + + + @ExtApiFn(name = "试管夹平移电机-读取位置", group = "通过归零测量位置") + public AppRet readXPosByMoveZero() throws HardwareException, InterruptedException { + return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.FeedingModXM, timep.getActionOvertime())); + } + + + @ExtApiFn(name = "通过归零读取<板夹仓>位置", group = "通过归零测量位置") + public AppRet readPlatesBoxYMPosByMoveToZero() throws HardwareException, InterruptedException { + return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.PlatesBoxYM, timep.getActionOvertime())); + } + + @ExtApiFn(name = "通过归零读取<推杆>位置", group = "通过归零测量位置") + public AppRet readPlatesBoxPusherMPosByMoveToZero() throws HardwareException, InterruptedException { + return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.PlatesBoxPusherM, timep.getActionOvertime())); + } + + @ExtApiFn(name = "通过归零读取<拉杆>位置", group = "通过归零测量位置") + public AppRet readOptModPullMPosByMoveToZero() throws HardwareException, InterruptedException { + return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.OptModPullM, timep.getActionOvertime())); + } + + @ExtApiFn(name = "通过归零读取<光学模组扫描器>位置", group = "通过归零测量位置") + public AppRet readOptModScannerMPosByMoveToZero() throws HardwareException, InterruptedException { + return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.OptModScannerM, timep.getActionOvertime())); + } + + @ExtApiFn(name = "通过归零读取<摇匀模组Z轴>位置", group = "通过归零测量位置") + public AppRet readShakeModGripperZMPosByMoveToZero() throws HardwareException, InterruptedException { + return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.ShakeModGripperZM, timep.getActionOvertime())); + } + + + @EnginnerPageStatu(name = "HbotPos", group = "Hbot") + public String getHbotPos() throws HardwareException { + Pos2d pos = canBus.hbotReadPos(MId.HbotM); + return pos.toString(); + } + + + @EnginnerPageStatu(name = "转盘位置") + public String getIncubatorRotateCtrlMPos() throws HardwareException { + Integer pos = canBus.stepMotorReadPos(MId.IncubatorRotateCtrlM); + return pos.toString(); + } + + @EnginnerPageStatu(name = "抓手Y轴位置", group = "摇匀模组") + public String getShakeModGripperYPos() throws HardwareException { + Integer pos = canBus.miniServoReadPos(MId.ShakeModGripperYSV); + return pos.toString(); + } + + @EnginnerPageStatu(name = "抓手位置", group = "摇匀模组") + public String getGripperPos() throws HardwareException { + Integer pos = canBus.miniServoReadPos(MId.ShakeModGripperSV); + return pos.toString(); + } + + +} diff --git a/src/main/java/a8k/service/bak_devicectrl/commonctrl/HardwareCommonCtrl.java b/src/main/java/a8k/service/bak_devicectrl/commonctrl/HardwareCommonCtrl.java new file mode 100644 index 0000000..e912db5 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/commonctrl/HardwareCommonCtrl.java @@ -0,0 +1,395 @@ +package a8k.service.bak_devicectrl.commonctrl; + + +import a8k.type.HardwareException; +import a8k.type.appret.AppRet; +import a8k.controler.extapi.utils.ExtApiTab; +import a8k.controler.extapi.utils.ExtApiFn; +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.hardware.type.a8kcanprotocol.IOId; +import a8k.hardware.type.a8kcanprotocol.MId; +import a8k.service.bak_devicectrl.param.PosParam; +import a8k.service.bak_devicectrl.param.TimeParam; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.HardwareCommonCtrl) +public class HardwareCommonCtrl { + static Logger logger = org.slf4j.LoggerFactory.getLogger(HardwareCommonCtrl.class); + + static class ORDER { + static final int initializeDevice = 1; + static final int deviceClear = 2; + static final int deviceForceStop = 3; + static final int forceDisableAllMOtor = 4; + static final int deviceEnable = 5; + } + + @Resource + A8kCanBusService canBus; + + @Resource + TimeParam timep; + + @Resource + PosParam posp; + + Boolean workState = false; + + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // CHECK + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + private AppRet checkDeviceStateBeforeRunToZero() throws HardwareException { + logger.info("checkDeviceStateBeforeRunToZero"); + //试管平移通道是否有障碍 + if (canBus.getIOState(IOId.THChInterPPS) || canBus.getIOState(IOId.THChOuterPPS)) { + logger.warn("THChInterPPS or THChOuterPPS is trigger"); + return AppRet.fail(A8kEcode.TubeXChannelIsNotEmpty.index); + } + + //板夹仓盖子是否盖上 + if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { + return AppRet.fail(A8kEcode.PlateBoxNotCover.index); + } + + //板夹仓卡板检测 + if (canBus.getIOState(IOId.PlateBoxPlateStuckPPS)) { + return AppRet.fail(A8kEcode.PlateStuckDetectorSensorTrigger.index); + } + + //检查钩板电机是否处于终点位置 + if (!canBus.getIOState(IOId.PullerMZeroPPS)) { + return AppRet.fail(A8kEcode.PullerMInitPosError.index); + } + + //检查板夹仓光电是否处于起点位置 + if (!canBus.getIOState(IOId.PusherMZeroPPS)) { + return AppRet.fail(A8kEcode.PusherMInitPosError.index); + } + //板夹仓光电 + if (canBus.getIOState(IOId.RecycleBinOverflowPPS)) { + return AppRet.fail(A8kEcode.RecycleBinOverflow.index); + } + + return AppRet.success(); + } + + private void checkStopFlag() throws HardwareException { + if (!workState) { + throw new HardwareException(A8kEcode.StopByUser.index); + } + } + + + private AppRet moveMotorToZero() throws HardwareException, InterruptedException { + + //进出料初始化 + canBus.stepMotorEasyMoveToZeroBlock(MId.FeedingModXM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + + canBus.miniServoMoveToBlock(MId.ShakeModTubeScanerClampingSV, 20, timep.getActionOvertime()); + checkStopFlag(); + + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, 300, timep.getActionOvertime()); + checkStopFlag(); + + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, 300, timep.getActionOvertime()); + checkStopFlag(); + + + canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModClampingM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModGripperZM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModShakeM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + + canBus.stepMotorEasyMoveTo(MId.ShakeModShakeM, 90); + checkStopFlag(); + + //板夹仓初始化 + canBus.stepMotorEasyMoveToZeroBlock(MId.PlatesBoxYM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + canBus.stepMotorEasyMoveToZeroBlock(MId.PlatesBoxPusherM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + //光学模组初始化 + canBus.stepMotorEasyMoveToZeroBlock(MId.OptModPullM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + canBus.stepMotorEasyMoveToZeroBlock(MId.OptModScannerM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + //HBot初始化 + canBus.hbotMoveToZero(MId.HbotM); + checkStopFlag(); + + // TODO canBus.stepMotorEasyMoveToZeroBlock(MId.PipetteModZM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + //转盘归零 + canBus.stepMotorEasyMoveToZeroBlock(MId.IncubatorRotateCtrlM, timep.getRuntoZeroActionOvertime()); + checkStopFlag(); + + + return AppRet.success(); + } + + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // Expose API + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @ExtApiFn(name = "设备初始化", order = ORDER.initializeDevice) + public AppRet initializeDevice() throws HardwareException, InterruptedException { + logger.info("Initializing device ..."); + boolean initSuc = false; + workState = true; + AppRet ecode; + try { + //打开必要的电源 + canBus.setIOState(IOId.RecycleBinOverflowPPSPowerCtrl, true); + + //检查设备状态 + ecode = checkDeviceStateBeforeRunToZero(); + if (!ecode.isSuccess()) { + return AppRet.fail(ecode); + } + // 复位设备 + logger.info("moveMotorToZero"); + ecode = moveMotorToZero(); + if (!ecode.isSuccess()) { + return AppRet.fail(ecode); + } + initSuc = true; + logger.info("Device initialization completed"); + + } finally { + if (!initSuc) { + try { + canBus.stepMotorEnable(MId.ShakeModClampingM, 1); + } catch (HardwareException ignored) { + } + try { + canBus.stepMotorEasyMoveBy(MId.ShakeModClampingM, 2); + } catch (HardwareException ignored) { + } + } + } + return AppRet.success("初始化完成"); + + } + + // @EnginnerPageAction(name = "清空板夹仓板夹", order = ORDER.deviceClear) + // public void clearDevice() { + // //TODO + // } + + + @ExtApiFn(name = "设备强制停止", order = ORDER.deviceForceStop) + public void deviceForceStop() throws HardwareException { + //StopAllMotor + //进出料初始化 + try { + canBus.moduleStop(MId.FeedingModInfeedM); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.FeedingModXM); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.FeedingModOutfeedM); + } catch (HardwareException ignored) { + } + //摇匀模组初始化 + try { + canBus.moduleStop(MId.ShakeModClampingM); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.ShakeModGripperZM); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.ShakeModShakeM); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.ShakeModGripperYSV); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.ShakeModGripperSV); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.ShakeModTubeScanerClampingSV); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.ShakeModTubeScanerRotateSV); + } catch (HardwareException ignored) { + } + //板夹仓初始化 + try { + canBus.moduleStop(MId.PlatesBoxYM); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.PlatesBoxPusherM); + } catch (HardwareException ignored) { + } + //光学模组初始化 + try { + canBus.moduleStop(MId.OptModPullM); + } catch (HardwareException ignored) { + } + try { + canBus.moduleStop(MId.OptModScannerM); + } catch (HardwareException ignored) { + } + //HBot初始化 + try { + canBus.moduleStop(MId.HbotM); + } catch (HardwareException ignored) { + } + // try { + // TODO canBus.moduleStop(MId.PipetteModZM); + // } catch (HardwareException ignored) { + // } + //转盘归零 + try { + canBus.moduleStop(MId.IncubatorRotateCtrlM); + } catch (HardwareException ignored) { + } + + } + + @ExtApiFn(name = "设备强制使能所有电机", order = ORDER.forceDisableAllMOtor) + public void forceDisableAllMOtor() { + //Disable all motor + //进出料初始化 + try { + canBus.stepMotorEnable(MId.FeedingModInfeedM, 0); + } catch (HardwareException ignored) { + } + try { + canBus.stepMotorEnable(MId.FeedingModXM, 0); + } catch (HardwareException ignored) { + } + try { + canBus.stepMotorEnable(MId.FeedingModOutfeedM, 0); + } catch (HardwareException ignored) { + } + + //摇匀模组初始化 + try { + canBus.stepMotorEnable(MId.ShakeModClampingM, 0); + } catch (HardwareException ignored) { + } + try { + canBus.stepMotorEnable(MId.ShakeModGripperZM, 0); + } catch (HardwareException ignored) { + } + try { + canBus.stepMotorEnable(MId.ShakeModShakeM, 0); + } catch (HardwareException ignored) { + } + try { + canBus.miniServoEnable(MId.ShakeModGripperYSV, 0); + } catch (HardwareException ignored) { + } + try { + canBus.miniServoEnable(MId.ShakeModGripperSV, 0); + } catch (HardwareException ignored) { + } + try { + canBus.miniServoEnable(MId.ShakeModTubeScanerClampingSV, 0); + } catch (HardwareException ignored) { + } + try { + canBus.miniServoEnable(MId.ShakeModTubeScanerRotateSV, 0); + } catch (HardwareException ignored) { + } + + //板夹仓初始化 + try { + canBus.stepMotorEnable(MId.PlatesBoxYM, 0); + } catch (HardwareException ignored) { + } + try { + canBus.stepMotorEnable(MId.PlatesBoxPusherM, 0); + } catch (HardwareException ignored) { + } + + //光学模组初始化 + try { + canBus.stepMotorEnable(MId.OptModPullM, 0); + } catch (HardwareException ignored) { + } + try { + canBus.stepMotorEnable(MId.OptModScannerM, 0); + } catch (HardwareException ignored) { + } + + //HBot初始化 + try { + canBus.hbotEnable(MId.HbotM, 0); + } catch (HardwareException ignored) { + } + // try { + //TODO canBus.stepMotorEnable(MId.PipetteModZM, 0); + // } catch (HardwareException ignored) { + // } + + //转盘归零 + try { + canBus.stepMotorEnable(MId.IncubatorRotateCtrlM, 0); + } catch (HardwareException ignored) { + } + } + + @ExtApiFn(name = "设备使能", order = ORDER.deviceEnable) + public void deviceEnable(Boolean enable) throws HardwareException { + //进出料初始化 + canBus.stepMotorEnable(MId.FeedingModInfeedM, enable ? 1 : 0); + canBus.stepMotorEnable(MId.FeedingModXM, enable ? 1 : 0); + canBus.stepMotorEnable(MId.FeedingModOutfeedM, enable ? 1 : 0); + + //摇匀模组初始化 + canBus.stepMotorEnable(MId.ShakeModClampingM, enable ? 1 : 0); + canBus.stepMotorEnable(MId.ShakeModGripperZM, enable ? 1 : 0); + canBus.stepMotorEnable(MId.ShakeModShakeM, enable ? 1 : 0); + canBus.miniServoEnable(MId.ShakeModGripperYSV, enable ? 1 : 0); + canBus.miniServoEnable(MId.ShakeModGripperSV, enable ? 1 : 0); + canBus.miniServoEnable(MId.ShakeModTubeScanerClampingSV, enable ? 1 : 0); + canBus.miniServoEnable(MId.ShakeModTubeScanerRotateSV, enable ? 1 : 0); + + //板夹仓初始化 + canBus.stepMotorEnable(MId.PlatesBoxYM, enable ? 1 : 0); + canBus.stepMotorEnable(MId.PlatesBoxPusherM, enable ? 1 : 0); + + //光学模组初始化 + canBus.stepMotorEnable(MId.OptModPullM, enable ? 1 : 0); + canBus.stepMotorEnable(MId.OptModScannerM, enable ? 1 : 0); + + //HBot初始化 + canBus.hbotEnable(MId.HbotM, enable ? 1 : 0); + // TODO canBus.stepMotorEnable(MId.PipetteModZM, enable ? 1 : 0); + + //转盘归零 + canBus.stepMotorEnable(MId.IncubatorRotateCtrlM, enable ? 1 : 0); + } + + public void checkBeforeMove(MId mId) throws HardwareException { + //板夹仓盖子是否盖上 + if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { + throw new HardwareException(A8kEcode.PlateBoxNotCover.index); + } + } + + public void stop() { + workState = false; + } + +} diff --git a/src/main/java/a8k/service/bak_devicectrl/ctrl/HbotControlService.java b/src/main/java/a8k/service/bak_devicectrl/ctrl/HbotControlService.java new file mode 100644 index 0000000..2b9c64d --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/ctrl/HbotControlService.java @@ -0,0 +1,353 @@ +package a8k.service.bak_devicectrl.ctrl; + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.type.ConsumableGroup; +import a8k.type.HardwareException; +import a8k.type.appret.AppRet; +import a8k.type.cfg.*; +import a8k.controler.extapi.utils.*; +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.hardware.type.a8kcanprotocol.IOId; +import a8k.hardware.type.a8kcanprotocol.MId; +import a8k.hardware.type.regindex.RegIndex; +import a8k.service.bak_devicectrl.commonctrl.HardwareCommonCtrl; +import a8k.service.bak_devicectrl.param.DebugParam; +import a8k.service.bak_devicectrl.param.PosParam; +import a8k.service.bak_devicectrl.param.TimeParam; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * Hbot控制服务 + */ +@Component +@ExtApiTab(cfg = ExtApiTabConfig.HbotControlService) +public class HbotControlService { + static Logger logger = LoggerFactory.getLogger(HbotControlService.class); + + @Resource + A8kCanBusService canBus; + @Resource + HardwareCommonCtrl hcc; + @Resource + TimeParam timep; + @Resource + PosParam pp; + @Resource + DebugParam dp; + + // + public Integer getGripperZeroYPos() { + // 之所以这样写,是因为是为了放置两个类之间的循环依赖 + // assert appCxt != null; + // TODO + // return + // appCxt.getBean(SamplesPreProcessModuleCtrlService.class).getGripperZeroYPos(); + return 0; + } + + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // 基础控制 + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + private void checkPublicArea() throws HardwareException { + if (canBus.miniServoReadPos(MId.ShakeModGripperYSV) > getGripperZeroYPos() + 20) { + logger.error("ShakeModGripperYSV Pos:{} > {}", canBus.miniServoReadPos(MId.ShakeModGripperYSV), + getGripperZeroYPos() + 20); + throw new HardwareException(A8kEcode.ShakeModGripperYSVInXYPublicArea.index); + } + } + + /** + * Hboot 移动 + * + * @param targetPos 目标位置 + * @throws HardwareException e + * @throws InterruptedException e + */ + public void hbotCheckAndMoveTo(Pos3d targetPos) throws HardwareException, InterruptedException { + logger.info("hbotCheckAndMoveTo:{}", targetPos); + if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { + throw new HardwareException(A8kEcode.PlateBoxNotCover.index); + } + + + boolean zEnable = true; + boolean hbotEnable = canBus.moduleGetReg(MId.HbotM, RegIndex.kreg_xyrobot_is_enable) == 1; + + //TODO + // if (canBus.moduleGetReg(MId.PipetteModZM, RegIndex.kreg_step_motor_is_enable) == 0) { + // canBus.stepMotorEnable(MId.PipetteModZM, 1); + // canBus.stepMotorEasyMoveToZeroBlock(MId.PipetteModZM, timep.getActionOvertime()); + // zEnable = false; + // } + + // TODO Z轴归零 + // if (!getZPPS()) { + // canBus.stepMotorEnable(MId.PipetteModZM, 1); + // canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); + // } + +// if (!getZPPS()) { TODO +// throw new HardwareException(A8kEcode.ZMNotAtZPosWhenHbotTryMove.index); +// } + Pos2d nowHbotPos = canBus.hbotReadPos(MId.HbotM); + HbotLimitArea sampleArea = pp.getSampleCollectionArea(); + + // 检查采样区域是否有障碍 + if (sampleArea.checkIsInArea(nowHbotPos) || sampleArea.checkIsInArea(targetPos.getXYPos())) { + checkPublicArea(); + } + + // HBot移动 + canBus.hbotEnable(MId.HbotM, 1); + canBus.hbotMoveToBlock(MId.HbotM, targetPos.x - 20, targetPos.y - 20, timep.getActionOvertime()); + canBus.hbotMoveToBlock(MId.HbotM, targetPos.x, targetPos.y, timep.getActionOvertime()); + canBus.hbotMoveToBlock(MId.HbotM, targetPos.x, targetPos.y, timep.getActionOvertime()); + + // Z轴移动 + if (targetPos.z != 0) { + // TODO canBus.stepMotorEnable(MId.PipetteModZM, 1); + // TODO canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); + // TODO zMoveTo(targetPos.z); + } + // TODO canBus.stepMotorEnable(MId.PipetteModZM, zEnable ? 1 : 0); + canBus.hbotEnable(MId.HbotM, hbotEnable ? 1 : 0); + } + + public void zMoveTo(Integer z) throws HardwareException, InterruptedException { + if (z == 0) { + // TODO canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); + } else { + //TODO canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, z, timep.getActionOvertime()); + } + } + + private void hbotCheckAndMoveTo(Pos2d targetPos) throws HardwareException, InterruptedException { + hbotCheckAndMoveTo(new Pos3d(targetPos.x, targetPos.y, 0)); + } + + private void modGroupMoveToZero() throws HardwareException, InterruptedException { + if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { + throw new HardwareException(A8kEcode.PlateBoxNotCover.index); + } + + // 归零前检查 + checkPublicArea(); + // TODO canBus.stepMotorEnable(MId.PipetteModZM, 1); + canBus.hbotEnable(MId.HbotM, 1); + +// canBus.stepMotorEasyMoveToZeroBlock(MId.PipetteModZM, timep.getActionOvertime()); + canBus.hbotMoveToZeroBlock(MId.HbotM, timep.getHbotRuntoZeroActionOvertime()); + + // 丢弃tip + Pos3d dropPos = pp.getTipDropPos(); + hbotCheckAndMoveTo(dropPos); + // TODO: canBus.pipetteCtrlInitDeviceBlock(MId.PipetteMod, timep.getActionOvertime()); + + // 快速归零 + modGroupMoveToZeroQuick(); + } + + private void modGroupMoveToZeroQuick() throws HardwareException, InterruptedException { + hbotCheckAndMoveTo(new Pos2d(0, 0)); + } + + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // 单步测试 + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + @ExtApiFn(name = "丢Tip", group = "单步测试") + public void dropTip() throws HardwareException, InterruptedException { + Pos3d pos = pp.getTipDropPos(); + hbotMoveTo(pos.x, pos.y); + zMoveTo(pos.z); + //TODO: canBus.pipetteCtrlPutTip(MId.PipetteMod); + zMoveTo(0); + } + + @ExtApiFn(name = "取Tip", group = "单步测试") + public AppRet takeTip(Integer groupId, Integer index) throws HardwareException, InterruptedException { + logger.info("takeTip groupId:{} index:{}", groupId, index); + if (groupId > 2 || groupId < 0) { + throw new HardwareException(A8kEcode.ParamOutOfRange.index); + } + + if (index > TipPickUpPosInfo.cgetTipNum() || index < 0) { + throw new HardwareException(A8kEcode.ParamOutOfRange.index); + } + + TipPickUpPosInfo tipPos = pp.getTipPickUpPosInfo(); + Pos2d pos = tipPos.getTipPos(groupId, index); + hbotMoveTo(pos.x, pos.y); + + Integer zCompensate = 0; + if (groupId > 1) { + zCompensate = 2; + } + + // TODO + // canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, tipPos.getPickUpZPos(groupId) + zCompensate, + // timep.getActionOvertime()); + // canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); + + Boolean isGetTip = canBus.moduleGetReg(MId.PipetteMod, RegIndex.kreg_pipette_tip_state) == 1; + if (!isGetTip) { + logger.error("takeTip fail"); + } + return AppRet.success(isGetTip); + } + + @ExtApiFn(name = "HBot移动到", group = "单步测试") + public void hbotMoveTo(Integer x, Integer y) throws HardwareException, InterruptedException { + hbotCheckAndMoveTo(new Pos2d(x, y)); + } + + @ExtApiFn(name = "HBot移动到小瓶缓冲液X孔", group = "单步测试") + public void hbotMoveToSmallBottleGroup(ConsumableGroup group, Integer Xhole) + throws HardwareException, InterruptedException { + BottleGroupsPosInfo posInfo = pp.getBottleBufferPosInfo(); + if (Xhole < 0 || Xhole > BottlesPosInfo.cgetMAX()) { + throw new HardwareException(A8kEcode.ParamOutOfRange.index); + } + Pos2d pos = posInfo.cgetSmallBottleBufferPos(group.off, Xhole); + hbotCheckAndMoveTo(pos); + } + + @ExtApiFn(name = "HBot移动到探测物质X孔", group = "单步测试") + public void hbotMoveToDetectMaterialPos(ConsumableGroup group, Integer Xhole) + throws HardwareException, InterruptedException { + BottleGroupsPosInfo posInfo = pp.getBottleBufferPosInfo(); + if (Xhole < 0 || Xhole > BottlesPosInfo.cgetMAX()) { + throw new HardwareException(A8kEcode.ParamOutOfRange.index); + } + Pos2d pos = posInfo.cgetDetectMaterialPos(group.off, Xhole); + hbotCheckAndMoveTo(pos); + } + + @ExtApiFn(name = "HBot移动到大瓶缓冲液X孔", group = "单步测试") + public void hbotMoveToLargeBottleGroup(ConsumableGroup ch) throws HardwareException, InterruptedException { + LargeBottleBufferPos posInfo = pp.getLargeBottleBufferPosInfo(); + Pos2d pos = posInfo.cgetBottlePos(ch.off); + hbotCheckAndMoveTo(pos); + } + + @ExtApiFn(name = "HBot移动到急诊位", group = "单步测试") + public void hbotMoveToEmergencyPos() throws HardwareException, InterruptedException { + hbotCheckAndMoveTo(pp.getEmergencyPos()); + } + + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // 坐标获取工具 + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + @ExtApiFn(name = "Hbot使能", group = "坐标获取工具") + public void hBotEnable() throws HardwareException, InterruptedException { + canBus.hbotEnable(MId.HbotM, 1); + } + + @ExtApiFn(name = "Hbot失能", group = "坐标获取工具") + public void hBotDisable() throws HardwareException, InterruptedException { + canBus.hbotEnable(MId.HbotM, 0); + } + + @ExtApiFn(name = "Z轴使能", group = "坐标获取工具") + public void zAxisEnable() throws HardwareException, InterruptedException { + // TODO: canBus.stepMotorEnable(MId.PipetteModZM, 1); + } + + @ExtApiFn(name = "Z轴失能", group = "坐标获取工具") + public void zAxisDisable() throws HardwareException, InterruptedException { + // TODO canBus.stepMotorEnable(MId.PipetteModZM, 0); + } + + // TODO @EnginnerPageAction(name = "归零读取Z轴坐标", group = "坐标获取工具") + // public AppRet readZAxisPosByMoveToZero() throws HardwareException, InterruptedException { + // return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.PipetteModZM, timep.getActionOvertime())); + // } + + @ExtApiFn(name = "打开扫码器", group = "坐标获取工具") + public void openCodeScaner(Boolean power) throws HardwareException, InterruptedException { + if (power) { + canBus.codeScanerStartScan(MId.PipetteModCodeScanner); + } else { + canBus.codeScanerStopScan(MId.PipetteModCodeScanner); + } + } + + Pos2d hbotRefPos = new Pos2d(0, 0); + + @ExtApiFn(name = "设置HBOT参考坐标", group = "坐标获取工具") + public void setHbotRefPos(Integer x, Integer y) throws HardwareException, InterruptedException { + hbotRefPos.x = x; + hbotRefPos.y = y; + } + + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // hbot移动到并扫码 + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + private AppRet hBotMoveToAndScan(Pos2d pos) throws HardwareException, InterruptedException { + hbotCheckAndMoveTo(pos); + canBus.codeScanerStartScan(MId.PipetteModCodeScanner); + String result = canBus.codeScanerWaittingForResult(MId.PipetteModCodeScanner, timep.getScancodeOvertime()); + return AppRet.success(result); + } + + // 扫描板夹仓二维码 + @ExtApiFn(name = "扫描板夹仓二维码", group = "扫码") + public AppRet scanPlatesCode(ConsumableGroup ch) throws HardwareException, InterruptedException { + var posInfo = pp.getPlates2dCodeScanPosInfo(); + return hBotMoveToAndScan(posInfo.cgetScanPos(ch.off)); + } + + // 扫描缓冲液二维码 + @ExtApiFn(name = "扫描缓冲液区二维码", group = "扫码") + public AppRet scanBottleBuffersCode(ConsumableGroup group) throws HardwareException, InterruptedException { + BottleGroupsPosInfo posInfo = pp.getBottleBufferPosInfo(); + return hBotMoveToAndScan(posInfo.cgetScanPos(group.ordinal())); + } + + // 扫描大缓冲液二维码 + @ExtApiFn(name = "扫描大缓冲液二维码", group = "扫码") + public AppRet scanBigBottleBufferCode(ConsumableGroup group) + throws HardwareException, InterruptedException { + LargeBottleBufferPos posInfo = pp.getLargeBottleBufferPosInfo(); + return hBotMoveToAndScan(posInfo.cgetScanPos(group.off)); + } + + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // hbot取样品 + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +// public Boolean getZPPS() throws HardwareException { + // TODO return canBus.stepMotorReadIoState(MId.PipetteModZM, 0); +// } + + public Boolean getXPPS() throws HardwareException { + return canBus.hbotReadInio(MId.HbotM, 0); + } + + public Boolean getYPPS() throws HardwareException { + return canBus.hbotReadInio(MId.HbotM, 1); + } + + public Boolean getTipPPS() throws HardwareException { + return canBus.moduleGetReg(MId.PipetteMod, RegIndex.kreg_pipette_tip_state) == 1; + } + + public String getPos() throws HardwareException { + Pos2d pos = canBus.hbotReadPos(MId.HbotM); + return pos.toString(); + } + + public String getHbotRelaPos() throws HardwareException { + Pos2d pos = canBus.hbotReadPos(MId.HbotM); + pos.x -= hbotRefPos.x; + pos.y -= hbotRefPos.y; + + return pos.toString(); + } +} diff --git a/src/main/java/a8k/service/bak_devicectrl/ctrl/PipetteGunCtrlService.java b/src/main/java/a8k/service/bak_devicectrl/ctrl/PipetteGunCtrlService.java new file mode 100644 index 0000000..4a7ded9 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/ctrl/PipetteGunCtrlService.java @@ -0,0 +1,32 @@ +package a8k.service.bak_devicectrl.ctrl; + + +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.springframework.stereotype.Component; + +/** + * + * 移液枪功能 + * 1. + * + * + * + */ + +@Component +public class PipetteGunCtrlService { + static Logger logger = org.slf4j.LoggerFactory.getLogger(PipetteGunCtrlService.class); + + public Integer a; + + @PostConstruct + void init() throws NoSuchMethodException { + System.out.println("PipetteGunCtrlService init"); + } + + //取样 + + // + +} diff --git a/src/main/java/a8k/service/bak_devicectrl/ctrl/ReactionPlatesTransmitCtrl.java b/src/main/java/a8k/service/bak_devicectrl/ctrl/ReactionPlatesTransmitCtrl.java new file mode 100644 index 0000000..9b953c4 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/ctrl/ReactionPlatesTransmitCtrl.java @@ -0,0 +1,210 @@ +package a8k.service.bak_devicectrl.ctrl; + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.utils.opt_algo.A8kOptAlgo; +import a8k.type.*; +import a8k.type.appret.AppRet; +import a8k.controler.extapi.utils.*; +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.hardware.type.a8kcanprotocol.IOId; +import a8k.hardware.type.a8kcanprotocol.MId; +import a8k.hardware.type.regindex.RegIndex; +import a8k.service.bak_devicectrl.param.DebugParam; +import a8k.service.bak_devicectrl.param.PosParam; +import a8k.service.bak_devicectrl.param.TimeParam; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.ReactionPlatesTransmitCtrl) +public class ReactionPlatesTransmitCtrl { + static Logger logger = LoggerFactory.getLogger(ReactionPlatesTransmitCtrl.class); + EnginnerParamReader hpReader = new EnginnerParamReader(ReactionPlatesTransmitCtrl.class); + + + @Resource + A8kCanBusService canBus; + @Resource + TimeParam timep; + @Resource + PosParam pp; + @Resource + DebugParam dp; + + + public void checkBeforeMoveTrunable() throws HardwareException { + //板夹仓卡板检测 + if (canBus.getIOState(IOId.PlateBoxPlateStuckPPS)) { + logger.error("PlateBoxPlateStuckPPS is trigger"); + throw new HardwareException(A8kEcode.PlateStuckDetectorSensorTrigger.index); + } + + //检查钩板电机是否处于终点位置 + if (!canBus.getIOState(IOId.PullerMZeroPPS)) { + logger.error("PullerM is not in zero pos"); + throw new HardwareException(A8kEcode.PullerMInitPosError.index); + } + + //检查板夹仓光电是否处于起点位置 + if (!canBus.getIOState(IOId.PusherMZeroPPS)) { + logger.error("PusherM is not in zero pos"); + throw new HardwareException(A8kEcode.PusherMInitPosError.index); + } + } + + public void checkBeforeMovePlateBox() throws HardwareException { + if (!canBus.getIOState(IOId.PusherMZeroPPS)) { + logger.error("PusherM is not in zero pos "); + throw new HardwareException(A8kEcode.PusherMInitPosError.index); + } + } + + public void modGroupMoveToZeroQuick() throws HardwareException, InterruptedException { + //光学模组初始化 + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.OptModPullM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.OptModScannerM, timep.getActionOvertime()); + + //板夹仓初始化 + checkBeforeMovePlateBox(); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxPusherM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxYM, timep.getActionOvertime()); + + //转盘归零 + checkBeforeMoveTrunable(); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.IncubatorRotateCtrlM, timep.getActionOvertime()); + } + + private void trunableMoveTo(Integer pos) throws HardwareException, InterruptedException { + checkBeforeMoveTrunable(); + //限制pos在 0--> 36000之间 + pos = pos % 36000; + if (pos < 0) { + pos += 36000; + } + + //先移动半个间距,用来检测是否发生卡板 + Integer nowPos = canBus.stepMotorReadPos(MId.IncubatorRotateCtrlM); + if (nowPos < pos) { + canBus.stepMotorEasyMoveByBlock(MId.IncubatorRotateCtrlM, pp.getTurntablePosSpacing(), timep.getActionOvertime()); + } else if (nowPos > pos) { + canBus.stepMotorEasyMoveByBlock(MId.IncubatorRotateCtrlM, -pp.getTurntablePosSpacing(), timep.getActionOvertime()); + } + + //解决齿轮间隙的问题 + if (nowPos < pos) { + canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos, timep.getActionOvertime()); + } else { + canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos - 300/**/, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos, timep.getActionOvertime()); + } + } + + /* ======================================================================================= + 基础操作 + =======================================================================================*/ + + @ExtApiFn(name = "转盘移动到推板位", group = "单步") + public void trunableMoveToPushPos(IncubatorPos index) throws HardwareException, InterruptedException { + trunableMoveTo(pp.getTurntablePushPos0() + index.off * pp.getTurntablePosSpacing()); + } + + @ExtApiFn(name = "转盘移动到出板位", group = "单步") + public void trunableMoveToPullPos(IncubatorPos index) throws HardwareException, InterruptedException { + trunableMoveTo(pp.getTurntablePullPos0() + index.off * pp.getTurntablePosSpacing()); + + } + + @ExtApiFn(name = "转盘移动到滴定位", group = "单步") + public void trunableMoveToDropLiquidPos(IncubatorPos index) throws HardwareException, InterruptedException { + trunableMoveTo(pp.getTurntableDropLiquidPos0() + index.off * pp.getTurntablePosSpacing()); + } + + + @ExtApiFn(name = "推板", group = "单步") + public AppRet pushPlate(ConsumableGroup PBCh, IncubatorPos turntablePosIndex) throws HardwareException, InterruptedException { + trunableMoveToPushPos(turntablePosIndex); + canBus.stepMotorEasyMoveToBlock(MId.PlatesBoxYM, pp.getPBCh0Pos() + PBCh.off * pp.getPBChSpacing(), timep.getActionOvertime()); + canBus.plateCodeScanerPushCardAndScanBlock(MId.PlatesBoxScanner, pp.getPusherEndPos(), 10000); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxPusherM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxYM, timep.getActionOvertime()); + return AppRet.success(canBus.plateCodeScannerReadCode(MId.PlatesBoxScanner)); + } + + public void pushPlateQuick(ConsumableGroup PBCh, IncubatorPos turntablePosIndex) throws HardwareException, InterruptedException { + trunableMoveToPushPos(turntablePosIndex); + canBus.stepMotorEasyMoveToBlock(MId.PlatesBoxYM, pp.getPBCh0Pos() + PBCh.off * pp.getPBChSpacing(), timep.getActionOvertime()); + canBus.stepMotorEasyMoveToBlock(MId.PlatesBoxPusherM, pp.getPusherEndPos(), timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxPusherM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxYM, timep.getActionOvertime()); + } + + + @ExtApiFn(name = "拉板", group = "单步操作") + public void pullPlate(IncubatorPos turntablePosIndex) throws HardwareException, InterruptedException { + trunableMoveToPullPos(turntablePosIndex); + canBus.stepMotorEasyMoveToBlock(MId.OptModScannerM, pp.getOptScanScandbyPos(), timep.getActionOvertime()); + canBus.stepMotorEasyMoveToBlock(MId.OptModPullM, pp.getPullerTargetPos(), timep.getActionOvertime()); + if (!canBus.getIOState(IOId.PullerMEndPPS)) { + logger.error("pull plate fail"); + throw new HardwareException(A8kEcode.PullPlateFail.index); + } + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.OptModPullM, timep.getActionOvertime()); + } + + @ExtApiFn(name = "丢板", group = "单步操作") + public void dropPlate() throws HardwareException, InterruptedException { + canBus.stepMotorEasyMoveToBlock(MId.OptModScannerM, pp.getPlateDropPos(), timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.OptModScannerM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToBlock(MId.OptModScannerM, pp.getOptScanScandbyPos(), timep.getActionOvertime()); + } + + // @EnginnerPageAction(name = "显示板夹扫码原始曲线", group = "辅助调试") + // public AppRet readPlateScanCurve() throws HardwareException, InterruptedException { + // List scanDataCurve = canBus.plateCodeScanerReadRawResult(MId.PlatesBoxScanner); + // List refLine = new ArrayList<>(); + // for (int i = 0; i < 15; i++) { + // refLine.add(i * 12 + 6); + // } + // return AppRet.success(new A8kScanCurve(scanDataCurve, refLine)); + // } + + private AppRet packetOptDisplayScanCurve(List scanDataCurve) { + A8kScanCurve scanCurve = new A8kScanCurve(); + logger.info("pointNum: " + scanDataCurve.size()); + scanCurve.scanDataCurve = A8kOptAlgo.preProcessOptData(scanDataCurve); + logger.info("pointNum: " + scanCurve.scanDataCurve.size()); + scanCurve.refCurve = A8kOptAlgo.preProcessOptData(scanDataCurve); + scanCurve.refLine = new ArrayList<>(); + for (int i = 1; i < 6; i++) { + scanCurve.refLine.add(40 * i); + } + return AppRet.success(scanCurve); + } + + @ExtApiFn(name = "T光学扫码", group = "光学调试") + public AppRet optTScan(OptScanDirection direction, Integer scanerGain) throws HardwareException, InterruptedException { + // canBus.moduleSetReg(MId.OptMod, RegIndex.kreg_a8k_opt_t_pos_offset, getTOptPosOffset()); + // canBus.moduleSetReg(MId.OptMod, RegIndex.kreg_a8k_opt_t_reverse_scan_pos_offset,getTOptPosOffset()-1200); + // canBus.optTStartScanBlock(MId.OptMod, direction, getOptTLasterGain(), scanerGain, getOptScanOvertime()); + // return packetOptDisplayScanCurve(canBus.optReadRaw(MId.OptMod)); + return AppRet.fail(A8kEcode.CmdNotSupport.index); + } + + @ExtApiFn(name = "F光学扫码", group = "光学调试") + public AppRet optFScan(OptScanDirection direction, Integer scanerGain) throws HardwareException, InterruptedException { + //getFOptPosOffset + canBus.moduleSetReg(MId.OptMod, RegIndex.kreg_a8k_opt_f_pos_offset, pp.getFOptPosOffset()); + canBus.moduleSetReg(MId.OptMod, RegIndex.kreg_a8k_opt_f_reverse_scan_pos_offset, pp.getFOptPosOffset() - 1200); + + canBus.optFStartScanBlock(MId.OptMod, direction, pp.getOptFLasterGain(), scanerGain, timep.getOptScanOvertime()); + return packetOptDisplayScanCurve(canBus.optReadRaw(MId.OptMod)); + } + + +} diff --git a/src/main/java/a8k/service/bak_devicectrl/ctrl/SamplesPreProcesCtrl.java b/src/main/java/a8k/service/bak_devicectrl/ctrl/SamplesPreProcesCtrl.java new file mode 100644 index 0000000..67dab49 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/ctrl/SamplesPreProcesCtrl.java @@ -0,0 +1,268 @@ +package a8k.service.bak_devicectrl.ctrl; + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.type.HardwareException; +import a8k.type.appret.AppRet; +import a8k.controler.extapi.utils.*; +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.hardware.type.a8kcanprotocol.MId; +import a8k.service.bak_devicectrl.param.DebugParam; +import a8k.service.bak_devicectrl.param.TimeParam; +import a8k.service.bak_devicectrl.param.PosParam; +import a8k.utils.ZEQ; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.SamplesPreProcesCtrl) +public class SamplesPreProcesCtrl { + static Logger logger = LoggerFactory.getLogger(SamplesPreProcesCtrl.class); + + static class ORDER { + + static final int moduleReset = 1; + static final int moduleEnable = 2; + static final int moduleDisable = 3; + static final int takeTubeAndJudgeTubeExist = 4; + static final int shakeTube = 5; + static final int takeTubeCap = 6; + static final int pushBackTubeCapAndTakeBakTube = 7; + static final int setAeroslFanPower = 8; + } + + @Resource + A8kCanBusService canBus; + @Resource + TimeParam timep; + @Resource + PosParam pp; + @Resource + DebugParam dp; + + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // PRIVATE + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + private void modGroupMoveToZero() throws HardwareException, InterruptedException { + + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperClosePos(), timep.getActionOvertime()); + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperZeroYPos(), timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModClampingM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModShakeM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToBlock(MId.ShakeModShakeM, 90, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, -2, timep.getActionOvertime()); + } + + + private void modGroupMoveToZeroQuick() throws HardwareException, InterruptedException { + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModClampingM, timep.getActionOvertime()); + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModShakeM, timep.getActionOvertime()); + modGroupMoveToZero(); + } + + @ExtApiFn(name = "模块复位", group = "辅助调试", order = ORDER.moduleReset) + public void moduleReset() throws HardwareException, InterruptedException { + modGroupMoveToZero(); + } + + @ExtApiFn(name = "模块使能", group = "辅助调试", order = ORDER.moduleEnable) + public void moduleEnable() throws HardwareException, InterruptedException { + canBus.miniServoEnable(MId.ShakeModGripperSV, 1); + canBus.miniServoEnable(MId.ShakeModGripperYSV, 1); + canBus.stepMotorEnable(MId.ShakeModClampingM, 1); + canBus.stepMotorEnable(MId.ShakeModGripperZM, 1); + canBus.stepMotorEnable(MId.ShakeModShakeM, 1); + canBus.stepMotorEnable(MId.ShakeModShakeM, 1); + } + + @ExtApiFn(name = "模块失能", group = "辅助调试", order = ORDER.moduleDisable) + public void moduleDisable() throws HardwareException, InterruptedException { + canBus.stepMotorEnable(MId.ShakeModClampingM, 1); + canBus.stepMotorEasyMoveByBlock(MId.ShakeModClampingM, 10, timep.getActionOvertime()); + + + canBus.miniServoEnable(MId.ShakeModGripperSV, 0); + canBus.miniServoEnable(MId.ShakeModGripperYSV, 0); + canBus.stepMotorEnable(MId.ShakeModClampingM, 0); + canBus.stepMotorEnable(MId.ShakeModGripperZM, 0); + canBus.stepMotorEnable(MId.ShakeModShakeM, 0); + canBus.stepMotorEnable(MId.ShakeModShakeM, 0); + } + + @ExtApiFn(name = "夹紧试管", group = "辅助调试", order = ORDER.moduleDisable) + public void clampTube() throws HardwareException, InterruptedException { + canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, pp.getShakeClampingPos(), timep.getActionOvertime()); + } + + + void tryClampTube() throws HardwareException, InterruptedException { + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos() - 20, timep.getActionOvertime()); + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos(), timep.getActionOvertime()); + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos() - 20, timep.getActionOvertime()); + } + + /** + * 取试管帽,如果试管帽存在, + * @param highTube true/false + */ + @ExtApiFn(name = "取试管", group = "单步", order = ORDER.takeTubeAndJudgeTubeExist) + public AppRet takeTubeAndJudgeTubeExist(Boolean highTube) throws HardwareException, InterruptedException { + /* + * 校验: + * 1.当前摇匀模组设计到的电机是否都处于待机位 + */ + + //Z轴在原点 + if (!canBus.stepMotorReadIoState(MId.ShakeModGripperZM, 0)) { + throw new HardwareException(MId.ShakeModGripperZM, A8kEcode.MNotInZeroPos.index); + } + + //Y轴在零点附近 + if (!ZEQ.IntEq(canBus.miniServoReadPos(MId.ShakeModGripperYSV), pp.getGripperZeroYPos(), 30)) { + throw new HardwareException(MId.ShakeModGripperYSV, A8kEcode.MNotInZeroPos.index); + } + + //夹爪没有零位置 + if (!ZEQ.IntEq(canBus.miniServoReadPos(MId.ShakeModGripperSV), pp.getGripperClosePos(), 30)) { + throw new HardwareException(MId.ShakeModGripperSV, A8kEcode.MNotInZeroPos.index); + } + + //检查摇匀夹紧是否在零位 + if (!canBus.stepMotorReadIoState(MId.ShakeModClampingM, 0)) { + throw new HardwareException(MId.ShakeModClampingM, A8kEcode.MNotInZeroPos.index); + } + + boolean isHighBlood = highTube; + boolean tubeCapExist = true; + Integer gripperJudgeCapZPos = isHighBlood ? pp.getGripperJudgeHTubeCapZPos() : pp.getGripperJudgeSTubeCapZPos(); + Integer gripperTakeTubeZPos = isHighBlood ? pp.getGripperTakeHTubeZPos() : pp.getGripperTakeSTubeZPos(); + Integer gripperShakeZPos = pp.getGripperShakeTubeZPos(); + + //固定试管架 + canBus.miniServoMoveToBlock(MId.ShakeModTubeScanerClampingSV, 900, timep.getActionOvertime()); + //试管夹紧移动到终点位置 + canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, 70, timep.getActionOvertime()); + //试管摇匀移动到90度 + canBus.stepMotorEasyMoveToBlock(MId.ShakeModShakeM, pp.getShakeModShakeMStandbyPos(), timep.getActionOvertime()); + //Y轴向前移动 + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperTakeTubeYPos(), timep.getActionOvertime()); + //打开夹爪 + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); + // //Z轴下移动到试管帽有无检测位 + // canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, gripperJudgeCapZPos, timep.getActionOvertime()); + //闭合夹爪检测试管帽是否存在 + // canBus.miniServoRotateWithTorque(MId.ShakeModGripperSV, -400); + // Thread.sleep(timep.getTubeCapJudgeDelayTime()); + // if (ZEQ.IntEq(canBus.miniServoReadPos(MId.ShakeModGripperSV), pp.getGripperClosePos(), 30)) { + // logger.info("试管帽不存在"); + // tubeCapExist = false; + // } + if (dp.getDebugMode() || tubeCapExist) { + //打开夹爪 + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); + //Z轴下移动到取试管位置 + canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, gripperTakeTubeZPos, timep.getActionOvertime()); + //夹爪夹紧 + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos(), timep.getActionOvertime()); + canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, gripperTakeTubeZPos - 100, timep.getActionOvertime()); + tryClampTube(); + + //Z轴上移动到零位 + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); + //夹爪夹紧 + //Y轴移动到摇匀位 + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperShakeYPos() - 50, timep.getActionOvertime()); //该动作是为了消除齿轮间隙 + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperShakeYPos(), timep.getActionOvertime()); + //Z轴下移动到摇匀位放试管的位置 + canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, gripperShakeZPos, timep.getActionOvertime()); + //夹紧试管 + canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, pp.getShakeClampingPos(), timep.getActionOvertime()); + //松开夹爪,放置试管 + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); + //Z轴上移动到零位 + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); + //Z轴归零,校准一次位置 + canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); + //Y轴移动到零位 + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperZeroYPos(), timep.getActionOvertime()); + } else { + modGroupMoveToZeroQuick(); + } + return AppRet.success(tubeCapExist); + } + + @ExtApiFn(name = "摇匀", group = "单步", order = ORDER.shakeTube) + public void shakeTube(Integer shakeDegree, Integer times) throws HardwareException, InterruptedException { + var standByPos = pp.getShakeModShakeMStandbyPos(); + var startPos = standByPos - shakeDegree; + var endPos = standByPos + shakeDegree; + canBus.stepMotorEasyReciprocatingMotion(MId.ShakeModShakeM, startPos, endPos, times); + canBus.waitForMod(MId.ShakeModShakeM, timep.getActionOvertime()); + } + + @ExtApiFn(name = "取试管帽", group = "单步", order = ORDER.takeTubeCap) + public void takeTubeCap() throws HardwareException, InterruptedException { + //Y移动到取试管帽位置 + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperShakeYPos(), timep.getActionOvertime()); + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); + //Z下移动到取试管帽位置 + canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, pp.getGripperTakeCapZPos() + 3, timep.getActionOvertime()); + //闭合夹爪 + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos(), timep.getActionOvertime()); + //Z上移动到零位 + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); + // tryClampTube(); + // canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos()-30, timep.getActionOvertime()); + + + //Y移动到待机位 + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperZeroYPos(), timep.getActionOvertime()); + } + + /** + * 盖试管帽,并将试管移动回试管架中 + */ + @ExtApiFn(name = "盖试管帽并放回试管架", group = "单步", order = ORDER.pushBackTubeCapAndTakeBakTube) + public void pushBackTubeCapAndTakeBakTube() throws HardwareException, InterruptedException { + //移动Y轴到取试管帽位置 + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperShakeYPos(), timep.getActionOvertime()); + //移动Z轴盖帽 + canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, pp.getGripperTakeCapZPos() + 20, timep.getActionOvertime()); + //打开试管夹 + canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, 70, timep.getActionOvertime()); + //移动Z轴到零位 + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); + + tryClampTube(); + + + //移动Y轴到方式管的位置 + canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperTakeTubeYPos(), timep.getActionOvertime()); + //移动Z轴到取试管位置 + canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, pp.getGripperTakeHTubeZPos() - 20, timep.getActionOvertime()); + //打开夹爪 + canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); + //Z轴上移动到零位 + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); + //设备快速归零 + modGroupMoveToZeroQuick(); + } + + /** + * 气溶胶风扇控制 + */ + @ExtApiFn(name = "气溶胶风扇控制", group = "其他", order = ORDER.setAeroslFanPower) + public void setAeroslFanPower(Boolean enable) throws Exception { + if (enable) { + canBus.fanControlerSetSpeed(MId.WbTubeFanMod, 99); + } else { + canBus.fanControlerSetSpeed(MId.WbTubeFanMod, 0); + } + } +} diff --git a/src/main/java/a8k/service/bak_devicectrl/ctrl/TubeRackMoveCtrl.java b/src/main/java/a8k/service/bak_devicectrl/ctrl/TubeRackMoveCtrl.java new file mode 100644 index 0000000..6a86263 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/ctrl/TubeRackMoveCtrl.java @@ -0,0 +1,298 @@ +package a8k.service.bak_devicectrl.ctrl; + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.type.HardwareException; +import a8k.type.TargetPosMeasureDirection; +import a8k.type.appret.AppRet; +import a8k.controler.extapi.utils.*; +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.hardware.type.a8kcanprotocol.IOId; +import a8k.hardware.type.a8kcanprotocol.MId; +import a8k.service.bak_devicectrl.param.DebugParam; +import a8k.service.bak_devicectrl.param.PosParam; +import a8k.service.bak_devicectrl.param.TimeParam; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.TubeRackMoveCtrl) +public class TubeRackMoveCtrl { + static Logger logger = LoggerFactory.getLogger(TubeRackMoveCtrl.class); + + static class ORDER { + static final int moveTubeRackTo = 1; + static final int scanClampModClamp = 2; + static final int scanClampModRelease = 3; + static final int tryEnterTubeRack = 4; + static final int tryEjectTubeRack = 5; + static final int tubeRackMoveToEnterPos = 6; + static final int moveTubeRackToExitPos = 7; + static final int moveTubeRackToScanPos = 8; + static final int moveTubeToScanPosAndScan = 9; + static final int moveTubeToPreProcessPos = 10; + static final int moveTubeToAltitJudgXPos = 11; + static final int judgeTubeExist = 12; + + } + + @Resource + private A8kCanBusService canBus; + @Resource + TimeParam timep; + @Resource + PosParam pp; + @Resource + DebugParam dp; + + + private Boolean isTubeExist() throws HardwareException { + return canBus.getIOState(IOId.TubeExistPPS); + } + + private Boolean isTubeRackInEnterPos() throws HardwareException { + return canBus.getIOState(IOId.InfeedPPS); + } + + private Boolean isTubeRackInExitPos() throws HardwareException { + return canBus.getIOState(IOId.OutfeedPPS); + } + + private Boolean isHighTube() throws HardwareException { + return canBus.getIOState(IOId.TubeHeightPPS); + } + + + /** + * 移动试管到扫码位置 + * @param tubeIndex 试管索引 + */ + private void moveTubeToScanPos(Integer tubeIndex) throws HardwareException, InterruptedException { + var scanPos = pp.getTScanXPos() + tubeIndex * pp.getTubeSpacing(); + scanClampModClamp(); + moveTubeRackTo(scanPos, TargetPosMeasureDirection.NEGATIVE, false); + } + + /** + * 移动<试管架>到试管架扫码位置 + */ + private void moveTubeRackToScanPos() throws HardwareException, InterruptedException { + moveTubeRackTo(pp.getTRScanXPos(), TargetPosMeasureDirection.POSITIVE, false); + } + + /*========================================================================================= + * 基础方法 + *========================================================================================*/ + + /** + * 移动试管架到指定位置 + * @param pos 指定位置 + * @throws HardwareException 硬件异常 + * @throws InterruptedException 打断异常 + */ + @ExtApiFn(name = "移动到坐标", group = "基础方法", order = ORDER.moveTubeRackTo) + public void moveTubeRackTo(Integer pos, TargetPosMeasureDirection moveDiretion, Boolean moveToZero) throws HardwareException, InterruptedException { + if (!canBus.stepMotorReadIoState(MId.ShakeModGripperZM, 0)) { + throw new HardwareException(A8kEcode.ShakeModGripperZMNotInZeroPos.index); + } + //打开扫码夹具 + scanClampModRelease(); + + //使能电机 + canBus.stepMotorEnable(MId.FeedingModXM, 1); + if (moveToZero) { + canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.FeedingModXM, timep.getActionOvertime()); + } + + // 处理试管架和试管架之间的间隙导致的运行位置误差 + Integer nowPos = canBus.stepMotorReadPos(MId.FeedingModXM); + if (TargetPosMeasureDirection.POSITIVE.equals(moveDiretion)) { + if (nowPos > (pos + 1)) { + canBus.stepMotorEasyMoveToBlock(MId.FeedingModXM, pos + 30, timep.getActionOvertime()); + } + } else if (TargetPosMeasureDirection.NEGATIVE.equals(moveDiretion)) { + if (nowPos < (pos - 1)) { + canBus.stepMotorEasyMoveToBlock(MId.FeedingModXM, pos - 30, timep.getActionOvertime()); + } + } + canBus.stepMotorEasyMoveToBlock(MId.FeedingModXM, pos, timep.getActionOvertime()); + + } + + /** + * 扫描夹紧机构夹紧 + */ + @ExtApiFn(name = "扫描夹紧机构夹紧", group = "基础方法", order = ORDER.scanClampModClamp) + public void scanClampModClamp() throws HardwareException, InterruptedException { + canBus.miniServoEnable(MId.ShakeModTubeScanerClampingSV, 1); + canBus.miniServoMoveTo(MId.ShakeModTubeScanerClampingSV, 900); + canBus.waitForMod(MId.ShakeModTubeScanerClampingSV, timep.getActionOvertime()); + } + + /** + * 扫描夹紧机构复位 + */ + @ExtApiFn(name = "扫描夹紧机构复位", group = "基础方法", order = ORDER.scanClampModRelease) + public void scanClampModRelease() throws HardwareException, InterruptedException { + canBus.miniServoEnable(MId.ShakeModTubeScanerClampingSV, 1); + canBus.miniServoMoveTo(MId.ShakeModTubeScanerClampingSV, 0); + canBus.waitForMod(MId.ShakeModTubeScanerClampingSV, timep.getActionOvertime()); + } + + + public Boolean getTHchOuterPPS() throws HardwareException { + return canBus.getIOState(IOId.THChOuterPPS); + } + + public Boolean getTHchInterPPS() throws HardwareException { + return canBus.getIOState(IOId.THChInterPPS); + } + + + /*========================================================================================= + * 片段 + *========================================================================================*/ + + /** + * 移动试管架到入口位置 + */ + private void tubeRackMoveToEnterPos() throws HardwareException, InterruptedException { + moveTubeRackTo(pp.getTREnterXPos(), TargetPosMeasureDirection.NOTCARE, true); + } + + /** + * 移动<试管架>到出口位置 + */ + private void moveTubeRackToExitPos() throws HardwareException, InterruptedException { + moveTubeRackTo(pp.getTRExitXPos(), TargetPosMeasureDirection.NOTCARE, false); + moveTubeRackTo(pp.getTRExitXPos() - 10, TargetPosMeasureDirection.NOTCARE, false); + } + + /** + * 移动<试管架>到出口位置 + */ + @ExtApiFn(name = "入料", group = "单步", order = ORDER.moveTubeRackToExitPos) + public void enterTubeHolder() throws HardwareException, InterruptedException { + if (getTHchInterPPS() || getTHchOuterPPS()) { + throw new HardwareException(A8kEcode.TubeXChannelIsNotEmpty.index); + } + tubeRackMoveToEnterPos(); + try { + canBus.stepMotorEasyRotate(MId.FeedingModInfeedM, -1); + for (int i = 0; i < timep.getInfeedOvertime() / 100; i++) { + Thread.sleep(100); + if (getTHchInterPPS()) { + break; + } + } + Thread.sleep(1000); + canBus.stepMotorStop(MId.FeedingModInfeedM); + if (!getTHchInterPPS()) { + throw new HardwareException(A8kEcode.InfeedOvertimeFail.index); + } + } finally { + canBus.moduleStop(MId.FeedingModInfeedM); + } + } + + @ExtApiFn(name = "出料", group = "单步", order = ORDER.moveTubeRackToExitPos) + public void ejectTubeHolder() throws HardwareException, InterruptedException { + moveTubeRackToExitPos(); + try { + canBus.stepMotorEasyRotate(MId.FeedingModOutfeedM, 1); + for (int i = 0; i < timep.getOutfeedOvertime() / 100; i++) { + Thread.sleep(100); + logger.info("getTHchInterPPS:{} getTHchOuterPPS:{}", getTHchInterPPS(), getTHchOuterPPS()); + if (!getTHchInterPPS() && !getTHchOuterPPS()) { + break; + } + } + Thread.sleep(1000); + canBus.stepMotorStop(MId.FeedingModOutfeedM); + if (getTHchInterPPS() || getTHchOuterPPS()) { + throw new HardwareException(A8kEcode.OutfeedOvertimeFail.index); + } + } finally { + canBus.moduleStop(MId.FeedingModOutfeedM); + } + } + + /** + * 移动试管架到扫码并扫码 + */ + @ExtApiFn(name = "扫描<试管架>编码", group = "单步扫码", order = ORDER.moveTubeRackToScanPos) + public AppRet moveTubeRackToScanPosAndScan() throws HardwareException, InterruptedException { + String result; + moveTubeRackToScanPos(); + + scanClampModClamp(); + canBus.codeScanerStartScan(MId.FeedingModScannerMod); + result = canBus.codeScanerWaittingForResult(MId.FeedingModScannerMod, 1000); + scanClampModRelease(); + if (result == null || result.isEmpty()) { + return AppRet.fail(A8kEcode.ScanTimeout.index); + } + return AppRet.success(result); + } + // + // 试管移动 + // + + /** + * 移动试管到扫码位置,并扫码 + * @param tubeIndex 试管索引 + */ + @ExtApiFn(name = "扫描<试管X>编码", group = "单步扫码", order = ORDER.moveTubeToScanPosAndScan) + public AppRet moveTubeToScanPosAndScan(Integer tubeIndex) throws HardwareException, InterruptedException { + moveTubeToScanPos(tubeIndex); + try { + scanClampModClamp(); + + canBus.codeScanerStartScan(MId.FeedingModScannerMod); + canBus.miniServoRotateWithTorque(MId.ShakeModTubeScanerClampingSV, pp.getTubeScanServoTorque()); + String result = canBus.codeScanerWaittingForResult(MId.FeedingModScannerMod, pp.getTubeScanOvertime()); + if (result == null || result.isEmpty()) { + return AppRet.fail(A8kEcode.ScanTimeout.index); + } + return AppRet.success(result); + } finally { + canBus.moduleStop(MId.ShakeModTubeScanerClampingSV); + canBus.moduleStop(MId.FeedingModScannerMod); + scanClampModRelease(); + } + } + + /** + * 移动试管到试管预处理的位置 + * @param tubeIndex 试管索引 + */ + @ExtApiFn(name = "移动<试管N>摇匀位", group = "单步-处理", order = ORDER.moveTubeToPreProcessPos) + public void moveTubeToPreProcessPos(Integer tubeIndex) throws HardwareException, InterruptedException { + moveTubeRackTo(pp.getTPreProcessXPos() + tubeIndex * pp.getTubeSpacing(), TargetPosMeasureDirection.POSITIVE, false); + } + + /** + * 移动试管到试管高低判断位置 + * @param tubeIndex 试管索引 + */ + @ExtApiFn(name = "判断<试管N>高低", group = "单步-其他", order = ORDER.moveTubeToAltitJudgXPos) + public AppRet moveTubeToAltitJudgXPos(Integer tubeIndex) throws HardwareException, InterruptedException { + moveTubeRackTo(pp.getTAltitJudgXPos() + tubeIndex * pp.getTubeSpacing(), TargetPosMeasureDirection.NEGATIVE, false); + return AppRet.success(isHighTube()); + } + + + /** + * 移动试管到试管有无判断位置 + * @param tubeIndex 试管索引 + */ + @ExtApiFn(name = "判断<试管N>是否存在", group = "单步-其他", order = ORDER.judgeTubeExist) + public AppRet judgeTubeExist(Integer tubeIndex) throws HardwareException, InterruptedException { + moveTubeRackTo(pp.getTExistJudgXPos() + tubeIndex * pp.getTubeSpacing(), TargetPosMeasureDirection.NEGATIVE, false); + return AppRet.success(isTubeExist()); + } + + +} diff --git a/src/main/java/a8k/service/bak_devicectrl/param/DebugParam.java b/src/main/java/a8k/service/bak_devicectrl/param/DebugParam.java new file mode 100644 index 0000000..b89a946 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/param/DebugParam.java @@ -0,0 +1,29 @@ +package a8k.service.bak_devicectrl.param; + +import a8k.controler.extapi.utils.ExtApiTab; +import a8k.controler.extapi.utils.ExtApiFn; +import a8k.controler.extapi.utils.EnginnerPageStatu; +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.DebugParam) +public class DebugParam { + + Boolean debugMode = false; + + @ExtApiFn(name = "使能调试模式", order = 1) + public void enableDebugMode() { + debugMode = true; + } + + @ExtApiFn(name = "禁用调试模式", order = 2) + public void disableDebugMode() { + debugMode = false; + } + + @EnginnerPageStatu(name = "调试模式") + public Boolean getDebugMode() { + return debugMode; + } +} diff --git a/src/main/java/a8k/service/bak_devicectrl/param/PosParam.java b/src/main/java/a8k/service/bak_devicectrl/param/PosParam.java new file mode 100644 index 0000000..b0af1a2 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/param/PosParam.java @@ -0,0 +1,392 @@ +package a8k.service.bak_devicectrl.param; + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.type.cfg.*; +import a8k.controler.extapi.utils.*; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.PosParam) +public class PosParam { + EnginnerParamReader hpReader = new EnginnerParamReader(PosParam.class); + + class ORDER { + static final int getGripperOpenPos = 1; + static final int getGripperClosePos = 2; + static final int getGripperTakeCapPos = 3; + static final int getGripperTakeTubeYPos = 4; + static final int getGripperShakeYPos = 5; + static final int getGripperZeroYPos = 6; + static final int getGripperTakeHTubeZPos = 7; + static final int getGripperTakeSTubeZPos = 8; + static final int getGripperJudgeHTubeCapZPos = 9; + static final int getGripperJudgeSTubeCapZPos = 10; + static final int getGripperShakeTubeZPos = 11; + static final int getGripperTakeCapZPos = 12; + static final int getShakeClampingPos = 13; + static final int getShakeModShakeMStandbyPos = 14; + static final int getTREnterXPos = 15; + static final int getTRExitXPos = 16; + static final int getTRScanXPos = 17; + static final int getTScanXPos = 18; + static final int getTAltitJudgXPos = 19; + static final int getTExistJudgXPos = 20; + static final int getTPreProcessXPos = 21; + static final int getTubeSpacing = 22; + static final int getTubeScanServoTorque = 23; + static final int getTubeScanOvertime = 24; + static final int getPBCh0Pos = 25; + static final int getPBChSpacing = 26; + static final int getPusherEndPos = 27; + static final int getPusherScanStartPos = 28; + static final int getTurntablePushPos0 = 29; + static final int getTurntablePullPos0 = 30; + static final int getTurntableDropLiquidPos0 = 31; + static final int getTurntablePosSpacing = 32; + static final int getPullerTargetPos = 33; + static final int getPlateDropPos = 34; + static final int getOptScanScandbyPos = 35; + static final int getTOptPosOffset = 36; + static final int getFOptPosOffset = 37; + static final int getOptTLasterGain = 38; + static final int getOptFLasterGain = 39; + static final int getEmergencyPos = 40; + static final int getTipPickUpPosInfo = 41; + static final int getTipDropPos = 42; + static final int getReactionPos = 43; + static final int getBottleBufferPosInfo = 44; + static final int getPlates2dCodeScanPosInfo = 45; + static final int getLargeBottleBufferPosInfo = 46; + static final int getSampleCollectionArea = 47; + } + + + // + // SamplesPreProcessModuleCtrlService + // + + @EnginnerPageParam(name = "抓手张开位置", group = "抓手", order = ORDER.getGripperOpenPos) + public Integer getGripperOpenPos() { + return hpReader.getInteger("GripperOpenPos", 450); + } + + @EnginnerPageParam(name = "抓手闭合位置", group = "抓手", order = ORDER.getGripperClosePos) + public Integer getGripperClosePos() { + return hpReader.getInteger("GripperClosePos", 310); + } + + @EnginnerPageParam(name = "抓手取试管位置", group = "抓手", order = ORDER.getGripperTakeCapPos) + public Integer getGripperTakeCapPos() { + return hpReader.getInteger("GripperTakeCapPos", 355); + } + + @EnginnerPageParam(name = "取试管位置", group = "抓手Y轴位置", order = ORDER.getGripperTakeTubeYPos) + public Integer getGripperTakeTubeYPos() { + return hpReader.getInteger("GripperTakeTubeYPos", 3080); + } + + @EnginnerPageParam(name = "摇匀位置", group = "抓手Y轴位置", order = ORDER.getGripperShakeYPos) + public Integer getGripperShakeYPos() { + return hpReader.getInteger("GripperShakeYPos", 2130); + } + + @EnginnerPageParam(name = "待机位", group = "抓手Y轴位置", order = ORDER.getGripperZeroYPos) + public Integer getGripperZeroYPos() { + return hpReader.getInteger("GripperZeroYPos", 300); + } + + + @EnginnerPageParam(name = "取高试管位置", group = "抓手Z轴位置", order = ORDER.getGripperTakeHTubeZPos) + public Integer getGripperTakeHTubeZPos() { + return hpReader.getInteger("GripperTakeHTubeZPos", 739); + } + + @EnginnerPageParam(name = "取低试管位置", group = "抓手Z轴位置", order = ORDER.getGripperTakeSTubeZPos) + public Integer getGripperTakeSTubeZPos() { + return hpReader.getInteger("GripperTakeSTubeZPos", 983); + } + + //JudgeTubeCapZ + @EnginnerPageParam(name = "高试管帽有无判断位", group = "抓手Z轴位置", order = ORDER.getGripperJudgeHTubeCapZPos) + public Integer getGripperJudgeHTubeCapZPos() { + return hpReader.getInteger("GripperJudgeHTubeCapZPos", 591); + } + + @EnginnerPageParam(name = "低试管帽有无判断位", group = "抓手Z轴位置", order = ORDER.getGripperJudgeSTubeCapZPos) + public Integer getGripperJudgeSTubeCapZPos() { + return hpReader.getInteger("GripperJudgeSTubeCapZPos", 867); + } + + //ShakeTubeZ + @EnginnerPageParam(name = "摇匀放置位置", group = "抓手Z轴位置", order = ORDER.getGripperShakeTubeZPos) + public Integer getGripperShakeTubeZPos() { + return hpReader.getInteger("GripperShakeTubeZPos", 835); + } + + //TakeCapZ + @EnginnerPageParam(name = "取试管帽位", group = "抓手Z轴位置", order = ORDER.getGripperTakeCapZPos) + public Integer getGripperTakeCapZPos() { + return hpReader.getInteger("GripperTakeCapZPos", 835); + } + + + @EnginnerPageParam(name = "试管夹紧位", group = "试管夹紧模块", order = ORDER.getShakeClampingPos) + public Integer getShakeClampingPos() { + return hpReader.getInteger("ShakeClampingPos", 10); + } + + @EnginnerPageParam(name = "摇匀臂", group = "试管摇匀待机位", order = ORDER.getShakeModShakeMStandbyPos) + public Integer getShakeModShakeMStandbyPos() { + return hpReader.getInteger("ShakeModShakeMStandbyPos", 90); + } + + + // + // MotorTubeRackMoveCtrlService + // + + @EnginnerPageParam(name = "入料X位置", group = "进出料<试管架>坐标", order = ORDER.getTREnterXPos) + public Integer getTREnterXPos() { + return hpReader.getInteger("TREnterXPos", -46); + } + + @EnginnerPageParam(name = "出料X位置", group = "进出料<试管架>坐标", order = ORDER.getTRExitXPos) + public Integer getTRExitXPos() { + return hpReader.getInteger("TRExitXPos", 3975); + } + + @EnginnerPageParam(name = "试管架扫码X位置", group = "进出料<试管架>坐标", order = ORDER.getTRScanXPos) + public Integer getTRScanXPos() { + return hpReader.getInteger("TRScanXPos", 2202); + } + + @EnginnerPageParam(name = "试管扫码位置", group = "进出料<试管位置>信息", order = ORDER.getTScanXPos) + public Integer getTScanXPos() { + //运动方向: -> + return hpReader.getInteger("TScanXPos", 505); + + } + + @EnginnerPageParam(name = "试管高度判断位置", group = "进出料<试管位置>信息", order = ORDER.getTAltitJudgXPos) + public Integer getTAltitJudgXPos() { + //运动方向: -> + return hpReader.getInteger("TAltitJudgXPos", 505); + } + + @EnginnerPageParam(name = "试管是否存在判断位置", group = "进出料<试管位置>信息", order = ORDER.getTExistJudgXPos) + public Integer getTExistJudgXPos() { + //运动方向: <- + return hpReader.getInteger("TExistJudgXPos", 300); + } + + @EnginnerPageParam(name = "试管预处理位置", group = "进出料<试管位置>信息", order = ORDER.getTPreProcessXPos) + public Integer getTPreProcessXPos() { + //运动方向: <- + return hpReader.getInteger("TPreProcessXPos", 1225); + } + + @EnginnerPageParam(name = "试管架孔间距", group = "其他", order = ORDER.getTubeSpacing) + public Integer getTubeSpacing() { + return hpReader.getInteger("TubeSpacing", 200); + } + + @EnginnerPageParam(name = "扫码舵机转速(0..900)", group = "其他", order = ORDER.getTubeScanServoTorque) + public Integer getTubeScanServoTorque() { + return hpReader.getInteger("TubeScanServoTorque", 500); + } + + @EnginnerPageParam(name = "试管扫码超时时间", group = "其他", order = ORDER.getTubeScanOvertime) + public Integer getTubeScanOvertime() { + return hpReader.getInteger("TubeScanOvertime", 1000); + } + + + // + // + // + + + @EnginnerPageParam(name = "板夹仓通道0位置", group = "板夹仓参数", order = ORDER.getPBCh0Pos) + public Integer getPBCh0Pos() { + return hpReader.getInteger("PBCh0Pos", -17); + } + + @EnginnerPageParam(name = "板夹仓通道间距", group = "板夹仓参数", order = ORDER.getPBChSpacing) + public Integer getPBChSpacing() { + return hpReader.getInteger("PBChSpacing", 265); + } + + @EnginnerPageParam(name = "推杆到位坐标", group = "板夹仓参数", order = ORDER.getPusherEndPos) + public Integer getPusherEndPos() { + return hpReader.getInteger("PusherEndPos", 1160); + } + + @EnginnerPageParam(name = "推杆扫码开始坐标", group = "板夹仓参数", order = ORDER.getPusherScanStartPos) + public Integer getPusherScanStartPos() { + return hpReader.getInteger("PusherScanStartPos", 960); + } + + /* + * 转盘相关位置 + */ + + @EnginnerPageParam(name = "仓位0入板位置", group = "转盘坐标参数", order = ORDER.getTurntablePushPos0) + public Integer getTurntablePushPos0() { + return hpReader.getInteger("TurntablePushPos0", 1650); + } + + @EnginnerPageParam(name = "仓位0出板位置", group = "转盘坐标参数", order = ORDER.getTurntablePullPos0) + public Integer getTurntablePullPos0() { + return hpReader.getInteger("TurntablePullPos0", 19700); + } + + @EnginnerPageParam(name = "仓位0点滴位", group = "转盘坐标参数", order = ORDER.getTurntableDropLiquidPos0) + public Integer getTurntableDropLiquidPos0() { + return hpReader.getInteger("TurntableDropLiquidPos0", 1650 + 8950); + } + + public Integer getTurntablePosSpacing() { + return 1800; + } + + /* + * 光学模组相关 + */ + @EnginnerPageParam(name = "拉板目标位置", group = "光学模组坐标参数", order = ORDER.getPullerTargetPos) + public Integer getPullerTargetPos() { + return hpReader.getInteger("PullerTargetPos", 1147); + } + + @EnginnerPageParam(name = "丢板坐标", group = "光学模组坐标参数", order = ORDER.getPlateDropPos) + public Integer getPlateDropPos() { + return hpReader.getInteger("PlateDropPos", -349); + } + + @EnginnerPageParam(name = "扫描待机位", group = "光学模组坐标参数", order = ORDER.getOptScanScandbyPos) + public Integer getOptScanScandbyPos() { + return hpReader.getInteger("OptScanScandbyPos", 305); + } + + @EnginnerPageParam(name = "T光学扫描起始坐标", group = "光学模组坐标参数", order = ORDER.getTOptPosOffset) + public Integer getTOptPosOffset() { + //3509 + return hpReader.getInteger("TOptPosOffset", 3723); + } + + @EnginnerPageParam(name = "F光学扫描起始坐标", group = "光学模组坐标参数", order = ORDER.getFOptPosOffset) + public Integer getFOptPosOffset() { + return hpReader.getInteger("FOptPosOffset", 2559); + } + + @EnginnerPageParam(name = "T光学发光增益", group = "光学模组坐标参数", order = ORDER.getOptTLasterGain) + public Integer getOptTLasterGain() { + return hpReader.getInteger("OptTLasterGain", 0); + } + + @EnginnerPageParam(name = "F光学发光增益", group = "光学模组坐标参数", order = ORDER.getOptFLasterGain) + public Integer getOptFLasterGain() { + return hpReader.getInteger("OptFLasterGain", 0); + } + + + @EnginnerPageParam(name = "急诊位", group = "简单位置坐标", order = ORDER.getEmergencyPos) + public Pos3d getEmergencyPos() { + return new Pos3d( + 4858, + 3196, + 246 + ); + } + + @EnginnerPageParam(name = "TIP组位置信息", group = "HBOT位置坐标集合", order = ORDER.getTipPickUpPosInfo) + public TipPickUpPosInfo getTipPickUpPosInfo() { + return hpReader.getObject("TipPickUpPosInfo", TipPickUpPosInfo.class, + new TipPickUpPosInfo( + new Pos2d(887, -15), + new Pos2d(2413, -15), + new Pos2d(3947, -15), + 92.3, + 92.15, + 578, + 580, + 585 + )); + } + + + @EnginnerPageParam(name = "Tip丢弃位置", group = "简单位置坐标", order = ORDER.getTipDropPos) + public Pos3d getTipDropPos() { + return new Pos3d( + 4873, + 2563, + 661 + ); + } + + @EnginnerPageParam(name = "滴液反应位", group = "简单位置坐标", order = ORDER.getReactionPos) + public Pos3d getReactionPos() { + return hpReader.getObject("ReactionPos", Pos3d.class, + new Pos3d( + 0, + 0, + 0 + )); + } + + @EnginnerPageParam(name = "缓冲液位置", group = "HBOT位置坐标集合", order = ORDER.getBottleBufferPosInfo) + public BottleGroupsPosInfo getBottleBufferPosInfo() { + return hpReader.getObject("BottleBufferPosInfo", BottleGroupsPosInfo.class, + new BottleGroupsPosInfo( + new Pos2d(741, 937), + 1230, + 1250, + new Pos2d(579, 1097), + 320, + new BottlesPosInfo + ( + new Pos2d(160, 160), + 210, + 210, + 0 + ), + new BottlesPosInfo + ( + new Pos2d(215, 205), + 187, + 187, + 0 + ) + )); + } + + @EnginnerPageParam(name = "板夹仓扫码位置", group = "HBOT位置坐标集合", order = ORDER.getPlates2dCodeScanPosInfo) + public Plates2dCodeScanPos getPlates2dCodeScanPosInfo() { + return hpReader.getObject("Plates2dCodeScanPosInfo", Plates2dCodeScanPos.class,// + new Plates2dCodeScanPos( + new Pos2d(-20, 1504), + 265 + ) + ); + } + + @EnginnerPageParam(name = "大瓶缓冲液位置", group = "HBOT位置坐标集合", order = ORDER.getLargeBottleBufferPosInfo) + public LargeBottleBufferPos getLargeBottleBufferPosInfo() { + return hpReader.getObject("LargeBottleBufferPosInfo", LargeBottleBufferPos.class, + new LargeBottleBufferPos( + new Pos2d(4474, 1172), + new Pos2d(109, 182), + 280, + 280, + new Pos2d(60, 30), + 280, + 580 + )); + } + + @EnginnerPageParam(name = "Hbot采样区", group = "限制值", order = ORDER.getSampleCollectionArea) + public HbotLimitArea getSampleCollectionArea() { + return hpReader.getObject("HbotPublicArea", HbotLimitArea.class, + new HbotLimitArea(0, 3643, 5060, 4074)); + } + +} diff --git a/src/main/java/a8k/service/bak_devicectrl/param/TimeParam.java b/src/main/java/a8k/service/bak_devicectrl/param/TimeParam.java new file mode 100644 index 0000000..77d5912 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/param/TimeParam.java @@ -0,0 +1,52 @@ +package a8k.service.bak_devicectrl.param; + + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.controler.extapi.utils.*; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.TimeParam) +public class TimeParam { + EnginnerParamReader hpReader = new EnginnerParamReader(EnginnerPageParams.class); + + @EnginnerPageParam(name = "动作超时时间", group = "基础参数") + public Integer getActionOvertime() { + return hpReader.getInteger("ActionOvertime", 5000); + } + + @EnginnerPageParam(name = "归零超时时间", group = "基础参数") + public Integer getRuntoZeroActionOvertime() { + return hpReader.getInteger("RuntoZeroActionOvertime", 15000); + } + + @EnginnerPageParam(name = "入料超时时间", group = "基础参数") + public Integer getInfeedOvertime() { + return hpReader.getInteger("InfeedOvertime", 10000); + } + + @EnginnerPageParam(name = "出料超时时间", group = "基础参数") + public Integer getOutfeedOvertime() { + return hpReader.getInteger("OutfeedOvertime", 10000); + } + + @EnginnerPageParam(name = "试管帽有无判断时间", group = "基础参数") + public Integer getTubeCapJudgeDelayTime() { + return hpReader.getInteger("TubeCapJudgeDelayTime", 300); + } + + @EnginnerPageParam(name = "光学扫描超时时间", group = "光学") + public Integer getOptScanOvertime() { + return hpReader.getInteger("optScanOvertime", 12000); + } + + @EnginnerPageParam(name = "Hbot归零超时时间", group = "基础配置") + public Integer getHbotRuntoZeroActionOvertime() { + return hpReader.getInteger("HbotRuntoZeroActionOvertime", 20000); + } + + @EnginnerPageParam(name = "扫码超时时间", group = "基础配置") + public Integer getScancodeOvertime() { + return hpReader.getInteger("ScancodeOvertime", 1000); + } +} diff --git a/src/main/java/a8k/service/bak_devicectrl/status/DeviceStatus.java b/src/main/java/a8k/service/bak_devicectrl/status/DeviceStatus.java new file mode 100644 index 0000000..5a6aca3 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/status/DeviceStatus.java @@ -0,0 +1,87 @@ +package a8k.service.bak_devicectrl.status; + +import a8k.type.HardwareException; +import a8k.controler.extapi.utils.ExtApiTab; +import a8k.controler.extapi.utils.EnginnerPageStatu; +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.IOId; +import a8k.hardware.type.a8kcanprotocol.MId; +import a8k.hardware.type.regindex.RegIndex; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.DeviceStatus) +public class DeviceStatus { + @Resource + A8kCanBusService canBus; + + static class ORDER { + static final int isTubeExist = 1; + static final int isTubeRackInEnterPos = 2; + static final int isTubeRackInExitPos = 3; + static final int isHighTube = 4; + static final int getTHchOuterPPS = 5; + static final int getTHchInterPPS = 6; + static final int getXPPS = 7; + static final int getYPPS = 8; + static final int getZPPS = 9; + static final int getTipPPS = 10; + } + + // + // 状态 + // + @EnginnerPageStatu(name = "试管架存在", group = "进出料光电", order = ORDER.isTubeExist) + public Boolean isTubeExist() throws HardwareException { + return canBus.getIOState(IOId.TubeExistPPS); + } + + @EnginnerPageStatu(name = "入口光电", group = "进出料光电", order = ORDER.isTubeRackInEnterPos) + public Boolean isTubeRackInEnterPos() throws HardwareException { + return canBus.getIOState(IOId.InfeedPPS); + } + + @EnginnerPageStatu(name = "出口光电", group = "进出料光电", order = ORDER.isTubeRackInExitPos) + public Boolean isTubeRackInExitPos() throws HardwareException { + return canBus.getIOState(IOId.OutfeedPPS); + } + + @EnginnerPageStatu(name = "试管高低判读光电", group = "进出料光电", order = ORDER.isHighTube) + public Boolean isHighTube() throws HardwareException { + return canBus.getIOState(IOId.TubeHeightPPS); + } + + @EnginnerPageStatu(name = "通道外光电", group = "进出料光电", order = ORDER.getTHchOuterPPS) + public Boolean getTHchOuterPPS() throws HardwareException { + return canBus.getIOState(IOId.THChOuterPPS); + } + + @EnginnerPageStatu(name = "通道内光电", group = "进出料光电", order = ORDER.getTHchInterPPS) + public Boolean getTHchInterPPS() throws HardwareException { + return canBus.getIOState(IOId.THChInterPPS); + } + + @EnginnerPageStatu(name = "X轴光电➡", group = "HBOT", order = ORDER.getXPPS) + public Boolean getXPPS() throws HardwareException { + return canBus.hbotReadInio(MId.HbotM, 0); + } + + @EnginnerPageStatu(name = "Y轴光电⬇", group = "HBOT", order = ORDER.getYPPS) + public Boolean getYPPS() throws HardwareException { + return canBus.hbotReadInio(MId.HbotM, 1); + } + +// @EnginnerPageStatu(name = "Z轴光电⬆", group = "HBOT", order = ORDER.getZPPS) +// public Boolean getZPPS() throws HardwareException { +// return canBus.stepMotorReadIoState(MId.PipetteModZM, 0); +// } + + + // @HardwareServiceStatus(name = "TipState") + public Boolean getTipPPS() throws HardwareException { + return canBus.moduleGetReg(MId.PipetteMod, RegIndex.kreg_pipette_tip_state) == 1; + } + +} diff --git a/src/main/java/a8k/service/bak_devicectrl/testscript/TestScript.java b/src/main/java/a8k/service/bak_devicectrl/testscript/TestScript.java new file mode 100644 index 0000000..0eb3019 --- /dev/null +++ b/src/main/java/a8k/service/bak_devicectrl/testscript/TestScript.java @@ -0,0 +1,250 @@ +package a8k.service.bak_devicectrl.testscript; + +import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; +import a8k.type.ConsumableGroup; +import a8k.type.HardwareException; +import a8k.type.IncubatorPos; +import a8k.type.appret.AppRet; +import a8k.type.cfg.BottleGroupsPosInfo; +import a8k.type.cfg.BottlesPosInfo; +import a8k.type.cfg.TipPickUpPosInfo; +import a8k.controler.extapi.utils.*; +import a8k.service.bak_devicectrl.ctrl.SamplesPreProcesCtrl; +import a8k.service.bak_devicectrl.ctrl.TubeRackMoveCtrl; +import a8k.hardware.A8kCanBusService; +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.hardware.type.a8kcanprotocol.MId; +import a8k.hardware.type.regindex.RegIndex; +import a8k.service.bak_devicectrl.ctrl.HbotControlService; +import a8k.service.bak_devicectrl.ctrl.ReactionPlatesTransmitCtrl; +import a8k.service.bak_devicectrl.param.DebugParam; +import a8k.service.bak_devicectrl.param.PosParam; +import a8k.service.bak_devicectrl.param.TimeParam; +import jakarta.annotation.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +@Component +@ExtApiTab(cfg = ExtApiTabConfig.TestScript) +public class TestScript { + static Logger logger = LoggerFactory.getLogger(TestScript.class); + + static class ORDER { + static final int testTakeAllTipStop = 0; + static final int takeTipTestStep = 1; + static final int testTakeAllTip = 2; + static final int testAllLittleBottleBufferPos = 3; + static final int testAllDetectMaterialPos = 4; + static final int testAllBigBottleBufferPos = 5; + static final int pushAllPlateAndDrop = 6; + static final int testSamplePreProcessModule = 7; + } + + @Resource + A8kCanBusService canBus; + + @Resource + ApplicationContext appCxt; + + @Resource + HbotControlService hbotcs; + + @Resource + TimeParam timep; + @Resource + PosParam pp; + @Resource + DebugParam dp; + + @Resource + ReactionPlatesTransmitCtrl reactionPlatesTransmitCtrl; + + @Resource + SamplesPreProcesCtrl samplesPreProcesCtrl; + + @Resource + TubeRackMoveCtrl tubeRackMoveCtrl; + + EnginnerParamReader settingReader = new EnginnerParamReader(HbotControlService.class); + + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // 测试 + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Boolean testScriptWorkFlag = false; + + void checkTestScriptWorkFlag() throws HardwareException { + if (testScriptWorkFlag) { + testScriptWorkFlag = false; + throw new HardwareException(A8kEcode.TestScripIsRunning.index); + } + } + + @ExtApiFn(name = "停止测试脚本", group = "控制", order = ORDER.testTakeAllTipStop) + public void testTakeAllTipStop() { + testScriptWorkFlag = false; + } + + @ExtApiFn(name = "取放Tip-单步", group = "Hbot测试脚本", order = ORDER.takeTipTestStep) + public AppRet takeTipTestStep(Integer tipgroup, Integer index) throws HardwareException, InterruptedException { + checkTestScriptWorkFlag(); + testScriptWorkFlag = true; + var ret = hbotcs.takeTip(tipgroup, index); + TipPickUpPosInfo tipPos = pp.getTipPickUpPosInfo(); + + //TODO canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, tipPos.getPickUpZPos(tipgroup) - 100, timep.getActionOvertime()); + // TODO canBus.pipetteCtrlPutTipBlock(MId.PipetteMod); + + if (canBus.moduleGetReg(MId.PipetteMod, RegIndex.kreg_pipette_tip_state) == 1) { + throw new HardwareException(A8kEcode.PutTipFail.index); + } + + // TODO canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); + testScriptWorkFlag = false; + return ret; + } + + @ExtApiFn(name = "取放Tip-全部", group = "Hbot测试脚本", order = ORDER.testTakeAllTip) + public AppRet> testTakeAllTip(Integer groupId, Integer startFrom) throws HardwareException, InterruptedException { + checkTestScriptWorkFlag(); + + testScriptWorkFlag = true; + Map result = new HashMap<>(); + for (int i = startFrom; i < TipPickUpPosInfo.cgetTipNum(); i++) { + var ret = takeTipTestStep(groupId, i); + if (!ret.getData()) { + throw new HardwareException(A8kEcode.TakeTipFail.index); + } + + result.put("Tip" + i, ret.getData() ? "suc" : "fail"); + logger.info("Take Tip {}-{} => {}", groupId, i, ret.getData()); + if (!testScriptWorkFlag) { + break; + } + } + testScriptWorkFlag = false; + return AppRet.success(result); + } + + @ExtApiFn(name = "测试所有小瓶缓冲液位置", group = "Hbot测试脚本", order = ORDER.testAllLittleBottleBufferPos) + public void testAllLittleBottleBufferPos(ConsumableGroup group) throws HardwareException, InterruptedException { + checkTestScriptWorkFlag(); + + testScriptWorkFlag = true; + BottleGroupsPosInfo posInfo = pp.getBottleBufferPosInfo(); + for (int i = 0; i < BottlesPosInfo.cgetMAX(); i++) { + BottleGroupsPosInfo pos = pp.getBottleBufferPosInfo(); + hbotcs.hbotMoveToSmallBottleGroup(group, i); + //TODO: canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, pos.posTestZ, timep.getActionOvertime()); + //TODO: canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); + if (!testScriptWorkFlag) { + break; + } + } + testScriptWorkFlag = false; + } + + @ExtApiFn(name = "测试所有探测物质位置", group = "Hbot测试脚本", order = ORDER.testAllDetectMaterialPos) + public void testAllDetectMaterialPos(ConsumableGroup group) throws HardwareException, InterruptedException { + checkTestScriptWorkFlag(); + + testScriptWorkFlag = true; + for (int i = 0; i < BottlesPosInfo.cgetMAX(); i++) { + BottleGroupsPosInfo pos = pp.getBottleBufferPosInfo(); + hbotcs.hbotMoveToDetectMaterialPos(group, i); + //TODO: canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, pos.posTestZ, timep.getActionOvertime()); + //TODO: canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); + if (!testScriptWorkFlag) { + break; + } + } + testScriptWorkFlag = false; + } + + @ExtApiFn(name = "测试所有大瓶缓冲液位置", group = "Hbot测试脚本", order = ORDER.testAllBigBottleBufferPos) + public void testAllBigBottleBufferPos() throws HardwareException, InterruptedException { + checkTestScriptWorkFlag(); + + testScriptWorkFlag = true; + // 遍历枚举 ConsumableGroup + for (ConsumableGroup group : ConsumableGroup.values()) { + hbotcs.hbotMoveToLargeBottleGroup(group); + //TODO: canBus.stepMotorEasyMoveByBlock(MId.PipetteModZM, 100, timep.getActionOvertime()); + //TODO: canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); + if (!testScriptWorkFlag) { + break; + } + } + testScriptWorkFlag = false; + } + + @ExtApiFn(name = "推全部板同时丢弃", group = "板夹移动测试脚本", order = ORDER.pushAllPlateAndDrop) + public void pushAllPlateAndDrop(ConsumableGroup PBCh, IncubatorPos startPos) throws HardwareException, InterruptedException { + checkTestScriptWorkFlag(); + testScriptWorkFlag = true; + reactionPlatesTransmitCtrl.checkBeforeMoveTrunable(); + reactionPlatesTransmitCtrl.checkBeforeMovePlateBox(); + reactionPlatesTransmitCtrl.modGroupMoveToZeroQuick(); + reactionPlatesTransmitCtrl.dropPlate(); + for (IncubatorPos index : IncubatorPos.values()) { + if (index.compareTo(startPos) < 0) { + continue; + } + reactionPlatesTransmitCtrl.pushPlateQuick(PBCh, index); + reactionPlatesTransmitCtrl.pullPlate(index); + reactionPlatesTransmitCtrl.dropPlate(); + if (!testScriptWorkFlag) { + break; + } + } + testScriptWorkFlag = false; + } + + @ExtApiFn(name = "测试摇匀模组", group = "摇匀模组测试", order = ORDER.testSamplePreProcessModule) + public AppRet testSamplePreProcessModule() throws HardwareException, InterruptedException { + checkTestScriptWorkFlag(); + testScriptWorkFlag = true; + + try { + tubeRackMoveCtrl.enterTubeHolder(); + AppRet scanResult = tubeRackMoveCtrl.moveTubeRackToScanPosAndScan(); + if (!scanResult.isSuccess()) { + tubeRackMoveCtrl.ejectTubeHolder(); + logger.info("没有扫到试管架的码"); + return AppRet.message("没有扫到试管架的码", null); + } + if (!scanResult.getData().equals("1111\r")) { + tubeRackMoveCtrl.ejectTubeHolder(); + logger.info("不是全血试管架 {}", scanResult.getData()); + return AppRet.message("不是全血试管架", null); + } + + AppRet isExistTube = tubeRackMoveCtrl.judgeTubeExist(0); + AppRet isHighTube = tubeRackMoveCtrl.moveTubeToAltitJudgXPos(0); + tubeRackMoveCtrl.moveTubeToPreProcessPos(0); + + if (!isExistTube.getData()) { + tubeRackMoveCtrl.ejectTubeHolder(); + logger.info("试管架上没有试管"); + return AppRet.message("试管架上没有试管", null); + } + + + samplesPreProcesCtrl.takeTubeAndJudgeTubeExist(isHighTube.getData()); + samplesPreProcesCtrl.shakeTube(50, 5); + samplesPreProcesCtrl.takeTubeCap(); + samplesPreProcesCtrl.pushBackTubeCapAndTakeBakTube(); + tubeRackMoveCtrl.ejectTubeHolder(); + } finally { + testScriptWorkFlag = false; + } + + return AppRet.message("测试完成", null); + + } + +} diff --git a/src/main/java/a8k/service/devicectrl/calibration/PositionCalibration.java b/src/main/java/a8k/service/devicectrl/calibration/PositionCalibration.java deleted file mode 100644 index 86761f9..0000000 --- a/src/main/java/a8k/service/devicectrl/calibration/PositionCalibration.java +++ /dev/null @@ -1,119 +0,0 @@ -package a8k.service.devicectrl.calibration; - -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.type.HardwareException; -import a8k.type.appret.AppRet; -import a8k.type.cfg.Pos2d; -import a8k.controler.extapi.utils.*; -import a8k.hardware.A8kCanBusService; -import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.service.devicectrl.param.DebugParam; -import a8k.service.devicectrl.param.PosParam; -import a8k.service.devicectrl.param.TimeParam; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.PositionCalibration) -public class PositionCalibration { - - @Resource - A8kCanBusService canBus; - @Resource - TimeParam timep; - @Resource - PosParam pp; - @Resource - DebugParam dp; - - @ExtApiFn(name = "试管夹平移电机-使能", group = "电机使能") - public void FeedingModXMEnable(Boolean enable) throws HardwareException { - canBus.stepMotorEnable(MId.FeedingModXM, enable ? 1 : 0); - } - - @ExtApiFn(name = "板夹仓Y轴-使能", group = "电机使能") - public void platesBoxYMEndble(Boolean enable) throws HardwareException { - canBus.stepMotorEnable(MId.PlatesBoxYM, enable ? 1 : 0); - } - - @ExtApiFn(name = "板夹仓推杆-使能", group = "电机使能") - public void platesBoxPusherMEndble(Boolean enable) throws HardwareException { - canBus.stepMotorEnable(MId.PlatesBoxPusherM, enable ? 1 : 0); - } - - @ExtApiFn(name = "拉杆-使能", group = "电机使能") - public void optModPullMEndble(Boolean enable) throws HardwareException { - canBus.stepMotorEnable(MId.OptModPullM, enable ? 1 : 0); - } - - @ExtApiFn(name = "光学模组扫描器-使能", group = "电机使能") - public void optModScannerMEndble(Boolean enable) throws HardwareException { - canBus.stepMotorEnable(MId.OptModScannerM, enable ? 1 : 0); - } - - @ExtApiFn(name = "转盘-使能", group = "电机使能") - public void incubatorRotateCtrlMEndble(Boolean enable) throws HardwareException { - canBus.stepMotorEnable(MId.IncubatorRotateCtrlM, enable ? 1 : 0); - - } - - - @ExtApiFn(name = "试管夹平移电机-读取位置", group = "通过归零测量位置") - public AppRet readXPosByMoveZero() throws HardwareException, InterruptedException { - return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.FeedingModXM, timep.getActionOvertime())); - } - - - @ExtApiFn(name = "通过归零读取<板夹仓>位置", group = "通过归零测量位置") - public AppRet readPlatesBoxYMPosByMoveToZero() throws HardwareException, InterruptedException { - return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.PlatesBoxYM, timep.getActionOvertime())); - } - - @ExtApiFn(name = "通过归零读取<推杆>位置", group = "通过归零测量位置") - public AppRet readPlatesBoxPusherMPosByMoveToZero() throws HardwareException, InterruptedException { - return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.PlatesBoxPusherM, timep.getActionOvertime())); - } - - @ExtApiFn(name = "通过归零读取<拉杆>位置", group = "通过归零测量位置") - public AppRet readOptModPullMPosByMoveToZero() throws HardwareException, InterruptedException { - return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.OptModPullM, timep.getActionOvertime())); - } - - @ExtApiFn(name = "通过归零读取<光学模组扫描器>位置", group = "通过归零测量位置") - public AppRet readOptModScannerMPosByMoveToZero() throws HardwareException, InterruptedException { - return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.OptModScannerM, timep.getActionOvertime())); - } - - @ExtApiFn(name = "通过归零读取<摇匀模组Z轴>位置", group = "通过归零测量位置") - public AppRet readShakeModGripperZMPosByMoveToZero() throws HardwareException, InterruptedException { - return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.ShakeModGripperZM, timep.getActionOvertime())); - } - - - @EnginnerPageStatu(name = "HbotPos", group = "Hbot") - public String getHbotPos() throws HardwareException { - Pos2d pos = canBus.hbotReadPos(MId.HbotM); - return pos.toString(); - } - - - @EnginnerPageStatu(name = "转盘位置") - public String getIncubatorRotateCtrlMPos() throws HardwareException { - Integer pos = canBus.stepMotorReadPos(MId.IncubatorRotateCtrlM); - return pos.toString(); - } - - @EnginnerPageStatu(name = "抓手Y轴位置", group = "摇匀模组") - public String getShakeModGripperYPos() throws HardwareException { - Integer pos = canBus.miniServoReadPos(MId.ShakeModGripperYSV); - return pos.toString(); - } - - @EnginnerPageStatu(name = "抓手位置", group = "摇匀模组") - public String getGripperPos() throws HardwareException { - Integer pos = canBus.miniServoReadPos(MId.ShakeModGripperSV); - return pos.toString(); - } - - -} diff --git a/src/main/java/a8k/service/devicectrl/commonctrl/HardwareCommonCtrl.java b/src/main/java/a8k/service/devicectrl/commonctrl/HardwareCommonCtrl.java deleted file mode 100644 index b32463b..0000000 --- a/src/main/java/a8k/service/devicectrl/commonctrl/HardwareCommonCtrl.java +++ /dev/null @@ -1,395 +0,0 @@ -package a8k.service.devicectrl.commonctrl; - - -import a8k.type.HardwareException; -import a8k.type.appret.AppRet; -import a8k.controler.extapi.utils.ExtApiTab; -import a8k.controler.extapi.utils.ExtApiFn; -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.hardware.A8kCanBusService; -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.hardware.type.a8kcanprotocol.IOId; -import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.service.devicectrl.param.PosParam; -import a8k.service.devicectrl.param.TimeParam; -import jakarta.annotation.Resource; -import org.slf4j.Logger; -import org.springframework.stereotype.Component; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.HardwareCommonCtrl) -public class HardwareCommonCtrl { - static Logger logger = org.slf4j.LoggerFactory.getLogger(HardwareCommonCtrl.class); - - static class ORDER { - static final int initializeDevice = 1; - static final int deviceClear = 2; - static final int deviceForceStop = 3; - static final int forceDisableAllMOtor = 4; - static final int deviceEnable = 5; - } - - @Resource - A8kCanBusService canBus; - - @Resource - TimeParam timep; - - @Resource - PosParam posp; - - Boolean workState = false; - - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // CHECK - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - private AppRet checkDeviceStateBeforeRunToZero() throws HardwareException { - logger.info("checkDeviceStateBeforeRunToZero"); - //试管平移通道是否有障碍 - if (canBus.getIOState(IOId.THChInterPPS) || canBus.getIOState(IOId.THChOuterPPS)) { - logger.warn("THChInterPPS or THChOuterPPS is trigger"); - return AppRet.fail(A8kEcode.TubeXChannelIsNotEmpty.index); - } - - //板夹仓盖子是否盖上 - if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { - return AppRet.fail(A8kEcode.PlateBoxNotCover.index); - } - - //板夹仓卡板检测 - if (canBus.getIOState(IOId.PlateBoxPlateStuckPPS)) { - return AppRet.fail(A8kEcode.PlateStuckDetectorSensorTrigger.index); - } - - //检查钩板电机是否处于终点位置 - if (!canBus.getIOState(IOId.PullerMZeroPPS)) { - return AppRet.fail(A8kEcode.PullerMInitPosError.index); - } - - //检查板夹仓光电是否处于起点位置 - if (!canBus.getIOState(IOId.PusherMZeroPPS)) { - return AppRet.fail(A8kEcode.PusherMInitPosError.index); - } - //板夹仓光电 - if (canBus.getIOState(IOId.RecycleBinOverflowPPS)) { - return AppRet.fail(A8kEcode.RecycleBinOverflow.index); - } - - return AppRet.success(); - } - - private void checkStopFlag() throws HardwareException { - if (!workState) { - throw new HardwareException(A8kEcode.StopByUser.index); - } - } - - - private AppRet moveMotorToZero() throws HardwareException, InterruptedException { - - //进出料初始化 - canBus.stepMotorEasyMoveToZeroBlock(MId.FeedingModXM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - - canBus.miniServoMoveToBlock(MId.ShakeModTubeScanerClampingSV, 20, timep.getActionOvertime()); - checkStopFlag(); - - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, 300, timep.getActionOvertime()); - checkStopFlag(); - - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, 300, timep.getActionOvertime()); - checkStopFlag(); - - - canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModClampingM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModGripperZM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModShakeM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - - canBus.stepMotorEasyMoveTo(MId.ShakeModShakeM, 90); - checkStopFlag(); - - //板夹仓初始化 - canBus.stepMotorEasyMoveToZeroBlock(MId.PlatesBoxYM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - canBus.stepMotorEasyMoveToZeroBlock(MId.PlatesBoxPusherM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - //光学模组初始化 - canBus.stepMotorEasyMoveToZeroBlock(MId.OptModPullM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - canBus.stepMotorEasyMoveToZeroBlock(MId.OptModScannerM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - //HBot初始化 - canBus.hbotMoveToZero(MId.HbotM); - checkStopFlag(); - - // TODO canBus.stepMotorEasyMoveToZeroBlock(MId.PipetteModZM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - //转盘归零 - canBus.stepMotorEasyMoveToZeroBlock(MId.IncubatorRotateCtrlM, timep.getRuntoZeroActionOvertime()); - checkStopFlag(); - - - return AppRet.success(); - } - - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Expose API - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @ExtApiFn(name = "设备初始化", order = ORDER.initializeDevice) - public AppRet initializeDevice() throws HardwareException, InterruptedException { - logger.info("Initializing device ..."); - boolean initSuc = false; - workState = true; - AppRet ecode; - try { - //打开必要的电源 - canBus.setIOState(IOId.RecycleBinOverflowPPSPowerCtrl, true); - - //检查设备状态 - ecode = checkDeviceStateBeforeRunToZero(); - if (!ecode.isSuccess()) { - return AppRet.fail(ecode); - } - // 复位设备 - logger.info("moveMotorToZero"); - ecode = moveMotorToZero(); - if (!ecode.isSuccess()) { - return AppRet.fail(ecode); - } - initSuc = true; - logger.info("Device initialization completed"); - - } finally { - if (!initSuc) { - try { - canBus.stepMotorEnable(MId.ShakeModClampingM, 1); - } catch (HardwareException ignored) { - } - try { - canBus.stepMotorEasyMoveBy(MId.ShakeModClampingM, 2); - } catch (HardwareException ignored) { - } - } - } - return AppRet.success("初始化完成"); - - } - - // @EnginnerPageAction(name = "清空板夹仓板夹", order = ORDER.deviceClear) - // public void clearDevice() { - // //TODO - // } - - - @ExtApiFn(name = "设备强制停止", order = ORDER.deviceForceStop) - public void deviceForceStop() throws HardwareException { - //StopAllMotor - //进出料初始化 - try { - canBus.moduleStop(MId.FeedingModInfeedM); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.FeedingModXM); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.FeedingModOutfeedM); - } catch (HardwareException ignored) { - } - //摇匀模组初始化 - try { - canBus.moduleStop(MId.ShakeModClampingM); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.ShakeModGripperZM); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.ShakeModShakeM); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.ShakeModGripperYSV); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.ShakeModGripperSV); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.ShakeModTubeScanerClampingSV); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.ShakeModTubeScanerRotateSV); - } catch (HardwareException ignored) { - } - //板夹仓初始化 - try { - canBus.moduleStop(MId.PlatesBoxYM); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.PlatesBoxPusherM); - } catch (HardwareException ignored) { - } - //光学模组初始化 - try { - canBus.moduleStop(MId.OptModPullM); - } catch (HardwareException ignored) { - } - try { - canBus.moduleStop(MId.OptModScannerM); - } catch (HardwareException ignored) { - } - //HBot初始化 - try { - canBus.moduleStop(MId.HbotM); - } catch (HardwareException ignored) { - } - // try { - // TODO canBus.moduleStop(MId.PipetteModZM); - // } catch (HardwareException ignored) { - // } - //转盘归零 - try { - canBus.moduleStop(MId.IncubatorRotateCtrlM); - } catch (HardwareException ignored) { - } - - } - - @ExtApiFn(name = "设备强制使能所有电机", order = ORDER.forceDisableAllMOtor) - public void forceDisableAllMOtor() { - //Disable all motor - //进出料初始化 - try { - canBus.stepMotorEnable(MId.FeedingModInfeedM, 0); - } catch (HardwareException ignored) { - } - try { - canBus.stepMotorEnable(MId.FeedingModXM, 0); - } catch (HardwareException ignored) { - } - try { - canBus.stepMotorEnable(MId.FeedingModOutfeedM, 0); - } catch (HardwareException ignored) { - } - - //摇匀模组初始化 - try { - canBus.stepMotorEnable(MId.ShakeModClampingM, 0); - } catch (HardwareException ignored) { - } - try { - canBus.stepMotorEnable(MId.ShakeModGripperZM, 0); - } catch (HardwareException ignored) { - } - try { - canBus.stepMotorEnable(MId.ShakeModShakeM, 0); - } catch (HardwareException ignored) { - } - try { - canBus.miniServoEnable(MId.ShakeModGripperYSV, 0); - } catch (HardwareException ignored) { - } - try { - canBus.miniServoEnable(MId.ShakeModGripperSV, 0); - } catch (HardwareException ignored) { - } - try { - canBus.miniServoEnable(MId.ShakeModTubeScanerClampingSV, 0); - } catch (HardwareException ignored) { - } - try { - canBus.miniServoEnable(MId.ShakeModTubeScanerRotateSV, 0); - } catch (HardwareException ignored) { - } - - //板夹仓初始化 - try { - canBus.stepMotorEnable(MId.PlatesBoxYM, 0); - } catch (HardwareException ignored) { - } - try { - canBus.stepMotorEnable(MId.PlatesBoxPusherM, 0); - } catch (HardwareException ignored) { - } - - //光学模组初始化 - try { - canBus.stepMotorEnable(MId.OptModPullM, 0); - } catch (HardwareException ignored) { - } - try { - canBus.stepMotorEnable(MId.OptModScannerM, 0); - } catch (HardwareException ignored) { - } - - //HBot初始化 - try { - canBus.hbotEnable(MId.HbotM, 0); - } catch (HardwareException ignored) { - } - // try { - //TODO canBus.stepMotorEnable(MId.PipetteModZM, 0); - // } catch (HardwareException ignored) { - // } - - //转盘归零 - try { - canBus.stepMotorEnable(MId.IncubatorRotateCtrlM, 0); - } catch (HardwareException ignored) { - } - } - - @ExtApiFn(name = "设备使能", order = ORDER.deviceEnable) - public void deviceEnable(Boolean enable) throws HardwareException { - //进出料初始化 - canBus.stepMotorEnable(MId.FeedingModInfeedM, enable ? 1 : 0); - canBus.stepMotorEnable(MId.FeedingModXM, enable ? 1 : 0); - canBus.stepMotorEnable(MId.FeedingModOutfeedM, enable ? 1 : 0); - - //摇匀模组初始化 - canBus.stepMotorEnable(MId.ShakeModClampingM, enable ? 1 : 0); - canBus.stepMotorEnable(MId.ShakeModGripperZM, enable ? 1 : 0); - canBus.stepMotorEnable(MId.ShakeModShakeM, enable ? 1 : 0); - canBus.miniServoEnable(MId.ShakeModGripperYSV, enable ? 1 : 0); - canBus.miniServoEnable(MId.ShakeModGripperSV, enable ? 1 : 0); - canBus.miniServoEnable(MId.ShakeModTubeScanerClampingSV, enable ? 1 : 0); - canBus.miniServoEnable(MId.ShakeModTubeScanerRotateSV, enable ? 1 : 0); - - //板夹仓初始化 - canBus.stepMotorEnable(MId.PlatesBoxYM, enable ? 1 : 0); - canBus.stepMotorEnable(MId.PlatesBoxPusherM, enable ? 1 : 0); - - //光学模组初始化 - canBus.stepMotorEnable(MId.OptModPullM, enable ? 1 : 0); - canBus.stepMotorEnable(MId.OptModScannerM, enable ? 1 : 0); - - //HBot初始化 - canBus.hbotEnable(MId.HbotM, enable ? 1 : 0); - // TODO canBus.stepMotorEnable(MId.PipetteModZM, enable ? 1 : 0); - - //转盘归零 - canBus.stepMotorEnable(MId.IncubatorRotateCtrlM, enable ? 1 : 0); - } - - public void checkBeforeMove(MId mId) throws HardwareException { - //板夹仓盖子是否盖上 - if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { - throw new HardwareException(A8kEcode.PlateBoxNotCover.index); - } - } - - public void stop() { - workState = false; - } - -} diff --git a/src/main/java/a8k/service/devicectrl/ctrl/HbotControlService.java b/src/main/java/a8k/service/devicectrl/ctrl/HbotControlService.java deleted file mode 100644 index f1430ea..0000000 --- a/src/main/java/a8k/service/devicectrl/ctrl/HbotControlService.java +++ /dev/null @@ -1,353 +0,0 @@ -package a8k.service.devicectrl.ctrl; - -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.type.ConsumableGroup; -import a8k.type.HardwareException; -import a8k.type.appret.AppRet; -import a8k.type.cfg.*; -import a8k.controler.extapi.utils.*; -import a8k.hardware.A8kCanBusService; -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.hardware.type.a8kcanprotocol.IOId; -import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.hardware.type.regindex.RegIndex; -import a8k.service.devicectrl.commonctrl.HardwareCommonCtrl; -import a8k.service.devicectrl.param.DebugParam; -import a8k.service.devicectrl.param.PosParam; -import a8k.service.devicectrl.param.TimeParam; -import jakarta.annotation.Resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * Hbot控制服务 - */ -@Component -@ExtApiTab(cfg = ExtApiTabConfig.HbotControlService) -public class HbotControlService { - static Logger logger = LoggerFactory.getLogger(HbotControlService.class); - - @Resource - A8kCanBusService canBus; - @Resource - HardwareCommonCtrl hcc; - @Resource - TimeParam timep; - @Resource - PosParam pp; - @Resource - DebugParam dp; - - // - public Integer getGripperZeroYPos() { - // 之所以这样写,是因为是为了放置两个类之间的循环依赖 - // assert appCxt != null; - // TODO - // return - // appCxt.getBean(SamplesPreProcessModuleCtrlService.class).getGripperZeroYPos(); - return 0; - } - - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // 基础控制 - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - private void checkPublicArea() throws HardwareException { - if (canBus.miniServoReadPos(MId.ShakeModGripperYSV) > getGripperZeroYPos() + 20) { - logger.error("ShakeModGripperYSV Pos:{} > {}", canBus.miniServoReadPos(MId.ShakeModGripperYSV), - getGripperZeroYPos() + 20); - throw new HardwareException(A8kEcode.ShakeModGripperYSVInXYPublicArea.index); - } - } - - /** - * Hboot 移动 - * - * @param targetPos 目标位置 - * @throws HardwareException e - * @throws InterruptedException e - */ - public void hbotCheckAndMoveTo(Pos3d targetPos) throws HardwareException, InterruptedException { - logger.info("hbotCheckAndMoveTo:{}", targetPos); - if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { - throw new HardwareException(A8kEcode.PlateBoxNotCover.index); - } - - - boolean zEnable = true; - boolean hbotEnable = canBus.moduleGetReg(MId.HbotM, RegIndex.kreg_xyrobot_is_enable) == 1; - - //TODO - // if (canBus.moduleGetReg(MId.PipetteModZM, RegIndex.kreg_step_motor_is_enable) == 0) { - // canBus.stepMotorEnable(MId.PipetteModZM, 1); - // canBus.stepMotorEasyMoveToZeroBlock(MId.PipetteModZM, timep.getActionOvertime()); - // zEnable = false; - // } - - // TODO Z轴归零 - // if (!getZPPS()) { - // canBus.stepMotorEnable(MId.PipetteModZM, 1); - // canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); - // } - -// if (!getZPPS()) { TODO -// throw new HardwareException(A8kEcode.ZMNotAtZPosWhenHbotTryMove.index); -// } - Pos2d nowHbotPos = canBus.hbotReadPos(MId.HbotM); - HbotLimitArea sampleArea = pp.getSampleCollectionArea(); - - // 检查采样区域是否有障碍 - if (sampleArea.checkIsInArea(nowHbotPos) || sampleArea.checkIsInArea(targetPos.getXYPos())) { - checkPublicArea(); - } - - // HBot移动 - canBus.hbotEnable(MId.HbotM, 1); - canBus.hbotMoveToBlock(MId.HbotM, targetPos.x - 20, targetPos.y - 20, timep.getActionOvertime()); - canBus.hbotMoveToBlock(MId.HbotM, targetPos.x, targetPos.y, timep.getActionOvertime()); - canBus.hbotMoveToBlock(MId.HbotM, targetPos.x, targetPos.y, timep.getActionOvertime()); - - // Z轴移动 - if (targetPos.z != 0) { - // TODO canBus.stepMotorEnable(MId.PipetteModZM, 1); - // TODO canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); - // TODO zMoveTo(targetPos.z); - } - // TODO canBus.stepMotorEnable(MId.PipetteModZM, zEnable ? 1 : 0); - canBus.hbotEnable(MId.HbotM, hbotEnable ? 1 : 0); - } - - public void zMoveTo(Integer z) throws HardwareException, InterruptedException { - if (z == 0) { - // TODO canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); - } else { - //TODO canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, z, timep.getActionOvertime()); - } - } - - private void hbotCheckAndMoveTo(Pos2d targetPos) throws HardwareException, InterruptedException { - hbotCheckAndMoveTo(new Pos3d(targetPos.x, targetPos.y, 0)); - } - - private void modGroupMoveToZero() throws HardwareException, InterruptedException { - if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) { - throw new HardwareException(A8kEcode.PlateBoxNotCover.index); - } - - // 归零前检查 - checkPublicArea(); - // TODO canBus.stepMotorEnable(MId.PipetteModZM, 1); - canBus.hbotEnable(MId.HbotM, 1); - -// canBus.stepMotorEasyMoveToZeroBlock(MId.PipetteModZM, timep.getActionOvertime()); - canBus.hbotMoveToZeroBlock(MId.HbotM, timep.getHbotRuntoZeroActionOvertime()); - - // 丢弃tip - Pos3d dropPos = pp.getTipDropPos(); - hbotCheckAndMoveTo(dropPos); - // TODO: canBus.pipetteCtrlInitDeviceBlock(MId.PipetteMod, timep.getActionOvertime()); - - // 快速归零 - modGroupMoveToZeroQuick(); - } - - private void modGroupMoveToZeroQuick() throws HardwareException, InterruptedException { - hbotCheckAndMoveTo(new Pos2d(0, 0)); - } - - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // 单步测试 - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - @ExtApiFn(name = "丢Tip", group = "单步测试") - public void dropTip() throws HardwareException, InterruptedException { - Pos3d pos = pp.getTipDropPos(); - hbotMoveTo(pos.x, pos.y); - zMoveTo(pos.z); - //TODO: canBus.pipetteCtrlPutTip(MId.PipetteMod); - zMoveTo(0); - } - - @ExtApiFn(name = "取Tip", group = "单步测试") - public AppRet takeTip(Integer groupId, Integer index) throws HardwareException, InterruptedException { - logger.info("takeTip groupId:{} index:{}", groupId, index); - if (groupId > 2 || groupId < 0) { - throw new HardwareException(A8kEcode.ParamOutOfRange.index); - } - - if (index > TipPickUpPosInfo.cgetTipNum() || index < 0) { - throw new HardwareException(A8kEcode.ParamOutOfRange.index); - } - - TipPickUpPosInfo tipPos = pp.getTipPickUpPosInfo(); - Pos2d pos = tipPos.getTipPos(groupId, index); - hbotMoveTo(pos.x, pos.y); - - Integer zCompensate = 0; - if (groupId > 1) { - zCompensate = 2; - } - - // TODO - // canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, tipPos.getPickUpZPos(groupId) + zCompensate, - // timep.getActionOvertime()); - // canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); - - Boolean isGetTip = canBus.moduleGetReg(MId.PipetteMod, RegIndex.kreg_pipette_tip_state) == 1; - if (!isGetTip) { - logger.error("takeTip fail"); - } - return AppRet.success(isGetTip); - } - - @ExtApiFn(name = "HBot移动到", group = "单步测试") - public void hbotMoveTo(Integer x, Integer y) throws HardwareException, InterruptedException { - hbotCheckAndMoveTo(new Pos2d(x, y)); - } - - @ExtApiFn(name = "HBot移动到小瓶缓冲液X孔", group = "单步测试") - public void hbotMoveToSmallBottleGroup(ConsumableGroup group, Integer Xhole) - throws HardwareException, InterruptedException { - BottleGroupsPosInfo posInfo = pp.getBottleBufferPosInfo(); - if (Xhole < 0 || Xhole > BottlesPosInfo.cgetMAX()) { - throw new HardwareException(A8kEcode.ParamOutOfRange.index); - } - Pos2d pos = posInfo.cgetSmallBottleBufferPos(group.off, Xhole); - hbotCheckAndMoveTo(pos); - } - - @ExtApiFn(name = "HBot移动到探测物质X孔", group = "单步测试") - public void hbotMoveToDetectMaterialPos(ConsumableGroup group, Integer Xhole) - throws HardwareException, InterruptedException { - BottleGroupsPosInfo posInfo = pp.getBottleBufferPosInfo(); - if (Xhole < 0 || Xhole > BottlesPosInfo.cgetMAX()) { - throw new HardwareException(A8kEcode.ParamOutOfRange.index); - } - Pos2d pos = posInfo.cgetDetectMaterialPos(group.off, Xhole); - hbotCheckAndMoveTo(pos); - } - - @ExtApiFn(name = "HBot移动到大瓶缓冲液X孔", group = "单步测试") - public void hbotMoveToLargeBottleGroup(ConsumableGroup ch) throws HardwareException, InterruptedException { - LargeBottleBufferPos posInfo = pp.getLargeBottleBufferPosInfo(); - Pos2d pos = posInfo.cgetBottlePos(ch.off); - hbotCheckAndMoveTo(pos); - } - - @ExtApiFn(name = "HBot移动到急诊位", group = "单步测试") - public void hbotMoveToEmergencyPos() throws HardwareException, InterruptedException { - hbotCheckAndMoveTo(pp.getEmergencyPos()); - } - - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // 坐标获取工具 - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - @ExtApiFn(name = "Hbot使能", group = "坐标获取工具") - public void hBotEnable() throws HardwareException, InterruptedException { - canBus.hbotEnable(MId.HbotM, 1); - } - - @ExtApiFn(name = "Hbot失能", group = "坐标获取工具") - public void hBotDisable() throws HardwareException, InterruptedException { - canBus.hbotEnable(MId.HbotM, 0); - } - - @ExtApiFn(name = "Z轴使能", group = "坐标获取工具") - public void zAxisEnable() throws HardwareException, InterruptedException { - // TODO: canBus.stepMotorEnable(MId.PipetteModZM, 1); - } - - @ExtApiFn(name = "Z轴失能", group = "坐标获取工具") - public void zAxisDisable() throws HardwareException, InterruptedException { - // TODO canBus.stepMotorEnable(MId.PipetteModZM, 0); - } - - // TODO @EnginnerPageAction(name = "归零读取Z轴坐标", group = "坐标获取工具") - // public AppRet readZAxisPosByMoveToZero() throws HardwareException, InterruptedException { - // return AppRet.success(canBus.stepMotorReadPosByMoveToZeroBlock(MId.PipetteModZM, timep.getActionOvertime())); - // } - - @ExtApiFn(name = "打开扫码器", group = "坐标获取工具") - public void openCodeScaner(Boolean power) throws HardwareException, InterruptedException { - if (power) { - canBus.codeScanerStartScan(MId.PipetteModCodeScanner); - } else { - canBus.codeScanerStopScan(MId.PipetteModCodeScanner); - } - } - - Pos2d hbotRefPos = new Pos2d(0, 0); - - @ExtApiFn(name = "设置HBOT参考坐标", group = "坐标获取工具") - public void setHbotRefPos(Integer x, Integer y) throws HardwareException, InterruptedException { - hbotRefPos.x = x; - hbotRefPos.y = y; - } - - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // hbot移动到并扫码 - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - private AppRet hBotMoveToAndScan(Pos2d pos) throws HardwareException, InterruptedException { - hbotCheckAndMoveTo(pos); - canBus.codeScanerStartScan(MId.PipetteModCodeScanner); - String result = canBus.codeScanerWaittingForResult(MId.PipetteModCodeScanner, timep.getScancodeOvertime()); - return AppRet.success(result); - } - - // 扫描板夹仓二维码 - @ExtApiFn(name = "扫描板夹仓二维码", group = "扫码") - public AppRet scanPlatesCode(ConsumableGroup ch) throws HardwareException, InterruptedException { - var posInfo = pp.getPlates2dCodeScanPosInfo(); - return hBotMoveToAndScan(posInfo.cgetScanPos(ch.off)); - } - - // 扫描缓冲液二维码 - @ExtApiFn(name = "扫描缓冲液区二维码", group = "扫码") - public AppRet scanBottleBuffersCode(ConsumableGroup group) throws HardwareException, InterruptedException { - BottleGroupsPosInfo posInfo = pp.getBottleBufferPosInfo(); - return hBotMoveToAndScan(posInfo.cgetScanPos(group.ordinal())); - } - - // 扫描大缓冲液二维码 - @ExtApiFn(name = "扫描大缓冲液二维码", group = "扫码") - public AppRet scanBigBottleBufferCode(ConsumableGroup group) - throws HardwareException, InterruptedException { - LargeBottleBufferPos posInfo = pp.getLargeBottleBufferPosInfo(); - return hBotMoveToAndScan(posInfo.cgetScanPos(group.off)); - } - - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // hbot取样品 - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -// public Boolean getZPPS() throws HardwareException { - // TODO return canBus.stepMotorReadIoState(MId.PipetteModZM, 0); -// } - - public Boolean getXPPS() throws HardwareException { - return canBus.hbotReadInio(MId.HbotM, 0); - } - - public Boolean getYPPS() throws HardwareException { - return canBus.hbotReadInio(MId.HbotM, 1); - } - - public Boolean getTipPPS() throws HardwareException { - return canBus.moduleGetReg(MId.PipetteMod, RegIndex.kreg_pipette_tip_state) == 1; - } - - public String getPos() throws HardwareException { - Pos2d pos = canBus.hbotReadPos(MId.HbotM); - return pos.toString(); - } - - public String getHbotRelaPos() throws HardwareException { - Pos2d pos = canBus.hbotReadPos(MId.HbotM); - pos.x -= hbotRefPos.x; - pos.y -= hbotRefPos.y; - - return pos.toString(); - } -} diff --git a/src/main/java/a8k/service/devicectrl/ctrl/PipetteGunCtrlService.java b/src/main/java/a8k/service/devicectrl/ctrl/PipetteGunCtrlService.java deleted file mode 100644 index a917dd5..0000000 --- a/src/main/java/a8k/service/devicectrl/ctrl/PipetteGunCtrlService.java +++ /dev/null @@ -1,32 +0,0 @@ -package a8k.service.devicectrl.ctrl; - - -import jakarta.annotation.PostConstruct; -import org.slf4j.Logger; -import org.springframework.stereotype.Component; - -/** - * - * 移液枪功能 - * 1. - * - * - * - */ - -@Component -public class PipetteGunCtrlService { - static Logger logger = org.slf4j.LoggerFactory.getLogger(PipetteGunCtrlService.class); - - public Integer a; - - @PostConstruct - void init() throws NoSuchMethodException { - System.out.println("PipetteGunCtrlService init"); - } - - //取样 - - // - -} diff --git a/src/main/java/a8k/service/devicectrl/ctrl/ReactionPlatesTransmitCtrl.java b/src/main/java/a8k/service/devicectrl/ctrl/ReactionPlatesTransmitCtrl.java deleted file mode 100644 index 6a45921..0000000 --- a/src/main/java/a8k/service/devicectrl/ctrl/ReactionPlatesTransmitCtrl.java +++ /dev/null @@ -1,210 +0,0 @@ -package a8k.service.devicectrl.ctrl; - -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.utils.opt_algo.A8kOptAlgo; -import a8k.type.*; -import a8k.type.appret.AppRet; -import a8k.controler.extapi.utils.*; -import a8k.hardware.A8kCanBusService; -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.hardware.type.a8kcanprotocol.IOId; -import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.hardware.type.regindex.RegIndex; -import a8k.service.devicectrl.param.DebugParam; -import a8k.service.devicectrl.param.PosParam; -import a8k.service.devicectrl.param.TimeParam; -import jakarta.annotation.Resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.List; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.ReactionPlatesTransmitCtrl) -public class ReactionPlatesTransmitCtrl { - static Logger logger = LoggerFactory.getLogger(ReactionPlatesTransmitCtrl.class); - EnginnerParamReader hpReader = new EnginnerParamReader(ReactionPlatesTransmitCtrl.class); - - - @Resource - A8kCanBusService canBus; - @Resource - TimeParam timep; - @Resource - PosParam pp; - @Resource - DebugParam dp; - - - public void checkBeforeMoveTrunable() throws HardwareException { - //板夹仓卡板检测 - if (canBus.getIOState(IOId.PlateBoxPlateStuckPPS)) { - logger.error("PlateBoxPlateStuckPPS is trigger"); - throw new HardwareException(A8kEcode.PlateStuckDetectorSensorTrigger.index); - } - - //检查钩板电机是否处于终点位置 - if (!canBus.getIOState(IOId.PullerMZeroPPS)) { - logger.error("PullerM is not in zero pos"); - throw new HardwareException(A8kEcode.PullerMInitPosError.index); - } - - //检查板夹仓光电是否处于起点位置 - if (!canBus.getIOState(IOId.PusherMZeroPPS)) { - logger.error("PusherM is not in zero pos"); - throw new HardwareException(A8kEcode.PusherMInitPosError.index); - } - } - - public void checkBeforeMovePlateBox() throws HardwareException { - if (!canBus.getIOState(IOId.PusherMZeroPPS)) { - logger.error("PusherM is not in zero pos "); - throw new HardwareException(A8kEcode.PusherMInitPosError.index); - } - } - - public void modGroupMoveToZeroQuick() throws HardwareException, InterruptedException { - //光学模组初始化 - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.OptModPullM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.OptModScannerM, timep.getActionOvertime()); - - //板夹仓初始化 - checkBeforeMovePlateBox(); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxPusherM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxYM, timep.getActionOvertime()); - - //转盘归零 - checkBeforeMoveTrunable(); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.IncubatorRotateCtrlM, timep.getActionOvertime()); - } - - private void trunableMoveTo(Integer pos) throws HardwareException, InterruptedException { - checkBeforeMoveTrunable(); - //限制pos在 0--> 36000之间 - pos = pos % 36000; - if (pos < 0) { - pos += 36000; - } - - //先移动半个间距,用来检测是否发生卡板 - Integer nowPos = canBus.stepMotorReadPos(MId.IncubatorRotateCtrlM); - if (nowPos < pos) { - canBus.stepMotorEasyMoveByBlock(MId.IncubatorRotateCtrlM, pp.getTurntablePosSpacing(), timep.getActionOvertime()); - } else if (nowPos > pos) { - canBus.stepMotorEasyMoveByBlock(MId.IncubatorRotateCtrlM, -pp.getTurntablePosSpacing(), timep.getActionOvertime()); - } - - //解决齿轮间隙的问题 - if (nowPos < pos) { - canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos, timep.getActionOvertime()); - } else { - canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos - 300/**/, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos, timep.getActionOvertime()); - } - } - - /* ======================================================================================= - 基础操作 - =======================================================================================*/ - - @ExtApiFn(name = "转盘移动到推板位", group = "单步") - public void trunableMoveToPushPos(IncubatorPos index) throws HardwareException, InterruptedException { - trunableMoveTo(pp.getTurntablePushPos0() + index.off * pp.getTurntablePosSpacing()); - } - - @ExtApiFn(name = "转盘移动到出板位", group = "单步") - public void trunableMoveToPullPos(IncubatorPos index) throws HardwareException, InterruptedException { - trunableMoveTo(pp.getTurntablePullPos0() + index.off * pp.getTurntablePosSpacing()); - - } - - @ExtApiFn(name = "转盘移动到滴定位", group = "单步") - public void trunableMoveToDropLiquidPos(IncubatorPos index) throws HardwareException, InterruptedException { - trunableMoveTo(pp.getTurntableDropLiquidPos0() + index.off * pp.getTurntablePosSpacing()); - } - - - @ExtApiFn(name = "推板", group = "单步") - public AppRet pushPlate(ConsumableGroup PBCh, IncubatorPos turntablePosIndex) throws HardwareException, InterruptedException { - trunableMoveToPushPos(turntablePosIndex); - canBus.stepMotorEasyMoveToBlock(MId.PlatesBoxYM, pp.getPBCh0Pos() + PBCh.off * pp.getPBChSpacing(), timep.getActionOvertime()); - canBus.plateCodeScanerPushCardAndScanBlock(MId.PlatesBoxScanner, pp.getPusherEndPos(), 10000); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxPusherM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxYM, timep.getActionOvertime()); - return AppRet.success(canBus.plateCodeScannerReadCode(MId.PlatesBoxScanner)); - } - - public void pushPlateQuick(ConsumableGroup PBCh, IncubatorPos turntablePosIndex) throws HardwareException, InterruptedException { - trunableMoveToPushPos(turntablePosIndex); - canBus.stepMotorEasyMoveToBlock(MId.PlatesBoxYM, pp.getPBCh0Pos() + PBCh.off * pp.getPBChSpacing(), timep.getActionOvertime()); - canBus.stepMotorEasyMoveToBlock(MId.PlatesBoxPusherM, pp.getPusherEndPos(), timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxPusherM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxYM, timep.getActionOvertime()); - } - - - @ExtApiFn(name = "拉板", group = "单步操作") - public void pullPlate(IncubatorPos turntablePosIndex) throws HardwareException, InterruptedException { - trunableMoveToPullPos(turntablePosIndex); - canBus.stepMotorEasyMoveToBlock(MId.OptModScannerM, pp.getOptScanScandbyPos(), timep.getActionOvertime()); - canBus.stepMotorEasyMoveToBlock(MId.OptModPullM, pp.getPullerTargetPos(), timep.getActionOvertime()); - if (!canBus.getIOState(IOId.PullerMEndPPS)) { - logger.error("pull plate fail"); - throw new HardwareException(A8kEcode.PullPlateFail.index); - } - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.OptModPullM, timep.getActionOvertime()); - } - - @ExtApiFn(name = "丢板", group = "单步操作") - public void dropPlate() throws HardwareException, InterruptedException { - canBus.stepMotorEasyMoveToBlock(MId.OptModScannerM, pp.getPlateDropPos(), timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.OptModScannerM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToBlock(MId.OptModScannerM, pp.getOptScanScandbyPos(), timep.getActionOvertime()); - } - - // @EnginnerPageAction(name = "显示板夹扫码原始曲线", group = "辅助调试") - // public AppRet readPlateScanCurve() throws HardwareException, InterruptedException { - // List scanDataCurve = canBus.plateCodeScanerReadRawResult(MId.PlatesBoxScanner); - // List refLine = new ArrayList<>(); - // for (int i = 0; i < 15; i++) { - // refLine.add(i * 12 + 6); - // } - // return AppRet.success(new A8kScanCurve(scanDataCurve, refLine)); - // } - - private AppRet packetOptDisplayScanCurve(List scanDataCurve) { - A8kScanCurve scanCurve = new A8kScanCurve(); - logger.info("pointNum: " + scanDataCurve.size()); - scanCurve.scanDataCurve = A8kOptAlgo.preProcessOptData(scanDataCurve); - logger.info("pointNum: " + scanCurve.scanDataCurve.size()); - scanCurve.refCurve = A8kOptAlgo.preProcessOptData(scanDataCurve); - scanCurve.refLine = new ArrayList<>(); - for (int i = 1; i < 6; i++) { - scanCurve.refLine.add(40 * i); - } - return AppRet.success(scanCurve); - } - - @ExtApiFn(name = "T光学扫码", group = "光学调试") - public AppRet optTScan(OptScanDirection direction, Integer scanerGain) throws HardwareException, InterruptedException { - // canBus.moduleSetReg(MId.OptMod, RegIndex.kreg_a8k_opt_t_pos_offset, getTOptPosOffset()); - // canBus.moduleSetReg(MId.OptMod, RegIndex.kreg_a8k_opt_t_reverse_scan_pos_offset,getTOptPosOffset()-1200); - // canBus.optTStartScanBlock(MId.OptMod, direction, getOptTLasterGain(), scanerGain, getOptScanOvertime()); - // return packetOptDisplayScanCurve(canBus.optReadRaw(MId.OptMod)); - return AppRet.fail(A8kEcode.CmdNotSupport.index); - } - - @ExtApiFn(name = "F光学扫码", group = "光学调试") - public AppRet optFScan(OptScanDirection direction, Integer scanerGain) throws HardwareException, InterruptedException { - //getFOptPosOffset - canBus.moduleSetReg(MId.OptMod, RegIndex.kreg_a8k_opt_f_pos_offset, pp.getFOptPosOffset()); - canBus.moduleSetReg(MId.OptMod, RegIndex.kreg_a8k_opt_f_reverse_scan_pos_offset, pp.getFOptPosOffset() - 1200); - - canBus.optFStartScanBlock(MId.OptMod, direction, pp.getOptFLasterGain(), scanerGain, timep.getOptScanOvertime()); - return packetOptDisplayScanCurve(canBus.optReadRaw(MId.OptMod)); - } - - -} diff --git a/src/main/java/a8k/service/devicectrl/ctrl/SamplesPreProcesCtrl.java b/src/main/java/a8k/service/devicectrl/ctrl/SamplesPreProcesCtrl.java deleted file mode 100644 index 4f3f75b..0000000 --- a/src/main/java/a8k/service/devicectrl/ctrl/SamplesPreProcesCtrl.java +++ /dev/null @@ -1,268 +0,0 @@ -package a8k.service.devicectrl.ctrl; - -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.type.HardwareException; -import a8k.type.appret.AppRet; -import a8k.controler.extapi.utils.*; -import a8k.hardware.A8kCanBusService; -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.service.devicectrl.param.DebugParam; -import a8k.service.devicectrl.param.TimeParam; -import a8k.service.devicectrl.param.PosParam; -import a8k.utils.ZEQ; -import jakarta.annotation.Resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.SamplesPreProcesCtrl) -public class SamplesPreProcesCtrl { - static Logger logger = LoggerFactory.getLogger(SamplesPreProcesCtrl.class); - - static class ORDER { - - static final int moduleReset = 1; - static final int moduleEnable = 2; - static final int moduleDisable = 3; - static final int takeTubeAndJudgeTubeExist = 4; - static final int shakeTube = 5; - static final int takeTubeCap = 6; - static final int pushBackTubeCapAndTakeBakTube = 7; - static final int setAeroslFanPower = 8; - } - - @Resource - A8kCanBusService canBus; - @Resource - TimeParam timep; - @Resource - PosParam pp; - @Resource - DebugParam dp; - - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // PRIVATE - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - private void modGroupMoveToZero() throws HardwareException, InterruptedException { - - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperClosePos(), timep.getActionOvertime()); - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperZeroYPos(), timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModClampingM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModShakeM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToBlock(MId.ShakeModShakeM, 90, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, -2, timep.getActionOvertime()); - } - - - private void modGroupMoveToZeroQuick() throws HardwareException, InterruptedException { - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModClampingM, timep.getActionOvertime()); - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModShakeM, timep.getActionOvertime()); - modGroupMoveToZero(); - } - - @ExtApiFn(name = "模块复位", group = "辅助调试", order = ORDER.moduleReset) - public void moduleReset() throws HardwareException, InterruptedException { - modGroupMoveToZero(); - } - - @ExtApiFn(name = "模块使能", group = "辅助调试", order = ORDER.moduleEnable) - public void moduleEnable() throws HardwareException, InterruptedException { - canBus.miniServoEnable(MId.ShakeModGripperSV, 1); - canBus.miniServoEnable(MId.ShakeModGripperYSV, 1); - canBus.stepMotorEnable(MId.ShakeModClampingM, 1); - canBus.stepMotorEnable(MId.ShakeModGripperZM, 1); - canBus.stepMotorEnable(MId.ShakeModShakeM, 1); - canBus.stepMotorEnable(MId.ShakeModShakeM, 1); - } - - @ExtApiFn(name = "模块失能", group = "辅助调试", order = ORDER.moduleDisable) - public void moduleDisable() throws HardwareException, InterruptedException { - canBus.stepMotorEnable(MId.ShakeModClampingM, 1); - canBus.stepMotorEasyMoveByBlock(MId.ShakeModClampingM, 10, timep.getActionOvertime()); - - - canBus.miniServoEnable(MId.ShakeModGripperSV, 0); - canBus.miniServoEnable(MId.ShakeModGripperYSV, 0); - canBus.stepMotorEnable(MId.ShakeModClampingM, 0); - canBus.stepMotorEnable(MId.ShakeModGripperZM, 0); - canBus.stepMotorEnable(MId.ShakeModShakeM, 0); - canBus.stepMotorEnable(MId.ShakeModShakeM, 0); - } - - @ExtApiFn(name = "夹紧试管", group = "辅助调试", order = ORDER.moduleDisable) - public void clampTube() throws HardwareException, InterruptedException { - canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, pp.getShakeClampingPos(), timep.getActionOvertime()); - } - - - void tryClampTube() throws HardwareException, InterruptedException { - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos() - 20, timep.getActionOvertime()); - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos(), timep.getActionOvertime()); - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos() - 20, timep.getActionOvertime()); - } - - /** - * 取试管帽,如果试管帽存在, - * @param highTube true/false - */ - @ExtApiFn(name = "取试管", group = "单步", order = ORDER.takeTubeAndJudgeTubeExist) - public AppRet takeTubeAndJudgeTubeExist(Boolean highTube) throws HardwareException, InterruptedException { - /* - * 校验: - * 1.当前摇匀模组设计到的电机是否都处于待机位 - */ - - //Z轴在原点 - if (!canBus.stepMotorReadIoState(MId.ShakeModGripperZM, 0)) { - throw new HardwareException(MId.ShakeModGripperZM, A8kEcode.MNotInZeroPos.index); - } - - //Y轴在零点附近 - if (!ZEQ.IntEq(canBus.miniServoReadPos(MId.ShakeModGripperYSV), pp.getGripperZeroYPos(), 30)) { - throw new HardwareException(MId.ShakeModGripperYSV, A8kEcode.MNotInZeroPos.index); - } - - //夹爪没有零位置 - if (!ZEQ.IntEq(canBus.miniServoReadPos(MId.ShakeModGripperSV), pp.getGripperClosePos(), 30)) { - throw new HardwareException(MId.ShakeModGripperSV, A8kEcode.MNotInZeroPos.index); - } - - //检查摇匀夹紧是否在零位 - if (!canBus.stepMotorReadIoState(MId.ShakeModClampingM, 0)) { - throw new HardwareException(MId.ShakeModClampingM, A8kEcode.MNotInZeroPos.index); - } - - boolean isHighBlood = highTube; - boolean tubeCapExist = true; - Integer gripperJudgeCapZPos = isHighBlood ? pp.getGripperJudgeHTubeCapZPos() : pp.getGripperJudgeSTubeCapZPos(); - Integer gripperTakeTubeZPos = isHighBlood ? pp.getGripperTakeHTubeZPos() : pp.getGripperTakeSTubeZPos(); - Integer gripperShakeZPos = pp.getGripperShakeTubeZPos(); - - //固定试管架 - canBus.miniServoMoveToBlock(MId.ShakeModTubeScanerClampingSV, 900, timep.getActionOvertime()); - //试管夹紧移动到终点位置 - canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, 70, timep.getActionOvertime()); - //试管摇匀移动到90度 - canBus.stepMotorEasyMoveToBlock(MId.ShakeModShakeM, pp.getShakeModShakeMStandbyPos(), timep.getActionOvertime()); - //Y轴向前移动 - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperTakeTubeYPos(), timep.getActionOvertime()); - //打开夹爪 - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); - // //Z轴下移动到试管帽有无检测位 - // canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, gripperJudgeCapZPos, timep.getActionOvertime()); - //闭合夹爪检测试管帽是否存在 - // canBus.miniServoRotateWithTorque(MId.ShakeModGripperSV, -400); - // Thread.sleep(timep.getTubeCapJudgeDelayTime()); - // if (ZEQ.IntEq(canBus.miniServoReadPos(MId.ShakeModGripperSV), pp.getGripperClosePos(), 30)) { - // logger.info("试管帽不存在"); - // tubeCapExist = false; - // } - if (dp.getDebugMode() || tubeCapExist) { - //打开夹爪 - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); - //Z轴下移动到取试管位置 - canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, gripperTakeTubeZPos, timep.getActionOvertime()); - //夹爪夹紧 - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos(), timep.getActionOvertime()); - canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, gripperTakeTubeZPos - 100, timep.getActionOvertime()); - tryClampTube(); - - //Z轴上移动到零位 - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); - //夹爪夹紧 - //Y轴移动到摇匀位 - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperShakeYPos() - 50, timep.getActionOvertime()); //该动作是为了消除齿轮间隙 - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperShakeYPos(), timep.getActionOvertime()); - //Z轴下移动到摇匀位放试管的位置 - canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, gripperShakeZPos, timep.getActionOvertime()); - //夹紧试管 - canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, pp.getShakeClampingPos(), timep.getActionOvertime()); - //松开夹爪,放置试管 - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); - //Z轴上移动到零位 - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); - //Z轴归零,校准一次位置 - canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); - //Y轴移动到零位 - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperZeroYPos(), timep.getActionOvertime()); - } else { - modGroupMoveToZeroQuick(); - } - return AppRet.success(tubeCapExist); - } - - @ExtApiFn(name = "摇匀", group = "单步", order = ORDER.shakeTube) - public void shakeTube(Integer shakeDegree, Integer times) throws HardwareException, InterruptedException { - var standByPos = pp.getShakeModShakeMStandbyPos(); - var startPos = standByPos - shakeDegree; - var endPos = standByPos + shakeDegree; - canBus.stepMotorEasyReciprocatingMotion(MId.ShakeModShakeM, startPos, endPos, times); - canBus.waitForMod(MId.ShakeModShakeM, timep.getActionOvertime()); - } - - @ExtApiFn(name = "取试管帽", group = "单步", order = ORDER.takeTubeCap) - public void takeTubeCap() throws HardwareException, InterruptedException { - //Y移动到取试管帽位置 - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperShakeYPos(), timep.getActionOvertime()); - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); - //Z下移动到取试管帽位置 - canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, pp.getGripperTakeCapZPos() + 3, timep.getActionOvertime()); - //闭合夹爪 - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos(), timep.getActionOvertime()); - //Z上移动到零位 - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); - // tryClampTube(); - // canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperTakeCapPos()-30, timep.getActionOvertime()); - - - //Y移动到待机位 - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperZeroYPos(), timep.getActionOvertime()); - } - - /** - * 盖试管帽,并将试管移动回试管架中 - */ - @ExtApiFn(name = "盖试管帽并放回试管架", group = "单步", order = ORDER.pushBackTubeCapAndTakeBakTube) - public void pushBackTubeCapAndTakeBakTube() throws HardwareException, InterruptedException { - //移动Y轴到取试管帽位置 - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperShakeYPos(), timep.getActionOvertime()); - //移动Z轴盖帽 - canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, pp.getGripperTakeCapZPos() + 20, timep.getActionOvertime()); - //打开试管夹 - canBus.stepMotorEasyMoveToBlock(MId.ShakeModClampingM, 70, timep.getActionOvertime()); - //移动Z轴到零位 - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); - - tryClampTube(); - - - //移动Y轴到方式管的位置 - canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, pp.getGripperTakeTubeYPos(), timep.getActionOvertime()); - //移动Z轴到取试管位置 - canBus.stepMotorEasyMoveToBlock(MId.ShakeModGripperZM, pp.getGripperTakeHTubeZPos() - 20, timep.getActionOvertime()); - //打开夹爪 - canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, pp.getGripperOpenPos(), timep.getActionOvertime()); - //Z轴上移动到零位 - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.ShakeModGripperZM, timep.getActionOvertime()); - //设备快速归零 - modGroupMoveToZeroQuick(); - } - - /** - * 气溶胶风扇控制 - */ - @ExtApiFn(name = "气溶胶风扇控制", group = "其他", order = ORDER.setAeroslFanPower) - public void setAeroslFanPower(Boolean enable) throws Exception { - if (enable) { - canBus.fanControlerSetSpeed(MId.WbTubeFanMod, 99); - } else { - canBus.fanControlerSetSpeed(MId.WbTubeFanMod, 0); - } - } -} diff --git a/src/main/java/a8k/service/devicectrl/ctrl/TubeRackMoveCtrl.java b/src/main/java/a8k/service/devicectrl/ctrl/TubeRackMoveCtrl.java deleted file mode 100644 index 38fae2a..0000000 --- a/src/main/java/a8k/service/devicectrl/ctrl/TubeRackMoveCtrl.java +++ /dev/null @@ -1,298 +0,0 @@ -package a8k.service.devicectrl.ctrl; - -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.type.HardwareException; -import a8k.type.TargetPosMeasureDirection; -import a8k.type.appret.AppRet; -import a8k.controler.extapi.utils.*; -import a8k.hardware.A8kCanBusService; -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.hardware.type.a8kcanprotocol.IOId; -import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.service.devicectrl.param.DebugParam; -import a8k.service.devicectrl.param.PosParam; -import a8k.service.devicectrl.param.TimeParam; -import jakarta.annotation.Resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.TubeRackMoveCtrl) -public class TubeRackMoveCtrl { - static Logger logger = LoggerFactory.getLogger(TubeRackMoveCtrl.class); - - static class ORDER { - static final int moveTubeRackTo = 1; - static final int scanClampModClamp = 2; - static final int scanClampModRelease = 3; - static final int tryEnterTubeRack = 4; - static final int tryEjectTubeRack = 5; - static final int tubeRackMoveToEnterPos = 6; - static final int moveTubeRackToExitPos = 7; - static final int moveTubeRackToScanPos = 8; - static final int moveTubeToScanPosAndScan = 9; - static final int moveTubeToPreProcessPos = 10; - static final int moveTubeToAltitJudgXPos = 11; - static final int judgeTubeExist = 12; - - } - - @Resource - private A8kCanBusService canBus; - @Resource - TimeParam timep; - @Resource - PosParam pp; - @Resource - DebugParam dp; - - - private Boolean isTubeExist() throws HardwareException { - return canBus.getIOState(IOId.TubeExistPPS); - } - - private Boolean isTubeRackInEnterPos() throws HardwareException { - return canBus.getIOState(IOId.InfeedPPS); - } - - private Boolean isTubeRackInExitPos() throws HardwareException { - return canBus.getIOState(IOId.OutfeedPPS); - } - - private Boolean isHighTube() throws HardwareException { - return canBus.getIOState(IOId.TubeHeightPPS); - } - - - /** - * 移动试管到扫码位置 - * @param tubeIndex 试管索引 - */ - private void moveTubeToScanPos(Integer tubeIndex) throws HardwareException, InterruptedException { - var scanPos = pp.getTScanXPos() + tubeIndex * pp.getTubeSpacing(); - scanClampModClamp(); - moveTubeRackTo(scanPos, TargetPosMeasureDirection.NEGATIVE, false); - } - - /** - * 移动<试管架>到试管架扫码位置 - */ - private void moveTubeRackToScanPos() throws HardwareException, InterruptedException { - moveTubeRackTo(pp.getTRScanXPos(), TargetPosMeasureDirection.POSITIVE, false); - } - - /*========================================================================================= - * 基础方法 - *========================================================================================*/ - - /** - * 移动试管架到指定位置 - * @param pos 指定位置 - * @throws HardwareException 硬件异常 - * @throws InterruptedException 打断异常 - */ - @ExtApiFn(name = "移动到坐标", group = "基础方法", order = ORDER.moveTubeRackTo) - public void moveTubeRackTo(Integer pos, TargetPosMeasureDirection moveDiretion, Boolean moveToZero) throws HardwareException, InterruptedException { - if (!canBus.stepMotorReadIoState(MId.ShakeModGripperZM, 0)) { - throw new HardwareException(A8kEcode.ShakeModGripperZMNotInZeroPos.index); - } - //打开扫码夹具 - scanClampModRelease(); - - //使能电机 - canBus.stepMotorEnable(MId.FeedingModXM, 1); - if (moveToZero) { - canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.FeedingModXM, timep.getActionOvertime()); - } - - // 处理试管架和试管架之间的间隙导致的运行位置误差 - Integer nowPos = canBus.stepMotorReadPos(MId.FeedingModXM); - if (TargetPosMeasureDirection.POSITIVE.equals(moveDiretion)) { - if (nowPos > (pos + 1)) { - canBus.stepMotorEasyMoveToBlock(MId.FeedingModXM, pos + 30, timep.getActionOvertime()); - } - } else if (TargetPosMeasureDirection.NEGATIVE.equals(moveDiretion)) { - if (nowPos < (pos - 1)) { - canBus.stepMotorEasyMoveToBlock(MId.FeedingModXM, pos - 30, timep.getActionOvertime()); - } - } - canBus.stepMotorEasyMoveToBlock(MId.FeedingModXM, pos, timep.getActionOvertime()); - - } - - /** - * 扫描夹紧机构夹紧 - */ - @ExtApiFn(name = "扫描夹紧机构夹紧", group = "基础方法", order = ORDER.scanClampModClamp) - public void scanClampModClamp() throws HardwareException, InterruptedException { - canBus.miniServoEnable(MId.ShakeModTubeScanerClampingSV, 1); - canBus.miniServoMoveTo(MId.ShakeModTubeScanerClampingSV, 900); - canBus.waitForMod(MId.ShakeModTubeScanerClampingSV, timep.getActionOvertime()); - } - - /** - * 扫描夹紧机构复位 - */ - @ExtApiFn(name = "扫描夹紧机构复位", group = "基础方法", order = ORDER.scanClampModRelease) - public void scanClampModRelease() throws HardwareException, InterruptedException { - canBus.miniServoEnable(MId.ShakeModTubeScanerClampingSV, 1); - canBus.miniServoMoveTo(MId.ShakeModTubeScanerClampingSV, 0); - canBus.waitForMod(MId.ShakeModTubeScanerClampingSV, timep.getActionOvertime()); - } - - - public Boolean getTHchOuterPPS() throws HardwareException { - return canBus.getIOState(IOId.THChOuterPPS); - } - - public Boolean getTHchInterPPS() throws HardwareException { - return canBus.getIOState(IOId.THChInterPPS); - } - - - /*========================================================================================= - * 片段 - *========================================================================================*/ - - /** - * 移动试管架到入口位置 - */ - private void tubeRackMoveToEnterPos() throws HardwareException, InterruptedException { - moveTubeRackTo(pp.getTREnterXPos(), TargetPosMeasureDirection.NOTCARE, true); - } - - /** - * 移动<试管架>到出口位置 - */ - private void moveTubeRackToExitPos() throws HardwareException, InterruptedException { - moveTubeRackTo(pp.getTRExitXPos(), TargetPosMeasureDirection.NOTCARE, false); - moveTubeRackTo(pp.getTRExitXPos() - 10, TargetPosMeasureDirection.NOTCARE, false); - } - - /** - * 移动<试管架>到出口位置 - */ - @ExtApiFn(name = "入料", group = "单步", order = ORDER.moveTubeRackToExitPos) - public void enterTubeHolder() throws HardwareException, InterruptedException { - if (getTHchInterPPS() || getTHchOuterPPS()) { - throw new HardwareException(A8kEcode.TubeXChannelIsNotEmpty.index); - } - tubeRackMoveToEnterPos(); - try { - canBus.stepMotorEasyRotate(MId.FeedingModInfeedM, -1); - for (int i = 0; i < timep.getInfeedOvertime() / 100; i++) { - Thread.sleep(100); - if (getTHchInterPPS()) { - break; - } - } - Thread.sleep(1000); - canBus.stepMotorStop(MId.FeedingModInfeedM); - if (!getTHchInterPPS()) { - throw new HardwareException(A8kEcode.InfeedOvertimeFail.index); - } - } finally { - canBus.moduleStop(MId.FeedingModInfeedM); - } - } - - @ExtApiFn(name = "出料", group = "单步", order = ORDER.moveTubeRackToExitPos) - public void ejectTubeHolder() throws HardwareException, InterruptedException { - moveTubeRackToExitPos(); - try { - canBus.stepMotorEasyRotate(MId.FeedingModOutfeedM, 1); - for (int i = 0; i < timep.getOutfeedOvertime() / 100; i++) { - Thread.sleep(100); - logger.info("getTHchInterPPS:{} getTHchOuterPPS:{}", getTHchInterPPS(), getTHchOuterPPS()); - if (!getTHchInterPPS() && !getTHchOuterPPS()) { - break; - } - } - Thread.sleep(1000); - canBus.stepMotorStop(MId.FeedingModOutfeedM); - if (getTHchInterPPS() || getTHchOuterPPS()) { - throw new HardwareException(A8kEcode.OutfeedOvertimeFail.index); - } - } finally { - canBus.moduleStop(MId.FeedingModOutfeedM); - } - } - - /** - * 移动试管架到扫码并扫码 - */ - @ExtApiFn(name = "扫描<试管架>编码", group = "单步扫码", order = ORDER.moveTubeRackToScanPos) - public AppRet moveTubeRackToScanPosAndScan() throws HardwareException, InterruptedException { - String result; - moveTubeRackToScanPos(); - - scanClampModClamp(); - canBus.codeScanerStartScan(MId.FeedingModScannerMod); - result = canBus.codeScanerWaittingForResult(MId.FeedingModScannerMod, 1000); - scanClampModRelease(); - if (result == null || result.isEmpty()) { - return AppRet.fail(A8kEcode.ScanTimeout.index); - } - return AppRet.success(result); - } - // - // 试管移动 - // - - /** - * 移动试管到扫码位置,并扫码 - * @param tubeIndex 试管索引 - */ - @ExtApiFn(name = "扫描<试管X>编码", group = "单步扫码", order = ORDER.moveTubeToScanPosAndScan) - public AppRet moveTubeToScanPosAndScan(Integer tubeIndex) throws HardwareException, InterruptedException { - moveTubeToScanPos(tubeIndex); - try { - scanClampModClamp(); - - canBus.codeScanerStartScan(MId.FeedingModScannerMod); - canBus.miniServoRotateWithTorque(MId.ShakeModTubeScanerClampingSV, pp.getTubeScanServoTorque()); - String result = canBus.codeScanerWaittingForResult(MId.FeedingModScannerMod, pp.getTubeScanOvertime()); - if (result == null || result.isEmpty()) { - return AppRet.fail(A8kEcode.ScanTimeout.index); - } - return AppRet.success(result); - } finally { - canBus.moduleStop(MId.ShakeModTubeScanerClampingSV); - canBus.moduleStop(MId.FeedingModScannerMod); - scanClampModRelease(); - } - } - - /** - * 移动试管到试管预处理的位置 - * @param tubeIndex 试管索引 - */ - @ExtApiFn(name = "移动<试管N>摇匀位", group = "单步-处理", order = ORDER.moveTubeToPreProcessPos) - public void moveTubeToPreProcessPos(Integer tubeIndex) throws HardwareException, InterruptedException { - moveTubeRackTo(pp.getTPreProcessXPos() + tubeIndex * pp.getTubeSpacing(), TargetPosMeasureDirection.POSITIVE, false); - } - - /** - * 移动试管到试管高低判断位置 - * @param tubeIndex 试管索引 - */ - @ExtApiFn(name = "判断<试管N>高低", group = "单步-其他", order = ORDER.moveTubeToAltitJudgXPos) - public AppRet moveTubeToAltitJudgXPos(Integer tubeIndex) throws HardwareException, InterruptedException { - moveTubeRackTo(pp.getTAltitJudgXPos() + tubeIndex * pp.getTubeSpacing(), TargetPosMeasureDirection.NEGATIVE, false); - return AppRet.success(isHighTube()); - } - - - /** - * 移动试管到试管有无判断位置 - * @param tubeIndex 试管索引 - */ - @ExtApiFn(name = "判断<试管N>是否存在", group = "单步-其他", order = ORDER.judgeTubeExist) - public AppRet judgeTubeExist(Integer tubeIndex) throws HardwareException, InterruptedException { - moveTubeRackTo(pp.getTExistJudgXPos() + tubeIndex * pp.getTubeSpacing(), TargetPosMeasureDirection.NEGATIVE, false); - return AppRet.success(isTubeExist()); - } - - -} diff --git a/src/main/java/a8k/service/devicectrl/param/DebugParam.java b/src/main/java/a8k/service/devicectrl/param/DebugParam.java deleted file mode 100644 index 48acc17..0000000 --- a/src/main/java/a8k/service/devicectrl/param/DebugParam.java +++ /dev/null @@ -1,29 +0,0 @@ -package a8k.service.devicectrl.param; - -import a8k.controler.extapi.utils.ExtApiTab; -import a8k.controler.extapi.utils.ExtApiFn; -import a8k.controler.extapi.utils.EnginnerPageStatu; -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import org.springframework.stereotype.Component; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.DebugParam) -public class DebugParam { - - Boolean debugMode = false; - - @ExtApiFn(name = "使能调试模式", order = 1) - public void enableDebugMode() { - debugMode = true; - } - - @ExtApiFn(name = "禁用调试模式", order = 2) - public void disableDebugMode() { - debugMode = false; - } - - @EnginnerPageStatu(name = "调试模式") - public Boolean getDebugMode() { - return debugMode; - } -} diff --git a/src/main/java/a8k/service/devicectrl/param/PosParam.java b/src/main/java/a8k/service/devicectrl/param/PosParam.java deleted file mode 100644 index 138038a..0000000 --- a/src/main/java/a8k/service/devicectrl/param/PosParam.java +++ /dev/null @@ -1,392 +0,0 @@ -package a8k.service.devicectrl.param; - -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.type.cfg.*; -import a8k.controler.extapi.utils.*; -import org.springframework.stereotype.Component; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.PosParam) -public class PosParam { - EnginnerParamReader hpReader = new EnginnerParamReader(PosParam.class); - - class ORDER { - static final int getGripperOpenPos = 1; - static final int getGripperClosePos = 2; - static final int getGripperTakeCapPos = 3; - static final int getGripperTakeTubeYPos = 4; - static final int getGripperShakeYPos = 5; - static final int getGripperZeroYPos = 6; - static final int getGripperTakeHTubeZPos = 7; - static final int getGripperTakeSTubeZPos = 8; - static final int getGripperJudgeHTubeCapZPos = 9; - static final int getGripperJudgeSTubeCapZPos = 10; - static final int getGripperShakeTubeZPos = 11; - static final int getGripperTakeCapZPos = 12; - static final int getShakeClampingPos = 13; - static final int getShakeModShakeMStandbyPos = 14; - static final int getTREnterXPos = 15; - static final int getTRExitXPos = 16; - static final int getTRScanXPos = 17; - static final int getTScanXPos = 18; - static final int getTAltitJudgXPos = 19; - static final int getTExistJudgXPos = 20; - static final int getTPreProcessXPos = 21; - static final int getTubeSpacing = 22; - static final int getTubeScanServoTorque = 23; - static final int getTubeScanOvertime = 24; - static final int getPBCh0Pos = 25; - static final int getPBChSpacing = 26; - static final int getPusherEndPos = 27; - static final int getPusherScanStartPos = 28; - static final int getTurntablePushPos0 = 29; - static final int getTurntablePullPos0 = 30; - static final int getTurntableDropLiquidPos0 = 31; - static final int getTurntablePosSpacing = 32; - static final int getPullerTargetPos = 33; - static final int getPlateDropPos = 34; - static final int getOptScanScandbyPos = 35; - static final int getTOptPosOffset = 36; - static final int getFOptPosOffset = 37; - static final int getOptTLasterGain = 38; - static final int getOptFLasterGain = 39; - static final int getEmergencyPos = 40; - static final int getTipPickUpPosInfo = 41; - static final int getTipDropPos = 42; - static final int getReactionPos = 43; - static final int getBottleBufferPosInfo = 44; - static final int getPlates2dCodeScanPosInfo = 45; - static final int getLargeBottleBufferPosInfo = 46; - static final int getSampleCollectionArea = 47; - } - - - // - // SamplesPreProcessModuleCtrlService - // - - @EnginnerPageParam(name = "抓手张开位置", group = "抓手", order = ORDER.getGripperOpenPos) - public Integer getGripperOpenPos() { - return hpReader.getInteger("GripperOpenPos", 450); - } - - @EnginnerPageParam(name = "抓手闭合位置", group = "抓手", order = ORDER.getGripperClosePos) - public Integer getGripperClosePos() { - return hpReader.getInteger("GripperClosePos", 310); - } - - @EnginnerPageParam(name = "抓手取试管位置", group = "抓手", order = ORDER.getGripperTakeCapPos) - public Integer getGripperTakeCapPos() { - return hpReader.getInteger("GripperTakeCapPos", 355); - } - - @EnginnerPageParam(name = "取试管位置", group = "抓手Y轴位置", order = ORDER.getGripperTakeTubeYPos) - public Integer getGripperTakeTubeYPos() { - return hpReader.getInteger("GripperTakeTubeYPos", 3080); - } - - @EnginnerPageParam(name = "摇匀位置", group = "抓手Y轴位置", order = ORDER.getGripperShakeYPos) - public Integer getGripperShakeYPos() { - return hpReader.getInteger("GripperShakeYPos", 2130); - } - - @EnginnerPageParam(name = "待机位", group = "抓手Y轴位置", order = ORDER.getGripperZeroYPos) - public Integer getGripperZeroYPos() { - return hpReader.getInteger("GripperZeroYPos", 300); - } - - - @EnginnerPageParam(name = "取高试管位置", group = "抓手Z轴位置", order = ORDER.getGripperTakeHTubeZPos) - public Integer getGripperTakeHTubeZPos() { - return hpReader.getInteger("GripperTakeHTubeZPos", 739); - } - - @EnginnerPageParam(name = "取低试管位置", group = "抓手Z轴位置", order = ORDER.getGripperTakeSTubeZPos) - public Integer getGripperTakeSTubeZPos() { - return hpReader.getInteger("GripperTakeSTubeZPos", 983); - } - - //JudgeTubeCapZ - @EnginnerPageParam(name = "高试管帽有无判断位", group = "抓手Z轴位置", order = ORDER.getGripperJudgeHTubeCapZPos) - public Integer getGripperJudgeHTubeCapZPos() { - return hpReader.getInteger("GripperJudgeHTubeCapZPos", 591); - } - - @EnginnerPageParam(name = "低试管帽有无判断位", group = "抓手Z轴位置", order = ORDER.getGripperJudgeSTubeCapZPos) - public Integer getGripperJudgeSTubeCapZPos() { - return hpReader.getInteger("GripperJudgeSTubeCapZPos", 867); - } - - //ShakeTubeZ - @EnginnerPageParam(name = "摇匀放置位置", group = "抓手Z轴位置", order = ORDER.getGripperShakeTubeZPos) - public Integer getGripperShakeTubeZPos() { - return hpReader.getInteger("GripperShakeTubeZPos", 835); - } - - //TakeCapZ - @EnginnerPageParam(name = "取试管帽位", group = "抓手Z轴位置", order = ORDER.getGripperTakeCapZPos) - public Integer getGripperTakeCapZPos() { - return hpReader.getInteger("GripperTakeCapZPos", 835); - } - - - @EnginnerPageParam(name = "试管夹紧位", group = "试管夹紧模块", order = ORDER.getShakeClampingPos) - public Integer getShakeClampingPos() { - return hpReader.getInteger("ShakeClampingPos", 10); - } - - @EnginnerPageParam(name = "摇匀臂", group = "试管摇匀待机位", order = ORDER.getShakeModShakeMStandbyPos) - public Integer getShakeModShakeMStandbyPos() { - return hpReader.getInteger("ShakeModShakeMStandbyPos", 90); - } - - - // - // MotorTubeRackMoveCtrlService - // - - @EnginnerPageParam(name = "入料X位置", group = "进出料<试管架>坐标", order = ORDER.getTREnterXPos) - public Integer getTREnterXPos() { - return hpReader.getInteger("TREnterXPos", -46); - } - - @EnginnerPageParam(name = "出料X位置", group = "进出料<试管架>坐标", order = ORDER.getTRExitXPos) - public Integer getTRExitXPos() { - return hpReader.getInteger("TRExitXPos", 3975); - } - - @EnginnerPageParam(name = "试管架扫码X位置", group = "进出料<试管架>坐标", order = ORDER.getTRScanXPos) - public Integer getTRScanXPos() { - return hpReader.getInteger("TRScanXPos", 2202); - } - - @EnginnerPageParam(name = "试管扫码位置", group = "进出料<试管位置>信息", order = ORDER.getTScanXPos) - public Integer getTScanXPos() { - //运动方向: -> - return hpReader.getInteger("TScanXPos", 505); - - } - - @EnginnerPageParam(name = "试管高度判断位置", group = "进出料<试管位置>信息", order = ORDER.getTAltitJudgXPos) - public Integer getTAltitJudgXPos() { - //运动方向: -> - return hpReader.getInteger("TAltitJudgXPos", 505); - } - - @EnginnerPageParam(name = "试管是否存在判断位置", group = "进出料<试管位置>信息", order = ORDER.getTExistJudgXPos) - public Integer getTExistJudgXPos() { - //运动方向: <- - return hpReader.getInteger("TExistJudgXPos", 300); - } - - @EnginnerPageParam(name = "试管预处理位置", group = "进出料<试管位置>信息", order = ORDER.getTPreProcessXPos) - public Integer getTPreProcessXPos() { - //运动方向: <- - return hpReader.getInteger("TPreProcessXPos", 1225); - } - - @EnginnerPageParam(name = "试管架孔间距", group = "其他", order = ORDER.getTubeSpacing) - public Integer getTubeSpacing() { - return hpReader.getInteger("TubeSpacing", 200); - } - - @EnginnerPageParam(name = "扫码舵机转速(0..900)", group = "其他", order = ORDER.getTubeScanServoTorque) - public Integer getTubeScanServoTorque() { - return hpReader.getInteger("TubeScanServoTorque", 500); - } - - @EnginnerPageParam(name = "试管扫码超时时间", group = "其他", order = ORDER.getTubeScanOvertime) - public Integer getTubeScanOvertime() { - return hpReader.getInteger("TubeScanOvertime", 1000); - } - - - // - // - // - - - @EnginnerPageParam(name = "板夹仓通道0位置", group = "板夹仓参数", order = ORDER.getPBCh0Pos) - public Integer getPBCh0Pos() { - return hpReader.getInteger("PBCh0Pos", -17); - } - - @EnginnerPageParam(name = "板夹仓通道间距", group = "板夹仓参数", order = ORDER.getPBChSpacing) - public Integer getPBChSpacing() { - return hpReader.getInteger("PBChSpacing", 265); - } - - @EnginnerPageParam(name = "推杆到位坐标", group = "板夹仓参数", order = ORDER.getPusherEndPos) - public Integer getPusherEndPos() { - return hpReader.getInteger("PusherEndPos", 1160); - } - - @EnginnerPageParam(name = "推杆扫码开始坐标", group = "板夹仓参数", order = ORDER.getPusherScanStartPos) - public Integer getPusherScanStartPos() { - return hpReader.getInteger("PusherScanStartPos", 960); - } - - /* - * 转盘相关位置 - */ - - @EnginnerPageParam(name = "仓位0入板位置", group = "转盘坐标参数", order = ORDER.getTurntablePushPos0) - public Integer getTurntablePushPos0() { - return hpReader.getInteger("TurntablePushPos0", 1650); - } - - @EnginnerPageParam(name = "仓位0出板位置", group = "转盘坐标参数", order = ORDER.getTurntablePullPos0) - public Integer getTurntablePullPos0() { - return hpReader.getInteger("TurntablePullPos0", 19700); - } - - @EnginnerPageParam(name = "仓位0点滴位", group = "转盘坐标参数", order = ORDER.getTurntableDropLiquidPos0) - public Integer getTurntableDropLiquidPos0() { - return hpReader.getInteger("TurntableDropLiquidPos0", 1650 + 8950); - } - - public Integer getTurntablePosSpacing() { - return 1800; - } - - /* - * 光学模组相关 - */ - @EnginnerPageParam(name = "拉板目标位置", group = "光学模组坐标参数", order = ORDER.getPullerTargetPos) - public Integer getPullerTargetPos() { - return hpReader.getInteger("PullerTargetPos", 1147); - } - - @EnginnerPageParam(name = "丢板坐标", group = "光学模组坐标参数", order = ORDER.getPlateDropPos) - public Integer getPlateDropPos() { - return hpReader.getInteger("PlateDropPos", -349); - } - - @EnginnerPageParam(name = "扫描待机位", group = "光学模组坐标参数", order = ORDER.getOptScanScandbyPos) - public Integer getOptScanScandbyPos() { - return hpReader.getInteger("OptScanScandbyPos", 305); - } - - @EnginnerPageParam(name = "T光学扫描起始坐标", group = "光学模组坐标参数", order = ORDER.getTOptPosOffset) - public Integer getTOptPosOffset() { - //3509 - return hpReader.getInteger("TOptPosOffset", 3723); - } - - @EnginnerPageParam(name = "F光学扫描起始坐标", group = "光学模组坐标参数", order = ORDER.getFOptPosOffset) - public Integer getFOptPosOffset() { - return hpReader.getInteger("FOptPosOffset", 2559); - } - - @EnginnerPageParam(name = "T光学发光增益", group = "光学模组坐标参数", order = ORDER.getOptTLasterGain) - public Integer getOptTLasterGain() { - return hpReader.getInteger("OptTLasterGain", 0); - } - - @EnginnerPageParam(name = "F光学发光增益", group = "光学模组坐标参数", order = ORDER.getOptFLasterGain) - public Integer getOptFLasterGain() { - return hpReader.getInteger("OptFLasterGain", 0); - } - - - @EnginnerPageParam(name = "急诊位", group = "简单位置坐标", order = ORDER.getEmergencyPos) - public Pos3d getEmergencyPos() { - return new Pos3d( - 4858, - 3196, - 246 - ); - } - - @EnginnerPageParam(name = "TIP组位置信息", group = "HBOT位置坐标集合", order = ORDER.getTipPickUpPosInfo) - public TipPickUpPosInfo getTipPickUpPosInfo() { - return hpReader.getObject("TipPickUpPosInfo", TipPickUpPosInfo.class, - new TipPickUpPosInfo( - new Pos2d(887, -15), - new Pos2d(2413, -15), - new Pos2d(3947, -15), - 92.3, - 92.15, - 578, - 580, - 585 - )); - } - - - @EnginnerPageParam(name = "Tip丢弃位置", group = "简单位置坐标", order = ORDER.getTipDropPos) - public Pos3d getTipDropPos() { - return new Pos3d( - 4873, - 2563, - 661 - ); - } - - @EnginnerPageParam(name = "滴液反应位", group = "简单位置坐标", order = ORDER.getReactionPos) - public Pos3d getReactionPos() { - return hpReader.getObject("ReactionPos", Pos3d.class, - new Pos3d( - 0, - 0, - 0 - )); - } - - @EnginnerPageParam(name = "缓冲液位置", group = "HBOT位置坐标集合", order = ORDER.getBottleBufferPosInfo) - public BottleGroupsPosInfo getBottleBufferPosInfo() { - return hpReader.getObject("BottleBufferPosInfo", BottleGroupsPosInfo.class, - new BottleGroupsPosInfo( - new Pos2d(741, 937), - 1230, - 1250, - new Pos2d(579, 1097), - 320, - new BottlesPosInfo - ( - new Pos2d(160, 160), - 210, - 210, - 0 - ), - new BottlesPosInfo - ( - new Pos2d(215, 205), - 187, - 187, - 0 - ) - )); - } - - @EnginnerPageParam(name = "板夹仓扫码位置", group = "HBOT位置坐标集合", order = ORDER.getPlates2dCodeScanPosInfo) - public Plates2dCodeScanPos getPlates2dCodeScanPosInfo() { - return hpReader.getObject("Plates2dCodeScanPosInfo", Plates2dCodeScanPos.class,// - new Plates2dCodeScanPos( - new Pos2d(-20, 1504), - 265 - ) - ); - } - - @EnginnerPageParam(name = "大瓶缓冲液位置", group = "HBOT位置坐标集合", order = ORDER.getLargeBottleBufferPosInfo) - public LargeBottleBufferPos getLargeBottleBufferPosInfo() { - return hpReader.getObject("LargeBottleBufferPosInfo", LargeBottleBufferPos.class, - new LargeBottleBufferPos( - new Pos2d(4474, 1172), - new Pos2d(109, 182), - 280, - 280, - new Pos2d(60, 30), - 280, - 580 - )); - } - - @EnginnerPageParam(name = "Hbot采样区", group = "限制值", order = ORDER.getSampleCollectionArea) - public HbotLimitArea getSampleCollectionArea() { - return hpReader.getObject("HbotPublicArea", HbotLimitArea.class, - new HbotLimitArea(0, 3643, 5060, 4074)); - } - -} diff --git a/src/main/java/a8k/service/devicectrl/param/TimeParam.java b/src/main/java/a8k/service/devicectrl/param/TimeParam.java deleted file mode 100644 index d356413..0000000 --- a/src/main/java/a8k/service/devicectrl/param/TimeParam.java +++ /dev/null @@ -1,52 +0,0 @@ -package a8k.service.devicectrl.param; - - -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.controler.extapi.utils.*; -import org.springframework.stereotype.Component; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.TimeParam) -public class TimeParam { - EnginnerParamReader hpReader = new EnginnerParamReader(EnginnerPageParams.class); - - @EnginnerPageParam(name = "动作超时时间", group = "基础参数") - public Integer getActionOvertime() { - return hpReader.getInteger("ActionOvertime", 5000); - } - - @EnginnerPageParam(name = "归零超时时间", group = "基础参数") - public Integer getRuntoZeroActionOvertime() { - return hpReader.getInteger("RuntoZeroActionOvertime", 15000); - } - - @EnginnerPageParam(name = "入料超时时间", group = "基础参数") - public Integer getInfeedOvertime() { - return hpReader.getInteger("InfeedOvertime", 10000); - } - - @EnginnerPageParam(name = "出料超时时间", group = "基础参数") - public Integer getOutfeedOvertime() { - return hpReader.getInteger("OutfeedOvertime", 10000); - } - - @EnginnerPageParam(name = "试管帽有无判断时间", group = "基础参数") - public Integer getTubeCapJudgeDelayTime() { - return hpReader.getInteger("TubeCapJudgeDelayTime", 300); - } - - @EnginnerPageParam(name = "光学扫描超时时间", group = "光学") - public Integer getOptScanOvertime() { - return hpReader.getInteger("optScanOvertime", 12000); - } - - @EnginnerPageParam(name = "Hbot归零超时时间", group = "基础配置") - public Integer getHbotRuntoZeroActionOvertime() { - return hpReader.getInteger("HbotRuntoZeroActionOvertime", 20000); - } - - @EnginnerPageParam(name = "扫码超时时间", group = "基础配置") - public Integer getScancodeOvertime() { - return hpReader.getInteger("ScancodeOvertime", 1000); - } -} diff --git a/src/main/java/a8k/service/devicectrl/status/DeviceStatus.java b/src/main/java/a8k/service/devicectrl/status/DeviceStatus.java deleted file mode 100644 index 3b794e4..0000000 --- a/src/main/java/a8k/service/devicectrl/status/DeviceStatus.java +++ /dev/null @@ -1,87 +0,0 @@ -package a8k.service.devicectrl.status; - -import a8k.type.HardwareException; -import a8k.controler.extapi.utils.ExtApiTab; -import a8k.controler.extapi.utils.EnginnerPageStatu; -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.hardware.A8kCanBusService; -import a8k.hardware.type.a8kcanprotocol.IOId; -import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.hardware.type.regindex.RegIndex; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.DeviceStatus) -public class DeviceStatus { - @Resource - A8kCanBusService canBus; - - static class ORDER { - static final int isTubeExist = 1; - static final int isTubeRackInEnterPos = 2; - static final int isTubeRackInExitPos = 3; - static final int isHighTube = 4; - static final int getTHchOuterPPS = 5; - static final int getTHchInterPPS = 6; - static final int getXPPS = 7; - static final int getYPPS = 8; - static final int getZPPS = 9; - static final int getTipPPS = 10; - } - - // - // 状态 - // - @EnginnerPageStatu(name = "试管架存在", group = "进出料光电", order = ORDER.isTubeExist) - public Boolean isTubeExist() throws HardwareException { - return canBus.getIOState(IOId.TubeExistPPS); - } - - @EnginnerPageStatu(name = "入口光电", group = "进出料光电", order = ORDER.isTubeRackInEnterPos) - public Boolean isTubeRackInEnterPos() throws HardwareException { - return canBus.getIOState(IOId.InfeedPPS); - } - - @EnginnerPageStatu(name = "出口光电", group = "进出料光电", order = ORDER.isTubeRackInExitPos) - public Boolean isTubeRackInExitPos() throws HardwareException { - return canBus.getIOState(IOId.OutfeedPPS); - } - - @EnginnerPageStatu(name = "试管高低判读光电", group = "进出料光电", order = ORDER.isHighTube) - public Boolean isHighTube() throws HardwareException { - return canBus.getIOState(IOId.TubeHeightPPS); - } - - @EnginnerPageStatu(name = "通道外光电", group = "进出料光电", order = ORDER.getTHchOuterPPS) - public Boolean getTHchOuterPPS() throws HardwareException { - return canBus.getIOState(IOId.THChOuterPPS); - } - - @EnginnerPageStatu(name = "通道内光电", group = "进出料光电", order = ORDER.getTHchInterPPS) - public Boolean getTHchInterPPS() throws HardwareException { - return canBus.getIOState(IOId.THChInterPPS); - } - - @EnginnerPageStatu(name = "X轴光电➡", group = "HBOT", order = ORDER.getXPPS) - public Boolean getXPPS() throws HardwareException { - return canBus.hbotReadInio(MId.HbotM, 0); - } - - @EnginnerPageStatu(name = "Y轴光电⬇", group = "HBOT", order = ORDER.getYPPS) - public Boolean getYPPS() throws HardwareException { - return canBus.hbotReadInio(MId.HbotM, 1); - } - -// @EnginnerPageStatu(name = "Z轴光电⬆", group = "HBOT", order = ORDER.getZPPS) -// public Boolean getZPPS() throws HardwareException { -// return canBus.stepMotorReadIoState(MId.PipetteModZM, 0); -// } - - - // @HardwareServiceStatus(name = "TipState") - public Boolean getTipPPS() throws HardwareException { - return canBus.moduleGetReg(MId.PipetteMod, RegIndex.kreg_pipette_tip_state) == 1; - } - -} diff --git a/src/main/java/a8k/service/devicectrl/testscript/TestScript.java b/src/main/java/a8k/service/devicectrl/testscript/TestScript.java deleted file mode 100644 index 767b734..0000000 --- a/src/main/java/a8k/service/devicectrl/testscript/TestScript.java +++ /dev/null @@ -1,250 +0,0 @@ -package a8k.service.devicectrl.testscript; - -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.type.ConsumableGroup; -import a8k.type.HardwareException; -import a8k.type.IncubatorPos; -import a8k.type.appret.AppRet; -import a8k.type.cfg.BottleGroupsPosInfo; -import a8k.type.cfg.BottlesPosInfo; -import a8k.type.cfg.TipPickUpPosInfo; -import a8k.controler.extapi.utils.*; -import a8k.service.devicectrl.ctrl.SamplesPreProcesCtrl; -import a8k.service.devicectrl.ctrl.TubeRackMoveCtrl; -import a8k.hardware.A8kCanBusService; -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.hardware.type.a8kcanprotocol.MId; -import a8k.hardware.type.regindex.RegIndex; -import a8k.service.devicectrl.ctrl.HbotControlService; -import a8k.service.devicectrl.ctrl.ReactionPlatesTransmitCtrl; -import a8k.service.devicectrl.param.DebugParam; -import a8k.service.devicectrl.param.PosParam; -import a8k.service.devicectrl.param.TimeParam; -import jakarta.annotation.Resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; - -import java.util.HashMap; -import java.util.Map; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.TestScript) -public class TestScript { - static Logger logger = LoggerFactory.getLogger(TestScript.class); - - static class ORDER { - static final int testTakeAllTipStop = 0; - static final int takeTipTestStep = 1; - static final int testTakeAllTip = 2; - static final int testAllLittleBottleBufferPos = 3; - static final int testAllDetectMaterialPos = 4; - static final int testAllBigBottleBufferPos = 5; - static final int pushAllPlateAndDrop = 6; - static final int testSamplePreProcessModule = 7; - } - - @Resource - A8kCanBusService canBus; - - @Resource - ApplicationContext appCxt; - - @Resource - HbotControlService hbotcs; - - @Resource - TimeParam timep; - @Resource - PosParam pp; - @Resource - DebugParam dp; - - @Resource - ReactionPlatesTransmitCtrl reactionPlatesTransmitCtrl; - - @Resource - SamplesPreProcesCtrl samplesPreProcesCtrl; - - @Resource - TubeRackMoveCtrl tubeRackMoveCtrl; - - EnginnerParamReader settingReader = new EnginnerParamReader(HbotControlService.class); - - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // 测试 - // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Boolean testScriptWorkFlag = false; - - void checkTestScriptWorkFlag() throws HardwareException { - if (testScriptWorkFlag) { - testScriptWorkFlag = false; - throw new HardwareException(A8kEcode.TestScripIsRunning.index); - } - } - - @ExtApiFn(name = "停止测试脚本", group = "控制", order = ORDER.testTakeAllTipStop) - public void testTakeAllTipStop() { - testScriptWorkFlag = false; - } - - @ExtApiFn(name = "取放Tip-单步", group = "Hbot测试脚本", order = ORDER.takeTipTestStep) - public AppRet takeTipTestStep(Integer tipgroup, Integer index) throws HardwareException, InterruptedException { - checkTestScriptWorkFlag(); - testScriptWorkFlag = true; - var ret = hbotcs.takeTip(tipgroup, index); - TipPickUpPosInfo tipPos = pp.getTipPickUpPosInfo(); - - //TODO canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, tipPos.getPickUpZPos(tipgroup) - 100, timep.getActionOvertime()); - // TODO canBus.pipetteCtrlPutTipBlock(MId.PipetteMod); - - if (canBus.moduleGetReg(MId.PipetteMod, RegIndex.kreg_pipette_tip_state) == 1) { - throw new HardwareException(A8kEcode.PutTipFail.index); - } - - // TODO canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); - testScriptWorkFlag = false; - return ret; - } - - @ExtApiFn(name = "取放Tip-全部", group = "Hbot测试脚本", order = ORDER.testTakeAllTip) - public AppRet> testTakeAllTip(Integer groupId, Integer startFrom) throws HardwareException, InterruptedException { - checkTestScriptWorkFlag(); - - testScriptWorkFlag = true; - Map result = new HashMap<>(); - for (int i = startFrom; i < TipPickUpPosInfo.cgetTipNum(); i++) { - var ret = takeTipTestStep(groupId, i); - if (!ret.getData()) { - throw new HardwareException(A8kEcode.TakeTipFail.index); - } - - result.put("Tip" + i, ret.getData() ? "suc" : "fail"); - logger.info("Take Tip {}-{} => {}", groupId, i, ret.getData()); - if (!testScriptWorkFlag) { - break; - } - } - testScriptWorkFlag = false; - return AppRet.success(result); - } - - @ExtApiFn(name = "测试所有小瓶缓冲液位置", group = "Hbot测试脚本", order = ORDER.testAllLittleBottleBufferPos) - public void testAllLittleBottleBufferPos(ConsumableGroup group) throws HardwareException, InterruptedException { - checkTestScriptWorkFlag(); - - testScriptWorkFlag = true; - BottleGroupsPosInfo posInfo = pp.getBottleBufferPosInfo(); - for (int i = 0; i < BottlesPosInfo.cgetMAX(); i++) { - BottleGroupsPosInfo pos = pp.getBottleBufferPosInfo(); - hbotcs.hbotMoveToSmallBottleGroup(group, i); - //TODO: canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, pos.posTestZ, timep.getActionOvertime()); - //TODO: canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); - if (!testScriptWorkFlag) { - break; - } - } - testScriptWorkFlag = false; - } - - @ExtApiFn(name = "测试所有探测物质位置", group = "Hbot测试脚本", order = ORDER.testAllDetectMaterialPos) - public void testAllDetectMaterialPos(ConsumableGroup group) throws HardwareException, InterruptedException { - checkTestScriptWorkFlag(); - - testScriptWorkFlag = true; - for (int i = 0; i < BottlesPosInfo.cgetMAX(); i++) { - BottleGroupsPosInfo pos = pp.getBottleBufferPosInfo(); - hbotcs.hbotMoveToDetectMaterialPos(group, i); - //TODO: canBus.stepMotorEasyMoveToBlock(MId.PipetteModZM, pos.posTestZ, timep.getActionOvertime()); - //TODO: canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); - if (!testScriptWorkFlag) { - break; - } - } - testScriptWorkFlag = false; - } - - @ExtApiFn(name = "测试所有大瓶缓冲液位置", group = "Hbot测试脚本", order = ORDER.testAllBigBottleBufferPos) - public void testAllBigBottleBufferPos() throws HardwareException, InterruptedException { - checkTestScriptWorkFlag(); - - testScriptWorkFlag = true; - // 遍历枚举 ConsumableGroup - for (ConsumableGroup group : ConsumableGroup.values()) { - hbotcs.hbotMoveToLargeBottleGroup(group); - //TODO: canBus.stepMotorEasyMoveByBlock(MId.PipetteModZM, 100, timep.getActionOvertime()); - //TODO: canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PipetteModZM, timep.getActionOvertime()); - if (!testScriptWorkFlag) { - break; - } - } - testScriptWorkFlag = false; - } - - @ExtApiFn(name = "推全部板同时丢弃", group = "板夹移动测试脚本", order = ORDER.pushAllPlateAndDrop) - public void pushAllPlateAndDrop(ConsumableGroup PBCh, IncubatorPos startPos) throws HardwareException, InterruptedException { - checkTestScriptWorkFlag(); - testScriptWorkFlag = true; - reactionPlatesTransmitCtrl.checkBeforeMoveTrunable(); - reactionPlatesTransmitCtrl.checkBeforeMovePlateBox(); - reactionPlatesTransmitCtrl.modGroupMoveToZeroQuick(); - reactionPlatesTransmitCtrl.dropPlate(); - for (IncubatorPos index : IncubatorPos.values()) { - if (index.compareTo(startPos) < 0) { - continue; - } - reactionPlatesTransmitCtrl.pushPlateQuick(PBCh, index); - reactionPlatesTransmitCtrl.pullPlate(index); - reactionPlatesTransmitCtrl.dropPlate(); - if (!testScriptWorkFlag) { - break; - } - } - testScriptWorkFlag = false; - } - - @ExtApiFn(name = "测试摇匀模组", group = "摇匀模组测试", order = ORDER.testSamplePreProcessModule) - public AppRet testSamplePreProcessModule() throws HardwareException, InterruptedException { - checkTestScriptWorkFlag(); - testScriptWorkFlag = true; - - try { - tubeRackMoveCtrl.enterTubeHolder(); - AppRet scanResult = tubeRackMoveCtrl.moveTubeRackToScanPosAndScan(); - if (!scanResult.isSuccess()) { - tubeRackMoveCtrl.ejectTubeHolder(); - logger.info("没有扫到试管架的码"); - return AppRet.message("没有扫到试管架的码", null); - } - if (!scanResult.getData().equals("1111\r")) { - tubeRackMoveCtrl.ejectTubeHolder(); - logger.info("不是全血试管架 {}", scanResult.getData()); - return AppRet.message("不是全血试管架", null); - } - - AppRet isExistTube = tubeRackMoveCtrl.judgeTubeExist(0); - AppRet isHighTube = tubeRackMoveCtrl.moveTubeToAltitJudgXPos(0); - tubeRackMoveCtrl.moveTubeToPreProcessPos(0); - - if (!isExistTube.getData()) { - tubeRackMoveCtrl.ejectTubeHolder(); - logger.info("试管架上没有试管"); - return AppRet.message("试管架上没有试管", null); - } - - - samplesPreProcesCtrl.takeTubeAndJudgeTubeExist(isHighTube.getData()); - samplesPreProcesCtrl.shakeTube(50, 5); - samplesPreProcesCtrl.takeTubeCap(); - samplesPreProcesCtrl.pushBackTubeCapAndTakeBakTube(); - tubeRackMoveCtrl.ejectTubeHolder(); - } finally { - testScriptWorkFlag = false; - } - - return AppRet.message("测试完成", null); - - } - -} diff --git a/src/main/java/a8k/service/project_mgr/AppProjIDCardMgrService.java b/src/main/java/a8k/service/project_mgr/AppProjIDCardMgrService.java deleted file mode 100644 index 652049b..0000000 --- a/src/main/java/a8k/service/project_mgr/AppProjIDCardMgrService.java +++ /dev/null @@ -1,137 +0,0 @@ -package a8k.service.project_mgr; - - -import a8k.baseservice.appeventbus.appevent.*; -import a8k.controler.extapi.pagecontrol.ExtApiTabConfig; -import a8k.controler.extapi.utils.*; -import a8k.baseservice.appeventbus.AppEventListener; -import a8k.dbservice.A8kProjIdCardDBService; -import a8k.dbservice.type.A8kProjIdCardDBIterm; -import a8k.hardware.type.regindex.RegIndex; -import a8k.type.HardwareException; -import a8k.type.appret.AppRet; -import a8k.baseservice.appeventbus.AppEventBusService; -import a8k.hardware.A8kCanBusService; -import a8k.hardware.type.a8kcanprotocol.*; -import a8k.type.projecttype.a8kidcard.A8kIdCardInfo; -import a8k.utils.A8kIdCardDataParser; -import a8k.utils.wq.ZWorkQueue; -import jakarta.annotation.PostConstruct; -import jakarta.annotation.Resource; -import org.slf4j.Logger; -import org.springframework.stereotype.Component; - -import java.util.List; - -@Component -@ExtApiTab(cfg = ExtApiTabConfig.AppProjectItemMgrService) -public class AppProjIDCardMgrService implements AppEventListener { - static Logger logger = org.slf4j.LoggerFactory.getLogger(AppProjIDCardMgrService.class); - - static class ORDER { - static final int readIDCardInfo = 1; - static final int saveIDCardInfo = 2; - static final int getProjectInfoList = 3; - static final int getProjectInfo = 4; - } - - @Resource - A8kCanBusService canBus; - - @Resource - AppEventBusService eventBus; - - @Resource - A8kProjIdCardDBService a8kProjIdCardDBService; - - - A8kIdCardInfo mountedIdCardInfo; - - ZWorkQueue workQueue = new ZWorkQueue(2, 1); - - @PostConstruct - public void init() { - eventBus.regListener(this); - } - - /** - * 事件总线事件处理 - * @param event e - */ - @Override public void onAppEvent(AppEvent event) { - if (event instanceof A8kHardwareReport canPacket) { - A8kPacket packet = canPacket.getReportPacket(); - CmdId cmdId = CmdId.valueOf(packet.getCmdId()); - if (CmdId.event_a8000_idcard_online.equals(cmdId)) { - logger.info("插入ID卡"); - workQueue.addTask(this::readIDCard); - } else if (CmdId.event_a8000_idcard_offline.equals(cmdId)) { - eventBus.pushEvent(new AppIDCardUnmountEvent()); - logger.info("拔出ID卡"); - } - } else if (event instanceof A8kCanBusOnConnectEvent canPacket) { - if (idCardStatus()) { - logger.info("ID卡读卡器在线"); - workQueue.addTask(this::readIDCard); - } - } - } - - - void readIDCard() { - //读取ID卡信息 - byte[] data = null; - try { - data = canBus.a8kIdcardReaderReadRaw(); - logger.info("ID卡信息:\n{}", A8kIdCardDataParser.dumpByte(data, 10)); - - A8kIdCardDataParser parser = new A8kIdCardDataParser(data); - mountedIdCardInfo = parser.parse(); - - - // - //TODO: - //检查解析结果,如果解析结果存在异常,则抛出错误事件给前端 - if (mountedIdCardInfo.lotName.isEmpty()) { - eventBus.pushEvent(new A8kErrorPromptEvent(A8kEcode.A8kIdCardLotIdIsEmpty.index)); - return; - } - - //如果检查结果,如果解析结果正常,则抛出新ID卡上限事件 - eventBus.pushEvent(new AppIDCardMountEvent(mountedIdCardInfo)); - } catch (HardwareException ignored) { - } - } - - - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // EXT - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @ExtApiFn(name = "读取挂载的ID卡信息", order = ORDER.readIDCardInfo) - public AppRet readMountedIDCardInfo() { - return AppRet.success(mountedIdCardInfo); - } - - @ExtApiFn(name = "获取ID卡信息列表", order = ORDER.getProjectInfoList) - public AppRet> getProjectInfoList() { - return AppRet.success(a8kProjIdCardDBService.getAllIdCards()); - } - - @ExtApiFn(name = "保存挂载ID卡信息", order = ORDER.saveIDCardInfo) - public void saveIDCardInfo() { - a8kProjIdCardDBService.addIdCard(mountedIdCardInfo); - } - - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // STATUS - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - @ExtApiFn(name = "ID卡状态") - public Boolean idCardStatus() { - try { - return canBus.moduleGetReg(MId.A8kIdCardReader, RegIndex.kreg_id_card_reader_is_online) == 1; - } catch (HardwareException ignored) { - } - return false; - } -}