| | |
| | | int backpackLev = 0; |
| | | int backpack = agvService.getBackpack(agvId); |
| | | List<Integer> usedBackpacks = segmentService.selectUsedBackpacks(currSeg.getTravelId(), agvId); |
| | | if (usedBackpacks.size() >= backpack) { |
| | | throw new CoolException("[Agv:" + agvNo + "] allocate inbound segment failed: no idle backpack to use"); |
| | | } |
| | | for (int lev = 1; lev <= backpack; lev++) { |
| | | if (!usedBackpacks.contains(lev)) { |
| | | backpackLev = lev; |
| | |
| | | currSeg.setState(SegmentStateType.INIT.toString()); |
| | | currSeg.setUpdateTime(now); |
| | | if (!segmentService.updateById(currSeg)) { |
| | | log.error("Segment [{}] failed to update !!!", currSeg.getGroupId() + " - " + currSeg.getSerial()); |
| | | // log.error("Segment [{}] failed to update !!!", currSeg.getGroupId() + " - " + currSeg.getSerial()); |
| | | throw new CoolException("failed to update segment [" + currSeg.getGroupId() + "-" + currSeg.getSerial() + "] failed"); |
| | | } |
| | | |
| | | // new oriSta seg |
| | |
| | | loadSeg.setCreateTime(now); |
| | | loadSeg.setUpdateTime(now); |
| | | if (!segmentService.save(loadSeg)) { |
| | | log.error("Segment [{}] failed to save !!!", loadSeg.getTravelId() + " - " + loadSeg.getSerial()); |
| | | // log.error("Segment [{}] failed to save !!!", loadSeg.getTravelId() + " - " + loadSeg.getSerial()); |
| | | throw new CoolException("failed to save segment [" + loadSeg.getGroupId() + "-" + loadSeg.getSerial() + "] failed"); |
| | | } |
| | | |
| | | // place segment |
| | | TaskTypeType taskType = Objects.requireNonNull(TaskTypeType.get(task.getTaskTypeEl())); |
| | | TaskPosDto.PosType posType; |
| | | Long endCodeId; |
| | | Code endCode; |
| | | switch (taskType) { |
| | | case STA_TO_LOC: |
| | | posType = TaskPosDto.PosType.DEST_LOC; |
| | | Loc destLoc = locService.getById(task.getDestLoc()); |
| | | endCodeId = destLoc.getCode(); |
| | | endCode = codeService.getCacheById(destLoc.getCode()); |
| | | break; |
| | | case STA_TO_STA: |
| | | posType = TaskPosDto.PosType.DEST_STA; |
| | | Sta destSta = staService.getById(task.getDestSta()); |
| | | endCodeId = destSta.getCode(); |
| | | endCode = codeService.getCacheById(destSta.getCode()); |
| | | break; |
| | | default: |
| | | throw new BusinessException("[Agv:" + agvNo + "] allocate inbound only supports STA_TO_LOC/STA_TO_STA"); |
| | | } |
| | | |
| | | // calc placeSeg serial, through code position |
| | | List<Segment> destSegList = segmentService.list(new LambdaQueryWrapper<Segment>() |
| | | .eq(Segment::getAgvId, agvId) |
| | | .eq(Segment::getTravelId, currSeg.getTravelId()) |
| | | .ne(Segment::getState, SegmentStateType.FINISH.toString()) |
| | | .in(Segment::getPosType, |
| | | TaskPosDto.PosType.DEST_LOC.toString(), |
| | | TaskPosDto.PosType.DEST_STA.toString()) |
| | | .orderByAsc(Segment::getSerial) |
| | | ); |
| | | |
| | | // build destPosList and sort |
| | | List<TaskPosDto> destPosList = new ArrayList<>(); |
| | | for (Segment destSeg : destSegList) { |
| | | Code code = codeService.getCacheById(destSeg.getEndNode()); |
| | | if (code == null) continue; |
| | | |
| | | TaskPosDto dto = new TaskPosDto(destSeg.getTaskId(), new Double[]{code.getX(), code.getY()}, TaskPosDto.PosType.DEST_LOC); |
| | | dto.setCodeId(code.getId()); |
| | | dto.setSegId(destSeg.getId()); |
| | | destPosList.add(dto); |
| | | } |
| | | TaskPosDto newDto = new TaskPosDto(task.getId(), new Double[]{endCode.getX(), endCode.getY()}, TaskPosDto.PosType.DEST_LOC); |
| | | newDto.setCodeId(endCode.getId()); |
| | | destPosList.add(newDto); |
| | | |
| | | destPosList.sort((a, b) -> { |
| | | int c1 = Double.compare(a.getXy()[0], b.getXy()[0]); // X |
| | | if (c1 != 0) return c1; |
| | | int c2 = Double.compare(a.getXy()[1], b.getXy()[1]); // Y |
| | | if (c2 != 0) return c2; |
| | | // 同坐标时用 taskId 打散(避免排序不稳定) |
| | | return Long.compare(a.getTaskId(), b.getTaskId()); |
| | | }); |
| | | |
| | | // get placeSeg serial |
| | | int placeSegSerial; |
| | | // query placeSeg idx |
| | | int idx = -1; |
| | | for (int i = 0; i < destPosList.size(); i++) { |
| | | if (Objects.equals(destPosList.get(i).getCodeId(), newDto.getCodeId()) |
| | | && Objects.equals(destPosList.get(i).getTaskId(), newDto.getTaskId())) { |
| | | idx = i; |
| | | break; |
| | | } |
| | | } |
| | | if (idx < 0) { |
| | | throw new BusinessException("failed to locate new destination in sorted list"); |
| | | } |
| | | |
| | | // 后继点 |
| | | if (idx + 1 == destPosList.size()) { |
| | | placeSegSerial = destSegList.get(destSegList.size() - 1).getSerial() + 1; |
| | | } else { |
| | | TaskPosDto afterTaskPos = destPosList.get(idx + 1); |
| | | Segment afterSeg = destSegList.stream() |
| | | .filter(destSeg -> Objects.equals(destSeg.getId(), afterTaskPos.getSegId())) |
| | | .findFirst() |
| | | .orElse(null); |
| | | if (null == afterSeg) { |
| | | placeSegSerial = destSegList.get(destSegList.size() - 1).getSerial() + 1; |
| | | } else { |
| | | placeSegSerial = afterSeg.getSerial(); |
| | | } |
| | | } |
| | | // placeSegSerial = Math.max(placeSegSerial, currSeg.getSerial() + 1); |
| | | |
| | | // shift serial after |
| | | segmentService.update(new LambdaUpdateWrapper<Segment>() |
| | | .eq(Segment::getAgvId, agvId) |
| | | .eq(Segment::getTravelId, currSeg.getTravelId()) |
| | | .ge(Segment::getSerial, placeSegSerial) |
| | | .ne(Segment::getState, SegmentStateType.FINISH.toString()) |
| | | .setSql("serial = serial + 1") |
| | | .set(Segment::getUpdateTime, now) |
| | | ); |
| | | |
| | | // save place segment |
| | | Segment placeSeg = new Segment(); |
| | | placeSeg.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); |
| | | placeSeg.setTravelId(currSeg.getTravelId()); |
| | | placeSeg.setAgvId(agvId); |
| | | placeSeg.setTaskId(task.getId()); |
| | | placeSeg.setSerial(); |
| | | placeSeg.setEndNode(endCodeId); |
| | | placeSeg.setSerial(placeSegSerial); |
| | | placeSeg.setEndNode(endCode.getId()); |
| | | placeSeg.setPosType(posType.toString()); |
| | | placeSeg.setState(SegmentStateType.INIT.toString()); |
| | | placeSeg.setBackpack(backpackLev); |
| | | placeSeg.setCreateTime(now); |
| | | placeSeg.setUpdateTime(now); |
| | | if (!segmentService.save(placeSeg)) { |
| | | log.error("Segment [{}] failed to save !!!", placeSeg.getTravelId() + " - " + placeSeg.getSerial()); |
| | | // log.error("Segment [{}] failed to save !!!", placeSeg.getTravelId() + " - " + placeSeg.getSerial()); |
| | | throw new CoolException("failed to save segment [" + placeSeg.getGroupId() + "-" + placeSeg.getSerial() + "] failed"); |
| | | } |
| | | |
| | | // update task |