Browse Source

Merge remote-tracking branch 'origin/master'

tags/v0
sige 1 year ago
parent
commit
2c21be4d4b
  1. 4
      README.md
  2. 9
      src/main/java/a8k/appbean/OptScanDirection.java
  3. 49
      src/main/java/a8k/canbus/A8kCanBusService.java
  4. 10
      src/main/java/a8k/canbus/A8kModParamInitializer.java
  5. 1
      src/main/java/a8k/canbus/protocol/A8kEcode.java
  6. 15
      src/main/java/a8k/canbus/protocol/CmdId.java
  7. 77
      src/main/java/a8k/opt_algo/A8kOptAlgo.java
  8. 112
      src/main/java/a8k/service/hardware/ReactionPlatesTransmitCtrlService.java
  9. BIN
      zhaohe_app.db

4
README.md

@ -38,6 +38,10 @@
TODO:
1.想办法解决
4:号仓位退不出
14
```

9
src/main/java/a8k/appbean/OptScanDirection.java

@ -0,0 +1,9 @@
package a8k.appbean;
public enum OptScanDirection {
POSITIVE, NEGATIVE;
public Integer getInteger() {
return this == POSITIVE ? 1 : -1;
}
}

49
src/main/java/a8k/canbus/A8kCanBusService.java

@ -1,6 +1,7 @@
package a8k.canbus;
import a8k.app_eventbus.appevent.A8kCanBusOnConnectEvent;
import a8k.appbean.OptScanDirection;
import a8k.appbean.PlateInfo;
import a8k.canbus.custom_param_mgr.A8kModCustomParamMgr;
import a8k.canbus.protocol.*;
@ -154,7 +155,53 @@ public class A8kCanBusService {
}
//plate_code_scaner_adc_readraw
// ka8k_opt_v2_t_start_scan = CMDID(7, 0), //(int32_t scanDirection, int32_t lasterGain,int32_t scanGain)
// ka8k_opt_v2_f_start_scan = CMDID(7, 1), //(int32_t scanDirection, int32_t lasterGain,int32_t scanGain)
// ka8k_opt_v2_f_readVal = CMDID(7, 15), //(int32_t *val0,int32_t *val1) for_debug
// a8k_opt_v2_t_start_scan(0x0700, "a8k_opt_v2_t_start_scan"),//
// a8k_opt_v2_f_start_scan(0x0701, "a8k_opt_v2_f_start_scan"),//
// a8k_opt_v2_t_open_laster(0x070a, "a8k_opt_v2_t_open_laster"),//
// a8k_opt_v2_t_close_laster(0x070b, "a8k_opt_v2_t_close_laster"),//
// a8k_opt_v2_t_readVal(0x070c, "a8k_opt_v2_t_readVal"),//
// a8k_opt_v2_f_open_laster(0x070d, "a8k_opt_v2_f_open_laster"),//
// a8k_opt_v2_f_close_laster(0x070e, "a8k_opt_v2_f_close_laster"),//
// a8k_opt_v2_f_readVal(0x070f, "a8k_opt_v2_f_readVal"),//
//a8k_opt_v2_read_raw
public void optTStartScan(MId id, OptScanDirection scanDirection, Integer lasterGain, Integer scanGain) throws HardwareException, InterruptedException {
callcmd(id.toInt(), CmdId.a8k_opt_v2_t_start_scan.toInt(), scanDirection.getInteger(), lasterGain, scanGain);
}
public void optTStartScanBlock(MId id, OptScanDirection scanDirection, Integer lasterGain, Integer scanGain, Integer actionOvertime) throws HardwareException, InterruptedException {
optTStartScan(id, scanDirection, lasterGain, scanGain);
waitForMod(id, actionOvertime);
}
public void optFStartScan(MId id, OptScanDirection scanDirection, Integer lasterGain, Integer scanGain) throws HardwareException, InterruptedException {
callcmd(id.toInt(), CmdId.a8k_opt_v2_f_start_scan.toInt(), scanDirection.getInteger(), lasterGain, scanGain);
}
public void optFStartScanBlock(MId id, OptScanDirection scanDirection, Integer lasterGain, Integer scanGain, Integer actionOvertime) throws HardwareException, InterruptedException {
optFStartScan(id, scanDirection, lasterGain, scanGain);
waitForMod(id, actionOvertime);
}
public List<Integer> optReadRaw(MId id) throws HardwareException, InterruptedException {
int i = 0;
List<Integer> result = new ArrayList<>();
while (true) {
var rxPacket = callcmd(id.toInt(), CmdId.a8k_opt_v2_read_raw.toInt(), i++);
if (rxPacket.getCmdContent().length == 0) {
break;
}
var rawdata = ByteArray.readU16bitArray(rxPacket.getCmdContent());
result.addAll(Arrays.asList(rawdata));
}
return result;
}
public void plateCodeScanerPushCardAndScan(MId id, Integer finalStopPos) throws HardwareException, InterruptedException {

10
src/main/java/a8k/canbus/A8kModParamInitializer.java

@ -70,6 +70,16 @@ public class A8kModParamInitializer implements AppEventListener {
//
canBus.moduleSetReg(MId.OptModPullM, RegIndex.kreg_step_motor_run_to_zero_speed, 500);
canBus.moduleSetReg(MId.OptModPullM, RegIndex.kreg_step_motor_default_velocity, 2200);
canBus.moduleSetReg(MId.OptModPullM, RegIndex.kreg_step_motor_irun, 31);
canBus.moduleSetReg(MId.PlatesBoxPusherM, RegIndex.kreg_step_motor_default_velocity, 1800);
canBus.moduleSetReg(MId.PlatesBoxPusherM, RegIndex.kreg_step_motor_irun, 31);
canBus.moduleSetReg(MId.PlatesBoxYM, RegIndex.kreg_step_motor_default_velocity, 1800);
canBus.moduleSetReg(MId.PlatesBoxYM, RegIndex.kreg_step_motor_irun, 25);
// canBus.moduleSetReg(MId.OptModPullM, RegIndex.kreg_step_motor_run_to_zero_speed, 500);
}

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

@ -27,6 +27,7 @@ public enum A8kEcode {
TubeXChannelIsNotEmpty(21, "试管架平移通道不为空"),//
TubeTypeNotSupport(22, "试管类型不支持"),//
CmdIdNotSupport(23, "不支持指令"),//
PullPlateFail(24, "钩板卡板"),//
//
// FOR HARDWARE
//

15
src/main/java/a8k/canbus/protocol/CmdId.java

@ -9,7 +9,7 @@ public enum CmdId {
event_bus_reg_change_report(0x0064, "event_bus_reg_change_report"),//
//
module_ping(0x0100, "module_ping"),//
module_get_status(0x0104, "module_get_status", false),//
module_get_status(0x0104, "module_get_status", true),//
module_stop(0x0101, "module_stop"),//
module_set_reg(0x0105, "module_set_reg"),//
module_get_reg(0x0106, "module_get_reg"),//
@ -47,17 +47,8 @@ public enum CmdId {
pipette_aspirate_llf(0x720c, "pipette_aspirate_llf"),//
pipette_distribut_llf(0x720d, "pipette_distribut_llf"),//
pipette_shake_up_llf(0x720e, "pipette_shake_up_llf"),//
//
a8000_optical_module_power_ctrl(0x0600, "a8000_optical_module_power_ctrl"),//
a8000_optical_open_laser(0x0601, "a8000_optical_open_laser"),//
a8000_optical_close_laser(0x0602, "a8000_optical_close_laser"),//
a8000_optical_set_laster_gain(0x0603, "a8000_optical_set_laster_gain"),//
a8000_optical_set_scan_amp_gain(0x0604, "a8000_optical_set_scan_amp_gain"),//
a8000_optical_read_scanner_adc_val(0x0605, "a8000_optical_read_scanner_adc_val"),//
a8000_optical_read_laster_adc_val(0x0606, "a8000_optical_read_laster_adc_val"),//
a8000_optical_scan_current_point_amp_adc_val(0x0607, "a8000_optical_scan_current_point_amp_adc_val"),//
a8000_optical_start_capture(0x0608, "a8000_optical_start_capture"),//
a8000_optical_read_raw(0x0609, "a8000_optical_read_raw", CmdId.ATTACH_IS_INT32, CmdId.ATTACH_IS_BYTES),//
a8k_opt_v2_read_raw(0x0609, "a8k_opt_v2_read_raw", CmdId.ATTACH_IS_INT32, CmdId.ATTACH_IS_BYTES),//
//
a8k_opt_v2_t_start_scan(0x0700, "a8k_opt_v2_t_start_scan"),//
a8k_opt_v2_f_start_scan(0x0701, "a8k_opt_v2_f_start_scan"),//

77
src/main/java/a8k/opt_algo/A8kOptAlgo.java

@ -0,0 +1,77 @@
package a8k.opt_algo;
import java.util.ArrayList;
import java.util.List;
public class A8kOptAlgo {
static private List<Double> createDoubleList(int size) {
List<Double> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(0.0);
}
return list;
}
static private List<Double> integerToDouble(List<Integer> input) {
List<Double> output = new ArrayList<>(input.size());
for (Integer i : input) {
output.add(i.doubleValue());
}
return output;
}
static private List<Integer> doubleToInteger(List<Double> input) {
List<Integer> output = new ArrayList<>(input.size());
for (Double i : input) {
output.add(i.intValue());
}
return output;
}
static public List<Integer> preProcessOptData(List<Integer> input) {
List<Double> inputRaw = integerToDouble(input);
List<Double> upSamplingRaw = superSampling(inputRaw, 24);
List<Double> subSamplingRaw = subSampling(upSamplingRaw, 5);
return doubleToInteger(subSamplingRaw);
}
static public List<Double> superSampling(List<Double> input, Integer factor) {
int outputLength = input.size() * factor;
List<Double> upSamplingRaw = createDoubleList(outputLength);
for (int si = 0, di = 0; si < input.size() - 1; di++) {
Double a = upSamplingRaw.set(di * factor, input.get(si));
Double b = upSamplingRaw.set((di + 1) * factor, input.get(++si));
Double slope = (b - a) / factor;
for (int i = 0; i < factor - 1; i++) {
int baseIndex = (di * factor) + i;
upSamplingRaw.set(baseIndex + 1, upSamplingRaw.get(baseIndex) + slope);
}
}
return upSamplingRaw;
}
static public List<Double> subSampling(List<Double> inputRaw, Integer nSubSampleRate) {
int nSum = 0;
double fAvg = 0.0;
int subIndex = 0;
int nOutputLength = inputRaw.size() / nSubSampleRate;
List<Double> subSampledRaw = createDoubleList(nOutputLength);
for (int index = 0; index < inputRaw.size(); index++) {
if (index % nSubSampleRate == 0 && index > 0) {
fAvg = (double) nSum / nSubSampleRate;
subSampledRaw.set(subIndex++, fAvg);
nSum = 0;
}
nSum += inputRaw.get(index);
}
subSampledRaw.set(nOutputLength - 1, subSampledRaw.get(nOutputLength - 2));
return subSampledRaw;
}
}

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

@ -6,6 +6,7 @@ import a8k.canbus.protocol.IOId;
import a8k.canbus.protocol.MId;
import a8k.appbean.ecode.AppRet;
import a8k.canbus.A8kCanBusService;
import a8k.opt_algo.A8kOptAlgo;
import a8k.utils.*;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
@ -28,7 +29,12 @@ public class ReactionPlatesTransmitCtrlService implements HardwareCtrlModule {
@HardwareServiceParam(name = "动作超时时间", group = "基础参数")
public Integer getActionOvertime() {
return hpReader.getInteger("actionOvertime", 10000);
return hpReader.getInteger("actionOvertime", 7000);
}
@HardwareServiceParam(name = "光学扫描超时时间", group = "基础参数")
public Integer getOptScanOvertime() {
return hpReader.getInteger("optScanOvertime", 10000);
}
@HardwareServiceParam(name = "板夹仓通道0位置", group = "板夹仓参数")
@ -62,7 +68,7 @@ public class ReactionPlatesTransmitCtrlService implements HardwareCtrlModule {
@HardwareServiceParam(name = "仓位0出板位置", group = "转盘参数")
public Integer getTurntablePullPos0() {
return hpReader.getInteger("TurntablePullPos0", 1650 + 18000);
return hpReader.getInteger("TurntablePullPos0", 19700);
}
@HardwareServiceParam(name = "仓位0点滴位", group = "转盘参数")
@ -89,9 +95,30 @@ public class ReactionPlatesTransmitCtrlService implements HardwareCtrlModule {
@HardwareServiceParam(name = "扫描待机位", group = "光学模组参数")
public Integer getOptScanScandbyPos() {
return hpReader.getInteger("OptScanScandbyPos", 580);
return hpReader.getInteger("OptScanScandbyPos", 305);
}
@HardwareServiceParam(name = "T光学扫描起始坐标", group = "光学模组参数")
public Integer getTOptPosOffset() {
return hpReader.getInteger("TOptPosOffset", 3723);
}
@HardwareServiceParam(name = "F光学扫描起始坐标", group = "光学模组参数")
public Integer getFOptPosOffset() {
return hpReader.getInteger("FOptPosOffset", 2559);
}
@HardwareServiceParam(name = "T光学发光增益", group = "光学模组参数")
public Integer getOptTLasterGain() {
return hpReader.getInteger("OptTLasterGain", 0);
}
@HardwareServiceParam(name = "F光学发光增益", group = "光学模组参数")
public Integer getOptFLasterGain() {
return hpReader.getInteger("OptFLasterGain", 0);
}
/**
* ZERO_DPOS
*/
@ -216,7 +243,22 @@ public class ReactionPlatesTransmitCtrlService implements HardwareCtrlModule {
//限制pos在 0--> 36000之间
pos = pos % 36000;
if (pos < 0) {pos += 36000;}
canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos, getActionOvertime());
//先移动半个间距用来检测是否发生卡板
Integer nowPos = canBus.stepMotorReadPos(MId.IncubatorRotateCtrlM);
if (nowPos < pos) {
canBus.stepMotorEasyMoveByBlock(MId.IncubatorRotateCtrlM, getTurntablePosSpacing(), getActionOvertime());
} else if (nowPos > pos) {
canBus.stepMotorEasyMoveByBlock(MId.IncubatorRotateCtrlM, -getTurntablePosSpacing(), getActionOvertime());
}
//解决齿轮间隙的问题
if (nowPos < pos) {
canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos, getActionOvertime());
} else {
canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos - 300/**/, getActionOvertime());
canBus.stepMotorEasyMoveToBlock(MId.IncubatorRotateCtrlM, pos, getActionOvertime());
}
}
@ -247,12 +289,24 @@ public class ReactionPlatesTransmitCtrlService implements HardwareCtrlModule {
return AppRet.success(canBus.plateCodeScannerReadCode(MId.PlatesBoxScanner));
}
public void pushPlateQuick(PlateBoxCh PBCh, IncubatorPos turntablePosIndex) throws HardwareException, InterruptedException {
trunableMoveToPushPos(turntablePosIndex);
canBus.stepMotorEasyMoveToBlock(MId.PlatesBoxYM, getPBCh0Pos() + PBCh.off * getPBChSpacing(), getActionOvertime());
canBus.stepMotorEasyMoveToBlock(MId.PlatesBoxPusherM, getPusherEndPos(), getActionOvertime());
canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxPusherM, getActionOvertime());
canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.PlatesBoxYM, getActionOvertime());
}
@HardwareServiceAction(name = "拉板", group = "单步操作")
public void pullPlate(IncubatorPos turntablePosIndex) throws HardwareException, InterruptedException {
trunableMoveToPullPos(turntablePosIndex);
canBus.stepMotorEasyMoveToBlock(MId.OptModScannerM, getOptScanScandbyPos(), getActionOvertime());
canBus.stepMotorEasyMoveToBlock(MId.OptModPullM, getPullerTargetPos(), getActionOvertime());
if (!canBus.getIOState(IOId.PullerMEndPPS)) {
logger.error("pull plate fail");
throw new HardwareException(A8kEcode.PullPlateFail);
}
canBus.stepMotorEasyMoveToZeroPointQuickBlock(MId.OptModPullM, getActionOvertime());
}
@ -263,29 +317,31 @@ public class ReactionPlatesTransmitCtrlService implements HardwareCtrlModule {
canBus.stepMotorEasyMoveToBlock(MId.OptModScannerM, getOptScanScandbyPos(), getActionOvertime());
}
private Boolean breakDropAllPlateFlag = false;
Boolean pushAllPlateAndDropBreakFlag = false;
@HardwareServiceAction(name = "丢弃全部板", group = "测试")
public void dropAllPlate() throws HardwareException, InterruptedException {
breakDropAllPlateFlag = false;
@HardwareServiceAction(name = "推全部板同时丢弃", group = "位置测试")
public void pushAllPlateAndDrop(PlateBoxCh PBCh, IncubatorPos startPos) throws HardwareException, InterruptedException {
pushAllPlateAndDropBreakFlag = false;
checkBeforeMoveTrunable();
checkBeforeMovePlateBox();
modGroupMoveToZeroQuick();
dropPlate();
for (IncubatorPos index : IncubatorPos.values()) {
if (index.compareTo(startPos) < 0) {
continue;
}
pushPlateQuick(PBCh, index);
pullPlate(index);
dropPlate();
if (breakDropAllPlateFlag) {
break;
}
if (pushAllPlateAndDropBreakFlag) {break;}
}
}
@HardwareServiceAction(name = "打断-丢弃全部板", group = "测试")
public void breakDropAllPlate() throws HardwareException, InterruptedException {
breakDropAllPlateFlag = true;
@HardwareServiceAction(name = "推全部板同时丢弃中断", group = "位置测试")
public void pushAllPlateAndDropBreak() {
pushAllPlateAndDropBreakFlag = true;
}
@HardwareServiceAction(name = "显示板夹扫码原始曲线", group = "辅助调试")
public AppRet<A8kScanCurve> readPlateScanCurve() throws HardwareException, InterruptedException {
List<Integer> scanDataCurve = canBus.plateCodeScanerReadRawResult(MId.PlatesBoxScanner);
@ -296,6 +352,32 @@ public class ReactionPlatesTransmitCtrlService implements HardwareCtrlModule {
return AppRet.success(new A8kScanCurve(scanDataCurve, refLine));
}
private AppRet<A8kScanCurve> packetOptDisplayScanCurve(List<Integer> scanDataCurve) {
A8kScanCurve scanCurve = new A8kScanCurve();
scanCurve.scanDataCurve = A8kOptAlgo.preProcessOptData(scanDataCurve);
scanCurve.refCurve = A8kOptAlgo.preProcessOptData(scanDataCurve);
scanCurve.refLine = new ArrayList<>();
for (int i = 1; i < 6; i++) {
scanCurve.refLine.add(40 * i);
}
return AppRet.success(scanCurve);
}
@HardwareServiceAction(name = "T光学扫码", group = "光学调试")
public AppRet<A8kScanCurve> optTScan(OptScanDirection direction, Integer scanerGain) throws HardwareException, InterruptedException {
canBus.optTStartScanBlock(MId.OptMod, direction, getOptTLasterGain(), scanerGain, getOptScanOvertime());
return packetOptDisplayScanCurve(canBus.optReadRaw(MId.OptMod));
}
@HardwareServiceAction(name = "F光学扫码", group = "光学调试")
public AppRet<A8kScanCurve> optFScan(OptScanDirection direction, Integer scanerGain) throws HardwareException, InterruptedException {
canBus.optFStartScanBlock(MId.OptMod, direction, getOptTLasterGain(), scanerGain, getOptScanOvertime());
return packetOptDisplayScanCurve(canBus.optReadRaw(MId.OptMod));
}
//
// 状态
//
@HardwareServiceAction(name = "读取<转盘>位置", group = "位置测量")
public AppRet<Integer> readTrunablePos() throws HardwareException, InterruptedException {

BIN
zhaohe_app.db

Loading…
Cancel
Save