Browse Source

添加停止重置操作

master
sige 2 years ago
parent
commit
53e8c81b53
  1. 3
      src/main/java/com/dreamworks/boditech/driver/Device.java
  2. 5
      src/main/java/com/dreamworks/boditech/driver/actuator/ActIncubator.java
  3. 8
      src/main/java/com/dreamworks/boditech/driver/actuator/ActMotor.java
  4. 14
      src/main/java/com/dreamworks/boditech/driver/actuator/ActPipette.java
  5. 7
      src/main/java/com/dreamworks/boditech/driver/actuator/ActuatorBase.java
  6. 117
      src/main/java/com/dreamworks/boditech/driver/task/TaskReset.java
  7. 157
      src/main/java/com/dreamworks/boditech/driver/task/TaskStartReset.java
  8. 9
      src/main/java/com/dreamworks/boditech/driver/task/TaskStopReset.java
  9. 15
      src/main/java/com/dreamworks/boditech/driver/task/step/StepPretreatment.java
  10. 12
      src/main/java/com/dreamworks/boditech/mapper/RuntimeVariableMapper.java
  11. 45
      src/main/java/com/dreamworks/boditech/service/DeviceService.java
  12. 33
      src/main/java/com/dreamworks/boditech/service/RuntimeVariableService.java

3
src/main/java/com/dreamworks/boditech/driver/Device.java

@ -7,6 +7,7 @@ import com.dreamworks.boditech.mapper.DeviceLogMapper;
import com.dreamworks.boditech.mapper.ProjectMapper;
import com.dreamworks.boditech.service.ProjectService;
import com.dreamworks.boditech.service.RuntimeOptionService;
import com.dreamworks.boditech.service.RuntimeVariableService;
import com.dreamworks.boditech.utils.MyByteBuffer;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
@ -36,6 +37,8 @@ public class Device {
public ProjectService projectService;
@Resource
public DeviceLogMapper deviceLogMapper;
@Resource
public RuntimeVariableService runtimeVariableService;
// consumable : test cards
public final CsmTestCardManager testCards = new CsmTestCardManager(this);

5
src/main/java/com/dreamworks/boditech/driver/actuator/ActIncubator.java

@ -28,6 +28,11 @@ public class ActIncubator extends ActMotor {
return null;
}
// get slot by index
public IncubatorSlot getSlotByIndex( int index ) {
return this.slots[index];
}
// lock slot
public void lockSlot( int index ) {
this.slots[index].isFree = false;

8
src/main/java/com/dreamworks/boditech/driver/actuator/ActMotor.java

@ -3,6 +3,8 @@ import com.dreamworks.boditech.driver.DeviceCommand;
import com.dreamworks.boditech.driver.Device;
import com.dreamworks.boditech.driver.DeviceRegister;
import java.nio.ByteBuffer;
public class ActMotor extends ActuatorBase {
// rotate direction
public static final int ROTATE_DIRECTION_CLOCKWISE = 1;
@ -34,7 +36,11 @@ public class ActMotor extends ActuatorBase {
// move to given position
public void moveTo(int position) {
this.call(DeviceCommand.CMD_MOTOR_EASY_MOVE_TO, position);
ByteBuffer response = this.call(DeviceCommand.CMD_MOTOR_EASY_MOVE_TO, position);
if ( null == response ) {
this.moveTo(position);
return ;
}
this.waitForFinish();
}

14
src/main/java/com/dreamworks/boditech/driver/actuator/ActPipette.java

@ -2,11 +2,9 @@ package com.dreamworks.boditech.driver.actuator;
import com.dreamworks.boditech.driver.DeviceCommand;
import com.dreamworks.boditech.driver.Device;
import com.dreamworks.boditech.driver.consumable.CsmPipetteTip;
public class ActPipette extends ActuatorBase {
// indicate whether the pipette has tip
// @TODO : this should be false by default
private boolean hasTip = true;
// has tip
private Boolean hasTip = false;
// constructor
public ActPipette(Integer mid, Device device) {
@ -24,7 +22,10 @@ public class ActPipette extends ActuatorBase {
this.hasTip = true;
}
// drop tip
/**
* drop tip to discard hole, and move arm z to 0, it would not
* move arm xy to any position after drop tip.
*/
public void dropTip () {
ActArmXY armXY = (ActArmXY)this.getDevice().getActuator(ActuatorModule.ARM_XY);
ActMotor armZMotor = (ActMotor)this.getDevice().getActuator(ActuatorModule.ARM_Z_MOTOR);
@ -33,10 +34,11 @@ public class ActPipette extends ActuatorBase {
armZMotor.moveTo("tipDiscardDepth");
armXY.moveTo("tipDiscardDrop");
armZMotor.moveTo(0);
this.hasTip = false;
}
// get whether the pipette has tip
public boolean getHasTip() {
public Boolean getHasTip() {
return this.hasTip;
}

7
src/main/java/com/dreamworks/boditech/driver/actuator/ActuatorBase.java

@ -1,6 +1,8 @@
package com.dreamworks.boditech.driver.actuator;
import com.dreamworks.boditech.driver.DeviceCommand;
import com.dreamworks.boditech.driver.Device;
import com.dreamworks.boditech.service.RuntimeVariableService;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Objects;
@ -9,11 +11,14 @@ public class ActuatorBase implements Actuator {
private final Device device;
// mid
private final Integer mid;
// runtime variables
protected RuntimeVariableService runtimeVariables;
// constructor
public ActuatorBase(Integer mid, Device device) {
this.mid = mid;
this.device = device;
this.runtimeVariables = device.runtimeVariableService;
}
// get device
@ -26,6 +31,8 @@ public class ActuatorBase implements Actuator {
return mid;
}
// call device command
protected ByteBuffer call(Integer cmd, Object ... params) {
return this.getDevice().call(cmd, this.getMid(), params);

117
src/main/java/com/dreamworks/boditech/driver/task/TaskReset.java

@ -1,117 +0,0 @@
package com.dreamworks.boditech.driver.task;
import com.dreamworks.boditech.driver.Device;
import com.dreamworks.boditech.driver.DeviceRegister;
import com.dreamworks.boditech.driver.actuator.ActArmXY;
import com.dreamworks.boditech.driver.actuator.ActIncubator;
import com.dreamworks.boditech.driver.actuator.ActMotor;
import com.dreamworks.boditech.driver.actuator.ActuatorModule;
import com.dreamworks.boditech.driver.entity.IncubatorSlot;
import java.util.Objects;
public class TaskReset extends TaskBase {
// mode : normal
public static final Integer MODE_NORMAL = 0;
// mode : error
public static final Integer MODE_ERROR = 1;
// reset mode
public Integer mode = MODE_NORMAL;
@Override
public void execute(Executor executor) {
Device device = executor.getDevice();
//01. 试管夹复位
ActMotor testTubeShakingClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CLIP_MOTOR);
testTubeShakingClipMotor.reset();
// 02. 试管夹旋转复位
ActMotor testTubeShakingClipRotateMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_ROTATE_MOTOR);
testTubeShakingClipRotateMotor.reset();
// 03. 机械臂Z轴复位
ActMotor armZMotor = (ActMotor)device.getActuator(ActuatorModule.ARM_Z_MOTOR);
armZMotor.reset();
// 04. 机械臂XY轴复位
ActArmXY armXY = (ActArmXY)device.getActuator(ActuatorModule.ARM_XY);
armXY.reset();
// 错误模式下可能还有TIP未丢弃
if (Objects.equals(this.mode, TaskReset.MODE_ERROR)) {
armXY.moveTo("tipDiscardPrepareHole");
armZMotor.moveTo("tipDiscardDepth");
armXY.moveTo("tipDiscardDrop");
armZMotor.reset();
}
// 05. 摇匀电机复位
// @TODO : 摇匀电机没有零点暂时没法复位
// 06. 试管帽夹复位
ActMotor testTubeShakingCapClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CAP_CLIP_MOTOR);
testTubeShakingCapClipMotor.moveTo("testTubeShakingCapClipClose");
// 07. 摇匀升降电机复位
// @TODO : 升降电机需要向上复位但是目前没有更新所以暂时不复位
ActMotor testTubeShakingMoveMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_MOVE_MOTOR);
// testTubeShakingMoveMotor.reset();
if ( Objects.equals(this.mode, TaskReset.MODE_ERROR) ) {
// 出错的情况下这个时候可能还存在试管需要把试管放回到试管架上
testTubeShakingMoveMotor.moveTo("testTubeShakingCapPickUp");
testTubeShakingCapClipMotor.moveTo("testTubeShakingCapClipOpen");
testTubeShakingMoveMotor.moveTo("testTubeShakingUpDownStandBy");
testTubeShakingCapClipMotor.moveTo("testTubeShakingCapClipClose");
}
// 08. 试管架电机复位
ActMotor testTubeRackMoveMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_RACK_MOVE_MOTOR);
testTubeRackMoveMotor.reset();
testTubeRackMoveMotor.moveTo("testTubeRackExitPrepare");
testTubeRackMoveMotor.moveTo("testTubeRackExit");
ActMotor testTubeRackExitMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_RACK_EXIT_MOTOR);
testTubeRackExitMotor.moveBy(500);
testTubeRackMoveMotor.reset();
// 09. 板夹仓推杆电机复位
ActMotor testCardFeedMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_CARD_FEED_MOTOR);
// @TODO : 检查是否存在试管正在被从板夹仓推出
// @TODO : 读取试管夹二次验证相机数据判断是否存在上述情况
boolean hasTestCardInFeedRack = true;
if ( hasTestCardInFeedRack ) {
testCardFeedMotor.moveToPoint(ActMotor.POINT_END);
}
testCardFeedMotor.reset();
testCardFeedMotor.moveTo("testCardFeedStandBy");
// 10. 板夹仓复位
ActMotor testCardBoxMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_CARD_BOX_MOTOR);
testCardBoxMotor.reset();
// 11. 光学扫描电机复位
ActMotor analysisScanMotor = (ActMotor)device.getActuator(ActuatorModule.ANALYSIS_SCAN_MOTOR);
analysisScanMotor.reset();
analysisScanMotor.moveTo("analysisScanMotorStandBy");
// 11. 光学推杆电机复位
ActMotor analysisPushMotor = (ActMotor)device.getActuator(ActuatorModule.ANALYSIS_PUSH_MOTOR);
Integer analysisPushMotorInputState = analysisPushMotor.getRegister(DeviceRegister.MODULE_INPUT_STATE);
boolean isAnalysisPushMotorPushing = ((analysisPushMotorInputState >> 1) & 0x01) == 0x00;
if ( isAnalysisPushMotorPushing ) {
analysisPushMotor.reset();
analysisScanMotor.moveTo("analysisScanMotorDropCard");
analysisScanMotor.moveTo("analysisScanMotorStandBy");
analysisPushMotor.moveTo("analysisPushMotorStandby");
}
// 12. 孵育盘电机复位
ActIncubator incubatorMotor = (ActIncubator)device.getActuator(ActuatorModule.INCUBATOR_MOTOR);
incubatorMotor.reset();
IncubatorSlot incubatorSlot = incubatorMotor.getFreeSlot();
incubatorMotor.moveTo(incubatorSlot.getExitLocation());
analysisPushMotor.reset();
analysisPushMotor.moveTo("analysisPushMotorStandby");
}
}

157
src/main/java/com/dreamworks/boditech/driver/task/TaskStartReset.java

@ -0,0 +1,157 @@
package com.dreamworks.boditech.driver.task;
import com.dreamworks.boditech.driver.Device;
import com.dreamworks.boditech.driver.DeviceRegister;
import com.dreamworks.boditech.driver.actuator.*;
import com.dreamworks.boditech.driver.entity.IncubatorSlot;
import java.util.Objects;
public class TaskStartReset extends TaskBase {
// mode : normal
public static final Integer MODE_NORMAL = 0;
// mode : error
public static final Integer MODE_ERROR = 1;
// reset mode
public Integer mode = MODE_NORMAL;
// device instance
private Device device;
// test tube rack move motor
private ActMotor testTubeRackMoveMotor;
// test card feed motor
private ActMotor testCardFeedMotor;
// analysis scan motor
private ActMotor analysisPushMotor;
// analysis scan motor
private ActMotor analysisScanMotor;
@Override
public void execute(Executor executor) {
this.device = executor.getDevice();
this.testTubeRackMoveMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_RACK_MOVE_MOTOR);
this.analysisPushMotor = (ActMotor)device.getActuator(ActuatorModule.ANALYSIS_PUSH_MOTOR);
this.analysisScanMotor = (ActMotor)device.getActuator(ActuatorModule.ANALYSIS_SCAN_MOTOR);
//01. 试管夹复位
ActMotor testTubeShakingClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CLIP_MOTOR);
testTubeShakingClipMotor.reset();
// 02. 试管夹旋转复位
ActMotor testTubeShakingClipRotateMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_ROTATE_MOTOR);
testTubeShakingClipRotateMotor.reset();
// 03. 机械臂Z轴复位
ActMotor armZMotor = (ActMotor)device.getActuator(ActuatorModule.ARM_Z_MOTOR);
armZMotor.reset();
// 04. 机械臂XY轴复位
ActArmXY armXY = (ActArmXY)device.getActuator(ActuatorModule.ARM_XY);
armXY.reset();
// 05. 丢弃移液枪头
ActPipette pipette = (ActPipette)this.device.getActuator(ActuatorModule.ARM_Z_PIPETTE);
pipette.dropTip();
armXY.reset();
// 05. 摇匀电机复位
// @TODO : 摇匀电机没有零点暂时没法复位
// 06. 试管帽夹复位
ActMotor testTubeShakingCapClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CAP_CLIP_MOTOR);
testTubeShakingCapClipMotor.moveTo("testTubeShakingCapClipClose");
// 07. 摇匀升降电机复位
ActMotor testTubeShakingMoveMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_MOVE_MOTOR);
testTubeShakingMoveMotor.reset();
this.cleanTestTubeCapClipIfError();
// 08. 试管架电机复位
this.testTubeRackMoveMotor.reset();
this.cleanTestTubeRackTrackIfError();
// 09. 板夹仓推杆电机复位
this.testCardFeedMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_CARD_FEED_MOTOR);
this.cleanTestCardFeedTrackIfError();
this.testCardFeedMotor.reset();
this.testCardFeedMotor.moveTo("testCardFeedStandBy");
// 10. 板夹仓复位
ActMotor testCardBoxMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_CARD_BOX_MOTOR);
testCardBoxMotor.reset();
// 11. 光学扫描电机复位
this.analysisScanMotor.reset();
this.analysisScanMotor.moveTo("analysisScanMotorStandBy");
this.cleanAnalysisPullTrackIfError();
// 12. 孵育盘电机复位
ActIncubator incubatorMotor = (ActIncubator)device.getActuator(ActuatorModule.INCUBATOR_MOTOR);
incubatorMotor.reset();
IncubatorSlot incubatorSlot = incubatorMotor.getFreeSlot();
incubatorMotor.moveTo(incubatorSlot.getExitLocation());
// 11. 光学推杆电机复位
this.analysisPushMotor.reset();
this.analysisPushMotor.moveTo("analysisPushMotorStandby");
}
// clean analysis scan track if error
private void cleanAnalysisPullTrackIfError() {
if ( !Objects.equals(this.mode, TaskStartReset.MODE_ERROR) ) {
return;
}
Integer analysisPushMotorInputState = analysisPushMotor.getRegister(DeviceRegister.MODULE_INPUT_STATE);
boolean isAnalysisPushMotorPushing = ((analysisPushMotorInputState >> 1) & 0x01) == 0x00;
if ( isAnalysisPushMotorPushing ) {
this.analysisPushMotor.reset();
this.analysisScanMotor.moveTo("analysisScanMotorDropCard");
this.analysisScanMotor.moveTo("analysisScanMotorStandBy");
this.analysisPushMotor.moveTo("analysisPushMotorStandby");
}
}
// clean test card feed track if error
private void cleanTestCardFeedTrackIfError() {
if ( !Objects.equals(this.mode, TaskStartReset.MODE_ERROR) ) {
return;
}
// @TODO : 检查是否存在试管正在被从板夹仓推出
// @TODO : 读取试管夹二次验证相机数据判断是否存在上述情况
boolean hasTestCardInFeedRack = true;
if ( hasTestCardInFeedRack ) {
this.testCardFeedMotor.moveToPoint(ActMotor.POINT_END);
}
}
// clean test tube cap clip if error
private void cleanTestTubeCapClipIfError() {
if ( !Objects.equals(this.mode, TaskStartReset.MODE_ERROR) ) {
return;
}
// @TODO : 出错的情况下这个时候可能还存在试管需要把试管放回到试管架上
// @TODO : 但是这个时候也可能试管不在试管帽夹上 ~~~ 这个目前判断不了
// @TODO : ~~~ 这个要不然直接忽略掉 因为前台已经给弹框提示要清理了 ~~~
// testTubeShakingMoveMotor.moveTo("testTubeShakingCapPickUp");
// testTubeShakingCapClipMotor.moveTo("testTubeShakingCapClipOpen");
// testTubeShakingMoveMotor.moveTo("testTubeShakingUpDownStandBy");
// testTubeShakingCapClipMotor.moveTo("testTubeShakingCapClipClose");
}
// clean test tube rack track if error
private void cleanTestTubeRackTrackIfError() {
if ( !Objects.equals(this.mode, TaskStartReset.MODE_ERROR) ) {
return;
}
// 试管架推送至退出位置
testTubeRackMoveMotor.moveTo("testTubeRackExitPrepare");
testTubeRackMoveMotor.moveTo("testTubeRackExit");
// 推出试管架并复位
ActMotor testTubeRackExitMotor = (ActMotor)this.device.getActuator(ActuatorModule.TEST_TUBE_RACK_EXIT_MOTOR);
testTubeRackExitMotor.moveBy("testTubeRackExitDistance");
testTubeRackMoveMotor.moveTo(0);
}
}

9
src/main/java/com/dreamworks/boditech/driver/task/TaskStopReset.java

@ -0,0 +1,9 @@
package com.dreamworks.boditech.driver.task;
import com.dreamworks.boditech.driver.Device;
public class TaskStopReset extends TaskBase {
@Override
public void execute(Executor executor) {
Device device = executor.getDevice();
// @TODO : 后面慢慢写 ~~~
}
}

15
src/main/java/com/dreamworks/boditech/driver/task/step/StepPretreatment.java

@ -56,13 +56,14 @@ public class StepPretreatment extends StepBase {
this.testTubeMoveMotor.moveTo("shakeTestTubeMoveStandby");
// 05. 摇晃
this.testTubeShakeMotor.rotate(ActMotor.ROTATE_DIRECTION_CLOCKWISE);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
this.testTubeShakeMotor.stop();
// @TODO : 摇不得摇不得 没限位 要乱的
// this.testTubeShakeMotor.rotate(ActMotor.ROTATE_DIRECTION_CLOCKWISE);
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// this.testTubeShakeMotor.stop();
this.testTubeMoveMotor.moveTo("shakeTestTubeMoveCapClip");
this.uncap("shaking");

12
src/main/java/com/dreamworks/boditech/mapper/RuntimeVariableMapper.java

@ -0,0 +1,12 @@
package com.dreamworks.boditech.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
@Mapper
public interface RuntimeVariableMapper {
@Select("SELECT `value` FROM btd_runtime_variables WHERE name = #{variableName}")
String getVariableValue(String variableName);
@Update("UPDATE btd_runtime_variables SET `value` = #{variableValue} WHERE name = #{variableName}")
void setVariableValue(String variableName, String variableValue);
}

45
src/main/java/com/dreamworks/boditech/service/DeviceService.java

@ -3,6 +3,7 @@ import com.dreamworks.boditech.driver.*;
import com.dreamworks.boditech.driver.consumable.*;
import com.dreamworks.boditech.driver.entity.*;
import com.dreamworks.boditech.driver.task.*;
import com.dreamworks.boditech.driver.task.TaskStopReset;
import com.dreamworks.boditech.entity.ParamTestEmergencyAppend;
import com.dreamworks.boditech.entity.ParamTestRegularAppend;
import com.dreamworks.boditech.entity.ParamTestRegularAppendTask;
@ -13,6 +14,8 @@ import java.util.*;
public class DeviceService {
@Resource
public Device device;
@Resource
public RuntimeVariableService runtimeVariableService;
// tasks
private final List<Task> tasks = new ArrayList<>();
@ -149,7 +152,7 @@ public class DeviceService {
// reset to initial state
public void reset() {
TaskReset task = new TaskReset();
TaskStartReset task = new TaskStartReset();
Executor.executeTask(this.device, task);
}
@ -159,6 +162,29 @@ public class DeviceService {
this.taskExecutorThread = new Thread(this.taskExecutor);
this.taskExecutorThread.setName("task-executor");
this.taskExecutorThread.start();
Boolean isDeviceAllModuleReset = this.runtimeVariableService.getBoolean("DeviceIsAllModuleReset");
if ( !isDeviceAllModuleReset) {
throw new RuntimeException("设备未正常复位, 需要给个警告弹框,然后再执行错误复位");
}
this.runtimeVariableService.setBoolean("DeviceIsAllModuleReset", false);
TaskStartReset task = new TaskStartReset();
task.mode = TaskStartReset.MODE_NORMAL;
Executor.executeTask(this.device, task);
}
// stop
public void stop() {
TaskStopReset task = new TaskStopReset();
Executor.executeTask(this.device, task);
this.runtimeVariableService.setBoolean("DeviceIsAllModuleReset", true);
this.taskExecutor.stop();
try {
this.taskExecutorThread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
// emergency task append
@ -196,21 +222,4 @@ public class DeviceService {
this.tasks.notifyAll();
}
}
// stop
public void stop() {
this.taskExecutor.stop();
try {
this.taskExecutorThread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

33
src/main/java/com/dreamworks/boditech/service/RuntimeVariableService.java

@ -0,0 +1,33 @@
package com.dreamworks.boditech.service;
import com.dreamworks.boditech.mapper.RuntimeVariableMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@Service
public class RuntimeVariableService {
@Resource
private RuntimeVariableMapper runtimeVariableMapper;
// get integer value
public Integer getInteger(String variableName) {
String value = this.runtimeVariableMapper.getVariableValue(variableName);
return Integer.parseInt(value);
}
// set integer value
public void setInteger(String variableName, Integer variableValue) {
String value = variableValue.toString();
this.runtimeVariableMapper.setVariableValue(variableName, value);
}
// get boolean value
public Boolean getBoolean(String variableName) {
String value = this.runtimeVariableMapper.getVariableValue(variableName);
return "YES".equals(value);
}
// set boolean value
public void setBoolean(String variableName, Boolean variableValue) {
String value = variableValue ? "YES" : "NO";
this.runtimeVariableMapper.setVariableValue(variableName, value);
}
}
Loading…
Cancel
Save