18 changed files with 308 additions and 9 deletions
-
2src/main/java/com/dreamworks/boditech/driver/Command.java
-
16src/main/java/com/dreamworks/boditech/driver/Device.java
-
10src/main/java/com/dreamworks/boditech/driver/actuator/ActArmXY.java
-
6src/main/java/com/dreamworks/boditech/driver/actuator/ActMotor.java
-
46src/main/java/com/dreamworks/boditech/driver/actuator/ActPipette.java
-
1src/main/java/com/dreamworks/boditech/driver/actuator/ActuatorModule.java
-
13src/main/java/com/dreamworks/boditech/driver/consumable/CsmBufferTubeA.java
-
7src/main/java/com/dreamworks/boditech/driver/consumable/CsmBufferTubeB.java
-
5src/main/java/com/dreamworks/boditech/driver/consumable/CsmLargeBufferTube.java
-
4src/main/java/com/dreamworks/boditech/driver/consumable/CsmPipetteTip.java
-
17src/main/java/com/dreamworks/boditech/driver/consumable/CsmSampleTube.java
-
11src/main/java/com/dreamworks/boditech/driver/consumable/ReactionTube.java
-
34src/main/java/com/dreamworks/boditech/driver/task/TaskTest.java
-
1src/main/java/com/dreamworks/boditech/driver/task/step/StepManager.java
-
2src/main/java/com/dreamworks/boditech/driver/task/step/StepPuncture.java
-
116src/main/java/com/dreamworks/boditech/driver/task/step/StepSampling.java
-
8src/main/java/com/dreamworks/boditech/mapper/OptionMapper.java
-
18src/main/java/com/dreamworks/boditech/service/RuntimeOptionService.java
@ -0,0 +1,46 @@ |
|||
package com.dreamworks.boditech.driver.actuator; |
|||
import com.dreamworks.boditech.driver.Command; |
|||
import com.dreamworks.boditech.driver.Device; |
|||
public class ActPipette extends ActuatorBase { |
|||
// indicate whether the pipette has tip |
|||
// @TODO : this should be false by default |
|||
private boolean hasTip = true; |
|||
|
|||
// constructor |
|||
public ActPipette(Integer mid, Device device) { |
|||
super(mid, device); |
|||
} |
|||
|
|||
// set whether the pipette has tip |
|||
public void setHasTip(boolean hasTip) { |
|||
this.hasTip = hasTip; |
|||
} |
|||
|
|||
// get whether the pipette has tip |
|||
public boolean getHasTip() { |
|||
return this.hasTip; |
|||
} |
|||
|
|||
// init device |
|||
public void initDevice() { |
|||
this.call(Command.CMD_PIPETTE_CTRL_INIT_DEVICE); |
|||
this.waitForFinish(); |
|||
} |
|||
|
|||
// move to given position |
|||
public void aspiration(int volume) { |
|||
this.call(Command.CMD_PIPETTE_CTRL_MOVE_TO_UL, volume); |
|||
this.waitForFinish(); |
|||
} |
|||
|
|||
// move to given position |
|||
public void dispense(int volume) { |
|||
this.call(Command.CMD_PIPETTE_CTRL_MOVE_TO_UL, volume); |
|||
this.waitForFinish(); |
|||
} |
|||
|
|||
// move to given position |
|||
public void dispense() { |
|||
this.dispense(0); |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
package com.dreamworks.boditech.driver.consumable; |
|||
public class CsmSampleTube { |
|||
// get location x |
|||
public Integer getLocationX() { |
|||
return 0; |
|||
} |
|||
|
|||
// get location y |
|||
public Integer getLocationY() { |
|||
return 0; |
|||
} |
|||
|
|||
// get location z |
|||
public Integer getLocationZ() { |
|||
return 1400; |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
package com.dreamworks.boditech.driver.consumable; |
|||
public interface ReactionTube { |
|||
// get location x |
|||
public Integer getLocationX(); |
|||
|
|||
// get location y |
|||
public Integer getLocationY(); |
|||
|
|||
// get location z |
|||
public Integer getLocationZ(); |
|||
} |
@ -0,0 +1,116 @@ |
|||
package com.dreamworks.boditech.driver.task.step; |
|||
import com.dreamworks.boditech.driver.Device; |
|||
import com.dreamworks.boditech.driver.Task; |
|||
import com.dreamworks.boditech.driver.TaskExecutor; |
|||
import com.dreamworks.boditech.driver.actuator.ActArmXY; |
|||
import com.dreamworks.boditech.driver.actuator.ActMotor; |
|||
import com.dreamworks.boditech.driver.actuator.ActPipette; |
|||
import com.dreamworks.boditech.driver.actuator.ActuatorModule; |
|||
import com.dreamworks.boditech.driver.consumable.*; |
|||
import com.dreamworks.boditech.driver.task.TaskTest; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
public class StepSampling extends StepBase { |
|||
@JsonProperty("action") |
|||
public String action; |
|||
|
|||
@JsonProperty("sourceTubeType") |
|||
public String sourceTubeType; |
|||
|
|||
@JsonProperty("amount") |
|||
public String amount; |
|||
|
|||
@JsonProperty("dropTip") |
|||
public String dropTip = "YES"; |
|||
|
|||
@JsonProperty("requireNewTip") |
|||
public String requireNewTip = "YES"; |
|||
|
|||
@Override |
|||
public void execute(TaskExecutor executor, Task task) { |
|||
Device device = executor.getDevice(); |
|||
ActPipette pipette = (ActPipette)device.getActuator(ActuatorModule.ARM_Z_PIPETTE); |
|||
ActArmXY armXY = (ActArmXY)device.getActuator(ActuatorModule.ARM_XY); |
|||
ActMotor armZMotor = (ActMotor)device.getActuator(ActuatorModule.ARM_Z_MOTOR); |
|||
TaskTest taskTest = (TaskTest)task; |
|||
|
|||
// 丢弃TIP |
|||
if ( this.requireNewTip.equals("YES") && pipette.getHasTip() ) { |
|||
armXY.moveTo("tipDiscardPrepareHole"); |
|||
armZMotor.moveTo("tipDiscardDepth"); |
|||
armXY.moveTo("tipDiscardDrop"); |
|||
armZMotor.moveTo(0); |
|||
armXY.moveTo(0, 0); |
|||
pipette.setHasTip(false); |
|||
} |
|||
|
|||
// get tip |
|||
if ( !pipette.getHasTip() ) { |
|||
CsmPipetteTip tip = device.getPipetteTip(); |
|||
armXY.moveTo(tip.getLocationX(), tip.getLocationY()); |
|||
armZMotor.moveTo("tipPickUpDepth"); |
|||
armZMotor.moveTo(0); |
|||
pipette.setHasTip(true); |
|||
} |
|||
|
|||
// 1. 获取样本 |
|||
// 2. 移动到样本采集位置 |
|||
Integer srcTubeLocationZ = 0; |
|||
if ( this.sourceTubeType.equals("LargeBufferTube") ) { |
|||
CsmLargeBufferTube tube = device.getLargeBufferTube(taskTest.projectName); |
|||
armXY.moveTo(tube.getLocationX(), tube.getLocationY()); |
|||
srcTubeLocationZ = tube.getLocationZ(); |
|||
} else if ( this.sourceTubeType.equals("BufferTubeA") ) { |
|||
CsmBufferTubeA tube = device.getBufferTubeA(taskTest.projectName); |
|||
armXY.moveTo(tube.getLocationX(), tube.getLocationY()); |
|||
srcTubeLocationZ = tube.getLocationZ(); |
|||
} else if ( this.sourceTubeType.equals("BufferTubeB") ) { |
|||
CsmBufferTubeB tube = device.getBufferTubeB(taskTest.projectName); |
|||
armXY.moveTo(tube.getLocationX(), tube.getLocationY()); |
|||
srcTubeLocationZ = tube.getLocationZ(); |
|||
} else if ( this.sourceTubeType.equals("Sample") ) { |
|||
armXY.moveTo("sampleTestTube"); |
|||
srcTubeLocationZ = taskTest.getSampleTube().getLocationZ(); |
|||
} else { |
|||
throw new RuntimeException("unknown source tube type " + this.sourceTubeType); |
|||
} |
|||
|
|||
// 3. 下降到样本采集位置 |
|||
armZMotor.moveTo(srcTubeLocationZ); |
|||
|
|||
// 4. 吸入样本 |
|||
pipette.aspiration(Integer.parseInt(this.amount)); |
|||
|
|||
// 5. 上升到准备位置 |
|||
armZMotor.moveTo(0); |
|||
|
|||
// 6. 移动到反应试管放置位置 |
|||
ReactionTube reactionTube = taskTest.getReactionTube(); |
|||
armXY.moveTo(reactionTube.getLocationX(), reactionTube.getLocationY()); |
|||
|
|||
// 7. 下降到反应试管放置位置 |
|||
armZMotor.moveTo(reactionTube.getLocationZ()); |
|||
|
|||
// 8. 吐出样本 |
|||
pipette.dispense(); |
|||
|
|||
// 9. 吞吐混合均匀 |
|||
int mixAmount = Integer.parseInt(this.amount); |
|||
for ( int i = 0; i < 3; i++ ) { |
|||
pipette.aspiration(mixAmount); |
|||
pipette.dispense(); |
|||
} |
|||
|
|||
// 10. 上升到准备位置 |
|||
armZMotor.moveTo(0); |
|||
|
|||
// 丢弃TIP |
|||
if ( this.dropTip.equals("YES") ) { |
|||
armXY.moveTo("tipDiscardPrepareHole"); |
|||
armZMotor.moveTo("tipDiscardDepth"); |
|||
armXY.moveTo("tipDiscardDrop"); |
|||
armZMotor.moveTo(0); |
|||
armXY.moveTo(0, 0); |
|||
pipette.setHasTip(false); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
package com.dreamworks.boditech.mapper; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
import org.apache.ibatis.annotations.Select; |
|||
@Mapper |
|||
public interface OptionMapper { |
|||
@Select("SELECT `value` FROM bdt_options WHERE name=#{name} LIMIT 1") |
|||
String findByName(String name); |
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.dreamworks.boditech.service; |
|||
import com.dreamworks.boditech.mapper.OptionMapper; |
|||
import jakarta.annotation.Resource; |
|||
import org.springframework.stereotype.Service; |
|||
@Service |
|||
public class RuntimeOptionService { |
|||
@Resource |
|||
private OptionMapper optionMapper; |
|||
|
|||
// get integer value |
|||
public Integer getInteger(String name) { |
|||
String value = this.optionMapper.findByName(name); |
|||
if ( value == null ) { |
|||
throw new RuntimeException("option not found: " + name); |
|||
} |
|||
return Integer.parseInt(value); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue