| | |
| | | import com.zy.asrs.wcs.core.entity.*; |
| | | import com.zy.asrs.wcs.core.kernel.AnalyzeService; |
| | | import com.zy.asrs.wcs.core.model.NavigateNode; |
| | | import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; |
| | | import com.zy.asrs.wcs.core.model.enums.NavigationMapType; |
| | | 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.enums.*; |
| | | import com.zy.asrs.wcs.core.service.*; |
| | | import com.zy.asrs.wcs.rcs.News; |
| | | import com.zy.asrs.wcs.rcs.cache.SlaveConnection; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 搜索可用库位,通过小车号和目标库位 |
| | | */ |
| | | public String searchAvailableLocNo(Integer shuttleNo, Long hostId, String currentLocNo, List<String> locNos) { |
| | | BasShuttle basShuttle = basShuttleService.getOne(new LambdaQueryWrapper<BasShuttle>() |
| | | .eq(BasShuttle::getShuttleNo, shuttleNo) |
| | | .eq(BasShuttle::getHostId, hostId)); |
| | | if (basShuttle == null) { |
| | | throw new CoolException("小车基础数据不存在"); |
| | | } |
| | | |
| | | if (locNos.isEmpty()) { |
| | | throw new CoolException("当前层无避让位置"); |
| | | } |
| | | |
| | | int lev = Utils.getLev(currentLocNo); |
| | | |
| | | Integer finalDistance = ShuttleDispatcher.INF; |
| | | String recentLoc = null; |
| | | for (String loc : locNos) { |
| | | //当前穿梭车到避让位计算 |
| | | List<NavigateNode> currentShuttlePath = NavigateUtils.calc( |
| | | currentLocNo |
| | | , loc |
| | | , NavigationMapType.NORMAL.id |
| | | , Utils.getShuttlePoints(shuttleNo, lev) |
| | | );//使用正常通道地图 |
| | | if (currentShuttlePath == null) { |
| | | continue; |
| | | } |
| | | |
| | | Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 |
| | | if (currDistance < finalDistance) { |
| | | finalDistance = currDistance; |
| | | recentLoc = loc; |
| | | } |
| | | } |
| | | |
| | | if (recentLoc == null) { |
| | | throw new CoolException("搜索避让位置失败"); |
| | | } |
| | | |
| | | return recentLoc; |
| | | } |
| | | |
| | | /** |
| | | * 检测目标楼层车数量是否小于允许的最大数量 |
| | | * true: 小于最大数量 false: 大于或等于最大数量 |
| | | */ |
| | |
| | | |
| | | } |
| | | |
| | | //搜索是否存在前往目标楼层的小车工作档 |
| | | for (Task task : taskService.list(new LambdaQueryWrapper<Task>() |
| | | .in(Task::getTaskSts, TaskStsType.NEW_INBOUND.sts, TaskStsType.ANALYZE_INBOUND.sts, TaskStsType.EXECUTE_INBOUND.sts, TaskStsType.COMPLETE_INBOUND.sts |
| | | , TaskStsType.NEW_OUTBOUND.sts, TaskStsType.ANALYZE_OUTBOUND.sts, TaskStsType.EXECUTE_OUTBOUND.sts, TaskStsType.COMPLETE_OUTBOUND.sts))) { |
| | | |
| | | List<Motion> motions = motionService.list(new LambdaQueryWrapper<Motion>() |
| | | .eq(Motion::getTaskNo, task.getTaskNo()) |
| | | .in(Motion::getMotionCtg, MotionCtgType.SHUTTLE_MOVE |
| | | , MotionCtgType.SHUTTLE_MOVE_LIFT_PALLET |
| | | , MotionCtgType.SHUTTLE_MOVE_DOWN_PALLET |
| | | , MotionCtgType.SHUTTLE_MOVE_FROM_LIFT |
| | | , MotionCtgType.SHUTTLE_MOVE_TO_LIFT |
| | | , MotionCtgType.SHUTTLE_MOVE_FROM_CONVEYOR |
| | | , MotionCtgType.SHUTTLE_MOVE_TO_CONVEYOR |
| | | , MotionCtgType.SHUTTLE_MOVE_FROM_LIFT_TO_CONVEYOR |
| | | )); |
| | | |
| | | boolean isUpdateLev = false; |
| | | for (Motion motion : motions) { |
| | | if (motion.getOrigin() == null || motion.getTarget() == null) { |
| | | continue; |
| | | } |
| | | |
| | | int sourceLev = Utils.getLev(motion.getOrigin());//动作源楼层 |
| | | int targetLev = Utils.getLev(motion.getTarget());//动作目标楼层 |
| | | if (sourceLev != targetLev) { |
| | | isUpdateLev = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if(isUpdateLev) { |
| | | levCount++;//工作档属于跨层任务,小车归属于目标楼层 |
| | | continue; |
| | | } |
| | | |
| | | } |
| | | |
| | | return levCount < Integer.parseInt(dict.getValue()); |
| | | } |
| | | //分析出库路径待机库位 |
| | | public String analyzeOutPathWaitLoc(String startLoc, String targetLoc, Device shuttleDevice) { |
| | | //计算路径并分解成两段动作 |
| | | List<NavigateNode> nodeList = NavigateUtils.calc(startLoc, targetLoc, NavigationMapType.DFX.id, Utils.getShuttlePoints(Integer.parseInt(shuttleDevice.getDeviceNo()), Utils.getLev(startLoc))); |
| | | if (nodeList == null) { |
| | | News.error("{} dash {} can't find navigate path!", startLoc, targetLoc); |
| | | return null; |
| | | } |
| | | //获取分段路径 |
| | | ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(nodeList); |
| | | if (data.size() <= 1) { |
| | | return null;//两点之间只有一段路径 |
| | | } |
| | | |
| | | //取出倒数第二段路径 |
| | | ArrayList<NavigateNode> navigateNodes = data.get(data.size() - 2); |
| | | NavigateNode startNode = navigateNodes.get(0); |
| | | String lastPathStartLoc = Utils.getLocNo(startNode.getX(), startNode.getY(), startNode.getZ()); |
| | | return lastPathStartLoc; |
| | | } |
| | | |
| | | } |