sige 2 years ago
parent
commit
f3f4af43ce
  1. 1
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java
  2. 1
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommand.java
  3. 8
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java
  4. 2
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTestcase.java
  5. 16
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTestcaseBase.java
  6. 11
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTestcaseInfo.java
  7. 72
      src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTestcaseManager.java
  8. 7
      src/src/main/java/com/my/graphiteDigesterBg/diframe/actuator/DiActServo.java
  9. 27
      src/src/main/java/com/my/graphiteDigesterBg/diframe/api/DiApiTest.java
  10. 4
      src/src/main/java/com/my/graphiteDigesterBg/move/MoveMoveTubeRackFromHeatPlateToLiquidPlate.java
  11. 4
      src/src/main/java/com/my/graphiteDigesterBg/move/MoveMoveTubeRackFromLiquidPlateToHeatPlate.java
  12. 15
      src/src/main/java/com/my/graphiteDigesterBg/move/MoveTubeToErrorRackSlot.java
  13. 33
      src/src/main/java/com/my/graphiteDigesterBg/task/TaskStartReset.java
  14. 72
      src/src/main/java/com/my/graphiteDigesterBg/testcase/TestcaseLocateEachTubeSlot.java
  15. 2
      src/src/main/java/com/my/graphiteDigesterBg/testcase/TestcasePeristalticPumpTest.java
  16. 2
      src/src/main/resources/application.yml
  17. 7
      src/src/main/resources/device.yml

1
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java

@ -15,6 +15,7 @@ public class DiApplicationRunner implements ApplicationRunner {
this.device.getRegisters().setup();
this.device.getActuators().setup();
this.device.getIO().setup();
this.device.getTestcases().setup();
this.device.getTaskManager().scanTaskClasses("com.my.graphiteDigesterBg.task");
this.device.getTaskManager().scanTaskStepClasses("com.my.graphiteDigesterBg.step");

1
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiCommand.java

@ -10,6 +10,7 @@ public enum DiCommand {
MOTOR_EASY_MOVE_BY("motor_easy_move_by", 0x0212),
MOTOR_EASY_MOVE_TO("motor_easy_move_to", 0x0213),
MOTOR_EASY_MOVE_TO_ZERO("motor_easy_move_to_zero", 0x0214),
MOTOR_EASY_SET_CURRENT_POS("motor_easy_set_current_pos", 0x0215),
MOTOR_EASY_MOVE_TO_IO("motor_easy_move_to_io", 0x0216);
// command name

8
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java

@ -37,6 +37,8 @@ public class DiDevice {
private DiDeviceRuntimeVariableManager runtimeVariables;
// message index
private short messageIndex = 0;
// testcase manager
private DiTestcaseManager testcaseManager;
@PostConstruct
public void init() {
@ -50,6 +52,7 @@ public class DiDevice {
this.resource = new DiDeviceResourceManager(this);
this.taskManager = new DiTaskManager(this);
this.runtimeVariables = new DiDeviceRuntimeVariableManager();
this.testcaseManager = new DiTestcaseManager(this);
}
// load device.yml
@ -144,6 +147,11 @@ public class DiDevice {
return this.runtimeVariables;
}
// get testcase manager
public DiTestcaseManager getTestcases() {
return this.testcaseManager;
}
// get config
public String getConfig( String path ) {
String[] parts = path.split("\\.");

2
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTestcase.java

@ -2,4 +2,6 @@ package com.my.graphiteDigesterBg.diframe;
public interface DiTestcase {
// execute testcase
void run();
void setDevice(DiDevice device);
}

16
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTestcaseBase.java

@ -3,7 +3,7 @@ abstract public class DiTestcaseBase implements DiTestcase {
// device
private DiDevice device;
// set device
@Override
public void setDevice(DiDevice device) {
this.device = device;
}
@ -28,4 +28,18 @@ abstract public class DiTestcaseBase implements DiTestcase {
DiActuator actuator = this.getDevice().getActuators().get(actuatorKey);
return clazz.cast(actuator);
}
// assert equal
public void assertEqual( Object expected, Object actual ) {
if ( !expected.equals(actual) ) {
throw new RuntimeException("expected: " + expected + ", actual: " + actual);
}
}
// assert not equal
public void assertNotEqual( Object expected, Object actual ) {
if ( expected.equals(actual) ) {
throw new RuntimeException("expected: " + expected + ", actual: " + actual);
}
}
}

11
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTestcaseInfo.java

@ -0,0 +1,11 @@
package com.my.graphiteDigesterBg.diframe;
public class DiTestcaseInfo {
// name
public String name;
// title
public String title;
// description
public String description;
// class
public Class<?> clazz;
}

72
src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTestcaseManager.java

@ -0,0 +1,72 @@
package com.my.graphiteDigesterBg.diframe;
import com.my.graphiteDigesterBg.diframe.util.DiClassHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DiTestcaseManager {
// logger
public static final Logger LOG = LoggerFactory.getLogger(DiTestcaseManager.class);
// device
private final DiDevice device;
// testcase classes
private final Map<String, DiTestcaseInfo> testcasees;
// constructor
public DiTestcaseManager(DiDevice device) {
this.device = device;
this.testcasees = new HashMap<>();
}
// setup
public void setup() {
var options = (Map<String,Object>)this.device.getConfig().get("testcase");
var packageNames = (List<String>)options.get("packages");
for ( String packageName : packageNames ) {
List<Class<?>> testClasses = DiClassHelper.getAllClassesInPackage(packageName);
for ( Class<?> testClass : testClasses ) {
if ( DiTestcaseBase.class.isAssignableFrom(testClass) ) {
Testcase testcaseAnnotation = testClass.getAnnotation(Testcase.class);
if ( testcaseAnnotation != null ) {
var info = new DiTestcaseInfo();
info.name = testcaseAnnotation.name();
info.title = testcaseAnnotation.title();
info.description = testcaseAnnotation.description();
info.clazz = testClass;
this.testcasees.put(testcaseAnnotation.name(), info);
LOG.info("(Testcase) {} => {}", testcaseAnnotation.name(), testClass.getName());
}
}
}
}
}
// execute testcase by name
public void execute( String name ) {
var info = this.testcasees.get(name);
if ( info == null ) {
throw new RuntimeException("Testcase not found: " + name);
}
Constructor<?> constructor = null;
try {
constructor = info.clazz.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
DiTestcase testcase = null;
try {
testcase = (DiTestcase)constructor.newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
testcase.setDevice(this.device);
testcase.run();
}
}

7
src/src/main/java/com/my/graphiteDigesterBg/diframe/actuator/DiActServo.java

@ -32,7 +32,8 @@ public class DiActServo extends DiActuatorBase {
this.waitForFinish();
}
public void moveBy( Integer delta ) {}
public void rotate( Integer direction ) {}
public void stop() {}
// set current position as middle
public void setCurrentPosAsMiddle() {
this.call(DiCommand.MOTOR_EASY_SET_CURRENT_POS, 2047);
}
}

27
src/src/main/java/com/my/graphiteDigesterBg/diframe/api/DiApiTest.java

@ -0,0 +1,27 @@
package com.my.graphiteDigesterBg.diframe.api;
import com.my.graphiteDigesterBg.diframe.DiApiControllerBase;
import com.my.graphiteDigesterBg.diframe.DiApiResponse;
import com.my.graphiteDigesterBg.diframe.DiDevice;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
@Controller
public class DiApiTest extends DiApiControllerBase {
@Resource
private DiDevice device;
@ResponseBody
@PostMapping("/api/test/execute")
public DiApiResponse execute(@RequestBody Map<String,Object> params ) {
String name = (String)params.get("name");
try {
this.device.getTestcases().execute(name);
} catch (Exception e) {
return this.error(e.getMessage());
}
return this.success();
}
}

4
src/src/main/java/com/my/graphiteDigesterBg/move/MoveMoveTubeRackFromHeatPlateToLiquidPlate.java

@ -24,7 +24,7 @@ public class MoveMoveTubeRackFromHeatPlateToLiquidPlate extends DiTaskMoveBase {
// 加热盘转盘移动到取放架位置
heatPlateMotor.moveTo("HeatPlateSlot", this.slotIndex);
// 打开试管架盖
slotCoverServo.moveTo("HeatPlateSlotCoverOpen", this.slotIndex);
slotCoverServo.moveTo("HeatPlateSlotCoverOpen");
// 搬运上升到顶部
transUdMotor.moveTo("TransUdMotorTop");
// 搬运移动到加热取架位置
@ -46,7 +46,7 @@ public class MoveMoveTubeRackFromHeatPlateToLiquidPlate extends DiTaskMoveBase {
// 搬运上升到顶部
transUdMotor.moveTo("TransUdMotorTop");
// 关闭试管架盖
slotCoverServo.moveTo("HeatPlateSlotCoverClose", this.slotIndex);
slotCoverServo.moveTo("HeatPlateSlotCoverClose");
// 搬运移动到就绪位置
transLrMotor.moveTo("TransLrMotorStandby");
// 加热盘移动到就绪位置

4
src/src/main/java/com/my/graphiteDigesterBg/move/MoveMoveTubeRackFromLiquidPlateToHeatPlate.java

@ -35,7 +35,7 @@ public class MoveMoveTubeRackFromLiquidPlateToHeatPlate extends DiTaskMoveBase {
heatPlateMotor.moveTo("HeatPlateSlot", this.slotIndex);
// 打开试管架盖
slotCoverServo.moveTo("HeatPlateSlotCoverOpen", this.slotIndex);
slotCoverServo.moveTo("HeatPlateSlotCoverOpen");
// 搬运移动到加热盘取放位置
transLrMotor.moveTo("TransLrMotorHeatPlateSlot");
@ -49,7 +49,7 @@ public class MoveMoveTubeRackFromLiquidPlateToHeatPlate extends DiTaskMoveBase {
transLrMotor.moveTo("TransLrMotorStandby");
// 试管架盖关闭
slotCoverServo.moveTo("HeatPlateSlotCoverClose", this.slotIndex);
slotCoverServo.moveTo("HeatPlateSlotCoverClose");
heatPlateMotor.moveTo("HeatPlateStandby");
liquidPlateMotor.moveTo("LiquidPlateStandby");

15
src/src/main/java/com/my/graphiteDigesterBg/move/MoveTubeToErrorRackSlot.java

@ -31,7 +31,7 @@ public class MoveTubeToErrorRackSlot extends DiTaskMoveBase {
heatPlateMotor.moveTo(heatPlateSlotLocation + heatPlateSlotTubeOffset);
// 打开试管架盖
srcSlotCoverServo.moveTo("HeatPlateSlotCoverOpen", this.srcSlotIndex);
srcSlotCoverServo.moveTo("HeatPlateSlotCoverOpen");
// 搬运左右移动到试管位置
Integer transLrMotorHeatPlateSlotLocation = transLrMotor.getLocationValue("TransLrMotorHeatPlateSlot");
@ -54,7 +54,7 @@ public class MoveTubeToErrorRackSlot extends DiTaskMoveBase {
transLrMotor.moveTo("TransLrMotorStandby");
// 试管架盖关闭
srcSlotCoverServo.moveTo("HeatPlateSlotCoverClose", this.srcSlotIndex);
srcSlotCoverServo.moveTo("HeatPlateSlotCoverClose");
// 错误准备
var slotMan = this.getResourceManager(ResHeatingTubeRackSlotManager.class);
@ -64,19 +64,16 @@ public class MoveTubeToErrorRackSlot extends DiTaskMoveBase {
// 加热盘移动到试管位置
Integer errorHeatPlateSlotLocation = heatPlateMotor.getLocationValue("HeatPlateSlot", errorSlot.index);
Integer errorHeatPlateSlotTubeOffset = heatPlateMotor.getLocationValue("HeatPlateSlotTubeOffset", errorSlot.index);
// heatPlateMotor.moveTo(errorHeatPlateSlotLocation + errorHeatPlateSlotTubeOffset);
// @TODO : 这个是临时的 ~~~ 上面的数值计算错误 ~~~ 因为先找抓取位置然后再找放置位置是正确的 ~~~
heatPlateMotor.moveTo(2700);
Integer errorHeatPlateSlotTubeOffset = heatPlateMotor.getLocationValue("HeatPlateSlotTubeOffset", this.errorTubeIndex);
heatPlateMotor.moveTo(errorHeatPlateSlotLocation + errorHeatPlateSlotTubeOffset);
// 打开试管架盖
errSlotCoverServo.moveTo("HeatPlateSlotCoverOpen", errorSlot.index);
errSlotCoverServo.moveTo("HeatPlateSlotCoverOpen");
// 搬运左右移动到试管位置
transLrMotorTubeOffset = transLrMotor.getLocationValue("TransLrMotorTubeOffset", this.errorTubeIndex);
transLrMotor.moveTo(transLrMotorHeatPlateSlotLocation + transLrMotorTubeOffset);
// 升降下降到试管位置
transUdMotor.moveTo("TransUdMotorTubeClip");
@ -93,7 +90,7 @@ public class MoveTubeToErrorRackSlot extends DiTaskMoveBase {
transLrMotor.moveTo("TransLrMotorStandby");
// 试管架盖关闭
errSlotCoverServo.moveTo("HeatPlateSlotCoverClose", errorSlot.index);
errSlotCoverServo.moveTo("HeatPlateSlotCoverClose");
// 加热盘移动到就绪位置
heatPlateMotor.moveTo("HeatPlateStandby");

33
src/src/main/java/com/my/graphiteDigesterBg/task/TaskStartReset.java

@ -12,64 +12,77 @@ public class TaskStartReset extends DiTaskBase {
var runtimeVars = this.getDevice().getRuntimeVariables();
runtimeVars.set("IsDeviceReady", "NO");
runtimeVars.set("IsTaskStartResetExecuting", "YES");
this.setProgressMessage("设备初始化...");
// 门电机
this.setProgressMessage("设备初始化 : 关闭设备门");
DiActMotor doorMotor = this.getActuator(MyDevice.ACT_DOOR_MOTOR, DiActMotor.class);
doorMotor.setEnable(true);
doorMotor.moveToIO(1, 1);
// 试管夹爪舵机
this.setProgressMessage("设备初始化 : 关闭夹爪");
DiActServo transferClipServo = this.getActuator(MyDevice.ACT_TRANSFER_CLIP_SERVO, DiActServo.class);
transferClipServo.setEnable(true);
transferClipServo.moveTo("TransClipServoClose");
// 加液机械臂启用并复位
this.setProgressMessage("设备初始化 : 加液臂复位");
DiActMotor liquidMotor = this.getActuator(MyDevice.ACT_LIQUID_MOTOR, DiActMotor.class);
liquidMotor.setEnable(true);
liquidMotor.reset();
liquidMotor.moveTo("LiquidArmStandby");
// @TODO: 这里要先手动移动到一个安全位置
// @todo http://127.0.0.1:5566/issues/38
this.setProgressMessage("设备初始化 : 搬运机械臂上下移动复位");
DiActMotor transUdMotor = this.getActuator(MyDevice.ACT_TRANSFER_UD_MOTOR, DiActMotor.class);
transUdMotor.setEnable(true);
transUdMotor.reset();
transUdMotor.moveTo("TransUdMotorStandby");
// 搬运机械臂左右移动初始化
this.setProgressMessage("设备初始化 : 搬运机械臂左右移动复位");
DiActMotor transLrMotor = this.getActuator(MyDevice.ACT_TRANSFER_LR_MOTOR, DiActMotor.class);
transLrMotor.setEnable(true);
transLrMotor.reset();
transLrMotor.moveTo("TransLrMotorStandby");
// 初始化加热盘盖舵机
for ( int i=0; i<5; i++ ) {
this.setProgressMessage("设备初始化 : 加热盘转盘槽盖关闭 " + (i+1) + "/5");
String key = "HeatingPlateMotorSlotCover_" + i;
DiActServo heatSlotCoverServo = this.getActuator(key, DiActServo.class);
heatSlotCoverServo.setEnable(true);
heatSlotCoverServo.moveTo("HeatPlateSlotCoverClose", i);
heatSlotCoverServo.setCurrentPosAsMiddle();
}
// 加液转盘
// @TODO : http://127.0.0.1:5566/issues/39
this.setProgressMessage("设备初始化 : 加液转盘复位");
DiActMotor liquidPlateMotor = this.getActuator(MyDevice.ACT_LIQUID_PLATE_MOTOR, DiActMotor.class);
liquidPlateMotor.setEnable(true);
liquidPlateMotor.reset();
// 加热盘转盘
// @TODO : http://127.0.0.1:5566/issues/40
this.setProgressMessage("设备初始化 : 加热盘转盘复位");
DiActMotor heatPlateMotor = this.getActuator(MyDevice.ACT_HEAT_PLATE_MOTOR, DiActMotor.class);
heatPlateMotor.setEnable(true);
heatPlateMotor.reset();
heatPlateMotor.moveTo("HeatPlateStandby");
// 蠕动泵初始化
int peristalticPumpCount = 1;
var actuators = this.getDevice().getActuators().getAll();
for ( var actuator : actuators ) {
if (actuator instanceof DiActPeristalticPump pump) {
this.setProgressMessage("设备初始化 : 蠕动泵复位 " + peristalticPumpCount + "/16");
pump.setEnable(true);
peristalticPumpCount++;
}
}
this.setProgressMessage("设备初始化 : 完成");
runtimeVars.set("IsDeviceReady", "YES");
runtimeVars.set("IsTaskStartResetExecuting", "NO");
this.setStatus(TaskStatus.FINISHED);
}
// set progress message
private void setProgressMessage(String message) {
var runtimeVars = this.getDevice().getRuntimeVariables();
runtimeVars.set("TaskStartResetMessage", message);
}
}

72
src/src/main/java/com/my/graphiteDigesterBg/testcase/TestcaseLocateEachTubeSlot.java

@ -0,0 +1,72 @@
package com.my.graphiteDigesterBg.testcase;
import com.my.graphiteDigesterBg.MyDevice;
import com.my.graphiteDigesterBg.diframe.DiTestcaseBase;
import com.my.graphiteDigesterBg.diframe.Testcase;
import com.my.graphiteDigesterBg.diframe.actuator.DiActMotor;
import com.my.graphiteDigesterBg.diframe.actuator.DiActServo;
@Testcase(
name="LocateEachTubeSlot",
title="测试每个试管孔定位情况",
description="测试时,需要将第一个试管孔位放置一个试管,用于观察定位情况"
)
public class TestcaseLocateEachTubeSlot extends DiTestcaseBase {
@Override
public void run() {
var heatPlateMotor = this.getActuator(MyDevice.ACT_HEAT_PLATE_MOTOR, DiActMotor.class);
heatPlateMotor.setEnable(true);
heatPlateMotor.reset();
var transUdMotor = this.getActuator(MyDevice.ACT_TRANSFER_UD_MOTOR, DiActMotor.class);
transUdMotor.setEnable(true);
transUdMotor.reset();
transUdMotor.moveTo("TransUdMotorStandby");
var transLrMotor = this.getActuator(MyDevice.ACT_TRANSFER_LR_MOTOR, DiActMotor.class);
transLrMotor.setEnable(true);
transLrMotor.reset();
transLrMotor.moveTo("TransLrMotorStandby");
for ( int i=0; i<5; i++ ) {
String key = "HeatingPlateMotorSlotCover_" + i;
DiActServo heatSlotCoverServo = this.getActuator(key, DiActServo.class);
heatSlotCoverServo.setEnable(true);
heatSlotCoverServo.setCurrentPosAsMiddle();
}
// 从第一个试管孔位取试管
for ( int tubeSlotIndex=0; tubeSlotIndex<16;tubeSlotIndex++ ) {
for ( int rackSlotIndex=0; rackSlotIndex<5; rackSlotIndex++ ) {
var coverKey = "HeatingPlateMotorSlotCover_" + rackSlotIndex;
var heatSlotCoverServo = this.getActuator(coverKey, DiActServo.class);
heatSlotCoverServo.moveTo("HeatPlateSlotCoverOpen");
// 计算孔位
var rackPickUpLocation = heatPlateMotor.getLocationValue("HeatPlateSlot", rackSlotIndex);
var tubePickUpOffset = heatPlateMotor.getLocationValue("HeatPlateSlotTubeOffset", tubeSlotIndex);
heatPlateMotor.moveTo(rackPickUpLocation + tubePickUpOffset);
// 左右移动到试管孔位
var transLrRackPickUpLocation = transLrMotor.getLocationValue("TransLrMotorHeatPlateSlot");
var transLrTubePickUpOffset = transLrMotor.getLocationValue("TransLrMotorTubeOffset", tubeSlotIndex);
transLrMotor.moveTo(transLrRackPickUpLocation + transLrTubePickUpOffset);
// 上下移动到试管预备位
transUdMotor.moveTo(300);
transUdMotor.moveTo("TransUdMotorTubeClip");
// 完成单次
// 上下移动到顶部
transUdMotor.moveTo("TransUdMotorTop");
// 左右移动到就绪位
transLrMotor.moveTo("TransLrMotorStandby");
// 关闭试管孔位盖
heatSlotCoverServo.moveTo("HeatPlateSlotCoverClose");
}
}
transUdMotor.moveTo("TransUdMotorStandby");
transLrMotor.moveTo("TransLrMotorStandby");
heatPlateMotor.moveTo("HeatPlateStandby");
heatPlateMotor.setEnable(false);
}
}

2
src/src/main/java/com/my/graphiteDigesterBg/testcase/TestcasePeristalticPumpTest.java

@ -1,8 +1,6 @@
package com.my.graphiteDigesterBg.testcase;
import com.my.graphiteDigesterBg.diframe.DiTestcaseBase;
import com.my.graphiteDigesterBg.diframe.Testcase;
import com.my.graphiteDigesterBg.diframe.actuator.DiActPeristalticPump;
@Testcase(
name="PeristalticPumpTest",
title="测试每个蠕动泵旋转情况",

2
src/src/main/resources/application.yml

@ -6,4 +6,4 @@ spring:
encoding: utf-8
app :
errorSlotIndex : 1
errorSlotIndex : 4

7
src/src/main/resources/device.yml

@ -11,6 +11,11 @@ connection :
# mode : hex
# callTimeout : 3000
# device actuators
testcase :
packages :
- com.my.graphiteDigesterBg.testcase
actuators :
- name : 加热盘电机
key : HeatingPlateMotor
@ -73,7 +78,7 @@ actuators :
defaultVelocity : 300
defaultAcc : 100
defaultDec : 100
runToZeroSpeed : 100
runToZeroSpeed : 300
runToZeroDec : 100
lookZeroEdgeSpeed : 25
lookZeroEdgeDec : 100

Loading…
Cancel
Save