22 changed files with 630 additions and 428 deletions
-
BINapp.db
-
2src/main/java/a8k/AppControlerExceptionProcesser.java
-
6src/main/java/a8k/constant/OptConstant.java
-
22src/main/java/a8k/extapi_controler/ExtApiControler.java
-
2src/main/java/a8k/extapi_controler/pagecontrol/ExtApiTabConfig.java
-
30src/main/java/a8k/hardware/A8kCanBusService.java
-
2src/main/java/a8k/optalgo/A8kOptAlgo.java
-
36src/main/java/a8k/optalgo/A8kOptAlgoUtils.java
-
106src/main/java/a8k/optalgo/OptAlgoUtils.java
-
8src/main/java/a8k/service/app/appctrl/mainflowctrl/action/PLATE_OPT_SCAN.java
-
32src/main/java/a8k/service/app/devicectrl/ctrlservice/OptScanModuleCtrlService.java
-
59src/main/java/a8k/service/app/devicectrl/driver/OptModuleDriver.java
-
18src/main/java/a8k/service/app/devicectrl/driver/type/OptModuleRegIndex.java
-
4src/main/java/a8k/service/app/devicectrl/exdriver/TubeTransportExDriver.java
-
165src/main/java/a8k/service/app/devicectrl/param/calibration/OptModuleParamCalibration.java
-
47src/main/java/a8k/service/app/devicectrl/param/param_mgr/OptModuleParamsMgr.java
-
4src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kOptType.java
-
2src/main/java/a8k/service/test/fakeproj/FakeProjInfo.java
-
11src/main/java/a8k/type/A8kScanCurve.java
-
5src/main/java/a8k/type/OptScanDirection.java
-
17src/main/java/a8k/type/appret/AppRet.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; |
|||
} |
@ -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); |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
} |
@ -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); |
|||
} |
|||
|
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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()); |
|||
} |
|||
|
|||
} |
@ -1,6 +1,6 @@ |
|||
package a8k.service.db.type.a8kidcard.zenum; |
|||
|
|||
public enum A8kOptType { |
|||
F, |
|||
T, |
|||
FOPT, |
|||
TOPT, |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue