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