Browse Source

加液检查液位

master
sige 1 year ago
parent
commit
8e1785ef9e
  1. BIN
      app.db
  2. 8
      src/main/java/com/iflytop/digester/controller/LiquidController.java
  3. 10
      src/main/java/com/iflytop/digester/controller/TestController.java
  4. 102
      src/main/java/com/iflytop/digester/deviceinstance/LiquidAdditionInstance.java
  5. 5
      src/main/java/com/iflytop/digester/deviceinstance/LiquidAdditionLiquid.java
  6. 11
      src/main/java/com/iflytop/digester/underframework/util/UfCommon.java
  7. 1
      src/main/resources/application-dev.yml

BIN
app.db

8
src/main/java/com/iflytop/digester/controller/LiquidController.java

@ -30,4 +30,12 @@ public class LiquidController extends UfApiControllerBase {
bucket.setVolume(bucket.totalVolume);
return this.success();
}
@ResponseBody
@PostMapping("/api/liquid/new-bucket")
public UfApiResponse newBucket(@RequestBody Map<String,Object> params) {
Integer bucketIndex = (Integer)params.get("index");
this.device.liquidAddition.liquidNewBucket(bucketIndex);
return this.success();
}
}

10
src/main/java/com/iflytop/digester/controller/TestController.java

@ -21,4 +21,14 @@ public class TestController extends UfApiControllerBase {
this.device.transferArm.takeOutTubesFromErrorSlot(indexes);
return this.success();
}
@ResponseBody
@PostMapping("/api/test/liquid-add")
public UfApiResponse liquidAdd(@RequestBody Map<String,Object> params) {
List<Integer> tubes = (List<Integer>)params.get("tubes");
String type = (String)params.get("type");
Integer volume = (Integer)params.get("volume");
this.device.liquidAddition.addLiquidToTubes(tubes, type, volume);
return this.success();
}
}

102
src/main/java/com/iflytop/digester/deviceinstance/LiquidAdditionInstance.java

@ -1,7 +1,12 @@
package com.iflytop.digester.deviceinstance;
import com.iflytop.digester.model.MdbRuntimeLog;
import com.iflytop.digester.underframework.UfActuatorCmdExecutor;
import com.iflytop.digester.underframework.UfApplication;
import com.iflytop.digester.underframework.UfCmdSnippetExecutor;
import com.iflytop.digester.underframework.dao.model.UfMdbNotification;
import com.iflytop.digester.underframework.dao.model.UfMdbOption;
import com.iflytop.digester.underframework.dao.model.UfMdbRuntimeVariable;
import com.iflytop.digester.underframework.util.UfCommon;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@ -10,6 +15,8 @@ import java.util.Map;
public class LiquidAdditionInstance {
// list of liquids
private List<LiquidAdditionLiquid> liquids;
// lock for bucket empty
private final Object bucketEmptyLock = new Object();
// setup
public void setup() {
@ -38,9 +45,7 @@ public class LiquidAdditionInstance {
public void addLiquidToTubes(List<Integer> tubes, List<Integer> pumpIndexes, int volume ) {
var pumpGroupOutIndex = pumpIndexes.get(0);
var pumpGroupInIndex = pumpIndexes.get(1);
var liquid = liquids.get(pumpGroupOutIndex/2);
var type = liquids.get(pumpGroupOutIndex/2).type;
var rotateDistance = this.convertVolumeToPumpRotationDistance(type, volume);
this.bucketVolumeCheck(pumpGroupOutIndex);
for ( int batchIndex=0; batchIndex<4; batchIndex++ ) {
// 外圈
@ -49,16 +54,10 @@ public class LiquidAdditionInstance {
if ( hasGoutTout || hasGoutTin ) {
UfCmdSnippetExecutor.execute("LiquidAdditionPrepare.Out." + batchIndex);
if ( hasGoutTout ) {
var snippetKey = "LiquidAdditionPump." + pumpGroupOutIndex;
Map<String,Object> snippetParams = Map.of("volume", rotateDistance);
UfCmdSnippetExecutor.execute(snippetKey, snippetParams);
liquid.volume -= volume;
this.pump(pumpGroupOutIndex, volume);
}
if ( hasGoutTin ) {
var snippetKey = "LiquidAdditionPump." + pumpGroupInIndex;
Map<String,Object> snippetParams = Map.of("volume", rotateDistance);
UfCmdSnippetExecutor.execute(snippetKey, snippetParams);
liquid.volume -= volume;
this.pump(pumpGroupInIndex, volume);
}
}
@ -68,16 +67,10 @@ public class LiquidAdditionInstance {
if ( hasGinTout || hasGinTin ) {
UfCmdSnippetExecutor.execute("LiquidAdditionPrepare.In." + batchIndex);
if ( hasGinTout ) {
var snippetKey = "LiquidAdditionPump." + pumpGroupOutIndex;
Map<String,Object> snippetParams = Map.of("volume", rotateDistance);
UfCmdSnippetExecutor.execute(snippetKey, snippetParams);
liquid.volume -= volume;
this.pump(pumpGroupOutIndex, volume);
}
if ( hasGinTin ) {
var snippetKey = "LiquidAdditionPump." + pumpGroupInIndex;
Map<String,Object> snippetParams = Map.of("volume", rotateDistance);
UfCmdSnippetExecutor.execute(snippetKey, snippetParams);
liquid.volume -= volume;
this.pump(pumpGroupInIndex, volume);
}
}
}
@ -85,6 +78,68 @@ public class LiquidAdditionInstance {
UfCmdSnippetExecutor.execute("LiquidAdditionReset");
}
// add liquid to tubes by given pump indexes
private void pump( Integer pumpIndex, Integer volume ) {
var liquid = liquids.get((0==pumpIndex%2) ? pumpIndex/2 : (pumpIndex-1)/2);
var type = liquid.type;
var snippetKey = "LiquidAdditionPump." + pumpIndex;
var rotateDistance = this.convertVolumeToPumpRotationDistance(type, volume);
Map<String,Object> snippetParams = Map.of("volume", rotateDistance);
UfCmdSnippetExecutor.execute(snippetKey, snippetParams);
// update liquid volume
liquid.setVolumeByConsumed(volume);
MdbRuntimeLog.log("LiquidAdd", "酸液消耗:%s - %d [%d/%d]", type, volume, liquid.volume, liquid.totalVolume);
}
// 检查液体量
private void bucketVolumeCheck( Integer pumpIndex ) {
var liquid = liquids.get((0==pumpIndex%2) ? pumpIndex/2 : (pumpIndex-1)/2);
var stateStr = UfActuatorCmdExecutor.execute("LiquidBucketVolumeIO", "module_readio");
var state = Integer.parseInt(stateStr);
MdbRuntimeLog.log("LiquidBucketVolumeIO", "液桶状态:[%s]", Integer.toString(state, 2));
var bucketState = state >> liquid.bucketIndex & 1;
if ( 1 == bucketState ) { // 酸液足够
return ;
}
// 如果缺少的液体不是水 则需要发送通知手动补充
var env = UfApplication.getApp().getEnv();
Integer waterBucketIndex = env.getProperty("app.liquidWaterBucketIndex", Integer.class);
assert waterBucketIndex != null;
if (!waterBucketIndex.equals(liquid.bucketIndex)) {
UfMdbNotification.action("LiquidBucketEmpty", Map.of("liquid", liquid));
MdbRuntimeLog.log("LiquidBucketEmpty", "酸液不足,等待手动补充完成 : %s", liquid.type);
synchronized ( this.bucketEmptyLock ) {
try {
this.bucketEmptyLock.wait();
MdbRuntimeLog.log("LiquidBucketEmpty", "酸液补充完成");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
this.bucketVolumeCheck(pumpIndex);
return;
}
// 水桶液位不足自动补充
MdbRuntimeLog.log("WaterBucketEmpty", "水桶液位不足,自动补充");
UfActuatorCmdExecutor.execute("LiquidBucketVolumeIO", "module_writeio", "8,1");
do {
// 检查上限位是否达到
var waterStateStr = UfActuatorCmdExecutor.execute("LiquidBucketVolumeIO", "module_readio");
var waterState = Integer.parseInt(waterStateStr);
boolean isBucketFull = 1 == (waterState >> 12 & 1);
if ( isBucketFull ) {
break;
}
UfCommon.delay(100);
} while ( true );
UfActuatorCmdExecutor.execute("LiquidBucketVolumeIO", "module_writeio", "8,0");
MdbRuntimeLog.log("WaterBucketEmpty", "水桶液位补充完成");
}
// 针对试管加液
public void addLiquidToTubes(List<Integer> tubes, String type, int volume ) {
var pumpIndexes = this.getPumpIndexForGroupOutAndIn(type);
@ -132,4 +187,13 @@ public class LiquidAdditionInstance {
}
UfCmdSnippetExecutor.execute("LiquidAddShakeStop");
}
// 酸液更换完成
public void liquidNewBucket( Integer index ) {
var liquid = liquids.get(index);
liquid.setVolume(liquid.totalVolume);
synchronized ( this.bucketEmptyLock ) {
this.bucketEmptyLock.notify();
}
}
}

5
src/main/java/com/iflytop/digester/deviceinstance/LiquidAdditionLiquid.java

@ -23,4 +23,9 @@ public class LiquidAdditionLiquid {
this.volume = volume;
UfMdbRuntimeVariable.setInteger(String.format("LiquidBucketVolume.%d", this.bucketIndex), volume);
}
// 通过消耗量设置剩余量
public void setVolumeByConsumed( Integer volume ) {
this.setVolume( this.volume - volume);
}
}

11
src/main/java/com/iflytop/digester/underframework/util/UfCommon.java

@ -0,0 +1,11 @@
package com.iflytop.digester.underframework.util;
public class UfCommon {
// delay for ms
public static void delay( Integer ms ) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

1
src/main/resources/application-dev.yml

@ -36,6 +36,7 @@ app :
errorSlotIndex : 4
liquidPeristalticPumpPipeSetupEnable : false
liquidPipeVolumn : 1
liquidWaterBucketIndex : 2
opencv-library-path: D:/ProgramFiles/OpenCV/opencv/build/java/x64/opencv_java490.dll
pylon-library-path: D:/ProgramFiles/Pylon5/Runtime/x64/PylonC_v5_2.dll
pylon-wrapper-path: D:/Sige5193/digester/src/main/java/com/iflytop/digester/camera/x64/Debug/baslerCamera.dll
Loading…
Cancel
Save