Browse Source

添加光学校准

tags/v0
zhaohe 10 months ago
parent
commit
1e46a7b36b
  1. BIN
      app.db
  2. 2
      src/main/java/a8k/AppControlerExceptionProcesser.java
  3. 6
      src/main/java/a8k/constant/OptConstant.java
  4. 22
      src/main/java/a8k/extapi_controler/ExtApiControler.java
  5. 2
      src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java
  6. 30
      src/main/java/a8k/hardware/A8kCanBusService.java
  7. 2
      src/main/java/a8k/optalgo/A8kOptAlgo.java
  8. 36
      src/main/java/a8k/optalgo/A8kOptAlgoUtils.java
  9. 106
      src/main/java/a8k/optalgo/OptAlgoUtils.java
  10. 8
      src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java
  11. 32
      src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java
  12. 59
      src/main/java/a8k/service/app/devicectrl/driver/OptModuleDriver.java
  13. 18
      src/main/java/a8k/service/app/devicectrl/driver/type/OptModuleRegIndex.java
  14. 4
      src/main/java/a8k/service/app/devicectrl/exdriver/TubeTransportExDriver.java
  15. 165
      src/main/java/a8k/service/app/devicectrl/param/calibration/OptModuleParamCalibration.java
  16. 49
      src/main/java/a8k/service/app/devicectrl/param/param_mgr/OptModuleParamsMgr.java
  17. 4
      src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kOptType.java
  18. 2
      src/main/java/a8k/service/test/fakeproj/FakeProjInfo.java
  19. 11
      src/main/java/a8k/type/A8kScanCurve.java
  20. 5
      src/main/java/a8k/type/OptScanDirection.java
  21. 21
      src/main/java/a8k/type/appret/AppRet.java

BIN
app.db

2
src/main/java/a8k/AppControlerExceptionProcesser.java

@ -14,7 +14,7 @@ public class AppControlerExceptionProcesser {
@ResponseBody
@ExceptionHandler(value = Exception.class)
public AppRet<?> controllerExceptionHandler(Exception e) {
public AppRet controllerExceptionHandler(Exception e) {
logger.info("捕获到异常 : ", e);
return AppRet.fail(e);
}

6
src/main/java/a8k/constant/OptConstant.java

@ -0,0 +1,6 @@
package a8k.constant;
public class OptConstant {
static public final Integer FOPT_LASTER_GAIN = 100;
static public final Integer TOPT_LASTER_GAIN = 100;
}

22
src/main/java/a8k/extapi_controler/ExtApiControler.java

@ -23,7 +23,7 @@ import java.util.Map;
public class ExtApiControler {
@PostMapping("/api/service-config/service-list")
@ResponseBody
public AppRet<Object> services() {
public AppRet services() {
List<Map<String, Object>> services = new ArrayList<>();
var classes = SpringBootBeanUtil.getBeans();
for (var clazz : classes) {
@ -43,7 +43,7 @@ public class ExtApiControler {
@PostMapping("/api/service-config/service-params-list")
@ResponseBody
public AppRet<Object> serviceParams(@RequestBody Map<String, Object> params)
public AppRet serviceParams(@RequestBody Map<String, Object> params)
throws InvocationTargetException, IllegalAccessException {
String serviceKey = (String) params.get("serviceKey");
var paramService = this.getServiceParamHandlerByServiceKey(serviceKey);
@ -77,7 +77,7 @@ public class ExtApiControler {
@PostMapping("/api/service-config/service-params-update")
@ResponseBody
public AppRet<Object> serviceParamsUpdate(@RequestBody Map<String, Object> params) throws Exception {
public AppRet serviceParamsUpdate(@RequestBody Map<String, Object> params) throws Exception {
String serviceKey = (String) params.get("serviceKey");
Map<String, Object> newParams = (Map<String, Object>) params.get("params");
@ -119,7 +119,7 @@ public class ExtApiControler {
@PostMapping("/api/service-config/service-params-reset")
@ResponseBody
public AppRet<Object> serviceParamsReset(@RequestBody Map<String, Object> params) throws Exception {
public AppRet serviceParamsReset(@RequestBody Map<String, Object> params) throws Exception {
// String serviceKey = (String) params.get("serviceKey");
// HardwareServiceSetting.deleteAllByServiceName(serviceKey);
return AppRet.success();
@ -127,7 +127,7 @@ public class ExtApiControler {
@PostMapping("/api/service-config/service-status-list")
@ResponseBody
public AppRet<Object> serviceStatus(@RequestBody Map<String, Object> params) throws InvocationTargetException, IllegalAccessException {
public AppRet serviceStatus(@RequestBody Map<String, Object> params) throws InvocationTargetException, IllegalAccessException {
String serviceKey = (String) params.get("serviceKey");
Class<?> serviceClass = null;
var classes = SpringBootBeanUtil.getBeans();
@ -166,7 +166,7 @@ public class ExtApiControler {
@PostMapping("/api/service-config/service-action-list")
@ResponseBody
public AppRet<Object> serviceActionList(@RequestBody Map<String, Object> params) throws Exception {
public AppRet serviceActionList(@RequestBody Map<String, Object> params) throws Exception {
String serviceKey = (String) params.get("serviceKey");
Class<?> serviceClass = null;
var classes = SpringBootBeanUtil.getBeans();
@ -244,7 +244,7 @@ public class ExtApiControler {
@PostMapping("/api/service-config/service-action-exec")
@ResponseBody
public AppRet<Object> serviceActionExecute(@RequestBody Map<String, Object> params) throws Throwable {
public AppRet serviceActionExecute(@RequestBody Map<String, Object> params) throws Throwable {
String serviceKey = (String) params.get("serviceKey");
var service = this.getServiceInstanceByServiceKey(serviceKey);
Assert.isTrue(service != null, "service not found");
@ -277,7 +277,7 @@ public class ExtApiControler {
@PostMapping("/api/service-config/service-action-exec-by-map")
@ResponseBody
public AppRet<Object> serviceActionExecuteByMap(@RequestBody Map<String, Object> params) throws Throwable {
public AppRet serviceActionExecuteByMap(@RequestBody Map<String, Object> params) throws Throwable {
String serviceKey = (String) params.get("serviceKey");
var service = this.getServiceInstanceByServiceKey(serviceKey);
Assert.isTrue(service != null, "service not found");
@ -322,7 +322,7 @@ public class ExtApiControler {
@PostMapping("/api/service-config/class-struct-info-get")
@ResponseBody
public AppRet<Object> classStructInfoGet(@RequestBody Map<String, Object> params) throws Exception {
public AppRet classStructInfoGet(@RequestBody Map<String, Object> params) throws Exception {
String className = (String) params.get("class");
Class<?> clazz = Class.forName(className);
List<Map<String, Object>> struct = new ArrayList<>();
@ -331,7 +331,7 @@ public class ExtApiControler {
}
// execute service action and get response
private AppRet<Object> executeServiceActionAndGetResponse(Object service, Method method, List<Object> actionParams) throws Throwable {
private AppRet executeServiceActionAndGetResponse(Object service, Method method, List<Object> actionParams) throws Throwable {
Object actionResult = null;
try {
var actionParamList = actionParams.toArray();
@ -353,7 +353,7 @@ public class ExtApiControler {
}
if (actionResult instanceof AppRet) {
return (AppRet<Object>) actionResult;
return (AppRet) actionResult;
}
return AppRet.success(actionResult);
}

2
src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java

@ -27,6 +27,7 @@ public enum ExtApiTabConfig {
HbotProbeSubstancePosCalibration("校准.探测物质位置校准", true),
PipetteGunLLDParamCalibration("校准.移液枪LLD参数校准", true),
PipetteGunLLFParamCalibration("校准.移液枪LLF参数校准", true),
OptModuleParamCalibration("校准.光学模块参数校准", true),
VirtualDeviceSimulationTest("测试.虚拟设备测试", true),
@ -35,6 +36,7 @@ public enum ExtApiTabConfig {
A8kPipetteCtrlModule("硬件驱动测试.移液枪测试", true),
ActionReactorService("底层调试.单步调试", false),//OK
ReactionPlatesTransmitCtrl("ReactionPlatesTransmitCtrl", false),
HbotControlService("HbotControlService", false),

30
src/main/java/a8k/hardware/A8kCanBusService.java

@ -168,37 +168,7 @@ public class A8kCanBusService {
}
public void optTStartScan(MId id, OptScanDirection scanDirection, Integer lasterGain, Integer scanGain) throws AppException {
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 AppException {
optTStartScan(id, scanDirection, lasterGain, scanGain);
waitForMod(id, actionOvertime);
}
public void optFStartScan(MId id, OptScanDirection scanDirection, Integer lasterGain, Integer scanGain) throws AppException {
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 AppException {
optFStartScan(id, scanDirection, lasterGain, scanGain);
waitForMod(id, actionOvertime);
}
public List<Integer> optReadRaw(MId id) throws AppException {
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 AppException {

2
src/main/java/a8k/optalgo/OptAlgo.java → src/main/java/a8k/optalgo/A8kOptAlgo.java

@ -12,7 +12,7 @@ import java.util.ArrayList;
import java.util.List;
@Slf4j
public class OptAlgo {
public class A8kOptAlgo {
public static OptAlgoResult processOptData(Integer expectPeakNum, Integer searchStart, double[] data) {
LineProcessContext cxt = new LineProcessContext();

36
src/main/java/a8k/optalgo/A8kOptAlgoUtils.java

@ -0,0 +1,36 @@
package a8k.optalgo;
import a8k.optalgo.utils.Filter;
import a8k.optalgo.utils.SubSampling;
import a8k.optalgo.utils.SupperSampling;
public class A8kOptAlgoUtils {
static public Integer[] supperSamplingAndSubSampling(Integer[] data) {
double[] indata = new double[data.length];
for (int i = 0; i < data.length; i++) {
indata[i] = data[i];
}
var result = supperSamplingAndSubSampling(indata);
Integer[] outdata = new Integer[result.length];
for (int i = 0; i < result.length; i++) {
outdata[i] = (int) result[i];
}
return outdata;
}
static public double[] supperSamplingAndSubSampling(double[] data) {
//过采样
var afSupperVal = SupperSampling.process(data, 5);
//中值滤波
var afSupperMedianVal = Filter.medianFiltering(afSupperVal, 25);
//下采样到1000个点
var raw1000 = SubSampling.process(afSupperMedianVal, 6);
//生成1000个的平滑曲线
var avg1000 = Filter.smooth(raw1000, 13);
return SubSampling.process(avg1000, 4);
}
}

106
src/main/java/a8k/optalgo/OptAlgoUtils.java

@ -1,106 +0,0 @@
package a8k.optalgo;
import a8k.optalgo.type.LinearResult;
import a8k.optalgo.type.OptAlgoResult;
import org.springframework.util.Assert;
public class OptAlgoUtils {
OptAlgoResult processOptData(Integer expectPeakNum, Float[] data) {
return null;
}
Boolean feq(double a, double b, double epsilon) {
double dv = a - b;
if (dv < 0)
dv = -dv;
return dv <= epsilon;
}
Float[] differentiate(Float[] inputRaw) {
/**
* @brief
* 巴迪泰源码对原始数据添加了一些微小的值原因未知
*/
for (int i = 0; i <= inputRaw.length - 8; i += 8) {
inputRaw[i + 1] = inputRaw[i + 1] + 0.001f;
inputRaw[i + 2] = inputRaw[i + 2] + 0.002f;
inputRaw[i + 3] = inputRaw[i + 3] + 0.003f;
inputRaw[i + 4] = inputRaw[i + 4] + 0.004f;
inputRaw[i + 5] = inputRaw[i + 5] + 0.005f;
inputRaw[i + 6] = inputRaw[i + 6] + 0.004f;
inputRaw[i + 7] = inputRaw[i + 7] + 0.003f;
inputRaw[i + 8] = inputRaw[i + 8] + 0.002f;
}
/**
* @brief
* @Warning: 此处求导和巴迪泰的存在差异
* 巴迪泰的是当前数值减去下一个数值
* 而此处是当前数值减去上一个数值
*/
Float[] differentiateRaw = new Float[inputRaw.length];
for (int i = 1; i < differentiateRaw.length; i++) {
differentiateRaw[i] = inputRaw[i] - inputRaw[i - 1];
}
differentiateRaw[0] = differentiateRaw[1];
return differentiateRaw;
}
Float[] least_square_method_differentiate(Float[] inputRaw, int windows_size) {
Assert.isTrue((windows_size > 0), "windows_size > 0");
Assert.isTrue((windows_size % 2 == 1), "windows_size % 2 == 1");
Float[] differentiateRaw = new Float[inputRaw.length];
Float[] windowsRaw = new Float[windows_size];
int windows_size_half = (windows_size - 1) / 2;
for (int index = windows_size_half; index < inputRaw.length - windows_size_half; index++) {
// windowsRaw = getwindowspoint(inputRaw, index, windows_size);
float intercept = 0;
// linear_least_squares(windowsRaw, windows_size, differentiateRaw[index],
// intercept);
}
for (int i = 0; i < windows_size_half; i++) {
differentiateRaw[i] = differentiateRaw[windows_size_half];
}
for (int i = inputRaw.length - windows_size_half; i < inputRaw.length; i++) {
differentiateRaw[i] = differentiateRaw[inputRaw.length - windows_size_half - 1];
}
return differentiateRaw;
}
float get_avg_in_windows(double[] src, int off, int windows) {
float sum = 0;
Assert.isTrue((windows % 2 == 1),"(windows % 2 == 1)");
for (int i = off - windows / 2; i <= off + windows / 2; i++) {
sum += (float) src[i];
}
return sum / windows;
}
void sort_vector(Float[] src) {
// 实现冒泡排序
for (int i = 0; i < src.length; i++) {
for (int j = 0; j < src.length - i - 1; j++) {
if (src[j] > src[j + 1]) {
float temp = src[j];
src[j] = src[j + 1];
src[j + 1] = temp;
}
}
}
}
}

8
src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java

@ -82,6 +82,14 @@ public class PLATE_OPT_SCAN extends A8kStepAction {
return reactionResults;
}
//
// 判断T光学是否需要扫描T光学扫描方向扫描范围
// 判断F光学是否需要扫描F光学扫描方向扫描范围
// 获取扫描起始位置峰的数量接收放大倍数扫描放大倍数是否自动调整放大倍数
// 根据峰计算最终结果
//
//TODO 扫描反应板
//丢板
optScanModuleCtrlService.dropPlate();

32
src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java

@ -1,12 +1,17 @@
package a8k.service.app.devicectrl.ctrlservice;
import a8k.constant.OptConstant;
import a8k.extapi_controler.pagecontrol.ExtApiTabConfig;
import a8k.extapi_controler.utils.ExtApiTab;
import a8k.service.app.devicectrl.driver.OptModuleDriver;
import a8k.service.app.devicectrl.driver.StepMotorCtrlDriver;
import a8k.service.app.devicectrl.driver.type.OptModuleRegIndex;
import a8k.service.app.devicectrl.driver.type.StepMotorMId;
import a8k.service.app.devicectrl.param.param_mgr.OptModuleParamsMgr;
import a8k.service.bases.ActionReactorService;
import a8k.service.db.type.a8kidcard.zenum.A8kOptType;
import a8k.type.IncubatorPos;
import a8k.type.OptScanDirection;
import a8k.type.exception.AppException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@ -23,6 +28,8 @@ public class OptScanModuleCtrlService {
StepMotorCtrlDriver stepMotorCtrlDriver;
@Resource
ActionReactorService actionReactor;
@Resource
OptModuleDriver optModuleDriver;
@Resource
OptModuleParamsMgr optModuleParamsMgr;
@ -43,4 +50,29 @@ public class OptScanModuleCtrlService {
stepMotorCtrlDriver.stepMotorEasyMoveToBlock(StepMotorMId.OptModScannerM, optModuleParamsMgr.getOptScanerScandbyPos(), overtime);
}
public Integer[] startOptScan(A8kOptType optType, OptScanDirection direction, Integer lasterGain, Integer scanGain) throws AppException {
Integer forwardScanPos = optModuleParamsMgr.getOptScanStartPos(optType);
switch (optType) {
case TOPT -> {
optModuleDriver.setReg(OptModuleRegIndex.kreg_a8k_opt_t_pos_offset, forwardScanPos);
optModuleDriver.setReg(OptModuleRegIndex.kreg_a8k_opt_t_reverse_scan_pos_offset, forwardScanPos - 1200);
optModuleDriver.setReg(OptModuleRegIndex.kreg_a8k_opt_scan_pointnum, 1200);
}
case FOPT -> {
optModuleDriver.setReg(OptModuleRegIndex.kreg_a8k_opt_f_pos_offset, forwardScanPos);
optModuleDriver.setReg(OptModuleRegIndex.kreg_a8k_opt_f_reverse_scan_pos_offset, forwardScanPos - 1200);
optModuleDriver.setReg(OptModuleRegIndex.kreg_a8k_opt_scan_pointnum, 1200);
}
}
switch (optType) {
case TOPT -> optModuleDriver.optTStartScan(direction, lasterGain, scanGain);
case FOPT -> optModuleDriver.optFStartScan(direction, lasterGain, scanGain);
}
return optModuleDriver.optReadRaw();
}
}

59
src/main/java/a8k/service/app/devicectrl/driver/OptModuleDriver.java

@ -0,0 +1,59 @@
package a8k.service.app.devicectrl.driver;
import a8k.hardware.A8kCanBusService;
import a8k.hardware.type.a8kcanprotocol.CmdId;
import a8k.hardware.type.a8kcanprotocol.MId;
import a8k.service.app.devicectrl.driver.type.OptModuleRegIndex;
import a8k.type.OptScanDirection;
import a8k.type.exception.AppException;
import a8k.utils.ByteArray;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Component
@Slf4j
public class OptModuleDriver {
static Integer actionOvertime = 10000;
@Resource
A8kCanBusService canBus;
public void optTStartScan(OptScanDirection scanDirection, Integer lasterGain, Integer scanGain) throws AppException {
canBus.callcmd(MId.OptMod, CmdId.a8k_opt_v2_t_start_scan, scanDirection.getInteger(), lasterGain, scanGain);
canBus.waitForMod(MId.OptMod, actionOvertime);
}
public void optFStartScan(OptScanDirection scanDirection, Integer lasterGain, Integer scanGain) throws AppException {
canBus.callcmd(MId.OptMod, CmdId.a8k_opt_v2_f_start_scan, scanDirection.getInteger(), lasterGain, scanGain);
canBus.waitForMod(MId.OptMod, actionOvertime);
}
public Integer[] optReadRaw() throws AppException {
int i = 0;
List<Integer> result = new ArrayList<>();
while (true) {
var rxPacket = canBus.callcmd(MId.OptMod, CmdId.a8k_opt_v2_read_raw, i++);
if (rxPacket.getCmdContent().length == 0) {
break;
}
var rawdata = ByteArray.readU16bitArray(rxPacket.getCmdContent());
result.addAll(Arrays.asList(rawdata));
}
return result.toArray(new Integer[0]);
}
public Integer readReg(OptModuleRegIndex regIndex) throws AppException {
return canBus.moduleGetReg(MId.OptMod, regIndex.regIndex);
}
public void setReg(OptModuleRegIndex regIndex, Integer value) throws AppException {
canBus.moduleSetReg(MId.OptMod, regIndex.regIndex, value);
}
}

18
src/main/java/a8k/service/app/devicectrl/driver/type/OptModuleRegIndex.java

@ -0,0 +1,18 @@
package a8k.service.app.devicectrl.driver.type;
import a8k.hardware.type.regindex.RegIndex;
public enum OptModuleRegIndex {
kreg_a8k_opt_t_pos_offset(RegIndex.kreg_a8k_opt_t_pos_offset),
kreg_a8k_opt_f_pos_offset(RegIndex.kreg_a8k_opt_f_pos_offset),
kreg_a8k_opt_t_reverse_scan_pos_offset(RegIndex.kreg_a8k_opt_t_reverse_scan_pos_offset),
kreg_a8k_opt_f_reverse_scan_pos_offset(RegIndex.kreg_a8k_opt_f_reverse_scan_pos_offset),
kreg_a8k_opt_scan_step_interval(RegIndex.kreg_a8k_opt_scan_step_interval),
kreg_a8k_opt_scan_pointnum(RegIndex.kreg_a8k_opt_scan_pointnum),
;
public final RegIndex regIndex;
OptModuleRegIndex(RegIndex regIndex) {
this.regIndex = regIndex;
}
}

4
src/main/java/a8k/service/app/devicectrl/exdriver/TubeTransportExDriver.java

@ -28,8 +28,6 @@ public class TubeTransportExDriver {
@Resource
MiniServoDriver miniServoDriver;
@Resource
TubeFeedingModuleParamMgr tubeScanPosMgr;
@Resource
StepMotorCtrlDriver stepMotorCtrlDriver;
@ -71,7 +69,6 @@ public class TubeTransportExDriver {
}
@ExtApiFn(name = "扫描夹紧机构夹紧", group = "基础方法", order = 1)
public void scanClampModClamp() throws AppException {
logger.info("扫描夹紧机构夹紧");
miniServoDriver.miniServoEnable(MiniServoMId.ShakeModTubeScanerClampingSV, 1);
@ -81,7 +78,6 @@ public class TubeTransportExDriver {
// canBus.waitForMod(MId.ShakeModTubeScanerClampingSV, overtime);
}
@ExtApiFn(name = "扫描夹紧机构复位", group = "基础方法", order = 2)
public void scanClampModRelease() throws AppException {
logger.info("扫描夹紧机构复位");
miniServoDriver.miniServoEnable(MiniServoMId.ShakeModTubeScanerClampingSV, 1);

165
src/main/java/a8k/service/app/devicectrl/param/calibration/OptModuleParamCalibration.java

@ -0,0 +1,165 @@
package a8k.service.app.devicectrl.param.calibration;
import a8k.extapi_controler.pagecontrol.ExtApiTabConfig;
import a8k.extapi_controler.utils.ExtApiFn;
import a8k.extapi_controler.utils.ExtApiTab;
import a8k.optalgo.A8kOptAlgoUtils;
import a8k.service.app.devicectrl.ctrlservice.OptScanModuleCtrlService;
import a8k.service.app.devicectrl.ctrlservice.PlateBoxCtrlService;
import a8k.service.app.devicectrl.driver.OptModuleDriver;
import a8k.service.app.devicectrl.driver.StepMotorCtrlDriver;
import a8k.service.app.devicectrl.driver.type.StepMotorMId;
import a8k.service.app.devicectrl.exdriver.MotorEnableExDriver;
import a8k.service.app.devicectrl.param.param_mgr.OptModuleParamsMgr;
import a8k.service.db.type.Parameter;
import a8k.service.db.type.a8kidcard.zenum.A8kOptType;
import a8k.type.*;
import a8k.type.exception.AppException;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
*
*
* 1.下面三个位置在ReactionPlatesTransmitControlerCalibration进行标定
* PullerTargetPos("拉板目标位置"),
* OptScanerDropPos("丢板坐标"),
* OptScanerScandbyPos("扫描待机位"),
*
* 2. 该模块只用来标定
* TOptScanStartPos (T光学扫描起始位置)
* FOptScanStartPos (F光学扫描起始位置)
*/
@ExtApiTab(cfg = ExtApiTabConfig.OptModuleParamCalibration)
@Component
public class OptModuleParamCalibration {
Integer actionOvertime = 5000;
@Resource
OptModuleParamsMgr optModuleParamsMgr;
@Resource
MotorEnableExDriver motorEnableExDriver;
@Resource
StepMotorCtrlDriver stepMotorCtrlDriver;
@Resource
PlateBoxCtrlService plateBoxCtrlService;
@Resource
OptScanModuleCtrlService optScanModuleCtrlService;
@Resource
OptModuleDriver optModuleDriver;
@ExtApiFn(name = "获得参数", group = "基础", order = 1)
public List<Parameter> getParams() throws AppException {
return optModuleParamsMgr.getParams();
}
@ExtApiFn(name = "归零", group = "测试工具", order = 11)
public void deviceReset() throws AppException {
enableModule();
//板夹仓初始化
stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.PlatesBoxYM, actionOvertime);
stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.PlatesBoxPusherM, actionOvertime);
//光学模组初始化
stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.OptModPullM, actionOvertime);
stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.OptModScannerM, actionOvertime);
//转盘归零
stepMotorCtrlDriver.stepMotorEasyMoveToZeroBlock(StepMotorMId.IncubatorRotateCtrlM, actionOvertime);
}
@ExtApiFn(name = "使能相关模块", group = "测试工具", order = 12)
public void enableModule() throws AppException {
motorEnableExDriver.enableAllMotor();
}
@ExtApiFn(name = "失能相关模块", group = "测试工具", order = 13)
public void disableModule() throws AppException {
motorEnableExDriver.forceDisableAllMotor();
}
//
// 辅助方法
//
/**
* From: 0号仓
* TrunablePos:0号仓到
*/
@ExtApiFn(name = "推板到光学模组", group = "测试工具", order = 100)
public void pushOnePlateToOptModule() throws AppException {
//先清空当前通道
optScanModuleCtrlService.dropPlate();
optScanModuleCtrlService.pullPlate(IncubatorPos.SPACE01);
optScanModuleCtrlService.dropPlate();
//推板到光学模组
plateBoxCtrlService.pushPlateQuick(ConsumableGroup.GROUP0, IncubatorPos.SPACE01);
optScanModuleCtrlService.pullPlate(IncubatorPos.SPACE01);
}
@ExtApiFn(name = "拉板到光学模组", group = "测试工具", order = 101)
public void dropPlate() throws AppException {
optScanModuleCtrlService.dropPlate();
}
// @ExtApiFn(name = "曲线显示测试", group = "测试工具", order = 102)
// public A8kScanCurve testCurveDisplay() {
// A8kScanCurve result = new A8kScanCurve();
// result.refCurve = List.of(40, 80, 120, 160, 200);
// result.scanDataCurve = new ArrayList<>();
// for (int i = 0; i < 250; i++) {
// result.scanDataCurve.add(i * 10);
// }
// return result;
// }
A8kScanCurve createScanCurve1200Point(Integer[] optScanResult) {
// Integer[] optScanResult250 = A8kOptAlgoUtils.supperSamplingAndSubSampling(optScanResult);
List<Integer> refCurve = new ArrayList<>();
for (int i = 1; i < 6; i++) {
refCurve.add((int) (40 * 4.8 * i));
}
var result = new A8kScanCurve();
result.refCurve = refCurve;
result.scanDataCurve = List.of(optScanResult);
return result;
}
@ExtApiFn(name = "设置光学扫描参考点", group = "设置", order = 200)
public void setCurrentAsScanRefPos() throws AppException {
stepMotorCtrlDriver.stepMotorEnable(StepMotorMId.OptModScannerM, 1);
Integer pos = stepMotorCtrlDriver.stepMotorReadPosByMoveToZeroBlock(StepMotorMId.OptModScannerM, 10000);
optModuleParamsMgr.setOptScanRefPos(pos);
}
@ExtApiFn(name = "设置F光学扫描偏移", group = "设置", order = 201)
public void setFOptScanShift(Integer shift) {
optModuleParamsMgr.setFOptScanShift(shift);
}
@ExtApiFn(name = "设置T光学扫描偏移", group = "设置", order = 202)
public void setTOptScanShift(Integer shift) {
optModuleParamsMgr.setTOptScanShift(shift);
}
@ExtApiFn(name = "F光学扫描", group = "扫描", order = 102)
public A8kScanCurve FOptScan(Integer lasterGain, Integer scanGain) throws AppException {
var result = optScanModuleCtrlService.startOptScan(A8kOptType.FOPT, OptScanDirection.FORWARD, lasterGain, scanGain);
return createScanCurve1200Point(result);
}
@ExtApiFn(name = "T光学扫描", group = "扫描", order = 102)
public A8kScanCurve TOptScan(Integer lasterGain, Integer scanGain) throws AppException {
var result = optScanModuleCtrlService.startOptScan(A8kOptType.TOPT, OptScanDirection.FORWARD, lasterGain, scanGain);
return createScanCurve1200Point(optModuleDriver.optReadRaw());
}
}

49
src/main/java/a8k/service/app/devicectrl/param/param_mgr/OptModuleParamsMgr.java

@ -2,6 +2,8 @@ package a8k.service.app.devicectrl.param.param_mgr;
import a8k.service.app.devicectrl.param.param_mgr.base.ParamMgr;
import a8k.service.db.type.a8kidcard.zenum.A8kOptType;
import a8k.type.OptScanDirection;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -11,7 +13,7 @@ import org.springframework.stereotype.Component;
* HBOT二维码扫描坐标参数
*/
@Component
public class OptModuleParamsMgr extends ParamMgr {
public class OptModuleParamsMgr extends ParamMgr {
static final Logger logger = LoggerFactory.getLogger(OptModuleParamsMgr.class);
@ -19,8 +21,9 @@ public class OptModuleParamsMgr extends ParamMgr {
PullerTargetPos("拉板目标位置"),
OptScanerDropPos("丢板坐标"),
OptScanerScandbyPos("扫描待机位"),
TOptScanStartPos("T光学扫描起始坐标"),
FOptScanStartPos("F光学扫描起始坐标"),
OptScanRefPos("光学扫描参考坐标"),
TOptScanShift("T光学扫描偏移"),
FOptScanShift("F光学扫描偏移"),
;
public final String chName;
@ -42,8 +45,9 @@ public class OptModuleParamsMgr extends ParamMgr {
setParam(POS.PullerTargetPos, 1147);
setParam(POS.OptScanerDropPos, -349);
setParam(POS.OptScanerScandbyPos, 305);
setParam(POS.TOptScanStartPos, 3723);
setParam(POS.FOptScanStartPos, 2559);
setParam(POS.OptScanerScandbyPos, 4000);
setParam(POS.TOptScanShift, 277);
setParam(POS.FOptScanShift, 1441);
}
public Integer getPullerTargetPos() {
@ -58,13 +62,6 @@ public class OptModuleParamsMgr extends ParamMgr {
return getParam(POS.OptScanerScandbyPos, Integer.class);
}
public Integer getTOptScanStartPos() {
return getParam(POS.TOptScanStartPos, Integer.class);
}
public Integer getFOptScanStartPos() {
return getParam(POS.FOptScanStartPos, Integer.class);
}
public void setPullerTargetPos(Integer pos) {
setParam(POS.PullerTargetPos, pos);
@ -78,12 +75,32 @@ public class OptModuleParamsMgr extends ParamMgr {
setParam(POS.OptScanerScandbyPos, pos);
}
public void setTOptScanStartPos(Integer pos) {
setParam(POS.TOptScanStartPos, pos);
public void setOptScanRefPos(Integer pos) {
setParam(POS.OptScanRefPos, pos);
}
public void setFOptScanStartPos(Integer pos) {
setParam(POS.FOptScanStartPos, pos);
public void setTOptScanShift(Integer pos) {
setParam(POS.TOptScanShift, pos);
}
public void setFOptScanShift(Integer pos) {
setParam(POS.FOptScanShift, pos);
}
public Integer getOptScanStartPos(A8kOptType type) {
Integer shift = switch (type) {
case TOPT -> getParam(POS.TOptScanShift, Integer.class);
case FOPT -> getParam(POS.FOptScanShift, Integer.class);
};
Integer scanStartPos = getParam(POS.OptScanRefPos, Integer.class);
scanStartPos = scanStartPos + shift;
return scanStartPos;
}
}

4
src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kOptType.java

@ -1,6 +1,6 @@
package a8k.service.db.type.a8kidcard.zenum;
public enum A8kOptType {
F,
T,
FOPT,
TOPT,
}

2
src/main/java/a8k/service/test/fakeproj/FakeProjInfo.java

@ -88,7 +88,7 @@ public class FakeProjInfo {
/*光学配置*/
projOptConfig.subProjName = String.format("%s_%d", projName, subIndex);
projOptConfig.subProjShortName = String.format("%s_%d", projShortName, subIndex);
projOptConfig.subProjOptType = A8kOptType.F;
projOptConfig.subProjOptType = A8kOptType.FOPT;
projOptConfig.subProjScanRange = 200;
projOptConfig.subProjScanDirection = OptScanDirection.Forward;
projOptConfig.subProjPeakNum = 3;

11
src/main/java/a8k/type/A8kScanCurve.java

@ -1,17 +1,14 @@
package a8k.type;
import java.util.ArrayList;
import java.util.List;
public class A8kScanCurve {
public List<Integer> scanDataCurve;
public List<Integer> refCurve;
public List<Integer> refLine;
public List<Integer> scanDataCurve = new ArrayList<>();
public List<Integer> refCurve = new ArrayList<>();
public List<Integer> refLine = new ArrayList<>();
public A8kScanCurve() {
}
public A8kScanCurve(List<Integer> scanDataCurve, List<Integer> refLine) {
this.scanDataCurve = scanDataCurve;
this.refLine = refLine;
}
}

5
src/main/java/a8k/type/OptScanDirection.java

@ -1,9 +1,10 @@
package a8k.type;
public enum OptScanDirection {
POSITIVE, NEGATIVE;
FORWARD, //从左向右扫描
BACKWARD;
public Integer getInteger() {
return this == POSITIVE ? 1 : -1;
return this == FORWARD ? 1 : -1;
}
}

21
src/main/java/a8k/type/appret/AppRet.java

@ -5,7 +5,7 @@ import a8k.hardware.type.a8kcanprotocol.A8kEcode;
import a8k.type.exception.AppException;
import lombok.Getter;
public class AppRet<T> {
public class AppRet {
public AppRetType appRetType = AppRetType.SUCCESS;
// 错误信息
public AppError ecode = null;
@ -15,7 +15,7 @@ public class AppRet<T> {
public String traceInfo = null;
// 携带的对象
public String dataType;
public T data;
public Object data;
// 接口请求时间
@Getter
@ -29,32 +29,33 @@ public class AppRet<T> {
return !AppRetType.FAILURE.equals(appRetType);
}
public static <T> AppRet<T> success(T data) {
AppRet<T> r = new AppRet<>();
public static <T> AppRet success(T data) {
AppRet r = new AppRet();
r.appRetType = AppRetType.SUCCESS;
r.data = data;
r.dataType = data.getClass().getSimpleName();
return r;
}
public static <T> AppRet<T> success() {
AppRet<T> r = new AppRet<>();
public static AppRet success() {
AppRet r = new AppRet();
r.appRetType = AppRetType.SUCCESS;
return r;
}
public static <T> AppRet<T> fail(Exception e) {
public static AppRet fail(Exception e) {
StringBuilder traceSb = new StringBuilder();
for (var trace : e.getStackTrace()) {
traceSb.append(trace.toString()).append("\n");
}
String trace = traceSb.toString();
AppRet<T> r = new AppRet<>();
AppRet r = new AppRet();
r.appRetType = AppRetType.FAILURE;
if (e instanceof AppException hexcep) {
r.ecode = hexcep.error;
r.ecode = hexcep.error;
} else {
r.ecode = new AppError(A8kEcode.CODEERROR);
r.ecode = new AppError(A8kEcode.CODEERROR);
}
r.traceInfo = trace;
r.message = e.getMessage();

Loading…
Cancel
Save