Browse Source

update

tags/v0
zhaohe 10 months ago
parent
commit
68fec4cd3d
  1. 241
      doc/代码框架.md
  2. 3
      src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java
  3. 7
      src/main/java/a8k/optalgo/OptAlgo.java
  4. 9
      src/main/java/a8k/optalgo/type/OptAlgoError.java
  5. 14
      src/main/java/a8k/optalgo/type/OptAlgoResult.java
  6. 11
      src/main/java/a8k/optalgo/type/PeakInfo.java
  7. 31
      src/main/java/a8k/service/app/AppA8kDeviceStateMgrService.java
  8. 3
      src/main/java/a8k/service/app/AppConsumablesMgrService.java
  9. 3
      src/main/java/a8k/service/app/AppDeviceInitializationModule.java
  10. 4
      src/main/java/a8k/service/app/AppSampleFormulaMgrService.java
  11. 105
      src/main/java/a8k/service/appctrl/AppCoreCtrlService.java
  12. 89
      src/main/java/a8k/service/appctrl/AppRunTask.java
  13. 28
      src/main/java/a8k/service/appstate/A8kState.java
  14. 6
      src/main/java/a8k/service/appstate/type/EmergencyPosRunState.java
  15. 5
      src/main/java/a8k/service/appstate/type/IncubationPlateStatus.java
  16. 7
      src/main/java/a8k/service/appstate/type/ReactingPlateState.java
  17. 4
      src/main/java/a8k/service/appstate/type/SampleState.java
  18. 16
      src/main/java/a8k/service/appstate/type/TubeHolderState.java
  19. 26
      src/main/java/a8k/service/bak_appbase/A8kDeviceState.java
  20. 6
      src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java
  21. 20
      src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java
  22. 4
      src/main/java/a8k/type/exception/ActionBreakException.java
  23. 4
      src/main/java/a8k/type/exception/AppPauseException.java

241
doc/代码框架.md

@ -0,0 +1,241 @@
/*
*
* while(!isWaitingForStop()){
* if(当前样本处理完成){
* if(入料口有样本){
* 扫描样本 && 判断耗材是否充足
* 如果耗材不足,
* 提示用户(抛出提示事件),
* 暂停设备(退出线程(抛出pause异常))
* 如果扫描样本有误
* 提示用户
* 暂停设备
* }
* }
* else{
* 处理样本
* }
* }
*
* try{
*
* }catch(PauseException e){
* //pauseSelf
* //抛出事件
* }
*
* if(event){
* pauseSampleProcessThread();
* }
*
*/
经验:
动作与赋值分开
当一组动作完全执行完之后,再赋值给状态,这样就可以使得动作在执行过程中任意时间点都可以被打断。
while(true){
TubeCfg cfg = getTubeCfg(i);
moveTubeHolderProcessPos
if(tubeType == xxx)
takeTube
shakeTube(times,degree)
takeHap
move
else if(){
...
}
pausePoint;
}
问题:
有两种暂停状态:
一种是复位势暂停。
一种是保持现状势暂停。(前提是循环中)
pause/stop
动作划分为状态机
scan{
.
.
.
.
}
状态机->enter
状态机->enter
{
IDLE
{
if(state.eq(wokring)){
state.changeTo(scanPrepare)
}
}
SCANPREPARE
{
enterState
exitState
if(ioTrigger){
moveTubeHolderTo
waitForIoTrigger
changeStateTo(scanTubeHolderType)
if(error){
changeStateToError
}
}
}
SCANHODLER
{
move
scan
}
SCAN
PAUSE
{
}
}
```
用户PAUSE --> 暂停,恢复,全局状态的变更。
遇到错误 --> 通知,记录,清空工作位。无需恢复。
状态机 -->
修改全局状态。
记录。
执行动作。
前端接口:
pause;
continue;
全局都有哪些状态?
1. 类似于配置,
初始化
运行过程中修改(前端提交)
2. 运行过程控制,记录当前设备运行到哪一步,以便执行下一步。
步骤与暂停之间的关系。
步骤与恢复?
步骤与停止之间的关系。
步骤
步骤
步骤
步骤
步骤
暂停
步骤
----------------------------------------------
每一步都有几种处理方法
1. firstEnter
checkCondition是否满足
2. finalExit
3. loop
4. pause
5. continue
waitting_for_take_sample
pause
stepPause;
stepContinue;
stop
协作?
全局状态
{
take_tip
take_xxx
put_xxx
waitting_for
onPause{
....
}
onStop{
...
}
pauseCondtion{
...
}
}
{
pause...
}
pause_point
```
```
服务的提供者,
服务的使用者,
相互配合呢?
triggerHasTakeSample
doNext
---处理---
| |
| --搬运--(等待)
| |
扫描与预处理(等待) 抛出事件。
机械臂
takeSampleEnd
----------------------------
暂停:
waitingForPause,不需要弹出,只有单次循环结束
停止:
break?
异常:
exception?
第一假如需要允许暂停,则需要将步骤进行拆分,暂停点作为一步。
机械动作的暂停,涉及到,暂停和暂停恢复,不能简单的在代码中添加一个pause就可以的。
```

3
src/main/java/a8k/controler/extapi/pagecontrol/ExtApiTabConfig.java

@ -13,8 +13,9 @@ public enum ExtApiTabConfig {
AppDeviceInitializationModule("应用.初始化", true), //OK
AppConsumablesMgrService("应用.耗材扫描", true),
AppStateMgrService("应用.设备状态管理", true),
SampleFormulaMgrService("应用.配方管理", true),
AppSampleFormulaMgrService("应用.配方管理", true),
AppCtrlService("应用.设备控制", true),
AppCoreCtrlService("应用.核心控制", true),
Hbot2DCodeScanPosMgrService("参数.Hbot二维码扫描坐标参数", true),
UtilsProjectColorAllocer("工具.项目颜色分配", true),

7
src/main/java/a8k/optalgo/OptAlgo.java

@ -0,0 +1,7 @@
package a8k.optalgo;
public class OptAlgo {
}

9
src/main/java/a8k/optalgo/type/OptAlgoError.java

@ -0,0 +1,9 @@
package a8k.optalgo.type;
public enum OptAlgoError {
Success,
LostPeak,
LostPeakStart,
LostPeakEnd,
}

14
src/main/java/a8k/optalgo/type/OptAlgoResult.java

@ -0,0 +1,14 @@
package a8k.optalgo.type;
import java.util.List;
public class OptAlgoResult {
// vector<float> ogigin_val; // 1200
// vector<float> supper_val; // 原始数据线性填充1200*5=6000
// vector<float> supper_median_val; // supper_val 窗口平滑滤波6000
// vector<float> supper_smooth_sub_val; // supper_smooth_val 均值压缩6000/6=1000
public Float[] ogiginVal;
public Float[] supperVal;
public Float[] supperMedianVal;
public Float[] supperSmoothSubVal;
}

11
src/main/java/a8k/optalgo/type/PeakInfo.java

@ -0,0 +1,11 @@
package a8k.optalgo.type;
public class PeakInfo {
public Boolean findPeak;
public Float peakFullArea;
public Float peakBaseLineArea;
public Float area;
public Integer peakPos;
public Integer peakStartPos;
public Integer peakEndPos;
}

31
src/main/java/a8k/service/app/appstate/AppStateMgrService.java → src/main/java/a8k/service/app/AppA8kDeviceStateMgrService.java

@ -1,9 +1,10 @@
package a8k.service.app.appstate;
package a8k.service.app;
import a8k.controler.extapi.utils.ExtApiTab;
import a8k.controler.extapi.utils.ExtApiFn;
import a8k.controler.extapi.pagecontrol.ExtApiTabConfig;
import a8k.service.bak_appbase.A8kDeviceState;
import a8k.service.appstate.A8kState;
import a8k.service.bak_appbase.progress.TubeHolderProgress;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -11,34 +12,25 @@ import org.springframework.stereotype.Component;
@Component
@ExtApiTab(cfg = ExtApiTabConfig.AppStateMgrService)
public class AppStateMgrService {
public static final Logger logger = LoggerFactory.getLogger(AppStateMgrService.class);
public class AppA8kDeviceStateMgrService {
public static final Logger logger = LoggerFactory.getLogger(AppA8kDeviceStateMgrService.class);
static class ORDER {
static final int getDeviceState = 1;
}
public A8kDeviceState deviceState = new A8kDeviceState();
public A8kState deviceState = new A8kState();
@PostConstruct
public void init() {
}
// public void setConsumable(ConsumableState cig) {
// deviceState.consumable = cig;
// }
//
// public ConsumableState getConsumable() {
// return deviceState.consumable;
// }
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// EXPOSED API
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@ExtApiFn(name = "获取设备状态", order = ORDER.getDeviceState)
public A8kDeviceState getDeviceState() {
public A8kState getDeviceState() {
return deviceState;
}
@ -49,4 +41,13 @@ public class AppStateMgrService {
public void setDeviceInited(Boolean deviceInited) {
deviceState.deviceInited = deviceInited;
}
public TubeHolderProgress getTubeHolderProgress() {
return deviceState.tubeHolderProgress;
}
public void setTubeHolderProgress(TubeHolderProgress tubeHolderProgress) {
deviceState.tubeHolderProgress = tubeHolderProgress;
}
}

3
src/main/java/a8k/service/app/AppConsumablesMgrService.java

@ -12,7 +12,6 @@ import a8k.controler.extapi.utils.ExtApiTab;
import a8k.controler.extapi.utils.ExtApiFn;
import a8k.controler.extapi.pagecontrol.ExtApiTabConfig;
import a8k.service.app.app_consumables_mgr_service.ConsumableState;
import a8k.service.app.appstate.AppStateMgrService;
import a8k.type.cfg.Pos2d;
import a8k.type.exception.AppException;
import a8k.type.projecttype.A8kReactionFlowType;
@ -47,7 +46,7 @@ public class AppConsumablesMgrService {
ActionReactorService ar;
@Resource
AppStateMgrService stateMgrService;
AppA8kDeviceStateMgrService stateMgrService;
@Resource
Hbot2DCodeScanPosMgrService hbotScanPos;

3
src/main/java/a8k/service/app/AppDeviceInitializationModule.java

@ -7,7 +7,6 @@ import a8k.hardware.A8kCanBusService;
import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.hardware.type.a8kcanprotocol.IOId;
import a8k.hardware.type.a8kcanprotocol.MId;
import a8k.service.app.appstate.AppStateMgrService;
import a8k.baseservice.ActionReactorService;
import a8k.service.app.app_device_initialization_module.checkpoint.CheckPointType;
import a8k.service.app.app_device_initialization_module.checkpoint.CheckResult;
@ -33,7 +32,7 @@ public class AppDeviceInitializationModule {
A8kCanBusService canBus;
@Resource
AppStateMgrService stateMgrService;
AppA8kDeviceStateMgrService stateMgrService;
Integer actionOvertime = 10000;

4
src/main/java/a8k/service/app/SampleFormulaMgrService.java → src/main/java/a8k/service/app/AppSampleFormulaMgrService.java

@ -12,8 +12,8 @@ import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import org.springframework.stereotype.Component;
@Component
@ExtApiTab(cfg = ExtApiTabConfig.SampleFormulaMgrService)
public class SampleFormulaMgrService {
@ExtApiTab(cfg = ExtApiTabConfig.AppSampleFormulaMgrService)
public class AppSampleFormulaMgrService {
A8kDeviceSampleCfg deviceCfg = new A8kDeviceSampleCfg();
static class ORDER {

105
src/main/java/a8k/service/appctrl/AppCoreCtrlService.java

@ -0,0 +1,105 @@
package a8k.service.appctrl;
import a8k.controler.extapi.pagecontrol.ExtApiTabConfig;
import a8k.controler.extapi.utils.ExtApiTab;
import a8k.service.app.AppA8kDeviceStateMgrService;
import a8k.service.bak_appbase.progress.TubeHolderProgress;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
@ExtApiTab(cfg = ExtApiTabConfig.AppCoreCtrlService)
@Component
public class AppCoreCtrlService {
@Resource
AppA8kDeviceStateMgrService sms;
AppRunTask sampleScanAndPreProcessThread;
AppRunTask sampleProcessThread;
AppRunTask incubationPlateCtrlThread;
AppRunTask plateClampResultScanThread;
@PostConstruct
void init() {
sampleScanAndPreProcessThread = new AppRunTask();
sampleProcessThread = new AppRunTask();
incubationPlateCtrlThread = new AppRunTask();
plateClampResultScanThread = new AppRunTask();
sampleScanAndPreProcessThread.init(this::sampleScanAndPreProcessThreadWorkFn);
}
public void startWork() {
//启动所有线程
// setGState,notify
}
public void pauseWork() {
//暂停掉 入料和样本处理线程
// setGstate,notify
// waitForStop
// waitForStop
//
}
public void continueWork() {
//继续入料和样本处理线程
//setGState
//notify
}
public void stopWork() {
//停止所有线程
//setGState
//notify
//waitForStop
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* PRIV 私有方法
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
private void doSampleScanAndPreProcessThreadWorkFn() {
AppRunTask appRunTask = sampleScanAndPreProcessThread;
while (!appRunTask.isWaitingForStop()) {
//试管架处理状态-空闲
if (sms.getTubeHolderProgress().equals(TubeHolderProgress.Idle)) {
} else if (sms.getTubeHolderProgress().equals(TubeHolderProgress.Processing)) {
} else if (sms.getTubeHolderProgress().equals(TubeHolderProgress.Scaning)) {
}
}
/*
*
* motorRun
* waitForTrigger
* scanTubeHolderType
* pausePoint()
* for(int i < 6){
* scanTubeAndAssignTubeCfg;
* pausePoint(){throw PauseException;}
* }
* assignTubeCfg();
*
* 用户暂停
* 程序出错主动暂停
*
* // pause
*
*/
}
private void sampleScanAndPreProcessThreadWorkFn() {
try {
doSampleScanAndPreProcessThreadWorkFn();
} catch (Exception ignored) {
}
}
}

89
src/main/java/a8k/service/appctrl/AppRunTask.java

@ -0,0 +1,89 @@
package a8k.service.appctrl;
public class AppRunTask {
Thread workThread;
Runnable task;
Boolean ctrlState = false;
Boolean runState = false;
public AppRunTask() {
}
public void init(Runnable task) {
this.task = task;
this.workThread = new Thread(this::work);
this.workThread.start();
}
private void work() {
while (true) {
if (ctrlState) {
runState = true;
if (task != null)
task.run();
runState = false;
} else {
sleep(500);
}
}
}
public Boolean isWaitingForStop() {
return !ctrlState;
}
/**
* 启动线程
*/
public void start() {
ctrlState = true;
this.task.notify();
}
/**
* 停止线程
*/
public void stop() {
ctrlState = false;
}
/**
* 等待线程停止
*/
public void waitForStop() {
while (runState) {
sleep(10);
}
}
/**
* 睡眠
* @param mills 毫秒
*/
public void sleep(Integer mills) {
try {
Thread.sleep(mills);
} catch (InterruptedException ignored) {
}
}
/**
* 强制睡眠不会被打断
* @param mills 毫秒
*/
public void forceSleep(Integer mills) {
int end = mills + (int) System.currentTimeMillis();
while (System.currentTimeMillis() < end) {
sleep(50);
}
}
}

28
src/main/java/a8k/service/appstate/A8kState.java

@ -0,0 +1,28 @@
package a8k.service.appstate;
import a8k.service.appstate.type.*;
import a8k.service.bak_appbase.progress.TubeHolderProgress;
import java.util.List;
public class A8kState {
public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.Idle;
//当前正在被处理的试管架状态
public TubeHolderState tubeHolderState = new TubeHolderState();
//急诊为状态
public EmergencyPosRunState emergencyPosRunState = new EmergencyPosRunState();
//孵育盘状态
public IncubationPlateStatus incubationPlateStatus = new IncubationPlateStatus();
//温度
public Integer temperature = 25;
//设备是否初始化过
public Boolean deviceInited = false;
//所有样本的状态包含本次开机已经处理过的样本的状态
public List<SampleState> sampleStates;
//所有反应盘的状态(包含本次开机已经处理过的反应盘的状态)
public List<ReactingPlateState> reactingPlateStates;
}

6
src/main/java/a8k/service/bak_appbase/runstate/EmergencyPosRunState.java → src/main/java/a8k/service/appstate/type/EmergencyPosRunState.java

@ -1,4 +1,4 @@
package a8k.service.bak_appbase.runstate;
package a8k.service.appstate.type;
import a8k.type.sampleinfo.SampleInfo;
import a8k.service.bak_appbase.result.ReactionResult;
@ -7,8 +7,8 @@ import a8k.service.bak_appbase.progress.EmergencySampleProgress;
public class EmergencyPosRunState {
//急诊位状态
public EmergencySampleProgress emergencySampleProgress = EmergencySampleProgress.IDLE;
//
SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态
//样本位状态
SampleInfo sampleState = new SampleInfo(); //绑定的样本运行状态
//急诊位反应结果
public ReactionResult emergencyResult = new ReactionResult();
}

5
src/main/java/a8k/service/appstate/type/IncubationPlateStatus.java

@ -0,0 +1,5 @@
package a8k.service.appstate.type;
public class IncubationPlateStatus {
public ReactingPlateState[] plateStates = new ReactingPlateState[20];
}

7
src/main/java/a8k/service/bak_appbase/runstate/ReactingPlateRunState.java → src/main/java/a8k/service/appstate/type/ReactingPlateState.java

@ -1,4 +1,4 @@
package a8k.service.bak_appbase.runstate;
package a8k.service.appstate.type;
import a8k.service.bak_appbase.result.ReactionResult;
import a8k.type.sampleinfo.SampleInfo;
@ -6,14 +6,13 @@ import a8k.service.bak_appbase.progress.ReactionPlateProgress;
import java.util.Date;
public class ReactingPlateRunState {
public class ReactingPlateState {
String uuid;
ReactionPlateProgress progress; //孵育盘状态
String sampleUUID; //样本UUID 系统自动生成
String projectId; //项目id
SampleInfo bindSample; //绑定的样本运行状态
Integer incubationPos; //孵育盘中的位置 0->19
Date startIncubatedTime; //开始孵育时间
Integer targetIncubatedTimeS; //目标孵育时间

4
src/main/java/a8k/service/bak_appbase/runstate/TubeRunState.java → src/main/java/a8k/service/appstate/type/SampleState.java

@ -1,9 +1,9 @@
package a8k.service.bak_appbase.runstate;
package a8k.service.appstate.type;
import a8k.type.sampleinfo.SampleInfo;
import a8k.service.bak_appbase.progress.TubeProcessProgress;
public class TubeRunState {
public class SampleState {
public TubeProcessProgress tubeProcessProgress = TubeProcessProgress.EMPTY; //样本运行状态
public SampleInfo bindSample = new SampleInfo(); //绑定的样本运行状态
}

16
src/main/java/a8k/service/appstate/type/TubeHolderState.java

@ -0,0 +1,16 @@
package a8k.service.appstate.type;
import a8k.type.type.A8kTubeType;
import a8k.type.type.BloodType;
import a8k.service.bak_appbase.progress.TubeHolderProgress;
public class TubeHolderState {
public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //管子类型
public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型
//样本状态
public SampleState[] sampleStates = new SampleState[10];
public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.Idle; //管子状态
public Integer processingTubeIndex = -1; //当前正在被处理的试管索引
}

26
src/main/java/a8k/service/bak_appbase/A8kDeviceState.java

@ -1,26 +0,0 @@
package a8k.service.bak_appbase;
import a8k.service.app.app_consumables_mgr_service.ConsumableState;
import a8k.service.bak_appbase.runstate.ReactingPlateRunState;
import a8k.service.bak_appbase.runstate.EmergencyPosRunState;
import a8k.service.bak_appbase.runstate.TubeHolderRunState;
import java.util.List;
public class A8kDeviceState {
//耗材状态
public ConsumableState consumable = new ConsumableState();
//急诊为状态
public EmergencyPosRunState emergencyPosRunState = new EmergencyPosRunState();
//正在孵育的任务状态
public List<ReactingPlateRunState> incubatingPlateStates = null;
//当前正在被处理的试管架状态
public TubeHolderRunState tubeHolderRunState = new TubeHolderRunState();
//温度
public Integer temperature = 25;
public Boolean deviceInited = false; //设备是否初始化过
public Boolean devicePoweredOffNormally = false; //设备是否正常关机
}

6
src/main/java/a8k/service/bak_appbase/progress/TubeHolderProgress.java

@ -1,7 +1,7 @@
package a8k.service.bak_appbase.progress;
public enum TubeHolderProgress {
TubeHolderStateIdle, //空闲
TubeHolderStateProcessing, //处理中
TubeHolderStateProcessed, //处理完成
Idle, //空闲
Processing, //处理中
Scaning, //处理
}

20
src/main/java/a8k/service/bak_appbase/runstate/TubeHolderRunState.java

@ -1,20 +0,0 @@
package a8k.service.bak_appbase.runstate;
import a8k.type.type.A8kTubeType;
import a8k.type.type.BloodType;
import a8k.service.bak_appbase.progress.TubeHolderProgress;
public class TubeHolderRunState {
public BloodType bloodType = BloodType.WHOLE_BLOOD; //血型
public A8kTubeType tubeHolderType = A8kTubeType.BloodTube; //管子类型
public TubeHolderProgress tubeHolderProgress = TubeHolderProgress.TubeHolderStateIdle; //管子状态
public TubeRunState[] tubeRunStates = new TubeRunState[10]; //管子
public Integer processingTubeIndex = -1; //当前正在被处理的试管索引
public TubeHolderRunState() {
for (int i = 0; i < tubeRunStates.length; i++) {
tubeRunStates[i] = new TubeRunState();
}
processingTubeIndex = 1;
}
}

4
src/main/java/a8k/type/exception/ActionBreakException.java

@ -1,4 +0,0 @@
package a8k.type.exception;
public class ActionBreakException extends Exception {
}

4
src/main/java/a8k/type/exception/AppPauseException.java

@ -0,0 +1,4 @@
package a8k.type.exception;
public class AppPauseException extends Exception {
}
Loading…
Cancel
Save