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