From ea1515692eafb3623d71a177981751f5cd87202d Mon Sep 17 00:00:00 2001 From: sige Date: Mon, 8 Jan 2024 11:38:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A8=E8=A1=803ml=E8=AF=95=E7=AE=A1?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dreamworks/boditech/driver/Device.java | 2 +- .../dreamworks/boditech/driver/DeviceCommand.java | 1 + .../boditech/driver/actuator/ActMotor.java | 9 ++++ .../driver/task/TaskTestTubeRackPrepare.java | 60 +++++++++++++++++----- .../boditech/driver/task/step/StepCapTube.java | 41 +++++++++++---- .../driver/task/step/StepPretreatment.java | 18 ++++++- .../dreamworks/boditech/entity/MdbTestTube.java | 11 ++++ .../dreamworks/boditech/mapper/TestTubeMapper.java | 9 ++++ .../dreamworks/boditech/service/TestService.java | 7 +++ .../com/dreamworks/boditech/utils/AppError.java | 1 + 10 files changed, 135 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/dreamworks/boditech/entity/MdbTestTube.java create mode 100644 src/main/java/com/dreamworks/boditech/mapper/TestTubeMapper.java diff --git a/src/main/java/com/dreamworks/boditech/driver/Device.java b/src/main/java/com/dreamworks/boditech/driver/Device.java index dbc3b9a..a520762 100644 --- a/src/main/java/com/dreamworks/boditech/driver/Device.java +++ b/src/main/java/com/dreamworks/boditech/driver/Device.java @@ -64,7 +64,7 @@ public class Device { // message index private short messageIndex = 0; // device ready - private Boolean isReady = true; + private Boolean isReady = false; @PostConstruct public void init() { diff --git a/src/main/java/com/dreamworks/boditech/driver/DeviceCommand.java b/src/main/java/com/dreamworks/boditech/driver/DeviceCommand.java index 00ea2d1..104feb9 100644 --- a/src/main/java/com/dreamworks/boditech/driver/DeviceCommand.java +++ b/src/main/java/com/dreamworks/boditech/driver/DeviceCommand.java @@ -12,6 +12,7 @@ public class DeviceCommand { public static final Integer CMD_MOTOR_EASY_MOVE_BY = 0x0212; public static final Integer CMD_MOTOR_EASY_MOVE_TO = 0x0213; public static final Integer CMD_MOTOR_EASY_MOVE_TO_ZERO = 0x0214; + public static final Integer CMD_MOTOR_READ_POS = 0x020B; public static final Integer CMD_XYMOTOR_MOVE_TO = 0x0303; public static final Integer CMD_XYMOTOR_MOVE_TO_ZERO = 0x0304; public static final Integer CMD_PIPETTE_CTRL_INIT_DEVICE = 0x0501; diff --git a/src/main/java/com/dreamworks/boditech/driver/actuator/ActMotor.java b/src/main/java/com/dreamworks/boditech/driver/actuator/ActMotor.java index cb5f4c3..87bf128 100644 --- a/src/main/java/com/dreamworks/boditech/driver/actuator/ActMotor.java +++ b/src/main/java/com/dreamworks/boditech/driver/actuator/ActMotor.java @@ -68,6 +68,15 @@ public class ActMotor extends ActuatorBase { this.waitForFinish(); } + // read pos + public Integer readPos() { + ByteBuffer response = this.call(DeviceCommand.CMD_MOTOR_READ_POS); + if ( null == response ) { + return this.readPos(); + } + return this.getIntegerFromResponse(response, 0); + } + // move to point public void moveToPoint( int pointType ) { // @TODO : 硬件暂时未更新 diff --git a/src/main/java/com/dreamworks/boditech/driver/task/TaskTestTubeRackPrepare.java b/src/main/java/com/dreamworks/boditech/driver/task/TaskTestTubeRackPrepare.java index 659ecea..00399b2 100644 --- a/src/main/java/com/dreamworks/boditech/driver/task/TaskTestTubeRackPrepare.java +++ b/src/main/java/com/dreamworks/boditech/driver/task/TaskTestTubeRackPrepare.java @@ -1,6 +1,7 @@ package com.dreamworks.boditech.driver.task; import com.dreamworks.boditech.driver.Device; import com.dreamworks.boditech.driver.actuator.*; +import com.dreamworks.boditech.entity.MdbTestTube; import com.dreamworks.boditech.entity.MdbTestTubeRackTestTask; import com.dreamworks.boditech.entity.MdbTestTubeRackTestTaskTube; import com.dreamworks.boditech.service.TestService; @@ -20,6 +21,10 @@ public class TaskTestTubeRackPrepare extends TaskBase { private ActModuleTestTubeRackMovement testTubeMovement; // testTubeFeedMotor private ActMotor testTubeFeedMotor; + // testTubeMoveMotor + private ActMotor testTubeMoveMotor; + // testTubeScanner + private ActCodeScanner testTubeScanner; // testTubeExistsStatus private boolean[] testTubeExistsStatus; // testTubeBarcodes @@ -49,7 +54,8 @@ public class TaskTestTubeRackPrepare extends TaskBase { this.device = executor.getDevice(); this.testTubeFeedMotor = (ActMotor)this.device.getActuator(ActuatorModule.TEST_TUBE_RACK_FEED_MOTOR); this.testTubeMovement = (ActModuleTestTubeRackMovement)this.device.getActuator(ActuatorModule.TEST_TUBE_RACK_MOVEMENT); - ActMotor testTubeMoveMotor = (ActMotor)this.device.getActuator(ActuatorModule.TEST_TUBE_RACK_MOVE_MOTOR); + this.testTubeMoveMotor = (ActMotor)this.device.getActuator(ActuatorModule.TEST_TUBE_RACK_MOVE_MOTOR); + this.testTubeScanner = (ActCodeScanner)this.device.getActuator(ActuatorModule.TEST_TUBE_RACK_SCANNER); ActMotor testTubeRotateMotor = (ActMotor) this.device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_ROTATE_MOTOR); // 01. 入料 @@ -60,13 +66,15 @@ public class TaskTestTubeRackPrepare extends TaskBase { int tubeDistance = this.device.getLocationByName("testTubeRackTubeDistance"); int existsCheckStartPos = this.device.getLocationByName("testTubeRackExistsCheckStart"); for ( int i = 0; i < 10; i++ ) { - testTubeMoveMotor.moveTo(existsCheckStartPos + i * tubeDistance); + this.testTubeMoveMotor.moveTo(existsCheckStartPos + i * tubeDistance); Integer isExists = this.testTubeMovement.readIO(ActModuleTestTubeRackMovement.IO_TEST_TUBE_EXISTS); this.testTubeExistsStatus[i] = Objects.equals(this.device.getIOValueByName("testTubeRackTubeExistsYes"), isExists); } + // 03. 试管架类型检测 + this.testTubeRackTypeDetect(); + // 03. 逐个扫描试管 - ActCodeScanner testTubeScanner = (ActCodeScanner)this.device.getActuator(ActuatorModule.TEST_TUBE_RACK_SCANNER); this.testTubeBarcodes = new String[10]; int scanStartPos = this.device.getLocationByName("testTubeRackScanStart"); for ( int i = 0; i < 10; i++ ) { @@ -74,21 +82,15 @@ public class TaskTestTubeRackPrepare extends TaskBase { this.testTubeBarcodes[i] = ""; continue ; } - testTubeMoveMotor.moveTo(scanStartPos + i * tubeDistance); + this.testTubeMoveMotor.moveTo(scanStartPos + i * tubeDistance); testTubeRotateMotor.rotate(ActMotor.ROTATE_DIRECTION_CLOCKWISE); - String code = testTubeScanner.scan(1000); + String code = this.testTubeScanner.scan(1000); testTubeRotateMotor.reset(); this.testTubeBarcodes[i] = code; } - if ( this.mdbTask.tubeType.isEmpty() ) { - // @TODO : 试管为空需要扫描试管架了 - this.mdbTask.tubeType = "BloodTube5ml"; - this.testService.regularTaskUpdate(this.mdbTask); - } - // 04. 扫描完成后推送到预备区域 - testTubeMoveMotor.moveTo("testTubeRackStandby"); + this.testTubeMoveMotor.moveTo("testTubeRackStandby"); this.appendTestTasksToExecutor(executor); TaskBatchTubeExit exitTask = new TaskBatchTubeExit(); @@ -158,4 +160,38 @@ public class TaskTestTubeRackPrepare extends TaskBase { // 任然没有找到 throw new AppRuntimeException(AppError.TEST_TUBE_RACK_FEED_RACK_NOT_FOUND); } + + // 试管架类型检测 + private void testTubeRackTypeDetect() { + if ( !this.mdbTask.tubeType.isEmpty() ) { + return ; + } + + this.testTubeMoveMotor.moveTo("testTubeRackTubeTypeScan"); + String typeCode = this.testTubeScanner.scan(1000); + if ( "0000".equals(typeCode) ) { + // 如果是全血试管架,还需要检查当前是高试管还是低试管 ~~~ + // !!! 禁止一个试管架中既有高试管又有低试管 + ActMotor testTubeCapClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CAP_CLIP_MOTOR); + ActMotor testTubeShakeMoveMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_MOVE_MOTOR); + + this.testTubeMoveMotor.moveTo("testTubeRackTubeSamplingStart"); + testTubeCapClipMotor.moveTo("shakeTestTubeCapClipOpen"); + testTubeShakeMoveMotor.moveTo("shakeTestTubeMoveCapClip"); + testTubeCapClipMotor.moveTo("shakeTestTubeCapClipClose"); + Integer clipMotorPos = testTubeCapClipMotor.readPos(); + Integer btHighThreshold = this.device.getLocationByName("shakeTestTubeCapClipCloseBTHighThreshold"); + typeCode = btHighThreshold > clipMotorPos ? "0000H" : "0000L"; + testTubeCapClipMotor.moveTo("shakeTestTubeCapClipOpen"); + testTubeShakeMoveMotor.reset(); + testTubeCapClipMotor.moveTo("shakeTestTubeCapClipClose"); + } + + MdbTestTube testTube = this.testService.testTubeFindByCode(typeCode); + if ( null == testTube ) { + throw new AppRuntimeException(AppError.TEST_TUBE_RACK_TYPE_NOT_SUPPORTED); + } + this.mdbTask.tubeType = testTube.key; + this.testService.regularTaskUpdate(this.mdbTask); + } } diff --git a/src/main/java/com/dreamworks/boditech/driver/task/step/StepCapTube.java b/src/main/java/com/dreamworks/boditech/driver/task/step/StepCapTube.java index a7dd1e2..3daeefb 100644 --- a/src/main/java/com/dreamworks/boditech/driver/task/step/StepCapTube.java +++ b/src/main/java/com/dreamworks/boditech/driver/task/step/StepCapTube.java @@ -2,10 +2,15 @@ package com.dreamworks.boditech.driver.task.step; import com.dreamworks.boditech.driver.Device; import com.dreamworks.boditech.driver.actuator.ActMotor; import com.dreamworks.boditech.driver.actuator.ActuatorModule; +import com.dreamworks.boditech.driver.consumable.CsmSampleTube; import com.dreamworks.boditech.driver.task.Executor; import com.dreamworks.boditech.driver.task.Task; import com.dreamworks.boditech.driver.task.TaskTest; public class StepCapTube extends StepBase { + private ActMotor testTubeMoveMotor; + private ActMotor testTubeCapClipMotor; + private ActMotor testTubeClipMotor; + @Override public void execute(Executor executor, Task task) { TaskTest taskTest = (TaskTest)task; @@ -14,15 +19,33 @@ public class StepCapTube extends StepBase { } Device device = executor.getDevice(); - ActMotor testTubeMoveMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_MOVE_MOTOR); - ActMotor testTubeCapClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CAP_CLIP_MOTOR); - ActMotor testTubeClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CLIP_MOTOR); + this.testTubeMoveMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_MOVE_MOTOR); + this.testTubeCapClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CAP_CLIP_MOTOR); + this.testTubeClipMotor = (ActMotor)device.getActuator(ActuatorModule.TEST_TUBE_SHAKING_CLIP_MOTOR); + + String tubeType = taskTest.getSampleTube().type; + if (CsmSampleTube.TYPE_BLOOD_TUBE_5ML.equals(tubeType)) { + this.capForBloodTube5ml(); + } else if (CsmSampleTube.TYPE_BLOOD_TUBE_3ML.equals(tubeType)) { + this.capForBloodTube3ml(); + } else { + throw new RuntimeException("unknown tube type " + tubeType); + } + } + + // cap for blood tube 3ml + private void capForBloodTube3ml() { + // @TODO : 3ml全血试管暂时没法盖试管帽,试管帽夹需要调整角度,但目前无法调整 + throw new RuntimeException("3ml全血试管暂时没法盖试管帽,试管帽夹需要调整角度,但目前无法调整"); + } - testTubeMoveMotor.moveTo("shakeTestTubeMoveCapClip"); - testTubeCapClipMotor.moveTo("shakeTestTubeCapClipOpen"); - testTubeMoveMotor.moveTo("shakeTestTubeMoveStandby"); - testTubeCapClipMotor.moveTo("shakeTestTubeCapClipClose"); - testTubeClipMotor.rotate(ActMotor.ROTATE_DIRECTION_COUNTER_CLOCKWISE); - testTubeClipMotor.stop(); + // cap for blood tube 5ml + private void capForBloodTube5ml() { + this.testTubeMoveMotor.moveTo("shakeTestTubeMoveCapClip"); + this.testTubeCapClipMotor.moveTo("shakeTestTubeCapClipOpen"); + this.testTubeMoveMotor.moveTo("shakeTestTubeMoveStandby"); + this.testTubeCapClipMotor.moveTo("shakeTestTubeCapClipClose"); + this.testTubeClipMotor.rotate(ActMotor.ROTATE_DIRECTION_COUNTER_CLOCKWISE); + this.testTubeClipMotor.stop(); } } diff --git a/src/main/java/com/dreamworks/boditech/driver/task/step/StepPretreatment.java b/src/main/java/com/dreamworks/boditech/driver/task/step/StepPretreatment.java index 5e0a130..af3294b 100644 --- a/src/main/java/com/dreamworks/boditech/driver/task/step/StepPretreatment.java +++ b/src/main/java/com/dreamworks/boditech/driver/task/step/StepPretreatment.java @@ -1,5 +1,6 @@ package com.dreamworks.boditech.driver.task.step; import com.dreamworks.boditech.driver.Device; +import com.dreamworks.boditech.driver.consumable.CsmSampleTube; import com.dreamworks.boditech.driver.task.Task; import com.dreamworks.boditech.driver.task.Executor; import com.dreamworks.boditech.driver.actuator.ActMotor; @@ -50,8 +51,21 @@ public class StepPretreatment extends StepBase { } this.testTubeCapClipMotor.moveTo("shakeTestTubeCapClipOpen"); - this.testTubeMoveMotor.moveTo("shakeTestTubeMoveCapClip"); - this.testTubeCapClipMotor.moveTo("shakeTestTubeCapClipClose"); + if (CsmSampleTube.TYPE_BLOOD_TUBE_5ML.equals(this.taskTest.getSampleTube().type)) { // 全血试管:高 + this.testTubeMoveMotor.moveTo("shakeTestTubeMoveCapClip"); + this.testTubeCapClipMotor.moveTo("shakeTestTubeCapClipClose"); + } else if ( CsmSampleTube.TYPE_BLOOD_TUBE_3ML.equals(this.taskTest.getSampleTube().type) ) { // 全血试管:低 + this.testTubeMoveMotor.moveTo("shakeTestTubeCapBodyClipDepth"); // 下降到试管帽中间位置,用于夹住试管帽=1200 + this.testTubeCapClipMotor.moveTo("shakeTestTubeCapClipBodyClose"); //夹住试管帽=850 + this.testTubeMoveMotor.moveTo("shakeTestTubeBT3mlPullUpDepth"); //往上提一点=980 + this.testTubeClipMotor.rotate(ActMotor.ROTATE_DIRECTION_CLOCKWISE); //试管夹夹住试管 + this.testTubeCapClipMotor.moveTo("shakeTestTubeCapClipOpen"); //试管帽夹松开 + this.testTubeMoveMotor.moveTo("shakeTestTubeMoveCapClip"); //试管帽夹下降 + this.testTubeCapClipMotor.moveTo("shakeTestTubeCapClipBt3mlClose"); // 试管帽夹夹住整个试管帽=850 + this.testTubeClipMotor.rotate(ActMotor.ROTATE_DIRECTION_COUNTER_CLOCKWISE); //试管夹松开 + this.testTubeClipMotor.stop(); //试管夹停止 + } + this.testTubeMoveMotor.moveTo("shakeTestTubeMoveStandby"); // 05. 摇晃 diff --git a/src/main/java/com/dreamworks/boditech/entity/MdbTestTube.java b/src/main/java/com/dreamworks/boditech/entity/MdbTestTube.java new file mode 100644 index 0000000..d90e214 --- /dev/null +++ b/src/main/java/com/dreamworks/boditech/entity/MdbTestTube.java @@ -0,0 +1,11 @@ +package com.dreamworks.boditech.entity; +public class MdbTestTube { + // id + public Integer id; + // key + public String key; + // name + public String name; + // code + public String code; +} diff --git a/src/main/java/com/dreamworks/boditech/mapper/TestTubeMapper.java b/src/main/java/com/dreamworks/boditech/mapper/TestTubeMapper.java new file mode 100644 index 0000000..2533339 --- /dev/null +++ b/src/main/java/com/dreamworks/boditech/mapper/TestTubeMapper.java @@ -0,0 +1,9 @@ +package com.dreamworks.boditech.mapper; +import com.dreamworks.boditech.entity.MdbTestTube; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; +@Mapper +public interface TestTubeMapper { + @Select("SELECT * FROM bdt_test_tubes WHERE code = #{code}") + MdbTestTube findByCode(String code); +} diff --git a/src/main/java/com/dreamworks/boditech/service/TestService.java b/src/main/java/com/dreamworks/boditech/service/TestService.java index e46cb10..78ccc11 100644 --- a/src/main/java/com/dreamworks/boditech/service/TestService.java +++ b/src/main/java/com/dreamworks/boditech/service/TestService.java @@ -38,6 +38,8 @@ public class TestService { @Resource private ActionLogService actionLog; @Resource + private TestTubeMapper testTubeMapper; + @Resource @Lazy private DeviceService deviceService; // batch id @@ -412,4 +414,9 @@ public class TestService { this.emergencyTestTaskMapper.cancelAllTasks(); this.testMapper.cancelAllTasks(); } + + // test tube find by code + public MdbTestTube testTubeFindByCode( String code) { + return this.testTubeMapper.findByCode(code); + } } diff --git a/src/main/java/com/dreamworks/boditech/utils/AppError.java b/src/main/java/com/dreamworks/boditech/utils/AppError.java index 625a395..33ee5e3 100644 --- a/src/main/java/com/dreamworks/boditech/utils/AppError.java +++ b/src/main/java/com/dreamworks/boditech/utils/AppError.java @@ -14,6 +14,7 @@ public enum AppError { TEST_TUBE_RACK_FEED_RACK_NOT_FOUND, TEST_CARD_BOX_CASE_COVER_NOT_CLOSED, INCUBATOR_NO_FREE_SLOT, + TEST_TUBE_RACK_TYPE_NOT_SUPPORTED, // device DEVICE_BUSY,