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
-
49src/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
-
21src/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; |
package a8k.service.db.type.a8kidcard.zenum; |
||||
|
|
||||
public enum A8kOptType { |
public enum A8kOptType { |
||||
F, |
|
||||
T, |
|
||||
|
FOPT, |
||||
|
TOPT, |
||||
} |
} |
@ -1,17 +1,14 @@ |
|||||
package a8k.type; |
package a8k.type; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
import java.util.List; |
import java.util.List; |
||||
|
|
||||
public class A8kScanCurve { |
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() { |
||||
} |
} |
||||
|
|
||||
public A8kScanCurve(List<Integer> scanDataCurve, List<Integer> refLine) { |
|
||||
this.scanDataCurve = scanDataCurve; |
|
||||
this.refLine = refLine; |
|
||||
} |
|
||||
} |
} |
@ -1,9 +1,10 @@ |
|||||
package a8k.type; |
package a8k.type; |
||||
|
|
||||
public enum OptScanDirection { |
public enum OptScanDirection { |
||||
POSITIVE, NEGATIVE; |
|
||||
|
FORWARD, //从左向右扫描 |
||||
|
BACKWARD; |
||||
|
|
||||
public Integer getInteger() { |
public Integer getInteger() { |
||||
return this == POSITIVE ? 1 : -1; |
|
||||
|
return this == FORWARD ? 1 : -1; |
||||
} |
} |
||||
} |
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue