zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/BuildSupport.java
New file @@ -0,0 +1,7 @@ package com.zy.asrs.wcs.core; public interface BuildSupport<T> { void execute(T t); } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MotionDto.java
New file @@ -0,0 +1,40 @@ package com.zy.asrs.wcs.core.domain.dto; import com.zy.asrs.wcs.core.BuildSupport; import lombok.Data; /** * Created by vincent on 2023/10/16 */ @Data public class MotionDto { private Integer devpNo; private Integer shuttleNo; private Integer liftNo; private String locNo; private Integer row; private Integer bay; private Integer lev; private Integer staNo; private Boolean updateLiftNo; protected Integer wrkNo; public static MotionDto build(BuildSupport<MotionDto> support) { MotionDto dto = new MotionDto(); support.execute(dto); return dto; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java
New file @@ -0,0 +1,915 @@ package com.zy.asrs.wcs.core.kernel; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.wcs.core.domain.dto.MotionDto; import com.zy.asrs.wcs.core.entity.Task; import com.zy.asrs.wcs.core.model.enums.LiftCodeType; import com.zy.asrs.wcs.core.model.enums.MotionCtgType; import com.zy.asrs.wcs.core.model.enums.TaskStsType; import com.zy.asrs.wcs.core.model.enums.WorkZoneType; import com.zy.asrs.wcs.core.service.TaskService; import com.zy.asrs.wcs.core.utils.LiftDispatcher; import com.zy.asrs.wcs.core.utils.ShuttleDispatcher; import com.zy.asrs.wcs.core.utils.Utils; import com.zy.asrs.wcs.rcs.entity.Motion; import com.zy.asrs.wcs.rcs.model.protocol.LiftProtocol; import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol; import com.zy.asrs.wcs.rcs.service.MotionService; import com.zy.asrs.wcs.rcs.thread.LiftThread; import com.zy.asrs.wcs.rcs.thread.ShuttleThread; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** * todo:luxiaotao 1.充电任务,2.库位移转,3.小车迁移 * Created by vincent on 2023/10/11 */ @Service public class AnalyzeService { @Autowired private TaskService taskService; @Autowired private MotionService motionService; @Autowired private KernelService kernelService; @Autowired private ShuttleDispatcher shuttleDispatcher; @Autowired private LiftDispatcher liftDispatcher; // @Autowired // private ConveyorDispatcher conveyorDispatcher; public List<Motion> generateMotion(Task task) { List<Motion> motionList = new ArrayList<>(); switch (Objects.requireNonNull(WorkZoneType.query(task.getTaskSts() == TaskStsType.NEW_INBOUND.sts ? task.getOriginSite() : task.getDestSite()))) { case FIRST_ZONE: motionList = this.generateFirstZoneMotion(task); break; default: } return motionList; } public List<Motion> generateFirstZoneMotion(Task task) { List<Motion> motionList = new ArrayList<>(); String shuttleNo = null; String liftNo = null; /** * 入库 * 一、入库目标层有穿梭车 * 1.提升机升降到源层 * 2.货物从输送线到提升机 * 3.提升机载货移动(非必需) * 4.穿梭车走行至提升机 * 5.穿梭车入库至目标库位 */ if (task.getTaskSts() == TaskStsType.NEW_INBOUND.sts) { // lift LiftThread liftThread = liftDispatcher.queryLiftForTransport(task.getOriginSite()); LiftProtocol liftProtocol = liftThread.getStatus(); if (liftProtocol == null) { return motionList; } // shuttle ShuttleThread shuttleThread = shuttleDispatcher.queryShuttleWhichConvenient(task, Integer.parseInt(liftThread.getStatus().getLiftNo())); if (Cools.isEmpty(shuttleThread)) { return motionList; } ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); String shuttleLocNo = shuttleProtocol.getCurrentLocNo(); // // conveyor // DevpSlave devpSlave = conveyorDispatcher.queryByInBound(task.getSourceStaNo()); // DevpSlave.Sta slaveInSta = devpSlave.queryInSta(wrkMast.getSourceStaNo()); // //检测穿梭车是否有任务绑定 // boolean shuttleResult = Utils.checkShuttleHasBinding(shuttleProtocol.getShuttleNo().intValue()); // if (shuttleResult) { // //存在任务,禁止解析 // return motionList; // } // // //检测提升机是否有任务绑定 // boolean liftResult = Utils.checkLiftHasBinding(liftSlave.getId()); // if (liftResult) { // //存在任务,禁止解析 // return motionList; // } //穿梭车到提升机库位号 String liftLocNoTo = LiftCodeType.getLocNo(Integer.parseInt(liftNo), Utils.getLev(shuttleLocNo), task.getHostId()); //穿梭车出提升机库位号 String liftLocNoFrom = LiftCodeType.getLocNo(Integer.parseInt(liftNo), Utils.getLev(task.getDestLoc()), task.getHostId()); //穿梭车到提升机待机位库位号 String standbyLocNoTo = LiftCodeType.getStandbyLocNo(Integer.parseInt(liftNo), Utils.getLev(shuttleLocNo)); //穿梭车出提升机待机位库位号 String standbyLocNoFrom = LiftCodeType.getStandbyLocNo(Integer.parseInt(liftNo), Utils.getLev(task.getDestLoc())); // 入库目标层有穿梭车 if (Utils.getLev(shuttleLocNo) == Utils.getLev(task.getOriginLoc())) { // 穿梭车走行至库位 motionList.addAll(kernelService.shuttleMove( MotionDto.build((dto -> { dto.setShuttleNo(Integer.valueOf(shuttleProtocol.getShuttleNo())); dto.setLocNo(shuttleLocNo); })), MotionDto.build((dto -> { dto.setShuttleNo(Integer.valueOf(shuttleProtocol.getShuttleNo())); dto.setLocNo(task.getDestLoc()); })), MotionCtgType.SHUTTLE_MOVE )); // // 提升机空载移动 // motionList.addAll(kernelService.liftMove( // null // , MotionDto.build((dto -> { // dto.setLiftNo(Integer.valueOf(liftProtocol.getLiftNo())); //// dto.setLev(slaveInSta.getLiftLev()); // dto.setLev(1); // })) // )); // // // 输送线入库至提升机口 // motionList.addAll(kernelService.conveyorInbound( // MotionDto.build((dto -> { //// dto.setDevpNo(devpSlave.getId()); // dto.setDevpNo(1); // dto.setStaNo(Integer.valueOf(task.getOriginSite())); // })), // MotionDto.build((dto -> { // dto.setLiftNo(Integer.valueOf(liftProtocol.getLiftNo())); //// dto.setLev(slaveInSta.getLiftLev()); // dto.setLev(1); // })), // MotionCtgType.CONVEYOR_INBOUND_TO_LIFT // )); // // // 目标库位是否与输送线入库站属于同一层 // if (!slaveInSta.getLiftLev().equals(Utils.getLev(wrkMast.getLocNo()))) { // // 提升机载货移动 // motionList.addAll(kernelService.liftMoveGoods( // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(slaveInSta.getLiftLev()); // })) // , MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(wrkMast.getLocNo())); // })) // )); // } // // // 穿梭车走行至提升机库位待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(shuttleLocNo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(standbyLocNoTo); // })), // MotionCtgType.SHUTTLE_MOVE // )); // // // 提升机移动至小车楼层 // motionList.addAll(kernelService.liftMove( // null // , MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(shuttleLocNo)); // })) // )); // // // 穿梭车待机位至提升机库位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoTo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoTo); // })), // MotionCtgType.SHUTTLE_MOVE_TO_LIFT // )); // // // 穿梭车入库顶升并移动至提升机待机位 // motionList.addAll(kernelService.shuttleTransport( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionCtgType.SHUTTLE_TRANSPORT_FROM_LIFT // )); // // // 穿梭车走行至提升机库位待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(wrkMast.getLocNo()); // })), // MotionCtgType.SHUTTLE_MOVE_DOWN_PALLET // )); /** * 二、入库目标层没有穿梭车 * 1.提升机升降到穿梭车层 * 2.穿梭车走行至提升机待机位 * 3.提升机搬运穿梭车至目标层 * 4.货物从输送线到提升机 * 5.提升机载车与货移动(非必需) * 6.穿梭车入库至目标库位 */ } else { // // // 穿梭车走行至提升机库位待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(shuttleLocNo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(standbyLocNoTo); // })), // MotionCtgType.SHUTTLE_MOVE // )); // // // 提升机空载移动到穿梭车层 // motionList.addAll(kernelService.liftMove( // null // , MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(shuttleLocNo)); // })) // )); // // // 穿梭车待机位至提升机库位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoTo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoTo); // })), // MotionCtgType.SHUTTLE_MOVE_TO_LIFT // )); // // // 提升机搬车 至 输送线层 // motionList.addAll(kernelService.liftMoveShuttle( // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(shuttleLocNo)); // })), // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(slaveInSta.getLiftLev()); // })) // )); // // // 输送线入库至提升机口 // motionList.addAll(kernelService.conveyorInbound( // MotionDto.build((dto -> { // dto.setDevpNo(devpSlave.getId()); // dto.setStaNo(wrkMast.getSourceStaNo()); // })), // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(slaveInSta.getLiftLev()); // })), // MotionCtgType.CONVEYOR_INBOUND_TO_LIFT // )); // // // 目标库位是否与输送线入库站属于同一层 // if (!slaveInSta.getLiftLev().equals(Utils.getLev(wrkMast.getLocNo()))) { // // 提升机载货移动 // motionList.addAll(kernelService.liftMoveGoodsAndShuttle( // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(slaveInSta.getLiftLev()); // })) // , MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(wrkMast.getLocNo())); // })) // )); // } // // // 穿梭车入库顶升并移动至提升机待机位 // motionList.addAll(kernelService.shuttleTransport( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionCtgType.SHUTTLE_TRANSPORT_FROM_LIFT // )); // // // 穿梭车待机位至入库库位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(wrkMast.getLocNo()); // })), // MotionCtgType.SHUTTLE_MOVE_DOWN_PALLET // )); } shuttleNo = String.valueOf(shuttleProtocol.getShuttleNo()); liftNo = String.valueOf(liftProtocol.getLiftNo()); } /** * 出库 */ if (task.getTaskSts() == TaskStsType.NEW_OUTBOUND.sts) { // // lift // LiftProtocol liftProtocol = liftDispatcher.queryLiftForTransport(wrkMast.getStaNo()); // LiftSlave liftSlave = liftProtocol.querySlave(); // // // shuttle // ShuttleProtocol shuttleProtocol = shuttleDispatcher.queryShuttleWhichConvenient(wrkMast, liftProtocol.getLiftNo().intValue()); // if (Cools.isEmpty(shuttleProtocol)) { return motionList; } // String shuttleLocNo = shuttleProtocol.getCurrentLocNo(); // // // conveyor // DevpSlave devpSlave = conveyorDispatcher.queryByOutBound(wrkMast.getSourceStaNo()); // DevpSlave.Sta slaveOutSta = devpSlave.queryOutSta(wrkMast.getSourceStaNo()); // // //检测穿梭车是否有任务绑定 // boolean shuttleResult = Utils.checkShuttleHasBinding(shuttleProtocol.getShuttleNo().intValue()); // if (shuttleResult) { // //存在任务,禁止解析 // return motionList; // } // // //检测提升机是否有任务绑定 // boolean liftResult = Utils.checkLiftHasBinding(liftSlave.getId()); // if (liftResult) { // //存在任务,禁止解析 // return motionList; // } // // //穿梭车到提升机库位号 // String liftLocNoTo = LiftCodeType.getLocNo(liftSlave.getId(), Utils.getLev(shuttleLocNo)); // // //穿梭车出提升机库位号 // String liftLocNoFrom = LiftCodeType.getLocNo(liftSlave.getId(), Utils.getLev(wrkMast.getSourceLocNo())); // // //穿梭车到提升机待机位库位号 // String standbyLocNoTo = LiftCodeType.getStandbyLocNo(liftSlave.getId(), Utils.getLev(shuttleLocNo)); // // //穿梭车出提升机待机位库位号 // String standbyLocNoFrom = LiftCodeType.getStandbyLocNo(liftSlave.getId(), Utils.getLev(wrkMast.getSourceLocNo())); // // /** // * 出库 // * 一、出库起始层有穿梭车 // * 1.穿梭车走行至出库库位 // * 2.提升机到出库起始层 // * 3.穿梭车出库至提升机 // * 4.穿梭车离开提升机 // * 5.提升机载货移动(非必需) // * 6.输送线运输至出库口 // */ // if (Utils.getLev(shuttleLocNo) == Utils.getLev(wrkMast.getSourceLocNo())) { // // //穿梭车不在出库库位 // if (!shuttleLocNo.equals(wrkMast.getSourceLocNo())) { // // 穿梭车走行至出库库位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(shuttleLocNo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(wrkMast.getSourceLocNo()); // })), // MotionCtgType.SHUTTLE_MOVE // )); // } // // // 穿梭车出库至提升机待机位 // motionList.addAll(kernelService.shuttleTransport( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(wrkMast.getSourceLocNo()); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(standbyLocNoTo); // })), // MotionCtgType.SHUTTLE_MOVE_LIFT_PALLET // )); // // // 提升机空载移动 // motionList.addAll(kernelService.liftMove( // null // , MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(wrkMast.getSourceLocNo())); // })) // )); // // // 穿梭车待机位至提升机 // motionList.addAll(kernelService.shuttleTransport( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoTo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoTo); // })), // MotionCtgType.SHUTTLE_TRANSPORT_TO_LIFT // )); // // // 穿梭车离开提升机 - 到提升机待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionCtgType.SHUTTLE_MOVE_FROM_LIFT // )); // // // 提升机载货移动 // // 出库库位是否与输送线出库站属于同一层 // if (!slaveOutSta.getLiftLev().equals(Utils.getLev(wrkMast.getSourceLocNo()))) { // motionList.addAll(kernelService.liftMoveGoods( // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(wrkMast.getSourceLocNo())); // })), // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(slaveOutSta.getLiftLev()); // })) // )); // } // // LiftNeighborType neighborType = LiftNeighborType.query(liftSlave.getId(), slaveOutSta.getLiftLev(), false, wrkMast.getStaNo()); // // // 提升机运输到输送线 // motionList.addAll(kernelService.liftTransportGoodsToConveyor( // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(slaveOutSta.getLiftLev()); // })), // MotionDto.build((dto -> { // dto.setDevpNo(devpSlave.getId()); // dto.setStaNo(neighborType.staNo); // })) // )); // // // 穿梭车提升机待机位 - 到待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo( // ShuttleTempLocType.query(shuttleProtocol.getShuttleNo().intValue(), liftSlave.getId(), Utils.getLev(wrkMast.getSourceLocNo())).locNo // ); // })), // MotionCtgType.SHUTTLE_MOVE // )); // // /** // * 二、出库起始层没有穿梭车 // * // * 1.提升机到穿梭车层 // * 2.穿梭车走行至提升机 // * 3.提升机载车至出库起始层 // * 4.穿梭车走行至出库库位 // * 5.穿梭车出库至提升机 // * 6.穿梭车离开提升机 // * 7.提升机载货移动(非必需) // * 8.输送线运输至出库口 // * // */ // } else { // // // 穿梭车走行至提升机待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(shuttleLocNo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(standbyLocNoTo); // })), // MotionCtgType.SHUTTLE_MOVE // )); // // // 提升机到穿梭车层 // motionList.addAll(kernelService.liftMove( // null // , MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(shuttleLocNo)); // })) // )); // // // 穿梭车待机位至提升机 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoTo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoTo); // })), // MotionCtgType.SHUTTLE_MOVE_TO_LIFT // )); // // // 提升机载车至出库起始层 // motionList.addAll(kernelService.liftMoveShuttle( // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(shuttleLocNo)); // })), // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(wrkMast.getSourceLocNo())); // })) // )); // // // 穿梭车走行至提升机待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionCtgType.SHUTTLE_MOVE_FROM_LIFT // )); // // // 穿梭车提升机待机位至出库库位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(wrkMast.getSourceLocNo()); // })), // MotionCtgType.SHUTTLE_MOVE // )); // // // 穿梭车出库至提升机待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(wrkMast.getSourceLocNo()); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionCtgType.SHUTTLE_MOVE_LIFT_PALLET // )); // // // 穿梭车提升机待机位至提升机 // motionList.addAll(kernelService.shuttleTransport( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoFrom); // })), // MotionCtgType.SHUTTLE_TRANSPORT_TO_LIFT // )); // // // 穿梭车离开提升机 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(liftSlave.getId()); // dto.setLocNo(liftLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo( // ShuttleTempLocType.query(shuttleProtocol.getShuttleNo().intValue(), liftSlave.getId(), Utils.getLev(wrkMast.getSourceLocNo())).locNo // ); // })), // MotionCtgType.SHUTTLE_MOVE_FROM_LIFT // )); // // // 提升机载货移动 // // 出库库位是否与输送线出库站属于同一层 // if (!slaveOutSta.getLiftLev().equals(Utils.getLev(wrkMast.getSourceLocNo()))) { // motionList.addAll(kernelService.liftMoveGoods( // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(Utils.getLev(wrkMast.getSourceLocNo())); // })), // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(slaveOutSta.getLiftLev()); // })) // )); // } // // LiftNeighborType neighborType = LiftNeighborType.query(liftSlave.getId(), slaveOutSta.getLiftLev(), false, wrkMast.getStaNo()); // // // 提升机运输到输送线 // motionList.addAll(kernelService.liftTransportGoodsToConveyor( // MotionDto.build((dto -> { // dto.setLiftNo(liftSlave.getId()); // dto.setLev(slaveOutSta.getLiftLev()); // })), // MotionDto.build((dto -> { // dto.setDevpNo(devpSlave.getId()); // dto.setStaNo(neighborType.staNo); // })) // )); // // } // // shuttleNo = String.valueOf(shuttleProtocol.getShuttleNo()); // liftNo = String.valueOf(liftProtocol.getLiftNo()); } assert !Cools.isEmpty(shuttleNo); // task.setShuttleNo(Integer.parseInt(shuttleNo)); // task.setLiftNo(Integer.parseInt(liftNo)); return motionList; } // /** // * 生成充电动作 // */ // public List<Motion> generateChargeMotion(WrkCharge wrkCharge) { // List<Motion> motionList = new ArrayList<>(); // if (wrkCharge.getWrkSts() != WrkMastStsType.NEW_CHARGE.sts || wrkCharge.getIoType() != WrkIoTypeType.CHARGE.sts) { // return motionList; // } // // // locNo // String chargeLocNo = wrkCharge.getLocNo(); // // // lift // Integer transferLiftNo = 2; // SiemensLiftThread liftThread = (SiemensLiftThread) SlaveConnection.get(SlaveType.Lift, transferLiftNo); // LiftProtocol liftProtocol = liftThread.getLiftProtocol(); // if (liftProtocol == null || liftProtocol.getLiftNo() == null) { // return motionList; // } // // // shuttle // Integer shuttleNo = wrkCharge.getShuttleNo(); // ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo); // ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); // if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) { // return motionList; // } // if (!shuttleProtocol.isIdle()) { // return motionList; // } // // //检测穿梭车是否有任务绑定 // boolean shuttleResult = Utils.checkShuttleHasBinding(shuttleProtocol.getShuttleNo().intValue()); // if (shuttleResult) { // //存在任务,禁止解析 // return motionList; // } // // //检测提升机是否有任务绑定 // boolean liftResult = Utils.checkLiftHasBinding(transferLiftNo); // if (liftResult) { // //存在任务,禁止解析 // return motionList; // } // // String shuttleLocNo = shuttleProtocol.getCurrentLocNo(); // // //穿梭车到提升机库位号 // String liftLocNoTo = LiftCodeType.getLocNo(transferLiftNo, Utils.getLev(shuttleLocNo)); // // //穿梭车出提升机库位号 // String liftLocNoFrom = LiftCodeType.getLocNo(transferLiftNo, Utils.getLev(wrkCharge.getLocNo())); // // //穿梭车到提升机待机位库位号 // String standbyLocNoTo = LiftCodeType.getStandbyLocNo(transferLiftNo, Utils.getLev(shuttleLocNo)); // // //穿梭车出提升机待机位库位号 // String standbyLocNoFrom = LiftCodeType.getStandbyLocNo(transferLiftNo, Utils.getLev(wrkCharge.getLocNo())); // // // 判断穿梭车是否在充电层 // if (Utils.getLev(shuttleLocNo) == Utils.getLev(chargeLocNo)) { // // // 穿梭车走行至充电桩库位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(shuttleLocNo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(chargeLocNo); // })), // MotionCtgType.SHUTTLE_MOVE // )); // // } else { // // // 穿梭车走行至提升机待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(shuttleLocNo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoTo); // })), // MotionCtgType.SHUTTLE_MOVE // )); // // // 提升机空载移动到穿梭车层 // motionList.addAll(kernelService.liftMove( // null // , MotionDto.build((dto -> { // dto.setLiftNo(transferLiftNo); // dto.setLev(Utils.getLev(shuttleLocNo)); // })) // )); // // // 穿梭车提升机待机位至提升机库位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoTo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(transferLiftNo); // dto.setLocNo(liftLocNoTo); // })), // MotionCtgType.SHUTTLE_MOVE_TO_LIFT // )); // // // 提升机搬车 至 输送线层 // motionList.addAll(kernelService.liftMoveShuttle( // MotionDto.build((dto -> { // dto.setLiftNo(transferLiftNo); // dto.setLev(Utils.getLev(shuttleLocNo)); // })), // MotionDto.build((dto -> { // dto.setLiftNo(transferLiftNo); // dto.setLev(Utils.getLev(chargeLocNo)); // })) // )); // // // 穿梭车提升机至提升机待机位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLiftNo(transferLiftNo); // dto.setLocNo(liftLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionCtgType.SHUTTLE_MOVE_FROM_LIFT // )); // // // 穿梭车提升机待机位至充电位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(standbyLocNoFrom); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(chargeLocNo); // })), // MotionCtgType.SHUTTLE_MOVE // )); // // wrkCharge.setLiftNo(transferLiftNo); // wrkChargeMapper.updateById(wrkCharge); // } // // // 穿梭车开始充电 // motionList.addAll(kernelService.shuttleCharge( // null, // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // })) // )); // // return motionList; // } // // /** // * 生成充电完成动作 // */ // public List<Motion> generateShuttleChargeWrkComplete(WrkCharge wrkCharge) { // List<Motion> motionList = new ArrayList<>(); // if (wrkCharge.getWrkSts() != WrkMastStsType.NEW_MOVE.sts || wrkCharge.getIoType() != WrkIoTypeType.MOVE.sts) { // return motionList; // } // // // locNo // String locNo = wrkCharge.getLocNo(); // // // shuttle // Integer shuttleNo = wrkCharge.getShuttleNo(); // ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo); // ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); // if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) { // return motionList; // } // // String shuttleLocNo = shuttleProtocol.getCurrentLocNo(); // // // 判断穿梭车是否在目标层 // if (Utils.getLev(shuttleLocNo) == Utils.getLev(locNo)) { // // // 穿梭车走行至目标库位 // motionList.addAll(kernelService.shuttleMove( // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(shuttleLocNo); // })), // MotionDto.build((dto -> { // dto.setShuttleNo(shuttleProtocol.getShuttleNo().intValue()); // dto.setLocNo(locNo); // })), // MotionCtgType.SHUTTLE_MOVE // )); // // } // return motionList; // } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/KernelService.java
New file @@ -0,0 +1,308 @@ package com.zy.asrs.wcs.core.kernel; import com.zy.asrs.wcs.core.domain.dto.MotionDto; import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; import com.zy.asrs.wcs.core.model.enums.MotionCtgType; import com.zy.asrs.wcs.rcs.entity.Motion; import com.zy.asrs.wcs.rcs.service.MotionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; /** * Created by vincent on 2023/10/9 */ @Service(value = "kernelService") public class KernelService { @Autowired private MotionService motionService; // agv ----------------------------------------------------------------------------- @Deprecated public List<Motion> agvTransport() { List<Motion> motionList = new ArrayList<>(); // 1.AGV搬运货物 motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.AGV.val()); motion.setMotionCtg(MotionCtgType.AGV_TRANSPORT.val()); })); return motionList; } // lift ----------------------------------------------------------------------------- /** * 提升机移动 */ public List<Motion> liftMove(MotionDto origin, MotionDto target) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.LIFT.val()); motion.setDevice(String.valueOf(target.getLiftNo())); motion.setMotionCtg(MotionCtgType.LIFT_MOVE.val()); if (null != origin) { motion.setOrigin(String.valueOf(origin.getLev())); } motion.setTarget(String.valueOf(target.getLev())); })); // if (target.getUpdateLiftNo() != null && target.getWrkNo() != null) { // if (target.getUpdateLiftNo()) { // // } // } return motionList; } /** * 提升机载货移动 */ public List<Motion> liftMoveGoods(MotionDto origin, MotionDto target) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.LIFT.val()); motion.setDevice(String.valueOf(target.getLiftNo())); motion.setMotionCtg(MotionCtgType.LIFT_WITH_GOODS.val()); if (null != origin) { motion.setOrigin(String.valueOf(origin.getLev())); } motion.setTarget(String.valueOf(target.getLev())); })); return motionList; } /** * 提升机搬运穿梭车 */ public List<Motion> liftMoveShuttle(MotionDto origin, MotionDto target) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.LIFT.val()); motion.setDevice(String.valueOf(target.getLiftNo())); motion.setMotionCtg(MotionCtgType.LIFT_WITH_SHUTTLE.val()); if (null != origin) { motion.setOrigin(String.valueOf(origin.getLev())); } motion.setTarget(String.valueOf(target.getLev())); })); return motionList; } /** * 提升机载穿梭车与货移动 */ public List<Motion> liftMoveGoodsAndShuttle(MotionDto origin, MotionDto target) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.LIFT.val()); motion.setDevice(String.valueOf(target.getLiftNo())); motion.setMotionCtg(MotionCtgType.LIFT_WITH_GOODS_AND_SHUTTLE.val()); if (null != origin) { motion.setOrigin(String.valueOf(origin.getLev())); } motion.setTarget(String.valueOf(target.getLev())); })); return motionList; } /** * 提升机载穿梭车与货移动 */ public List<Motion> liftTransportGoodsToConveyor(MotionDto origin, MotionDto target) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.LIFT.val()); motion.setDevice(String.valueOf(origin.getLiftNo())); motion.setMotionCtg(MotionCtgType.LIFT_TRANSPORT_TO_CONVEYOR.val()); motion.setOrigin(String.valueOf(origin.getLev())); motion.setDockNo(String.valueOf(target.getDevpNo())); motion.setTarget(String.valueOf(target.getStaNo())); })); return motionList; } // shuttle ----------------------------------------------------------------------------- /** * 穿梭车空载移动 */ public List<Motion> shuttleMove(MotionDto origin, MotionDto target, MotionCtgType motionCtgType) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.SHUTTLE.val()); motion.setDevice(String.valueOf(target.getShuttleNo())); motion.setMotionCtg(motionCtgType.val()); motion.setOrigin(origin.getLocNo()); motion.setTarget(target.getLocNo()); switch (motionCtgType) { case SHUTTLE_MOVE_FROM_LIFT://穿梭车移出提升机 motion.setTemp(String.valueOf(origin.getLiftNo()));//保存提升机号 break; case SHUTTLE_MOVE_TO_LIFT://穿梭车移动到提升机 motion.setTemp(String.valueOf(target.getLiftNo()));//保存提升机号 break; case SHUTTLE_MOVE_FROM_CONVEYOR: motion.setDockNo(String.valueOf(origin.getStaNo())); break; case SHUTTLE_MOVE_TO_CONVEYOR: motion.setDockNo(String.valueOf(target.getStaNo())); break; case SHUTTLE_MOVE_FROM_LIFT_TO_CONVEYOR://穿梭车移出提升机去输送线 motion.setTemp(String.valueOf(origin.getLiftNo()));//保存提升机号 motion.setDockNo(String.valueOf(target.getStaNo())); break; default: break; } })); return motionList; } /** * 穿梭车载货移动 */ public List<Motion> shuttleTransport(MotionDto origin, MotionDto target, MotionCtgType motionCtgType) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.SHUTTLE.val()); motion.setDevice(String.valueOf(target.getShuttleNo())); motion.setMotionCtg(motionCtgType.val()); switch (motionCtgType) { case SHUTTLE_TRANSPORT_FROM_LIFT: motion.setTemp(String.valueOf(origin.getLiftNo()));//保存提升机号 break; case SHUTTLE_TRANSPORT_TO_LIFT: motion.setTemp(String.valueOf(target.getLiftNo()));//保存提升机号 break; case SHUTTLE_TRANSPORT_FROM_CONVEYOR: motion.setDockNo(String.valueOf(origin.getStaNo())); break; case SHUTTLE_TRANSPORT_TO_CONVEYOR: motion.setDockNo(String.valueOf(target.getStaNo())); break; default: break; } motion.setOrigin(origin.getLocNo()); motion.setTarget(target.getLocNo()); })); return motionList; } public List<Motion> shuttleCharge(MotionDto origin, MotionDto target) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.SHUTTLE.val()); motion.setDevice(String.valueOf(target.getShuttleNo())); motion.setMotionCtg(MotionCtgType.SHUTTLE_CHARGE_ON.val()); })); return motionList; } // conveyor ----------------------------------------------------------------------------- /** * 输送线入库 */ public List<Motion> conveyorInbound(MotionDto origin, MotionDto target, MotionCtgType motionCtgType) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.CONVEYOR.val()); motion.setDevice(String.valueOf(origin.getDevpNo())); motion.setMotionCtg(motionCtgType.val()); switch (motionCtgType) { case CONVEYOR_INBOUND: motion.setTarget(String.valueOf(target.getStaNo())); break; case CONVEYOR_INBOUND_TO_LIFT: motion.setDockNo(String.valueOf(target.getLiftNo())); motion.setTarget(String.valueOf(target.getLev())); break; default: break; } motion.setOrigin(String.valueOf(origin.getStaNo())); })); return motionList; } /** * 输送线出库 */ public List<Motion> conveyorOutbound(MotionDto origin, MotionDto target, MotionCtgType motionCtgType) { List<Motion> motionList = new ArrayList<>(); motionList.add(Motion.build(motion -> { motion.setDeviceCtg(DeviceCtgType.CONVEYOR.val()); motion.setDevice(String.valueOf(origin.getDevpNo())); motion.setMotionCtg(motionCtgType.val()); switch (motionCtgType) { case CONVEYOR_OUTBOUND: motion.setOrigin(String.valueOf(origin.getStaNo())); break; case CONVEYOR_OUTBOUND_FROM_LIFT: motion.setDockNo(String.valueOf(origin.getLiftNo())); break; default: break; } motion.setTarget(String.valueOf(target.getStaNo())); })); return motionList; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/mapper/TaskMapper.java
@@ -3,10 +3,15 @@ import com.zy.asrs.wcs.core.entity.Task; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; @Mapper @Repository public interface TaskMapper extends BaseMapper<Task> { List<Task> selectOutboundByShuttleNo(@Param("shuttleNo") Integer shuttleNo); } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/LiftCodeType.java
New file @@ -0,0 +1,79 @@ package com.zy.asrs.wcs.core.model.enums; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.framework.common.SpringUtils; import com.zy.asrs.wcs.core.entity.Loc; import com.zy.asrs.wcs.core.service.LocService; import com.zy.asrs.wcs.core.utils.Utils; public enum LiftCodeType { NONE(-1, -1, "未知", "0402001"), LIFT_2(2, 198, "2号提升机二维码", "0402001"), LIFT_1(1, 0, "1号提升机无二维码", "0800701"), ; public Integer liftNo; public Integer code; public String desc; public String standbyLocNo;//待机库位 LiftCodeType(Integer liftNo, Integer code, String desc, String standbyLocNo) { this.liftNo = liftNo; this.code = code; this.desc = desc; this.standbyLocNo = standbyLocNo; } public static LiftCodeType query(Integer code) { for (LiftCodeType value : LiftCodeType.values()) { if (value.code.equals(code)) { return value; } } return NONE; } public static String getLocNo(Integer liftNo, Integer lev, Long hostId) { LiftCodeType type = null; for (LiftCodeType value : LiftCodeType.values()) { if (value.liftNo.equals(liftNo)) { type = value; break; } } if (type == null) { return null; } LocService locService = SpringUtils.getBean(LocService.class); Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>() .eq(Loc::getHostId, hostId) .eq(Loc::getCode, type.code) .eq(Loc::getLev, lev)); if (loc == null) { return null; } return loc.getLocNo(); } public static String getStandbyLocNo(Integer liftNo, Integer lev) { LiftCodeType type = null; for (LiftCodeType value : LiftCodeType.values()) { if (value.liftNo.equals(liftNo)) { type = value; break; } } if (type == null) { return null; } return Utils.getLocNo(Utils.getRow(type.standbyLocNo), Utils.getBay(type.standbyLocNo), lev); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/TaskStsType.java
New file @@ -0,0 +1,49 @@ package com.zy.asrs.wcs.core.model.enums; import com.zy.asrs.framework.exception.CoolException; public enum TaskStsType { NEW_INBOUND(1, "生成入库任务"), ANALYZE_INBOUND(2, "入库任务解析"), EXECUTE_INBOUND(3, "执行入库任务"), COMPLETE_INBOUND(9, "入库完成"), SETTLE_INBOUND(10, "入库库存更新"), NEW_OUTBOUND(101, "生成出库任务"), ANALYZE_OUTBOUND(102, "出库任务解析"), EXECUTE_OUTBOUND(103, "执行出库任务"), COMPLETE_OUTBOUND(109, "出库完成"), SETTLE_OUTBOUND(110, "出库库存更新"), NEW_CHARGE(201, "生成充电任务"), ANALYZE_CHARGE(202, "充电任务解析"), EXECUTE_CHARGE(203, "执行充电任务"), CHARGE_WORKING(204, "充电中"), COMPLETE_CHARGE(210, "充电完成"), NEW_MOVE(301, "生成迁移任务"), ANALYZE_MOVE(302, "迁移任务解析"), EXECUTE_MOVE(303, "执行迁移任务"), COMPLETE_MOVE(310, "迁移完成"), ; public long sts; public String desc; TaskStsType(long sts, String desc) { this.sts = sts; this.desc = desc; } public static TaskStsType query(Long sts) { for (TaskStsType value : TaskStsType.values()) { if (value.sts == sts) { return value; } } throw new CoolException("TaskStsType Error!!!"); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/WorkZoneType.java
New file @@ -0,0 +1,34 @@ package com.zy.asrs.wcs.core.model.enums; import com.zy.asrs.framework.exception.CoolException; import java.util.ArrayList; import java.util.List; public enum WorkZoneType { FIRST_ZONE(new ArrayList<Integer>(){{add(1);add(2);}}, 2, 1), SECOND_ZONE(new ArrayList<Integer>(){{add(3);add(4);}}, 2, 1), THIRD_ZONE(new ArrayList<Integer>(){{add(5);add(6);add(7);add(8);add(9);add(10);add(11);}}, 1, 2) ; public List<Integer> staList; public Integer liftNo; public Integer devpPlcId; WorkZoneType(List<Integer> staList, Integer liftNo, Integer devpPlcId) { this.staList = staList; this.liftNo = liftNo; this.devpPlcId = devpPlcId; } public static WorkZoneType query(String sta) { for (WorkZoneType value : WorkZoneType.values()) { if (value.staList.contains(String.valueOf(sta))) { return value; } } throw new CoolException("WorkZoneType Error !!!"); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/TaskService.java
@@ -2,7 +2,14 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.zy.asrs.wcs.core.entity.Task; import org.apache.ibatis.annotations.Param; import java.util.List; public interface TaskService extends IService<Task> { Boolean judgeInbound(Task task); Boolean hasBusyOutboundByShuttle(Integer shuttleNo); } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/TaskServiceImpl.java
@@ -1,12 +1,57 @@ package com.zy.asrs.wcs.core.service.impl; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.wcs.core.mapper.TaskMapper; import com.zy.asrs.wcs.core.entity.Task; import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; import com.zy.asrs.wcs.core.model.enums.TaskStsType; import com.zy.asrs.wcs.core.service.TaskService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.zy.asrs.wcs.rcs.service.MotionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service("taskService") public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements TaskService { @Autowired private MotionService motionService; @Override public Boolean judgeInbound(Task task) { switch (TaskStsType.query(task.getTaskSts())) { case NEW_INBOUND: case ANALYZE_INBOUND: case EXECUTE_INBOUND: case COMPLETE_INBOUND: case SETTLE_INBOUND: return Boolean.TRUE; case NEW_OUTBOUND: case ANALYZE_OUTBOUND: case EXECUTE_OUTBOUND: case COMPLETE_OUTBOUND: case SETTLE_OUTBOUND: return Boolean.FALSE; } return Boolean.TRUE; } @Override public Boolean hasBusyOutboundByShuttle(Integer shuttleNo) { List<Task> tasks = this.baseMapper.selectOutboundByShuttleNo(shuttleNo); if (Cools.isEmpty(tasks)) { return false; } for (Task task : tasks) { if (task.getTaskSts().equals(TaskStsType.NEW_OUTBOUND.sts) || task.getTaskSts().equals(TaskStsType.ANALYZE_OUTBOUND.sts)) { return true; } if (!Cools.isEmpty(motionService.selectUnCompleteByUuidAndDeviceCtg(task.getUuid(), DeviceCtgType.SHUTTLE))) { return true; } } return false; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ConveyorDispatcher.java
New file @@ -0,0 +1,45 @@ //package com.zy.asrs.wcs.core.utils; // //import com.zy.core.model.DevpSlave; //import com.zy.core.properties.SlaveProperties; //import lombok.extern.slf4j.Slf4j; //import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.stereotype.Service; // ///** // * Created by vincent on 2023/10/20 // */ //@Slf4j //@Service //public class ConveyorDispatcher { // // @Autowired // private SlaveProperties slaveProperties; // // public DevpSlave queryByInBound(Integer staNo) { // for (DevpSlave devpSlave : slaveProperties.getDevp()) { // for (DevpSlave.Sta sta : devpSlave.getInSta()) { // if (sta.getStaNo().equals(staNo)) { // return devpSlave; // } // } // // } // return null; // } // // public DevpSlave queryByOutBound(Integer staNo) { // for (DevpSlave devpSlave : slaveProperties.getDevp()) { // for (DevpSlave.Sta sta : devpSlave.getOutSta()) { // if (sta.getStaNo().equals(staNo)) { // return devpSlave; // } // } // // } // return null; // } // // // //} zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/LiftDispatcher.java
New file @@ -0,0 +1,21 @@ package com.zy.asrs.wcs.core.utils; import com.zy.asrs.wcs.core.model.enums.WorkZoneType; import com.zy.asrs.wcs.rcs.cache.SlaveConnection; import com.zy.asrs.wcs.rcs.model.enums.SlaveType; import com.zy.asrs.wcs.rcs.thread.LiftThread; import org.springframework.stereotype.Service; /** * Created by vincent on 2023/10/16 */ @Service public class LiftDispatcher { public LiftThread queryLiftForTransport(String staNo) { WorkZoneType zoneType = WorkZoneType.query(staNo); LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, zoneType.liftNo); return liftThread; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java
New file @@ -0,0 +1,176 @@ package com.zy.asrs.wcs.core.utils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.common.wms.service.CommonService; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.SnowflakeIdWorker; import com.zy.asrs.framework.exception.CoolException; import com.zy.asrs.wcs.core.entity.Task; import com.zy.asrs.wcs.core.kernel.AnalyzeService; import com.zy.asrs.wcs.core.model.NavigateNode; import com.zy.asrs.wcs.core.model.enums.LiftCodeType; import com.zy.asrs.wcs.core.model.enums.NavigationMapType; import com.zy.asrs.wcs.core.service.TaskService; import com.zy.asrs.wcs.rcs.cache.SlaveConnection; import com.zy.asrs.wcs.rcs.entity.Device; import com.zy.asrs.wcs.rcs.entity.DeviceType; import com.zy.asrs.wcs.rcs.model.enums.SlaveType; import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol; import com.zy.asrs.wcs.rcs.service.DeviceService; import com.zy.asrs.wcs.rcs.service.DeviceTypeService; import com.zy.asrs.wcs.rcs.service.MotionService; import com.zy.asrs.wcs.rcs.thread.ShuttleThread; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; import java.util.List; /** * Created by vincent on 2023/10/12 */ @Service public class ShuttleDispatcher { private static final Integer INF = 9999999; private static final Integer WEIGHT = 1000000; @Autowired private TaskService taskService; @Autowired private LiftDispatcher liftDispatcher; @Autowired private SnowflakeIdWorker snowflakeIdWorker; // @Autowired // private CommonService commonService; @Autowired private AnalyzeService analyzeService; @Autowired private MotionService motionService; @Autowired private DeviceService deviceService; @Autowired private DeviceTypeService deviceTypeService; public ShuttleThread queryShuttleWhichConvenient(Task task, Integer liftNo) { String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc(); ShuttleThread resThread = null; Integer finalDistance = ShuttleDispatcher.INF; DeviceType deviceType = deviceTypeService.getOne(new LambdaQueryWrapper<DeviceType>() .eq(DeviceType::getHostId, task.getHostId()) .eq(DeviceType::getStatus, 1) .eq(DeviceType::getFlag, String.valueOf(SlaveType.Shuttle))); if (deviceType == null) { throw new CoolException("设备类型不存在"); } List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>() .eq(Device::getDeviceType, deviceType.getId()) .eq(Device::getHostId, task.getHostId()) .eq(Device::getStatus, 1)); for (Device device : list) { if (taskService.hasBusyOutboundByShuttle(Integer.parseInt(device.getDeviceNo()))) { continue; } //获取四向穿梭车线程 ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) { continue; } if (!shuttleProtocol.isIdle()) { continue; } // //检测是否存在充电任务 // WrkCharge wrkCharge = wrkChargeService.selectWorking(shuttle.getId()); // if (wrkCharge != null) { // continue; // } // 有没有被其他任务调度 int currentLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//小车当前层高 String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号 if (currentLocNo.equals(locNo)) { resThread = shuttleThread; break; } String targetLocNo = LiftCodeType.getStandbyLocNo(liftNo, currentLev);//默认到提升机待机位 // 同楼层直接计算到目标库位 if (currentLev == Utils.getLev(locNo)) { targetLocNo = locNo; } //当前穿梭车线程到当前车子所在楼层的提升机口距离 List<NavigateNode> currentShuttlePath = NavigateUtils.calc( currentLocNo , targetLocNo , NavigationMapType.NORMAL.id , Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), currentLev) );//搜索空闲穿梭车,使用正常通道地图 if (currentShuttlePath == null) { continue; } Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 // 不同楼层权重 if (currentLev != Utils.getLev(locNo)) { currDistance += WEIGHT; } // // 挂载任务权重 // List<Task> tasks = taskService.selectWorkingByShuttle(shuttle.getId()); // if (!Cools.isEmpty(tasks)) { // currDistance += tasks.size() * WEIGHT; // } if (currDistance < finalDistance) { finalDistance = currDistance; resThread = shuttleThread; } } return resThread; } // /** // * 生成穿梭车迁移任务 // */ // public WrkCharge generateShuttleChargeWrkComplete(Integer shuttleNo, String locNo) { // WrkCharge wrkCharge = new WrkCharge(); // wrkCharge.setShuttleNo(shuttleNo); // wrkCharge.setWrkNo(commonService.getChargeWorkNo(4)); // wrkCharge.setUuid(String.valueOf(snowflakeIdWorker.nextId())); // wrkCharge.setWrkSts(WrkMastStsType.NEW_MOVE.sts); // 迁移任务 // wrkCharge.setIoType(WrkIoTypeType.MOVE.sts); // wrkCharge.setIoPri((double) 10); // wrkCharge.setLocNo(locNo); // wrkCharge.setMemo("reset"); // wrkCharge.setAppeTime(new Date()); // // // generate motion list // List<Motion> motionList = analyzeService.generateShuttleChargeWrkComplete(wrkCharge); // if (Cools.isEmpty(motionList)) { // News.error("保存{}号四向穿梭车迁移任务失败!!!", shuttleNo); // return null; // } // motionService.batchInsert(motionList, wrkCharge.getUuid(), wrkCharge.getWrkNo()); // // wrkCharge.setWrkSts(WrkMastStsType.ANALYZE_MOVE.sts); // // if (!wrkChargeService.insert(wrkCharge)) { // News.error("保存{}号四向穿梭车迁移任务失败!!!", shuttleNo); // return null; // } // // return wrkCharge; // } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/entity/Motion.java
@@ -3,7 +3,9 @@ import java.text.SimpleDateFormat; import java.util.Date; import com.zy.asrs.wcs.core.BuildSupport; import com.zy.asrs.wcs.core.entity.DeviceCtg; import com.zy.asrs.wcs.core.model.enums.MotionStsType; import com.zy.asrs.wcs.core.service.DeviceCtgService; import com.zy.asrs.wcs.rcs.service.DeviceTypeService; import com.zy.asrs.wcs.rcs.service.MotionCtgService; @@ -273,6 +275,25 @@ this.hostId = hostId; } public static Motion build(BuildSupport<Motion> support) { Motion motion = new Motion(); Date date = new Date(); support.execute(motion); if (null == motion.getSync()) { motion.setSync(1); } if (null == motion.getMotionSts()) { motion.setMotionSts(MotionStsType.INIT.val()); } motion.setStatus(1); motion.setCreateTime(date); motion.setUpdateTime(date); return motion; } // Motion motion = new Motion( // null, // 编号 // null, // 任务号 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/ShuttleProtocol.java
@@ -249,4 +249,23 @@ return currentLoc.getLocNo(); } // 是否处于空闲待命状态 public Boolean isIdle() { if (this.deviceStatus == null || this.pakMk == null || this.errorCode == null || this.protocolStatus == null ) { return false; } boolean res = this.deviceStatus.equals(ShuttleDeviceStatusType.IDLE) && this.pakMk && !this.errorCode.equals("0") && this.getTaskNo() == 0 && this.protocolStatus.intValue() == ShuttleProtocolStatusType.IDLE.id ; return res; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/MotionService.java
@@ -1,8 +1,13 @@ package com.zy.asrs.wcs.rcs.service; import com.baomidou.mybatisplus.extension.service.IService; import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; import com.zy.asrs.wcs.rcs.entity.Motion; import java.util.List; public interface MotionService extends IService<Motion> { List<Motion> selectUnCompleteByUuidAndDeviceCtg(String uuid, DeviceCtgType deviceCtgType); } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/service/impl/MotionServiceImpl.java
@@ -1,12 +1,34 @@ package com.zy.asrs.wcs.rcs.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; import com.zy.asrs.wcs.core.model.enums.MotionStsType; import com.zy.asrs.wcs.core.service.DeviceCtgService; import com.zy.asrs.wcs.rcs.mapper.MotionMapper; import com.zy.asrs.wcs.rcs.entity.Motion; import com.zy.asrs.wcs.rcs.service.MotionService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.zy.asrs.wcs.rcs.service.MotionStsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service("motionService") public class MotionServiceImpl extends ServiceImpl<MotionMapper, Motion> implements MotionService { @Autowired private DeviceCtgService deviceCtgService; @Autowired private MotionStsService motionStsService; @Override public List<Motion> selectUnCompleteByUuidAndDeviceCtg(String uuid, DeviceCtgType deviceCtgType) { return this.list(new LambdaQueryWrapper<Motion>() .eq(Motion::getUuid, uuid) .eq(Motion::getDeviceCtg, deviceCtgService.selectByFlag(deviceCtgType.toString()).getId()) .lt(Motion::getMotionSts, motionStsService.selectByFlag(MotionStsType.COMPLETE.toString()).getId()) .orderByDesc(Motion::getPriority) ); } } zy-asrs-wcs/src/main/resources/mapper/core/TaskMapper.xml
@@ -2,4 +2,12 @@ <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.wcs.core.mapper.TaskMapper"> <select id="selectOutboundByShuttleNo" resultType="com.zy.asrs.wcs.core.entity.Task"> select * from wcs_task where 1=1 and task_sts in (101, 102, 103) and shuttle_no = #{shuttleNo} order by priority desc,start_time,task_no asc </select> </mapper>