|  |  |  | 
|---|
|  |  |  | import com.zy.acs.common.enums.AgvCompleteType; | 
|---|
|  |  |  | import com.zy.acs.common.enums.AgvDirectionType; | 
|---|
|  |  |  | import com.zy.acs.common.enums.AgvSpeedType; | 
|---|
|  |  |  | import com.zy.acs.common.utils.GsonUtils; | 
|---|
|  |  |  | import com.zy.acs.common.utils.Utils; | 
|---|
|  |  |  | import com.zy.acs.framework.common.Cools; | 
|---|
|  |  |  | import com.zy.acs.framework.common.SnowflakeIdWorker; | 
|---|
|  |  |  | 
|---|
|  |  |  | import com.zy.acs.manager.common.domain.TaskDto; | 
|---|
|  |  |  | import com.zy.acs.manager.common.domain.param.HandlerPublishParam; | 
|---|
|  |  |  | import com.zy.acs.manager.common.exception.BusinessException; | 
|---|
|  |  |  | import com.zy.acs.manager.common.utils.CommonUtil; | 
|---|
|  |  |  | import com.zy.acs.manager.core.domain.AgvBackpackDto; | 
|---|
|  |  |  | import com.zy.acs.manager.core.domain.Lane; | 
|---|
|  |  |  | import com.zy.acs.manager.core.domain.TaskPosDto; | 
|---|
|  |  |  | 
|---|
|  |  |  | for (Task task : taskList) { | 
|---|
|  |  |  | Agv agv = allocateService.execute(task); | 
|---|
|  |  |  | if (null == agv) { | 
|---|
|  |  |  | log.warn("Task[{}] has an issue, because it failed to checkout agv which is idle...", task.getSeqNum()); | 
|---|
|  |  |  | //                    log.warn("Task[{}] has an issue, because it failed to checkout agv which is idle...", task.getSeqNum()); | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | task.setAgvId(agv.getId()); | 
|---|
|  |  |  | 
|---|
|  |  |  | // valid ----------------------------------------------- | 
|---|
|  |  |  | Agv agv = agvService.getById(agvId); | 
|---|
|  |  |  | if (!agvService.judgeEnable(agv.getId(), true)) { | 
|---|
|  |  |  | throw new CoolException("AGV[" + agv.getUuid() + "]当前不可用..."); | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | //                throw new CoolException("AGV[" + agv.getUuid() + "]当前不可用..."); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!Cools.isEmpty(taskService.selectInSts(agvId, TaskStsType.ASSIGN, TaskStsType.PROGRESS))) { | 
|---|
|  |  |  | throw new CoolException("AGV[" + agv.getUuid() + "]分配任务失败,已存在执行任务..."); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.WAITING.toString())) | 
|---|
|  |  |  | || !Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.RUNNING.toString()))) { | 
|---|
|  |  |  | throw new CoolException("AGV[" + agv.getUuid() + "] failed to assign,because already has the segment in running..."); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // execute ---------------------------------------------------- | 
|---|
|  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 1.Map<String, List<TaskPosDto>> groups | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * key: 1000 + ORI_LOC | 
|---|
|  |  |  | * key: 1000 + ORIGIN | 
|---|
|  |  |  | * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * key: 3000 + ORI_LOC | 
|---|
|  |  |  | * key: 3000 + ORIGIN | 
|---|
|  |  |  | * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * key: 2000 + ORI_LOC | 
|---|
|  |  |  | * key: 2000 + ORIGIN | 
|---|
|  |  |  | * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * key: 1000 + DESTINATION | 
|---|
|  |  |  | * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * key: 2000 + DESTINATION | 
|---|
|  |  |  | * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * ...... | 
|---|
|  |  |  | 
|---|
|  |  |  | * 对所有巷道进行有序排序,先是针对List为一个单位,对他们进行FirstWeight排序,相当于表1的key的数值进行有序排序 | 
|---|
|  |  |  | *  List<TaskPosDto>: task list on the same lane | 
|---|
|  |  |  | *  ArrayList<List<TaskPosDto>>: all the task list by one agv | 
|---|
|  |  |  | * | 
|---|
|  |  |  | *  tip: ORI 和 DEST 永远不会存在同一个 List | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | ArrayList<List<TaskPosDto>> list = new ArrayList<>(groups.values()); | 
|---|
|  |  |  | list.sort((o1, o2) -> { | 
|---|
|  |  |  | 
|---|
|  |  |  | Code currCode = codeService.getById(agvDetail.getRecentCode()); | 
|---|
|  |  |  | Double[] currPosition = new Double[] {currCode.getX(), currCode.getY()}; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | List<TaskPosDto> theFirstOne = list.get(0); | 
|---|
|  |  |  | List<TaskPosDto> theLastOne = list.get(list.size() - 1); | 
|---|
|  |  |  | List<List<TaskPosDto>> pickGroups = new ArrayList<>(); | 
|---|
|  |  |  | List<List<TaskPosDto>> dropGroups = new ArrayList<>(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (list.size() == 1) { | 
|---|
|  |  |  | TaskPosDto head = theFirstOne.get(0); | 
|---|
|  |  |  | TaskPosDto tail = theFirstOne.get(theFirstOne.size() - 1); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int distanceByHead = CommonUtil.calcDistance(currPosition, head.getXy()); | 
|---|
|  |  |  | int distanceByTail = CommonUtil.calcDistance(currPosition, tail.getXy()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (distanceByTail < distanceByHead) { | 
|---|
|  |  |  | Collections.reverse(theFirstOne); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | TaskPosDto headOfFirst = theFirstOne.get(0); | 
|---|
|  |  |  | TaskPosDto tailOfFirst = theFirstOne.get(theFirstOne.size() - 1); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | TaskPosDto headOfLast = theLastOne.get(0); | 
|---|
|  |  |  | TaskPosDto tailOfLast = theLastOne.get(theLastOne.size() - 1); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int distanceByHeadOfFirst = CommonUtil.calcDistance(currPosition, headOfFirst.getXy()); | 
|---|
|  |  |  | int distanceByTailOfFirst = CommonUtil.calcDistance(currPosition, tailOfFirst.getXy()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int distanceByHeadOfLast = CommonUtil.calcDistance(currPosition, headOfLast.getXy()); | 
|---|
|  |  |  | int distanceByTailOfLast = CommonUtil.calcDistance(currPosition, tailOfLast.getXy()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (Math.min(distanceByHeadOfLast, distanceByTailOfLast) < Math.min(distanceByHeadOfFirst, distanceByTailOfFirst)) { | 
|---|
|  |  |  | Collections.reverse(list); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (distanceByTailOfLast < distanceByHeadOfLast) { | 
|---|
|  |  |  | Collections.reverse(theLastOne); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | for (List<TaskPosDto> group : list) { | 
|---|
|  |  |  | // Assume 一个任务组中所有TaskPosDto的PosType.brief相同 | 
|---|
|  |  |  | TaskPosDto.PosType posType = group.get(0).getPosType(); | 
|---|
|  |  |  | if (posType == TaskPosDto.PosType.ORI_LOC || posType == TaskPosDto.PosType.ORI_STA) { | 
|---|
|  |  |  | pickGroups.add(group); | 
|---|
|  |  |  | } else if (posType == TaskPosDto.PosType.DEST_LOC || posType == TaskPosDto.PosType.DEST_STA) { | 
|---|
|  |  |  | dropGroups.add(group); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | if (distanceByTailOfFirst < distanceByHeadOfFirst) { | 
|---|
|  |  |  | Collections.reverse(theFirstOne); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // import tip: the list must only contain ORIGIN and DESTINATION | 
|---|
|  |  |  | log.error("the list must only contain ORIGIN and DESTINATION"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | currPosition = allocateService.pac(currPosition, pickGroups); | 
|---|
|  |  |  | currPosition = allocateService.pac(currPosition, dropGroups); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | List<List<TaskPosDto>> reorderedList = new ArrayList<>(); | 
|---|
|  |  |  | reorderedList.addAll(pickGroups); | 
|---|
|  |  |  | reorderedList.addAll(dropGroups); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | list.clear(); | 
|---|
|  |  |  | list.addAll(reorderedList); | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // generate travel | 
|---|
|  |  |  | Travel travel = new Travel(); | 
|---|
|  |  |  | 
|---|
|  |  |  | if (!Cools.isEmpty(taskService.selectInSts(agv.getId(), TaskStsType.ASSIGN, TaskStsType.PROGRESS))) { | 
|---|
|  |  |  | throw new CoolException("AGV[" + agv.getUuid() + "] failed to assign,because already has the task in running..."); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.WAITING.toString())) | 
|---|
|  |  |  | || !Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.RUNNING.toString()))) { | 
|---|
|  |  |  | throw new CoolException("AGV[" + agv.getUuid() + "] failed to assign,because already has the segment in running..."); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Date now = new Date(); | 
|---|
|  |  |  | Code endCode = null; | 
|---|
|  |  |  | 
|---|
|  |  |  | travel.setTravelId(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); | 
|---|
|  |  |  | travel.setAgvId(agv.getId()); | 
|---|
|  |  |  | //            travel.setTaskContent(JSON.toJSONString(list)); | 
|---|
|  |  |  | travel.setTaskIds(JSON.toJSONString(Collections.singletonList(task.getId()))); | 
|---|
|  |  |  | travel.setTaskIds(GsonUtils.toJson(Utils.singletonList(task.getId()))); | 
|---|
|  |  |  | travel.setState(TravelStateType.RUNNING.toString()); | 
|---|
|  |  |  | if (!travelService.save(travel)) { | 
|---|
|  |  |  | throw new BusinessException("travel failed to save"); | 
|---|
|  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | if (null != jam && i == 0) { | 
|---|
|  |  |  | jam.setAvoSeg(next.getId()); | 
|---|
|  |  |  | jam.setAvoCode(endCode.getId()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | default: | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //            if (taskType.equals(TaskTypeType.TO_STANDBY)) { | 
|---|
|  |  |  | //                redis.setObject(RedisConstant.AGV_TO_STANDBY_FLAG, agv.getUuid(), false); | 
|---|
|  |  |  | //            } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|