From f07bff219b49a502f9bcc86f1d8445c6a15886bd Mon Sep 17 00:00:00 2001 From: zhaohe Date: Thu, 17 Oct 2024 20:01:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E7=93=B6=E7=BC=93=E5=86=B2=E6=B6=B2?= =?UTF-8?q?=E6=A0=A1=E5=87=86=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 + app.db | Bin 225280 -> 225280 bytes .../pagecontrol/ExtApiTabConfig.java | 1 + .../HbotLargeBottleBSPosCalibration.java | 200 +++++++++++++++++++++ .../HbotLittleBottleConsumableCalibration.java | 35 ++-- .../app/devicedriver/pos/HbotConsumablePosMgr.java | 24 ++- src/main/java/a8k/type/HbotConsumablePosParam.java | 3 + .../a8k/type/LargeBottleConsumableRefPoint.java | 22 +++ .../a8k/type/LargeBottoleConsumablePosInfo.java | 17 ++ src/main/java/a8k/utils/ZJsonHelper.java | 3 + src/main/java/a8k/utils/ZSqliteJdbcHelper.java | 17 +- 11 files changed, 301 insertions(+), 27 deletions(-) create mode 100644 src/main/java/a8k/service/app/devicedriver/calibration/HbotLargeBottleBSPosCalibration.java create mode 100644 src/main/java/a8k/type/LargeBottleConsumableRefPoint.java create mode 100644 src/main/java/a8k/type/LargeBottoleConsumablePosInfo.java diff --git a/README.md b/README.md index 2ca8d8f..d9eaad3 100644 --- a/README.md +++ b/README.md @@ -244,4 +244,10 @@ TODO: ... 错误码 ... +``` + + +``` +TODO: + 单片机层添加急停指令,同时添加急停错误。 ``` \ No newline at end of file diff --git a/app.db b/app.db index a2b79c9d6ddd449a47137cb88d2a784fcd6f034e..1fe34ab1d7d32eeb3f15baaf7f7917755119fa76 100644 GIT binary patch delta 504 zcmZp8z}xVEcY>6VsXYS&gE=vkz+c?14eVv0uFJeV(wNZ9&Tl} zbFA)6XW080Hcl24h~-R6XJ;@qmsSs)zVI=l$n#=1>D&p=7PMFRO)q%DsI%SuA)^{2A6p0m zo2h1aJkVH8N$u$$pED{=pZHd!xMR`%I*sk!H(S(_a?d0^ZXN<+{?A;8krm@M>`GCevfBuY7aJn_n1|~zZ z>736Q<)-UCXN==zf62fSng+DVnSs|Es$0}Yxnccl`poez~U#M zw|G}D=uIzt#Hhv-;gVk(9*6Ldk%p0lft~?+&^({j67h2SmKWRSX2b#&>x$ch?G>3G m`+`x5*TmGqR7a^&$;!~!%y4?$3r4l}TQ3;5-+IBM)(!xq;K*M9 delta 409 zcmZp8z}xVEcY>6V@pT3U26G@b17Z~h2Cf$qb&QyduWwAae}R#6v%|$WMn;a!^DoIT zF|u#obLBT9BirU3*B&x5vNq4Uv3=GJ#te40BMi!nlC0A?9x$5oJFvfG%H?il;^9_i zJIU%kSy13KQ-$C3f+vhR+ua{Bsxh*J#r4JnLKZY-{)P&Xq5=tav`FCF14uEibmu1uADVb>6P< zn9+opiCukq*fYjr&X{C&22(>xbytuXBGV^4Vr1h94h~MtEyziY3dk>>-uRYLc)H+o zMj1BtZlHd{>AKGu<2X5%FvKBg+whQ)efrARjNB0ACtfqku!P1zoUJvzM+}Im#DbMtoFBtiz%RdDYAeGbqKV; refpoints = new java.util.ArrayList<>(); + + + @ExtApiFn(name = "开始标定大瓶坐标", group = "标定大瓶缓液XY坐标", order = 30) + public void startCalibrate() throws AppException { + refpoints = new java.util.ArrayList<>(); + moveToZero(); + disableModule(); + } + + @ExtApiFn(name = "添加大瓶参考点", group = "标定大瓶缓液XY坐标", order = 31) + public Object addRefPoint(ConsumableGroup group) throws AppException { + enableModule(); + Pos2d xypos = hbotModule.readPos(); + // pipetteCtrlModule.zMotorMeasureDistance(); + // Integer z = pipetteCtrlModule.zMotorReadMeasureDistanceResult(); + LargeBottleConsumableRefPoint refPoints = new LargeBottleConsumableRefPoint(group, new Pos3d(xypos.x, xypos.y, 0)); + this.refpoints.add(refPoints); + disableModule(); + ObjectNode node = ZJsonHelper.createObjectNode(); + node.put("newPoint", ZJsonHelper.createObjectNode(refPoints)); + node.put("computeResult", ZJsonHelper.createObjectNode(computeLittleBottlePosInfo())); + return node; + } + + @ExtApiFn(name = "移除最后一个参考点", group = "标定大瓶缓液XY坐标", order = 32) + public void removeTheLastRefPoint() { + if (!refpoints.isEmpty()) { + refpoints.remove(refpoints.size() - 1); + } + } + + + @ExtApiFn(name = "读取坐标计算结果", group = "标定大瓶缓液XY坐标", order = 33) + public LargeBottoleConsumablePosInfo computeLittleBottlePosInfo() { + //第一排x求平均 + // x[0] = ZSimplAlgo.computeAverage( + // littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() % 3 == 0 && point.index % 5 == 0). + // map(point -> point.pos.x).toList() + // ); + + var p00 = refpoints.stream().filter(point -> point.group == ConsumableGroup.GROUP0).findFirst().orElse(null); + Double x, y, dx = null, dy = null; + + x = ZSimplAlgo.computeAverage( + refpoints.stream().filter(point -> point.group.ordinal() / 3 == 0). + map(point -> point.pos.x).toList()); + //第一列y求平均 + y = ZSimplAlgo.computeAverage( + refpoints.stream().filter(point -> point.group.ordinal() % 3 == 0). + map(point -> point.pos.y).toList()); + //除了第一列的所有点,减少x,相加,求平均 + if (p00 != null) { + dx = ZSimplAlgo.computeAverage( + refpoints.stream().filter(point -> point.getCol() != 0). + map(point -> (point.pos.x - p00.pos.x) * 1.0 / point.getCol()).toList()); + //除了第一排的所有点,减少y,相加,求平均 + dy = ZSimplAlgo.computeAverage( + refpoints.stream().filter(point -> point.getRow() != 0). + map(point -> (point.pos.y - p00.pos.y) * 1.0 / point.getRow()).toList()); + } + + return new LargeBottoleConsumablePosInfo(new Pos3d(x.intValue(), y.intValue(), 0), dx, dy); + } + + @ExtApiFn(name = "保存计算结果", group = "标定大瓶缓液XY坐标", order = 34) + public void savePosInfo() throws AppException { + hbotConsumablePosMgr.setLargeBufferGroupPosInfo(computeLittleBottlePosInfo()); + } + + @ExtApiFn(name = "读取所有参考点", group = "标定大瓶缓液XY坐标", order = 35) + public Object readAllRefPoint() throws AppException { + return refpoints; + } + + // + // 标定Z轴 + // + public void setZPos(HbotConsumablePosParam posName) throws AppException { + enableModule(); + pipetteCtrlModule.zMotorMeasureDistance(); + hbotConsumablePosMgr.setParam(posName, pipetteCtrlModule.zMotorReadMeasureDistanceResult()); + disableModule(); + } + + @ExtApiFn(name = "校准.大瓶缓冲液Z轴位置", group = "标定Z轴", order = 104) + public void setLargeBSSSampleZPos() throws AppException {setZPos(HbotConsumablePosParam.LargeBSSSampleZPos);} + + @ExtApiFn(name = "校准.大瓶缓冲液Z轴结束位置", group = "标定Z轴", order = 105) + public void setLargeBSSSampleEndZPos() throws AppException {setZPos(HbotConsumablePosParam.LargeBSSSampleEndZPos);} + + // + // 校验 + // + + @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/HbotLittleBottleConsumableCalibration.java b/src/main/java/a8k/service/app/devicedriver/calibration/HbotLittleBottleConsumableCalibration.java index 4e490b9..2e63cc9 100644 --- a/src/main/java/a8k/service/app/devicedriver/calibration/HbotLittleBottleConsumableCalibration.java +++ b/src/main/java/a8k/service/app/devicedriver/calibration/HbotLittleBottleConsumableCalibration.java @@ -102,8 +102,8 @@ public class HbotLittleBottleConsumableCalibration { public Object addLittleBottleGroupRefPoint(ConsumableGroup group, Integer off0To24) throws AppException { enableModule(); Pos2d xypos = hbotModule.readPos(); -// pipetteCtrlModule.zMotorMeasureDistance(); -// Integer z = pipetteCtrlModule.zMotorReadMeasureDistanceResult(); + // pipetteCtrlModule.zMotorMeasureDistance(); + // Integer z = pipetteCtrlModule.zMotorReadMeasureDistanceResult(); LittleBottleConsumableRefPoint littleBufferRefPoint = new LittleBottleConsumableRefPoint(group, off0To24, new Pos3d(xypos.x, xypos.y, 0)); this.littleBottleConsumableRefPoint.add(littleBufferRefPoint); disableModule(); @@ -222,31 +222,32 @@ public class HbotLittleBottleConsumableCalibration { // 标定Z轴 // + // LittleBSSampleEndZPos("小瓶缓冲液取样结束Z坐标"), + // ProbeSubstanceSampleZPos("探测物质取样Z坐标"), + // ProbeSubstanceSampleEndZPos("探测物质取样结束Z坐标"), - @ExtApiFn(name = "校准.小瓶穿孔Z轴位置", group = "标定Z轴", order = 101) - public void setLittleBSPierceZPos() throws AppException { + public void setZPos(HbotConsumablePosParam posName) throws AppException { enableModule(); pipetteCtrlModule.zMotorMeasureDistance(); - hbotConsumablePosMgr.setParam(HbotConsumablePosParam.LittleBSPierceZPos, pipetteCtrlModule.zMotorReadMeasureDistanceResult()); + hbotConsumablePosMgr.setParam(posName, pipetteCtrlModule.zMotorReadMeasureDistanceResult()); disableModule(); } + + @ExtApiFn(name = "校准.小瓶穿孔Z轴位置", group = "标定Z轴", order = 101) + public void setLittleBSPierceZPos() throws AppException {setZPos(HbotConsumablePosParam.LittleBSPierceZPos);} + @ExtApiFn(name = "校准.小瓶取样Z轴位置", group = "标定Z轴", order = 102) - public void setLittleBSSampleZPos() throws AppException { - enableModule(); - pipetteCtrlModule.zMotorMeasureDistance(); - hbotConsumablePosMgr.setParam(HbotConsumablePosParam.LittleBSSampleZPos, pipetteCtrlModule.zMotorReadMeasureDistanceResult()); - disableModule(); - } + public void setLittleBSSampleZPos() throws AppException {setZPos(HbotConsumablePosParam.LittleBSSampleZPos);} + + @ExtApiFn(name = "校准.探测物质取样结束Z轴位置", group = "标定Z轴", order = 103) + public void setProbeSubstanceSampleEndZPos() throws AppException {setZPos(HbotConsumablePosParam.ProbeSubstanceSampleEndZPos);} @ExtApiFn(name = "校准.探测物质取样Z轴位置", group = "标定Z轴", order = 103) - public void setProbeSubstanceSampleZPos() throws AppException { - enableModule(); - pipetteCtrlModule.zMotorMeasureDistance(); - hbotConsumablePosMgr.setParam(HbotConsumablePosParam.ProbeSubstanceSampleZPos, pipetteCtrlModule.zMotorReadMeasureDistanceResult()); - disableModule(); - } + public void setProbeSubstanceSampleZPos() throws AppException {setZPos(HbotConsumablePosParam.ProbeSubstanceSampleZPos);} + @ExtApiFn(name = "校准.小瓶缓冲液取样结束Z轴位置", group = "标定Z轴", order = 104) + public void setLittleBSSampleEndZPos() throws AppException {setZPos(HbotConsumablePosParam.LittleBSSampleEndZPos);} // // 校验 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 1b3a947..ff77270 100644 --- a/src/main/java/a8k/service/app/devicedriver/pos/HbotConsumablePosMgr.java +++ b/src/main/java/a8k/service/app/devicedriver/pos/HbotConsumablePosMgr.java @@ -5,14 +5,9 @@ import a8k.extapi_controler.utils.ExtApiParamsTab; import a8k.extapi_controler.utils.ExtApiTab; 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.*; import a8k.type.cfg.Pos3d; import a8k.type.type.TipGroup; -import a8k.utils.ZJsonHelper; -import com.fasterxml.jackson.databind.node.ObjectNode; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import org.slf4j.Logger; @@ -20,8 +15,6 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.Assert; -import java.util.List; - /** * HBOT二维码扫描坐标参数 */ @@ -161,6 +154,21 @@ public class HbotConsumablePosMgr { return info; } + public LargeBottoleConsumablePosInfo getLargeBufferGroupPosInfo() { + LargeBottoleConsumablePosInfo info = new LargeBottoleConsumablePosInfo(); + info.pos00 = posReader.getPos(HbotConsumablePosParam.LargeBuffer_0Pos, Pos3d.class); + info.dx = posReader.getPos(HbotConsumablePosParam.LargeBuffer_DX, Double.class); + info.dy = posReader.getPos(HbotConsumablePosParam.LargeBuffer_DY, Double.class); + return info; + } + + + public void setLargeBufferGroupPosInfo(LargeBottoleConsumablePosInfo info) { + posReader.updatePos(HbotConsumablePosParam.LargeBuffer_0Pos, info.pos00); + posReader.updatePos(HbotConsumablePosParam.LargeBuffer_DX, info.dx); + posReader.updatePos(HbotConsumablePosParam.LargeBuffer_DY, info.dy); + } + public LittleBottleConsumablePosInfo getLittleBottleConsumablePosInfo(LittleBottleConsumableType type) { if (type.equals(LittleBottleConsumableType.BufferSolution)) { return getLittleBufferGroupPosInfo(); diff --git a/src/main/java/a8k/type/HbotConsumablePosParam.java b/src/main/java/a8k/type/HbotConsumablePosParam.java index 1ae446f..6ed963e 100644 --- a/src/main/java/a8k/type/HbotConsumablePosParam.java +++ b/src/main/java/a8k/type/HbotConsumablePosParam.java @@ -38,8 +38,11 @@ public enum HbotConsumablePosParam { LittleBSPierceZPos("小瓶缓冲液刺破Z坐标"), LittleBSSampleZPos("小瓶缓冲液取样Z坐标"), + LittleBSSampleEndZPos("小瓶缓冲液取样结束Z坐标"), ProbeSubstanceSampleZPos("探测物质取样Z坐标"), + ProbeSubstanceSampleEndZPos("探测物质取样结束Z坐标"), LargeBSSSampleZPos("大瓶缓冲液取样Z坐标"), + LargeBSSSampleEndZPos("大瓶缓冲液取样结束Z坐标"), ; diff --git a/src/main/java/a8k/type/LargeBottleConsumableRefPoint.java b/src/main/java/a8k/type/LargeBottleConsumableRefPoint.java new file mode 100644 index 0000000..69ca111 --- /dev/null +++ b/src/main/java/a8k/type/LargeBottleConsumableRefPoint.java @@ -0,0 +1,22 @@ +package a8k.type; + +import a8k.type.cfg.Pos3d; + +public class LargeBottleConsumableRefPoint { + public ConsumableGroup group; + + public Pos3d pos; + + public LargeBottleConsumableRefPoint(ConsumableGroup group, Pos3d pos) { + this.group = group; + this.pos = pos; + } + + public Integer getRow() { + return group.ordinal() / 3; + } + + public Integer getCol() { + return group.ordinal() % 3; + } +} diff --git a/src/main/java/a8k/type/LargeBottoleConsumablePosInfo.java b/src/main/java/a8k/type/LargeBottoleConsumablePosInfo.java new file mode 100644 index 0000000..87fa30b --- /dev/null +++ b/src/main/java/a8k/type/LargeBottoleConsumablePosInfo.java @@ -0,0 +1,17 @@ +package a8k.type; + +import a8k.type.cfg.Pos3d; + +public class LargeBottoleConsumablePosInfo { + public Pos3d pos00; + public Double dx; + public Double dy; + + public LargeBottoleConsumablePosInfo(Pos3d pos00, Double dx, Double dy) { + this.pos00 = pos00; + this.dx = dx; + this.dy = dy; + } + + public LargeBottoleConsumablePosInfo(){} +} diff --git a/src/main/java/a8k/utils/ZJsonHelper.java b/src/main/java/a8k/utils/ZJsonHelper.java index 73a4b94..ca83a14 100644 --- a/src/main/java/a8k/utils/ZJsonHelper.java +++ b/src/main/java/a8k/utils/ZJsonHelper.java @@ -49,6 +49,9 @@ public class ZJsonHelper { public static ObjectNode createObjectNode(Object obj) { ObjectMapper ObjectMapper = new ObjectMapper(); + if (obj == null) { + return null; + } if (obj instanceof Integer) { return ObjectMapper.createObjectNode().put("value", (Integer) obj); } diff --git a/src/main/java/a8k/utils/ZSqliteJdbcHelper.java b/src/main/java/a8k/utils/ZSqliteJdbcHelper.java index 613a949..797cbae 100644 --- a/src/main/java/a8k/utils/ZSqliteJdbcHelper.java +++ b/src/main/java/a8k/utils/ZSqliteJdbcHelper.java @@ -3,6 +3,7 @@ package a8k.utils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; +import org.slf4j.Logger; import org.springframework.jdbc.core.JdbcTemplate; import java.lang.reflect.InvocationTargetException; @@ -17,6 +18,7 @@ import java.util.Date; import java.util.List; public class ZSqliteJdbcHelper { + static Logger logger = org.slf4j.LoggerFactory.getLogger(ZSqliteJdbcHelper.class); static public boolean isTableExist(JdbcTemplate jdbcTemplate, String tableName) { String sql = "select * from sqlite_master where type = 'table' and name = '" + tableName + "';"; @@ -74,6 +76,7 @@ public class ZSqliteJdbcHelper { static public Object rowMapper(ResultSet rs, Class tClass) throws SQLException, InstantiationException, IllegalAccessException { Object obj = tClass.newInstance(); for (java.lang.reflect.Field field : tClass.getDeclaredFields()) { + if (field.getType().equals(Integer.class)) { field.set(obj, rs.getInt(field.getName())); } else if (field.getType().equals(int.class)) { @@ -94,7 +97,13 @@ public class ZSqliteJdbcHelper { } else if (field.getType().equals(ObjectNode.class)) { ObjectMapper objectMapper = new ObjectMapper(); try { - field.set(obj, objectMapper.readTree(rs.getString(field.getName()))); + String val = rs.getString(field.getName()); + if (val != null && !val.isEmpty()) { +// logger.info("val: {}", val); + field.set(obj, objectMapper.readTree(val)); + } else { + field.set(obj, null); + } } catch (JsonProcessingException e) { throw new RuntimeException(e); } @@ -125,6 +134,11 @@ public class ZSqliteJdbcHelper { if (field.getName().equals("id")) continue; + if(field.get(obj) == null){ + args.add(null); + continue; + } + field.setAccessible(true); if (field.getType().equals(Integer.class) || field.getType().equals(int.class)) { // args[i] = field.getInt(obj); @@ -153,7 +167,6 @@ public class ZSqliteJdbcHelper { } else { ObjectMapper objectMapper = new ObjectMapper(); args.add(objectMapper.writeValueAsString(field.get(obj))); - } } catch (IllegalAccessException | JsonProcessingException e) { e.printStackTrace();