Browse Source

update

tags/v0
zhaohe 9 months ago
parent
commit
badabe167c
  1. 2
      README2.md
  2. 5
      src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java
  3. 4
      src/main/java/a8k/hardware/A8kModParamInitializer.java
  4. 1
      src/main/java/a8k/hardware/type/a8kcanprotocol/CmdId.java
  5. 2
      src/main/java/a8k/optalgo/A8kOptAlgoV2.java
  6. 4
      src/main/java/a8k/service/app/appctrl/AppMainFlowCtrlService.java
  7. 4
      src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java
  8. 5
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java
  9. 1
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_STOP.java
  10. 5
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java
  11. 5
      src/main/java/a8k/service/app/appstate/ConsumablesMgrService.java
  12. 24
      src/main/java/a8k/service/app/appstate/GStateService.java
  13. 16
      src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java
  14. 3
      src/main/java/a8k/service/app/devicectrl/ctrlservice/DeviceInitCtrlService.java
  15. 10
      src/main/java/a8k/service/app/devicectrl/driver/PipetteCtrlDriver.java
  16. 109
      src/main/java/a8k/service/app/devicectrl/param/LowerDeviceParamMgr.java
  17. 44
      src/main/java/a8k/service/app/devicectrl/script/DeviceCtrlScripter.java
  18. 114
      src/main/java/a8k/service/app/devicectrl/test/PipetteGunTest.java
  19. 139
      src/main/java/a8k/service/test/MainflowCtrlTestService.java
  20. 6
      src/main/java/a8k/service/test/fakeproj/FakeProjInfo.java
  21. 18
      src/main/java/a8k/type/exception/AppException.java
  22. BIN
      src/main/resources/app.db

2
README2.md

@ -125,5 +125,7 @@ TODO:
1. tip丢弃失败的问题
2. 舵机死机的问题
3. hbot收不到消息的BUG
4. 增加吸吐混匀速度
5. 修改处理流程的代码
```

5
src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java

@ -23,7 +23,10 @@ public enum ExtApiTabConfig {
TemperatureCtrlParamCalibration("校准.温度控制参数校准", true),
A8kPipetteCtrlModule("硬件驱动.移液枪测试", false),
PipetteGunTest("测试.PipetteGun",true),
A8kPipetteCtrlModule("硬件驱动.移液枪测试", true),
StepMotorCtrlDriver("硬件驱动.步进电机测试", false),
ActionReactorService("底层调试.单步调试", false),//OK

4
src/main/java/a8k/hardware/A8kModParamInitializer.java

@ -113,9 +113,7 @@ public class A8kModParamInitializer {
pipetteCtrlDriver.setReg(PipetteRegIndex.kreg_pipette_zm_default_velocity, 1500);
pipetteCtrlDriver.setReg(PipetteRegIndex.kreg_pipette_lld_motor_vel_rpm, 100);//80的时候刚好和液面齐平
}

1
src/main/java/a8k/hardware/type/a8kcanprotocol/CmdId.java

@ -144,6 +144,7 @@ public enum CmdId {
pipette_set_lld_p_threshold(0x7421, "移动枪设置液面探测压力阈值"),
kpipette_set_llf_startz(0x7422, "移动枪设置液面跟随开始限制高度"),
kpipette_set_llf_endz(0x7423, "移动枪设置液面跟随结束限制高度"),
kpipette_clear_hanging_liquid(0x7424, "移动枪清除悬液"),
;

2
src/main/java/a8k/optalgo/A8kOptAlgoV2.java

@ -88,7 +88,7 @@ public class A8kOptAlgoV2 {
static void findpeak(double[] data, int search_start, int search_end, A8kOptPeak retpeak) {
// find peak
log.info("find peak in [{} {}]", search_start, search_end);
// log.info("find peak in [{} {}]", search_start, search_end);
retpeak.state = PeakFindState.NOT_FIND_PEAK;
retpeak.area = 0.0;
retpeak.peakPos = 0;

4
src/main/java/a8k/service/app/appctrl/AppMainFlowCtrlService.java

@ -116,7 +116,7 @@ public class AppMainFlowCtrlService {
}
void postPorcessA8kEcode(DeviceWorkState state, List<A8kErrorContext> ecodeList) {
logger.info("处理错误 {}", ecodeList);
boolean hasErrorUnHandle = false;
List<A8kEcode> noHumanInterventionErrors = new ArrayList<>(); //无需人工干预的错误
noHumanInterventionErrors.add(A8kEcode.APPE_TAKE_TIP_FAIL);
@ -134,7 +134,7 @@ public class AppMainFlowCtrlService {
state.errorFlag = true;
state.ecodeList = ecodeList;
state.workState = A8kWorkState.PAUSE;
}else{
} else {
state.errorFlag = false;
state.ecodeList = ecodeList;
}

4
src/main/java/a8k/service/app/appctrl/mainflowctrl/MainFlowCtrlScheduler.java

@ -129,7 +129,7 @@ public class MainFlowCtrlScheduler {
} catch (MutiAppException mutiAppe) {
List<AppException> appExceptions = mutiAppe.bindExceptions;
for (AppException appe : appExceptions) {
appe.print();
logger.error("error {}", appe.getMessage(), appe);
}
if (appExceptions.size() > 1) {
logger.warn("发生多个错误,只报告第一个错误");
@ -137,7 +137,7 @@ public class MainFlowCtrlScheduler {
return new A8kErrorContext(key.step, appExceptions.get(0).error);
} catch (AppException appe) {
appe.print();
logger.error("error {}", appe.getMessage(), appe);
return new A8kErrorContext(key.step, appe.error);
} catch (Exception exception) {
logger.error("error {}", exception.getMessage(), exception);

5
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_CLEAR_ERROR_BEFORE_WORK.java

@ -9,6 +9,8 @@ import a8k.service.app.appstate.type.state.A8kWorkState;
import a8k.type.exception.AppException;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.List;
@ -24,6 +26,8 @@ import java.util.List;
@Component
public class DO_CLEAR_ERROR_BEFORE_WORK extends A8kStepAction {
private static final Logger log = LoggerFactory.getLogger(DO_CLEAR_ERROR_BEFORE_WORK.class);
DO_CLEAR_ERROR_BEFORE_WORK() {
super(A8kActionStepType.DO_CLEAR_ERROR_BEFORE_WORK);
}
@ -42,6 +46,7 @@ public class DO_CLEAR_ERROR_BEFORE_WORK extends A8kStepAction {
@Override public void doaction() throws AppException {
mfcs.errorFlag = false;
mfcs.ecodeList.clear();
log.info("运行前清除错误");
}
@Override public Boolean checkCondition() {

1
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/DO_STOP.java

@ -83,6 +83,7 @@ public class DO_STOP extends A8kStepAction {
@Override public void doaction() throws AppException {
mfcs.workStateChangeFlag = false;
//清空设备
doClearDevice();
//清空所有反应状态
projectProcessContextMgrService.finishedAll();

5
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ7_EJECT_TUBEHOLDER.java

@ -37,7 +37,7 @@ public class SEQ7_EJECT_TUBEHOLDER extends A8kStepAction {
@Resource
CondtionMgrService cms;
CondtionMgrService cms;
@Resource
TubeFeedingCtrlService tubeFeedingCtrlService;
@ -55,10 +55,11 @@ public class SEQ7_EJECT_TUBEHOLDER extends A8kStepAction {
tubeFeedingCtrlService.ejectTubeHolder();
tubeFeedingCtrlService.moveTubeRackMoveToEnterPos();
} else {
virtualDevice.doVirtualThings("弹出试管架", 2);
virtualDevice.doVirtualThings("弹出试管架", 2);
}
gstate.getTubeHolder().setState(TubeHolderState.IDLE);
gstate.setCurProcessingTube(null);
}
@Override public Boolean checkCondition() {

5
src/main/java/a8k/service/app/appstate/ConsumablesMgrService.java

@ -70,11 +70,12 @@ public class ConsumablesMgrService {
synchronized ConsumableGroup priGetConsumableGroupByProjIndex(Integer projId) {
var cState = gstate.getConsumableState();
for (int i = 0; i < cState.reactionPlateGroup.length; i++) {
if (cState.reactionPlateGroup[i].projId.equals(projId)) {
if (cState.reactionPlateGroup[i].num > 0) {
if (cState.reactionPlateGroup[i].num > 0) {
if (cState.reactionPlateGroup[i].projId.equals(projId)) {
return ConsumableGroup.fromInt(i);
}
}
}
return null;
}

24
src/main/java/a8k/service/app/appstate/GStateService.java

@ -20,27 +20,27 @@ public class GStateService {
public static final Logger logger = LoggerFactory.getLogger(GStateService.class);
//温度
Integer temperature = 25;
private Integer temperature = 25;
//设备是否初始化过
Boolean deviceInited = false;
private Boolean deviceInited = false;
//当前正在被处理的试管架状态
TubeHolder tubeHolder = new TubeHolder();
private TubeHolder tubeHolder = new TubeHolder();
//急诊为状态
EmergencyTubePos emergencyTubePos = new EmergencyTubePos();
private EmergencyTubePos emergencyTubePos = new EmergencyTubePos();
//孵育盘状态
IncubationPlate incubationPlate = new IncubationPlate();
private IncubationPlate incubationPlate = new IncubationPlate();
//耗材状态
ConsumableState consumableState = new ConsumableState();
private ConsumableState consumableState = new ConsumableState();
//光学模组状态
OptScanModule optScanModule = new OptScanModule();
private OptScanModule optScanModule = new OptScanModule();
//试管配置
List<TubeHolderSetting> tubeHolderSettings = new ArrayList<>();
private List<TubeHolderSetting> tubeHolderSettings = new ArrayList<>();
//当前正在处理的试管
Tube curProcessingTube = null;
private Tube curProcessingTube = null;
//
String appVersion = AppConstant.APP_VERSION;
String mcuVersion = "NOTSET";
String sn = "NOTSET";
private String appVersion = AppConstant.APP_VERSION;
private String mcuVersion = "NOTSET";
private String sn = "NOTSET";
SensorState sensorState = new SensorState();

16
src/main/java/a8k/service/app/appstate/ProjectProcessContextMgrService.java

@ -26,17 +26,17 @@ public class ProjectProcessContextMgrService {
static Logger logger = org.slf4j.LoggerFactory.getLogger(ProjectProcessContextMgrService.class);
@Resource
GStateService gstate;
GStateService gstate;
@Resource
SampleRecordDBDao sampleRecordDBDao;
SampleRecordDBDao sampleRecordDBDao;
@Resource
ConsumablesMgrService consumablesMgrService;
ConsumablesMgrService consumablesMgrService;
@Resource
IncubationPlateStateMgrService incubationPlateStateMgrService;
@Resource
ProjCfgMgrService projCfgMgrService;
ProjCfgMgrService projCfgMgrService;
@Resource
DeviceStatisticDao deviceStatisticDao;
DeviceStatisticDao deviceStatisticDao;
List<ProjProcessContext> contexts = new ArrayList<>();
@ -84,7 +84,7 @@ public class ProjectProcessContextMgrService {
for (ProjBriefInfo projInfo : projInfos) {
ProjProcessContext projProcessContext = new ProjProcessContext(tube.getSampleId());
projProcessContext.state = ProjProcessState.INIT;
projProcessContext.projId = projInfo.projId;
projProcessContext.projId = projInfo.projId;
projProcessContext.isHighTube = tube.getIsHighTube();
projProcessContext.isEmergency = tube.getIsEmergency();
projProcessContext.bloodType = tube.getBloodType();
@ -189,6 +189,8 @@ public class ProjectProcessContextMgrService {
logger.info(" 试管ID:{}", tube.getSampleId());
}
gstate.setTubeHolder(tubeholder);
gstate.setCurProcessingTube(null);
}
synchronized public void newEmergencyTube(Tube tube) {
@ -222,7 +224,7 @@ public class ProjectProcessContextMgrService {
* 挂起试管
* @param nextProcessTube 下一个处理的试管
*/
gstate.curProcessingTube = tube;
gstate.setCurProcessingTube(tube);
gstate.getCurProcessingTube().setState(TubeState.PENDING);
setProjProcessState(tube, ProjProcessState.PENDING);
}

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

@ -101,6 +101,8 @@ public class DeviceInitCtrlService {
for (CheckResult result : results) {
if (!result.pass) {
log.info("设备初始化失败: check {} fail", result.typechinfo);
stepMotorCtrlDriver.stepMotorEnable(StepMotorMId.ShakeModClampingM, 1);
stepMotorCtrlDriver.stepMotorEasyMoveByBlock(StepMotorMId.ShakeModClampingM, 10, 3000);
motorEnableExDriver.forceDisableAllMotor();
return results;
}
@ -143,7 +145,6 @@ public class DeviceInitCtrlService {
//hbot快速归零
hbotCtrlService.moveQuickToZero();
pipetteCtrlDriver.lldPrepareBlock();
return results;

10
src/main/java/a8k/service/app/devicectrl/driver/PipetteCtrlDriver.java

@ -245,8 +245,8 @@ public class PipetteCtrlDriver {
@ExtApiFn(name = "吸液准备", order = FnOrder.aspiratePrepareBlock)
public void aspiratePrepareBlock() throws AppException {
canBusService.callcmd(MId.PipetteMod.toInt(), CmdId.pipette_aspirate_prepare.toInt());
canBusService.waitForMod(MId.PipetteMod, overtime);
// canBusService.callcmd(MId.PipetteMod.toInt(), CmdId.pipette_aspirate_prepare.toInt());
// canBusService.waitForMod(MId.PipetteMod, overtime);
}
@ExtApiFn(name = "设置LLF速度", order = FnOrder.aspirateSetLlfVelocity)
@ -302,6 +302,12 @@ public class PipetteCtrlDriver {
canBusService.waitForMod(MId.PipetteMod, overtime + times * 3000);
}
@ExtApiFn(name = "清除悬液", order = FnOrder.shakeUpBlock)
public void clearHangingLiquid(Integer repeatTimes) throws AppException {
canBusService.callcmd(MId.PipetteMod.toInt(), CmdId.kpipette_clear_hanging_liquid.toInt(), repeatTimes);
canBusService.waitForMod(MId.PipetteMod, overtime);
}
@ExtApiFn(name = "吸液推算压力", order = FnOrder.aspirateInferPressureBlock)
public void aspirateInferPressureBlock(Integer ul) throws AppException {
canBusService.callcmd(MId.PipetteMod.toInt(), CmdId.pipette_aspirate_infer_pressure.toInt(), ul);

109
src/main/java/a8k/service/app/devicectrl/param/LowerDeviceParamMgr.java

@ -21,120 +21,19 @@ public class LowerDeviceParamMgr {
Assert.isTrue(var != null && var.val != null && !var.val.isEmpty(), String.format("CHECK %s.%s val fail", service, key));
}
@ExtApiFn(name = "恢复参数", group = "基础", order = 1)
@ExtApiFn(name = "!!!!!恢复参数!!!!!", group = "基础", order = 1)
public void recoveryParam() {
ldpdb.recoveryAllParam();
}
@ExtApiFn(name = "存储参数", group = "基础", order = 1)
@ExtApiFn(name = "!!!!!存储参数!!!!!", group = "基础", order = 2)
public void storageParam() {
ldpdb.storageAll();
}
@ExtApiFn(name = "检查参数是否全部设置", group = "基础", order = 1)
@ExtApiFn(name = "检查参数是否全部设置", group = "基础", order = 3)
public void checkParams() {
check("Hbot2DCodeScanParamMgr", "PBScanPos0");
check("Hbot2DCodeScanParamMgr", "PBScanPos1");
check("Hbot2DCodeScanParamMgr", "PBScanPos2");
check("Hbot2DCodeScanParamMgr", "PBScanPos3");
check("Hbot2DCodeScanParamMgr", "PBScanPos4");
check("Hbot2DCodeScanParamMgr", "PBScanPos5");
check("Hbot2DCodeScanParamMgr", "LittBS0");
check("Hbot2DCodeScanParamMgr", "LittBS1");
check("Hbot2DCodeScanParamMgr", "LittBS2");
check("Hbot2DCodeScanParamMgr", "LittBS3");
check("Hbot2DCodeScanParamMgr", "LittBS4");
check("Hbot2DCodeScanParamMgr", "LittBS5");
check("Hbot2DCodeScanParamMgr", "LarBS0");
check("Hbot2DCodeScanParamMgr", "LarBS1");
check("Hbot2DCodeScanParamMgr", "LarBS2");
check("Hbot2DCodeScanParamMgr", "LarBS3");
check("Hbot2DCodeScanParamMgr", "LarBS4");
check("Hbot2DCodeScanParamMgr", "LarBS5");
check("TurntablePosParamMgr", "PushPos0");
check("TurntablePosParamMgr", "PullPos0");
check("TurntablePosParamMgr", "DropLiquidPos0");
check("TurntablePosParamMgr", "PosSpacing");
check("TubeFeedingModuleParamMgr", "TubeHolderEnterXPos");
check("TubeFeedingModuleParamMgr", "TubeHolderExitXPos");
check("TubeFeedingModuleParamMgr", "TubeHolderScanXPos");
check("TubeFeedingModuleParamMgr", "Tube0ScanPos");
check("TubeFeedingModuleParamMgr", "Tube0AltitJudgPos");
check("TubeFeedingModuleParamMgr", "Tube0ExistJudgPos");
check("TubeFeedingModuleParamMgr", "Tube0PreProcessPos");
check("TubeFeedingModuleParamMgr", "TubeScanServoTorque");
check("TubeFeedingModuleParamMgr", "TubeSpacing");
check("HbotFixedPosParamMgr", "DropLiquidPos");
check("HbotSamplePosParamMgr", "EmergencyTubeSamplePos");
check("HbotSamplePosParamMgr", "EmergencyTubeSampleEndPos");
check("HbotSamplePosParamMgr", "BloodHTubeSamplePos");
check("HbotSamplePosParamMgr", "BloodHTubeSampleEndPos");
check("HbotSamplePosParamMgr", "BloodSTubeSamplePos");
check("HbotSamplePosParamMgr", "BloodSTubeSampleEndPos");
check("HbotSamplePosParamMgr", "MiniTubeSamplePos");
check("HbotSamplePosParamMgr", "MinitubeSampleEndPos");
check("HbotSamplePosParamMgr", "MiniBloodSamplePos");
check("HbotSamplePosParamMgr", "MiniBloodSampleEndPos");
check("HbotSamplePosParamMgr", "Bulltube1P5SamplePos");
check("HbotSamplePosParamMgr", "Bulltube1P5SampleEndPos");
check("HbotSamplePosParamMgr", "Bulltube0P5SamplePos");
check("HbotSamplePosParamMgr", "Bulltube0P5SampleEndPos");
check("HbotSamplePosParamMgr", "StoolTestTubeSamplePos");
check("HbotSamplePosParamMgr", "StoolTestTubeSampleEndPos");
check("HbotLittleBSPosMgr", "LittleBufferGroup0_000Pos");
check("HbotLittleBSPosMgr", "LittleBufferGroup1_000Pos");
check("HbotLittleBSPosMgr", "LittleBufferGroup2_000Pos");
check("HbotLittleBSPosMgr", "LittleBufferGroup3_000Pos");
check("HbotLittleBSPosMgr", "LittleBufferGroup4_000Pos");
check("HbotLittleBSPosMgr", "LittleBufferGroup5_000Pos");
check("HbotLittleBSPosMgr", "LittleBufferGroupDX");
check("HbotLittleBSPosMgr", "LittleBufferGroupDY");
check("HbotLittleBSPosMgr", "LittleBSPierceZPos");
check("HbotLittleBSPosMgr", "LittleBSSampleZPos");
check("HbotLittleBSPosMgr", "LittleBSSampleEndZPos");
check("HbotLargeBottleBSPosMgr", "LargeBuffer_0Pos");
check("HbotLargeBottleBSPosMgr", "LargeBuffer_DX");
check("HbotLargeBottleBSPosMgr", "LargeBuffer_DY");
check("HbotLargeBottleBSPosMgr", "LargeBSSSampleZPos");
check("HbotLargeBottleBSPosMgr", "LargeBSSSampleEndZPos");
check("HbotTipPosMgr", "TipGroup0_000Pos");
check("HbotTipPosMgr", "TipGroup0_SpaceingX");
check("HbotTipPosMgr", "TipGroup0_SpaceingY");
check("HbotTipPosMgr", "TipGroup1_000Pos");
check("HbotTipPosMgr", "TipGroup1_SpaceingX");
check("HbotTipPosMgr", "TipGroup1_SpaceingY");
check("HbotTipPosMgr", "TipGroup2_000Pos");
check("HbotTipPosMgr", "TipGroup2_SpaceingX");
check("HbotTipPosMgr", "TipGroup2_SpaceingY");
check("HbotTipPosMgr", "DropTipPos");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceGroup0_000Pos");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceGroup1_000Pos");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceGroup2_000Pos");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceGroup3_000Pos");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceGroup4_000Pos");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceGroup5_000Pos");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceDX");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceDY");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceSampleZPos");
check("HbotProbeSubstancePosMgr", "ProbeSubstanceSampleEndZPos");
check("OptModuleParamsMgr", "PullerTargetPos");
check("OptModuleParamsMgr", "OptScanerDropPos");
check("OptModuleParamsMgr", "OptScanerScandbyPos");
check("OptModuleParamsMgr", "TOptScanStartPos");
check("OptModuleParamsMgr", "FOptScanStartPos");
check("PlatesBoxPosParamMgr", "Ch0YPos");
check("PlatesBoxPosParamMgr", "Ch5YPos");
check("PlatesBoxPosParamMgr", "PushEndXPos");
check("TubePreProcesPosParamMgr", "GripperServoOpenPos");
check("TubePreProcesPosParamMgr", "GripperServoClosePos");
check("TubePreProcesPosParamMgr", "GripperServoTakeCapPos");
check("TubePreProcesPosParamMgr", "ShakeClampMotorClampPos");
check("TubePreProcesPosParamMgr", "ShakeClampMotorReleasePos");
check("TubePreProcesPosParamMgr", "YServoTakeTubePos");
check("TubePreProcesPosParamMgr", "YServoShakePos");
check("TubePreProcesPosParamMgr", "ZMotorTakeHTubePos");
check("TubePreProcesPosParamMgr", "ZMotorTakeSTubePos");
check("TubePreProcesPosParamMgr", "ZMotorShakeTubePos");
}

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

@ -75,6 +75,12 @@ public class DeviceCtrlScripter {
pipetteCtrlDriver.aspirateBlock(ul);
}
void distributeNoLLF(Integer ul) throws AppException {
pipetteCtrlDriver.aspirateSetLlfVelocity(0);
pipetteCtrlDriver.aspirateBlock(-ul);
}
void distribute(PipetteGunBindActionType actionType, ProjProcessContext ctx, Integer ul) throws AppException {
LLFParamPack llfParamPack = pipetteGunParamExMgr.getLLFParam(actionType, ctx);
pipetteCtrlDriver.aspirateSetLlfVelocity(llfParamPack.llfVel);
@ -94,6 +100,8 @@ public class DeviceCtrlScripter {
void aspirate(PipetteGunBindActionType actionType, ProjProcessContext 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);
@ -102,6 +110,8 @@ public class DeviceCtrlScripter {
void lld(PipetteGunBindActionType actionType, ProjProcessContext ctx) throws AppException {
pipetteCtrlDriver.lldPrepareBlock();
log.info("液面探测 {}", actionType);
LLDParamPack lldparm = pipetteGunParamExMgr.getLLDParam(actionType, ctx);
Pos3d sampleStartPos = null;
@ -153,20 +163,23 @@ public class DeviceCtrlScripter {
hbotCtrlService.dropTip();
//待机
hbotCtrlService.moveQuickToZero();
pipetteCtrlDriver.lldPrepareBlock();
//提前.取tip,
hbotCtrlService.takeTip(ctx.takeTip());
} else if (type.equals(A8kReactionFlowType.FlowType2)) {
log.info("样本预处理,取大瓶缓冲液液到探测物质中");
/*
* 取大瓶缓冲液液到探测物质中
*/
//ldd准备
pipetteCtrlDriver.lldPrepareBlock();
//取tip,
hbotCtrlService.takeTip(ctx.takeTip());
//移动到取样位置
hbotCtrlService.moveTo(hbotConsumableParamMgr.getLargeBufferSamplePos(ctx.consumable.getGroup()));
Pos3d pos = hbotConsumableParamMgr.getLargeBufferSamplePos(ctx.consumable.getGroup());
pos.z = 0;
hbotCtrlService.moveTo(pos);
//移动到目标位置,并液面探测
lld(PipetteGunBindActionType.TAKE_LARGE_BUFFER_SOLUTION, ctx);
@ -182,14 +195,13 @@ public class DeviceCtrlScripter {
hbotCtrlService.moveTo(hbotConsumableParamMgr.getProbeSubstanceSamplePosEnd(ctx.consumable.getGroup(), ctx.consumable.getPos()));
//吐液
distribute(PipetteGunBindActionType.DISTRIBUTION_LARGE_BUFFER_SOLUTION_PROBE_SUBSTANCE, ctx, -takeul);
distribute(PipetteGunBindActionType.DISTRIBUTION_LARGE_BUFFER_SOLUTION_PROBE_SUBSTANCE, ctx, takeul);
//丢tip
hbotCtrlService.dropTip();
//归零,待机
hbotCtrlService.moveQuickToZero();
pipetteCtrlDriver.lldPrepareBlock();
} else {
Assert.isTrue(false, "不支持的反应流程类型");
}
@ -199,16 +211,19 @@ public class DeviceCtrlScripter {
Integer sampleul = ProjProcessContextUtils.getSampleVol(ctx);
Integer reactionul = ProjProcessContextUtils.getReactionPlateDropletVolUl(ctx);
//ldd准备
pipetteCtrlDriver.lldPrepareBlock();
//取tip,
hbotCtrlService.takeTip(ctx.takeTip());
A8kReactionFlowType type = ctx.projCfg.projectInfo.reactionFlowType;
if (type.equals(A8kReactionFlowType.FlowType1)) {
// hbotCtrlService.takeTip(ctx.takeTip());
} else {
hbotCtrlService.takeTip(ctx.takeTip());
}
//移动到取样位置
A8kSamplePos samplePos = ProjProcessContextUtils.getSamplePos(ctx);
log.info("移动到 {}", samplePos);
hbotCtrlService.moveTo(hbotSamplePosParamMgr.getSampleStartPos(samplePos));
Pos3d pos = hbotSamplePosParamMgr.getSampleStartPos(samplePos);
pos.z = 0;
hbotCtrlService.moveTo(pos);
//ldd准备
lld(PipetteGunBindActionType.SAMPLE, ctx);
@ -244,9 +259,12 @@ public class DeviceCtrlScripter {
//旋转转盘
turnableMoveCtrlService.trunableMoveToDropLiquidPos(ctx.incubatorPos);
//取样到反应板
//吐液到反应板
hbotCtrlService.moveTo(hbotFixedPosParamMgr.getDropLiquidPos());
aspirateNoLLF(reactionul);
distributeNoLLF(reactionul);
pipetteCtrlDriver.clearHangingLiquid(2);
//丢tip
hbotCtrlService.dropTip();

114
src/main/java/a8k/service/app/devicectrl/test/PipetteGunTest.java

@ -0,0 +1,114 @@
package a8k.service.app.devicectrl.test;
import a8k.extapi_controler.pagecontrol.ExtApiTabConfig;
import a8k.extapi_controler.utils.ExtApiFn;
import a8k.extapi_controler.utils.ExtApiTab;
import a8k.hardware.type.LldType;
import a8k.service.app.devicectrl.driver.PipetteCtrlDriver;
import a8k.service.app.devicectrl.exdriver.HbotBaseMoveExDriver;
import a8k.service.app.devicectrl.exdriver.MotorEnableExDriver;
import a8k.service.app.devicectrl.param.param_mgr.PipetteGunLLDParamMgr;
import a8k.service.app.devicectrl.param.type.PipetteGunLLDThresholdParam;
import a8k.service.app.devicectrl.param.type.PipetteGunLLDTypeParam;
import a8k.type.exception.AppException;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
@ExtApiTab(cfg = ExtApiTabConfig.PipetteGunTest)
@Component
public class PipetteGunTest {
@Resource
PipetteGunLLDParamMgr pipetteGunLLDParamMgr;
@Resource
PipetteCtrlDriver pipetteCtrlDriver;
@Resource
HbotBaseMoveExDriver hbotBaseMoveExDriver;
@Resource
MotorEnableExDriver motorEnableExDriver;
// 测试工具
// @ExtApiFn(name = "归零", group = "基础", order = 1)
// public void moveToZero() throws AppException {
// enableModule();
// pipetteCtrlDriver.zMotorMoveZeroBlock();
// }
@ExtApiFn(name = "移液枪初始化(Tip会掉落)", group = "基础", order = 2)
public void pipetteInitDeviceBlock() throws AppException {
pipetteCtrlDriver.pipetteInitDeviceBlock();
}
@ExtApiFn(name = "使能相关模块", group = "基础", order = 3)
public void enableModule() throws AppException {
pipetteCtrlDriver.zMotorEnable(1);
}
@ExtApiFn(name = "失能相关模块", group = "基础", order = 4)
public void disableModule() throws AppException {
motorEnableExDriver.forceDisableAllMotor();
}
@ExtApiFn(name = "获取相关参数", group = "基础", order = 5)
public Object getParams() throws AppException {
return pipetteGunLLDParamMgr.getParams();
}
Integer lldStartPos;
Integer lldEndPos;
@ExtApiFn(name = "设置LLD开始位置", group = "测试", order = 100)
public void setStartTestPos() throws AppException {
pipetteCtrlDriver.zMotorEnable(1);
pipetteCtrlDriver.zMotorMeasureDistance();
lldStartPos = pipetteCtrlDriver.zMotorReadMeasureDistanceResult();
pipetteCtrlDriver.zMotorEnable(0);
}
@ExtApiFn(name = "设置LLD结束位置", group = "测试", order = 101)
public void setEndTestPos() throws AppException {
pipetteCtrlDriver.zMotorEnable(1);
pipetteCtrlDriver.zMotorMeasureDistance();
lldEndPos = pipetteCtrlDriver.zMotorReadMeasureDistanceResult();
pipetteCtrlDriver.zMotorEnable(0);
}
@ExtApiFn(name = "LLD准备(每次LLD前都要调用一次,同时更换tip头)", group = "测试", order = 102)
public void lldPrepare() throws AppException {
pipetteCtrlDriver.zMotorEnable(1);
pipetteCtrlDriver.zMotorMoveZeroBlock();
pipetteCtrlDriver.lldPrepareBlock();
}
@ExtApiFn(name = "LDD测量液体属性", group = "测试", order = 103)
public Object lldCalibrate() throws AppException {
if (lldStartPos > lldEndPos) {
throw AppException.of("开始位置大于结束位置");
}
pipetteCtrlDriver.zMotorEnable(1);
pipetteCtrlDriver.zMotorMoveZeroBlock();
pipetteCtrlDriver.setStartZ(lldStartPos);
pipetteCtrlDriver.setEndZ(lldEndPos);
pipetteCtrlDriver.lldCalibrationBlock();
return pipetteCtrlDriver.getSensorSampleData();
}
@ExtApiFn(name = "LLD测试", group = "测试", order = 104)
public void lldTest(LldType type, Integer c_val, Integer p_val) throws AppException {
pipetteCtrlDriver.zMotorEnable(1);
pipetteCtrlDriver.zMotorMoveZeroBlock();
pipetteCtrlDriver.setStartZ(lldStartPos);
pipetteCtrlDriver.setEndZ(lldEndPos);
pipetteCtrlDriver.setLldType(type);
pipetteCtrlDriver.setLldCThreshold(c_val);
pipetteCtrlDriver.setLldPThreshold(p_val);
pipetteCtrlDriver.lldBlock();
}
}

139
src/main/java/a8k/service/test/MainflowCtrlTestService.java

@ -7,22 +7,27 @@ import a8k.extapi_controler.utils.ExtApiTab;
import a8k.service.app.appctrl.AppConsumablesScanService;
import a8k.service.app.appctrl.AppDeviceCtrlService;
import a8k.service.app.appctrl.AppTubeSettingMgrService;
import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService;
import a8k.service.app.appctrl.mainflowctrl.MainFlowCtrlScheduler;
import a8k.service.app.appstate.ConsumablesMgrService;
import a8k.service.app.appstate.GStateService;
import a8k.service.app.appstate.type.DeviceWorkState;
import a8k.service.app.appstate.type.state.A8kWorkState;
import a8k.service.app.devicectrl.ctrlservice.OptScanModuleCtrlService;
import a8k.service.app.devicectrl.driver.StepMotorCtrlDriver;
import a8k.service.app.devicectrl.driver.type.StepMotorMId;
import a8k.service.app.devicectrl.exdriver.MotorEnableExDriver;
import a8k.service.dao.A8kProjIdCardDao;
import a8k.service.dao.A8kProjInfoDao;
import a8k.service.dao.A8kProjOptConfigDao;
import a8k.service.test.fakeproj.FAKE_PROJ_01;
import a8k.service.test.fakeproj.FAKE_PROJ_02;
import a8k.service.test.fakeproj.FakeProjInfo;
import a8k.service.test.fakeproj.FakeProjInfoFactory;
import a8k.service.test.state.TestModeState;
import a8k.service.test.state.VirtualDevice;
import a8k.service.test.type.MainFlowCtrlTestCaseType;
import a8k.type.ConsumableGroup;
import a8k.type.ConsumablesScanReport;
import a8k.type.TubeHolderScanResult;
import a8k.type.TubesScanResult;
import a8k.type.*;
import a8k.type.checkpoint.CheckResult;
import a8k.type.consumables.ConsumablesScanReportErrorType;
import a8k.type.ecode.AECodeError;
@ -32,6 +37,7 @@ import a8k.type.type.A8kTubeHolderType;
import a8k.type.type.TipGroup;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@ -73,7 +79,18 @@ public class MainflowCtrlTestService {
// Ctrl
//
@Resource
AppDeviceCtrlService appDeviceCtrlService;
AppDeviceCtrlService appDeviceCtrlService;
@Resource
MainFlowCtrlScheduler mainFlowCtrlScheduler;
@Resource
MotorEnableExDriver motorEnableExDriver;
@Resource
StepMotorCtrlDriver stepMotorCtrlDriver;
@Resource
OptScanModuleCtrlService optScanModuleCtrlService;
@Resource
CondtionMgrService condtionMgrService;
void resetProjDB() {
@ -142,12 +159,68 @@ public class MainflowCtrlTestService {
testModeState.setEnableOptScan(enable);
}
//
// 辅助工具
//
@ExtApiFn(name = "失能整机", group = "调试工具", order = 200)
public void disableDevice() throws AppException {
stepMotorCtrlDriver.stepMotorEnable(StepMotorMId.ShakeModClampingM, 1);
stepMotorCtrlDriver.stepMotorEasyMoveByBlock(StepMotorMId.ShakeModClampingM, 10, 3000);
motorEnableExDriver.forceDisableAllMotor();
}
@ExtApiFn(name = "使能整机", group = "调试工具", order = 201)
public void enableDevice() throws AppException {
motorEnableExDriver.enableAllMotor();
}
//
// 测试配置
//
@ExtApiFn(name = "读取设备状态", group = "设备控制", order = 401)
public DeviceWorkState readDeviceState() {
return gstate.getDeviceWorkState();
}
@ExtApiFn(name = "获取动作执行条件", group = "设备控制", order = 402)
synchronized public CondtionMgrService getCondtionMgrService() {
return condtionMgrService;
}
void waittingForStop() {
while (gstate.getDeviceWorkState().isPending()) {
log.info("等待设备停止工作....");
OS.forceSleep(1000);
}
}
@ExtApiFn(name = "停止", group = "设备控制", order = 403)
public void stopWork() {
appDeviceCtrlService.stopWork();
waittingForStop();
}
@ExtApiFn(name = "暂停", group = "设备控制", order = 404)
public void pauseWork() {
appDeviceCtrlService.pauseWork();
waittingForStop();
}
@ExtApiFn(name = "继续", group = "设备控制", order = 405)
public void continueWork() {
appDeviceCtrlService.continueWork();
waittingForStop();
}
//
// 测试用例
//
@ExtApiFn(name = "设备初始化", order = 200)
@ExtApiFn(name = "设备初始化", order = 300)
public Object deviceInit() throws AppException {
List<CheckResult> checkResults = appDeviceCtrlService.initDevice();
for (CheckResult checkResult : checkResults) {
@ -158,24 +231,31 @@ public class MainflowCtrlTestService {
return checkResults;
}
@ExtApiFn(name = "清空孵育盘", order = 301)
public void clearIncubatorPos(IncubatorPos incubatorPos) throws AppException {
optScanModuleCtrlService.pullPlate(incubatorPos);
optScanModuleCtrlService.dropPlate();
}
void stopAndWaittingForDeviceStop() {
log.info("doSimpleTest");
//停止工作
if (!gstate.getDeviceWorkState().workState.equals(A8kWorkState.IDLE)) {
appDeviceCtrlService.stopWork();
while (gstate.getDeviceWorkState().isPending()) {
log.info("等待设备停止工作....");
OS.forceSleep(1000);
}
waittingForStop();
}
}
@ExtApiFn(name = "执行一次简单的测试(无试管测试)", order = 200)
@ExtApiFn(name = "执行一次简单的测试(无试管测试.流程1)", order = 400)
public String doSimpleTest(Boolean isHTube, Integer tubeNum) throws AppException {
if (tubeNum <= 0) {
throw AppException.of("试管数量必须大于0");
}
gstate.setDeviceInited(true);
stopAndWaittingForDeviceStop();
//清空项目的数据库配置
resetProjDB();
@ -205,5 +285,42 @@ public class MainflowCtrlTestService {
return "开始测试";
}
@ExtApiFn(name = "执行一次简单的测试(无试管测试.流程2)", order = 401)
public String doSimpleTest2(Boolean isHTube, Integer tubeNum) throws AppException {
if (tubeNum <= 0) {
throw AppException.of("试管数量必须大于0");
}
gstate.setDeviceInited(true);
stopAndWaittingForDeviceStop();
//清空项目的数据库配置
resetProjDB();
//设置虚拟耗材,只有一个高试管
testModeState.setVirtualTubeScanResult(createScanResult(A8kTubeHolderType.BloodTube, isHTube, tubeNum));
//无校验模式
testModeState.setNoCheckMode(true);
//无光学检查
testModeState.setEnableOptScan(true);
//添加项目信息
addProjInfo(FAKE_PROJ_02.class);
//设置耗材状态假定已经扫描过耗材
LoadingConsumablesDirectly(ConsumableGroup.GROUP1, new FAKE_PROJ_02());
//设置试管架扫描信息全部设置成高试管
appTubeSettingMgrService.removeAllTubeSetting();
for (int i = 0; i < 3; i++) {
TubeHolderSetting setting = createOneActiveTubeHolderSetting(A8kTubeHolderType.BloodTube, tubeNum, List.of(new FAKE_PROJ_02().projId));
appTubeSettingMgrService.newTubeHolderSetting(setting);
}
//开始工作
appDeviceCtrlService.startWork();
return "开始测试";
}
}

6
src/main/java/a8k/service/test/fakeproj/FakeProjInfo.java

@ -25,10 +25,10 @@ public class FakeProjInfo {
public Integer wBloodSampleVolUl = 100;
public Integer serumSampleVolUl = 100;
public Integer shakeTimes = 5;
public Integer bigBufferSampleUl = 200;
public Integer mixLiquidAspirMixingCnt = 3;
public Integer bigBufferSampleUl = 100;
public Integer mixLiquidAspirMixingCnt = 1;
public Integer reactionPlateIncubationTimeMin = 1;
public Integer reactionPlateDropletVolUl = 100;
public Integer reactionPlateDropletVolUl = 50;
public Boolean expired = false;
FakeProjInfo(Integer projNum) {

18
src/main/java/a8k/type/exception/AppException.java

@ -44,14 +44,14 @@ public class AppException extends Exception {
return new AppException(new AECommonError(message));
}
public void print() {
// printStackTrace();
log.error("error {}",this.getMessage(), this);
// log.error("exception {}", this.toString());
// for (StackTraceElement ste : this.getStackTrace()) {
// log.error(ste.toString());
// }
}
//
// public void print() {
//// printStackTrace();
// log.error("error {}",this.getMessage(), this);
//// log.error("exception {}", this.toString());
//// for (StackTraceElement ste : this.getStackTrace()) {
//// log.error(ste.toString());
//// }
// }
}

BIN
src/main/resources/app.db

Loading…
Cancel
Save