From c051864c093e6a0dc6585fd32ac1c6e89787c089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=87=A4=E5=90=89?= Date: Sat, 26 Jul 2025 17:18:40 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E5=AE=8C=E5=96=84=E5=B7=A5=E8=89=BA?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../transfer/TrayMoveTitrationAreaCommand.java | 2 +- .../app/core/crafts/CraftsContext.java | 2 +- .../app/core/crafts/CraftsExecutionService.java | 137 +++++++++++++++++++-- .../app/service/module/HeatModuleService.java | 17 +++ .../app/service/module/TransferModuleService.java | 2 +- 5 files changed, 145 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/iflytop/colortitration/app/command/control/transfer/TrayMoveTitrationAreaCommand.java b/src/main/java/com/iflytop/colortitration/app/command/control/transfer/TrayMoveTitrationAreaCommand.java index 35cf156..8b85fea 100644 --- a/src/main/java/com/iflytop/colortitration/app/command/control/transfer/TrayMoveTitrationAreaCommand.java +++ b/src/main/java/com/iflytop/colortitration/app/command/control/transfer/TrayMoveTitrationAreaCommand.java @@ -54,7 +54,7 @@ public class TrayMoveTitrationAreaCommand extends BaseCommandHandler { transferModuleService.zMoveDownWithTrayArea(); //关闭夹爪 transferModuleService.clawClose(); - //判断滴定位传感器状态 + //判断滴定位传感器状态 TODO 拍摄照片判断滴定位是否有试管 boolean titrationExist = switch (titrationModuleCode) { //1、首先检测试管所在的托盘传感器的值 case MultipleModuleCode.MODULE_1 -> deviceState.getTitrationModuleStateMap().get(MultipleModuleCode.MODULE_1).isTubeExist(); diff --git a/src/main/java/com/iflytop/colortitration/app/core/crafts/CraftsContext.java b/src/main/java/com/iflytop/colortitration/app/core/crafts/CraftsContext.java index fa67cb0..05812c0 100644 --- a/src/main/java/com/iflytop/colortitration/app/core/crafts/CraftsContext.java +++ b/src/main/java/com/iflytop/colortitration/app/core/crafts/CraftsContext.java @@ -23,7 +23,7 @@ public class CraftsContext { private int historyCommandCount = 0; private MultipleModuleCode currentTitrationModuleCode; private MultipleModuleCode currentHeatModuleCode; - private TubeCurrentLocal tubeCurrentLocal; + private TubeCurrentLocal tubeCurrentLocal = TubeCurrentLocal.TRAY; /** * 自增当前指令计数器 diff --git a/src/main/java/com/iflytop/colortitration/app/core/crafts/CraftsExecutionService.java b/src/main/java/com/iflytop/colortitration/app/core/crafts/CraftsExecutionService.java index c947b3d..7071642 100644 --- a/src/main/java/com/iflytop/colortitration/app/core/crafts/CraftsExecutionService.java +++ b/src/main/java/com/iflytop/colortitration/app/core/crafts/CraftsExecutionService.java @@ -3,14 +3,21 @@ package com.iflytop.colortitration.app.core.crafts; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.iflytop.colortitration.app.common.enums.AddSolutionType; +import com.iflytop.colortitration.app.common.enums.MultipleModuleCode; +import com.iflytop.colortitration.app.common.enums.TubeCurrentLocal; import com.iflytop.colortitration.app.common.utils.CommandUtil; import com.iflytop.colortitration.app.core.command.CommandFuture; +import com.iflytop.colortitration.app.core.state.DeviceState; +import com.iflytop.colortitration.app.core.state.HeatModuleState; import com.iflytop.colortitration.app.service.DeviceCommandService; +import com.iflytop.colortitration.app.service.module.HeatModuleService; import com.iflytop.colortitration.app.service.module.TitrationModuleService; +import com.iflytop.colortitration.app.service.module.TransferModuleService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.List; /** @@ -22,6 +29,9 @@ import java.util.List; public class CraftsExecutionService { private final DeviceCommandService deviceCommandService; private final TitrationModuleService titrationModuleService; + private final HeatModuleService heatModuleService; + private final DeviceState deviceState; + private final TransferModuleService transferModuleService; /** * 执行工艺步骤,直接从 CraftsContext 中获取步骤 @@ -44,8 +54,6 @@ public class CraftsExecutionService { } private boolean addSolution(CraftsContext craftsContext, JSONObject params) throws Exception { - moveToTitration();//移动至滴定 - //TODO 调用相机判断滴定位是否存在试管 Long solutionId = params.getLong("solutionId");//使用的溶液id Double amount = params.getDouble("amount");//加液量 Long colorId = params.getLong("colorId");//终点颜色 @@ -55,8 +63,11 @@ public class CraftsExecutionService { Double maxAmount = params.getDouble("maxAmount");//滴定最大体积 Boolean stirFlag = params.getBool("stirFlag");//是否搅拌 - if(stirFlag){ - //调用开始搅拌 + moveToTitration(craftsContext);//移动至滴定 + //TODO 调用相机判断滴定位是否存在试管 + + if (stirFlag) { + //TODO 调用开始搅拌 } if (AddSolutionType.fixed.equals(addSolutionType)) {//定量加液 titrationModuleService.addSolutionStart(craftsContext.getCurrentTitrationModuleCode(), solutionId, amount); @@ -72,20 +83,41 @@ public class CraftsExecutionService { } } } - if(stirFlag){ - //调用停止搅拌 + if (stirFlag) { + //TODO 调用停止搅拌 } return true; } - private boolean heat(CraftsContext craftsContext, JSONObject params) { - moveToHeat();//移动至加热 + private boolean heat(CraftsContext craftsContext, JSONObject params) throws Exception { + Double temperature = params.getDouble("temperature"); + Integer time = params.getInt("time"); + Boolean preHeat = params.getBool("preHeat"); + HeatModuleState heatModuleState = deviceState.getHeatModuleStateMap().get(craftsContext.getCurrentHeatModuleCode()); + heatModuleState.setTargetTemperature(temperature);//设定目标温度 + heatModuleState.setTargetTime(time); + if (preHeat) { + heatModuleService.openHeatRod(craftsContext.getCurrentHeatModuleCode(), temperature); + heatModuleState.setOpen(true);//开启加热 + heatModuleState.setStartHeatTime(LocalDateTime.now()); + //循环等待 + while (heatModuleState.getTemperature() < temperature) { + sleep(5 * 1000L); + } + } + moveToHeat(craftsContext);//移动至加热 //TODO 调用传感器判断加热位是否存在试管 - + if (!preHeat) { + heatModuleService.openHeatRod(craftsContext.getCurrentHeatModuleCode(), temperature); + heatModuleState.setOpen(true);//开启加热 + heatModuleState.setStartHeatTime(LocalDateTime.now()); + sleep(time * 1000L); + } return true; } private boolean addMagnet(CraftsContext craftsContext, JSONObject params) { + //TODO 添加磁子方式待定 return true; } @@ -96,13 +128,94 @@ public class CraftsExecutionService { } //移动至滴定 - private void moveToTitration() { - //动态分配使用的模块 + private void moveToTitration(CraftsContext craftsContext) throws Exception { + //动态分配滴定模块 + if (!TubeCurrentLocal.TITRATION.equals(craftsContext.getTubeCurrentLocal())) {//如果试管不在滴定位的话 + while (true) { + if (!deviceState.getTitrationModuleStateMap().get(MultipleModuleCode.MODULE_1).isTubeExist()) {//如果滴定位1没有试管的话 + deviceState.getTitrationModuleStateMap().get(MultipleModuleCode.MODULE_1).setTubeExist(true); + craftsContext.setCurrentTitrationModuleCode(MultipleModuleCode.MODULE_1); + break; + } else if (!deviceState.getTitrationModuleStateMap().get(MultipleModuleCode.MODULE_2).isTubeExist()) {//如果滴定位2没有试管的话 + deviceState.getTitrationModuleStateMap().get(MultipleModuleCode.MODULE_2).setTubeExist(true); + craftsContext.setCurrentTitrationModuleCode(MultipleModuleCode.MODULE_2); + break; + } else { + //都没有空位置 + sleep(2 * 1000L); + } + } + transferModuleService.requestTransferModule();//申请使用机械臂 + if (TubeCurrentLocal.TRAY.equals(craftsContext.getTubeCurrentLocal())) {//判断试管是否在托盘中 + titrationModuleService.titrationMotorOrigin(craftsContext.getCurrentTitrationModuleCode());//滴定电机回原点 + transferModuleService.roboticMoveToTubePosition(craftsContext.getTubeNum()); //移动到需要移动的试管为止,z轴先抬升,再移动到试管上方 + transferModuleService.clawOpen();//打开夹爪 + transferModuleService.zMoveDownWithTrayArea(); //z轴下降 + transferModuleService.clawClose(); //关闭夹爪 + //TODO 拍摄照片判断滴定位是否有试管 + transferModuleService.roboticMoveToTitration(craftsContext.getCurrentHeatModuleCode()); //移动到滴定位上方 + transferModuleService.zMoveDownWithTitrationArea();//z轴下降 + transferModuleService.clawOpen(); //打开夹爪 + //TODO 拍摄照片判断滴定位是否有试管 + transferModuleService.roboticMoveToOrigin();//机械臂回到原点 + } else if (TubeCurrentLocal.HEAT.equals(craftsContext.getTubeCurrentLocal())) {//判断试管是否在加热位 + titrationModuleService.titrationMotorOrigin(craftsContext.getCurrentTitrationModuleCode());//滴定电机回原点 + transferModuleService.roboticMoveToHeat(craftsContext.getCurrentHeatModuleCode()); //移动到需要移动的试管为止,z轴先抬升,再移动到试管上方 + transferModuleService.clawOpen();//打开夹爪 + transferModuleService.zMoveDownWithHeatArea();//z轴下降 + transferModuleService.clawClose(); //关闭夹爪 + transferModuleService.roboticMoveToTitration(craftsContext.getCurrentHeatModuleCode());//移动到滴定位上方 + transferModuleService.zMoveDownWithTitrationArea();//z轴下降 + transferModuleService.clawOpen();//打开夹爪 + //TODO 拍摄照片判断滴定位是否有试管 + transferModuleService.roboticMoveToOrigin();//机械臂回到原点 + } + transferModuleService.releaseTransferModule();//释放机械臂 + } } //移动至加热 - private void moveToHeat() { + private void moveToHeat(CraftsContext craftsContext) throws Exception { //动态分配使用的模块 + if (!TubeCurrentLocal.HEAT.equals(craftsContext.getTubeCurrentLocal())) {//如果试管不在滴定位的话 + while (true) { + if (!deviceState.getHeatModuleStateMap().get(MultipleModuleCode.MODULE_1).isTubeExist()) {//如果滴定位1没有试管的话 + deviceState.getHeatModuleStateMap().get(MultipleModuleCode.MODULE_1).setTubeExist(true); + craftsContext.setCurrentHeatModuleCode(MultipleModuleCode.MODULE_1); + break; + } else if (!deviceState.getHeatModuleStateMap().get(MultipleModuleCode.MODULE_2).isTubeExist()) {//如果滴定位2没有试管的话 + deviceState.getHeatModuleStateMap().get(MultipleModuleCode.MODULE_2).setTubeExist(true); + craftsContext.setCurrentHeatModuleCode(MultipleModuleCode.MODULE_2); + break; + } else { + //都没有空位置 + sleep(2 * 1000L); + } + transferModuleService.requestTransferModule();//申请使用机械臂 + if (TubeCurrentLocal.TRAY.equals(craftsContext.getTubeCurrentLocal())) {//判断试管是否在托盘中 + transferModuleService.roboticMoveToTubePosition(craftsContext.getTubeNum());//移动到需要移动的试管为止,z轴先抬升,再移动到试管上方 + transferModuleService.clawOpen();//打开夹爪 + transferModuleService.zMoveDownWithTitrationArea();//z轴下降 + transferModuleService.clawClose(); //关闭夹爪 + transferModuleService.roboticMoveToHeat(craftsContext.getCurrentHeatModuleCode());//移动到加热位上方 + transferModuleService.zMoveDownWithHeatArea();//z轴下降 + transferModuleService.clawOpen();//打开夹爪 + transferModuleService.roboticMoveToOrigin();//机械臂回到原点 + } else if (TubeCurrentLocal.HEAT.equals(craftsContext.getTubeCurrentLocal())) {//判断试管是否在滴定位 + titrationModuleService.titrationMotorOrigin(craftsContext.getCurrentTitrationModuleCode());//滴定电机回原点 + transferModuleService.roboticMoveToTitration(craftsContext.getCurrentTitrationModuleCode());//移动到需要移动的试管为止,z轴先抬升,再移动到试管上方 + transferModuleService.clawOpen();//打开夹爪 + transferModuleService.zMoveDownWithTitrationArea();//z轴下降 + transferModuleService.clawClose(); //关闭夹爪 + transferModuleService.roboticMoveToHeat(craftsContext.getCurrentHeatModuleCode());//移动到加热位上方 + transferModuleService.zMoveDownWithHeatArea();//z轴下降 + transferModuleService.clawOpen();//打开夹爪 + transferModuleService.roboticMoveToOrigin();//机械臂回到原点 + } + transferModuleService.releaseTransferModule();//释放机械臂 + } + + } } /** diff --git a/src/main/java/com/iflytop/colortitration/app/service/module/HeatModuleService.java b/src/main/java/com/iflytop/colortitration/app/service/module/HeatModuleService.java index e820006..82a21d1 100644 --- a/src/main/java/com/iflytop/colortitration/app/service/module/HeatModuleService.java +++ b/src/main/java/com/iflytop/colortitration/app/service/module/HeatModuleService.java @@ -1,6 +1,9 @@ package com.iflytop.colortitration.app.service.module; +import cn.hutool.json.JSONObject; import com.iflytop.colortitration.app.common.enums.MultipleModuleCode; +import com.iflytop.colortitration.app.common.utils.CommandUtil; +import com.iflytop.colortitration.app.core.command.CommandFuture; import com.iflytop.colortitration.app.core.command.DeviceCommand; import com.iflytop.colortitration.app.core.command.DeviceCommandGenerator; import com.iflytop.colortitration.app.service.DeviceCommandService; @@ -39,4 +42,18 @@ public class HeatModuleService { deviceCommandService.sendCommand(deviceCommand); } + /** + * 获取指定加热棒温度 + */ + public Double getHeatRodTemperature(MultipleModuleCode heatModuleCode) throws Exception { + DeviceCommand deviceCommand = switch (heatModuleCode) { + case MultipleModuleCode.MODULE_1 -> DeviceCommandGenerator.heatRod1Get(); + case MultipleModuleCode.MODULE_2 -> DeviceCommandGenerator.heatRod2Get(); + }; + CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(deviceCommand); + CommandUtil.wait(deviceCommandFuture); + JSONObject result = deviceCommandFuture.getResponseResult(); + return result.getDouble("temperature"); + } + } diff --git a/src/main/java/com/iflytop/colortitration/app/service/module/TransferModuleService.java b/src/main/java/com/iflytop/colortitration/app/service/module/TransferModuleService.java index 59b7e8d..dee0405 100644 --- a/src/main/java/com/iflytop/colortitration/app/service/module/TransferModuleService.java +++ b/src/main/java/com/iflytop/colortitration/app/service/module/TransferModuleService.java @@ -73,7 +73,7 @@ public class TransferModuleService { } /** - * 机械臂移动到指定试管为止 + * 机械臂移动到指定托盘试管上方 */ public void roboticMoveToTubePosition(Integer index) throws Exception { Point3D position = positionService.getPositionByCode(DevicePositionCode.tube).getPoint3D(); //根据index和第一个托盘试管的位置计算index试管的位置 todo