From b4ff6a27c779f5a0e5165bbdf60b8e8b1bce87c2 Mon Sep 17 00:00:00 2001 From: sige Date: Sat, 11 May 2024 17:52:00 +0800 Subject: [PATCH] EPP0.5/EPP1.5 --- app.db | Bin 147456 -> 155648 bytes pom.xml | 2 +- .../iflytop/a800/controller/DemoController.java | 34 ++++++++++++ src/main/java/com/iflytop/a800/device/Pipette.java | 61 +++++++++++++++++++-- 4 files changed, 92 insertions(+), 5 deletions(-) diff --git a/app.db b/app.db index fce7551fb23342d8f79e091665545c71419269a3..5abc8008f5a7680cb944d9f420d4b3dcb5626328 100644 GIT binary patch delta 8681 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 a0}<$IjJe9{Mj;2=D9w delta 1662 zcma)6e@Ixz8Vskn$eRxp43Ie9q^5 zzn|}Ca3(T17=_j2z8Zokp#zH7eaP1S)f3EHkzG*L4pCz-YoR#RlrRUK)H;ULpg zWl1$tl99&up{bjqMHfLqhMQsg&@7B}1!H9D*iPc4sY#}BKUzv!=XM}6 zoGcG0ovZZKv;r1nis5a35g3edHA)XP~jmm7d=MANTv3 z;luEQDY_;*mq=#C7iz$dd|P%Y3ChWjlC_Xtptz6N3;ZP8#q{t|{wVzy^A5eh9O7=X zCHx3e!Kb;s-0N%uGsphK+~XWBpZ$#g?%%_2Y6bPt0aJF!ut{M^T}fdS2Wh5;k!Hz` zV>%jEbt_Sk)ee%1gAEPqNK|o9K}|x2Dmlm&Q=*}3X3|V2%jjXMSHU(mWl~#BNn?a< z!$w-lQISHnrwG0w*>XICXsObGC^-^Avy%vmhJ_4;P*E%sE3$z#39B&zS-BNumj;kq z5$!IL#EEr1KJj0IEFqCk>M6yL9L+(FXzPgF!9ZG?^nqgQie~AyZl%oP;B2?`bi(`d zX)y1d+7A+7hkx%VIBo&aw?74!_GImZtzOPAAWej@1NyDMf)80Bk7vUpZd>d2a8?IT zhstl9f@ebDfd6|47J*RMrYgPbMX=JXIsBk+hvB72RLU8mNF^uv5l;|ci6;uM!tW5^ zWY{eg&V*KZbSM041+YCgpYRVJKxP75T^)fCfqyjy=YZRF^4UmqG4y=UDRtg+Yu(l4 zjv5F3<8c_yM4;hRBGZ3$ThYo!6Ps=i@s-lPx{R+>jR<9{zOn@!dEdt1-oT^+jAQ?J z6LD5IXvTr9NNj^heMs5Vn?{7#8Y7~^|C8YcT0_=mU>r+QoE5Psc8)$Du}F>&M~H7_ wjN)AFx_1Ot(c@K@!TL<*hm#eVyw-X@Keg&>OC;c#OujZTy`{C2cWxy0Z?^~Q{{R30 diff --git a/pom.xml b/pom.xml index 1e83266..71aa56c 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ com.iflytop uf - 0.0.20 + 0.0.21 diff --git a/src/main/java/com/iflytop/a800/controller/DemoController.java b/src/main/java/com/iflytop/a800/controller/DemoController.java index 140ffd0..65c9acf 100644 --- a/src/main/java/com/iflytop/a800/controller/DemoController.java +++ b/src/main/java/com/iflytop/a800/controller/DemoController.java @@ -1,6 +1,7 @@ package com.iflytop.a800.controller; import com.iflytop.a800.device.Device; import com.iflytop.a800.resource.BufferTube; +import com.iflytop.uf.UfActuatorCmdExecutor; import com.iflytop.uf.controller.UfApiControllerBase; import com.iflytop.uf.controller.UfApiResponse; import org.springframework.stereotype.Controller; @@ -41,4 +42,37 @@ public class DemoController extends UfApiControllerBase { pipette.aspirateFromLargeBufferTube(tube, 50); return this.success(); } + + @PostMapping("/api/demo/pipette-aspirate-from-emergency-tube") + @ResponseBody + public UfApiResponse pipetteAspirateFromEmergencyTube() { + var pipette = Device.getInstance().pipette; + pipette.aspirateFromEmergencyTube(0, 100); + UfActuatorCmdExecutor.execute("Pipette","pipette_ctrl_move_to_ul", "0"); + pipette.aspirateFromEmergencyTube(1, 100); + UfActuatorCmdExecutor.execute("Pipette","pipette_ctrl_move_to_ul", "0"); + return this.success(); + } + + @PostMapping("/api/demo/pipette-aspirate-from-sample-epp-0.5") + @ResponseBody + public UfApiResponse pipetteAspirateFromSampleEpp05() { + var pipette = Device.getInstance().pipette; + for ( int i=0; i<10; i++) { + pipette.aspirateFromSampleEpp0_5(i, 100); + UfActuatorCmdExecutor.execute("Pipette","pipette_ctrl_move_to_ul", "0"); + } + return this.success(); + } + + @PostMapping("/api/demo/pipette-aspirate-from-sample-epp-1.5") + @ResponseBody + public UfApiResponse pipetteAspirateFromSampleEpp1_5() { + var pipette = Device.getInstance().pipette; + for ( int i=0; i<10; i++) { + pipette.aspirateFromSampleEpp1_5(i, 100); + UfActuatorCmdExecutor.execute("Pipette","pipette_ctrl_move_to_ul", "0"); + } + return this.success(); + } } diff --git a/src/main/java/com/iflytop/a800/device/Pipette.java b/src/main/java/com/iflytop/a800/device/Pipette.java index 5112120..9efc0f0 100644 --- a/src/main/java/com/iflytop/a800/device/Pipette.java +++ b/src/main/java/com/iflytop/a800/device/Pipette.java @@ -163,15 +163,68 @@ public class Pipette { this.aspirateWithLiquidLevelFollow(volume, depth); } + // 从急诊试管吸液 + public void aspirateFromEmergencyTube( Integer index, Integer volume ) { + UfCmdSnippetExecutor.execute(String.format("PipetteAspirateFromEmergencyTubePrepare.%d", index)); + + var maxDepth = UfMdbOption.getInteger("EmergencyTubeLiquidDetectMaxDepth"); + var threshold = UfMdbOption.getInteger("EmergencyTubeLiquidDetectThreshold"); + this.moveToLiquidLevel(maxDepth, threshold); + + Double coefficient = UfMdbOption.getDouble("EmergencyTubeLiquidLevelFollowCoefficient"); + Integer depth = (int)(coefficient * volume); + this.aspirateWithLiquidLevelFollow(volume, depth); + } + + // 从样本Epp0.5吸液 + public void aspirateFromSampleEpp0_5( Integer index, Integer volume ) { + var tubeRackTubeStartPos = UfMdbOption.getInteger("SampleTubeRackTubeStartPos"); + var tubeRackTubeDistance = UfMdbOption.getInteger("SampleTubeRackTubeDistance"); + Map params = Map.of("tubePos", tubeRackTubeStartPos + index * tubeRackTubeDistance); + UfCmdSnippetExecutor.execute("PipetteAspirateFromSampleEpp0.5", params); + + var maxDepth = UfMdbOption.getInteger("SampleTubeRackEpp0.5TubeLiquidDetectMaxDepth"); + var threshold = UfMdbOption.getInteger("SampleTubeRackEpp0.5TubeLiquidDetectThreshold"); + this.moveToLiquidLevel(maxDepth, threshold); + + Double coefficient = UfMdbOption.getDouble("SampleTubeRackEpp0.5TubeLiquidLevelFollowCoefficient"); + Integer depth = (int)(coefficient * volume); + this.aspirateWithLiquidLevelFollow(volume, depth); + } + + // 从样本Epp0.5吸液 + public void aspirateFromSampleEpp1_5( Integer index, Integer volume ) { + var tubeRackTubeStartPos = UfMdbOption.getInteger("SampleTubeRackTubeStartPos"); + var tubeRackTubeDistance = UfMdbOption.getInteger("SampleTubeRackTubeDistance"); + Map params = Map.of("tubePos", tubeRackTubeStartPos + index * tubeRackTubeDistance); + UfCmdSnippetExecutor.execute("PipetteAspirateFromSampleEpp1.5", params); + + var maxDepth = UfMdbOption.getInteger("SampleTubeRackEpp1.5TubeLiquidDetectMaxDepth"); + var threshold = UfMdbOption.getInteger("SampleTubeRackEpp1.5TubeLiquidDetectThreshold"); + this.moveToLiquidLevel(maxDepth, threshold); + + Double coefficient = UfMdbOption.getDouble("SampleTubeRackEpp1.5TubeLiquidLevelFollowCoefficient"); + Integer depth = (int)(coefficient * volume); + this.aspirateWithLiquidLevelFollow(volume, depth); + } + // 移动到液面 private void moveToLiquidLevel( Integer maxDepth, Integer threshold ) { int stepDepth = 10; int depth = 0; do { - String capValStr = UfActuatorCmdExecutor.execute("Pipette", "read_pipette_capacitance_val"); - int capVal = Integer.parseInt(capValStr); - if ( capVal > threshold ) { - break; + int capMatchCount = 0; + for ( int i=0; i<3; i++) { + String capValStr = UfActuatorCmdExecutor.execute("Pipette", "read_pipette_capacitance_val"); + LOG.info("[Pipette] Capacitance value : {}; threshold : {}", capValStr, threshold); + int capVal = Integer.parseInt(capValStr); + if ( capVal > threshold ) { + capMatchCount ++; + } + UfCommon.delay(10); + } + if ( 1 < capMatchCount ) { + break ; } depth += stepDepth;