diff --git a/src/main/java/com/iflytop/gd/app/cmd/DoorCloseCommand.java b/src/main/java/com/iflytop/gd/app/cmd/DoorCloseCommand.java new file mode 100644 index 0000000..e3ef965 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/DoorCloseCommand.java @@ -0,0 +1,34 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.app.service.DevicePositionService; +import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.enums.data.DevicePositionCode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 关门 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("door_close")//业务指令注解 +public class DoorCloseCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + private final DevicePositionService devicePositionService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + return runAsync(() -> { + Double doorOpenDistance = devicePositionService.getPosition(DevicePositionCode.doorClose).getDistance(); + deviceCommandUtilService.doorMove(doorOpenDistance); + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/DoorOpenCommand.java b/src/main/java/com/iflytop/gd/app/cmd/DoorOpenCommand.java new file mode 100644 index 0000000..13b5281 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/DoorOpenCommand.java @@ -0,0 +1,34 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.app.service.DevicePositionService; +import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.enums.data.DevicePositionCode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 开门 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("door_open")//业务指令注解 +public class DoorOpenCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + private final DevicePositionService devicePositionService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + return runAsync(() -> { + Double doorOpenDistance = devicePositionService.getPosition(DevicePositionCode.doorOpen).getDistance(); + deviceCommandUtilService.doorMove(doorOpenDistance); + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/HeatStartCommand.java b/src/main/java/com/iflytop/gd/app/cmd/HeatStartCommand.java new file mode 100644 index 0000000..d72dc0a --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/HeatStartCommand.java @@ -0,0 +1,34 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.enums.HeatModuleId; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 开始加热 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("heat_start")//业务指令注解 +public class HeatStartCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + String heatId = cmdDTO.getStringParam("heatId"); + Double temperature = cmdDTO.getDoubleParam("temperature"); + HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); + return runAsync(() -> { + deviceCommandUtilService.heatRodOpen(heatModuleId, temperature); + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/HeatStopCommand.java b/src/main/java/com/iflytop/gd/app/cmd/HeatStopCommand.java new file mode 100644 index 0000000..0387e5a --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/HeatStopCommand.java @@ -0,0 +1,33 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.enums.HeatModuleId; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 停止加热 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("heat_stop")//业务指令注解 +public class HeatStopCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + String heatId = cmdDTO.getStringParam("heatId"); + HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); + return runAsync(() -> { + deviceCommandUtilService.heatRodClose(heatModuleId); + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/MoveToHeatAreaCommand.java b/src/main/java/com/iflytop/gd/app/cmd/MoveToHeatAreaCommand.java new file mode 100644 index 0000000..20a18c1 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/MoveToHeatAreaCommand.java @@ -0,0 +1,74 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.bo.Point3D; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.app.service.DevicePositionService; +import com.iflytop.gd.app.service.GantryArmService; +import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.enums.HeatModuleId; +import com.iflytop.gd.common.enums.data.DevicePositionCode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 移至加热 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("move_to_heat_area")//业务指令注解 +public class MoveToHeatAreaCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + private final DevicePositionService devicePositionService; + private final GantryArmService gantryArmService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + String heatId = cmdDTO.getStringParam("heatId"); + HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); + return runAsync(() -> { + Point3D liquidAreaTrayPoint3D = devicePositionService.getPosition(DevicePositionCode.liquidAreaTrayPoint).getPoint3D();//获取加液区托盘夹爪点 + deviceCommandUtilService.gantryMove(liquidAreaTrayPoint3D); //将机械臂移动至加液区托盘上方 + double clawTrayPick = devicePositionService.getPosition(DevicePositionCode.clawTrayPick).getDistance();//获取夹爪托盘夹取距离 + deviceCommandUtilService.clawMove(clawTrayPick);//将夹爪张开 + double clawDescend = devicePositionService.getPosition(DevicePositionCode.clawDescend).getDistance();//获取下降机械臂使夹爪可以夹住的距离 + deviceCommandUtilService.gantryZMove(clawDescend); //下降机械臂使夹爪可以夹住托盘 + double clawTrayGrip = devicePositionService.getPosition(DevicePositionCode.clawTrayGrip).getDistance();//获取夹爪托盘夹紧距离 + deviceCommandUtilService.clawMove(clawTrayGrip);//将夹爪收紧 + double traySafetyHeight = devicePositionService.getPosition(DevicePositionCode.traySafetyHeight).getDistance();//获取移动托盘的安全高度 + deviceCommandUtilService.gantryZMoveBy(-traySafetyHeight);//机械臂提升至移动托盘的安全高度 + Point3D heatAreaTrayClawPoint3D = deviceCommandUtilService.getHeatAreaTrayClawPoint3D(heatModuleId);//获取指定托盘上方点位 + Point3D heatAreaTrayClawSafetyHeightPoint3D = new Point3D(heatAreaTrayClawPoint3D.getX(), heatAreaTrayClawPoint3D.getY(), heatAreaTrayClawPoint3D.getZ() - traySafetyHeight);//加热区托盘点位上方减去移动托盘的安全高度 + deviceCommandUtilService.gantryMove(heatAreaTrayClawSafetyHeightPoint3D);//将携带托盘的机械臂移动至托盘上方 + deviceCommandUtilService.gantryZMoveBy(traySafetyHeight);//下降机械臂将托盘与试管落入加热区 + deviceCommandUtilService.gantryZMoveBy(-clawDescend);//将机械臂提升至托盘上方高度 + Point3D capStorageCapClawPoint3D = devicePositionService.getPosition(DevicePositionCode.capStorageCapClawPoint).getPoint3D();//获取拍子存放区上方点位; + deviceCommandUtilService.gantryMove(capStorageCapClawPoint3D);//移动机械臂至拍子存放区上方 + //下降机械臂使夹爪可以夹住拍子 + double clawCapPick = devicePositionService.getPosition(DevicePositionCode.clawCapPick).getDistance(); //拍子夹取距离 + deviceCommandUtilService.clawMove(clawCapPick);//将夹爪张开 + deviceCommandUtilService.gantryZMove(clawDescend); //下降机械臂使夹爪可以夹住拍子 + double clawCapGrip = devicePositionService.getPosition(DevicePositionCode.clawCapGrip).getDistance(); //获取拍子夹紧距离 + deviceCommandUtilService.clawMove(clawCapGrip);//将夹爪收紧 + double capSafetyHeight = devicePositionService.getPosition(DevicePositionCode.capSafetyHeight).getDistance();//获取移动拍子的安全高度 + deviceCommandUtilService.gantryZMoveBy(-capSafetyHeight);//机械臂提升至移动拍子的安全高度 + deviceCommandUtilService.capMotorMove(1); //提升拍子存放区1个位置 + Point3D heatAreaCapClawPoint3D = deviceCommandUtilService.getHeatAreaCapClawPointPoint3D(heatModuleId);//获取托盘上方拍子点位 + Point3D heatAreaCapClawSafetyHeightPoint3D = new Point3D(heatAreaCapClawPoint3D.getX(), heatAreaCapClawPoint3D.getY(), heatAreaCapClawPoint3D.getZ() - capSafetyHeight);//加热区拍子上方加上移动拍子的安全高度 + deviceCommandUtilService.gantryMove(heatAreaCapClawSafetyHeightPoint3D);//将机械臂移动至拍子上方加上移动拍子的安全高度 + deviceCommandUtilService.gantryZMoveBy(traySafetyHeight); //降下机械臂使拍子盖住托盘试管 + deviceCommandUtilService.clawMove(clawCapPick);//将夹爪张开 + deviceCommandUtilService.gantryZMoveBy(-clawDescend);//抬升机械臂至托盘上方 + gantryArmService.setLiquidIdleTrue();//释放加液区等待 + + double trayLower = devicePositionService.getPosition(DevicePositionCode.trayLower).getDistance(); //获取加热位下降托盘位置 + deviceCommandUtilService.heaterMotorMove(heatModuleId, trayLower);//下降加热位托盘 + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/MoveToSolutionAreaCommand.java b/src/main/java/com/iflytop/gd/app/cmd/MoveToSolutionAreaCommand.java new file mode 100644 index 0000000..85bac20 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/MoveToSolutionAreaCommand.java @@ -0,0 +1,75 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.bo.Point3D; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.app.service.DevicePositionService; +import com.iflytop.gd.app.service.GantryArmService; +import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.enums.HeatModuleId; +import com.iflytop.gd.common.enums.data.DevicePositionCode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 移至加液 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("move_to_solution_area")//业务指令注解 +public class MoveToSolutionAreaCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + private final DevicePositionService devicePositionService; + private final GantryArmService gantryArmService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + String heatId = cmdDTO.getStringParam("heatId"); + HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); + return runAsync(() -> { + gantryArmService.waitLiquidIdle();//等待加液区空闲 + + double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); //获取加热位抬升托盘位置 + deviceCommandUtilService.heaterMotorMove(heatModuleId, trayLift);//抬升加热位托盘 + //TODO 判断托盘是否有拍子 + Point3D heatAreaCapClawPoint3D = deviceCommandUtilService.getHeatAreaCapClawPointPoint3D(heatModuleId);//获取托盘上方拍子点位 + deviceCommandUtilService.gantryMove(heatAreaCapClawPoint3D);//将机械臂移动至拍子上方 + double clawCapPick = devicePositionService.getPosition(DevicePositionCode.clawCapPick).getDistance(); //拍子夹取距离 + deviceCommandUtilService.clawMove(clawCapPick);//将夹爪张开 + double clawDescend = devicePositionService.getPosition(DevicePositionCode.clawDescend).getDistance();//获取下降机械臂使夹爪可以夹住的距离 + deviceCommandUtilService.gantryZMove(clawDescend); //下降机械臂使夹爪可以夹住拍子 + double clawCapGrip = devicePositionService.getPosition(DevicePositionCode.clawCapGrip).getDistance(); //获取拍子夹紧距离 + deviceCommandUtilService.clawMove(clawCapGrip);//将夹爪收紧 + double capSafetyHeight = devicePositionService.getPosition(DevicePositionCode.capSafetyHeight).getDistance();//获取移动拍子的安全高度 + deviceCommandUtilService.gantryZMoveBy(-capSafetyHeight);//机械臂提升至移动拍子的安全高度 + deviceCommandUtilService.capMotorMove(-1); //下降拍子存放区1个位置 + Point3D capStorageCapClawPoint3D = devicePositionService.getPosition(DevicePositionCode.capStorageCapClawPoint).getPoint3D();//获取拍子存放区上方点位; + Point3D capStorageCapClawSafetyHeightPoint3D = new Point3D(capStorageCapClawPoint3D.getX(), capStorageCapClawPoint3D.getY(), capStorageCapClawPoint3D.getZ() - capSafetyHeight);//拍子存放区上方加上移动拍子的安全高度 + deviceCommandUtilService.gantryMove(capStorageCapClawSafetyHeightPoint3D);//移动机械臂至拍子存放区上方上减去拍子的安全高度 + deviceCommandUtilService.gantryZMoveBy(capSafetyHeight);//下降机械臂,使拍子落入存放区 + deviceCommandUtilService.clawMove(clawCapPick); //松开夹爪,放开拍子 + deviceCommandUtilService.gantryZMoveBy(clawDescend);//将机械臂抬升至托盘上方 + Point3D heatAreaTrayClawPoint3D = deviceCommandUtilService.getHeatAreaTrayClawPoint3D(heatModuleId);//获取指定托盘上方点位 + deviceCommandUtilService.gantryMove(heatAreaTrayClawPoint3D);//将机械臂移动至托盘上方 + double clawTrayPick = devicePositionService.getPosition(DevicePositionCode.clawTrayPick).getDistance();//获取夹爪托盘夹取距离 + deviceCommandUtilService.clawMove(clawTrayPick);//将夹爪张开 + deviceCommandUtilService.gantryZMove(clawDescend); //下降机械臂使夹爪可以夹住托盘 + double clawTrayGrip = devicePositionService.getPosition(DevicePositionCode.clawTrayGrip).getDistance();//获取夹爪托盘夹紧距离 + deviceCommandUtilService.clawMove(clawTrayGrip);//将夹爪收紧 + double traySafetyHeight = devicePositionService.getPosition(DevicePositionCode.traySafetyHeight).getDistance();//获取移动托盘的安全高度 + deviceCommandUtilService.gantryZMoveBy(-traySafetyHeight);//机械臂提升至移动托盘的安全高度 + Point3D liquidAreaTrayPoint3D = devicePositionService.getPosition(DevicePositionCode.liquidAreaTrayPoint).getPoint3D();//获取加液区托盘夹爪点 + Point3D liquidAreaTraySafetyHeightPoint3D = new Point3D(liquidAreaTrayPoint3D.getX(), liquidAreaTrayPoint3D.getY(), liquidAreaTrayPoint3D.getZ() - traySafetyHeight);//加液区托盘点位上方加上移动托盘的安全高度 + deviceCommandUtilService.gantryMove(liquidAreaTraySafetyHeightPoint3D);//移动机械臂至加液区托盘点位上方减去移动托盘的安全高度 + deviceCommandUtilService.gantryZMoveBy(traySafetyHeight);//下降机械臂将托盘与试管落入加液区 + deviceCommandUtilService.clawMove(clawTrayPick);//松开夹爪,放下托盘 + deviceCommandUtilService.gantryZMoveBy(-clawDescend);//抬升机械臂至托盘上方 + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/ShakeStartCommand.java b/src/main/java/com/iflytop/gd/app/cmd/ShakeStartCommand.java new file mode 100644 index 0000000..37cc119 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/ShakeStartCommand.java @@ -0,0 +1,30 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.common.annotation.CommandMapping; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 开始摇匀 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("shake_start")//业务指令注解 +public class ShakeStartCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + return runAsync(() -> { + deviceCommandUtilService.shakeStart();//开始摇匀 + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/ShakeStopCommand.java b/src/main/java/com/iflytop/gd/app/cmd/ShakeStopCommand.java new file mode 100644 index 0000000..3346839 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/ShakeStopCommand.java @@ -0,0 +1,30 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.common.annotation.CommandMapping; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 结束摇匀 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("shake_stop")//业务指令注解 +public class ShakeStopCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + return runAsync(() -> { + deviceCommandUtilService.shakeStop();//停止摇匀 + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/SolutionAddCommand.java b/src/main/java/com/iflytop/gd/app/cmd/SolutionAddCommand.java new file mode 100644 index 0000000..d2532e2 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/SolutionAddCommand.java @@ -0,0 +1,56 @@ +package com.iflytop.gd.app.cmd; + +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.bo.Point2D; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.ContainerService; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.enums.AcidPumpDevice; +import com.iflytop.gd.common.exception.AppException; +import com.iflytop.gd.common.result.ResultCode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 添加溶液 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("solution_add")//业务指令注解 +public class SolutionAddCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + private final ContainerService containerService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + return runAsync(() -> { + JSONArray dataList = (JSONArray) cmdDTO.getParams().get("dataList"); + for (int i = 0; i < dataList.size(); i++) { + JSONObject tubeSol = dataList.getJSONObject(i); + Integer tubeNum = tubeSol.getInt("tubeNum"); + JSONArray solutionList = tubeSol.getJSONArray("solutionList"); + for (int j = 0; j < solutionList.size(); j++) { + JSONObject addSolution = solutionList.getJSONObject(j); + Long solId = addSolution.getLong("solId"); + Double volume = addSolution.getDouble("volume"); + AcidPumpDevice acidPumpDevice = containerService.getPumpBySolutionId(solId); + if (acidPumpDevice == null) { + throw new AppException(ResultCode.CRAFT_CONTAINER_NOT_FOUND); + } + Point2D tubePoint2D = deviceCommandUtilService.getPointByTubeNum(tubeNum);//根据试管编号获取点位 + deviceCommandUtilService.dualRobotMovePoint(tubePoint2D);//移动加液机械臂到指定试管点位 + deviceCommandUtilService.acidPumpMoveBy(acidPumpDevice, volume);//添加溶液 + } + } + deviceCommandUtilService.dualRobotOrigin(); + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/TakePhotoCommand.java b/src/main/java/com/iflytop/gd/app/cmd/TakePhotoCommand.java new file mode 100644 index 0000000..baab915 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/TakePhotoCommand.java @@ -0,0 +1,32 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.common.annotation.CommandMapping; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 拍照 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("take_photo")//业务指令注解 +public class TakePhotoCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + return runAsync(() -> { + deviceCommandUtilService.fillLightOpen(100.0);//TODO 开启补光灯 亮度从数据库获取 + deviceCommandUtilService.takePhoto();//拍照 + deviceCommandUtilService.fillLightClose();//关闭补光灯 + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/TrayDownCommand.java b/src/main/java/com/iflytop/gd/app/cmd/TrayDownCommand.java new file mode 100644 index 0000000..69445f1 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/TrayDownCommand.java @@ -0,0 +1,38 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.core.CraftsDebugGenerator; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.app.service.DevicePositionService; +import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.enums.HeatModuleId; +import com.iflytop.gd.common.enums.data.DevicePositionCode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 降下托盘 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("tray_down")//业务指令注解 +public class TrayDownCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + private final DevicePositionService devicePositionService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + String heatId = cmdDTO.getStringParam("heatId"); + HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); + return runAsync(() -> { + double trayLower = devicePositionService.getPosition(DevicePositionCode.trayLower).getDistance(); //获取加热位下降托盘位置 + deviceCommandUtilService.heaterMotorMove(heatModuleId, trayLower);//下降加热位托盘 + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/TrayUpCommand.java b/src/main/java/com/iflytop/gd/app/cmd/TrayUpCommand.java new file mode 100644 index 0000000..c309d60 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/cmd/TrayUpCommand.java @@ -0,0 +1,38 @@ +package com.iflytop.gd.app.cmd; + +import com.iflytop.gd.app.core.BaseCommandHandler; +import com.iflytop.gd.app.core.CraftsDebugGenerator; +import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandUtilService; +import com.iflytop.gd.app.service.DevicePositionService; +import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.enums.HeatModuleId; +import com.iflytop.gd.common.enums.data.DevicePositionCode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +/** + * 抬起托盘 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@CommandMapping("tray_up")//业务指令注解 +public class TrayUpCommand extends BaseCommandHandler { + private final DeviceCommandUtilService deviceCommandUtilService; + private final DevicePositionService devicePositionService; + + @Override + public CompletableFuture handle(CmdDTO cmdDTO) { + String heatId = cmdDTO.getStringParam("heatId"); + HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); + return runAsync(() -> { + double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); //获取加热位抬升托盘位置 + deviceCommandUtilService.heaterMotorMove(heatModuleId, trayLift);//抬升加热位托盘 + }); + } +} + diff --git a/src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftDownCommandHandler.java b/src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftDownCommandHandler.java index acc8aef..7644c5b 100644 --- a/src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftDownCommandHandler.java +++ b/src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftDownCommandHandler.java @@ -29,7 +29,7 @@ public class CoverElevatorLiftDownCommandHandler extends BaseCommandHandler { Double distance = cmdDTO.getDoubleParam("distance"); Double velocity = cmdDTO.getDoubleParam("velocity"); - if(velocity != null){ + if (velocity != null) { DeviceCommandBundle deviceCommand = DeviceCommandGenerator.trayMotorSet(velocity); CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand); commandWait(deviceCommandFuture); diff --git a/src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftUpCommandHandler.java b/src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftUpCommandHandler.java index 8105667..5cc4482 100644 --- a/src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftUpCommandHandler.java +++ b/src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftUpCommandHandler.java @@ -30,7 +30,7 @@ public class CoverElevatorLiftUpCommandHandler extends BaseCommandHandler { Double distance = cmdDTO.getDoubleParam("distance"); Double velocity = cmdDTO.getDoubleParam("velocity"); - if(velocity != null){ + if (velocity != null) { DeviceCommandBundle deviceCommand = DeviceCommandGenerator.trayMotorSet(velocity); CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand); commandWait(deviceCommandFuture); diff --git a/src/main/java/com/iflytop/gd/app/cmd/debug/LiquidPumpStartCommandHandler.java b/src/main/java/com/iflytop/gd/app/cmd/debug/LiquidPumpStartCommandHandler.java index 10f1101..3ffb0a1 100644 --- a/src/main/java/com/iflytop/gd/app/cmd/debug/LiquidPumpStartCommandHandler.java +++ b/src/main/java/com/iflytop/gd/app/cmd/debug/LiquidPumpStartCommandHandler.java @@ -8,7 +8,6 @@ import com.iflytop.gd.common.cmd.CommandFuture; import com.iflytop.gd.common.cmd.DeviceCommandBundle; import com.iflytop.gd.common.cmd.DeviceCommandGenerator; import com.iflytop.gd.common.enums.AcidPumpDevice; -import com.iflytop.gd.common.enums.cmd.CmdDirection; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -33,7 +32,7 @@ public class LiquidPumpStartCommandHandler extends BaseCommandHandler { Double velocity = cmdDTO.getDoubleParam("velocity"); AcidPumpDevice acidPumpDevice = AcidPumpDevice.valueOf(index); DeviceCommandBundle deviceCommand; - if(velocity != null) { + if (velocity != null) { switch (acidPumpDevice) { case acid_pump_01 -> deviceCommand = DeviceCommandGenerator.acidPump1Set(velocity); case acid_pump_02 -> deviceCommand = DeviceCommandGenerator.acidPump2Set(velocity); diff --git a/src/main/java/com/iflytop/gd/app/cmd/debug/ShakerStartCommandHandler.java b/src/main/java/com/iflytop/gd/app/cmd/debug/ShakerStartCommandHandler.java index c6b26a9..afdfbc0 100644 --- a/src/main/java/com/iflytop/gd/app/cmd/debug/ShakerStartCommandHandler.java +++ b/src/main/java/com/iflytop/gd/app/cmd/debug/ShakerStartCommandHandler.java @@ -27,7 +27,7 @@ public class ShakerStartCommandHandler extends BaseCommandHandler { public CompletableFuture handle(CmdDTO cmdDTO) { return runAsync(() -> { Double velocity = cmdDTO.getDoubleParam("velocity"); - if(velocity != null) { + if (velocity != null) { DeviceCommandBundle deviceCommand = DeviceCommandGenerator.shakeMotorSet(velocity); CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand); commandWait(deviceCommandFuture); diff --git a/src/main/java/com/iflytop/gd/app/controller/SystemController.java b/src/main/java/com/iflytop/gd/app/controller/SystemController.java index 538df98..ddcff76 100644 --- a/src/main/java/com/iflytop/gd/app/controller/SystemController.java +++ b/src/main/java/com/iflytop/gd/app/controller/SystemController.java @@ -1,6 +1,6 @@ package com.iflytop.gd.app.controller; -import com.iflytop.gd.app.core.DeviceState; +import com.iflytop.gd.app.core.device.DeviceState; import com.iflytop.gd.app.model.dto.SetSystemDatetimeDTO; import com.iflytop.gd.app.service.SystemConfigService; import com.iflytop.gd.common.result.Result; @@ -9,10 +9,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @Tag(name = "系统设置") @RestController @@ -25,16 +22,22 @@ public class SystemController { @Operation(summary = "是否启动虚拟模式") @PostMapping("/virtual") public Result changeVirtualMode(Boolean mode) { - DeviceState.getInstance().getVirtual().set(mode); + DeviceState.getInstance().setVirtual(mode); return Result.success(); } + @Operation(summary = "系统状态") + @GetMapping("/device-status") + public Result getDeviceStatus() { + return Result.success(DeviceState.getInstance()); + } @Operation(summary = "设置系统时间") - @PostMapping("/setDatetime") + @PostMapping("/datetime") public Result setDatetime(@Valid @RequestBody SetSystemDatetimeDTO setSystemDatetimeDTO) { systemConfigService.setDatetime(setSystemDatetimeDTO.getDatetime()); return Result.success(); } + } diff --git a/src/main/java/com/iflytop/gd/app/core/DeviceState.java b/src/main/java/com/iflytop/gd/app/core/DeviceState.java deleted file mode 100644 index 973d007..0000000 --- a/src/main/java/com/iflytop/gd/app/core/DeviceState.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.iflytop.gd.app.core; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -@Schema(description = "当前设备状态") -@Data -public class DeviceState { - private final Lock liquidLock = new ReentrantLock(); - private final Condition liquidIdleCondition = liquidLock.newCondition(); - - @Schema(description = "虚拟模式,true为虚拟") - private AtomicBoolean virtual = new AtomicBoolean(false); - - @Schema(description = "是否是急停状态,true为急停") - private AtomicBoolean emergencyStop = new AtomicBoolean(false); - - @Schema(description = "门状态,true为开启状态,false为关闭状态") - private AtomicBoolean doorStatus = new AtomicBoolean(false); - - @Schema(description = "龙门架机械臂状态") - private AtomicReference gantryArm = new AtomicReference<>(new GantryArm()); - - @Schema(description = "加液操作区属性") - private AtomicReference liquidArea = new AtomicReference<>(new LiquidArea()); - - @Schema(description = "加热操作区属性") - private List heatArea = new ArrayList<>(); - - @Schema(description = "碱容器状态") - private AtomicReference alkaliBucket = new AtomicReference<>(new LiquidBucket()); - - @Data - private static class GantryArm { - @Schema(description = "是否空闲,true为空闲,false为占用") - private AtomicBoolean idle = new AtomicBoolean(true); - } - - @Data - public static class LiquidArea { - @Schema(description = "是否空闲,true为空闲,false为占用") - private AtomicBoolean idle = new AtomicBoolean(true); - - @Schema(description = "是否正在摇匀,true为正在摇匀,false为停止摇匀") - private AtomicBoolean isShaking = new AtomicBoolean(false); - - @Schema(description = "托盘状态,0为无托盘,1为有托盘") - private AtomicInteger trayStatus = new AtomicInteger(0); - - @Schema(description = "溶液容器状态") - private List solutionBucket = new ArrayList<>(); - - @Schema(description = "是否正在加液,true正在加液,false未运行") - private AtomicBoolean isPumping = new AtomicBoolean(false); - } - - @Data - public static class HeatArea { - @Schema(description = "加热器设备id") - private String hardwareId; - - @Schema(description = "托盘状态,0为无托盘,1为有托盘,2为托盘抬起") - private AtomicInteger trayStatus = new AtomicInteger(0); - - @Schema(description = "是否正在加热,true为正在加热,false为未加热") - private AtomicBoolean isHeating = new AtomicBoolean(false); - - @Schema(description = "拍子状态,true为存在拍子,false无拍子") - private AtomicBoolean capStatus = new AtomicBoolean(false); - - @Schema(description = "加热器当前温度") - private AtomicInteger temperature = new AtomicInteger(0); - } - - @Data - public static class LiquidBucket { - @Schema(description = "容器是否为空,true为空,false不为空") - private AtomicBoolean isEmpty = new AtomicBoolean(false); - - @Schema(description = "容器是否为满,true为满,false不满") - private AtomicBoolean isFull = new AtomicBoolean(false); - } - - private DeviceState() { - } - - public static DeviceState getInstance() { - return DeviceStateHolder.INSTANCE; - } - - private static class DeviceStateHolder { - private static final DeviceState INSTANCE = new DeviceState(); - } - - - /** - * 等待加液区空闲 - */ - public void waitLiquidIdle() { - liquidLock.lock(); - try { - while (!DeviceState.getInstance().getLiquidArea().get().getIdle().get()) { - liquidIdleCondition.await(); - } - } catch (InterruptedException e) { - throw new RuntimeException("等待加液区空闲错误", e); - } finally { - liquidLock.unlock(); - } - } - - /** - * 释放加液区 - */ - public void setLiquidIdleTrue() { - liquidLock.lock(); - try { - DeviceState.getInstance().getLiquidArea().get().getIdle().set(true); - liquidIdleCondition.signalAll(); // 唤醒所有等待的线程 - } finally { - liquidLock.unlock(); - } - } -} diff --git a/src/main/java/com/iflytop/gd/app/core/device/DeviceState.java b/src/main/java/com/iflytop/gd/app/core/device/DeviceState.java new file mode 100644 index 0000000..6955f52 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/core/device/DeviceState.java @@ -0,0 +1,108 @@ +package com.iflytop.gd.app.core.device; + +import com.iflytop.gd.common.enums.HeatModuleId; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Schema(description = "当前设备状态") +@Data +public class DeviceState { + @Schema(description = "虚拟模式,true为虚拟") + private boolean virtual = false; + + @Schema(description = "是否是急停状态,true为急停") + private boolean emergencyStop = false; + + @Schema(description = "门状态,true为开启状态,false为关闭状态") + private boolean doorStatus = false; + + @Schema(description = "龙门架机械臂状态") + private GantryArm gantryArm = new GantryArm(); + + @Schema(description = "加液操作区属性") + private SolutionArea solutionArea = new SolutionArea(); + + @Schema(description = "加热操作区属性") + private List heatArea = new ArrayList<>(); + + @Schema(description = "碱容器状态") + private SolutionContainer alkaliContainer; + + @Data + public static class GantryArm { + @Schema(description = "是否空闲,true为空闲,false为占用") + private boolean idle = true; + } + + @Data + public static class SolutionArea { + @Schema(description = "是否空闲,true为空闲,false为占用") + private boolean idle = true; + + @Schema(description = "是否正在摇匀,true为正在摇匀,false为停止摇匀") + private boolean shaking = false; + + @Schema(description = "托盘状态,0为无托盘,1为有托盘") + private int trayStatus = 0; + + @Schema(description = "溶液容器状态") + private List solutionContainer = new ArrayList<>(); + + @Schema(description = "是否正在加液,true正在加液,false未运行") + private boolean pumping = false; + } + + @Data + public static class HeatArea { + @Schema(description = "加热器设备id") + private HeatModuleId heatModuleId; + + @Schema(description = "托盘状态,0为无托盘,1为有托盘,2为托盘抬起") + private int trayStatus = 0; + + @Schema(description = "是否正在加热,true为正在加热,false为未加热") + private boolean heating = false; + + @Schema(description = "拍子状态,true为存在拍子,false无拍子") + private boolean capStatus = false; + + @Schema(description = "加热器当前温度") + private double temperature = 0.0; + + public HeatArea(HeatModuleId heatModuleId) { + this.heatModuleId = heatModuleId; + } + } + + @Data + public static class SolutionContainer { + @Schema(description = "容器id") + private Long id; + + @Schema(description = "容器是否为空,true为空,false不为空") + private boolean empty = false; + + @Schema(description = "容器是否为满,true为满,false不满") + private boolean full = false; + + public SolutionContainer(Long id) { + this.id = id; + } + } + + private DeviceState() { + } + + public static DeviceState getInstance() { + return DeviceStateHolder.INSTANCE; + } + + private static class DeviceStateHolder { + private static final DeviceState INSTANCE = new DeviceState(); + } + + +} diff --git a/src/main/java/com/iflytop/gd/app/core/device/GantryArm.java b/src/main/java/com/iflytop/gd/app/core/device/GantryArm.java new file mode 100644 index 0000000..d3d75f4 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/core/device/GantryArm.java @@ -0,0 +1,4 @@ +package com.iflytop.gd.app.core.device; + +public class GantryArm { +} diff --git a/src/main/java/com/iflytop/gd/app/model/dto/CmdDTO.java b/src/main/java/com/iflytop/gd/app/model/dto/CmdDTO.java index 82a95c2..d80569a 100644 --- a/src/main/java/com/iflytop/gd/app/model/dto/CmdDTO.java +++ b/src/main/java/com/iflytop/gd/app/model/dto/CmdDTO.java @@ -2,7 +2,6 @@ package com.iflytop.gd.app.model.dto; import cn.hutool.json.JSONUtil; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -24,32 +23,29 @@ public class CmdDTO { @Schema(description = "参数") private Map params; + // 获取 Double 类型的参数,null 或空字符串时返回 null public Double getDoubleParam(String key) { - return Optional.ofNullable(params.get(key)) - .map(Object::toString) - .filter(value -> !value.isEmpty()) - .map(Double::parseDouble) - .orElse(null); + String value = getStringParam(key); + return (value != null && !value.isEmpty()) ? Double.parseDouble(value) : null; } + // 获取 String 类型的参数,null 或空字符串时返回 null public String getStringParam(String key) { - return (String) params.get(key); + Object value = params.get(key); + // 确保值不是 null 或空字符串,转换成 String 后返回 + return (value != null && !value.toString().isEmpty()) ? value.toString() : null; } + // 获取 Integer 类型的参数,null 或空字符串时返回 null public Integer getIntegerParam(String key) { - return Optional.ofNullable(params.get(key)) - .map(Object::toString) - .filter(value -> !value.isEmpty()) - .map(Integer::parseInt) - .orElse(null); + String value = getStringParam(key); + return (value != null && !value.isEmpty()) ? Integer.parseInt(value) : null; } + // 获取 Boolean 类型的参数,null 或空字符串时返回 null public Boolean getBooleanParam(String key) { - return Optional.ofNullable(params.get(key)) - .map(Object::toString) - .filter(value -> !value.isEmpty()) - .map(Boolean::parseBoolean) - .orElse(null); + String value = getStringParam(key); + return (value != null && !value.isEmpty()) ? Boolean.parseBoolean(value) : null; } @Override diff --git a/src/main/java/com/iflytop/gd/app/service/CraftsStepService.java b/src/main/java/com/iflytop/gd/app/service/CraftsStepService.java index 0ee9e77..df9ec7f 100644 --- a/src/main/java/com/iflytop/gd/app/service/CraftsStepService.java +++ b/src/main/java/com/iflytop/gd/app/service/CraftsStepService.java @@ -3,7 +3,6 @@ package com.iflytop.gd.app.service; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import com.iflytop.gd.app.core.CraftsDebugGenerator; -import com.iflytop.gd.app.core.DeviceState; import com.iflytop.gd.app.model.bo.CraftsStep; import com.iflytop.gd.app.model.bo.Point2D; import com.iflytop.gd.app.model.bo.Point3D; @@ -25,6 +24,7 @@ public class CraftsStepService { private final DevicePositionService devicePositionService; private final ContainerService containerService; private final WebSocketService webSocketService; + private final GantryArmService gantryArmService; /** @@ -53,7 +53,7 @@ public class CraftsStepService { HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "等待加液区空闲", null)); - DeviceState.getInstance().waitLiquidIdle();//等待加液区空闲 + gantryArmService.waitLiquidIdle();//等待加液区空闲 webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "加液区已空闲", null)); double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); //获取加热位抬升托盘位置 @@ -208,7 +208,7 @@ public class CraftsStepService { webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "抬升机械臂至托盘上方", -clawDescend)); deviceCommandUtilService.gantryZMoveBy(-clawDescend);//抬升机械臂至托盘上方 webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "释放加液区等待", null)); - DeviceState.getInstance().setLiquidIdleTrue();//释放加液区等待 + gantryArmService.setLiquidIdleTrue();//释放加液区等待 double trayLower = devicePositionService.getPosition(DevicePositionCode.trayLower).getDistance(); //获取加热位下降托盘位置 webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "下降加热位托盘", trayLower)); @@ -234,7 +234,7 @@ public class CraftsStepService { HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "等待加液区空闲", null)); - DeviceState.getInstance().waitLiquidIdle();//等待加液区空闲 + gantryArmService.waitLiquidIdle();//等待加液区空闲 webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "加液区已空闲", null)); double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); //获取加热位抬升托盘位置 diff --git a/src/main/java/com/iflytop/gd/app/service/DeviceCommandService.java b/src/main/java/com/iflytop/gd/app/service/DeviceCommandService.java index 0e2f228..2802961 100644 --- a/src/main/java/com/iflytop/gd/app/service/DeviceCommandService.java +++ b/src/main/java/com/iflytop/gd/app/service/DeviceCommandService.java @@ -3,7 +3,7 @@ package com.iflytop.gd.app.service; import cn.hutool.json.JSONObject; import com.iflytop.gd.app.core.DebugGenerator; -import com.iflytop.gd.app.core.DeviceState; +import com.iflytop.gd.app.core.device.DeviceState; import com.iflytop.gd.common.cmd.CommandFuture; import com.iflytop.gd.common.cmd.CyclicNumberGenerator; import com.iflytop.gd.common.cmd.DeviceCommandBundle; @@ -94,7 +94,7 @@ public class DeviceCommandService { commandFuture.getDeviceCommandBundle().getDeviceCommand().setCmdId(cmdId); sendCommandFutureMap.put(cmdId, commandFuture); commandFuture.setStartSendTime(System.currentTimeMillis()); - if (!DeviceState.getInstance().getVirtual().get()) { + if (!DeviceState.getInstance().isVirtual()) { if (!hardwareService.sendCommand(commandFuture.getDeviceCommandBundle().getDeviceCommand())) { sendCommandFutureMap.remove(commandFuture.getDeviceCommandBundle().getDeviceCommand().getCmdId()); throw new RuntimeException("向设备发送指令失败"); diff --git a/src/main/java/com/iflytop/gd/app/service/DeviceCommandUtilService.java b/src/main/java/com/iflytop/gd/app/service/DeviceCommandUtilService.java index c6d7410..f68266d 100644 --- a/src/main/java/com/iflytop/gd/app/service/DeviceCommandUtilService.java +++ b/src/main/java/com/iflytop/gd/app/service/DeviceCommandUtilService.java @@ -23,70 +23,77 @@ public class DeviceCommandUtilService { private final DevicePositionService devicePositionService; /** + * 门电机移动 + */ + public void doorMove(double position) throws Exception { + DeviceCommandBundle deviceCommand = DeviceCommandGenerator.doorMove(position); + CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(deviceCommand); + commandWait(deviceCommandFuture); + } + + /** * 龙门架机械臂移动到指定点 */ public void gantryMove(Point3D point) throws Exception { DeviceCommandBundle gantryXMoveDeviceCommand = DeviceCommandGenerator.gantryXMove(point.getX()); DeviceCommandBundle gantryYMoveDeviceCommand = DeviceCommandGenerator.gantryYMove(point.getY()); DeviceCommandBundle gantryZMoveDeviceCommand = DeviceCommandGenerator.gantryZMove(point.getZ()); - CommandFuture gantryXMoveDeviceCommandFuture = deviceCommandService.sendCommand(gantryXMoveDeviceCommand); - CommandFuture gantryYMoveDeviceCommandFuture = deviceCommandService.sendCommand(gantryYMoveDeviceCommand); - CommandFuture gantryZMoveDeviceCommandFuture = deviceCommandService.sendCommand(gantryZMoveDeviceCommand); - commandWait(gantryXMoveDeviceCommandFuture, gantryYMoveDeviceCommandFuture, gantryZMoveDeviceCommandFuture); + CommandFuture[] deviceCommandFutureArr = deviceCommandService.sendCommandQueue(gantryXMoveDeviceCommand, gantryYMoveDeviceCommand, gantryZMoveDeviceCommand); + commandWait(deviceCommandFutureArr); } /** * 龙门架机械臂X轴移动到指定点 */ public void gantryXMove(double position) throws Exception { - DeviceCommandBundle gantryXMoveDeviceCommand = DeviceCommandGenerator.gantryXMove(position); - CommandFuture gantryXMoveDeviceCommandFuture = deviceCommandService.sendCommand(gantryXMoveDeviceCommand); - commandWait(gantryXMoveDeviceCommandFuture); + DeviceCommandBundle deviceCommand = DeviceCommandGenerator.gantryXMove(position); + CommandFuture[] deviceCommandFutureArr = deviceCommandService.sendCommandQueue(deviceCommand); + commandWait(deviceCommandFutureArr); } /** * 龙门架机械臂Y轴移动到指定点 */ public void gantryYMove(double position) throws Exception { - DeviceCommandBundle gantryXMoveDeviceCommand = DeviceCommandGenerator.gantryYMove(position); - CommandFuture gantryXMoveDeviceCommandFuture = deviceCommandService.sendCommand(gantryXMoveDeviceCommand); - commandWait(gantryXMoveDeviceCommandFuture); + DeviceCommandBundle deviceCommand = DeviceCommandGenerator.gantryYMove(position); + CommandFuture[] deviceCommandFutureArr = deviceCommandService.sendCommandQueue(deviceCommand); + commandWait(deviceCommandFutureArr); } /** * 龙门架机械臂Z轴移动到指定点 */ public void gantryZMove(double position) throws Exception { - DeviceCommandBundle gantryXMoveDeviceCommand = DeviceCommandGenerator.gantryZMove(position); - CommandFuture gantryXMoveDeviceCommandFuture = deviceCommandService.sendCommand(gantryXMoveDeviceCommand); - commandWait(gantryXMoveDeviceCommandFuture); + DeviceCommandBundle deviceCommand = DeviceCommandGenerator.gantryZMove(position); + CommandFuture[] deviceCommandFutureArr = deviceCommandService.sendCommandQueue(deviceCommand); + commandWait(deviceCommandFutureArr); } /** * 龙门架机械臂X轴相对移动到指定点 */ public void gantryXMoveBy(double position) throws Exception { - DeviceCommandBundle gantryXMoveDeviceCommand = DeviceCommandGenerator.gantryXMoveBy(position); - CommandFuture gantryXMoveDeviceCommandFuture = deviceCommandService.sendCommand(gantryXMoveDeviceCommand); - commandWait(gantryXMoveDeviceCommandFuture); + DeviceCommandBundle deviceCommand = DeviceCommandGenerator.gantryXMoveBy(position); + CommandFuture[] deviceCommandFutureArr = deviceCommandService.sendCommandQueue(deviceCommand); + commandWait(deviceCommandFutureArr); } /** * 龙门架机械臂Y轴相对移动到指定点 */ public void gantryYMoveBy(double position) throws Exception { - DeviceCommandBundle gantryXMoveDeviceCommand = DeviceCommandGenerator.gantryYMoveBy(position); - CommandFuture gantryXMoveDeviceCommandFuture = deviceCommandService.sendCommand(gantryXMoveDeviceCommand); - commandWait(gantryXMoveDeviceCommandFuture); + DeviceCommandBundle deviceCommand = DeviceCommandGenerator.gantryYMoveBy(position); + CommandFuture[] deviceCommandFutureArr = deviceCommandService.sendCommandQueue(deviceCommand); + commandWait(deviceCommandFutureArr); } /** * 龙门架机械臂Z轴相对移动到指定点 */ public void gantryZMoveBy(double position) throws Exception { - DeviceCommandBundle gantryXMoveDeviceCommand = DeviceCommandGenerator.gantryZMoveBy(position); - CommandFuture gantryXMoveDeviceCommandFuture = deviceCommandService.sendCommand(gantryXMoveDeviceCommand); - commandWait(gantryXMoveDeviceCommandFuture); + DeviceCommandBundle deviceCommand = DeviceCommandGenerator.gantryZMoveBy(position); + CommandFuture[] deviceCommandFutureArr = deviceCommandService.sendCommandQueue(deviceCommand); + commandWait(deviceCommandFutureArr); } /** @@ -290,7 +297,7 @@ public class DeviceCommandUtilService { * 根据试管需要获取点位 */ public Point2D getPointByTubeNum(int tubeNum) { - return new Point2D(tubeNum * 60.0,tubeNum * 60.0);//TODO 算法需要完善 + return new Point2D(tubeNum * 60.0, tubeNum * 60.0);//TODO 算法需要完善 } } diff --git a/src/main/java/com/iflytop/gd/app/service/DeviceStateInitializerService.java b/src/main/java/com/iflytop/gd/app/service/DeviceStateInitializerService.java new file mode 100644 index 0000000..d3528d1 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/service/DeviceStateInitializerService.java @@ -0,0 +1,39 @@ +package com.iflytop.gd.app.service; + +import com.iflytop.gd.app.core.device.DeviceState; +import com.iflytop.gd.app.model.entity.Container; +import com.iflytop.gd.common.enums.HeatModuleId; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class DeviceStateInitializerService { + private final ContainerService containerService; + + @PostConstruct + public void initializeDeviceState() { + DeviceState deviceState = DeviceState.getInstance(); + List heatArea = deviceState.getHeatArea(); + heatArea.add(new DeviceState.HeatArea(HeatModuleId.heat_module_01)); + heatArea.add(new DeviceState.HeatArea(HeatModuleId.heat_module_02)); + heatArea.add(new DeviceState.HeatArea(HeatModuleId.heat_module_03)); + heatArea.add(new DeviceState.HeatArea(HeatModuleId.heat_module_04)); + heatArea.add(new DeviceState.HeatArea(HeatModuleId.heat_module_05)); + heatArea.add(new DeviceState.HeatArea(HeatModuleId.heat_module_06)); + + List containerList = containerService.getList(); + List solutionBucket = deviceState.getSolutionArea().getSolutionContainer(); + for (Container container : containerList) { + if (container.getType() == 0) { + solutionBucket.add(new DeviceState.SolutionContainer(container.getId())); + } else { + deviceState.setAlkaliContainer(new DeviceState.SolutionContainer(container.getId())); + } + } + + } +} diff --git a/src/main/java/com/iflytop/gd/app/service/GantryArmService.java b/src/main/java/com/iflytop/gd/app/service/GantryArmService.java new file mode 100644 index 0000000..82170b0 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/service/GantryArmService.java @@ -0,0 +1,49 @@ +package com.iflytop.gd.app.service; + + +import com.iflytop.gd.app.core.device.DeviceState; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +@Slf4j +@Service +@RequiredArgsConstructor +public class GantryArmService { + private final Lock liquidLock = new ReentrantLock(); + private final Condition liquidIdleCondition = liquidLock.newCondition(); + + /** + * 等待加液区空闲 + */ + public void waitLiquidIdle() { + liquidLock.lock(); + try { + while (!DeviceState.getInstance().getSolutionArea().isIdle()) { + liquidIdleCondition.await(); + } + } catch (InterruptedException e) { + throw new RuntimeException("等待加液区空闲错误", e); + } finally { + liquidLock.unlock(); + } + } + + /** + * 释放加液区 + */ + public void setLiquidIdleTrue() { + liquidLock.lock(); + try { + DeviceState.getInstance().getSolutionArea().setIdle(true); + liquidIdleCondition.signalAll(); // 唤醒所有等待的线程 + } finally { + liquidLock.unlock(); + } + } + +}