Browse Source

update

tags/v0
zhaohe 10 months ago
parent
commit
66c698b502
  1. BIN
      app.db
  2. 18
      src/main/java/a8k/hardware/A8kModParamInitializer.java
  3. 120
      src/main/java/a8k/service/app/devicedriver/calibration/HbotLittleBottleConsumableCalibration.java
  4. 60
      src/main/java/a8k/service/app/devicedriver/pos/HbotConsumablePosMgr.java
  5. 2
      src/main/java/a8k/type/LittleBottleConsumableRefPoint.java
  6. 1
      src/main/java/a8k/utils/ZJsonHelper.java
  7. 22
      src/main/java/a8k/utils/ZSimplAlgo.java

BIN
app.db

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

@ -1,5 +1,7 @@
package a8k.hardware;
import a8k.service.app.devicedriver.basectrl.PipetteCtrlModule;
import a8k.service.app.devicedriver.basectrl.type.PipetteRegIndex;
import a8k.service.bases.AppEventBusService;
import a8k.service.bases.appevent.A8kCanBusOnConnectEvent;
import a8k.service.bases.appevent.AppEvent;
@ -15,14 +17,17 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class A8kModParamInitializer {
public class A8kModParamInitializer {
static Logger logger = LoggerFactory.getLogger(A8kModParamInitializer.class);
@Resource
AppEventBusService eventBus;
@Resource
A8kCanBusService canBus;
A8kCanBusService canBus;
@Resource
PipetteCtrlModule pipetteCtrlModule;
@Resource
A8kModCustomParamMgr customParamMgr;
@ -54,7 +59,7 @@ public class A8kModParamInitializer {
canBus.moduleSetReg(MId.PlatesBoxPusherM, RegIndex.kret_step_motor_pos_devi_tolerance, 5);
canBus.moduleSetReg(MId.OptModPullM, RegIndex.kret_step_motor_pos_devi_tolerance, 5);
canBus.moduleSetReg(MId.OptModScannerM, RegIndex.kret_step_motor_pos_devi_tolerance, 5);
// canBus.moduleSetReg(MId.PipetteModZM, RegIndex.kret_step_motor_pos_devi_tolerance, 20);
pipetteCtrlModule.setReg(PipetteRegIndex.kreg_pipette_zm_pos_devi_tolerance, 20);
canBus.moduleSetReg(MId.IncubatorRotateCtrlM, RegIndex.kret_step_motor_pos_devi_tolerance, 5);
canBus.moduleSetReg(MId.FeedingModXM, RegIndex.kret_step_motor_io_trigger_append_distance, 10);
@ -65,7 +70,7 @@ public class A8kModParamInitializer {
canBus.moduleSetReg(MId.PlatesBoxPusherM, RegIndex.kret_step_motor_io_trigger_append_distance, 3);
canBus.moduleSetReg(MId.OptModPullM, RegIndex.kret_step_motor_io_trigger_append_distance, 10);
canBus.moduleSetReg(MId.OptModScannerM, RegIndex.kret_step_motor_io_trigger_append_distance, 10);
// canBus.moduleSetReg(MId.PipetteModZM, RegIndex.kret_step_motor_io_trigger_append_distance, 10);
pipetteCtrlModule.setReg(PipetteRegIndex.kreg_pipette_zm_io_trigger_append_distance, 10);
canBus.moduleSetReg(MId.IncubatorRotateCtrlM, RegIndex.kret_step_motor_io_trigger_append_distance, 10);
canBus.moduleSetReg(MId.ShakeModGripperYSV, RegIndex.kreg_mini_servo_limit_torque, 700);
@ -81,6 +86,7 @@ public class A8kModParamInitializer {
canBus.moduleSetReg(MId.PlatesBoxYM, RegIndex.kreg_step_motor_default_velocity, 1800);
canBus.moduleSetReg(MId.PlatesBoxYM, RegIndex.kreg_step_motor_irun, 25);
pipetteCtrlModule.setReg(PipetteRegIndex.kreg_pipette_zm_default_velocity, 1500);
//Hbot-丢步容忍距离
canBus.moduleSetReg(MId.HbotM, RegIndex.kreg_xyrobot_pos_devi_tolerance, 5);
@ -98,11 +104,7 @@ public class A8kModParamInitializer {
canBus.moduleSetReg(MId.HbotM, RegIndex.kreg_xyrobot_vstop, 1);
canBus.moduleSetReg(MId.HbotM, RegIndex.kreg_xyrobot_tzerowait, 300);
// canBus.moduleSetReg(MId.PipetteModZM, RegIndex.kreg_step_motor_default_velocity, 1500);
// canBus.moduleSetReg(MId.HbotM, RegIndex.kreg_xyrobot_run_to_zero_speed, 300);
// canBus.moduleSetReg(MId.HbotM, RegIndex.kreg_xyrobot_one_circle_pulse, 7215);
// canBus.moduleSetReg(MId.OptModPullM, RegIndex.kreg_step_motor_run_to_zero_speed, 500);
}

120
src/main/java/a8k/service/app/devicedriver/calibration/HbotLittleBottleConsumableCalibration.java

@ -13,7 +13,10 @@ import a8k.type.*;
import a8k.type.cfg.Pos2d;
import a8k.type.cfg.Pos3d;
import a8k.type.exception.AppException;
import a8k.utils.ZJsonHelper;
import a8k.utils.ZSimplAlgo;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
@ -57,9 +60,9 @@ public class HbotLittleBottleConsumableCalibration {
}
@ExtApiFn(name = "获取所有坐标", group = "基础", order = 1)
public Object getPoss() throws AppException {
return hbotConsumablePosMgr.getParams();
@ExtApiFn(name = "获取坐标", group = "基础", order = 1)
public Object getPoss(LittleBottleConsumableType type) throws AppException {
return hbotConsumablePosMgr.getLittleBottleConsumablePosInfo(type);
}
@ -84,9 +87,10 @@ public class HbotLittleBottleConsumableCalibration {
}
LittleBottleConsumableType littleBottleConsumableType = LittleBottleConsumableType.BufferSolution;
List<LittleBottleConsumableRefPoint> littleBottleConsumableRefPoint;
LittleBottleConsumableType littleBottleConsumableType = LittleBottleConsumableType.BufferSolution;
List<LittleBottleConsumableRefPoint> littleBottleConsumableRefPoint = new java.util.ArrayList<>();
LittleBottleConsumablePosInfo littleBottleConsumablePosInfo;
List<Integer> zpos = new java.util.ArrayList<>();
@ExtApiFn(name = "开始标定小瓶坐标", group = "标定小瓶坐标", order = 30)
@ -94,6 +98,7 @@ public class HbotLittleBottleConsumableCalibration {
littleBottleConsumablePosInfo = null;
littleBottleConsumableRefPoint = new java.util.ArrayList<>();
littleBottleConsumableType = type;
zpos.clear();
moveToZero();
disableModule();
}
@ -107,10 +112,23 @@ public class HbotLittleBottleConsumableCalibration {
LittleBottleConsumableRefPoint littleBufferRefPoint = new LittleBottleConsumableRefPoint(group, off0To24, new Pos3d(xypos.x, xypos.y, z));
this.littleBottleConsumableRefPoint.add(littleBufferRefPoint);
disableModule();
return computeLittleBottlePosInfo();
ObjectNode node = ZJsonHelper.createObjectNode();
node.put("newPoint", ZJsonHelper.createObjectNode(littleBufferRefPoint));
node.put("computeResult", ZJsonHelper.createObjectNode(computeLittleBottlePosInfo()));
return node;
}
@ExtApiFn(name = "删除上一个小瓶参考点", group = "标定小瓶坐标", order = 32)
@ExtApiFn(name = "添加Z轴坐标点", group = "标定小瓶坐标", order = 32)
public Object addLittleBottleGroupRefPoint() throws AppException {
enableModule();
pipetteCtrlModule.zMotorMeasureDistance();
Integer z = pipetteCtrlModule.zMotorReadMeasureDistanceResult();
zpos.add(z);
disableModule();
return z;
}
@ExtApiFn(name = "计算坐标", group = "标定小瓶坐标", order = 32)
public LittleBottleConsumablePosInfo computeLittleBottlePosInfo() {
//计算y0,所有group==0,1,2,同时0<=off<5的点求平均
Double[] y = new Double[2];
@ -119,7 +137,16 @@ public class HbotLittleBottleConsumableCalibration {
Double[] dys = new Double[6];
Double dx;
Double dy;
Double z;
double z = 0.0;
LittleBottleConsumableRefPoint[] gx_00 = new LittleBottleConsumableRefPoint[6];
gx_00[0] = littleBottleConsumableRefPoint.stream().filter(point -> point.group == ConsumableGroup.GROUP0 && point.index == 0).findFirst().orElse(null);
gx_00[1] = littleBottleConsumableRefPoint.stream().filter(point -> point.group == ConsumableGroup.GROUP1 && point.index == 0).findFirst().orElse(null);
gx_00[2] = littleBottleConsumableRefPoint.stream().filter(point -> point.group == ConsumableGroup.GROUP2 && point.index == 0).findFirst().orElse(null);
gx_00[3] = littleBottleConsumableRefPoint.stream().filter(point -> point.group == ConsumableGroup.GROUP3 && point.index == 0).findFirst().orElse(null);
gx_00[4] = littleBottleConsumableRefPoint.stream().filter(point -> point.group == ConsumableGroup.GROUP4 && point.index == 0).findFirst().orElse(null);
gx_00[5] = littleBottleConsumableRefPoint.stream().filter(point -> point.group == ConsumableGroup.GROUP5 && point.index == 0).findFirst().orElse(null);
y[0] = ZSimplAlgo.computeAverage(
littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() < 3 && point.index < 5).
@ -131,89 +158,96 @@ public class HbotLittleBottleConsumableCalibration {
map(point -> point.pos.y).toList()
);
//计算y0,所有group==0,3,同时off==0,5,10,15,20的点求y平均
//计算x0,所有group==0,3,同时off==0,5,10,15,20的点求y平均
x[0] = ZSimplAlgo.computeAverage(
littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() % 3 == 0 && point.index % 5 == 0).
map(point -> point.pos.y).toList()
map(point -> point.pos.x).toList()
);
//计算y1,所有group==1,4,同时off==0,5,10,15,20的点求y平均
//计算x1,所有group==1,4,同时off==0,5,10,15,20的点求y平均
x[1] = ZSimplAlgo.computeAverage(
littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() % 3 == 1 && point.index % 5 == 0).
map(point -> point.pos.y).toList()
map(point -> point.pos.x).toList()
);
//计算y2
//计算x2
x[2] = ZSimplAlgo.computeAverage(
littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() % 3 == 2 && point.index % 5 == 0).
map(point -> point.pos.y).toList()
);
//
z = ZSimplAlgo.computeAverage(
littleBottleConsumableRefPoint.stream().map(point -> point.pos.z).toList()
map(point -> point.pos.x).toList()
);
z = ZSimplAlgo.computeAverage(zpos);
//计算d0x,所有 非0,5,10,15,20的点到x0的距离/偏移差值求平均
for (int i = 0; i < 6; i++) {
int finalI = i;
dxs[i] = ZSimplAlgo.computeAverage(
if (gx_00[i] == null) {
continue;
}
Double val = ZSimplAlgo.computeAverage(
littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() == finalI && point.getColOff() != 0).
map(point -> point.pos.x - x[finalI % 3] / (point.getColOff())).toList()
map(point -> (point.pos.x - gx_00[finalI].pos.x) / (point.getColOff())).toList()
);
dxs[i] = val;
}
dx = ZSimplAlgo.computeAverage(dxs);
//计算dy,
for (int i = 0; i < 6; i++) {
int finalI = i;
if (gx_00[i] == null)
continue;
dys[i] = ZSimplAlgo.computeAverage(
littleBottleConsumableRefPoint.stream().filter(point -> point.group.ordinal() == finalI && point.getRowOff() != 0).
map(point -> point.pos.y - y[finalI / 3] / (point.getRowOff())).toList()
map(point -> (point.pos.y - gx_00[finalI].pos.y) / (point.getRowOff())).toList()
);
}
dy = ZSimplAlgo.computeAverage(dys);
littleBottleConsumablePosInfo = new LittleBottleConsumablePosInfo();
littleBottleConsumablePosInfo.g0_000 = new Pos3d(x[0].intValue(), y[0].intValue(), z.intValue());
littleBottleConsumablePosInfo.g1_000 = new Pos3d(x[1].intValue(), y[0].intValue(), z.intValue());
littleBottleConsumablePosInfo.g2_000 = new Pos3d(x[2].intValue(), y[0].intValue(), z.intValue());
littleBottleConsumablePosInfo.g3_000 = new Pos3d(x[0].intValue(), y[1].intValue(), z.intValue());
littleBottleConsumablePosInfo.g4_000 = new Pos3d(x[1].intValue(), y[1].intValue(), z.intValue());
littleBottleConsumablePosInfo.g5_000 = new Pos3d(x[2].intValue(), y[1].intValue(), z.intValue());
littleBottleConsumablePosInfo.g0_000 = new Pos3d(x[0].intValue(), y[0].intValue(), (int) z);
littleBottleConsumablePosInfo.g1_000 = new Pos3d(x[1].intValue(), y[0].intValue(), (int) z);
littleBottleConsumablePosInfo.g2_000 = new Pos3d(x[2].intValue(), y[0].intValue(), (int) z);
littleBottleConsumablePosInfo.g3_000 = new Pos3d(x[0].intValue(), y[1].intValue(), (int) z);
littleBottleConsumablePosInfo.g4_000 = new Pos3d(x[1].intValue(), y[1].intValue(), (int) z);
littleBottleConsumablePosInfo.g5_000 = new Pos3d(x[2].intValue(), y[1].intValue(), (int) z);
littleBottleConsumablePosInfo.dx = dx;
littleBottleConsumablePosInfo.dy = dy;
return littleBottleConsumablePosInfo;
}
@ExtApiFn(name = "保存小瓶坐标", group = "标定小瓶坐标", order = 33)
@ExtApiFn(name = "保存计算结果", group = "标定小瓶坐标", order = 33)
public void saveLittleBottleConsumablePosInfo() throws AppException {
hbotConsumablePosMgr.setLittleBottleConsumablePosInfo(littleBottleConsumableType, littleBottleConsumablePosInfo);
}
@ExtApiFn(name = "读取所有参考点", group = "标定小瓶坐标", order = 33)
public Object readAllRefPoint() throws AppException {
return littleBottleConsumableRefPoint;
}
//
// 校验
//
@ExtApiFn(name = "校验小瓶缓冲液坐标", group = "校验", order = 301)
public void testMoveToLittleBufferPos() throws AppException {
public void testMoveToLittleBufferPos(ConsumableGroup group) throws AppException {
resetStopFlag();
enableModule();
for (ConsumableGroup group : ConsumableGroup.values()) {
for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) {
hbotControler.moveToLittleBufferPos(group, i);
if (checkStopFlag())
return;
}
for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) {
hbotControler.moveToLittleBufferPos(group, i);
pipetteCtrlModule.zMotorMoveToZeroPointQuickBlock();
if (checkStopFlag())
return;
}
}
@ExtApiFn(name = "校验探测物质坐标", group = "校验", order = 302)
public void testMoveToProbeSubstancePos() throws AppException {
public void testMoveToProbeSubstancePos(ConsumableGroup group) throws AppException {
resetStopFlag();
enableModule();
for (ConsumableGroup group : ConsumableGroup.values()) {
for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) {
hbotControler.moveToProbeSubstancePos(group, i);
if (checkStopFlag())
return;
}
for (int i = 0; i < AppConstant.CONSUMABLE_NUM; i++) {
hbotControler.moveToProbeSubstancePos(group, i);
pipetteCtrlModule.zMotorMoveToZeroPointQuickBlock();
if (checkStopFlag())
return;
}
}

60
src/main/java/a8k/service/app/devicedriver/pos/HbotConsumablePosMgr.java

@ -62,6 +62,32 @@ public class HbotConsumablePosMgr {
posReader.updatePos(HbotConsumablePosParam.TipGroup2_SpaceingX, 0.0);
posReader.updatePos(HbotConsumablePosParam.TipGroup2_SpaceingY, 0.0);
posReader.updatePos(HbotConsumablePosParam.LittleBufferGroup0_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.LittleBufferGroup1_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.LittleBufferGroup2_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.LittleBufferGroup3_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.LittleBufferGroup4_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.LittleBufferGroup5_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.LittleBufferGroupDX, 0.0);
posReader.updatePos(HbotConsumablePosParam.LittleBufferGroupDY, 0.0);
posReader.updatePos(HbotConsumablePosParam.ProbeSubstanceGroup0_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.ProbeSubstanceGroup1_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.ProbeSubstanceGroup2_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.ProbeSubstanceGroup3_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.ProbeSubstanceGroup4_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.ProbeSubstanceGroup5_000Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.ProbeSubstanceDX, 0.0);
posReader.updatePos(HbotConsumablePosParam.ProbeSubstanceDY, 0.0);
posReader.updatePos(HbotConsumablePosParam.LargeBuffer_0Pos, new Pos3d());
posReader.updatePos(HbotConsumablePosParam.LargeBuffer_DX, 0.0);
posReader.updatePos(HbotConsumablePosParam.LargeBuffer_DY, 0.0);
}
public List<ObjectNode> getParams() {
@ -107,6 +133,40 @@ public class HbotConsumablePosMgr {
posReader.updatePos(tipDyPos, dy);
}
public LittleBottleConsumablePosInfo getLittleBufferGroupPosInfo() {
LittleBottleConsumablePosInfo info = new LittleBottleConsumablePosInfo();
info.g0_000 = posReader.getPos(HbotConsumablePosParam.LittleBufferGroup0_000Pos, Pos3d.class);
info.g1_000 = posReader.getPos(HbotConsumablePosParam.LittleBufferGroup1_000Pos, Pos3d.class);
info.g2_000 = posReader.getPos(HbotConsumablePosParam.LittleBufferGroup2_000Pos, Pos3d.class);
info.g3_000 = posReader.getPos(HbotConsumablePosParam.LittleBufferGroup3_000Pos, Pos3d.class);
info.g4_000 = posReader.getPos(HbotConsumablePosParam.LittleBufferGroup4_000Pos, Pos3d.class);
info.g5_000 = posReader.getPos(HbotConsumablePosParam.LittleBufferGroup5_000Pos, Pos3d.class);
info.dx = posReader.getPos(HbotConsumablePosParam.LittleBufferGroupDX, Double.class);
info.dy = posReader.getPos(HbotConsumablePosParam.LittleBufferGroupDY, Double.class);
return info;
}
public LittleBottleConsumablePosInfo getProbeSubstanceGroupPosInfo() {
LittleBottleConsumablePosInfo info = new LittleBottleConsumablePosInfo();
info.g0_000 = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceGroup0_000Pos, Pos3d.class);
info.g1_000 = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceGroup1_000Pos, Pos3d.class);
info.g2_000 = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceGroup2_000Pos, Pos3d.class);
info.g3_000 = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceGroup3_000Pos, Pos3d.class);
info.g4_000 = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceGroup4_000Pos, Pos3d.class);
info.g5_000 = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceGroup5_000Pos, Pos3d.class);
info.dx = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceDX, Double.class);
info.dy = posReader.getPos(HbotConsumablePosParam.ProbeSubstanceDY, Double.class);
return info;
}
public LittleBottleConsumablePosInfo getLittleBottleConsumablePosInfo(LittleBottleConsumableType type) {
if (type.equals(LittleBottleConsumableType.BufferSolution)) {
return getLittleBufferGroupPosInfo();
} else {
return getProbeSubstanceGroupPosInfo();
}
}
public void setLittleBottleConsumablePosInfo(LittleBottleConsumableType type, LittleBottleConsumablePosInfo info) {
HbotConsumablePosParam group0_000Pos;
HbotConsumablePosParam group1_000Pos;

2
src/main/java/a8k/type/LittleBottleConsumableRefPoint.java

@ -20,6 +20,6 @@ public class LittleBottleConsumableRefPoint {
}
public Integer getColOff() {
return index % AppConstant.CONSUMABLE_COL_NUM;
return index % AppConstant.CONSUMABLE_ROW_NUM;
}
}

1
src/main/java/a8k/utils/ZJsonHelper.java

@ -20,6 +20,7 @@ public class ZJsonHelper {
return new ObjectMapper().createObjectNode();
}
public static ObjectNode createObjectNode(Object obj) {
ObjectMapper ObjectMapper = new ObjectMapper();
return ObjectMapper.valueToTree(obj);

22
src/main/java/a8k/utils/ZSimplAlgo.java

@ -5,28 +5,46 @@ import java.util.List;
public class ZSimplAlgo {
public static Double computeAverage(List<?> data) {
double sum = 0.0;
int cnt = 0;
for (var datum : data) {
if(datum == null) {
continue;
}
if (datum instanceof Double) {
if (Double.isNaN((Double) datum) || Double.isInfinite((Double) datum)) {
continue;
}
sum += (Double) datum;
} else if (datum instanceof Integer) {
sum += (Integer) datum;
} else if (datum instanceof Long) {
sum += (Long) datum;
} else if (datum instanceof Float) {
if (Float.isNaN((Float) datum) || Float.isInfinite((Float) datum)) {
continue;
}
sum += (Float) datum;
} else {
throw new IllegalArgumentException("Unsupported type: " + datum.getClass().getName());
}
cnt++;
}
return sum / data.size();
}
public static Double computeAverage(Double[] data) {
Double sum = 0.0;
Double sum = 0.0;
Integer cnt = 0;
for (Double datum : data) {
if (datum == null || datum.isNaN() || datum.isInfinite()) {
continue;
}
sum += datum;
cnt++;
}
return sum / data.length;
return sum / cnt;
}
}
Loading…
Cancel
Save