From 3c893d58538303adfb137248e677f8f428bacfd1 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Thu, 17 Oct 2024 14:10:49 +0800 Subject: [PATCH] update --- app.db | Bin 225280 -> 225280 bytes src/main/java/a8k/constant/AppConstant.java | 8 +- .../pagecontrol/ExtApiTabConfig.java | 3 +- .../calibration/HbotConsumablePosCalibration.java | 267 --------------------- .../HbotLittleBottleConsumableCalibration.java | 237 ++++++++++++++++++ .../calibration/HbotTipPosCalibration.java | 222 +++++++++++++++++ ...ReactionPlatesTransmitControlerCalibration.java | 46 ++-- .../app/devicedriver/pos/HbotConsumablePosMgr.java | 116 +++++---- .../a8k/service/debug/AppDebugHelperService.java | 12 +- src/main/java/a8k/type/ConsumableGroup.java | 2 +- src/main/java/a8k/type/HbotConsumablePosParam.java | 41 ++-- .../a8k/type/LittleBottleConsumablePosInfo.java | 15 ++ .../a8k/type/LittleBottleConsumableRefPoint.java | 25 ++ .../java/a8k/type/LittleBottleConsumableType.java | 6 + src/main/java/a8k/utils/ZSimplAlgo.java | 19 +- 15 files changed, 650 insertions(+), 369 deletions(-) delete mode 100644 src/main/java/a8k/service/app/devicedriver/calibration/HbotConsumablePosCalibration.java create mode 100644 src/main/java/a8k/service/app/devicedriver/calibration/HbotLittleBottleConsumableCalibration.java create mode 100644 src/main/java/a8k/service/app/devicedriver/calibration/HbotTipPosCalibration.java create mode 100644 src/main/java/a8k/type/LittleBottleConsumablePosInfo.java create mode 100644 src/main/java/a8k/type/LittleBottleConsumableRefPoint.java create mode 100644 src/main/java/a8k/type/LittleBottleConsumableType.java diff --git a/app.db b/app.db index 6f968439ca20dc72e3d2fbc9444645f882755e13..3b6fffa5a3c58059569b50d2b38937342bd1ee09 100644 GIT binary patch delta 101 zcmZp8z}xVEcY?Iw3kC)Tb09VYVig7kPOphN#*8mECLBD^YsD^ZY|PjaTauWRlRDY) zg79X?3-*kRmYW+d$}llnY@T=dHzT9@=2=%CGBTQNuDO1Uozbe<`F^|eea7w1_nG!i F002jzBl`dV delta 101 zcmZp8z}xVEcY?IwE(Qh$b09VYVig7kPP2(R#*Di*CLBD^YrrmUY|PjaTauWRlRDY) zg79X?3-*kR`kNas$}lnNZJu}eHzT9&=2=%CGBWCHuDO1UozbA#`F^|eea7w1_nG!i F0010hBToPT diff --git a/src/main/java/a8k/constant/AppConstant.java b/src/main/java/a8k/constant/AppConstant.java index 4bcb0ca..b7f63ea 100644 --- a/src/main/java/a8k/constant/AppConstant.java +++ b/src/main/java/a8k/constant/AppConstant.java @@ -3,9 +3,11 @@ package a8k.constant; import a8k.type.Consumable; public class AppConstant { - public static final int CONSUMABLE_NUM = 25; - public static final int TIP_NUM = 120; - public static final String APP_VERSION = "1.0.0"; + public static final int CONSUMABLE_NUM = 25; + public static final int CONSUMABLE_COL_NUM = 5; + public static final int CONSUMABLE_ROW_NUM = 5; + public static final int TIP_NUM = 120; + public static final String APP_VERSION = "1.0.0"; public static final Integer ShakeModTubeScanerClampingSVReleasePos = 10; public static final Integer ShakeModTubeScanerClampingSVClampingPos = 900; diff --git a/src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java b/src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java index 8d025d7..6249665 100644 --- a/src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java +++ b/src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java @@ -18,7 +18,8 @@ public enum ExtApiTabConfig { TubeFeedingModulePosCalibration("校准.试管入料校准", true), TubePreProcesPosCalibration("校准.试管预处理校准", true), ReactionPlatesTransmitControlerCalibration("校准.反应板相关位置校准", true), - HbotConsumablePosCalibration("校准.耗材位置校准", true), + HbotTipPosCalibration("校准.Tip耗材位置校准", true), + HbotLittleBottleConsumableCalibration("校准.小瓶耗材位置校准", true), ActionReactorService("底层调试.单步调试", false),//OK Hbot2DCodeScanPos("参数.Hbot二维码扫描坐标参数", false), diff --git a/src/main/java/a8k/service/app/devicedriver/calibration/HbotConsumablePosCalibration.java b/src/main/java/a8k/service/app/devicedriver/calibration/HbotConsumablePosCalibration.java deleted file mode 100644 index 5102197..0000000 --- a/src/main/java/a8k/service/app/devicedriver/calibration/HbotConsumablePosCalibration.java +++ /dev/null @@ -1,267 +0,0 @@ -package a8k.service.app.devicedriver.calibration; - - -import a8k.constant.AppConstant; -import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; -import a8k.extapi_controler.utils.ExtApiFn; -import a8k.extapi_controler.utils.ExtApiTab; -import a8k.hardware.type.a8kcanprotocol.A8kEcode; -import a8k.service.app.devicedriver.basectrl.CodeScaner; -import a8k.service.app.devicedriver.basectrl.HbotBaseMoveControler; -import a8k.service.app.devicedriver.basectrl.HbotModule; -import a8k.service.app.devicedriver.basectrl.PipetteCtrlModule; -import a8k.service.app.devicedriver.ctrl.ConsumablesScanCtrl; -import a8k.service.app.devicedriver.ctrl.HbotControler; -import a8k.service.app.devicedriver.pos.Hbot2DCodeScanPos; -import a8k.service.app.devicedriver.pos.HbotConsumablePosMgr; -import a8k.service.app.devicedriver.pos.HbotSamplePosMgr; -import a8k.type.*; -import a8k.type.cfg.Pos2d; -import a8k.type.cfg.Pos3d; -import a8k.type.exception.AppException; -import a8k.type.type.TipGroup; -import a8k.utils.ZJsonHelper; -import a8k.utils.ZSimplAlgo; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import jakarta.annotation.Resource; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; -import org.slf4j.Logger; -import org.springframework.context.annotation.Bean; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@ExtApiTab(cfg = ExtApiTabConfig.HbotConsumablePosCalibration) -@Component -@Aspect -public class HbotConsumablePosCalibration { - static Logger logger = org.slf4j.LoggerFactory.getLogger(HbotConsumablePosCalibration.class); - - @Resource - PipetteCtrlModule pipetteCtrlModule; - @Resource - HbotModule hbotModule; - - - @Resource - HbotControler hbotControler; - @Resource - HbotConsumablePosMgr hbotConsumablePosMgr; - - Boolean stopFlag = false; - - Boolean checkStopFlag() { - if (stopFlag) { - stopFlag = false; - return true; - } - return false; - } - - void resetStopFlag() { - stopFlag = false; - } - - void setStopFlag() { - stopFlag = true; - } - - - @ExtApiFn(name = "获取所有坐标", group = "基础", order = 1) - public Object getPoss() throws AppException { - return hbotConsumablePosMgr.getParams(); - } - - - // 测试工具 - @ExtApiFn(name = "归零", group = "测试工具", order = 11) - public void deviceReset() throws AppException { - enableModule(); - pipetteCtrlModule.zMotorMoveZeroBlock(); - hbotModule.moveToZeroBlock(); - } - - @ExtApiFn(name = "使能相关模块", group = "测试工具", order = 12) - public void enableModule() throws AppException { - pipetteCtrlModule.zMotorEnable(1); - hbotModule.enable(1); - } - - @ExtApiFn(name = "失能相关模块", group = "测试工具", order = 13) - public void disableModule() throws AppException { - pipetteCtrlModule.zMotorEnable(0); - hbotModule.enable(0); - } - - // - // 标定 - // - - TipGroup tipGroup; - List tipRefPosList; - Pos3d tip000; - Double tipdx; - Double tipdy; - - - @ExtApiFn(name = "开始标定Tip坐标", group = "标定TIP坐标", order = 20) - public void startCalibrateTipPos(TipGroup tipGroup) throws AppException { - this.tipGroup = tipGroup; - tipRefPosList = new java.util.ArrayList<>(); - deviceReset(); - disableModule(); - tipdx = 0.0; - tipdy = 0.0; - tip000 = new Pos3d(0, 0, 0); - } - - - @ExtApiFn(name = "添加Tip参考点", group = "标定TIP坐标", order = 21) - public Object addTipPosRefPoint(TipRowNum row, TipColumnNum columnNum) throws AppException { - enableModule(); - Pos2d xypos = hbotModule.readPos(); - pipetteCtrlModule.zMotorMeasureDistance(); - Integer z = pipetteCtrlModule.zMotorReadMeasureDistanceResult(); - pipetteCtrlModule.putTipBlock(); - TipRefPoint tipRefPoint = new TipRefPoint(row, columnNum, new Pos3d(xypos.x, xypos.y, z)); - tipRefPosList.add(tipRefPoint); - disableModule(); - - Map ret = new java.util.HashMap<>(); - ret.put("newPoint", tipRefPoint); - ret.put("computeResult", computeTipGroupPos()); - return ret; - } - - @ExtApiFn(name = "删除上一个Tip参考点", group = "标定TIP坐标", order = 22) - public Object removeTipPosRefPoint() throws AppException { - if (!tipRefPosList.isEmpty()) { - tipRefPosList.remove(tipRefPosList.size() - 1); - } - Map ret = new java.util.HashMap<>(); - ret.put("computeResult", computeTipGroupPos()); - return ret; - } - - - @ExtApiFn(name = "计算Tip坐标", group = "标定TIP坐标", order = 23) - public ObjectNode computeTipGroupPos() throws AppException { - TipRefPoint tip_ref_01_01 = tipRefPosList.stream().filter(tipRefPoint -> tipRefPoint.eq(TipRowNum.ROW00, TipColumnNum.Colu00)).findFirst().orElse(null); - - if (tip_ref_01_01 == null) { - throw new AppException(A8kEcode.CALIBRATION_TIP_REF_POINT_NOT_ENOUGH); - } - - - //计算tip01_01_x,取所有第一列tip坐标x的平局值 - Double tip01_01_x = ZSimplAlgo.computeAverage( - tipRefPosList.stream().filter(tipRefPoint -> tipRefPoint.col == TipColumnNum.Colu00). - map(tipRefPoint -> Double.valueOf(tipRefPoint.pos.x)).toList() - ); - - //计算tip01_01_y,取所有第1行tip坐标y的平局值 - Double tip01_01_y = ZSimplAlgo.computeAverage( - tipRefPosList.stream().filter(tipRefPoint -> tipRefPoint.row == TipRowNum.ROW00). - map(tipRefPoint -> Double.valueOf(tipRefPoint.pos.y)).toList() - ); - - //计算z,取所有tip坐标z的平局值 - Double tip01_01_z = ZSimplAlgo.computeAverage( - tipRefPosList.stream().map(tipRefPoint -> Double.valueOf(tipRefPoint.pos.z)).toList() - ); - //计算dx,所有点到tip01_01的距离除以行数 之后的平均值 - Double dx = ZSimplAlgo.computeAverage( - tipRefPosList.stream().filter(point -> !point.col.equals(TipColumnNum.Colu00)). - map(point -> Math.abs(point.pos.x - Double.valueOf(tip_ref_01_01.pos.x)) / point.col.ordinal()).toList() - ); - //计算dy,所有点到tip01_01的距离除以列数 之后的平均值 - Double dy = ZSimplAlgo.computeAverage( - tipRefPosList.stream().filter(point -> !point.row.equals(TipRowNum.ROW00)). - map(point -> Math.abs(point.pos.y - Double.valueOf(tip_ref_01_01.pos.y)) / point.row.ordinal()).toList() - ); - - tip01_01_z += 3; - - tip000 = new Pos3d(tip01_01_x.intValue(), tip01_01_y.intValue(), tip01_01_z.intValue()); - tipdx = dx; - tipdy = dy; - - - ObjectNode node = new ObjectMapper().createObjectNode(); - node.put("tip000", ZJsonHelper.createObjectNode(tip000)); - node.put("tipdx", tipdx); - node.put("tipdy", tipdy); - return node; - } - - - @ExtApiFn(name = "保存计算结果", group = "标定TIP坐标", order = 24) - public void saveTipGroupPos() throws AppException { - hbotConsumablePosMgr.setTipGroupParam(tipGroup, tip000, tipdx, tipdy); - } - - - // - // 校验 - // - @ExtApiFn(name = "校验Tip坐标", group = "校验", order = 30) - public void testTakeTip(TipGroup tipGroup) throws AppException { - resetStopFlag(); - enableModule(); - for (int i = 0; i < AppConstant.TIP_NUM; i++) { - hbotControler.testTakeTip(tipGroup, i); - if (checkStopFlag()) - return; - } - } - - @ExtApiFn(name = "校验小瓶缓冲液坐标", group = "校验", order = 31) - public void testMoveToLittleBufferPos() throws AppException { - resetStopFlag(); - enableModule(); - for (ConsumableGroup group : ConsumableGroup.values()) { - for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) { - hbotControler.moveToLittleBufferPos(group, i); - if (checkStopFlag()) - return; - } - } - - } - - @ExtApiFn(name = "校验探测物质坐标", group = "校验", order = 32) - public void testMoveToProbeSubstancePos() throws AppException { - resetStopFlag(); - enableModule(); - for (ConsumableGroup group : ConsumableGroup.values()) { - for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) { - hbotControler.moveToProbeSubstancePos(group, i); - if (checkStopFlag()) - return; - } - } - } - - @ExtApiFn(name = "校验大瓶缓冲液坐标", group = "校验", order = 33) - public void testMoveToLargeBufferPos() throws AppException { - resetStopFlag(); - enableModule(); - for (ConsumableGroup group : ConsumableGroup.values()) { - hbotControler.moveToLargeBufferPos(group); - if (checkStopFlag()) - return; - } - } - - @ExtApiFn(name = "停止校验", group = "校验", order = 34) - public void stopTest() throws AppException { - setStopFlag(); - } - - -} diff --git a/src/main/java/a8k/service/app/devicedriver/calibration/HbotLittleBottleConsumableCalibration.java b/src/main/java/a8k/service/app/devicedriver/calibration/HbotLittleBottleConsumableCalibration.java new file mode 100644 index 0000000..781907e --- /dev/null +++ b/src/main/java/a8k/service/app/devicedriver/calibration/HbotLittleBottleConsumableCalibration.java @@ -0,0 +1,237 @@ +package a8k.service.app.devicedriver.calibration; + + +import a8k.constant.AppConstant; +import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; +import a8k.extapi_controler.utils.ExtApiFn; +import a8k.extapi_controler.utils.ExtApiTab; +import a8k.service.app.devicedriver.basectrl.HbotModule; +import a8k.service.app.devicedriver.basectrl.PipetteCtrlModule; +import a8k.service.app.devicedriver.ctrl.HbotControler; +import a8k.service.app.devicedriver.pos.HbotConsumablePosMgr; +import a8k.type.*; +import a8k.type.cfg.Pos2d; +import a8k.type.cfg.Pos3d; +import a8k.type.exception.AppException; +import a8k.utils.ZSimplAlgo; +import jakarta.annotation.Resource; +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.springframework.stereotype.Component; + +import java.util.List; + +@ExtApiTab(cfg = ExtApiTabConfig.HbotLittleBottleConsumableCalibration) +@Component +@Aspect +public class HbotLittleBottleConsumableCalibration { + static Logger logger = org.slf4j.LoggerFactory.getLogger(HbotLittleBottleConsumableCalibration.class); + + @Resource + PipetteCtrlModule pipetteCtrlModule; + @Resource + HbotModule hbotModule; + + + @Resource + HbotControler hbotControler; + @Resource + HbotConsumablePosMgr hbotConsumablePosMgr; + + Boolean stopFlag = false; + + Boolean checkStopFlag() { + if (stopFlag) { + stopFlag = false; + return true; + } + return false; + } + + void resetStopFlag() { + stopFlag = false; + } + + void setStopFlag() { + stopFlag = true; + } + + + @ExtApiFn(name = "获取所有坐标", group = "基础", order = 1) + public Object getPoss() throws AppException { + return hbotConsumablePosMgr.getParams(); + } + + + // 测试工具 + @ExtApiFn(name = "归零", group = "测试工具", order = 11) + public void moveToZero() throws AppException { + enableModule(); + pipetteCtrlModule.zMotorMoveZeroBlock(); + hbotModule.moveToZeroBlock(); + } + + @ExtApiFn(name = "使能相关模块", group = "测试工具", order = 12) + public void enableModule() throws AppException { + pipetteCtrlModule.zMotorEnable(1); + hbotModule.enable(1); + } + + @ExtApiFn(name = "失能相关模块", group = "测试工具", order = 13) + public void disableModule() throws AppException { + pipetteCtrlModule.zMotorEnable(0); + hbotModule.enable(0); + } + + + LittleBottleConsumableType littleBottleConsumableType = LittleBottleConsumableType.BufferSolution; + List littleBottleConsumableRefPoint; + LittleBottleConsumablePosInfo littleBottleConsumablePosInfo; + + + @ExtApiFn(name = "开始标定小瓶坐标", group = "标定小瓶坐标", order = 30) + public void startCalibrateLittleBottleGroup(LittleBottleConsumableType type) throws AppException { + littleBottleConsumablePosInfo = null; + littleBottleConsumableRefPoint = new java.util.ArrayList<>(); + littleBottleConsumableType = type; + moveToZero(); + disableModule(); + } + + @ExtApiFn(name = "添加小瓶参考点", group = "标定小瓶坐标", order = 31) + public Object addLittleBottleGroupRefPoint(ConsumableGroup group, Integer off0To24) throws AppException { + enableModule(); + Pos2d xypos = hbotModule.readPos(); + pipetteCtrlModule.zMotorMeasureDistance(); + Integer z = pipetteCtrlModule.zMotorReadMeasureDistanceResult(); + LittleBottleConsumableRefPoint littleBufferRefPoint = new LittleBottleConsumableRefPoint(group, off0To24, new Pos3d(xypos.x, xypos.y, z)); + this.littleBottleConsumableRefPoint.add(littleBufferRefPoint); + disableModule(); + return computeLittleBottlePosInfo(); + } + + @ExtApiFn(name = "删除上一个小瓶参考点", group = "标定小瓶坐标", order = 32) + public LittleBottleConsumablePosInfo computeLittleBottlePosInfo() { + //计算y0,所有group==0,1,2,同时0<=off<5的点,求平均 + Double[] y = new Double[2]; + Double[] x = new Double[3]; + Double[] dxs = new Double[6]; + Double[] dys = new Double[6]; + Double dx; + Double dy; + Double z; + + y[0] = ZSimplAlgo.computeAverage( + littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() < 3 && point.index < 5). + map(point -> point.pos.y).toList() + ); + //计算y1,所有group==3,4,5,同时0<=off<5的点,求平均 + y[1] = ZSimplAlgo.computeAverage( + littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() >= 3 && point.index < 5). + map(point -> point.pos.y).toList() + ); + + //计算y0,所有group==0,3,同时off==0,5,10,15,20的点,求y平均 + x[0] = ZSimplAlgo.computeAverage( + littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() % 3 == 0 && point.index % 5 == 0). + map(point -> point.pos.y).toList() + ); + //计算y1,所有group==1,4,同时off==0,5,10,15,20的点,求y平均 + x[1] = ZSimplAlgo.computeAverage( + littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() % 3 == 1 && point.index % 5 == 0). + map(point -> point.pos.y).toList() + ); + //计算y2 + x[2] = ZSimplAlgo.computeAverage( + littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() % 3 == 2 && point.index % 5 == 0). + map(point -> point.pos.y).toList() + ); + // + z = ZSimplAlgo.computeAverage( + littleBottleConsumableRefPoint.stream().map(point -> point.pos.z).toList() + ); + //计算d0x,所有 非0,5,10,15,20的点,到x0的距离/偏移差值,求平均 + for (int i = 0; i < 6; i++) { + int finalI = i; + dxs[i] = ZSimplAlgo.computeAverage( + littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() == finalI && point.getColOff() != 0). + map(point -> point.pos.x - x[finalI % 3] / (point.getColOff())).toList() + ); + } + dx = ZSimplAlgo.computeAverage(dxs); + //计算dy, + for (int i = 0; i < 6; i++) { + int finalI = i; + dys[i] = ZSimplAlgo.computeAverage( + littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() == finalI && point.getRowOff() != 0). + map(point -> point.pos.y - y[finalI / 3] / (point.getRowOff())).toList() + ); + } + dy = ZSimplAlgo.computeAverage(dys); + + littleBottleConsumablePosInfo = new LittleBottleConsumablePosInfo(); + littleBottleConsumablePosInfo.g0_000 = new Pos3d(x[0].intValue(), y[0].intValue(), z.intValue()); + littleBottleConsumablePosInfo.g1_000 = new Pos3d(x[1].intValue(), y[0].intValue(), z.intValue()); + littleBottleConsumablePosInfo.g2_000 = new Pos3d(x[2].intValue(), y[0].intValue(), z.intValue()); + littleBottleConsumablePosInfo.g3_000 = new Pos3d(x[0].intValue(), y[1].intValue(), z.intValue()); + littleBottleConsumablePosInfo.g4_000 = new Pos3d(x[1].intValue(), y[1].intValue(), z.intValue()); + littleBottleConsumablePosInfo.g5_000 = new Pos3d(x[2].intValue(), y[1].intValue(), z.intValue()); + littleBottleConsumablePosInfo.dx = dx; + littleBottleConsumablePosInfo.dy = dy; + return littleBottleConsumablePosInfo; + } + + @ExtApiFn(name = "保存小瓶坐标", group = "标定小瓶坐标", order = 33) + public void saveLittleBottleConsumablePosInfo() throws AppException { + hbotConsumablePosMgr.setLittleBottleConsumablePosInfo(littleBottleConsumableType, littleBottleConsumablePosInfo); + } + + // + // 校验 + // + + @ExtApiFn(name = "校验小瓶缓冲液坐标", group = "校验", order = 301) + public void testMoveToLittleBufferPos() throws AppException { + resetStopFlag(); + enableModule(); + for (ConsumableGroup group : ConsumableGroup.values()) { + for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) { + hbotControler.moveToLittleBufferPos(group, i); + if (checkStopFlag()) + return; + } + } + + } + + @ExtApiFn(name = "校验探测物质坐标", group = "校验", order = 302) + public void testMoveToProbeSubstancePos() throws AppException { + resetStopFlag(); + enableModule(); + for (ConsumableGroup group : ConsumableGroup.values()) { + for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) { + hbotControler.moveToProbeSubstancePos(group, i); + if (checkStopFlag()) + return; + } + } + } + + // @ExtApiFn(name = "校验大瓶缓冲液坐标", group = "校验", order = 303) + // public void testMoveToLargeBufferPos() throws AppException { + // resetStopFlag(); + // enableModule(); + // for (ConsumableGroup group : ConsumableGroup.values()) { + // hbotControler.moveToLargeBufferPos(group); + // if (checkStopFlag()) + // return; + // } + // } + + @ExtApiFn(name = "停止校验", group = "校验", order = 304) + public void stopTest() throws AppException { + setStopFlag(); + } + + +} diff --git a/src/main/java/a8k/service/app/devicedriver/calibration/HbotTipPosCalibration.java b/src/main/java/a8k/service/app/devicedriver/calibration/HbotTipPosCalibration.java new file mode 100644 index 0000000..0070a6d --- /dev/null +++ b/src/main/java/a8k/service/app/devicedriver/calibration/HbotTipPosCalibration.java @@ -0,0 +1,222 @@ +package a8k.service.app.devicedriver.calibration; + + +import a8k.constant.AppConstant; +import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; +import a8k.extapi_controler.utils.ExtApiFn; +import a8k.extapi_controler.utils.ExtApiTab; +import a8k.hardware.type.a8kcanprotocol.A8kEcode; +import a8k.service.app.devicedriver.basectrl.HbotModule; +import a8k.service.app.devicedriver.basectrl.PipetteCtrlModule; +import a8k.service.app.devicedriver.ctrl.HbotControler; +import a8k.service.app.devicedriver.pos.HbotConsumablePosMgr; +import a8k.type.*; +import a8k.type.cfg.Pos2d; +import a8k.type.cfg.Pos3d; +import a8k.type.exception.AppException; +import a8k.type.LittleBottleConsumablePosInfo; +import a8k.type.type.TipGroup; +import a8k.utils.ZJsonHelper; +import a8k.utils.ZSimplAlgo; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import jakarta.annotation.Resource; +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +@ExtApiTab(cfg = ExtApiTabConfig.HbotTipPosCalibration) +@Component +@Aspect +public class HbotTipPosCalibration { + static Logger logger = org.slf4j.LoggerFactory.getLogger(HbotTipPosCalibration.class); + + @Resource + PipetteCtrlModule pipetteCtrlModule; + @Resource + HbotModule hbotModule; + + + @Resource + HbotControler hbotControler; + @Resource + HbotConsumablePosMgr hbotConsumablePosMgr; + + Boolean stopFlag = false; + + Boolean checkStopFlag() { + if (stopFlag) { + stopFlag = false; + return true; + } + return false; + } + + void resetStopFlag() { + stopFlag = false; + } + + void setStopFlag() { + stopFlag = true; + } + + + @ExtApiFn(name = "获取所有坐标", group = "基础", order = 1) + public Object getPoss() throws AppException { + return hbotConsumablePosMgr.getParams(); + } + + + // 测试工具 + @ExtApiFn(name = "归零", group = "测试工具", order = 11) + public void moveToZero() throws AppException { + enableModule(); + pipetteCtrlModule.zMotorMoveZeroBlock(); + hbotModule.moveToZeroBlock(); + } + + @ExtApiFn(name = "使能相关模块", group = "测试工具", order = 12) + public void enableModule() throws AppException { + pipetteCtrlModule.zMotorEnable(1); + hbotModule.enable(1); + } + + @ExtApiFn(name = "失能相关模块", group = "测试工具", order = 13) + public void disableModule() throws AppException { + pipetteCtrlModule.zMotorEnable(0); + hbotModule.enable(0); + } + + // + // 标定 + // + + TipGroup tipGroup; + List tipRefPosList; + Pos3d tip000; + Double tipdx; + Double tipdy; + + + @ExtApiFn(name = "开始标定Tip坐标", group = "标定TIP坐标", order = 20) + public void startCalibrateTipPos(TipGroup tipGroup) throws AppException { + this.tipGroup = tipGroup; + tipRefPosList = new java.util.ArrayList<>(); + moveToZero(); + disableModule(); + tipdx = 0.0; + tipdy = 0.0; + tip000 = new Pos3d(0, 0, 0); + } + + + @ExtApiFn(name = "添加Tip参考点", group = "标定TIP坐标", order = 21) + public Object addTipPosRefPoint(TipRowNum row, TipColumnNum columnNum) throws AppException { + enableModule(); + Pos2d xypos = hbotModule.readPos(); + pipetteCtrlModule.zMotorMeasureDistance(); + Integer z = pipetteCtrlModule.zMotorReadMeasureDistanceResult(); + pipetteCtrlModule.putTipBlock(); + TipRefPoint tipRefPoint = new TipRefPoint(row, columnNum, new Pos3d(xypos.x, xypos.y, z)); + tipRefPosList.add(tipRefPoint); + disableModule(); + + Map ret = new java.util.HashMap<>(); + ret.put("newPoint", tipRefPoint); + ret.put("computeResult", computeTipGroupPos()); + return ret; + } + + @ExtApiFn(name = "删除上一个Tip参考点", group = "标定TIP坐标", order = 22) + public Object removeTipPosRefPoint() throws AppException { + if (!tipRefPosList.isEmpty()) { + tipRefPosList.remove(tipRefPosList.size() - 1); + } + Map ret = new java.util.HashMap<>(); + ret.put("computeResult", computeTipGroupPos()); + return ret; + } + + + @ExtApiFn(name = "计算Tip坐标", group = "标定TIP坐标", order = 23) + public ObjectNode computeTipGroupPos() throws AppException { + TipRefPoint tip_ref_01_01 = tipRefPosList.stream().filter(tipRefPoint -> tipRefPoint.eq(TipRowNum.ROW00, TipColumnNum.Colu00)).findFirst().orElse(null); + + if (tip_ref_01_01 == null) { + throw new AppException(A8kEcode.CALIBRATION_TIP_REF_POINT_NOT_ENOUGH); + } + + + //计算tip01_01_x,取所有第一列tip坐标x的平局值 + Double tip01_01_x = ZSimplAlgo.computeAverage( + tipRefPosList.stream().filter(tipRefPoint -> tipRefPoint.col == TipColumnNum.Colu00). + map(tipRefPoint -> Double.valueOf(tipRefPoint.pos.x)).toList() + ); + + //计算tip01_01_y,取所有第1行tip坐标y的平局值 + Double tip01_01_y = ZSimplAlgo.computeAverage( + tipRefPosList.stream().filter(tipRefPoint -> tipRefPoint.row == TipRowNum.ROW00). + map(tipRefPoint -> Double.valueOf(tipRefPoint.pos.y)).toList() + ); + + //计算z,取所有tip坐标z的平局值 + Double tip01_01_z = ZSimplAlgo.computeAverage( + tipRefPosList.stream().map(tipRefPoint -> Double.valueOf(tipRefPoint.pos.z)).toList() + ); + //计算dx,所有点到tip01_01的距离除以行数 之后的平均值 + Double dx = ZSimplAlgo.computeAverage( + tipRefPosList.stream().filter(point -> !point.col.equals(TipColumnNum.Colu00)). + map(point -> Math.abs(point.pos.x - Double.valueOf(tip_ref_01_01.pos.x)) / point.col.ordinal()).toList() + ); + //计算dy,所有点到tip01_01的距离除以列数 之后的平均值 + Double dy = ZSimplAlgo.computeAverage( + tipRefPosList.stream().filter(point -> !point.row.equals(TipRowNum.ROW00)). + map(point -> Math.abs(point.pos.y - Double.valueOf(tip_ref_01_01.pos.y)) / point.row.ordinal()).toList() + ); + + tip01_01_z += 3; + + tip000 = new Pos3d(tip01_01_x.intValue(), tip01_01_y.intValue(), tip01_01_z.intValue()); + tipdx = dx; + tipdy = dy; + + + ObjectNode node = new ObjectMapper().createObjectNode(); + node.put("tip000", ZJsonHelper.createObjectNode(tip000)); + node.put("tipdx", tipdx); + node.put("tipdy", tipdy); + return node; + } + + + @ExtApiFn(name = "保存计算结果", group = "标定TIP坐标", order = 24) + public void saveTipGroupPos() throws AppException { + hbotConsumablePosMgr.setTipGroupParam(tipGroup, tip000, tipdx, tipdy); + } + + + + // + // 校验 + // + @ExtApiFn(name = "校验Tip坐标", group = "校验", order = 300) + public void testTakeTip(TipGroup tipGroup) throws AppException { + resetStopFlag(); + enableModule(); + for (int i = 0; i < AppConstant.TIP_NUM; i++) { + hbotControler.testTakeTip(tipGroup, i); + if (checkStopFlag()) + return; + } + } + + @ExtApiFn(name = "停止校验", group = "校验", order = 304) + public void stopTest() throws AppException { + setStopFlag(); + } + + +} diff --git a/src/main/java/a8k/service/app/devicedriver/calibration/ReactionPlatesTransmitControlerCalibration.java b/src/main/java/a8k/service/app/devicedriver/calibration/ReactionPlatesTransmitControlerCalibration.java index c615c10..8e39e2a 100644 --- a/src/main/java/a8k/service/app/devicedriver/calibration/ReactionPlatesTransmitControlerCalibration.java +++ b/src/main/java/a8k/service/app/devicedriver/calibration/ReactionPlatesTransmitControlerCalibration.java @@ -194,29 +194,29 @@ public class ReactionPlatesTransmitControlerCalibration { @ExtApiFn(name = "反应板.推所有丢所有", group = "校验", order = 1004) public void pushAllAndRemoveAll() throws AppException { - pushOneAndRemove(ConsumableGroup.GROUP1, IncubatorPos.SPACE01); - pushOneAndRemove(ConsumableGroup.GROUP2, IncubatorPos.SPACE02); - pushOneAndRemove(ConsumableGroup.GROUP3, IncubatorPos.SPACE03); - pushOneAndRemove(ConsumableGroup.GROUP4, IncubatorPos.SPACE04); - pushOneAndRemove(ConsumableGroup.GROUP5, IncubatorPos.SPACE05); - pushOneAndRemove(ConsumableGroup.GROUP6, IncubatorPos.SPACE06); - - pushOneAndRemove(ConsumableGroup.GROUP1, IncubatorPos.SPACE07); - pushOneAndRemove(ConsumableGroup.GROUP2, IncubatorPos.SPACE08); - pushOneAndRemove(ConsumableGroup.GROUP3, IncubatorPos.SPACE09); - pushOneAndRemove(ConsumableGroup.GROUP4, IncubatorPos.SPACE10); - pushOneAndRemove(ConsumableGroup.GROUP5, IncubatorPos.SPACE11); - pushOneAndRemove(ConsumableGroup.GROUP6, IncubatorPos.SPACE12); - - pushOneAndRemove(ConsumableGroup.GROUP1, IncubatorPos.SPACE13); - pushOneAndRemove(ConsumableGroup.GROUP2, IncubatorPos.SPACE14); - pushOneAndRemove(ConsumableGroup.GROUP3, IncubatorPos.SPACE15); - pushOneAndRemove(ConsumableGroup.GROUP4, IncubatorPos.SPACE16); - pushOneAndRemove(ConsumableGroup.GROUP5, IncubatorPos.SPACE17); - pushOneAndRemove(ConsumableGroup.GROUP6, IncubatorPos.SPACE18); - - pushOneAndRemove(ConsumableGroup.GROUP1, IncubatorPos.SPACE19); - pushOneAndRemove(ConsumableGroup.GROUP2, IncubatorPos.SPACE20); + pushOneAndRemove(ConsumableGroup.GROUP0, IncubatorPos.SPACE01); + pushOneAndRemove(ConsumableGroup.GROUP1, IncubatorPos.SPACE02); + pushOneAndRemove(ConsumableGroup.GROUP2, IncubatorPos.SPACE03); + pushOneAndRemove(ConsumableGroup.GROUP3, IncubatorPos.SPACE04); + pushOneAndRemove(ConsumableGroup.GROUP4, IncubatorPos.SPACE05); + pushOneAndRemove(ConsumableGroup.GROUP5, IncubatorPos.SPACE06); + + pushOneAndRemove(ConsumableGroup.GROUP0, IncubatorPos.SPACE07); + pushOneAndRemove(ConsumableGroup.GROUP1, IncubatorPos.SPACE08); + pushOneAndRemove(ConsumableGroup.GROUP2, IncubatorPos.SPACE09); + pushOneAndRemove(ConsumableGroup.GROUP3, IncubatorPos.SPACE10); + pushOneAndRemove(ConsumableGroup.GROUP4, IncubatorPos.SPACE11); + pushOneAndRemove(ConsumableGroup.GROUP5, IncubatorPos.SPACE12); + + pushOneAndRemove(ConsumableGroup.GROUP0, IncubatorPos.SPACE13); + pushOneAndRemove(ConsumableGroup.GROUP1, IncubatorPos.SPACE14); + pushOneAndRemove(ConsumableGroup.GROUP2, IncubatorPos.SPACE15); + pushOneAndRemove(ConsumableGroup.GROUP3, IncubatorPos.SPACE16); + pushOneAndRemove(ConsumableGroup.GROUP4, IncubatorPos.SPACE17); + pushOneAndRemove(ConsumableGroup.GROUP5, IncubatorPos.SPACE18); + + pushOneAndRemove(ConsumableGroup.GROUP0, IncubatorPos.SPACE19); + pushOneAndRemove(ConsumableGroup.GROUP1, IncubatorPos.SPACE20); } } diff --git a/src/main/java/a8k/service/app/devicedriver/pos/HbotConsumablePosMgr.java b/src/main/java/a8k/service/app/devicedriver/pos/HbotConsumablePosMgr.java index a815baa..1ff2576 100644 --- a/src/main/java/a8k/service/app/devicedriver/pos/HbotConsumablePosMgr.java +++ b/src/main/java/a8k/service/app/devicedriver/pos/HbotConsumablePosMgr.java @@ -7,6 +7,8 @@ import a8k.service.db.LowerDeviceParameterDBService; import a8k.service.db.utils.PosParameterReader; import a8k.type.ConsumableGroup; import a8k.type.HbotConsumablePosParam; +import a8k.type.LittleBottleConsumablePosInfo; +import a8k.type.LittleBottleConsumableType; import a8k.type.cfg.Pos3d; import a8k.type.type.TipGroup; import a8k.utils.ZJsonHelper; @@ -105,6 +107,46 @@ public class HbotConsumablePosMgr { posReader.updatePos(tipDyPos, dy); } + public void setLittleBottleConsumablePosInfo(LittleBottleConsumableType type, LittleBottleConsumablePosInfo info) { + HbotConsumablePosParam group0_000Pos; + HbotConsumablePosParam group1_000Pos; + HbotConsumablePosParam group2_000Pos; + HbotConsumablePosParam group3_000Pos; + HbotConsumablePosParam group4_000Pos; + HbotConsumablePosParam group5_000Pos; + HbotConsumablePosParam groupDX; + HbotConsumablePosParam groupDY; + + if (type.equals(LittleBottleConsumableType.BufferSolution)) { + group0_000Pos = HbotConsumablePosParam.LittleBufferGroup0_000Pos; + group1_000Pos = HbotConsumablePosParam.LittleBufferGroup1_000Pos; + group2_000Pos = HbotConsumablePosParam.LittleBufferGroup2_000Pos; + group3_000Pos = HbotConsumablePosParam.LittleBufferGroup3_000Pos; + group4_000Pos = HbotConsumablePosParam.LittleBufferGroup4_000Pos; + group5_000Pos = HbotConsumablePosParam.LittleBufferGroup5_000Pos; + groupDX = HbotConsumablePosParam.LittleBufferGroupDX; + groupDY = HbotConsumablePosParam.LittleBufferGroupDY; + } else { + group0_000Pos = HbotConsumablePosParam.ProbeSubstanceGroup0_000Pos; + group1_000Pos = HbotConsumablePosParam.ProbeSubstanceGroup1_000Pos; + group2_000Pos = HbotConsumablePosParam.ProbeSubstanceGroup2_000Pos; + group3_000Pos = HbotConsumablePosParam.ProbeSubstanceGroup3_000Pos; + group4_000Pos = HbotConsumablePosParam.ProbeSubstanceGroup4_000Pos; + group5_000Pos = HbotConsumablePosParam.ProbeSubstanceGroup5_000Pos; + groupDX = HbotConsumablePosParam.ProbeSubstanceDX; + groupDY = HbotConsumablePosParam.ProbeSubstanceDY; + } + + posReader.updatePos(group0_000Pos, info.g0_000); + posReader.updatePos(group1_000Pos, info.g1_000); + posReader.updatePos(group2_000Pos, info.g2_000); + posReader.updatePos(group3_000Pos, info.g3_000); + posReader.updatePos(group4_000Pos, info.g4_000); + posReader.updatePos(group5_000Pos, info.g5_000); + posReader.updatePos(groupDX, info.dx); + posReader.updatePos(groupDY, info.dy); + } + public Pos3d getTipPos(TipGroup tipGroup, Integer tipoff) { Pos3d tip000 = null; Double dx = 0.0; @@ -139,77 +181,51 @@ public class HbotConsumablePosMgr { } - private Pos3d getLittleBufferOrProbeSubstancePos( - Pos3d pos00_00, - Pos3d pos00_24, - Pos3d pos05_00, - Pos3d pos05_24, - ConsumableGroup group, Integer off) { - + public Pos3d getLittleBufferPos(ConsumableGroup group, Integer off) { + HbotConsumablePosParam param = HbotConsumablePosParam.valueOf(HbotConsumablePosParam.LittleBufferGroup0_000Pos.ordinal() + group.ordinal()); - Integer groupNum = group.off; - Integer groupXOff = off % 3; - Integer groupYOff = off / 3; + Pos3d pos00 = posReader.getPos(param, Pos3d.class); + Double dx = posReader.getPos(HbotConsumablePosParam.LittleBufferGroupDX, Double.class); + Double dy = posReader.getPos(HbotConsumablePosParam.LittleBufferGroupDY, Double.class); Integer xoff = off % 5; Integer yoff = off / 5; - Double gdx_0 = (pos05_00.x - pos00_00.x) / 3.0; - Double gdy_0 = (pos05_00.y - pos00_00.y) / 2.0; - - Double gdx_1 = (pos05_24.x - pos00_24.x) / 3.0; - Double gdy_1 = (pos05_24.y - pos00_24.y) / 2.0; - - Double gdx = (gdx_0 + gdx_1) / 2.0; - Double gdy = (gdy_0 + gdy_1) / 2.0; - - - Double dx_0 = (pos00_24.x - pos00_00.x) / 5.0; - Double dy_0 = (pos00_24.y - pos00_00.y) / 5.0; + double x = pos00.x + xoff * dx; + double y = pos00.y + yoff * dy; - Double dx_1 = (pos05_24.x - pos05_00.x) / 5.0; - Double dy_1 = (pos05_24.y - pos05_00.y) / 5.0; - Double dx = (dx_0 + dx_1) / 2.0; - Double dy = (dy_0 + dy_1) / 2.0; + return new Pos3d((int) x, (int) y, (int) pos00.z); + } + public Pos3d getProbeSubstancePos(ConsumableGroup group, Integer off) { + HbotConsumablePosParam param = HbotConsumablePosParam.valueOf(HbotConsumablePosParam.ProbeSubstanceGroup0_000Pos.ordinal() + group.ordinal()); - double x = pos00_00.x + groupXOff * gdx + xoff * dx; - double y = pos00_00.y + groupYOff * gdy + yoff * dy; - double z = (pos00_00.z + pos00_24.z + pos05_00.z + pos05_24.z) / 4.0; - return new Pos3d((int) x, (int) y, (int) z); + Pos3d pos00 = posReader.getPos(param, Pos3d.class); + Double dx = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceDX, Double.class); + Double dy = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceDY, Double.class); - } + Integer xoff = off % 5; + Integer yoff = off / 5; - public Pos3d getLittleBufferPos(ConsumableGroup group, Integer off) { - Pos3d pos00_00 = posReader.getPos(HbotConsumablePosParam.LittleBufferPos00_00.name(), Pos3d.class); - Pos3d pos00_24 = posReader.getPos(HbotConsumablePosParam.LittleBufferPos00_24.name(), Pos3d.class); - Pos3d pos05_00 = posReader.getPos(HbotConsumablePosParam.LittleBufferPos05_00.name(), Pos3d.class); - Pos3d pos05_24 = posReader.getPos(HbotConsumablePosParam.LittleBufferPos05_24.name(), Pos3d.class); - return getLittleBufferOrProbeSubstancePos(pos00_00, pos00_24, pos05_00, pos05_24, group, off); - } + double x = pos00.x + xoff * dx; + double y = pos00.y + yoff * dy; - public Pos3d getProbeSubstancePos(ConsumableGroup group, Integer off) { - Pos3d pos00_00 = posReader.getPos(HbotConsumablePosParam.ProbeSubstance00_00.name(), Pos3d.class); - Pos3d pos00_24 = posReader.getPos(HbotConsumablePosParam.ProbeSubstance00_24.name(), Pos3d.class); - Pos3d pos05_00 = posReader.getPos(HbotConsumablePosParam.ProbeSubstance05_00.name(), Pos3d.class); - Pos3d pos05_24 = posReader.getPos(HbotConsumablePosParam.ProbeSubstance05_24.name(), Pos3d.class); - return getLittleBufferOrProbeSubstancePos(pos00_00, pos00_24, pos05_00, pos05_24, group, off); + return new Pos3d((int) x, (int) y, (int) pos00.z); } public Pos3d getLargeBufferPos(ConsumableGroup group) { - Pos3d pos00 = posReader.getPos(HbotConsumablePosParam.LargeBufferPos00.name(), Pos3d.class); - Pos3d pos05 = posReader.getPos(HbotConsumablePosParam.LargeBufferPos05.name(), Pos3d.class); + Pos3d pos00 = posReader.getPos(HbotConsumablePosParam.LargeBuffer_0Pos.name(), Pos3d.class); + Double dx = posReader.getPos(HbotConsumablePosParam.LargeBuffer_DX, Double.class); + Double dy = posReader.getPos(HbotConsumablePosParam.LargeBuffer_DY, Double.class); + int xoff = group.off % 3; int yoff = group.off / 3; - double dx = (pos05.x - pos00.x) / 3.0; - double dy = (pos05.y - pos00.y) / 2.0; - double x = pos00.x + xoff * dx; double y = pos00.y + yoff * dy; - double z = (pos00.z + pos05.z) / 2.0; + double z = pos00.z; return new Pos3d((int) x, (int) y, (int) z); } } diff --git a/src/main/java/a8k/service/debug/AppDebugHelperService.java b/src/main/java/a8k/service/debug/AppDebugHelperService.java index 708ee4d..3882adc 100644 --- a/src/main/java/a8k/service/debug/AppDebugHelperService.java +++ b/src/main/java/a8k/service/debug/AppDebugHelperService.java @@ -174,12 +174,12 @@ public class AppDebugHelperService { @ExtApiFn(name = "插入六组正确的耗材", group = "A8K耗材.操作模拟", order = 2) public void putRightConsumable() { - putConsumableToCH(ConsumableGroup.GROUP1, A8kVirtualProjIDCard.P01_hsCRR, ConsumablesErrorType.PASS); - putConsumableToCH(ConsumableGroup.GROUP2, A8kVirtualProjIDCard.P02_PCT, ConsumablesErrorType.PASS); - putConsumableToCH(ConsumableGroup.GROUP3, A8kVirtualProjIDCard.P03_TSH, ConsumablesErrorType.PASS); - putConsumableToCH(ConsumableGroup.GROUP4, A8kVirtualProjIDCard.P05_T3, ConsumablesErrorType.PASS); - putConsumableToCH(ConsumableGroup.GROUP5, A8kVirtualProjIDCard.P06_T4, ConsumablesErrorType.PASS); - putConsumableToCH(ConsumableGroup.GROUP6, A8kVirtualProjIDCard.P22_PCTAndHsCRP, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP0, A8kVirtualProjIDCard.P01_hsCRR, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP1, A8kVirtualProjIDCard.P02_PCT, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP2, A8kVirtualProjIDCard.P03_TSH, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP3, A8kVirtualProjIDCard.P05_T3, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP4, A8kVirtualProjIDCard.P06_T4, ConsumablesErrorType.PASS); + putConsumableToCH(ConsumableGroup.GROUP5, A8kVirtualProjIDCard.P22_PCTAndHsCRP, ConsumablesErrorType.PASS); } diff --git a/src/main/java/a8k/type/ConsumableGroup.java b/src/main/java/a8k/type/ConsumableGroup.java index f8c0d59..71b980e 100644 --- a/src/main/java/a8k/type/ConsumableGroup.java +++ b/src/main/java/a8k/type/ConsumableGroup.java @@ -1,7 +1,7 @@ package a8k.type; public enum ConsumableGroup { - GROUP1, GROUP2, GROUP3, GROUP4, GROUP5, GROUP6; + GROUP0, GROUP1, GROUP2, GROUP3, GROUP4, GROUP5; final public int off; diff --git a/src/main/java/a8k/type/HbotConsumablePosParam.java b/src/main/java/a8k/type/HbotConsumablePosParam.java index 226a2fa..acdd42a 100644 --- a/src/main/java/a8k/type/HbotConsumablePosParam.java +++ b/src/main/java/a8k/type/HbotConsumablePosParam.java @@ -1,20 +1,6 @@ package a8k.type; public enum HbotConsumablePosParam { - LittleBufferPos00_00("第0组小瓶的第0个位置"), - LittleBufferPos00_24("第0组小瓶的第24个位置"), - LittleBufferPos05_00("第5组小瓶的第0个位置"), - LittleBufferPos05_24("第5组小瓶的第24个位置"), - - ProbeSubstance00_00("第0组探针的第0个位置"), - ProbeSubstance00_24("第0组探针的第24个位置"), - ProbeSubstance05_00("第5组探针的第0个位置"), - ProbeSubstance05_24("第5组探针的第24个位置"), - - LargeBufferPos00("左上角大瓶位置"), - LargeBufferPos05("右下角大瓶位置"), - - TipGroup0_000Pos("第1组TIP的第1个位置"), TipGroup0_SpaceingX("第1组TIP的X间距"), TipGroup0_SpaceingY("第1组TIP的Y间距"), @@ -26,10 +12,37 @@ public enum HbotConsumablePosParam { TipGroup2_000Pos("第3组TIP的第1个位置"), TipGroup2_SpaceingX("第3组TIP的X间距"), TipGroup2_SpaceingY("第3组TIP的Y间距"), + + + LittleBufferGroup0_000Pos("第1组小瓶缓冲液的第1个位置"), + LittleBufferGroup1_000Pos("第1组小瓶缓冲液的第2个位置"), + LittleBufferGroup2_000Pos("第1组小瓶缓冲液的第3个位置"), + LittleBufferGroup3_000Pos("第1组小瓶缓冲液的第4个位置"), + LittleBufferGroup4_000Pos("第1组小瓶缓冲液的第5个位置"), + LittleBufferGroup5_000Pos("第1组小瓶缓冲液的第6个位置"), + LittleBufferGroupDX("小瓶缓冲液的X间距"), + LittleBufferGroupDY("小瓶缓冲液的Y间距"), + + ProbeSubstanceGroup0_000Pos("第1组探测物质的第1个位置"), + ProbeSubstanceGroup1_000Pos("第1组探测物质的第2个位置"), + ProbeSubstanceGroup2_000Pos("第1组探测物质的第3个位置"), + ProbeSubstanceGroup3_000Pos("第1组探测物质的第4个位置"), + ProbeSubstanceGroup4_000Pos("第1组探测物质的第5个位置"), + ProbeSubstanceGroup5_000Pos("第1组探测物质的第6个位置"), + ProbeSubstanceDX("探测物质的X间距"), + ProbeSubstanceDY("探测物质的Y间距"), + + LargeBuffer_0Pos("大瓶缓冲液的第1个位置"), + LargeBuffer_DX("大瓶缓冲液的X间距"), + LargeBuffer_DY("大瓶缓冲液的Y间距"), ; final public String chName; HbotConsumablePosParam(String chName) { this.chName = chName; } + + public static HbotConsumablePosParam valueOf(int off) { + return HbotConsumablePosParam.values()[off]; + } } diff --git a/src/main/java/a8k/type/LittleBottleConsumablePosInfo.java b/src/main/java/a8k/type/LittleBottleConsumablePosInfo.java new file mode 100644 index 0000000..f8243ce --- /dev/null +++ b/src/main/java/a8k/type/LittleBottleConsumablePosInfo.java @@ -0,0 +1,15 @@ +package a8k.type; + +import a8k.type.cfg.Pos3d; + +public class LittleBottleConsumablePosInfo { + public Pos3d g0_000; + public Pos3d g1_000; + public Pos3d g2_000; + public Pos3d g3_000; + public Pos3d g4_000; + public Pos3d g5_000; + public Double dx; + public Double dy; + +} diff --git a/src/main/java/a8k/type/LittleBottleConsumableRefPoint.java b/src/main/java/a8k/type/LittleBottleConsumableRefPoint.java new file mode 100644 index 0000000..655f681 --- /dev/null +++ b/src/main/java/a8k/type/LittleBottleConsumableRefPoint.java @@ -0,0 +1,25 @@ +package a8k.type; + +import a8k.constant.AppConstant; +import a8k.type.cfg.Pos3d; + +public class LittleBottleConsumableRefPoint { + public ConsumableGroup group; + public Integer index;//from zero + + public Pos3d pos; + + public LittleBottleConsumableRefPoint(ConsumableGroup group, Integer index, Pos3d pos) { + this.group = group; + this.index = index; + this.pos = pos; + } + + public Integer getRowOff() { + return index / AppConstant.CONSUMABLE_COL_NUM; + } + + public Integer getColOff() { + return index % AppConstant.CONSUMABLE_COL_NUM; + } +} diff --git a/src/main/java/a8k/type/LittleBottleConsumableType.java b/src/main/java/a8k/type/LittleBottleConsumableType.java new file mode 100644 index 0000000..832c6a7 --- /dev/null +++ b/src/main/java/a8k/type/LittleBottleConsumableType.java @@ -0,0 +1,6 @@ +package a8k.type; + +public enum LittleBottleConsumableType { + BufferSolution, //缓冲液 + ProbeSubstance, //探测物质 +} diff --git a/src/main/java/a8k/utils/ZSimplAlgo.java b/src/main/java/a8k/utils/ZSimplAlgo.java index 8843e1e..0a90b97 100644 --- a/src/main/java/a8k/utils/ZSimplAlgo.java +++ b/src/main/java/a8k/utils/ZSimplAlgo.java @@ -3,14 +3,25 @@ package a8k.utils; import java.util.List; public class ZSimplAlgo { - public static Double computeAverage(List data) { - Double sum = 0.0; - for (Double datum : data) { - sum += datum; + public static Double computeAverage(List data) { + double sum = 0.0; + for (var datum : data) { + if (datum instanceof Double) { + sum += (Double) datum; + } else if (datum instanceof Integer) { + sum += (Integer) datum; + } else if (datum instanceof Long) { + sum += (Long) datum; + } else if (datum instanceof Float) { + sum += (Float) datum; + } else { + throw new IllegalArgumentException("Unsupported type: " + datum.getClass().getName()); + } } return sum / data.size(); } + public static Double computeAverage(Double[] data) { Double sum = 0.0; for (Double datum : data) {