Browse Source

update

tags/v0
zhaohe 9 months ago
parent
commit
f9e4a13c44
  1. 190
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java
  2. 6
      src/main/java/a8k/service/app/appstate/type/ProjectTaskContext.java
  3. 12
      src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java
  4. 26
      src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java
  5. 6
      src/main/java/a8k/service/app/devicectrl/param/calibration/HbotLargeBottleBSPosCalibration.java
  6. 4
      src/main/java/a8k/service/app/devicectrl/param/ext_param_mgr/HbotConsumableParamMgr.java
  7. 4
      src/main/java/a8k/service/app/devicectrl/param/param_mgr/HbotLittleBSPosMgr.java
  8. 274
      src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java
  9. 110
      src/main/java/a8k/service/app/devicectrl/script/PipeGunCtrlScripter.java
  10. 4
      src/main/java/a8k/utils/ProjProcessContextUtils.java

190
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java

@ -1,8 +1,6 @@
package a8k.service.app.appctrl.mainflowctrl.action;
import a8k.OS;
import a8k.constant.LogTopic;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.service.app.appctrl.mainflowctrl.PublicAreaResourceMgr;
import a8k.service.app.appctrl.mainflowctrl.base.*;
import a8k.service.app.appstate.statemgr.IncubationPlateStateMgrService;
@ -12,16 +10,29 @@ import a8k.service.app.appstate.type.ProjectTaskContext;
import a8k.service.app.appstate.type.Tube;
import a8k.service.app.appstate.type.TubeHolder;
import a8k.service.app.appstate.type.state.TubeState;
import a8k.service.app.devicectrl.ctrlservice.HbotCtrlService;
import a8k.service.app.devicectrl.ctrlservice.PlateBoxCtrlService;
import a8k.service.app.devicectrl.ctrlservice.TubePreProcesCtrlService;
import a8k.service.app.devicectrl.script.DeviceCtrlScripter;
import a8k.service.app.devicectrl.ctrlservice.TurnableMoveCtrlService;
import a8k.service.app.devicectrl.driver.PipetteCtrlDriver;
import a8k.service.app.devicectrl.exdriver.HbotBaseMoveExDriver;
import a8k.service.app.devicectrl.param.ext_param_mgr.HbotConsumableParamMgr;
import a8k.service.app.devicectrl.param.ext_param_mgr.PipetteGunParamExMgr;
import a8k.service.app.devicectrl.param.ext_param_mgr.base.PipetteGunBindActionType;
import a8k.service.app.devicectrl.param.param_mgr.HbotFixedPosParamMgr;
import a8k.service.app.devicectrl.param.param_mgr.HbotSamplePosParamMgr;
import a8k.service.app.devicectrl.param.type.A8kSamplePos;
import a8k.service.app.devicectrl.script.PipeGunCtrlScripter;
import a8k.service.app.erroranalyzer.ErrorAnalyzer;
import a8k.service.dao.type.a8kidcard.zenum.A8kReactionFlowType;
import a8k.service.test.state.TestModeState;
import a8k.service.test.state.VirtualDevice;
import a8k.type.ConsumableGroup;
import a8k.type.IncubatorPos;
import a8k.type.ecode.AppError;
import a8k.type.exception.AppException;
import a8k.type.exception.ZAppInterruptException;
import a8k.type.pos.Consumable;
import a8k.type.type.A8kTubeHolderType;
import a8k.utils.ProjInfoUtils;
import a8k.utils.ProjProcessContextUtils;
@ -72,11 +83,31 @@ public class SEQ5_PROCESS extends A8kStepAction {
// CtrlService
//
@Resource
DeviceCtrlScripter deviceCtrlScripter;
PipeGunCtrlScripter pipeGunCtrlScripter;
@Resource
PlateBoxCtrlService plateBoxCtrlService;
@Resource
TubePreProcesCtrlService tubePreProcesCtrlService;
@Resource
PipetteCtrlDriver pipetteCtrlDriver;
@Resource
HbotBaseMoveExDriver hbotBaseMoveExDriver;
@Resource
HbotCtrlService hbotCtrlService;
@Resource
TurnableMoveCtrlService turnableMoveCtrlService;
//
// Param
//
@Resource
HbotSamplePosParamMgr hbotSamplePosParamMgr;
@Resource
HbotConsumableParamMgr hbotConsumableParamMgr;
@Resource
HbotFixedPosParamMgr hbotFixedPosParamMgr;
@Resource
PipetteGunParamExMgr pipetteGunParamExMgr;
//
@ -209,8 +240,6 @@ public class SEQ5_PROCESS extends A8kStepAction {
//
// REAL
//
void samplePrepare() throws AppException, ZAppInterruptException {
Tube tube = tubeStateMgrService.getCurProcessingTube();
TubeHolder tubeHolder = tubeStateMgrService.getTubeHolder();
@ -280,31 +309,162 @@ public class SEQ5_PROCESS extends A8kStepAction {
List<ProjectTaskContext> cxts = projectContextMgrService.findCxts(tube.getSampleId());
Assert.isTrue(!cxts.isEmpty(), "项目上下文不能为空");
for (ProjectTaskContext cxt : cxts) {
try (
var ignored = publicAreaResourceMgr.apply(this.getClass(), PublicAreaResource.HbotArea);
) {
for (ProjectTaskContext cxt : cxts) {
deviceCtrlScripter.doSampleProcessPrepare(cxt);
doSampleProcess(cxt);
}
}
sampleProcessFinished.set();
}
void doSampleFlowType1PreProcess(ProjectTaskContext cxt) throws AppException, ZAppInterruptException {
Consumable consumable = cxt.getConsumable();
ConsumableGroup consumableGroup = consumable.getGroup();
Integer consumablePos = consumable.getPos();
log.info(" FlowType1->取TIP {}", cxt.getTopTip());
hbotCtrlService.takeTip(cxt.takeTip());
log.info(" FlowType1->刺破小缓冲液 {} {}", consumableGroup, consumablePos);
hbotCtrlService.moveToLittleBufferPiercePos(consumableGroup, consumablePos);
log.info(" FlowType1->hbot归零");
hbotCtrlService.quickResetHbot();
}
void doSampleFlowType2PreProcess(ProjectTaskContext cxt) throws AppException, ZAppInterruptException {
Consumable consumable = cxt.getConsumable();
ConsumableGroup consumableGroup = consumable.getGroup();
Integer consumablePos = consumable.getPos();
Integer largeBsVolume = ProjProcessContextUtils.getTakeLargeBSVolume(cxt);
log.info(" FlowType2->取TIP {}", cxt.getTopTip());
hbotCtrlService.takeTip(cxt.takeTip());//取tip
log.info(" FlowType2->刺破探测物质 {} {}", consumableGroup, consumablePos);
hbotCtrlService.moveToProbeSubstancePiercePos(consumableGroup, consumablePos);//刺破探测物质
log.info(" FlowType2->等待LDD准备完成");
pipetteCtrlDriver.lldPrepareBlock();
log.info(" FlowType2->移动到大缓冲液取液位 {}", consumableGroup);
hbotCtrlService.moveToLargeBSSamplePos(consumableGroup);//移动到取样位置
log.info(" FlowType2->液面探测准备");
pipeGunCtrlScripter.lld(PipetteGunBindActionType.TAKE_LARGE_BUFFER_SOLUTION, cxt); //优化这个方法的接口尽量去除掉cxt
log.info(" FlowType2->取液准备");
pipetteCtrlDriver.aspiratePrepareBlock();//取液.准备
log.info(" FlowType2->取液 {}", largeBsVolume);
pipeGunCtrlScripter.aspirate(PipetteGunBindActionType.TAKE_LARGE_BUFFER_SOLUTION, cxt, largeBsVolume);//取液
log.info(" FlowType2->移动到探测物质吐液位 {}", consumableGroup);
hbotCtrlService.moveToProbeSubstanceSamplePos(consumableGroup, consumablePos);//移动到吐液位
log.info(" FlowType2->吐液 {}", largeBsVolume);
pipeGunCtrlScripter.distribute(PipetteGunBindActionType.DISTRIBUTION_LARGE_BUFFER_SOLUTION_PROBE_SUBSTANCE, cxt, largeBsVolume);//吐液
log.info(" FlowType2->hbot归零");
hbotCtrlService.quickResetHbot();
}
void doSampleProcess(ProjectTaskContext cxt) throws AppException, ZAppInterruptException {
A8kReactionFlowType type = cxt.getProjBuildinInfo().projBaseInfo.reactionFlowType;
Consumable consumable = cxt.getConsumable();
ConsumableGroup consumableGroup = consumable.getGroup();
Integer consumablePos = consumable.getPos();
//TODO:可以提速的点
// 1. 在取tip之后就让移液枪移动到lldprepare的位置新增一条指令,这条指令在单片机端也是非阻塞的到lld位置时在执行lldprepare的指令这样即不破坏现有框架也可以提速
//
if (type.equals(A8kReactionFlowType.FlowType1)) {
log.info("FlowType1:");
doSampleFlowType1PreProcess(cxt);
// !!! 等待样本准备完成 !!!
sampleIsReady.waitTrue();
deviceCtrlScripter.doSampleProcess(cxt);
reactionPlateReady.waitTrue();
// 取样
try (
var ignored11 = publicAreaResourceMgr.apply(this.getClass(), PublicAreaResource.TubeSampleProcessAndTubeChannelArea);
) {
log.info(" FlowType1->取样");
takeSample(cxt);
log.info(" FlowType1->移动到初步反应位");
hbotCtrlService.moveToLittleBufferSamplePos(consumableGroup, consumablePos);
}
} else if (type.equals(A8kReactionFlowType.FlowType2)) {
log.info("FlowType2:");
doSampleFlowType2PreProcess(cxt);
// !!! 等待样本准备完成 !!!
sampleIsReady.waitTrue();
// 取样
try (
var ignored1 = publicAreaResourceMgr.apply(this.getClass(), PublicAreaResource.IncubationPlateArea);
var ignored11 = publicAreaResourceMgr.apply(this.getClass(), PublicAreaResource.TubeSampleProcessAndTubeChannelArea);
) {
deviceCtrlScripter.doSampleProcessPostProcess(cxt);
log.info(" FlowType2->取样");
takeSample(cxt);
log.info(" FlowType2->移动到初步反应位");
hbotCtrlService.moveToProbeSubstanceSamplePos(consumableGroup, consumablePos);
}
}
// 初步反应处理
{
Integer sampleul = ProjProcessContextUtils.getSampleVol(cxt);
Integer reactionul = ProjProcessContextUtils.getReactionPlateDropletVolUl(cxt);
log.info(" FlowTypeX->吐液 {}", sampleul);
pipeGunCtrlScripter.aspirateNoLLF(-sampleul);
log.info(" FlowTypeX->吸吐混匀 {}ul {} times", reactionul, ProjProcessContextUtils.getBSMixingCnt(cxt));
pipeGunCtrlScripter.mix(PipetteGunBindActionType.MIX_REACTION_LIQUOR, cxt, sampleul, ProjProcessContextUtils.getBSMixingCnt(cxt));
}
// 取初步反应混合液到反应板
try (
var ignored11 = publicAreaResourceMgr.apply(this.getClass(), PublicAreaResource.IncubationPlateArea);
) {
Integer reactionul = ProjProcessContextUtils.getReactionPlateDropletVolUl(cxt);
log.info(" FlowTypeX->吸液 {}", reactionul);
pipeGunCtrlScripter.aspirateNoLLF(reactionul);
log.info(" FlowTypeX->吐液到反应板");
hbotCtrlService.moveTo(hbotFixedPosParamMgr.getDropLiquidPos());
pipeGunCtrlScripter.distributeNoLLF(reactionul);
pipetteCtrlDriver.clearHangingLiquid(2);
pipetteCtrlDriver.zMotorMoveToZeroPointQuickBlock();
//孵育
cxt.setStartIncubatedTime(System.currentTimeMillis());
cxt.setIncubatedTimeSec(cxt.getProjBuildinInfo().projBaseInfo.reactionPlateIncubationTimeMin * 60);
}
log.info(" FlowTypeX->Hbot复位");
hbotCtrlService.moveQuickToZero();
}
sampleProcessFinished.set();
public void takeSample(ProjectTaskContext ctx) throws AppException {
Integer sampleul = ProjProcessContextUtils.getSampleVol(ctx);
A8kSamplePos samplePos = ProjProcessContextUtils.getSamplePos(ctx);
log.info(" -->取样准备");
hbotCtrlService.takeTip(ctx.takeTip());
log.info(" -->移动到取样位置 {}", samplePos);
hbotCtrlService.moveToSamplePosXY(samplePos);
log.info(" -->液面探测准备");
pipetteCtrlDriver.lldPrepareBlock();
log.info(" -->液面探测");
pipeGunCtrlScripter.lld(PipetteGunBindActionType.SAMPLE, ctx);
log.info(" -->取液准备");
pipetteCtrlDriver.aspiratePrepareBlock();
if (ProjProcessContextUtils.isDoMixTubeSample(ctx)) {
log.info(" -->吸吐混匀 {}", ProjProcessContextUtils.getTubeMixingCount(ctx));
pipeGunCtrlScripter.mix(PipetteGunBindActionType.MIX_SAMPLE, ctx, sampleul, ProjProcessContextUtils.getTubeMixingCount(ctx));
}
log.info(" -->取样 {}", sampleul);
pipeGunCtrlScripter.aspirate(PipetteGunBindActionType.SAMPLE, ctx, sampleul);
}

6
src/main/java/a8k/service/app/appstate/type/ProjectTaskContext.java

@ -110,6 +110,12 @@ public class ProjectTaskContext {
return tipPos.remove(0);
}
synchronized public TipPos getTopTip() {
if (tipPos == null || tipPos.isEmpty()) {
return null;
}
return tipPos.get(0);
}
synchronized public OptScanResult getfOptScanResult(A8kOptType optType) {
return switch (optType) {

12
src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java

@ -1,6 +1,5 @@
package a8k.service.app.devicectrl.ctrlservice;
import a8k.constant.LogTopic;
import a8k.hardware.A8kCanBusService;
import a8k.hardware.type.a8kcanprotocol.IOId;
import a8k.service.app.devicectrl.driver.MiniServoDriver;
@ -10,7 +9,6 @@ import a8k.service.app.devicectrl.driver.type.MiniServoMId;
import a8k.service.app.devicectrl.driver.type.StepMotorMId;
import a8k.service.app.devicectrl.exdriver.HbotBaseMoveExDriver;
import a8k.service.app.devicectrl.exdriver.MotorEnableExDriver;
import a8k.service.app.devicectrl.script.DeviceCtrlScripter;
import a8k.service.test.state.VirtualDevice;
import a8k.type.CheckPointType;
@ -60,8 +58,7 @@ public class DeviceInitCtrlService {
TubeFeedingCtrlService tubeFeedingCtrlService;
@Resource
HbotCtrlService hbotCtrlService;
@Resource
DeviceCtrlScripter deviceCtrlScripter;
@Resource
HbotBaseMoveExDriver hbotBaseMoveExDriver;
@ -148,7 +145,12 @@ public class DeviceInitCtrlService {
gstate.setDeviceInited(true);
//弹出无效物料
deviceCtrlScripter.dropAllPlates();
log.error("TODO:..............................清空孵育盘");
log.error("TODO:..............................清空孵育盘");
log.error("TODO:..............................清空孵育盘");
log.error("TODO:..............................清空孵育盘");
log.error("TODO:..............................清空孵育盘");
//弹出试管架
tubeFeedingCtrlService.ejectTubeHolder();
//丢弃tip头

26
src/main/java/a8k/service/app/devicectrl/ctrlservice/HbotCtrlService.java

@ -9,6 +9,7 @@ import a8k.service.app.devicectrl.driver.PipetteCtrlDriver;
import a8k.service.app.devicectrl.param.ext_param_mgr.HbotConsumableParamMgr;
import a8k.service.app.devicectrl.param.param_mgr.HbotFixedPosParamMgr;
import a8k.service.app.devicectrl.param.param_mgr.HbotSamplePosParamMgr;
import a8k.service.app.devicectrl.param.type.A8kSamplePos;
import a8k.type.ConsumableGroup;
import a8k.service.app.devicectrl.param.type.HbotSamplePos;
import a8k.type.pos.TipPos;
@ -96,6 +97,14 @@ public class HbotCtrlService {
}
}
public void quickResetHbot() throws AppException {
hbotBaseMoveExDriver.hbotMoveTo(hbotTipPosMgr.getDropTipPos());
pipetteCtrlDriver.pipetteInitDeviceBlock();
hbotBaseMoveExDriver.hbotMoveTo(new Pos3d(0, 0, 0));
hbotBaseMoveExDriver.moveToZero();
}
public Boolean isHasTip() throws AppException {
return pipetteCtrlDriver.isHasTip();
}
@ -123,7 +132,7 @@ public class HbotCtrlService {
}
public void moveToLittleBufferSamplePos(ConsumableGroup group, Integer off) throws AppException {
hbotBaseMoveExDriver.hbotMoveTo(hbotConsumableParamMgr.getLittleBufferSamplePosEnd(group, off));
hbotBaseMoveExDriver.hbotMoveTo(hbotConsumableParamMgr.getLittleBufferSamplePos(group, off));
}
// public void moveToProbeSubstanceSamplePos(ConsumableGroup group, Integer off) throws AppException {
@ -139,12 +148,12 @@ public class HbotCtrlService {
}
public void moveToLargeBufferPos(ConsumableGroup group) throws AppException {
public void moveToLargeBSSamplePos(ConsumableGroup group) throws AppException {
Pos3d toPos = hbotConsumableParamMgr.getLargeBufferSamplePos(group);
hbotBaseMoveExDriver.hbotMoveTo(toPos);
}
public void moveToLargeBufferPosEnd(ConsumableGroup group) throws AppException {
public void moveToLargeBSSampleEndPos(ConsumableGroup group) throws AppException {
Pos3d toPos = hbotConsumableParamMgr.getLargeBufferSamplePosEnd(group);
hbotBaseMoveExDriver.hbotMoveTo(toPos);
}
@ -154,6 +163,17 @@ public class HbotCtrlService {
hbotBaseMoveExDriver.hbotMoveTo(hbotSamplePosParamMgr.getSamplePos(pos));
}
public void moveToSampleStartPos(A8kSamplePos pos) throws AppException {
hbotBaseMoveExDriver.hbotMoveTo(hbotSamplePosParamMgr.getSampleStartPos(pos));
}
public void moveToSamplePosXY(A8kSamplePos pos) throws AppException {
var topos = hbotSamplePosParamMgr.getSampleStartPos(pos);
topos.z = 0;
hbotBaseMoveExDriver.hbotMoveTo(topos);
}
public void moveTo(Pos3d pos) throws AppException {
hbotBaseMoveExDriver.hbotMoveTo(pos);
}

6
src/main/java/a8k/service/app/devicectrl/param/calibration/HbotLargeBottleBSPosCalibration.java

@ -12,18 +12,14 @@ import a8k.service.app.devicectrl.ctrlservice.HbotCtrlService;
import a8k.service.app.devicectrl.param.param_mgr.HbotLargeBottleBSPosMgr;
import a8k.type.*;
import a8k.type.cfg.Pos2d;
import a8k.type.cfg.Pos3d;
import a8k.type.exception.AppException;
import a8k.utils.ZJsonHelper;
import a8k.utils.ZSimplAlgo;
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;
@ExtApiTab(cfg = ExtApiTabConfig.HbotLargeBottleBSPosCalibration)
@Component
@Aspect
@ -230,7 +226,7 @@ public class HbotLargeBottleBSPosCalibration {
enableModule();
pipetteCtrlDriver.zMotorMoveZeroBlock();
for (ConsumableGroup group : ConsumableGroup.values()) {
hbotCtrlService.moveToLargeBufferPosEnd(group);
hbotCtrlService.moveToLargeBSSampleEndPos(group);
pipetteCtrlDriver.zMotorMoveToZeroPointQuickBlock();
if (checkStopFlag())
break;

4
src/main/java/a8k/service/app/devicectrl/param/ext_param_mgr/HbotConsumableParamMgr.java

@ -37,8 +37,8 @@ public class HbotConsumableParamMgr {
return hbotLittleBSPosMgr.getPiercePos(group, off);
}
public Pos3d getLittleBufferSamplePosEnd(ConsumableGroup group, Integer off) {
return hbotLittleBSPosMgr.getSampleEndPos(group, off);
public Pos3d getLittleBufferSamplePos(ConsumableGroup group, Integer off) {
return hbotLittleBSPosMgr.getSamplePos(group, off);
}

4
src/main/java/a8k/service/app/devicectrl/param/param_mgr/HbotLittleBSPosMgr.java

@ -29,7 +29,7 @@ public class HbotLittleBSPosMgr extends ParamMgr {
for (int i = 0; i < 25; i++) {
getConsumablePos(group, i);
getPiercePos(group, i);
getSampleEndPos(group, i);
getSamplePos(group, i);
}
}
}
@ -70,7 +70,7 @@ public class HbotLittleBSPosMgr extends ParamMgr {
return pos;
}
public Pos3d getSampleEndPos(ConsumableGroup group, Integer off) {
public Pos3d getSamplePos(ConsumableGroup group, Integer off) {
Pos3d pos = getConsumablePos(group, off);
pos.z = getParam(HbotLittleBSPos.LittleBSSampleZPos, Integer.class);
return pos;

274
src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java

@ -1,274 +0,0 @@
package a8k.service.app.devicectrl.script;
import a8k.service.app.appstate.type.ProjectTaskContext;
import a8k.service.app.devicectrl.ctrlservice.HbotCtrlService;
import a8k.service.app.devicectrl.ctrlservice.OptScanModuleCtrlService;
import a8k.service.app.devicectrl.ctrlservice.TurnableMoveCtrlService;
import a8k.service.app.devicectrl.driver.PipetteCtrlDriver;
import a8k.service.app.devicectrl.exdriver.HbotBaseMoveExDriver;
import a8k.service.app.devicectrl.param.ext_param_mgr.HbotConsumableParamMgr;
import a8k.service.app.devicectrl.param.ext_param_mgr.base.PipetteGunBindActionType;
import a8k.service.app.devicectrl.param.ext_param_mgr.base.LLDParamPack;
import a8k.service.app.devicectrl.param.ext_param_mgr.PipetteGunParamExMgr;
import a8k.service.app.devicectrl.param.ext_param_mgr.base.LLFParamPack;
import a8k.service.app.devicectrl.param.param_mgr.HbotFixedPosParamMgr;
import a8k.service.app.devicectrl.param.param_mgr.HbotSamplePosParamMgr;
import a8k.service.app.devicectrl.param.type.A8kSamplePos;
import a8k.service.dao.type.a8kidcard.zenum.A8kReactionFlowType;
import a8k.type.cfg.Pos3d;
import a8k.type.exception.AppException;
import a8k.type.pos.Consumable;
import a8k.type.pos.TipPos;
import a8k.utils.ProjProcessContextUtils;
import a8k.utils.ZAppChecker;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
@Component
@Slf4j
public class DeviceCtrlScripter {
@Resource
PipetteCtrlDriver pipetteCtrlDriver;
@Resource
HbotBaseMoveExDriver hbotBaseMoveExDriver;
@Resource
HbotCtrlService hbotCtrlService;
@Resource
TurnableMoveCtrlService turnableMoveCtrlService;
@Resource
HbotSamplePosParamMgr hbotSamplePosParamMgr;
@Resource
HbotConsumableParamMgr hbotConsumableParamMgr;
@Resource
HbotFixedPosParamMgr hbotFixedPosParamMgr;
@Resource
PipetteGunParamExMgr pipetteGunParamExMgr;
@Resource
ZAppChecker zAppChecker;
@Resource
OptScanModuleCtrlService optScanModuleCtrlService;
public void dropAllPlates() throws AppException {
log.info("清空孵育盘");
//TODO:测试模式下不执行
// actionReactor.dosome("丢板", () -> optScanModuleCtrlService.dropPlate());
// for (var incubatorPos : IncubatorPos.values()) {
// actionReactor.dosome("拉板" + incubatorPos.name(), () -> optScanModuleCtrlService.pullPlate(incubatorPos));
// actionReactor.dosome("丢板", () -> optScanModuleCtrlService.dropPlate());
// }
}
void aspirateNoLLF(Integer ul) throws AppException {
pipetteCtrlDriver.aspirateSetLlfVelocity(0);
pipetteCtrlDriver.aspirateBlock(ul);
}
void distributeNoLLF(Integer ul) throws AppException {
pipetteCtrlDriver.aspirateSetLlfVelocity(0);
pipetteCtrlDriver.aspirateBlock(-ul);
}
void distribute(PipetteGunBindActionType actionType, ProjectTaskContext ctx, Integer ul) throws AppException {
LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx);
pipetteCtrlDriver.aspirateSetLlfVelocity(llfParamPack.llfVel);
pipetteCtrlDriver.setLlfStartZ(llfParamPack.llfStartPos);
pipetteCtrlDriver.setLlfEndZ(llfParamPack.llfEndPos);
pipetteCtrlDriver.aspirateBlock(-ul);
}
void mix(PipetteGunBindActionType actionType, ProjectTaskContext ctx, Integer ul, Integer times) throws AppException {
LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx);
pipetteCtrlDriver.aspirateSetLlfVelocity(llfParamPack.llfVel);
pipetteCtrlDriver.setLlfStartZ(llfParamPack.llfStartPos);
pipetteCtrlDriver.setLlfEndZ(llfParamPack.llfEndPos);
pipetteCtrlDriver.shakeUpBlock(ul, times);
}
void aspirate(PipetteGunBindActionType actionType, ProjectTaskContext ctx, Integer ul) throws AppException {
LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx);
log.info("吸液 {} , llfvel {} , llfStartPos {} , llfEndPos {}", ul, llfParamPack.llfVel, llfParamPack.llfStartPos, llfParamPack.llfEndPos);
pipetteCtrlDriver.aspirateSetLlfVelocity(llfParamPack.llfVel);
pipetteCtrlDriver.setLlfStartZ(llfParamPack.llfStartPos);
pipetteCtrlDriver.setLlfEndZ(llfParamPack.llfEndPos);
pipetteCtrlDriver.aspirateBlock(ul);
}
void lld(PipetteGunBindActionType actionType, ProjectTaskContext ctx) throws AppException {
pipetteCtrlDriver.lldPrepareBlock();
log.info("液面探测 {}", actionType);
LLDParamPack lldparm = pipetteGunParamExMgr.getLLDParam(actionType, ctx);
Pos3d sampleStartPos = null;
Pos3d sampleEndPos = null;
//取tip,移动到样本所在的位置,并液面探测
switch (actionType) {
case SAMPLE -> {
A8kSamplePos samplePos = ProjProcessContextUtils.getSamplePos(ctx);
sampleStartPos = hbotSamplePosParamMgr.getSampleStartPos(samplePos);
sampleEndPos = hbotSamplePosParamMgr.getSampleEndPos(samplePos);
}
case TAKE_LARGE_BUFFER_SOLUTION -> { //取大瓶缓冲液
var group = ctx.getConsumable().getGroup();
sampleStartPos = hbotConsumableParamMgr.getLargeBufferSamplePos(group);
sampleEndPos = hbotConsumableParamMgr.getLargeBufferSamplePosEnd(group);
}
}
Assert.notNull(sampleStartPos, "sampleStartPos is null");
Assert.notNull(sampleEndPos, "sampleEndPos is null");
pipetteCtrlDriver.setStartZ(sampleStartPos.z);
pipetteCtrlDriver.setEndZ(sampleEndPos.z);
pipetteCtrlDriver.setLldType(lldparm.type);
pipetteCtrlDriver.setLldCThreshold(lldparm.cThreshold);
pipetteCtrlDriver.setLldPThreshold(lldparm.pThreshold);
pipetteCtrlDriver.lldBlock();
}
public void doSampleProcessPrepare(ProjectTaskContext ctx) throws AppException {
A8kReactionFlowType type = ctx.getProjBuildinInfo().projBaseInfo.reactionFlowType;
if (type.equals(A8kReactionFlowType.FlowType1)) {
log.info("样本预处理,刺破小瓶缓冲液");
/*
* 刺破小瓶缓冲液
*/
TipPos tip = ctx.takeTip();
Assert.isTrue(tip != null, "tip is null");
Consumable consumable = ctx.getConsumable();
//取tip
hbotCtrlService.takeTip(tip);
//刺破
hbotCtrlService.moveToLittleBufferPiercePos(consumable.getGroup(), consumable.getPos());
//丢tip
hbotCtrlService.dropTip();
//待机
hbotCtrlService.moveQuickToZero();
//提前.取tip,
hbotCtrlService.takeTip(ctx.takeTip());
} else if (type.equals(A8kReactionFlowType.FlowType2)) {
log.info("样本预处理,取大瓶缓冲液液到探测物质中");
/*
* 取大瓶缓冲液液到探测物质中
*/
//ldd准备
//取tip,
hbotCtrlService.takeTip(ctx.takeTip());
//移动到取样位置
Pos3d pos = hbotConsumableParamMgr.getLargeBufferSamplePos(ctx.getConsumable().getGroup());
pos.z = 0;
hbotCtrlService.moveTo(pos);
//移动到目标位置,并液面探测
lld(PipetteGunBindActionType.TAKE_LARGE_BUFFER_SOLUTION, ctx);
//取液.准备
pipetteCtrlDriver.aspiratePrepareBlock();
//取液
Integer takeul = ProjProcessContextUtils.getTakeLargeBSVolume(ctx);
aspirate(PipetteGunBindActionType.TAKE_LARGE_BUFFER_SOLUTION, ctx, takeul);
//移动到吐液位
hbotCtrlService.moveTo(hbotConsumableParamMgr.getProbeSubstanceSamplePos(ctx.getConsumable().getGroup(), ctx.getConsumable().getPos()));
//吐液
distribute(PipetteGunBindActionType.DISTRIBUTION_LARGE_BUFFER_SOLUTION_PROBE_SUBSTANCE, ctx, takeul);
//丢tip
hbotCtrlService.dropTip();
//归零,待机
hbotCtrlService.moveQuickToZero();
} else {
Assert.isTrue(false, "不支持的反应流程类型");
}
}
public void doSampleProcess(ProjectTaskContext ctx) throws AppException {
Integer sampleul = ProjProcessContextUtils.getSampleVol(ctx);
Integer reactionul = ProjProcessContextUtils.getReactionPlateDropletVolUl(ctx);
A8kReactionFlowType type = ctx.getProjBuildinInfo().projBaseInfo.reactionFlowType;
if (type.equals(A8kReactionFlowType.FlowType1)) {
// hbotCtrlService.takeTip(ctx.takeTip());
} else {
hbotCtrlService.takeTip(ctx.takeTip());
}
//移动到取样位置
A8kSamplePos samplePos = ProjProcessContextUtils.getSamplePos(ctx);
log.info("移动到 {}", samplePos);
Pos3d pos = hbotSamplePosParamMgr.getSampleStartPos(samplePos);
pos.z = 0;
hbotCtrlService.moveTo(pos);
//ldd准备
lld(PipetteGunBindActionType.SAMPLE, ctx);
//取液准备
pipetteCtrlDriver.aspiratePrepareBlock();
//吸吐混匀
if (ProjProcessContextUtils.isDoMixTubeSample(ctx))
mix(PipetteGunBindActionType.MIX_SAMPLE, ctx, sampleul, ProjProcessContextUtils.getTubeMixingCount(ctx));
//取样
aspirate(PipetteGunBindActionType.SAMPLE, ctx, sampleul);
//移动到吐液位,
hbotCtrlService.moveTo(ProjProcessContextUtils.getReactionEndPos(ctx));
}
public void doSampleProcessPostProcess(ProjectTaskContext ctx) throws AppException {
Integer sampleul = ProjProcessContextUtils.getSampleVol(ctx);
Integer reactionul = ProjProcessContextUtils.getReactionPlateDropletVolUl(ctx);
//吐液
aspirateNoLLF(-sampleul);
//吸吐混匀
mix(PipetteGunBindActionType.MIX_REACTION_LIQUOR, ctx, sampleul, ProjProcessContextUtils.getBSMixingCnt(ctx));
//吸液
aspirateNoLLF(reactionul);
//旋转转盘
turnableMoveCtrlService.trunableMoveToDropLiquidPos(ctx.getIncubatorPos());
//吐液到反应板
hbotCtrlService.moveTo(hbotFixedPosParamMgr.getDropLiquidPos());
distributeNoLLF(reactionul);
pipetteCtrlDriver.clearHangingLiquid(2);
//丢tip
hbotCtrlService.dropTip();
//归零,待机
hbotCtrlService.moveQuickToZero();
}
}

110
src/main/java/a8k/service/app/devicectrl/script/PipeGunCtrlScripter.java

@ -0,0 +1,110 @@
package a8k.service.app.devicectrl.script;
import a8k.service.app.appstate.type.ProjectTaskContext;
import a8k.service.app.devicectrl.ctrlservice.HbotCtrlService;
import a8k.service.app.devicectrl.ctrlservice.OptScanModuleCtrlService;
import a8k.service.app.devicectrl.ctrlservice.TurnableMoveCtrlService;
import a8k.service.app.devicectrl.driver.PipetteCtrlDriver;
import a8k.service.app.devicectrl.exdriver.HbotBaseMoveExDriver;
import a8k.service.app.devicectrl.param.ext_param_mgr.HbotConsumableParamMgr;
import a8k.service.app.devicectrl.param.ext_param_mgr.base.PipetteGunBindActionType;
import a8k.service.app.devicectrl.param.ext_param_mgr.base.LLDParamPack;
import a8k.service.app.devicectrl.param.ext_param_mgr.PipetteGunParamExMgr;
import a8k.service.app.devicectrl.param.ext_param_mgr.base.LLFParamPack;
import a8k.service.app.devicectrl.param.param_mgr.HbotFixedPosParamMgr;
import a8k.service.app.devicectrl.param.param_mgr.HbotSamplePosParamMgr;
import a8k.service.app.devicectrl.param.type.A8kSamplePos;
import a8k.type.cfg.Pos3d;
import a8k.type.exception.AppException;
import a8k.utils.ProjProcessContextUtils;
import a8k.utils.ZAppChecker;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
@Component
@Slf4j
public class PipeGunCtrlScripter {
@Resource
PipetteCtrlDriver pipetteCtrlDriver;
@Resource
HbotSamplePosParamMgr hbotSamplePosParamMgr;
@Resource
HbotConsumableParamMgr hbotConsumableParamMgr;
@Resource
PipetteGunParamExMgr pipetteGunParamExMgr;
public void aspirateNoLLF(Integer ul) throws AppException {
pipetteCtrlDriver.aspirateSetLlfVelocity(0);
pipetteCtrlDriver.aspirateBlock(ul);
}
public void distributeNoLLF(Integer ul) throws AppException {
pipetteCtrlDriver.aspirateSetLlfVelocity(0);
pipetteCtrlDriver.aspirateBlock(-ul);
}
public void distribute(PipetteGunBindActionType actionType, ProjectTaskContext ctx, Integer ul) throws AppException {
LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx);
pipetteCtrlDriver.aspirateSetLlfVelocity(llfParamPack.llfVel);
pipetteCtrlDriver.setLlfStartZ(llfParamPack.llfStartPos);
pipetteCtrlDriver.setLlfEndZ(llfParamPack.llfEndPos);
pipetteCtrlDriver.aspirateBlock(-ul);
}
public void mix(PipetteGunBindActionType actionType, ProjectTaskContext ctx, Integer ul, Integer times) throws AppException {
LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx);
pipetteCtrlDriver.aspirateSetLlfVelocity(llfParamPack.llfVel);
pipetteCtrlDriver.setLlfStartZ(llfParamPack.llfStartPos);
pipetteCtrlDriver.setLlfEndZ(llfParamPack.llfEndPos);
pipetteCtrlDriver.shakeUpBlock(ul, times);
}
public void aspirate(PipetteGunBindActionType actionType, ProjectTaskContext ctx, Integer ul) throws AppException {
LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx);
log.info("吸液 {} , llfvel {} , llfStartPos {} , llfEndPos {}", ul, llfParamPack.llfVel, llfParamPack.llfStartPos, llfParamPack.llfEndPos);
pipetteCtrlDriver.aspirateSetLlfVelocity(llfParamPack.llfVel);
pipetteCtrlDriver.setLlfStartZ(llfParamPack.llfStartPos);
pipetteCtrlDriver.setLlfEndZ(llfParamPack.llfEndPos);
pipetteCtrlDriver.aspirateBlock(ul);
}
public void lld(PipetteGunBindActionType actionType, ProjectTaskContext ctx) throws AppException {
log.info("液面探测 {}", actionType);
LLDParamPack lldparm = pipetteGunParamExMgr.getLLDParam(actionType, ctx);
Pos3d sampleStartPos = null;
Pos3d sampleEndPos = null;
//取tip,移动到样本所在的位置,并液面探测
switch (actionType) {
case SAMPLE -> {
A8kSamplePos samplePos = ProjProcessContextUtils.getSamplePos(ctx);
sampleStartPos = hbotSamplePosParamMgr.getSampleStartPos(samplePos);
sampleEndPos = hbotSamplePosParamMgr.getSampleEndPos(samplePos);
}
case TAKE_LARGE_BUFFER_SOLUTION -> { //取大瓶缓冲液
var group = ctx.getConsumable().getGroup();
sampleStartPos = hbotConsumableParamMgr.getLargeBufferSamplePos(group);
sampleEndPos = hbotConsumableParamMgr.getLargeBufferSamplePosEnd(group);
}
}
Assert.notNull(sampleStartPos, "sampleStartPos is null");
Assert.notNull(sampleEndPos, "sampleEndPos is null");
pipetteCtrlDriver.setStartZ(sampleStartPos.z);
pipetteCtrlDriver.setEndZ(sampleEndPos.z);
pipetteCtrlDriver.setLldType(lldparm.type);
pipetteCtrlDriver.setLldCThreshold(lldparm.cThreshold);
pipetteCtrlDriver.setLldPThreshold(lldparm.pThreshold);
pipetteCtrlDriver.lldBlock();
}
}

4
src/main/java/a8k/utils/ProjProcessContextUtils.java

@ -154,11 +154,11 @@ public class ProjProcessContextUtils {
}
static public Pos3d getReactionEndPos(ProjectTaskContext ctx) {
static public Pos3d getFirstStepReactionPos(ProjectTaskContext ctx) {
HbotConsumableParamMgr hbotConsumableParamMgr = SpringBootBeanUtil.getBean(HbotConsumableParamMgr.class);
A8kReactionFlowType type = ctx.getProjBuildinInfo().projBaseInfo.reactionFlowType;
return switch (type) {
case FlowType1 -> hbotConsumableParamMgr.getLittleBufferSamplePosEnd(ctx.getConsumable().getGroup(), ctx.getConsumable().getPos());
case FlowType1 -> hbotConsumableParamMgr.getLittleBufferSamplePos(ctx.getConsumable().getGroup(), ctx.getConsumable().getPos());
case FlowType2 -> hbotConsumableParamMgr.getProbeSubstanceSamplePos(ctx.getConsumable().getGroup(), ctx.getConsumable().getPos());
};
}

Loading…
Cancel
Save