From e7109168b0a2f6eff18046cd2b1f4afe375e667d Mon Sep 17 00:00:00 2001 From: zhaohe Date: Wed, 30 Oct 2024 22:35:24 +0800 Subject: [PATCH] update --- README2.md | 7 +++++++ src/main/java/a8k/constant/MiniServoConstant.java | 2 +- .../action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java | 4 ++++ .../action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java | 15 +++++++++++++++ .../appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java | 2 +- .../app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java | 6 ++++++ .../appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java | 17 +++++++++++++++-- .../devicectrl/ctrlservice/DeviceInitCtrlService.java | 7 +++++-- .../app/devicectrl/ctrlservice/HbotCtrlService.java | 9 ++++++++- .../devicectrl/ctrlservice/TubeFeedingCtrlService.java | 2 -- .../app/devicectrl/driver/PipetteCtrlDriver.java | 5 ++--- .../param/param_mgr/HbotSamplePosParamMgr.java | 15 ++++++++------- .../app/devicectrl/script/DeviceCtrlScripter.java | 9 ++++++++- src/main/java/a8k/utils/ActionParallerExceutor.java | 5 ++++- 14 files changed, 84 insertions(+), 21 deletions(-) diff --git a/README2.md b/README2.md index 899dba3..6995653 100644 --- a/README2.md +++ b/README2.md @@ -119,4 +119,11 @@ TODO: 6. 支持吸空检测 (困难) 5. 支持鼠标? (困难) +``` + +```angular2html +1. tip丢弃失败的问题 +2. 舵机死机的问题 +3. hbot收不到消息的BUG + ``` \ No newline at end of file diff --git a/src/main/java/a8k/constant/MiniServoConstant.java b/src/main/java/a8k/constant/MiniServoConstant.java index a333275..833950e 100644 --- a/src/main/java/a8k/constant/MiniServoConstant.java +++ b/src/main/java/a8k/constant/MiniServoConstant.java @@ -4,7 +4,7 @@ import a8k.service.app.devicectrl.driver.type.MiniServoMId; import org.springframework.util.Assert; public class MiniServoConstant { - static public final Integer actionOvertime = 5000; + static public final Integer actionOvertime = 10000; //摇匀模组Y轴 static public final Integer ShakeModGripperYSV_zeroPos = 110; diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java index 26d91a4..6e57e4c 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ1_ENTER_TUBEHOLDER_AND_SCAN.java @@ -93,6 +93,10 @@ public class SEQ1_ENTER_TUBEHOLDER_AND_SCAN extends A8kStepAction { result = testModeState.getVirtualTubeScanResult(); } + if (result == null) { + stc.ejectTubeHolder(); + } + return result; } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java index 47047ba..7c7db66 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ2_SWITCH_TO_THE_NEXT_TUBE.java @@ -10,9 +10,11 @@ import a8k.service.app.appstate.type.TubeHolder; import a8k.service.app.appstate.type.Tube; import a8k.service.app.appstate.type.state.TubeState; import a8k.service.app.devicectrl.ctrlservice.TubeFeedingCtrlService; +import a8k.service.app.devicectrl.driver.PipetteCtrlDriver; import a8k.service.test.state.TestModeState; import a8k.service.test.state.VirtualDevice; import a8k.type.exception.AppException; +import a8k.utils.ActionParallerExceutor; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import org.slf4j.Logger; @@ -54,8 +56,13 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction { @Resource TubeFeedingCtrlService tubeFeedingCtrlService; + @Resource + PipetteCtrlDriver pipetteCtrlDriver; + DeviceWorkState state; + ActionParallerExceutor executor = new ActionParallerExceutor(); + @PostConstruct void init() { state = gstate.deviceWorkState; @@ -70,6 +77,14 @@ public class SEQ2_SWITCH_TO_THE_NEXT_TUBE extends A8kStepAction { virtualDevice.doVirtualThings("移动到下一个试管"); } else { tubeFeedingCtrlService.moveTubeToPreProcessPos(tubeIndex); + executor.submit(() -> tubeFeedingCtrlService.moveTubeToPreProcessPos(tubeIndex)); + // executor.submit(() -> pipetteCtrlDriver.lldPrepareBlock()); + + var exception = executor.waitAll(); + if (exception != null) { + throw exception; + } + } } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java index 5e30770..d672bb4 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ4_PRE_PROCESS.java @@ -161,7 +161,7 @@ public class SEQ4_PRE_PROCESS extends A8kStepAction { var mutiAppException = actionParallerExceutor.waitAll(); //如果依然有错误,将试管状态设置为错误,同时抛出异常 - if (!mutiAppException.bindExceptions.isEmpty()) { + if (mutiAppException != null) { projectProcessContextMgrService.changeTubeStateToError(gstate.getCurProcessingTube(), mutiAppException.getErrors()); throw mutiAppException; } diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java index bdc019a..1317081 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java @@ -81,7 +81,13 @@ public class SEQ5_PROCESS extends A8kStepAction { if (projProcessOff != 0) { //第一个项目的部分动作已经在前面完成 deviceCtrlScripter.doSampleProcessPrepare(cxt); } + deviceCtrlScripter.doSampleProcess(cxt); + + if (projProcessOff + 1 != tube.getProjIds().size()) { + deviceCtrlScripter.doSampleProcessPostProcess(cxt); + } + } @Override diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java index 2e4a939..e184079 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ6_POST_PROCESS.java @@ -1,8 +1,10 @@ package a8k.service.app.appctrl.mainflowctrl.action; +import a8k.service.app.appstate.type.ProjProcessContext; import a8k.service.app.devicectrl.ctrlservice.PipetteGunCtrlService; import a8k.service.app.devicectrl.ctrlservice.TubePreProcesCtrlService; import a8k.service.app.devicectrl.driver.PipetteCtrlDriver; +import a8k.service.app.devicectrl.script.DeviceCtrlScripter; import a8k.utils.ActionParallerExceutor; import a8k.utils.AppExceptionBuilder; import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; @@ -57,6 +59,8 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { ProjectProcessContextMgrService projectProcessContextMgrService; @Resource CondtionMgrService cms; + @Resource + DeviceCtrlScripter deviceCtrlScripter; ActionParallerExceutor actionParallerExceutor = new ActionParallerExceutor(); @@ -69,17 +73,25 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { state = gstate.deviceWorkState; } + + void tubePostProcess() throws AppException { + var tube = gstate.getCurProcessingTube(); + Integer projProcessOff = tube.getProjProcessOff(); + ProjProcessContext cxt = projectProcessContextMgrService.getProjProcessContext(tube.getSampleId(), tube.getProjIds().get(projProcessOff)); + deviceCtrlScripter.doSampleProcessPostProcess(cxt); + } + void doAction() throws AppException { if (virtualDevice.isEnable()) { virtualDevice.doVirtualThings("后处理样本", 3); } - actionParallerExceutor.submit(() -> pipetteCtrlDriver.lldPrepareBlock()); + actionParallerExceutor.submit(this::tubePostProcess); actionParallerExceutor.submit(() -> tubePreProcesCtrlService.resteModule()); var mutiAppException = actionParallerExceutor.waitAll(); - if (!mutiAppException.bindExceptions.isEmpty()) { + if (mutiAppException != null) { projectProcessContextMgrService.changeTubeStateToError(gstate.getCurProcessingTube(), mutiAppException.getErrors()); throw mutiAppException; } @@ -100,6 +112,7 @@ public class SEQ6_POST_PROCESS extends A8kStepAction { return List.of( A8kPublicResourceType.PlatesBoxModule, A8kPublicResourceType.HBOT, + A8kPublicResourceType.IncubationPlateModule, A8kPublicResourceType.CurTubeProcessToken ); } diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java index fbb6092..8366345 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java @@ -113,10 +113,10 @@ public class DeviceInitCtrlService { //进出料初始化 actionReactor.dosome("摇匀模组-扫码夹紧舵机回零", () -> miniServoDriver.miniServoMoveToZeroBlock(MiniServoMId.ShakeModTubeScanerClampingSV)); actionReactor.dosome("入料平移电机回零", () -> stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.FeedingModXM, actionOvertime)); + actionReactor.dosome("摇匀模组-夹爪Z轴电机回零", () -> stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.ShakeModGripperZM, actionOvertime)); actionReactor.dosome("摇匀模组-夹爪舵机回零", () -> miniServoDriver.miniServoMoveToZeroBlock(MiniServoMId.ShakeModGripperSV)); actionReactor.dosome("摇匀模组-夹爪Y轴舵机回零", () -> miniServoDriver.miniServoMoveToZeroBlock(MiniServoMId.ShakeModGripperYSV)); actionReactor.dosome("摇匀模组-夹紧电机回零", () -> stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.ShakeModClampingM, actionOvertime)); - actionReactor.dosome("摇匀模组-夹爪Z轴电机回零", () -> stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.ShakeModGripperZM, actionOvertime)); actionReactor.dosome("摇匀模组-摇匀电机回零", () -> stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.ShakeModShakeM, actionOvertime)); actionReactor.dosome("摇匀模组-摇匀电机摆动90度", () -> stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.ShakeModShakeM, 90, actionOvertime)); //板夹仓初始化 @@ -139,10 +139,13 @@ public class DeviceInitCtrlService { //弹出试管架 tubeFeedingCtrlService.ejectTubeHolder(); //丢弃tip头 - hbotCtrlService.dropTip(); + hbotCtrlService.initPipetterGun(); //hbot快速归零 hbotCtrlService.moveQuickToZero(); + pipetteCtrlDriver.lldPrepareBlock(); + + return results; } diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java index 0080f0c..e0dff1b 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java @@ -91,7 +91,14 @@ public class HbotCtrlService { public void dropTip() throws AppException { log.info("丢弃tip"); hbotBaseMoveExDriver.hbotMoveTo(hbotTipPosMgr.getDropTipPos()); - pipetteCtrlDriver.putTipBlock(); + if (pipetteCtrlDriver.isHasTip()) { + pipetteCtrlDriver.putTipBlock(); + } + } + + public void initPipetterGun() throws AppException { + hbotBaseMoveExDriver.hbotMoveTo(hbotTipPosMgr.getDropTipPos()); + pipetteCtrlDriver.pipetteInitDeviceBlock(); } public void moveToDropLiquidPos() throws AppException { diff --git a/src/main/java/a8k/service/app/devicectrl/ctrlservice/TubeFeedingCtrlService.java b/src/main/java/a8k/service/app/devicectrl/ctrlservice/TubeFeedingCtrlService.java index fc3dfee..40e16a1 100644 --- a/src/main/java/a8k/service/app/devicectrl/ctrlservice/TubeFeedingCtrlService.java +++ b/src/main/java/a8k/service/app/devicectrl/ctrlservice/TubeFeedingCtrlService.java @@ -267,7 +267,6 @@ public class TubeFeedingCtrlService { if (tubeType.isEmpty()) { logger.warn("扫描试管架类型失败,弹出试管架"); ebus.pushEvent(new AppWarningNotifyEvent(A8kEcode.APPE_SCAN_TUBEHOLDER_TYPE_TIMEOUT)); - ejectTubeHolder(); return null; } logger.info("扫描试管架类型成功,{}", tubeType); @@ -291,7 +290,6 @@ public class TubeFeedingCtrlService { if (!hasTube) { logger.error("试管架中没有试管"); ebus.pushEvent(new AppWarningNotifyEvent(A8kEcode.APPE_TUBE_HOLDER_TYPE_IS_NOT_SUPPORT)); - ejectTubeHolder(); return null; } result.tubeHolderType = tubeType; diff --git a/src/main/java/a8k/service/app/devicectrl/driver/PipetteCtrlDriver.java b/src/main/java/a8k/service/app/devicectrl/driver/PipetteCtrlDriver.java index 936090a..1144da0 100644 --- a/src/main/java/a8k/service/app/devicectrl/driver/PipetteCtrlDriver.java +++ b/src/main/java/a8k/service/app/devicectrl/driver/PipetteCtrlDriver.java @@ -150,9 +150,8 @@ public class PipetteCtrlDriver { @ExtApiFn(name = "放置吸头", order = FnOrder.putTipBlock) public void putTipBlock() throws AppException { - // canBusService.callcmd(MId.PipetteMod.toInt(), CmdId.pipette_put_tip.toInt()); - // canBusService.waitForMod(MId.PipetteMod, overtime); - pipetteInitDeviceBlock(); + canBusService.callcmd(MId.PipetteMod.toInt(), CmdId.pipette_put_tip.toInt()); + canBusService.waitForMod(MId.PipetteMod, overtime); } @ExtApiFn(name = "设置LLD起始位置", order = FnOrder.setLLDStartZ) diff --git a/src/main/java/a8k/service/app/devicectrl/param/param_mgr/HbotSamplePosParamMgr.java b/src/main/java/a8k/service/app/devicectrl/param/param_mgr/HbotSamplePosParamMgr.java index c5259e7..3fe7c88 100644 --- a/src/main/java/a8k/service/app/devicectrl/param/param_mgr/HbotSamplePosParamMgr.java +++ b/src/main/java/a8k/service/app/devicectrl/param/param_mgr/HbotSamplePosParamMgr.java @@ -39,13 +39,14 @@ public class HbotSamplePosParamMgr extends ParamMgr { public Pos3d getSampleStartPos(A8kSamplePos samplePos) { return switch (samplePos) { - case EmergencyTubePos -> getSamplePos(HbotSamplePos.BloodHTubeSamplePos); - case BloodHTubePos -> getSamplePos(HbotSamplePos.BloodSTubeSamplePos); - case BloodSTubePos -> getSamplePos(HbotSamplePos.MiniTubeSamplePos); - case MiniTubePos -> getSamplePos(HbotSamplePos.MiniBloodSamplePos); - case MiniBloodPos -> getSamplePos(HbotSamplePos.Bulltube1P5SamplePos); - case Bulltube1P5Pos -> getSamplePos(HbotSamplePos.Bulltube0P5SamplePos); - case Bulltube0P5Pos -> getSamplePos(HbotSamplePos.StoolTestTubeSamplePos); + case EmergencyTubePos -> getSamplePos(HbotSamplePos.EmergencyTubeSamplePos); + case BloodHTubePos -> getSamplePos(HbotSamplePos.BloodHTubeSamplePos); + case BloodSTubePos -> getSamplePos(HbotSamplePos.BloodSTubeSamplePos); + case MiniTubePos -> getSamplePos(HbotSamplePos.MiniTubeSamplePos); + case MiniBloodPos -> getSamplePos(HbotSamplePos.MiniBloodSamplePos); + case Bulltube1P5Pos -> getSamplePos(HbotSamplePos.Bulltube1P5SamplePos); + case Bulltube0P5Pos -> getSamplePos(HbotSamplePos.Bulltube0P5SamplePos); + case StoolTestTubePos -> getSamplePos(HbotSamplePos.StoolTestTubeSamplePos); default -> throw new IllegalStateException("Unexpected value: " + samplePos); }; } diff --git a/src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java b/src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java index d5bc107..6eaaf88 100644 --- a/src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java +++ b/src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java @@ -153,6 +153,7 @@ public class DeviceCtrlScripter { hbotCtrlService.dropTip(); //待机 hbotCtrlService.moveQuickToZero(); + pipetteCtrlDriver.lldPrepareBlock(); } else if (type.equals(A8kReactionFlowType.FlowType2)) { log.info("样本预处理,取大瓶缓冲液液到探测物质中"); /* @@ -188,6 +189,7 @@ public class DeviceCtrlScripter { //归零,待机 hbotCtrlService.moveQuickToZero(); + pipetteCtrlDriver.lldPrepareBlock(); } else { Assert.isTrue(false, "不支持的反应流程类型"); } @@ -221,9 +223,14 @@ public class DeviceCtrlScripter { //取样 aspirate(PipetteGunBindActionType.SAMPLE, ctx, sampleul); - //移动到吐液位, hbotCtrlService.moveTo(ProjProcessContextUtils.getReactionEndPos(ctx)); + } + + + public void doSampleProcessPostProcess(ProjProcessContext ctx) throws AppException { + Integer sampleul = ProjProcessContextUtils.getSampleVol(ctx); + Integer reactionul = ProjProcessContextUtils.getReactionPlateDropletVolUl(ctx); //吐液 aspirateNoLLF(-sampleul); diff --git a/src/main/java/a8k/utils/ActionParallerExceutor.java b/src/main/java/a8k/utils/ActionParallerExceutor.java index d3fb9a8..79edcee 100644 --- a/src/main/java/a8k/utils/ActionParallerExceutor.java +++ b/src/main/java/a8k/utils/ActionParallerExceutor.java @@ -12,7 +12,7 @@ import java.util.concurrent.*; public class ActionParallerExceutor { ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); - List> futures = new ArrayList<>(); + List> futures = new ArrayList<>(); // var doPrepareReactionPlateFuture = executor.submit(() -> ZFnCall.callfn(this::prepareReactionPlate)); //摇匀并取盖 @@ -36,6 +36,9 @@ public class ActionParallerExceutor { } catch (InterruptedException | ExecutionException ignored) { } exceptions.removeIf(Objects::isNull); + if (exceptions.isEmpty()) { + return null; + } return new MutiAppException(exceptions); // List errors = new java.util.ArrayList<>(List.of()); // exceptions.forEach(e -> errors.add(e.getError()));