Browse Source

update

tags/v0
zhaohe 1 year ago
parent
commit
2aea3b7b0c
  1. 8
      src/main/java/a8k/controler/engineer/utils/EnginnerPageTabOrder.java
  2. 40
      src/main/java/a8k/service/appcfgs/AppCfgMgrService.java
  3. 34
      src/main/java/a8k/service/appfrontend/AppFrontEndEventRouter.java
  4. 7
      src/main/java/a8k/service/hardware/HardwareTestScript.java
  5. 6
      src/main/java/a8k/service/hardware/HbotControlService.java
  6. 2
      src/main/java/a8k/service/hardware/MotorTubeRackMoveCtrlService.java
  7. 2
      src/main/java/a8k/service/hardware/ReactionPlatesTransmitCtrlService.java
  8. 2
      src/main/java/a8k/service/hardware/SamplesPreProcessModuleCtrlService.java
  9. 1
      src/main/java/a8k/service/hardware/canbus/protocol/A8kEcode.java
  10. 231
      src/main/java/a8k/service/hardwarev2/commonctrl/HardwareCommonCtrl.java
  11. 372
      src/main/java/a8k/service/hardwarev2/ctrl/SamplesPreProcesCtrl.java
  12. 87
      src/main/java/a8k/service/hardwarev2/param/PosParam.java
  13. 23
      src/main/java/a8k/service/hardwarev2/param/TimeParam.java
  14. 7
      src/main/java/a8k/utils/ZEQ.java

8
src/main/java/a8k/controler/engineer/utils/EnginnerPageTabOrder.java

@ -11,11 +11,17 @@ public enum EnginnerPageTabOrder {
AppCfgMgrService,
AppFrontEndEventRouter,
MotorTubeRackMoveCtrlService,
SamplesPreProcessModuleCtrlService,
ReactionPlatesTransmitCtrlService,
MotorTubeRackMoveCtrlService,
HbotControlService,
HardwareTestScript,
PosParam,
TimeParam,
HardwareCommonCtrl,
SamplesPreProcesCtrl,
Max;
}

40
src/main/java/a8k/service/appcfgs/AppCfgMgrService.java

@ -3,6 +3,7 @@ package a8k.service.appcfgs;
import a8k.appbase.appret.AppRet;
import a8k.controler.engineer.utils.EngineerPageTab;
import a8k.controler.engineer.utils.EnginnerPageAction;
import a8k.controler.engineer.utils.EnginnerPageTabOrder;
import a8k.service.appcfgs.base.A8kDeviceCfg;
import a8k.service.appcfgs.base.EmergencyCfg;
import a8k.appbase.type.BloodType;
@ -12,10 +13,23 @@ import a8k.service.hardware.canbus.protocol.A8kEcode;
import org.springframework.stereotype.Component;
@Component
@EngineerPageTab(name = "AppCfgMgrService")
@EngineerPageTab(name = "应用-测试任务提交", order = EnginnerPageTabOrder.AppCfgMgrService)
public class AppCfgMgrService {
A8kDeviceCfg deviceCfg = new A8kDeviceCfg();
static class ORDER {
static final int getA8kDeviceCfg = 1;
static final int addCfg = 2;
static final int removeCfg = 3;
static final int activeCfg = 4;
static final int updateTubeUsrCfg = 5;
static final int clearTubeProjectCfg = 6;
static final int addTubeProjectCode = 7;
static final int setTubeBloodType = 8;
static final int getEmergencyCfg = 9;
static final int addEmergencyCfg = 10;
}
private SampleTubeHolderCfg dbFindCfg(String tubeHolderCfgUUID) {
for (SampleTubeHolderCfg cfg : deviceCfg.cfgs) {
@ -39,26 +53,30 @@ public class AppCfgMgrService {
}
@EnginnerPageAction(name = "获取设备配置", group = "基础", groupOrder = 1)
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// EXTERNAL API
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@EnginnerPageAction(name = "获取设备配置", group = "基础", order = ORDER.getA8kDeviceCfg)
public A8kDeviceCfg getA8kDeviceCfg() {
return deviceCfg;
}
@EnginnerPageAction(name = "添加<试管架>配置", group = "试管架", groupOrder = 2)
@EnginnerPageAction(name = "添加<试管架>配置", group = "试管架", order = ORDER.addCfg)
public AppRet<SampleTubeHolderCfg> addCfg() {
SampleTubeHolderCfg cfg = new SampleTubeHolderCfg();
deviceCfg.cfgs.add(cfg);
return AppRet.success(cfg);
}
@EnginnerPageAction(name = "删除<试管架>配置", group = "试管架")
@EnginnerPageAction(name = "删除<试管架>配置", group = "试管架", order = ORDER.removeCfg)
public AppRet<Object> removeCfg(String tubeHolderCfgUUID) {
dbRemoveCfg(tubeHolderCfgUUID);
return AppRet.success();
}
@EnginnerPageAction(name = "激活<试管架>配置", group = "试管架")
@EnginnerPageAction(name = "激活<试管架>配置", group = "试管架", order = ORDER.activeCfg)
public AppRet<SampleTubeHolderCfg> activeCfg(String tubeHolderCfgUUID, Boolean active) {
SampleTubeHolderCfg cfg = dbFindCfg(tubeHolderCfgUUID);
if (cfg == null) {
@ -69,7 +87,7 @@ public class AppCfgMgrService {
}
@EnginnerPageAction(name = "修改<试管>用户信息配置", group = "试管", groupOrder = 3)
@EnginnerPageAction(name = "修改<试管>用户信息配置", group = "试管", order = ORDER.updateTubeUsrCfg)
public AppRet<SampleTubeCfg> updateTubeUsrCfg(String uuid, Integer tubeIndex, String udpid, String barcodeid) {
SampleTubeHolderCfg cfg = dbFindCfg(uuid);
assert cfg != null;
@ -79,7 +97,7 @@ public class AppCfgMgrService {
}
@EnginnerPageAction(name = "清除<试管>项目信息", group = "试管")
@EnginnerPageAction(name = "清除<试管>项目信息", group = "试管", order = ORDER.clearTubeProjectCfg)
public AppRet<SampleTubeCfg> clearTubeProjectCfg(String uuid, Integer tubeIndex) {
SampleTubeHolderCfg cfg = dbFindCfg(uuid);
assert cfg != null;
@ -88,7 +106,7 @@ public class AppCfgMgrService {
return AppRet.success(cfg.tubeCfgs.get(tubeIndex));
}
@EnginnerPageAction(name = "添加<试管>项目信息", group = "试管")
@EnginnerPageAction(name = "添加<试管>项目信息", group = "试管", order = ORDER.addTubeProjectCode)
public AppRet<SampleTubeCfg> addTubeProjectCode(String uuid, Integer tubeIndex, String pjc) {
SampleTubeHolderCfg cfg = dbFindCfg(uuid);
assert cfg != null;
@ -98,7 +116,7 @@ public class AppCfgMgrService {
return AppRet.success(tubeCfg);
}
@EnginnerPageAction(name = "设置<试管>血型", group = "试管")
@EnginnerPageAction(name = "设置<试管>血型", group = "试管", order = ORDER.setTubeBloodType)
public AppRet<SampleTubeCfg> setTubeBloodType(String uuid, Integer tubeIndex, BloodType bloodType) {
SampleTubeCfg tubeCfg = dbFindTubeCfg(uuid, tubeIndex);
assert tubeCfg != null;
@ -106,12 +124,12 @@ public class AppCfgMgrService {
return AppRet.success();
}
@EnginnerPageAction(name = "获取<急诊位>配置", group = "急诊位", groupOrder = 4)
@EnginnerPageAction(name = "获取<急诊位>配置", group = "急诊位", order = ORDER.getEmergencyCfg)
public AppRet<EmergencyCfg> getEmergencyCfg() {
return AppRet.success(deviceCfg.emergencyCfg);
}
@EnginnerPageAction(name = "添加<急诊位>配置", group = "急诊位")
@EnginnerPageAction(name = "添加<急诊位>配置", group = "急诊位", order = ORDER.addEmergencyCfg)
public AppRet<EmergencyCfg> addEmergencyCfg(EmergencyCfg cfg) {
deviceCfg.emergencyCfg = cfg;
return AppRet.success(deviceCfg.emergencyCfg);

34
src/main/java/a8k/service/appfrontend/AppFrontEndEventRouter.java

@ -1,5 +1,6 @@
package a8k.service.appfrontend;
import a8k.controler.engineer.utils.EnginnerPageTabOrder;
import a8k.service.appeventbus.AppEventListener;
import a8k.appbase.appret.AppRet;
import a8k.controler.engineer.utils.EngineerPageTab;
@ -15,10 +16,14 @@ import org.springframework.stereotype.Component;
import java.util.Queue;
@Component
@EngineerPageTab(name = "FrontEndEventRouter")
@EngineerPageTab(name = "应用-前端事件路由器", order = EnginnerPageTabOrder.AppFrontEndEventRouter)
public class AppFrontEndEventRouter implements AppEventListener {
static Logger logger = org.slf4j.LoggerFactory.getLogger(AppFrontEndEventRouter.class);
static class ORDER {
static final int pollAppEvent = 1;
}
@Resource
AppEventBusService eventBus;
@ -30,17 +35,30 @@ public class AppFrontEndEventRouter implements AppEventListener {
eventBus.regListener(this);
}
public Boolean filterEvent(AppEvent event) {
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Internal APIs
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/**
* 过滤事件
* @param event 事件
* @return 是否过滤
*/
Boolean filterEvent(AppEvent event) {
if (event instanceof A8kHardwareReport) {
return true;
}
return false;
}
synchronized public AppEvent _pollAppEvent() {
synchronized AppEvent pollAppEventFromQueue() {
return appEventQueue.poll();
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// 事件处理
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@Override public void onAppEvent(AppEvent event) {
if (filterEvent(event)) {
return;
@ -49,13 +67,17 @@ public class AppFrontEndEventRouter implements AppEventListener {
appEventQueue.add(event);
if (appEventQueue.size() >= 10) {
logger.warn("too many events in queue, drop some");
_pollAppEvent();
pollAppEventFromQueue();
}
}
@EnginnerPageAction(name = "pollAppEvent")
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Exposed APIs
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@EnginnerPageAction(name = "读取挂起事件")
public AppRet<AppEvent> pollAppEvent() {
AppEvent event = _pollAppEvent();
AppEvent event = pollAppEventFromQueue();
return AppRet.success(event);
}

7
src/main/java/a8k/service/hardware/HardwareTestScript.java

@ -4,14 +4,11 @@ import a8k.appbase.ConsumableGroup;
import a8k.appbase.HardwareException;
import a8k.appbase.cfg.*;
import a8k.appbase.appret.AppRet;
import a8k.controler.engineer.utils.*;
import a8k.service.hardware.canbus.A8kCanBusService;
import a8k.service.hardware.canbus.protocol.A8kEcode;
import a8k.service.hardware.canbus.protocol.MId;
import a8k.service.hardware.canbus.protocol.RegIndex;
import a8k.controler.engineer.utils.EnginnerParamReader;
import a8k.controler.engineer.utils.EngineerPageTab;
import a8k.controler.engineer.utils.EnginnerPageAction;
import a8k.controler.engineer.utils.EnginnerPageParams;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,7 +19,7 @@ import java.util.HashMap;
import java.util.Map;
@Component
@EngineerPageTab(name = "测试脚本")
@EngineerPageTab(name = "测试-测试脚本", order = EnginnerPageTabOrder.HardwareTestScript)
@EnginnerPageParams(service = HardwareTestScript.class)
public class HardwareTestScript {
static Logger logger = LoggerFactory.getLogger(HardwareTestScript.class);

6
src/main/java/a8k/service/hardware/HbotControlService.java

@ -21,7 +21,7 @@ import org.springframework.stereotype.Component;
* Hbot控制服务
*/
@Component
@EngineerPageTab(name = "Hbot控制")
@EngineerPageTab(name = "硬件-Hbot控制", order = EnginnerPageTabOrder.HbotControlService)
@EnginnerPageParams(service = HbotControlService.class)
public class HbotControlService implements HardwareCtrlModule {
static Logger logger = LoggerFactory.getLogger(HbotControlService.class);
@ -54,7 +54,7 @@ public class HbotControlService implements HardwareCtrlModule {
}
@EnginnerPageParam(name = "急诊位", group = "简单位置坐标")
public Pos3d getEmergencyPos() {
public Pos3d getEmergencyPos() {
return new Pos3d(
4858,
3196,
@ -403,7 +403,7 @@ public class HbotControlService implements HardwareCtrlModule {
Pos2d hbotRefPos = new Pos2d(0, 0);
@EnginnerPageAction(name = "设置HBOT参考坐标", group = "坐标获取工具")
public void openCodeScaner(Integer x, Integer y) throws HardwareException, InterruptedException {
public void setHbotRefPos(Integer x, Integer y) throws HardwareException, InterruptedException {
hbotRefPos.x = x;
hbotRefPos.y = y;
}

2
src/main/java/a8k/service/hardware/MotorTubeRackMoveCtrlService.java

@ -12,7 +12,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
@EngineerPageTab(name = "进出料控制模组")
@EngineerPageTab(name = "硬件-进出料控制模组", order = EnginnerPageTabOrder.MotorTubeRackMoveCtrlService)
@EnginnerPageParams(service = MotorTubeRackMoveCtrlService.class)
public class MotorTubeRackMoveCtrlService implements HardwareCtrlModule {

2
src/main/java/a8k/service/hardware/ReactionPlatesTransmitCtrlService.java

@ -19,7 +19,7 @@ import java.util.ArrayList;
import java.util.List;
@Component
@EngineerPageTab(name = "反应板条搬移服务", order= EnginnerPageTabOrder.ReactionPlatesTransmitCtrlService)
@EngineerPageTab(name = "硬件-反应板条搬移服务", order= EnginnerPageTabOrder.ReactionPlatesTransmitCtrlService)
@EnginnerPageParams(service = ReactionPlatesTransmitCtrlService.class)
public class ReactionPlatesTransmitCtrlService implements HardwareCtrlModule {
static Logger logger = LoggerFactory.getLogger(ReactionPlatesTransmitCtrlService.class);

2
src/main/java/a8k/service/hardware/SamplesPreProcessModuleCtrlService.java

@ -16,7 +16,7 @@ import java.lang.reflect.Method;
import java.util.List;
@Component
@EngineerPageTab(name = "样本预处理模块")
@EngineerPageTab(name = "硬件-样本预处理模块", order = EnginnerPageTabOrder.SamplesPreProcessModuleCtrlService)
@EnginnerPageParams(service = SamplesPreProcessModuleCtrlService.class)
public class SamplesPreProcessModuleCtrlService implements HardwareCtrlModule {
static Logger logger = LoggerFactory.getLogger(SamplesPreProcessModuleCtrlService.class);

1
src/main/java/a8k/service/hardware/canbus/protocol/A8kEcode.java

@ -31,6 +31,7 @@ public enum A8kEcode {
ZMNotAtZPosWhenHbotTryMove(26, "HBOT启动时,Z轴电机没有在原点"),//
TakeTipFail(27, "取Tip失败"),//
PutTipFail(28, "放Tip失败"),//
StopByUser(29, "用户停止"),//
PasswdError(100, "密码错误"), //
UsrNotExitError(101, "用户不存在"), //

231
src/main/java/a8k/service/hardwarev2/commonctrl/HardwareCommonCtrl.java

@ -0,0 +1,231 @@
package a8k.service.hardwarev2.commonctrl;
import a8k.appbase.HardwareException;
import a8k.appbase.appret.AppRet;
import a8k.controler.engineer.utils.EngineerPageTab;
import a8k.controler.engineer.utils.EnginnerPageAction;
import a8k.controler.engineer.utils.EnginnerPageParams;
import a8k.controler.engineer.utils.EnginnerPageTabOrder;
import a8k.service.hardware.canbus.A8kCanBusService;
import a8k.service.hardware.canbus.protocol.A8kEcode;
import a8k.service.hardware.canbus.protocol.IOId;
import a8k.service.hardware.canbus.protocol.MId;
import a8k.service.hardwarev2.param.PosParam;
import a8k.service.hardwarev2.param.TimeParam;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
@Component
@EngineerPageTab(name = "硬件控制-通用控制", order = EnginnerPageTabOrder.SamplesPreProcesCtrl)
@EnginnerPageParams(service = HardwareCommonCtrl.class)
public class HardwareCommonCtrl {
static Logger logger = org.slf4j.LoggerFactory.getLogger(HardwareCommonCtrl.class);
static class ORDER {
static final int initializeDevice = 1;
static final int deviceEnable = 2;
static final int deviceClear = 3;
}
@Resource
A8kCanBusService canBus;
@Resource
TimeParam timep;
@Resource
PosParam posp;
Boolean workState = false;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// CHECK
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
private AppRet<Object> checkDeviceStateBeforeRunToZero() throws HardwareException {
logger.info("checkDeviceStateBeforeRunToZero");
//试管平移通道是否有障碍
if (canBus.getIOState(IOId.THChInterPPS) || canBus.getIOState(IOId.THChOuterPPS)) {
logger.warn("THChInterPPS or THChOuterPPS is trigger");
return AppRet.fail(A8kEcode.TubeXChannelIsNotEmpty);
}
//板夹仓盖子是否盖上
if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) {
return AppRet.fail(A8kEcode.PlateBoxNotCover);
}
//板夹仓卡板检测
if (canBus.getIOState(IOId.PlateBoxPlateStuckPPS)) {
return AppRet.fail(A8kEcode.PlateStuckDetectorSensorTrigger);
}
//检查钩板电机是否处于终点位置
if (!canBus.getIOState(IOId.PullerMZeroPPS)) {
return AppRet.fail(A8kEcode.PullerMInitPosError);
}
//检查板夹仓光电是否处于起点位置
if (!canBus.getIOState(IOId.PusherMZeroPPS)) {
return AppRet.fail(A8kEcode.PusherMInitPosError);
}
//板夹仓光电
if (canBus.getIOState(IOId.RecycleBinOverflowPPS)) {
return AppRet.fail(A8kEcode.RecycleBinOverflow);
}
return AppRet.success();
}
private void checkStopFlag() throws HardwareException {
if (!workState) {
throw new HardwareException(A8kEcode.StopByUser);
}
}
private AppRet<Object> moveMotorToZero() throws HardwareException, InterruptedException {
//进出料初始化
canBus.stepMotorEasyMoveToZeroBlock(MId.FeedingModXM, timep.getActionOvertime());
checkStopFlag();
canBus.miniServoMoveToBlock(MId.ShakeModTubeScanerClampingSV, 10, timep.getActionOvertime());
checkStopFlag();
canBus.miniServoMoveToBlock(MId.ShakeModGripperSV, 10, timep.getActionOvertime());
checkStopFlag();
canBus.miniServoMoveToBlock(MId.ShakeModGripperYSV, 10, timep.getActionOvertime());
checkStopFlag();
canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModClampingM, timep.getActionOvertime());
checkStopFlag();
canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModGripperZM, timep.getActionOvertime());
checkStopFlag();
canBus.stepMotorEasyMoveToZeroBlock(MId.ShakeModShakeM, timep.getActionOvertime());
checkStopFlag();
canBus.stepMotorEasyMoveTo(MId.ShakeModShakeM, 90);
checkStopFlag();
//板夹仓初始化
canBus.stepMotorEasyMoveToZeroBlock(MId.PlatesBoxYM, timep.getActionOvertime());
checkStopFlag();
canBus.stepMotorEasyMoveToZeroBlock(MId.PlatesBoxPusherM, timep.getActionOvertime());
checkStopFlag();
//光学模组初始化
canBus.stepMotorEasyMoveToZeroBlock(MId.OptModPullM, timep.getActionOvertime());
checkStopFlag();
canBus.stepMotorEasyMoveToZeroBlock(MId.OptModScannerM, timep.getActionOvertime());
checkStopFlag();
//HBot初始化
canBus.hbotMoveToZero(MId.HbotM);
checkStopFlag();
canBus.stepMotorEasyMoveToZeroBlock(MId.PipetteModZM, timep.getActionOvertime());
checkStopFlag();
//转盘归零
canBus.stepMotorEasyMoveToZeroBlock(MId.IncubatorRotateCtrlM, timep.getActionOvertime());
checkStopFlag();
return AppRet.success();
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Expose API
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@EnginnerPageAction(name = "设备初始化", order = ORDER.initializeDevice)
public AppRet<Object> initializeDevice() throws HardwareException, InterruptedException {
logger.info("Initializing device ...");
boolean initSuc = false;
workState = true;
AppRet<Object> ecode;
try {
//打开必要的电源
canBus.setIOState(IOId.RecycleBinOverflowPPSPowerCtrl, true);
//检查设备状态
ecode = checkDeviceStateBeforeRunToZero();
if (!ecode.isSuccess()) {
return ecode;
}
// 复位设备
logger.info("moveMotorToZero");
ecode = moveMotorToZero();
if (!ecode.isSuccess()) {
return ecode;
}
initSuc = true;
logger.info("Device initialization completed");
} finally {
if (!initSuc) {
try {
canBus.stepMotorEnable(MId.ShakeModClampingM, 1);
} catch (HardwareException ignored) {
}
try {
canBus.stepMotorEasyMoveBy(MId.ShakeModClampingM, 2);
} catch (HardwareException ignored) {
}
}
}
return ecode;
}
@EnginnerPageAction(name = "清空板夹仓板夹", order = ORDER.deviceClear)
public void clearDevice() {
//TODO
}
@EnginnerPageAction(name = "设备使能", order = ORDER.deviceEnable)
public void deviceEnable(Boolean enable) throws HardwareException {
//进出料初始化
canBus.stepMotorEnable(MId.FeedingModInfeedM, enable ? 1 : 0);
canBus.stepMotorEnable(MId.FeedingModXM, enable ? 1 : 0);
canBus.stepMotorEnable(MId.FeedingModOutfeedM, enable ? 1 : 0);
//摇匀模组初始化
canBus.stepMotorEnable(MId.ShakeModClampingM, enable ? 1 : 0);
canBus.stepMotorEnable(MId.ShakeModGripperZM, enable ? 1 : 0);
canBus.stepMotorEnable(MId.ShakeModShakeM, enable ? 1 : 0);
canBus.miniServoEnable(MId.ShakeModGripperYSV, enable ? 1 : 0);
canBus.miniServoEnable(MId.ShakeModGripperSV, enable ? 1 : 0);
canBus.miniServoEnable(MId.ShakeModTubeScanerClampingSV, enable ? 1 : 0);
canBus.miniServoEnable(MId.ShakeModTubeScanerRotateSV, enable ? 1 : 0);
//板夹仓初始化
canBus.stepMotorEnable(MId.PlatesBoxYM, enable ? 1 : 0);
canBus.stepMotorEnable(MId.PlatesBoxPusherM, enable ? 1 : 0);
//光学模组初始化
canBus.stepMotorEnable(MId.OptModPullM, enable ? 1 : 0);
canBus.stepMotorEnable(MId.OptModScannerM, enable ? 1 : 0);
//HBot初始化
canBus.hbotEnable(MId.HbotM, enable ? 1 : 0);
canBus.stepMotorEnable(MId.PipetteModZM, enable ? 1 : 0);
//转盘归零
canBus.stepMotorEnable(MId.IncubatorRotateCtrlM, enable ? 1 : 0);
}
public void checkBeforeMove(MId mId) throws HardwareException {
//板夹仓盖子是否盖上
if (!canBus.getIOState(IOId.PlateBoxCoverClosurePPS)) {
throw new HardwareException(A8kEcode.PlateBoxNotCover);
}
}
public void stop() {
workState = false;
}
}

372
src/main/java/a8k/service/hardwarev2/ctrl/SamplesPreProcesCtrl.java

@ -0,0 +1,372 @@
package a8k.service.hardwarev2.ctrl;
import a8k.appbase.HardwareException;
import a8k.appbase.appret.AppRet;
import a8k.appbase.type.A8kTubeType;
import a8k.controler.engineer.utils.*;
import a8k.service.hardware.CommonHardwareOpeartion;
import a8k.service.hardware.HardwareCtrlModule;
import a8k.service.hardware.canbus.A8kCanBusService;
import a8k.service.hardware.canbus.protocol.A8kEcode;
import a8k.service.hardware.canbus.protocol.MId;
import a8k.service.hardwarev2.param.TimeParam;
import a8k.service.hardwarev2.param.PosParam;
import a8k.utils.ZEQ;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.List;
@Component
@EngineerPageTab(name = "硬件控制-样本预处理模块", order = EnginnerPageTabOrder.SamplesPreProcesCtrl)
@EnginnerPageParams(service = SamplesPreProcesCtrl.class)
public class SamplesPreProcesCtrl {
static Logger logger = LoggerFactory.getLogger(SamplesPreProcesCtrl.class);
@Resource
A8kCanBusService canBus;
@Resource
CommonHardwareOpeartion comHardwareOpear;
@Resource
TimeParam timep;
@Resource
PosParam pp;
Boolean debug = false;
@EnginnerPageAction(name = "使能调试模式", group = "调试")
public void enableDebugMode() {
this.debug = true;
}
@EnginnerPageAction(name = "失能调试模式", group = "调试")
public void disableDebugMode() {
this.debug = false;
}
@EnginnerPageAction(name = "模组归零")
public void modGroupMoveToZero() throws HardwareException, InterruptedException {
// if (!canBus.stepMotorReadIoState(MId.ShakeModGripperZM, 0)) {
// throw new HardwareException(A8kEcode.ShakeModGripperZMNotInZeroPos);
// }
canBus.miniServoMoveTo(MId.ShakeModGripperSV, pp.getGripperClosePos());//此步骤除了归零的同时还能够检测是否有试管在夹爪中
canBus.waitForMod(MId.ShakeModGripperSV, timep.getActionOvertime());
canBus.miniServoMoveTo(MId.ShakeModGripperYSV, pp.getGripperZeroYPos());
canBus.waitForMod(MId.ShakeModGripperYSV, timep.getActionOvertime());
canBus.stepMotorEasyMoveToZero(MId.ShakeModClampingM);
canBus.waitForMod(MId.ShakeModClampingM, timep.getActionOvertime());
canBus.stepMotorEasyMoveToZero(MId.ShakeModGripperZM);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
canBus.stepMotorEasyMoveToZero(MId.ShakeModShakeM);
canBus.waitForMod(MId.ShakeModShakeM, timep.getActionOvertime());
canBus.stepMotorEasyMoveTo(MId.ShakeModShakeM, 90);
canBus.waitForMod(MId.ShakeModShakeM, timep.getActionOvertime());
canBus.stepMotorEasyMoveTo(MId.ShakeModClampingM, -2);
}
@EnginnerPageAction(name = "模组快速归零")
public void modGroupMoveToZeroQuick() throws HardwareException, InterruptedException {
/*
* 1.Z轴回到零位
* 2.试管夹紧回到零位
* 3.摇匀回到零位
*/
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, 0);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
canBus.stepMotorEasyMoveTo(MId.ShakeModClampingM, 0);
canBus.waitForMod(MId.ShakeModClampingM, timep.getActionOvertime());
canBus.stepMotorEasyMoveTo(MId.ShakeModShakeM, 0);
canBus.waitForMod(MId.ShakeModShakeM, timep.getActionOvertime());
modGroupMoveToZero();
}
/**
* 取试管帽,如果试管帽存在
* @param highTube true/false
*/
@EnginnerPageAction(name = "取试管")
public AppRet<Boolean> takeTubeAndJudgeTubeExist(Boolean highTube) throws HardwareException, InterruptedException {
/*
* 校验:
* 1.当前摇匀模组设计到的电机是否都处于待机位
*/
//Z轴在原点
if (!canBus.stepMotorReadIoState(MId.ShakeModGripperZM, 0)) {
throw new HardwareException(MId.ShakeModGripperZM, A8kEcode.MNotInZeroPos);
}
//Y轴在零点附近
if (!ZEQ.IntEq(canBus.miniServoReadPos(MId.ShakeModGripperYSV), pp.getGripperZeroYPos(), 30)) {
throw new HardwareException(MId.ShakeModGripperYSV, A8kEcode.MNotInZeroPos);
}
//夹爪没有零位置
if (!ZEQ.IntEq(canBus.miniServoReadPos(MId.ShakeModGripperSV), pp.getGripperClosePos(), 30)) {
throw new HardwareException(MId.ShakeModGripperSV, A8kEcode.MNotInZeroPos);
}
//检查摇匀夹紧是否在零位
if (!canBus.stepMotorReadIoState(MId.ShakeModClampingM, 0)) {
throw new HardwareException(MId.ShakeModClampingM, A8kEcode.MNotInZeroPos);
}
boolean isHighBlood = highTube;
boolean tubeCapExist = true;
Integer gripperJudgeCapZPos = isHighBlood ? pp.getGripperJudgeHTubeCapZPos() : pp.getGripperJudgeSTubeCapZPos();
Integer gripperTakeTubeZPos = isHighBlood ? pp.getGripperTakeHTubeZPos() : pp.getGripperTakeSTubeZPos();
Integer gripperShakeZPos = pp.getGripperShakeTubeZPos();
//固定试管架
logger.info("固定试管架");
canBus.miniServoMoveTo(MId.ShakeModTubeScanerClampingSV, 900);
canBus.waitForMod(MId.ShakeModTubeScanerClampingSV, timep.getActionOvertime());
//试管夹紧移动到终点位置
logger.info("试管夹紧移动到终点位置");
canBus.stepMotorEasyMoveTo(MId.ShakeModClampingM, 70);
canBus.waitForMod(MId.ShakeModClampingM, timep.getActionOvertime());
//试管摇匀移动到90度
logger.info("试管摇匀移动到90度");
canBus.stepMotorEasyMoveTo(MId.ShakeModShakeM, pp.getShakeModShakeMStandbyPos());
canBus.waitForMod(MId.ShakeModShakeM, timep.getActionOvertime());
//Y轴向前移动
logger.info("夹爪Y轴移动到取试管位置");
canBus.miniServoMoveTo(MId.ShakeModGripperYSV, pp.getGripperTakeTubeYPos());
canBus.waitForMod(MId.ShakeModGripperYSV, timep.getActionOvertime());
//打开夹爪
logger.info("打开抓手");
canBus.miniServoMoveTo(MId.ShakeModGripperSV, pp.getGripperOpenPos());
canBus.waitForMod(MId.ShakeModGripperSV, timep.getActionOvertime());
//Z轴下移动到试管帽有无检测位
logger.info("Z轴下移动到试管帽有无检测位");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, gripperJudgeCapZPos);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//闭合夹爪检测试管帽是否存在
logger.info("闭合夹爪检测试管帽是否存在");
canBus.miniServoRotateWithTorque(MId.ShakeModGripperSV, -400);
Thread.sleep(timep.getTubeCapJudgeDelayTime());
if (ZEQ.IntEq(canBus.miniServoReadPos(MId.ShakeModGripperSV), pp.getGripperClosePos(), 30)) {
logger.info("试管帽不存在");
tubeCapExist = false;
}
if (debug || tubeCapExist) {
//打开夹爪
logger.info("打开夹爪");
canBus.miniServoMoveTo(MId.ShakeModGripperSV, pp.getGripperOpenPos());
canBus.waitForMod(MId.ShakeModGripperSV, timep.getActionOvertime());
//Z轴下移动到取试管位置
logger.info("Z轴下移动到取试管位置");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, gripperTakeTubeZPos);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//夹爪夹紧
logger.info("夹爪夹紧");
canBus.miniServoMoveTo(MId.ShakeModGripperSV, pp.getGripperTakeCapPos());
canBus.waitForMod(MId.ShakeModGripperSV, timep.getActionOvertime());
//Z轴上移动到零位
logger.info("Z轴上移动到零位");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, 0);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//Y轴移动到摇匀位
logger.info("Y轴移动到摇匀位");
canBus.miniServoMoveTo(MId.ShakeModGripperYSV, pp.getGripperShakeYPos() - 50); //该动作是为了消除齿轮间隙
canBus.waitForMod(MId.ShakeModGripperYSV, timep.getActionOvertime());
canBus.miniServoMoveTo(MId.ShakeModGripperYSV, pp.getGripperShakeYPos());
canBus.waitForMod(MId.ShakeModGripperYSV, timep.getActionOvertime());
//Z轴下移动到摇匀位放试管的位置
logger.info("Z轴下移动到摇匀位放试管的位置");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, gripperShakeZPos);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//夹紧试管
logger.info("夹紧试管");
canBus.stepMotorEasyMoveTo(MId.ShakeModClampingM, pp.getShakeClampingPos());
canBus.waitForMod(MId.ShakeModClampingM, timep.getActionOvertime());
//松开夹爪放置试管
logger.info("松开夹爪,放置试管");
canBus.miniServoMoveTo(MId.ShakeModGripperSV, pp.getGripperOpenPos());
canBus.waitForMod(MId.ShakeModGripperSV, timep.getActionOvertime());
//Z轴上移动到零位
logger.info("Z轴上移动到零位");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, 0);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//Z轴归零,校准一次位置
logger.info("Z轴归零");
canBus.stepMotorEasyMoveToZero(MId.ShakeModGripperZM);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//Y轴移动到零位
logger.info("Y轴移动到零位");
canBus.miniServoMoveTo(MId.ShakeModGripperYSV, pp.getGripperZeroYPos());
canBus.waitForMod(MId.ShakeModGripperYSV, timep.getActionOvertime());
} else {
modGroupMoveToZeroQuick();
}
return AppRet.success(tubeCapExist); //Z轴下移动试管判断的位置
}
@EnginnerPageAction(name = "摇匀")
public void shakeTube(Integer shakeDegree, Integer times) throws HardwareException, InterruptedException {
var standByPos = pp.getShakeModShakeMStandbyPos();
var startPos = standByPos - shakeDegree;
var endPos = standByPos + shakeDegree;
canBus.stepMotorEasyReciprocatingMotion(MId.ShakeModShakeM, startPos, endPos, times);
canBus.waitForMod(MId.ShakeModShakeM, timep.getActionOvertime());
}
@EnginnerPageAction(name = "取试管帽")
public void takeTubeCap() throws HardwareException, InterruptedException {
//Y移动到取试管帽位置
logger.info("Y移动到取试管帽位置 && 打开夹爪");
canBus.miniServoMoveTo(MId.ShakeModGripperYSV, pp.getGripperShakeYPos());
canBus.miniServoMoveTo(MId.ShakeModGripperSV, pp.getGripperOpenPos());
canBus.waitForMods(new MId[]{MId.ShakeModGripperYSV, MId.ShakeModGripperSV}, timep.getActionOvertime());
//Z下移动到取试管帽位置
logger.info("Z下移动到取试管帽位置");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, pp.getGripperTakeCapZPos() + 3);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//闭合夹爪
logger.info("闭合夹爪");
canBus.miniServoMoveTo(MId.ShakeModGripperSV, pp.getGripperTakeCapPos());
canBus.waitForMod(MId.ShakeModGripperSV, timep.getActionOvertime());
//Z上移动到零位
logger.info("Z上移动到零位");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, 0);
canBus.waitForMods(new MId[]{MId.ShakeModGripperZM}, timep.getActionOvertime());
//Y移动到待机位
logger.info("Y移动到待机位");
canBus.miniServoMoveTo(MId.ShakeModGripperYSV, pp.getGripperZeroYPos());
canBus.waitForMods(new MId[]{MId.ShakeModGripperYSV}, timep.getActionOvertime());
}
/**
* 盖试管帽并将试管移动回试管架中
*/
@EnginnerPageAction(name = "盖试管帽并放回试管架")
public void pushBackTubeCapAndTakeBakTube(A8kTubeType tubeType) throws HardwareException, InterruptedException {
//移动Y轴到取试管帽位置
logger.info("移动Y轴到取试管帽位置");
canBus.miniServoMoveTo(MId.ShakeModGripperYSV, pp.getGripperShakeYPos());
canBus.waitForMod(MId.ShakeModGripperYSV, timep.getActionOvertime());
//移动Z轴盖帽
logger.info("移动Z轴盖帽");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, pp.getGripperTakeCapZPos() + 10);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//打开试管夹
logger.info("打开试管夹");
canBus.stepMotorEasyMoveTo(MId.ShakeModClampingM, 70);
canBus.waitForMod(MId.ShakeModClampingM, timep.getActionOvertime());
//移动Z轴到零位
logger.info("移动Z轴到零位");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, 0);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//移动Y轴到方式管的位置
logger.info("移动Y轴到方式管的位置");
canBus.miniServoMoveTo(MId.ShakeModGripperYSV, pp.getGripperTakeTubeYPos());
canBus.waitForMod(MId.ShakeModGripperYSV, timep.getActionOvertime());
//移动Z轴到取试管位置
logger.info("移动Z轴到取试管位置");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, pp.getGripperTakeHTubeZPos() - 20);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//打开夹爪
logger.info("打开夹爪");
canBus.miniServoMoveTo(MId.ShakeModGripperSV, pp.getGripperOpenPos());
canBus.waitForMod(MId.ShakeModGripperSV, timep.getActionOvertime());
//Z轴上移动到零位
logger.info("Z轴上移动到零位");
canBus.stepMotorEasyMoveTo(MId.ShakeModGripperZM, 0);
canBus.waitForMod(MId.ShakeModGripperZM, timep.getActionOvertime());
//设备快速归零
modGroupMoveToZeroQuick();
}
/**
* 气溶胶风扇控制
*/
@EnginnerPageAction(
name = "气溶胶风扇控制",
order = 1,
beforeExecute = "beforeActionExec"
)
public void setAeroslFanPower(Boolean enable) throws Exception {
if (enable) {
canBus.fanControlerSetSpeed(MId.WbTubeFanMod, 99);
} else {
canBus.fanControlerSetSpeed(MId.WbTubeFanMod, 0);
}
}
public void beforeActionExec(Method method, List<Object> params) {
System.out.println("beforeActionExec");
}
}

87
src/main/java/a8k/service/hardwarev2/param/PosParam.java

@ -0,0 +1,87 @@
package a8k.service.hardwarev2.param;
import a8k.controler.engineer.utils.*;
import org.springframework.stereotype.Component;
@Component
@EngineerPageTab(name = "硬件参数-坐标参数", order = EnginnerPageTabOrder.PosParam)
@EnginnerPageParams(service = PosParam.class)
public class PosParam {
EnginnerParamReader hpReader = new EnginnerParamReader(EnginnerPageParams.class);
@EnginnerPageParam(name = "抓手张开位置", group = "抓手")
public Integer getGripperOpenPos() {
return hpReader.getInteger("GripperOpenPos", 150);
}
@EnginnerPageParam(name = "抓手闭合位置", group = "抓手")
public Integer getGripperClosePos() {
return hpReader.getInteger("GripperClosePos", 10);
}
@EnginnerPageParam(name = "抓手取试管位置", group = "抓手")
public Integer getGripperTakeCapPos() {
return hpReader.getInteger("GripperTakeCapPos", 55);
}
@EnginnerPageParam(name = "取试管位置", group = "Y轴位置")
public Integer getGripperTakeTubeYPos() {
return hpReader.getInteger("GripperTakeTubeYPos", 2750 + 300);
}
@EnginnerPageParam(name = "摇匀位置", group = "Y轴位置")
public Integer getGripperShakeYPos() {
return hpReader.getInteger("GripperShakeYPos", 1828 + 300);
}
@EnginnerPageParam(name = "待机位", group = "Y轴位置")
public Integer getGripperZeroYPos() {
return hpReader.getInteger("GripperZeroYPos", 300);
}
@EnginnerPageParam(name = "取高试管位置", group = "Z轴位置")
public Integer getGripperTakeHTubeZPos() {
return hpReader.getInteger("GripperTakeHTubeZPos", 739);
}
@EnginnerPageParam(name = "取低试管位置", group = "Z轴位置")
public Integer getGripperTakeSTubeZPos() {
return hpReader.getInteger("GripperTakeSTubeZPos", 985);
}
//JudgeTubeCapZ
@EnginnerPageParam(name = "高试管帽有无判断位", group = "Z轴位置")
public Integer getGripperJudgeHTubeCapZPos() {
return hpReader.getInteger("GripperJudgeHTubeCapZPos", 591);
}
@EnginnerPageParam(name = "低试管帽有无判断位", group = "Z轴位置")
public Integer getGripperJudgeSTubeCapZPos() {
return hpReader.getInteger("GripperJudgeSTubeCapZPos", 867);
}
//ShakeTubeZ
@EnginnerPageParam(name = "摇匀放置位置", group = "Z轴位置")
public Integer getGripperShakeTubeZPos() {
return hpReader.getInteger("GripperShakeTubeZPos", 835);
}
//TakeCapZ
@EnginnerPageParam(name = "取试管帽位", group = "Z轴位置")
public Integer getGripperTakeCapZPos() {
return hpReader.getInteger("GripperTakeCapZPos", 835);
}
@EnginnerPageParam(name = "试管夹紧位", group = "试管夹紧模块")
public Integer getShakeClampingPos() {
return hpReader.getInteger("ShakeClampingPos", 10);
}
@EnginnerPageParam(name = "摇匀臂", group = "试管摇匀待机位")
public Integer getShakeModShakeMStandbyPos() {
return hpReader.getInteger("ShakeModShakeMStandbyPos", 90);
}
}

23
src/main/java/a8k/service/hardwarev2/param/TimeParam.java

@ -0,0 +1,23 @@
package a8k.service.hardwarev2.param;
import a8k.controler.engineer.utils.*;
import org.springframework.stereotype.Component;
@Component
@EngineerPageTab(name = "底层-参数-时间参数", order = EnginnerPageTabOrder.TimeParam)
@EnginnerPageParams(service = PosParam.class)
public class TimeParam {
EnginnerParamReader hpReader = new EnginnerParamReader(EnginnerPageParams.class);
@EnginnerPageParam(name = "动作超时时间", group = "基础参数")
public Integer getActionOvertime() {
return hpReader.getInteger("ActionOvertime", 5000);
}
@EnginnerPageParam(name = "试管帽有无判断时间", group = "基础参数")
public Integer getTubeCapJudgeDelayTime() {
return hpReader.getInteger("TubeCapJudgeDelayTime", 300);
}
}

7
src/main/java/a8k/utils/ZEQ.java

@ -0,0 +1,7 @@
package a8k.utils;
public class ZEQ {
static public Boolean IntEq(Integer pos1, Integer pos2, Integer diff) {
return Math.abs(pos1 - pos2) < diff;
}
}
Loading…
Cancel
Save