zy-asrs-flow/src/pages/deviceConfig/shuttleStandby/components/edit.jsx
@@ -174,6 +174,13 @@ colProps={{ md: 12, xl: 12 }} /> </ProForm.Group> <ProForm.Group> <ProFormText name="lockPath" label="换层锁定路径" colProps={{ md: 12, xl: 12 }} /> </ProForm.Group> </ProForm> </Modal> zy-asrs-flow/src/pages/deviceConfig/shuttleStandby/index.jsx
@@ -305,6 +305,19 @@ setSearchParam={setSearchParam} />, }, { title: '换层锁定路径', dataIndex: 'lockPath', valueType: 'text', hidden: false, width: 140, filterDropdown: (props) => <TextFilter name='lockPath' {...props} actionRef={actionRef} setSearchParam={setSearchParam} />, }, { title: '操作', zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/TaskController.java
@@ -201,6 +201,7 @@ MotionLog motionLog = new MotionLog(); motionLog.sync(motion); motionLog.setUpdateTime(new Date()); motionLog.setHostId(null); motionLogService.save(motionLog); } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/ShuttleStandby.java
@@ -1,8 +1,9 @@ package com.zy.asrs.wcs.core.entity; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.annotation.TableLogic; import java.text.SimpleDateFormat; import java.util.Date; import java.util.*; import com.zy.asrs.wcs.system.entity.Host; import com.zy.asrs.wcs.system.entity.User; @@ -137,6 +138,12 @@ @ApiModelProperty(value= "小车待机位库位号") private String standbyLoc; /** * 换层锁定路径 */ @ApiModelProperty(value= "换层锁定路径") private String lockPath; public ShuttleStandby() {} public ShuttleStandby(String uuid,String name,String flag,Long hostId,Integer status,Integer deleted,Date createTime,Long createBy,Date updateTime,Long updateBy,String memo,Long deviceId,Integer deviceLev,String deviceLoc,String deviceStandbyLoc,String standbyLoc) { @@ -242,5 +249,14 @@ return null; } public List<String> getLockPath$() { ArrayList<String> list = new ArrayList<>(); if (this.lockPath != null) { List<String> lockPaths = JSON.parseArray(this.lockPath, String.class); list.addAll(lockPaths); } return list; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java
@@ -1,17 +1,14 @@ package com.zy.asrs.wcs.core.kernel; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.wcs.core.domain.dto.MotionDto; import com.zy.asrs.wcs.core.entity.*; import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; import com.zy.asrs.wcs.core.model.enums.MotionCtgType; import com.zy.asrs.wcs.core.model.enums.TaskCtgType; import com.zy.asrs.wcs.core.model.enums.TaskStsType; import com.zy.asrs.wcs.core.model.NavigateNode; import com.zy.asrs.wcs.core.model.enums.*; import com.zy.asrs.wcs.core.service.*; import com.zy.asrs.wcs.core.utils.ConveyorDispatcher; 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.core.utils.*; import com.zy.asrs.wcs.rcs.News; import com.zy.asrs.wcs.rcs.cache.SlaveConnection; import com.zy.asrs.wcs.rcs.entity.Device; import com.zy.asrs.wcs.rcs.model.enums.SlaveType; @@ -155,6 +152,9 @@ //穿梭车出提升机待机位库位号 String standbyLocNoFrom = shuttleStandbyFrom.getDeviceStandbyLoc(); //换层需要锁定的路径 List<String> lockPath = shuttleStandbyFrom.getLockPath$(); // 入库目标层有穿梭车 if (Utils.getLev(shuttleLocNo) == Utils.getLev(task.getDestLoc())) { @@ -196,7 +196,7 @@ MotionCtgType.SHUTTLE_PALLET_LIFT )); // 穿梭车走行至目标库位 // 穿梭车载货走行至目标库位 motionList.addAll(kernelService.shuttleMove( MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); @@ -207,7 +207,7 @@ dto.setLiftNo(transferLiftDevice.getId().intValue()); dto.setLocNo(destLoc); })), MotionCtgType.SHUTTLE_MOVE MotionCtgType.SHUTTLE_TRANSPORT )); // 穿梭车入库托盘下降 @@ -253,12 +253,12 @@ MotionCtgType.SHUTTLE_MOVE )); // 锁定目标楼层穿梭车待机位路径 // 锁定换层路径 motionList.addAll(kernelService.mapLockPath( null, MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(standbyLocNoFrom); dto.setLocNo(JSON.toJSONString(lockPath)); })) )); @@ -353,6 +353,15 @@ })) )); // 解锁换层路径 motionList.addAll(kernelService.mapUnlockPath( null, MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(JSON.toJSONString(lockPath)); })) )); // 穿梭车入库顶升 motionList.addAll(kernelService.shuttleAction( null, @@ -362,7 +371,7 @@ MotionCtgType.SHUTTLE_PALLET_LIFT )); // 穿梭车走行至目标库位 // 穿梭车载货走行至目标库位 motionList.addAll(kernelService.shuttleMove( MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); @@ -373,7 +382,7 @@ dto.setLiftNo(transferLiftDevice.getId().intValue()); dto.setLocNo(destLoc); })), MotionCtgType.SHUTTLE_MOVE MotionCtgType.SHUTTLE_TRANSPORT )); // 穿梭车入库托盘下降 @@ -470,6 +479,9 @@ //穿梭车出提升机后小车待机位 String shuttleFromLiftStandbyLoc = shuttleStandbyFrom.getStandbyLoc(); //换层需要锁定的路径 List<String> lockPath = shuttleStandbyFrom.getLockPath$(); //获取出库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.OUT)) @@ -485,6 +497,19 @@ if (basConveyorPath == null) { return motionList; } //计算路径并分解成两段动作 List<NavigateNode> nodeList = NavigateUtils.calc(originLoc, standbyLocNoTo, NavigationMapType.DFX.id, Utils.getShuttlePoints(Integer.parseInt(shuttleDevice.getDeviceNo()), Utils.getLev(originLoc))); if (nodeList == null) { News.error("{} dash {} can't find navigate path!", originLoc, standbyLocNoTo); return null; } //获取分段路径 ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(nodeList); //取出最后一段路径 ArrayList<NavigateNode> navigateNodes = data.get(data.size() - 1); NavigateNode startNode = navigateNodes.get(0); String lastPathStartLoc = Utils.getLocNo(startNode.getX(), startNode.getY(), startNode.getZ()); /** * 出库 @@ -516,7 +541,7 @@ MotionCtgType.SHUTTLE_PALLET_LIFT )); // 穿梭车出库至提升机待机位 // 穿梭车载货出库至最后一段路径等待 motionList.addAll(kernelService.shuttleMove( MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); @@ -524,10 +549,24 @@ })), MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(lastPathStartLoc); })), MotionCtgType.SHUTTLE_TRANSPORT )); // 穿梭车载货至提升机待机位 motionList.addAll(kernelService.shuttleMove( MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(lastPathStartLoc); })), MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLiftNo(transferLiftDevice.getId().intValue()); dto.setLocNo(standbyLocNoTo); dto.setStaNo(getStaByLev(Utils.getLev(task.getOriginLoc())));//输送站 })), MotionCtgType.SHUTTLE_MOVE MotionCtgType.SHUTTLE_TRANSPORT_TO_CONVEYOR )); // 穿梭车出库托盘下降 @@ -602,12 +641,12 @@ MotionCtgType.SHUTTLE_MOVE )); // 锁定目标楼层穿梭车待机位路径 // 锁定换层路径 motionList.addAll(kernelService.mapLockPath( null, MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(standbyLocNoFrom); dto.setLocNo(JSON.toJSONString(lockPath)); })) )); @@ -702,6 +741,15 @@ })) )); // 解锁换层路径 motionList.addAll(kernelService.mapUnlockPath( null, MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(JSON.toJSONString(lockPath)); })) )); // 穿梭车提升机待机位至出库库位 motionList.addAll(kernelService.shuttleMove( MotionDto.build((dto -> { @@ -725,7 +773,7 @@ MotionCtgType.SHUTTLE_PALLET_LIFT )); // 穿梭车出库至提升机待机位 // 穿梭车载货出库至最后一段路径等待 motionList.addAll(kernelService.shuttleMove( MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); @@ -733,10 +781,24 @@ })), MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(lastPathStartLoc); })), MotionCtgType.SHUTTLE_TRANSPORT )); // 穿梭车载货至提升机待机位 motionList.addAll(kernelService.shuttleMove( MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(lastPathStartLoc); })), MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLiftNo(transferLiftDevice.getId().intValue()); dto.setLocNo(standbyLocNoFrom); dto.setStaNo(getStaByLev(Utils.getLev(task.getOriginLoc())));//输送站 })), MotionCtgType.SHUTTLE_MOVE MotionCtgType.SHUTTLE_TRANSPORT_TO_CONVEYOR )); // 穿梭车出库托盘下降 @@ -1157,6 +1219,9 @@ //穿梭车出提升机待机位库位号 String standbyLocNoFrom = liftDispatcher.getLiftStandByLocNo(liftThread, Utils.getLev(task.getDestLoc())); //换层需要锁定的路径 List<String> lockPath = liftDispatcher.getLockPathByLocNo(liftThread, Utils.getLev(task.getDestLoc())); // 穿梭车走行至提升机库位待机位 motionList.addAll(kernelService.shuttleMove( @@ -1172,12 +1237,12 @@ MotionCtgType.SHUTTLE_MOVE )); // 锁定目标楼层穿梭车待机位路径 // 锁定换层路径 motionList.addAll(kernelService.mapLockPath( null, MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(standbyLocNoFrom); dto.setLocNo(JSON.toJSONString(lockPath)); })) )); @@ -1268,6 +1333,15 @@ null , MotionDto.build((dto -> { dto.setLiftNo(liftDevice.getId().intValue()); })) )); // 解锁换层路径 motionList.addAll(kernelService.mapUnlockPath( null, MotionDto.build((dto -> { dto.setShuttleNo(shuttleDevice.getId().intValue()); dto.setLocNo(JSON.toJSONString(lockPath)); })) )); @@ -1400,7 +1474,7 @@ motion.setMotionCtg(MotionCtgType.SHUTTLE_PALLET_LIFT.val()); })); // 穿梭车走行至目标库位 // 穿梭车载货走行至目标库位 motionList.addAll(kernelService.shuttleMove( MotionDto.build((dto -> { dto.setShuttleNo(device.getId().intValue()); @@ -1410,7 +1484,7 @@ dto.setShuttleNo(device.getId().intValue()); dto.setLocNo(targetLoc); })), MotionCtgType.SHUTTLE_MOVE MotionCtgType.SHUTTLE_TRANSPORT )); //托盘下降 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/KernelService.java
@@ -298,6 +298,9 @@ motion.setTemp(String.valueOf(origin.getLiftNo()));//保存提升机号 motion.setDockNo(String.valueOf(target.getStaNo())); break; case SHUTTLE_TRANSPORT_TO_CONVEYOR://穿梭车载货进输送线 motion.setDockNo(String.valueOf(target.getStaNo())); break; default: break; } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/MapCommandService.java
@@ -1,5 +1,6 @@ package com.zy.asrs.wcs.core.kernel.command; import com.alibaba.fastjson.JSON; import com.zy.asrs.wcs.core.entity.Motion; import com.zy.asrs.wcs.core.model.MapNode; import com.zy.asrs.wcs.core.model.NavigateNode; @@ -67,12 +68,20 @@ return false; } NavigateNode navigateNode = NavigatePositionConvert.locNoToNode(motion.getTarget()); List<NavigateNode> nodes = new ArrayList<>(); nodes.add(navigateNode); String target = motion.getTarget(); List<String> lockPath = JSON.parseArray(target, String.class); Integer lev = null; for (String loc : lockPath) { NavigateNode navigateNode = NavigatePositionConvert.locNoToNode(loc); nodes.add(navigateNode); lev = Utils.getLev(loc); } //所使用的路径进行锁定/解锁 boolean lockResult = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(motion.getTarget()), shuttleProtocol.getShuttleNo(), nodes, lock);//所使用的路径进行锁定/解锁 boolean lockResult = navigateMapUtils.writeNavigateNodeToRedisMap(lev, shuttleProtocol.getShuttleNo(), nodes, lock);//所使用的路径进行锁定/解锁 if (!lockResult) { return false;//锁定/解锁失败 } @@ -80,11 +89,17 @@ } private boolean checkLockPath(Motion motion, boolean lock) { NavigateNode navigateNode = NavigatePositionConvert.locNoToNode(motion.getTarget()); List<NavigateNode> nodes = new ArrayList<>(); nodes.add(navigateNode); int lev = Utils.getLev(motion.getTarget()); String target = motion.getTarget(); List<String> lockPath = JSON.parseArray(target, String.class); Integer lev = null; for (String loc : lockPath) { NavigateNode navigateNode = NavigatePositionConvert.locNoToNode(loc); nodes.add(navigateNode); lev = Utils.getLev(loc); } Object o = redisUtil.get(DeviceRedisConstant.MAP + lev); if (o == null) { @@ -103,6 +118,7 @@ //获取小车节点 List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleProtocol.getShuttleNo(), lev); navigateMapData.setLev(lev); List<List<MapNode>> map = navigateMapData.getJsonData(NavigationMapType.DFX.id, null, shuttlePoints); for (NavigateNode node : nodes) { zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/ShuttleCommandService.java
@@ -7,24 +7,20 @@ import com.zy.asrs.wcs.common.ExecuteSupport; import com.zy.asrs.wcs.core.action.LiftAction; import com.zy.asrs.wcs.core.action.ShuttleAction; import com.zy.asrs.wcs.core.entity.BasShuttle; import com.zy.asrs.wcs.core.entity.Loc; import com.zy.asrs.wcs.core.entity.Task; import com.zy.asrs.wcs.core.entity.*; import com.zy.asrs.wcs.core.model.NavigateNode; import com.zy.asrs.wcs.core.model.command.*; import com.zy.asrs.wcs.core.model.enums.*; import com.zy.asrs.wcs.core.service.BasShuttleService; import com.zy.asrs.wcs.core.service.LocService; import com.zy.asrs.wcs.core.service.TaskService; import com.zy.asrs.wcs.core.service.*; import com.zy.asrs.wcs.core.utils.*; import com.zy.asrs.wcs.rcs.News; import com.zy.asrs.wcs.rcs.cache.SlaveConnection; import com.zy.asrs.wcs.core.entity.Motion; import com.zy.asrs.wcs.rcs.model.enums.ShuttleProtocolStatusType; import com.zy.asrs.wcs.rcs.model.enums.SlaveType; import com.zy.asrs.wcs.rcs.model.protocol.LiftProtocol; import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol; import com.zy.asrs.wcs.core.service.MotionService; import com.zy.asrs.wcs.rcs.model.protocol.StaProtocol; import com.zy.asrs.wcs.rcs.thread.DevpThread; import com.zy.asrs.wcs.rcs.thread.LiftThread; import com.zy.asrs.wcs.rcs.thread.ShuttleThread; import lombok.extern.slf4j.Slf4j; @@ -60,6 +56,10 @@ private LiftAction liftAction; @Autowired private LiftDispatcher liftDispatcher; @Autowired private BasConveyorService basConveyorService; @Autowired private BasConveyorStaService basConveyorStaService; // 计算 public Boolean accept(Motion motion) { @@ -92,6 +92,11 @@ return false; } Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskNo, motion.getTaskNo())); if (task == null) { return false; } ShuttleAssignCommand assignCommand = new ShuttleAssignCommand(); assignCommand.setShuttleNo(deviceNo); assignCommand.setTaskNo(motion.getTaskNo()); @@ -112,6 +117,48 @@ if (String.valueOf(shuttleProtocol.getCurrentCode()).equals(locService.getOne(new LambdaQueryWrapper<Loc>() .eq(Loc::getLocNo, motion.getTarget()) .eq(Loc::getHostId, motion.getHostId())).getCode())) { return true; } shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread); shuttleTaskModeType = ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO; break; case SHUTTLE_TRANSPORT://穿梭车载货行走 // 如果已经在当前条码则过滤 if (String.valueOf(shuttleProtocol.getCurrentCode()).equals(locService.getOne(new LambdaQueryWrapper<Loc>() .eq(Loc::getLocNo, motion.getTarget()) .eq(Loc::getHostId, motion.getHostId())).getCode())) { return true; } shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread); shuttleTaskModeType = ShuttleTaskModeType.TRANSPORT; break; case SHUTTLE_TRANSPORT_TO_CONVEYOR://穿梭车载货进输送线 BasConveyorSta originStaObj = basConveyorStaService.selectBySiteNo(motion.getDockNo());//获取输送站点 if (originStaObj == null) { return false; } BasConveyor basConveyor = basConveyorService.getById(originStaObj.getConveyorId()); if(basConveyor == null) { return false; } DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue()); if (devpThread == null) { return false; } StaProtocol staProtocol = devpThread.getStation().get(Integer.parseInt(motion.getDockNo()));//输送站 if (staProtocol == null) { return false; } if (!(staProtocol.isAutoing() && !staProtocol.isLoading() && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable())) { return false; } // 如果已经在当前条码则过滤 if (String.valueOf(shuttleProtocol.getCurrentCode()).equals(locService.getOne(new LambdaQueryWrapper<Loc>() .eq(Loc::getLocNo, motion.getTarget()) .eq(Loc::getHostId, motion.getHostId())).getCode())) { return true; } shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread); @@ -297,6 +344,8 @@ case SHUTTLE_MOVE_DOWN_PALLET: case SHUTTLE_MOVE_TO_CONVEYOR: case SHUTTLE_MOVE_FROM_CONVEYOR: case SHUTTLE_TRANSPORT_TO_CONVEYOR://穿梭车载货进输送线 case SHUTTLE_TRANSPORT://穿梭车载货行走 if (!shuttleProtocol.getCurrentLocNo().equals(motion.getTarget())) { return false; } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/LiftDispatcher.java
@@ -125,6 +125,22 @@ return liftLocNo; } /** * 获取换层需要锁定的路径 */ public List<String> getLockPathByLocNo(LiftThread liftThread, Integer lev) { Device device = liftThread.getDevice(); ShuttleStandby standby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>() .eq(ShuttleStandby::getDeviceId, device.getId()) .eq(ShuttleStandby::getDeviceLev, lev) .eq(ShuttleStandby::getStatus, 1)); if (standby == null) { return null; } return standby.getLockPath$(); } public Integer getLiftLevOffset(Integer deviceId,Integer lev) { BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>().eq(BasLift::getDeviceId, deviceId)); if (basLift != null) {