4 changed files with 406 additions and 20 deletions
-
3.gitignore
-
BINbak/app.db
-
46src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrlService.java
-
377src/main/java/a8k/app/service/lowerctrl/LiquidOperationCtrlServiceBak.java
@ -0,0 +1,377 @@ |
|||||
|
package a8k.app.service.lowerctrl; |
||||
|
|
||||
|
|
||||
|
import a8k.app.dao.type.combination.ProjBuildinInfo; |
||||
|
import a8k.app.dao.type.db.ProjExtInfoCard; |
||||
|
import a8k.app.hardware.driver.PipetteCtrlDriver; |
||||
|
import a8k.app.hardware.type.A8kEcode; |
||||
|
import a8k.app.hardware.type.LldType; |
||||
|
import a8k.app.hardware.type.PipetteRegIndex; |
||||
|
import a8k.app.service.param.exparam.HbotConsumableExParamMgr; |
||||
|
import a8k.app.service.param.hbotpos.HbotSamplePosParamMgr; |
||||
|
import a8k.app.service.param.pipetteparam.PipetteGunExParamMgr; |
||||
|
import a8k.app.service.param.pipetteparam.PipetteGunLLFParamMgr; |
||||
|
import a8k.app.service.statemgr.ConsumablesMgrService; |
||||
|
import a8k.app.service.statemgr.GStateMgrService; |
||||
|
import a8k.app.service.utils.ZAppChecker; |
||||
|
import a8k.app.type.DeviceRunMode; |
||||
|
import a8k.app.type.a8k.ConsumableType; |
||||
|
import a8k.app.type.a8k.Pos3d; |
||||
|
import a8k.app.type.a8k.pos.LargeBufferPos; |
||||
|
import a8k.app.type.a8k.pos.PreReactionPos; |
||||
|
import a8k.app.type.a8k.pos.TipGroupPos; |
||||
|
import a8k.app.type.a8k.pos.TipPos; |
||||
|
import a8k.app.type.exception.AppException; |
||||
|
import a8k.app.type.param.type.A8kSamplePos; |
||||
|
import jakarta.annotation.Resource; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Component |
||||
|
@Slf4j |
||||
|
public class LiquidOperationCtrlServiceBak { |
||||
|
static public final Integer lldZmotorVmax = 50; |
||||
|
static public final Integer lldGunPumpVmax = 50; |
||||
|
static public final Integer aspiratePumpVmax = 100; |
||||
|
static public final Integer reactionVolumeUL = 75; |
||||
|
static public final Integer mixVolumeUL = 200; |
||||
|
|
||||
|
@Resource |
||||
|
GStateMgrService gstate; |
||||
|
|
||||
|
/* |
||||
|
* CTRL-SERVICE |
||||
|
*/ |
||||
|
@Resource |
||||
|
HbotMoveExCtrlService hbotMoveExCtrlService; |
||||
|
@Resource |
||||
|
PipetteCtrlDriver pipetteCtrlDriver; |
||||
|
|
||||
|
/* |
||||
|
* PARAM-MGR |
||||
|
*/ |
||||
|
@Resource |
||||
|
HbotConsumableExParamMgr hbotConsumableExParamMgr; |
||||
|
@Resource |
||||
|
PipetteGunLLFParamMgr pipetteGunLLFParamMgr; |
||||
|
@Resource |
||||
|
PipetteGunExParamMgr pipetteGunExParamMgr; |
||||
|
|
||||
|
/** |
||||
|
* StateMgr |
||||
|
*/ |
||||
|
@Resource |
||||
|
ConsumablesMgrService consumablesMgrService; |
||||
|
@Resource |
||||
|
HbotSamplePosParamMgr hbotSamplePosParamMgr; |
||||
|
|
||||
|
|
||||
|
ProjBuildinInfo projBuildinInfo; |
||||
|
ProjExtInfoCard projExtInfo; |
||||
|
|
||||
|
|
||||
|
synchronized public void setProjContext(ProjBuildinInfo projBuildinInfo, ProjExtInfoCard projExtInfo) { |
||||
|
this.projBuildinInfo = projBuildinInfo; |
||||
|
this.projExtInfo = projExtInfo; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 取TIP |
||||
|
* @param group TIP组 |
||||
|
* @param index TIP序号 |
||||
|
* @throws AppException 异常 |
||||
|
*/ |
||||
|
public void takeTip(TipGroupPos group, Integer index) throws AppException { |
||||
|
// 移动到取TIP位 |
||||
|
TipPos tipPos = new TipPos(); |
||||
|
tipPos.group = group; |
||||
|
tipPos.index = index; |
||||
|
hbotMoveExCtrlService.takeTip(tipPos); |
||||
|
} |
||||
|
|
||||
|
public void forceTakeTip() throws AppException { |
||||
|
if (hbotMoveExCtrlService.isHasTip()) { |
||||
|
return; |
||||
|
} |
||||
|
while (true) { |
||||
|
hbotMoveExCtrlService.takeTip(consumablesMgrService.takeNextTipPos()); |
||||
|
if (gstate.isInMode(DeviceRunMode.RunOnlyMode)) { |
||||
|
break; |
||||
|
} |
||||
|
if (hbotMoveExCtrlService.isHasTip()) { |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void dropTip() throws AppException { |
||||
|
hbotMoveExCtrlService.dropTip(); |
||||
|
} |
||||
|
|
||||
|
public Boolean checkTipIsExist(TipPos tipPos) throws AppException { |
||||
|
return hbotMoveExCtrlService.checkIfTipExist(tipPos.group, tipPos.index); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 取大瓶缓冲液到探测物质位置(不接触分配) |
||||
|
* @param from 大瓶缓冲液 |
||||
|
* @param topos 探测物质位置 |
||||
|
* @param ul 吸取量 |
||||
|
*/ |
||||
|
public void takeLargeBottleBufferLiquidToProbeSubstance(LargeBufferPos from, PreReactionPos topos, Integer ul) throws AppException { |
||||
|
// 取TIP |
||||
|
forceTakeTip(); |
||||
|
|
||||
|
// 检查是否有TIP |
||||
|
ZAppChecker.check(pipetteCtrlDriver.isHasTip(), A8kEcode.CODEERROR, "未检测到TIP"); |
||||
|
Pos3d largeBottleEndPos = hbotConsumableExParamMgr.getLargeBufferSamplePosEnd(from.group); |
||||
|
Pos3d largeBottlePos = hbotConsumableExParamMgr.getLargeBufferSamplePos(from.group); |
||||
|
Integer liquidLevel = 0; |
||||
|
|
||||
|
|
||||
|
// |
||||
|
// 刺破探测物质 |
||||
|
// |
||||
|
Pos3d piercePos = hbotConsumableExParamMgr.getProbeSubstancePiercePos(topos.group, topos.index); |
||||
|
hbotMoveExCtrlService.moveTo(piercePos); |
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(0); |
||||
|
|
||||
|
|
||||
|
// |
||||
|
// 移动到取样位 |
||||
|
// |
||||
|
hbotMoveExCtrlService.moveToXY(largeBottlePos); |
||||
|
|
||||
|
// |
||||
|
//lld |
||||
|
// |
||||
|
//清空tip中的液体和空气,同时预先吸入部分空气,以便后续清空由于lld吸入的液体,提高lld的准确性 |
||||
|
lddprepare(); |
||||
|
ldd(largeBottlePos.z, 1000, 30); |
||||
|
if (pipetteCtrlDriver.lldIsDetectLiquid() && gstate.isInMode(DeviceRunMode.RealMode)) { |
||||
|
throw AppException.of(A8kEcode.APPE_TAKE_LARGE_BUFFER_LIQUID_FAIL); |
||||
|
} |
||||
|
liquidLevel = pipetteCtrlDriver.getReg(PipetteRegIndex.kreg_pipette_zm_pos); |
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(0); |
||||
|
pumpMoveTo(8000, 0.0); |
||||
|
|
||||
|
// |
||||
|
//取样 |
||||
|
// |
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(liquidLevel); |
||||
|
if (ul < 100) { |
||||
|
pumpMoveTo(8000, 50.0);//预先吸入部分空气 |
||||
|
} else { |
||||
|
pumpMoveTo(8000, 25.0);//预先吸入部分空气 |
||||
|
} |
||||
|
|
||||
|
aspirate(largeBottleEndPos.z, aspiratePumpVmax, pipetteGunLLFParamMgr.getLargeBSBottleLlfVel(), ul * 1.0); |
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(0); |
||||
|
|
||||
|
// |
||||
|
// 移动到探测物质的位置 |
||||
|
// |
||||
|
Pos3d toCPos = hbotConsumableExParamMgr.getProbeSubstanceSamplePos(topos.group, topos.index); |
||||
|
hbotMoveExCtrlService.moveTo(toCPos); |
||||
|
pumpMoveTo(8000, 0.0); |
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(0); |
||||
|
|
||||
|
// |
||||
|
// 丢弃TIP |
||||
|
// |
||||
|
hbotMoveExCtrlService.initPipetterGun(); |
||||
|
hbotMoveExCtrlService.moveQuickToZero(); |
||||
|
} |
||||
|
|
||||
|
private Pos3d getPreReactionPos(PreReactionPos pos) { |
||||
|
Pos3d toCPos = null; |
||||
|
if (pos.type.equals(ConsumableType.ProbeSubstance)) { |
||||
|
toCPos = hbotConsumableExParamMgr.getProbeSubstanceSamplePos(pos.group, pos.index); |
||||
|
} else { |
||||
|
toCPos = hbotConsumableExParamMgr.getLittleBufferSamplePos(pos.group, pos.index); |
||||
|
} |
||||
|
return toCPos; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 取样本到探测物质 |
||||
|
* @param from 样本位置 |
||||
|
* @param pos 预先反应位置P |
||||
|
* @param ul 吸取量 |
||||
|
* @throws AppException 异常 |
||||
|
*/ |
||||
|
public void takeSample(A8kSamplePos from, PreReactionPos pos, Integer ul) throws AppException { |
||||
|
log.info("takeSampleToPreReactionPos: from={}, pos={}, ul={}ul", from, pos, ul); |
||||
|
// 取TIP |
||||
|
forceTakeTip(); |
||||
|
ZAppChecker.check(pipetteCtrlDriver.isHasTip(), A8kEcode.CODEERROR, "未检测到TIP"); |
||||
|
|
||||
|
// |
||||
|
// 取样位 |
||||
|
// |
||||
|
|
||||
|
// 取样 |
||||
|
Pos3d sampleStartPos = hbotSamplePosParamMgr.getSampleStartPos(from); |
||||
|
Integer sampleEndZPos = hbotSamplePosParamMgr.getSampleEndPos(from); |
||||
|
Integer liquidLevel = 0; |
||||
|
// 移动到取样位 |
||||
|
hbotMoveExCtrlService.moveToXY(sampleStartPos); |
||||
|
|
||||
|
//lld |
||||
|
//清空tip中的液体和空气,同时预先吸入部分空气,以便后续清空由于lld吸入的液体,提高lld的准确性 |
||||
|
lddprepare(); |
||||
|
ldd(sampleStartPos.z, sampleEndZPos, 20); |
||||
|
if (!pipetteCtrlDriver.lldIsDetectLiquid() && gstate.isInMode(DeviceRunMode.RealMode)) { |
||||
|
throw AppException.of(A8kEcode.APPE_TAKE_SAMPLE_FAIL); |
||||
|
} |
||||
|
|
||||
|
//获取当前液面高度 |
||||
|
liquidLevel = pipetteCtrlDriver.getReg(PipetteRegIndex.kreg_pipette_zm_pos); |
||||
|
liquidLevel += 10;//保证液面高度 |
||||
|
|
||||
|
//取样准备 |
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(sampleStartPos.z); //回到0 |
||||
|
pumpMoveTo(8000, 0.0); //排空 |
||||
|
pumpMoveTo(aspiratePumpVmax, 10.0); //预先吸入部分空气 |
||||
|
|
||||
|
//取样 |
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(liquidLevel); |
||||
|
aspirate(sampleEndZPos, aspiratePumpVmax, pipetteGunLLFParamMgr.getSampleLLFVel(from), ul * 1.0); |
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(0); |
||||
|
|
||||
|
|
||||
|
// |
||||
|
// 移动到反应位 |
||||
|
// |
||||
|
log.info("move to pre reaction pos: {}", pos); |
||||
|
hbotMoveExCtrlService.moveTo(getPreReactionPos(pos)); |
||||
|
|
||||
|
//吐液,此过程会产生气泡,但由于气泡在液面附近,而吸吐位在液面之下,问题不大 |
||||
|
log.info("drop liquid"); |
||||
|
pumpMoveTo(200, 0.0); |
||||
|
|
||||
|
//混匀 |
||||
|
Integer shakeUl = mixVolumeUL; |
||||
|
Integer shakeTimes = 5; |
||||
|
if (projBuildinInfo != null) { |
||||
|
shakeUl = projBuildinInfo.mixedLiquidMixingVolUl; |
||||
|
shakeTimes = projBuildinInfo.mixedLiquidMixingTimes; |
||||
|
} |
||||
|
//摇匀 |
||||
|
shakeUp(shakeUl, shakeTimes); |
||||
|
|
||||
|
//z轴回0 |
||||
|
pipetteCtrlDriver.zMotorMoveToZeroPointQuickBlock(); |
||||
|
} |
||||
|
|
||||
|
public void pirceLittleBuffer(PreReactionPos pos) throws AppException { |
||||
|
forceTakeTip(); |
||||
|
|
||||
|
hbotMoveExCtrlService.moveToLittleBufferPiercePos(pos.group, pos.index); |
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(0); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 取反应液到反应板上 |
||||
|
* @param pos 反应板位置 |
||||
|
* @throws AppException 异常 |
||||
|
*/ |
||||
|
public void takePreReactionLiquidToReation(PreReactionPos pos) throws AppException { |
||||
|
log.info("takePreReactionLiquidToReactionPos: from pos={}", pos); |
||||
|
forceTakeTip(); |
||||
|
Pos3d reactionPos = getPreReactionPos(pos); |
||||
|
|
||||
|
hbotMoveExCtrlService.moveToXY(reactionPos); |
||||
|
pipetteCtrlDriver.zMotorMoveByBlock(0); |
||||
|
makeReserveAir(100); |
||||
|
|
||||
|
hbotMoveExCtrlService.moveToZ(reactionPos); |
||||
|
aspirate(reactionPos.z, aspiratePumpVmax, 0, (double) reactionVolumeUL); |
||||
|
|
||||
|
hbotMoveExCtrlService.moveToDropLiquidPos(); |
||||
|
pumpMoveTo(8000, 0.0); |
||||
|
|
||||
|
hbotMoveExCtrlService.initPipetterGun(); |
||||
|
hbotMoveExCtrlService.moveQuickToZero(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// |
||||
|
// PRIVATE |
||||
|
// |
||||
|
|
||||
|
|
||||
|
private void pumpMoveTo(Integer pumpvmax, Double ul) throws AppException { |
||||
|
pipetteCtrlDriver.liquidOperationClearParams(); |
||||
|
pipetteCtrlDriver.liquidOperationSetGunRunParams(14, 14, 0, 1000, pumpvmax); |
||||
|
pipetteCtrlDriver.liquidOperationFreshParams(); |
||||
|
pipetteCtrlDriver.pipettePumpMoveTo(ul); |
||||
|
} |
||||
|
|
||||
|
private void lddprepare() throws AppException { |
||||
|
|
||||
|
pipetteCtrlDriver.liquidOperationClearParams(); |
||||
|
pipetteCtrlDriver.liquidOperationSetGunRunParams(14, 14, 0, 1000, 8000); |
||||
|
pipetteCtrlDriver.liquidOperationFreshParams(); |
||||
|
|
||||
|
pipetteCtrlDriver.pipettePumpMoveTo(0.0); |
||||
|
pipetteCtrlDriver.pipettePumpMoveTo(50.0); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private void ldd(Integer startpos, Integer maxpos, Integer p_threshold) throws AppException { |
||||
|
log.info("lld: startpos={}, maxpos={}, p_threshold={}", startpos, maxpos, p_threshold); |
||||
|
|
||||
|
pipetteCtrlDriver.zMotorMoveToBlock(startpos); |
||||
|
|
||||
|
pipetteCtrlDriver.liquidOperationClearParams(); |
||||
|
pipetteCtrlDriver.liquidOperationSetGunRunParams(14, 14, 0, 1000, lldGunPumpVmax); |
||||
|
pipetteCtrlDriver.liquidOperationSetZMotorRunParams(0, maxpos, lldZmotorVmax); |
||||
|
pipetteCtrlDriver.liquidOperationFreshParams(); |
||||
|
|
||||
|
pipetteCtrlDriver.pipetteLld(LldType.kplld, 0, p_threshold); |
||||
|
} |
||||
|
|
||||
|
private void makeReserveAir(Integer ul) throws AppException { |
||||
|
pipetteCtrlDriver.liquidOperationClearParams(); |
||||
|
pipetteCtrlDriver.liquidOperationSetGunRunParams(14, 14, 0, 1000, 8000); |
||||
|
pipetteCtrlDriver.liquidOperationFreshParams(); |
||||
|
|
||||
|
pipetteCtrlDriver.pipettePumpMoveTo(0.0); |
||||
|
pipetteCtrlDriver.pipettePumpMoveTo(Double.valueOf(ul)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 在当前位置吸取液体 |
||||
|
* @param maxpos 最大位置 |
||||
|
* @param gunv 枪速 |
||||
|
* @param zv z轴速度 |
||||
|
* @param ul 吸取量 |
||||
|
* @throws AppException 异常 |
||||
|
*/ |
||||
|
private void aspirate(Integer maxpos, int gunv, int zv, Double ul) throws AppException { |
||||
|
log.info("aspirate: maxpos={}, gunv={}, zv={}, ul={}", maxpos, gunv, zv, ul); |
||||
|
pipetteCtrlDriver.liquidOperationClearParams(); |
||||
|
pipetteCtrlDriver.liquidOperationSetGunRunParams(14, 14, 0, 1000, gunv); |
||||
|
pipetteCtrlDriver.liquidOperationSetZMotorRunParams(0, maxpos, zv); |
||||
|
pipetteCtrlDriver.liquidOperationFreshParams(); |
||||
|
|
||||
|
Double realul = pipetteGunExParamMgr.calibrateVolume(ul); |
||||
|
// Double realul = ul; |
||||
|
pipetteCtrlDriver.pipetteAspirate(realul); |
||||
|
} |
||||
|
|
||||
|
private void shakeUp(Integer ul, Integer times) throws AppException { |
||||
|
log.info("shakeUp: ul={}, times={}", ul, times); |
||||
|
pipetteCtrlDriver.liquidOperationClearParams(); |
||||
|
pipetteCtrlDriver.liquidOperationSetGunRunParams(14, 14, 0, 1000, 8000); |
||||
|
pipetteCtrlDriver.liquidOperationFreshParams(); |
||||
|
pipetteCtrlDriver.pipetteShakeUp((double) ul, times); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue