Browse Source

feat:增加业务指令

master
白凤吉 3 months ago
parent
commit
bc9be86978
  1. 34
      src/main/java/com/iflytop/gd/app/cmd/DoorCloseCommand.java
  2. 34
      src/main/java/com/iflytop/gd/app/cmd/DoorOpenCommand.java
  3. 34
      src/main/java/com/iflytop/gd/app/cmd/HeatStartCommand.java
  4. 33
      src/main/java/com/iflytop/gd/app/cmd/HeatStopCommand.java
  5. 74
      src/main/java/com/iflytop/gd/app/cmd/MoveToHeatAreaCommand.java
  6. 75
      src/main/java/com/iflytop/gd/app/cmd/MoveToSolutionAreaCommand.java
  7. 30
      src/main/java/com/iflytop/gd/app/cmd/ShakeStartCommand.java
  8. 30
      src/main/java/com/iflytop/gd/app/cmd/ShakeStopCommand.java
  9. 56
      src/main/java/com/iflytop/gd/app/cmd/SolutionAddCommand.java
  10. 32
      src/main/java/com/iflytop/gd/app/cmd/TakePhotoCommand.java
  11. 38
      src/main/java/com/iflytop/gd/app/cmd/TrayDownCommand.java
  12. 38
      src/main/java/com/iflytop/gd/app/cmd/TrayUpCommand.java
  13. 2
      src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftDownCommandHandler.java
  14. 2
      src/main/java/com/iflytop/gd/app/cmd/debug/CoverElevatorLiftUpCommandHandler.java
  15. 3
      src/main/java/com/iflytop/gd/app/cmd/debug/LiquidPumpStartCommandHandler.java
  16. 2
      src/main/java/com/iflytop/gd/app/cmd/debug/ShakerStartCommandHandler.java
  17. 17
      src/main/java/com/iflytop/gd/app/controller/SystemController.java
  18. 133
      src/main/java/com/iflytop/gd/app/core/DeviceState.java
  19. 108
      src/main/java/com/iflytop/gd/app/core/device/DeviceState.java
  20. 4
      src/main/java/com/iflytop/gd/app/core/device/GantryArm.java
  21. 30
      src/main/java/com/iflytop/gd/app/model/dto/CmdDTO.java
  22. 8
      src/main/java/com/iflytop/gd/app/service/CraftsStepService.java
  23. 4
      src/main/java/com/iflytop/gd/app/service/DeviceCommandService.java
  24. 53
      src/main/java/com/iflytop/gd/app/service/DeviceCommandUtilService.java
  25. 39
      src/main/java/com/iflytop/gd/app/service/DeviceStateInitializerService.java
  26. 49
      src/main/java/com/iflytop/gd/app/service/GantryArmService.java

34
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<Void> handle(CmdDTO cmdDTO) {
return runAsync(() -> {
Double doorOpenDistance = devicePositionService.getPosition(DevicePositionCode.doorClose).getDistance();
deviceCommandUtilService.doorMove(doorOpenDistance);
});
}
}

34
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<Void> handle(CmdDTO cmdDTO) {
return runAsync(() -> {
Double doorOpenDistance = devicePositionService.getPosition(DevicePositionCode.doorOpen).getDistance();
deviceCommandUtilService.doorMove(doorOpenDistance);
});
}
}

34
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<Void> handle(CmdDTO cmdDTO) {
String heatId = cmdDTO.getStringParam("heatId");
Double temperature = cmdDTO.getDoubleParam("temperature");
HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId);
return runAsync(() -> {
deviceCommandUtilService.heatRodOpen(heatModuleId, temperature);
});
}
}

33
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<Void> handle(CmdDTO cmdDTO) {
String heatId = cmdDTO.getStringParam("heatId");
HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId);
return runAsync(() -> {
deviceCommandUtilService.heatRodClose(heatModuleId);
});
}
}

74
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<Void> 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);//下降加热位托盘
});
}
}

75
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<Void> 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);//抬升机械臂至托盘上方
});
}
}

30
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<Void> handle(CmdDTO cmdDTO) {
return runAsync(() -> {
deviceCommandUtilService.shakeStart();//开始摇匀
});
}
}

30
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<Void> handle(CmdDTO cmdDTO) {
return runAsync(() -> {
deviceCommandUtilService.shakeStop();//停止摇匀
});
}
}

56
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<Void> 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();
});
}
}

32
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<Void> handle(CmdDTO cmdDTO) {
return runAsync(() -> {
deviceCommandUtilService.fillLightOpen(100.0);//TODO 开启补光灯 亮度从数据库获取
deviceCommandUtilService.takePhoto();//拍照
deviceCommandUtilService.fillLightClose();//关闭补光灯
});
}
}

38
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<Void> 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);//下降加热位托盘
});
}
}

38
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<Void> 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);//抬升加热位托盘
});
}
}

2
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 distance = cmdDTO.getDoubleParam("distance");
Double velocity = cmdDTO.getDoubleParam("velocity"); Double velocity = cmdDTO.getDoubleParam("velocity");
if(velocity != null){
if (velocity != null) {
DeviceCommandBundle deviceCommand = DeviceCommandGenerator.trayMotorSet(velocity); DeviceCommandBundle deviceCommand = DeviceCommandGenerator.trayMotorSet(velocity);
CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand); CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand);
commandWait(deviceCommandFuture); commandWait(deviceCommandFuture);

2
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 distance = cmdDTO.getDoubleParam("distance");
Double velocity = cmdDTO.getDoubleParam("velocity"); Double velocity = cmdDTO.getDoubleParam("velocity");
if(velocity != null){
if (velocity != null) {
DeviceCommandBundle deviceCommand = DeviceCommandGenerator.trayMotorSet(velocity); DeviceCommandBundle deviceCommand = DeviceCommandGenerator.trayMotorSet(velocity);
CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand); CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand);
commandWait(deviceCommandFuture); commandWait(deviceCommandFuture);

3
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.DeviceCommandBundle;
import com.iflytop.gd.common.cmd.DeviceCommandGenerator; import com.iflytop.gd.common.cmd.DeviceCommandGenerator;
import com.iflytop.gd.common.enums.AcidPumpDevice; import com.iflytop.gd.common.enums.AcidPumpDevice;
import com.iflytop.gd.common.enums.cmd.CmdDirection;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -33,7 +32,7 @@ public class LiquidPumpStartCommandHandler extends BaseCommandHandler {
Double velocity = cmdDTO.getDoubleParam("velocity"); Double velocity = cmdDTO.getDoubleParam("velocity");
AcidPumpDevice acidPumpDevice = AcidPumpDevice.valueOf(index); AcidPumpDevice acidPumpDevice = AcidPumpDevice.valueOf(index);
DeviceCommandBundle deviceCommand; DeviceCommandBundle deviceCommand;
if(velocity != null) {
if (velocity != null) {
switch (acidPumpDevice) { switch (acidPumpDevice) {
case acid_pump_01 -> deviceCommand = DeviceCommandGenerator.acidPump1Set(velocity); case acid_pump_01 -> deviceCommand = DeviceCommandGenerator.acidPump1Set(velocity);
case acid_pump_02 -> deviceCommand = DeviceCommandGenerator.acidPump2Set(velocity); case acid_pump_02 -> deviceCommand = DeviceCommandGenerator.acidPump2Set(velocity);

2
src/main/java/com/iflytop/gd/app/cmd/debug/ShakerStartCommandHandler.java

@ -27,7 +27,7 @@ public class ShakerStartCommandHandler extends BaseCommandHandler {
public CompletableFuture<Void> handle(CmdDTO cmdDTO) { public CompletableFuture<Void> handle(CmdDTO cmdDTO) {
return runAsync(() -> { return runAsync(() -> {
Double velocity = cmdDTO.getDoubleParam("velocity"); Double velocity = cmdDTO.getDoubleParam("velocity");
if(velocity != null) {
if (velocity != null) {
DeviceCommandBundle deviceCommand = DeviceCommandGenerator.shakeMotorSet(velocity); DeviceCommandBundle deviceCommand = DeviceCommandGenerator.shakeMotorSet(velocity);
CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand); CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand);
commandWait(deviceCommandFuture); commandWait(deviceCommandFuture);

17
src/main/java/com/iflytop/gd/app/controller/SystemController.java

@ -1,6 +1,6 @@
package com.iflytop.gd.app.controller; 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.model.dto.SetSystemDatetimeDTO;
import com.iflytop.gd.app.service.SystemConfigService; import com.iflytop.gd.app.service.SystemConfigService;
import com.iflytop.gd.common.result.Result; import com.iflytop.gd.common.result.Result;
@ -9,10 +9,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; 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 = "系统设置") @Tag(name = "系统设置")
@RestController @RestController
@ -25,16 +22,22 @@ public class SystemController {
@Operation(summary = "是否启动虚拟模式") @Operation(summary = "是否启动虚拟模式")
@PostMapping("/virtual") @PostMapping("/virtual")
public Result<?> changeVirtualMode(Boolean mode) { public Result<?> changeVirtualMode(Boolean mode) {
DeviceState.getInstance().getVirtual().set(mode);
DeviceState.getInstance().setVirtual(mode);
return Result.success(); return Result.success();
} }
@Operation(summary = "系统状态")
@GetMapping("/device-status")
public Result<DeviceState> getDeviceStatus() {
return Result.success(DeviceState.getInstance());
}
@Operation(summary = "设置系统时间") @Operation(summary = "设置系统时间")
@PostMapping("/setDatetime")
@PostMapping("/datetime")
public Result<?> setDatetime(@Valid @RequestBody SetSystemDatetimeDTO setSystemDatetimeDTO) { public Result<?> setDatetime(@Valid @RequestBody SetSystemDatetimeDTO setSystemDatetimeDTO) {
systemConfigService.setDatetime(setSystemDatetimeDTO.getDatetime()); systemConfigService.setDatetime(setSystemDatetimeDTO.getDatetime());
return Result.success(); return Result.success();
} }
} }

133
src/main/java/com/iflytop/gd/app/core/DeviceState.java

@ -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> gantryArm = new AtomicReference<>(new GantryArm());
@Schema(description = "加液操作区属性")
private AtomicReference<LiquidArea> liquidArea = new AtomicReference<>(new LiquidArea());
@Schema(description = "加热操作区属性")
private List<HeatArea> heatArea = new ArrayList<>();
@Schema(description = "碱容器状态")
private AtomicReference<LiquidBucket> 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<LiquidBucket> 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();
}
}
}

108
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> 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> 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();
}
}

4
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 {
}

30
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 cn.hutool.json.JSONUtil;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
@ -24,32 +23,29 @@ public class CmdDTO {
@Schema(description = "参数") @Schema(description = "参数")
private Map<String, Object> params; private Map<String, Object> params;
// 获取 Double 类型的参数null 或空字符串时返回 null
public Double getDoubleParam(String key) { 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) { 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) { 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) { 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 @Override

8
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.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import com.iflytop.gd.app.core.CraftsDebugGenerator; 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.CraftsStep;
import com.iflytop.gd.app.model.bo.Point2D; import com.iflytop.gd.app.model.bo.Point2D;
import com.iflytop.gd.app.model.bo.Point3D; import com.iflytop.gd.app.model.bo.Point3D;
@ -25,6 +24,7 @@ public class CraftsStepService {
private final DevicePositionService devicePositionService; private final DevicePositionService devicePositionService;
private final ContainerService containerService; private final ContainerService containerService;
private final WebSocketService webSocketService; private final WebSocketService webSocketService;
private final GantryArmService gantryArmService;
/** /**
@ -53,7 +53,7 @@ public class CraftsStepService {
HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId);
webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "等待加液区空闲", null)); webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "等待加液区空闲", null));
DeviceState.getInstance().waitLiquidIdle();//等待加液区空闲
gantryArmService.waitLiquidIdle();//等待加液区空闲
webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "加液区已空闲", null)); webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "加液区已空闲", null));
double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); //获取加热位抬升托盘位置 double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); //获取加热位抬升托盘位置
@ -208,7 +208,7 @@ public class CraftsStepService {
webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "抬升机械臂至托盘上方", -clawDescend)); webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "抬升机械臂至托盘上方", -clawDescend));
deviceCommandUtilService.gantryZMoveBy(-clawDescend);//抬升机械臂至托盘上方 deviceCommandUtilService.gantryZMoveBy(-clawDescend);//抬升机械臂至托盘上方
webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "释放加液区等待", null)); webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "释放加液区等待", null));
DeviceState.getInstance().setLiquidIdleTrue();//释放加液区等待
gantryArmService.setLiquidIdleTrue();//释放加液区等待
double trayLower = devicePositionService.getPosition(DevicePositionCode.trayLower).getDistance(); //获取加热位下降托盘位置 double trayLower = devicePositionService.getPosition(DevicePositionCode.trayLower).getDistance(); //获取加热位下降托盘位置
webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "下降加热位托盘", trayLower)); webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "下降加热位托盘", trayLower));
@ -234,7 +234,7 @@ public class CraftsStepService {
HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId); HeatModuleId heatModuleId = HeatModuleId.valueOf(heatId);
webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "等待加液区空闲", null)); webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "等待加液区空闲", null));
DeviceState.getInstance().waitLiquidIdle();//等待加液区空闲
gantryArmService.waitLiquidIdle();//等待加液区空闲
webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "加液区已空闲", null)); webSocketService.pushCraftsDebug(CraftsDebugGenerator.generateJson(heatId, "加液区已空闲", null));
double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); //获取加热位抬升托盘位置 double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); //获取加热位抬升托盘位置

4
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 cn.hutool.json.JSONObject;
import com.iflytop.gd.app.core.DebugGenerator; 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.CommandFuture;
import com.iflytop.gd.common.cmd.CyclicNumberGenerator; import com.iflytop.gd.common.cmd.CyclicNumberGenerator;
import com.iflytop.gd.common.cmd.DeviceCommandBundle; import com.iflytop.gd.common.cmd.DeviceCommandBundle;
@ -94,7 +94,7 @@ public class DeviceCommandService {
commandFuture.getDeviceCommandBundle().getDeviceCommand().setCmdId(cmdId); commandFuture.getDeviceCommandBundle().getDeviceCommand().setCmdId(cmdId);
sendCommandFutureMap.put(cmdId, commandFuture); sendCommandFutureMap.put(cmdId, commandFuture);
commandFuture.setStartSendTime(System.currentTimeMillis()); commandFuture.setStartSendTime(System.currentTimeMillis());
if (!DeviceState.getInstance().getVirtual().get()) {
if (!DeviceState.getInstance().isVirtual()) {
if (!hardwareService.sendCommand(commandFuture.getDeviceCommandBundle().getDeviceCommand())) { if (!hardwareService.sendCommand(commandFuture.getDeviceCommandBundle().getDeviceCommand())) {
sendCommandFutureMap.remove(commandFuture.getDeviceCommandBundle().getDeviceCommand().getCmdId()); sendCommandFutureMap.remove(commandFuture.getDeviceCommandBundle().getDeviceCommand().getCmdId());
throw new RuntimeException("向设备发送指令失败"); throw new RuntimeException("向设备发送指令失败");

53
src/main/java/com/iflytop/gd/app/service/DeviceCommandUtilService.java

@ -23,70 +23,77 @@ public class DeviceCommandUtilService {
private final DevicePositionService devicePositionService; 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 { public void gantryMove(Point3D point) throws Exception {
DeviceCommandBundle gantryXMoveDeviceCommand = DeviceCommandGenerator.gantryXMove(point.getX()); DeviceCommandBundle gantryXMoveDeviceCommand = DeviceCommandGenerator.gantryXMove(point.getX());
DeviceCommandBundle gantryYMoveDeviceCommand = DeviceCommandGenerator.gantryYMove(point.getY()); DeviceCommandBundle gantryYMoveDeviceCommand = DeviceCommandGenerator.gantryYMove(point.getY());
DeviceCommandBundle gantryZMoveDeviceCommand = DeviceCommandGenerator.gantryZMove(point.getZ()); 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轴移动到指定点 * 龙门架机械臂X轴移动到指定点
*/ */
public void gantryXMove(double position) throws Exception { 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轴移动到指定点 * 龙门架机械臂Y轴移动到指定点
*/ */
public void gantryYMove(double position) throws Exception { 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轴移动到指定点 * 龙门架机械臂Z轴移动到指定点
*/ */
public void gantryZMove(double position) throws Exception { 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轴相对移动到指定点 * 龙门架机械臂X轴相对移动到指定点
*/ */
public void gantryXMoveBy(double position) throws Exception { 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轴相对移动到指定点 * 龙门架机械臂Y轴相对移动到指定点
*/ */
public void gantryYMoveBy(double position) throws Exception { 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轴相对移动到指定点 * 龙门架机械臂Z轴相对移动到指定点
*/ */
public void gantryZMoveBy(double position) throws Exception { 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) { 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 算法需要完善
} }
} }

39
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<DeviceState.HeatArea> 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<Container> containerList = containerService.getList();
List<DeviceState.SolutionContainer> 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()));
}
}
}
}

49
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();
}
}
}
Loading…
Cancel
Save