| | |
| | | public class ZyStationV5Thread implements Runnable, com.zy.core.thread.StationThread { |
| | | |
| | | private static final int RUN_BLOCK_REROUTE_STATE_EXPIRE_SECONDS = 60 * 60 * 24; |
| | | private static final int SHORT_PATH_REPEAT_AVOID_THRESHOLD = 3; |
| | | |
| | | private List<StationProtocol> statusList = new ArrayList<>(); |
| | | private DeviceConfig deviceConfig; |
| | |
| | | } |
| | | |
| | | Set<String> issuedRouteSignatureSet = rerouteState.getIssuedRouteSignatureSet(); |
| | | List<RerouteCandidateCommand> candidateCommandList = new ArrayList<>(); |
| | | for (List<NavigateNode> candidatePath : candidatePathList) { |
| | | StationCommand rerouteCommand = buildMoveCommand(taskNo, stationId, targetStationId, palletSize, candidatePath); |
| | | if (rerouteCommand == null || rerouteCommand.getNavigatePath() == null || rerouteCommand.getNavigatePath().isEmpty()) { |
| | | continue; |
| | | } |
| | | String routeSignature = buildPathSignature(rerouteCommand.getNavigatePath()); |
| | | if (Cools.isEmpty(routeSignature) || issuedRouteSignatureSet.contains(routeSignature)) { |
| | | if (Cools.isEmpty(routeSignature)) { |
| | | continue; |
| | | } |
| | | RerouteCandidateCommand candidateCommand = new RerouteCandidateCommand(); |
| | | candidateCommand.setCommand(rerouteCommand); |
| | | candidateCommand.setRouteSignature(routeSignature); |
| | | candidateCommand.setPathLength(rerouteCommand.getNavigatePath().size()); |
| | | candidateCommand.setIssuedCount(rerouteState.getRouteIssueCountMap().getOrDefault(routeSignature, 0)); |
| | | candidateCommandList.add(candidateCommand); |
| | | } |
| | | if (candidateCommandList.isEmpty()) { |
| | | return null; |
| | | } |
| | | |
| | | List<RerouteCandidateCommand> orderedCandidateCommandList = reorderCandidateCommandsForLoopRelease(candidateCommandList); |
| | | for (RerouteCandidateCommand candidateCommand : orderedCandidateCommandList) { |
| | | if (candidateCommand == null || candidateCommand.getCommand() == null) { |
| | | continue; |
| | | } |
| | | if (issuedRouteSignatureSet.contains(candidateCommand.getRouteSignature())) { |
| | | continue; |
| | | } |
| | | |
| | | issuedRouteSignatureSet.add(routeSignature); |
| | | StationCommand rerouteCommand = candidateCommand.getCommand(); |
| | | issuedRouteSignatureSet.add(candidateCommand.getRouteSignature()); |
| | | rerouteState.getIssuedRoutePathList().add(new ArrayList<>(rerouteCommand.getNavigatePath())); |
| | | rerouteState.setLastSelectedRoute(new ArrayList<>(rerouteCommand.getNavigatePath())); |
| | | rerouteState.getRouteIssueCountMap().put( |
| | | candidateCommand.getRouteSignature(), |
| | | rerouteState.getRouteIssueCountMap().getOrDefault(candidateCommand.getRouteSignature(), 0) + 1 |
| | | ); |
| | | return rerouteCommand; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private List<RerouteCandidateCommand> reorderCandidateCommandsForLoopRelease(List<RerouteCandidateCommand> candidateCommandList) { |
| | | if (candidateCommandList == null || candidateCommandList.isEmpty()) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | int shortestPathLength = Integer.MAX_VALUE; |
| | | boolean shortestPathOverused = false; |
| | | boolean hasLongerCandidate = false; |
| | | for (RerouteCandidateCommand candidateCommand : candidateCommandList) { |
| | | if (candidateCommand == null || candidateCommand.getPathLength() == null || candidateCommand.getPathLength() <= 0) { |
| | | continue; |
| | | } |
| | | shortestPathLength = Math.min(shortestPathLength, candidateCommand.getPathLength()); |
| | | } |
| | | if (shortestPathLength == Integer.MAX_VALUE) { |
| | | return candidateCommandList; |
| | | } |
| | | |
| | | for (RerouteCandidateCommand candidateCommand : candidateCommandList) { |
| | | if (candidateCommand == null || candidateCommand.getPathLength() == null || candidateCommand.getPathLength() <= 0) { |
| | | continue; |
| | | } |
| | | if (candidateCommand.getPathLength() > shortestPathLength) { |
| | | hasLongerCandidate = true; |
| | | } |
| | | if (candidateCommand.getPathLength() == shortestPathLength |
| | | && candidateCommand.getIssuedCount() != null |
| | | && candidateCommand.getIssuedCount() >= SHORT_PATH_REPEAT_AVOID_THRESHOLD) { |
| | | shortestPathOverused = true; |
| | | } |
| | | } |
| | | if (!shortestPathOverused || !hasLongerCandidate) { |
| | | return candidateCommandList; |
| | | } |
| | | |
| | | List<RerouteCandidateCommand> reorderedList = new ArrayList<>(); |
| | | for (RerouteCandidateCommand candidateCommand : candidateCommandList) { |
| | | if (candidateCommand != null |
| | | && candidateCommand.getPathLength() != null |
| | | && candidateCommand.getPathLength() > shortestPathLength) { |
| | | reorderedList.add(candidateCommand); |
| | | } |
| | | } |
| | | for (RerouteCandidateCommand candidateCommand : candidateCommandList) { |
| | | if (candidateCommand == null || candidateCommand.getPathLength() == null) { |
| | | continue; |
| | | } |
| | | if (candidateCommand.getPathLength() <= shortestPathLength) { |
| | | reorderedList.add(candidateCommand); |
| | | } |
| | | } |
| | | return reorderedList; |
| | | } |
| | | |
| | | private RunBlockRerouteState loadRunBlockRerouteState(Integer taskNo, Integer blockStationId) { |
| | |
| | | private List<List<Integer>> issuedRoutePathList = new ArrayList<>(); |
| | | private List<Integer> lastSelectedRoute = new ArrayList<>(); |
| | | private Set<String> issuedRouteSignatureSet = new LinkedHashSet<>(); |
| | | private Map<String, Integer> routeIssueCountMap = new HashMap<>(); |
| | | |
| | | private RunBlockRerouteState normalize() { |
| | | if (planCount == null || planCount < 0) { |
| | |
| | | if (issuedRouteSignatureSet == null) { |
| | | issuedRouteSignatureSet = new LinkedHashSet<>(); |
| | | } |
| | | if (routeIssueCountMap == null) { |
| | | routeIssueCountMap = new HashMap<>(); |
| | | } |
| | | for (List<Integer> routePath : issuedRoutePathList) { |
| | | if (routePath == null || routePath.isEmpty()) { |
| | | continue; |
| | | } |
| | | StringBuilder builder = new StringBuilder(buildPathSignatureText(routePath)); |
| | | if (builder.length() > 0) { |
| | | issuedRouteSignatureSet.add(builder.toString()); |
| | | String pathSignature = buildPathSignatureText(routePath); |
| | | if (!Cools.isEmpty(pathSignature)) { |
| | | issuedRouteSignatureSet.add(pathSignature); |
| | | routeIssueCountMap.putIfAbsent(pathSignature, 1); |
| | | } |
| | | } |
| | | return this; |
| | |
| | | return builder.toString(); |
| | | } |
| | | } |
| | | |
| | | @Data |
| | | private static class RerouteCandidateCommand { |
| | | private StationCommand command; |
| | | private String routeSignature; |
| | | private Integer pathLength; |
| | | private Integer issuedCount; |
| | | } |
| | | } |