10 changed files with 701 additions and 0 deletions
-
BINapp.db
-
4src/main/java/a8k/service/app/devicedriver/basectrl/PipetteCtrlModule.java
-
173src/main/java/a8k/service/app/devicedriver/calibration/HbotConsumablePosCalibration.java
-
108src/main/java/a8k/service/app/devicedriver/ctrl/HbotControler.java
-
200src/main/java/a8k/service/app/devicedriver/pos/HbotConsumablePosMgr.java
-
61src/main/java/a8k/service/app/devicedriver/pos/HbotFixPosMgr.java
-
57src/main/java/a8k/service/app/devicedriver/pos/HbotSamplePosMgr.java
-
37src/main/java/a8k/type/HbotConsumablePos.java
-
11src/main/java/a8k/type/HbotSamplePos.java
-
50src/main/java/a8k/utils/PlaneUtils.java
@ -0,0 +1,173 @@ |
|||||
|
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.ConsumableGroup; |
||||
|
import a8k.type.ConsumableScanRawResult; |
||||
|
import a8k.type.HbotConsumablePos; |
||||
|
import a8k.type.cfg.Pos2d; |
||||
|
import a8k.type.cfg.Pos3d; |
||||
|
import a8k.type.exception.AppException; |
||||
|
import a8k.type.type.TipGroup; |
||||
|
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.slf4j.Logger; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
@ExtApiTab(cfg = ExtApiTabConfig.Hbot2DCodeScanPosCalibration) |
||||
|
@Component |
||||
|
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 = 2) |
||||
|
public Object getPossChName() throws AppException { |
||||
|
return hbotConsumablePosMgr.getParamsChName(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// 测试工具 |
||||
|
@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); |
||||
|
} |
||||
|
|
||||
|
// |
||||
|
// 标定 |
||||
|
// |
||||
|
|
||||
|
@ExtApiFn(name = "标定HBOT坐标", group = "标定", order = 21) |
||||
|
void calibratePos(HbotConsumablePos hbotConsumablePos) throws AppException { |
||||
|
enableModule(); |
||||
|
Pos2d xypos = hbotModule.readPos(); |
||||
|
pipetteCtrlModule.zMotorMeasureDistance(); |
||||
|
Integer z = pipetteCtrlModule.zMotorReadMeasureDistanceResult(); |
||||
|
hbotConsumablePosMgr.setParam(hbotConsumablePos, new Pos3d(xypos.x, xypos.y, z)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// |
||||
|
// 校验 |
||||
|
// |
||||
|
@ExtApiFn(name = "校验Tip坐标", group = "校验", order = 30) |
||||
|
public void testTakeTip() throws AppException { |
||||
|
resetStopFlag(); |
||||
|
enableModule(); |
||||
|
for (TipGroup tipGroup : TipGroup.values()) { |
||||
|
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(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,108 @@ |
|||||
|
package a8k.service.app.devicedriver.ctrl; |
||||
|
|
||||
|
import a8k.constant.AppConstant; |
||||
|
import a8k.hardware.type.a8kcanprotocol.A8kEcode; |
||||
|
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.pos.HbotConsumablePosMgr; |
||||
|
import a8k.service.app.devicedriver.pos.HbotFixPosMgr; |
||||
|
import a8k.service.app.devicedriver.pos.HbotSamplePosMgr; |
||||
|
import a8k.type.ConsumableGroup; |
||||
|
import a8k.type.HbotSamplePos; |
||||
|
import a8k.type.cfg.Pos3d; |
||||
|
import a8k.type.exception.AppException; |
||||
|
import a8k.type.type.TipGroup; |
||||
|
import a8k.utils.HbotScanerPosComputer; |
||||
|
import jakarta.annotation.Resource; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Component |
||||
|
public class HbotControler { |
||||
|
static Logger logger = LoggerFactory.getLogger(HbotControler.class); |
||||
|
|
||||
|
@Resource |
||||
|
HbotFixPosMgr hbotFixPosMgr; |
||||
|
@Resource |
||||
|
HbotSamplePosMgr hbotSamplePosMgr; |
||||
|
@Resource |
||||
|
HbotConsumablePosMgr hbotConsumablePosMgr; |
||||
|
|
||||
|
@Resource |
||||
|
PipetteCtrlModule pipetteCtrlModule; |
||||
|
@Resource |
||||
|
HbotBaseMoveControler hbotBaseMoveControler; |
||||
|
|
||||
|
public void checkTipIndex(TipGroup tipGroup, Integer index) throws AppException { |
||||
|
if (index >= AppConstant.TIP_NUM) { |
||||
|
throw new AppException(A8kEcode.CODEERROR_PARAM_OUT_OF_RANGE); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Boolean takeTip(TipGroup tipGroup, Integer index) throws AppException { |
||||
|
logger.info("takeTip groupId:{} index:{}", tipGroup.ordinal(), index); |
||||
|
checkTipIndex(tipGroup, index); |
||||
|
|
||||
|
Pos3d tipPos = hbotConsumablePosMgr.getTipPos(tipGroup, index); |
||||
|
hbotBaseMoveControler.hbotMoveTo(tipPos); |
||||
|
pipetteCtrlModule.zMotorMoveToZeroPointQuickBlock(); |
||||
|
|
||||
|
return pipetteCtrlModule.isHasTip(); |
||||
|
} |
||||
|
|
||||
|
public void testTakeTip(TipGroup tipGroup, Integer index) throws AppException { |
||||
|
checkTipIndex(tipGroup, index); |
||||
|
|
||||
|
Pos3d tipPos = hbotConsumablePosMgr.getTipPos(tipGroup, index); |
||||
|
hbotBaseMoveControler.hbotMoveTo(tipPos); |
||||
|
|
||||
|
//取tip |
||||
|
pipetteCtrlModule.zMotorMoveToBlock(tipPos.z - 100); |
||||
|
if (!pipetteCtrlModule.isHasTip()) { |
||||
|
throw new AppException(A8kEcode.APPE_TAKE_TIP_FAIL); |
||||
|
} |
||||
|
|
||||
|
//丢tip |
||||
|
pipetteCtrlModule.putTipBlock(); |
||||
|
if (pipetteCtrlModule.isHasTip()) { |
||||
|
throw new AppException(A8kEcode.APPE_PUT_TIP_FAIL); |
||||
|
} |
||||
|
|
||||
|
//z轴归零 |
||||
|
pipetteCtrlModule.zMotorMoveToZeroPointQuickBlock(); |
||||
|
} |
||||
|
|
||||
|
public void dropTip() throws AppException { |
||||
|
hbotBaseMoveControler.hbotMoveTo(hbotFixPosMgr.getDropTipPos()); |
||||
|
pipetteCtrlModule.putTipBlock(); |
||||
|
} |
||||
|
|
||||
|
public void moveToDropLiquidPos() throws AppException { |
||||
|
hbotBaseMoveControler.hbotMoveTo(hbotFixPosMgr.getDropLiquidPos()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 移动到取样位置 |
||||
|
* @param pos 取样位置 |
||||
|
* @throws AppException 异常 |
||||
|
*/ |
||||
|
public void moveToTakeSamplePos(HbotSamplePos pos) throws AppException { |
||||
|
hbotBaseMoveControler.hbotMoveTo(hbotSamplePosMgr.getSamplePos(pos)); |
||||
|
} |
||||
|
|
||||
|
public void moveToLittleBufferPos(ConsumableGroup group, Integer off) throws AppException { |
||||
|
hbotBaseMoveControler.hbotMoveTo(hbotConsumablePosMgr.getLittleBufferPos(group, off)); |
||||
|
} |
||||
|
|
||||
|
public void moveToProbeSubstancePos(ConsumableGroup group, Integer off) throws AppException { |
||||
|
hbotBaseMoveControler.hbotMoveTo(hbotConsumablePosMgr.getProbeSubstancePos(group, off)); |
||||
|
} |
||||
|
|
||||
|
public void moveToLargeBufferPos(ConsumableGroup group) throws AppException { |
||||
|
hbotBaseMoveControler.hbotMoveTo(hbotConsumablePosMgr.getLargeBufferPos(group)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,200 @@ |
|||||
|
package a8k.service.app.devicedriver.pos; |
||||
|
|
||||
|
import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; |
||||
|
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.HbotConsumablePos; |
||||
|
import a8k.type.cfg.Pos3d; |
||||
|
import a8k.type.type.TipGroup; |
||||
|
import a8k.utils.PlaneUtils; |
||||
|
import jakarta.annotation.PostConstruct; |
||||
|
import jakarta.annotation.Resource; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* HBOT二维码扫描坐标参数 |
||||
|
*/ |
||||
|
@Component |
||||
|
@ExtApiTab(cfg = ExtApiTabConfig.Hbot2DCodeScanPos) |
||||
|
@ExtApiParamsTab(service = HbotConsumablePosMgr.class) |
||||
|
public class HbotConsumablePosMgr { |
||||
|
static final Logger logger = LoggerFactory.getLogger(HbotConsumablePosMgr.class); |
||||
|
|
||||
|
@Resource |
||||
|
LowerDeviceParameterDBService lowerDeviceParameterDBService; |
||||
|
PosParameterReader posReader = null; |
||||
|
|
||||
|
static Integer nowParaVersion = 0; |
||||
|
|
||||
|
@PostConstruct |
||||
|
void initialize() { |
||||
|
posReader = lowerDeviceParameterDBService.getReader(this.getClass()); |
||||
|
Integer paraVersion = posReader.getVersion(); |
||||
|
if (!nowParaVersion.equals(paraVersion)) { |
||||
|
paramReset(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void paramReset() { |
||||
|
logger.info("init param"); |
||||
|
posReader.setVersion(nowParaVersion); |
||||
|
posReader.updatePos(HbotConsumablePos.Tip00_000Pos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotConsumablePos.Tip00_119Pos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotConsumablePos.Tip01_000Pos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotConsumablePos.Tip01_119Pos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotConsumablePos.Tip02_000Pos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotConsumablePos.Tip02_119Pos.name(), new Pos3d(0, 0, 0)); |
||||
|
|
||||
|
posReader.updatePos(HbotConsumablePos.LittleBufferPos00_00.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotConsumablePos.LittleBufferPos05_24.name(), new Pos3d(0, 0, 0)); |
||||
|
|
||||
|
posReader.updatePos(HbotConsumablePos.ProbeSubstance00_00.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotConsumablePos.ProbeSubstance05_24.name(), new Pos3d(0, 0, 0)); |
||||
|
} |
||||
|
|
||||
|
public Map<String, Pos3d> getParams() { |
||||
|
Map<String, Pos3d> map = new java.util.HashMap<>(); |
||||
|
for (HbotConsumablePos param : HbotConsumablePos.values()) { |
||||
|
map.put(param.name(), posReader.getPos(param.name(), Pos3d.class)); |
||||
|
} |
||||
|
return map; |
||||
|
} |
||||
|
|
||||
|
public Map<String, String> getParamsChName() { |
||||
|
Map<String, String> map = new java.util.HashMap<>(); |
||||
|
for (HbotConsumablePos param : HbotConsumablePos.values()) { |
||||
|
map.put(param.name(), param.chName); |
||||
|
} |
||||
|
return map; |
||||
|
} |
||||
|
|
||||
|
public void setParam(HbotConsumablePos param, Pos3d pos) { |
||||
|
posReader.updatePos(param.name(), pos); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Pos3d getTipPos(TipGroup tipGroup, Integer tipoff) { |
||||
|
Pos3d tip000 = null; |
||||
|
Pos3d tip011 = null; |
||||
|
Pos3d tip108 = null; |
||||
|
Pos3d tip119 = null; |
||||
|
|
||||
|
if (tipGroup == TipGroup.GROUP0) { |
||||
|
tip000 = posReader.getPos(HbotConsumablePos.Tip00_000Pos.name(), Pos3d.class); |
||||
|
tip011 = posReader.getPos(HbotConsumablePos.Tip00_011Pos.name(), Pos3d.class); |
||||
|
tip108 = posReader.getPos(HbotConsumablePos.Tip00_108Pos.name(), Pos3d.class); |
||||
|
tip119 = posReader.getPos(HbotConsumablePos.Tip00_119Pos.name(), Pos3d.class); |
||||
|
|
||||
|
} else if (tipGroup == TipGroup.GROUP1) { |
||||
|
tip000 = posReader.getPos(HbotConsumablePos.Tip01_000Pos.name(), Pos3d.class); |
||||
|
tip011 = posReader.getPos(HbotConsumablePos.Tip01_011Pos.name(), Pos3d.class); |
||||
|
tip108 = posReader.getPos(HbotConsumablePos.Tip01_108Pos.name(), Pos3d.class); |
||||
|
tip119 = posReader.getPos(HbotConsumablePos.Tip01_119Pos.name(), Pos3d.class); |
||||
|
} else if (tipGroup == TipGroup.GROUP2) { |
||||
|
tip000 = posReader.getPos(HbotConsumablePos.Tip02_000Pos.name(), Pos3d.class); |
||||
|
tip011 = posReader.getPos(HbotConsumablePos.Tip02_011Pos.name(), Pos3d.class); |
||||
|
tip108 = posReader.getPos(HbotConsumablePos.Tip02_108Pos.name(), Pos3d.class); |
||||
|
tip119 = posReader.getPos(HbotConsumablePos.Tip02_119Pos.name(), Pos3d.class); |
||||
|
} |
||||
|
assert tip000 != null; |
||||
|
assert tip011 != null; |
||||
|
assert tip108 != null; |
||||
|
assert tip119 != null; |
||||
|
|
||||
|
//水平方向 |
||||
|
double dx = (tip119.x - tip000.x) / 12.0; |
||||
|
//前后方向 |
||||
|
double dy = (tip119.y - tip000.y) / 10.0; |
||||
|
|
||||
|
int xoff = tipoff % 12; |
||||
|
int yoff = tipoff / 12; |
||||
|
|
||||
|
double x = tip000.x + xoff * dx; |
||||
|
double y = tip000.y + yoff * dy; |
||||
|
double z = PlaneUtils.calculateZ(tip000, tip011, tip119, x, y); |
||||
|
|
||||
|
return new Pos3d((int) x, (int) y, (int) z); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private Pos3d getLittleBufferOrProbeSubstancePos( |
||||
|
Pos3d pos00_00, |
||||
|
Pos3d pos00_24, |
||||
|
Pos3d pos05_00, |
||||
|
Pos3d pos05_24, |
||||
|
ConsumableGroup group, Integer off) { |
||||
|
|
||||
|
|
||||
|
Integer groupNum = group.off; |
||||
|
Integer groupXOff = off % 3; |
||||
|
Integer groupYOff = off / 3; |
||||
|
|
||||
|
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 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; |
||||
|
|
||||
|
|
||||
|
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); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public Pos3d getLittleBufferPos(ConsumableGroup group, Integer off) { |
||||
|
Pos3d pos00_00 = posReader.getPos(HbotConsumablePos.LittleBufferPos00_00.name(), Pos3d.class); |
||||
|
Pos3d pos00_24 = posReader.getPos(HbotConsumablePos.LittleBufferPos00_24.name(), Pos3d.class); |
||||
|
Pos3d pos05_00 = posReader.getPos(HbotConsumablePos.LittleBufferPos05_00.name(), Pos3d.class); |
||||
|
Pos3d pos05_24 = posReader.getPos(HbotConsumablePos.LittleBufferPos05_24.name(), Pos3d.class); |
||||
|
return getLittleBufferOrProbeSubstancePos(pos00_00, pos00_24, pos05_00, pos05_24, group, off); |
||||
|
} |
||||
|
|
||||
|
public Pos3d getProbeSubstancePos(ConsumableGroup group, Integer off) { |
||||
|
Pos3d pos00_00 = posReader.getPos(HbotConsumablePos.ProbeSubstance00_00.name(), Pos3d.class); |
||||
|
Pos3d pos00_24 = posReader.getPos(HbotConsumablePos.ProbeSubstance00_24.name(), Pos3d.class); |
||||
|
Pos3d pos05_00 = posReader.getPos(HbotConsumablePos.ProbeSubstance05_00.name(), Pos3d.class); |
||||
|
Pos3d pos05_24 = posReader.getPos(HbotConsumablePos.ProbeSubstance05_24.name(), Pos3d.class); |
||||
|
return getLittleBufferOrProbeSubstancePos(pos00_00, pos00_24, pos05_00, pos05_24, group, off); |
||||
|
} |
||||
|
|
||||
|
public Pos3d getLargeBufferPos(ConsumableGroup group) { |
||||
|
Pos3d pos00 = posReader.getPos(HbotConsumablePos.LargeBufferPos00.name(), Pos3d.class); |
||||
|
Pos3d pos05 = posReader.getPos(HbotConsumablePos.LargeBufferPos05.name(), Pos3d.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; |
||||
|
return new Pos3d((int) x, (int) y, (int) z); |
||||
|
} |
||||
|
} |
@ -0,0 +1,61 @@ |
|||||
|
package a8k.service.app.devicedriver.pos; |
||||
|
|
||||
|
import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; |
||||
|
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.cfg.Pos3d; |
||||
|
import jakarta.annotation.PostConstruct; |
||||
|
import jakarta.annotation.Resource; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* HBOT二维码扫描坐标参数 |
||||
|
*/ |
||||
|
@Component |
||||
|
@ExtApiTab(cfg = ExtApiTabConfig.Hbot2DCodeScanPos) |
||||
|
@ExtApiParamsTab(service = HbotFixPosMgr.class) |
||||
|
public class HbotFixPosMgr { |
||||
|
static final Logger logger = LoggerFactory.getLogger(HbotFixPosMgr.class); |
||||
|
|
||||
|
enum Pos { |
||||
|
DropTipPos, |
||||
|
DropLiquidPos, |
||||
|
} |
||||
|
|
||||
|
; |
||||
|
@Resource |
||||
|
LowerDeviceParameterDBService lowerDeviceParameterDBService; |
||||
|
PosParameterReader posReader = null; |
||||
|
|
||||
|
static Integer nowParaVersion = 0; |
||||
|
|
||||
|
@PostConstruct |
||||
|
void initialize() { |
||||
|
posReader = lowerDeviceParameterDBService.getReader(this.getClass()); |
||||
|
Integer paraVersion = posReader.getVersion(); |
||||
|
if (!nowParaVersion.equals(paraVersion)) { |
||||
|
paramReset(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void paramReset() { |
||||
|
logger.info("init param"); |
||||
|
posReader.setVersion(nowParaVersion); |
||||
|
posReader.updatePos(Pos.DropTipPos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(Pos.DropLiquidPos.name(), new Pos3d(0, 0, 0)); |
||||
|
} |
||||
|
|
||||
|
public Pos3d getDropTipPos() { |
||||
|
return posReader.getPos(Pos.DropTipPos, Pos3d.class); |
||||
|
} |
||||
|
|
||||
|
public Pos3d getDropLiquidPos() { |
||||
|
return posReader.getPos(Pos.DropLiquidPos, Pos3d.class); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,57 @@ |
|||||
|
package a8k.service.app.devicedriver.pos; |
||||
|
|
||||
|
import a8k.extapi_controler.pagecontrol.ExtApiTabConfig; |
||||
|
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.HbotSamplePos; |
||||
|
import a8k.type.cfg.Pos3d; |
||||
|
import jakarta.annotation.PostConstruct; |
||||
|
import jakarta.annotation.Resource; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* HBOT二维码扫描坐标参数 |
||||
|
*/ |
||||
|
@Component |
||||
|
@ExtApiTab(cfg = ExtApiTabConfig.Hbot2DCodeScanPos) |
||||
|
@ExtApiParamsTab(service = HbotSamplePosMgr.class) |
||||
|
public class HbotSamplePosMgr { |
||||
|
static final Logger logger = LoggerFactory.getLogger(HbotSamplePosMgr.class); |
||||
|
|
||||
|
@Resource |
||||
|
LowerDeviceParameterDBService lowerDeviceParameterDBService; |
||||
|
PosParameterReader posReader = null; |
||||
|
|
||||
|
static Integer nowParaVersion = 0; |
||||
|
|
||||
|
@PostConstruct |
||||
|
void initialize() { |
||||
|
posReader = lowerDeviceParameterDBService.getReader(this.getClass()); |
||||
|
Integer paraVersion = posReader.getVersion(); |
||||
|
if (!nowParaVersion.equals(paraVersion)) { |
||||
|
paramReset(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void paramReset() { |
||||
|
logger.info("init param"); |
||||
|
posReader.setVersion(nowParaVersion); |
||||
|
posReader.updatePos(HbotSamplePos.EmergencyTubePos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotSamplePos.BloodTubeSamplePos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotSamplePos.MiniTubeSamplePos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotSamplePos.MiniBloodSamplePos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotSamplePos.Bulltube1P5SamplePos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotSamplePos.Bulltube0P5SamplePos.name(), new Pos3d(0, 0, 0)); |
||||
|
posReader.updatePos(HbotSamplePos.StoolTestTubeSamplePos.name(), new Pos3d(0, 0, 0)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Pos3d getSamplePos(HbotSamplePos pos) { |
||||
|
return posReader.getPos(pos, Pos3d.class); |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,37 @@ |
|||||
|
package a8k.type; |
||||
|
|
||||
|
public enum HbotConsumablePos { |
||||
|
Tip00_000Pos("Tip00_000Pos"), |
||||
|
Tip00_011Pos("Tip00_011Pos"), |
||||
|
Tip00_108Pos("Tip00_108Pos"), |
||||
|
Tip00_119Pos("Tip00_119Pos"), |
||||
|
|
||||
|
Tip01_000Pos("Tip01_000Pos"), |
||||
|
Tip01_011Pos("Tip01_011Pos"), |
||||
|
Tip01_108Pos("Tip01_108Pos"), |
||||
|
Tip01_119Pos("Tip01_119Pos"), |
||||
|
|
||||
|
Tip02_000Pos("Tip02_000Pos"), |
||||
|
Tip02_011Pos("Tip02_011Pos"), |
||||
|
Tip02_108Pos("Tip02_108Pos"), |
||||
|
Tip02_119Pos("Tip02_119Pos"), |
||||
|
|
||||
|
LittleBufferPos00_00("LittleBufferPos00_00"), |
||||
|
LittleBufferPos00_24("LittleBufferPos00_24"), |
||||
|
LittleBufferPos05_00("LittleBufferPos05_00"), |
||||
|
LittleBufferPos05_24("LittleBufferPos05_24"), |
||||
|
|
||||
|
ProbeSubstance00_00("ProbeSubstance00_00"), |
||||
|
ProbeSubstance00_24("ProbeSubstance00_24"), |
||||
|
ProbeSubstance05_00("ProbeSubstance05_00"), |
||||
|
ProbeSubstance05_24("ProbeSubstance05_24"), |
||||
|
|
||||
|
LargeBufferPos00("LargeBufferPos00"), |
||||
|
LargeBufferPos05("LargeBufferPos05"), |
||||
|
|
||||
|
; |
||||
|
final public String chName; |
||||
|
HbotConsumablePos(String chName) { |
||||
|
this.chName = chName; |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package a8k.type; |
||||
|
|
||||
|
public enum HbotSamplePos { |
||||
|
EmergencyTubePos, //急诊位取样位置 |
||||
|
BloodTubeSamplePos, //全血试管 |
||||
|
MiniTubeSamplePos, //迷你试管 |
||||
|
MiniBloodSamplePos, //阳普管 |
||||
|
Bulltube1P5SamplePos, //子弹头试管1.5mL |
||||
|
Bulltube0P5SamplePos, //子弹头试管0.5mL |
||||
|
StoolTestTubeSamplePos, //粪便试管 |
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
package a8k.utils; |
||||
|
|
||||
|
import a8k.type.cfg.Pos3d; |
||||
|
|
||||
|
public class PlaneUtils { |
||||
|
|
||||
|
// 计算平面方程的系数 |
||||
|
public static double[] calculatePlaneCoefficients(Pos3d p1, Pos3d p2, Pos3d p3) { |
||||
|
// 计算平面方程的A、B、C、D |
||||
|
double A = (p2.y - p1.y) * (p3.z - p1.z) - (p2.z - p1.z) * (p3.y - p1.y); |
||||
|
double B = (p2.z - p1.z) * (p3.x - p1.x) - (p2.x - p1.x) * (p3.z - p1.z); |
||||
|
double C = (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x); |
||||
|
double D = -(A * p1.x + B * p1.y + C * p1.z); // 计算D |
||||
|
|
||||
|
return new double[]{A, B, C, D}; |
||||
|
} |
||||
|
|
||||
|
public static double calculateZ(double[] planeCoefficients, double x, double y) { |
||||
|
double A = planeCoefficients[0]; |
||||
|
double B = planeCoefficients[1]; |
||||
|
double C = planeCoefficients[2]; |
||||
|
double D = planeCoefficients[3]; |
||||
|
|
||||
|
// z = -(Ax + By + D) / C |
||||
|
if (C == 0) { |
||||
|
throw new ArithmeticException("C不能为零,无法求解z"); |
||||
|
} |
||||
|
return -(A * x + B * y + D) / C; |
||||
|
} |
||||
|
|
||||
|
public static double calculateZ(Pos3d p1, Pos3d p2, Pos3d p3, double x, double y) { |
||||
|
double[] planeCoefficients = calculatePlaneCoefficients(p1, p2, p3); |
||||
|
return calculateZ(planeCoefficients, x, y); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public static void main(String[] args) { |
||||
|
Pos3d p1 = new Pos3d(0, 0, 100); |
||||
|
Pos3d p2 = new Pos3d(100, 0, 105); |
||||
|
Pos3d p3 = new Pos3d(0, 100, 110); |
||||
|
|
||||
|
double[] planeCoefficients = calculatePlaneCoefficients(p1, p2, p3); |
||||
|
System.out.println("平面方程系数:" + planeCoefficients[0] + " " + planeCoefficients[1] + " " + planeCoefficients[2] + " " + planeCoefficients[3]); |
||||
|
|
||||
|
double x = 20; |
||||
|
double y = 80; |
||||
|
double z = calculateZ(planeCoefficients, x, y); |
||||
|
System.out.println("x=" + x + ", y=" + y + "时,z=" + z); |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue