| | |
| | | package com.zy.acs.manager.core.service; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.acs.common.enums.AgvDirectionType; |
| | | import com.zy.acs.common.enums.ActuatorDirectionType; |
| | | import com.zy.acs.framework.common.Cools; |
| | | import com.zy.acs.framework.exception.CoolException; |
| | | import com.zy.acs.manager.core.constant.MapDataConstant; |
| | | import com.zy.acs.manager.core.domain.DirectionDto; |
| | | import com.zy.acs.manager.core.domain.LaneDto; |
| | | import com.zy.acs.manager.core.domain.SortCodeDto; |
| | | import com.zy.acs.manager.core.domain.UnlockPathTask; |
| | | import com.zy.acs.manager.core.domain.type.CodeDirectionType; |
| | | import com.zy.acs.manager.core.domain.VehicleFootprint; |
| | | import com.zy.acs.manager.core.service.astart.*; |
| | | import com.zy.acs.manager.core.service.astart.domain.AStarNavigateNode; |
| | | import com.zy.acs.manager.core.service.astart.domain.DynamicNode; |
| | |
| | | import com.zy.acs.manager.manager.entity.Segment; |
| | | import com.zy.acs.manager.manager.entity.Sta; |
| | | import com.zy.acs.manager.manager.enums.CodeSpinType; |
| | | import com.zy.acs.manager.manager.service.ActionService; |
| | | import com.zy.acs.manager.manager.service.CodeService; |
| | | import com.zy.acs.manager.system.service.ConfigService; |
| | | import com.zy.acs.manager.manager.service.LaneService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | |
| | | @Autowired |
| | | private AStarNavigateService aStarNavigateService; |
| | | @Autowired |
| | | private ConfigService configService; |
| | | private LaneService laneService; |
| | | @Autowired |
| | | private ActionService actionService; |
| | | private LaneBuilder laneBuilder; |
| | | @Autowired |
| | | private LinkedBlockingQueue<UnlockPathTask> unlockTaskQueue; |
| | | |
| | |
| | | return angle; |
| | | } |
| | | |
| | | // 坐标货架阈值 todo:luxiaotao |
| | | public AgvDirectionType calculateAgvWorkDirectionByShelf(Loc loc, Code code) { |
| | | // 坐标货架阈值 |
| | | public ActuatorDirectionType calculateAgvWorkDirectionByShelf(Loc loc, Code code) { |
| | | Integer compDirect = loc.getCompDirect(); |
| | | AgvDirectionType agvDirectionType = null; |
| | | if (compDirect == 0) { |
| | | agvDirectionType = AgvDirectionType.RIGHT; |
| | | } |
| | | if (compDirect == 1) { |
| | | agvDirectionType = AgvDirectionType.LEFT; |
| | | } |
| | | return agvDirectionType; |
| | | return ActuatorDirectionType.fromVal(compDirect); |
| | | } |
| | | |
| | | public Double getStaAngle(Sta sta, Double workDirection) { |
| | | if (null == sta) { |
| | | return null; |
| | | public Double getStaAngle(Sta sta) { |
| | | if (null == sta.getCode()) { |
| | | throw new CoolException(sta.getStaNo() + "号接驳站未设置地码!"); |
| | | } |
| | | if (Cools.isEmpty(sta.getAngle())) { |
| | | return workDirection; |
| | | Code code = codeService.getCacheById(sta.getCode()); |
| | | if (code.getCornerBool()) { |
| | | if (!Cools.isEmpty(sta.getAngle())) { |
| | | return Double.parseDouble(sta.getAngle()); |
| | | } else { |
| | | throw new CoolException(sta.getStaNo() + "号接驳站未设置车体作业角度!"); |
| | | } |
| | | } else { |
| | | LaneDto laneDto = laneBuilder.search(code.getData()); |
| | | Double laneDir = laneService.getLaneDirection(laneDto); |
| | | |
| | | if (!Cools.isEmpty(laneDir)) { |
| | | if (!Cools.isEmpty(sta.getAngle()) && !laneDir.equals(Double.parseDouble(sta.getAngle()))) { |
| | | throw new CoolException(sta.getStaNo() + "号接驳站车体作业角度与巷道进入角度不一致!"); |
| | | } |
| | | return laneDir; |
| | | } else { |
| | | if (!Cools.isEmpty(sta.getAngle())) { |
| | | return Double.parseDouble(sta.getAngle()); |
| | | } |
| | | throw new CoolException("未设置" + sta.getStaNo() + "号接驳站所处巷道的进入角度"); |
| | | } |
| | | } |
| | | return Double.parseDouble(sta.getAngle()); |
| | | } |
| | | |
| | | public Double calculateAgvWorkDirectionByStation(Double staWorkDirection, Double lastDirection) { |
| | |
| | | return includeList; |
| | | } |
| | | |
| | | public List<NavigateNode> getWaveScopeByCode(Integer lev, String code, VehicleFootprint footprint, double headingRad, double buffer) { |
| | | int[] centerIdx = mapDataDispatcher.getCodeMatrixIdx(lev, code); |
| | | if (centerIdx == null) { |
| | | throw new CoolException(code + " does not exist in codeMatrix"); |
| | | } |
| | | Double[][][] cdaMatrix = mapDataDispatcher.getCdaMatrix(lev); |
| | | Double centerX = cdaMatrix[centerIdx[0]][centerIdx[1]][0]; |
| | | Double centerY = cdaMatrix[centerIdx[0]][centerIdx[1]][1]; |
| | | if (centerX == null || centerY == null) { |
| | | throw new CoolException(code + " does not exist in cdaMatrix"); |
| | | } |
| | | |
| | | double searchRadius = footprint.maxExtent() + buffer; |
| | | |
| | | List<NavigateNode> candidates = this.getWaveScopeByCode(lev, code, searchRadius); |
| | | |
| | | List<NavigateNode> includeList = new ArrayList<>(); |
| | | for (NavigateNode node : candidates) { |
| | | Double px = cdaMatrix[node.getX()][node.getY()][0]; |
| | | Double py = cdaMatrix[node.getX()][node.getY()][1]; |
| | | |
| | | if (isInsideExpandedFootprint(px, py, centerX, centerY, footprint, headingRad, buffer)) { |
| | | includeList.add(node); |
| | | } |
| | | |
| | | } |
| | | return includeList; |
| | | } |
| | | |
| | | public void spreadWaveNode(NavigateNode originNode, NavigateNode currNode |
| | | , String[][] codeMatrix, Double[][][] cdaMatrix, Double radiusLenSquared |
| | | , List<NavigateNode> includeList, Set<NavigateNode> existNodes) { |
| | |
| | | this.spreadWaveNode(originNode, nextNode, codeMatrix, cdaMatrix, radiusLenSquared, includeList, existNodes); |
| | | } |
| | | |
| | | } |
| | | |
| | | private boolean isInsideExpandedFootprint(double px, double py, double centerX, double centerY |
| | | , VehicleFootprint footprint, double headingRad, double buffer) { |
| | | double dx = px - centerX; |
| | | double dy = py - centerY; |
| | | |
| | | double localX = dx * Math.cos(headingRad) + dy * Math.sin(headingRad); |
| | | double localY = -dx * Math.sin(headingRad) + dy * Math.cos(headingRad); |
| | | |
| | | double xMin = -footprint.getTail(); |
| | | double xMax = footprint.getHead(); |
| | | double yMin = -footprint.getHalfWidth(); |
| | | double yMax = footprint.getHalfWidth(); |
| | | |
| | | double excessX = 0D; |
| | | if (localX < xMin) { |
| | | excessX = xMin - localX; |
| | | } else if (localX > xMax) { |
| | | excessX = localX - xMax; |
| | | } |
| | | |
| | | double excessY = 0D; |
| | | if (localY < yMin) { |
| | | excessY = yMin - localY; |
| | | } else if (localY > yMax) { |
| | | excessY = localY - yMax; |
| | | } |
| | | |
| | | return excessX * excessX + excessY * excessY <= buffer * buffer; |
| | | } |
| | | |
| | | // v2 BFS ------------------------------------------------------------------------------ |
| | |
| | | public static void main(String[] args) { |
| | | CodeSpinType codeSpinType = calcSpinDirection(null, 260.0, 10.0); |
| | | List<DirectionDto> directionDtoList = DirectionDto.initCodeDirections(); |
| | | System.out.println(JSON.toJSONString(directionDtoList)); |
| | | System.out.println(codeSpinType.toString()); |
| | | } |
| | | |
| | |
| | | return CodeSpinType.NA; |
| | | } |
| | | List<Double> disableAngleList = new ArrayList<>(); |
| | | List<DirectionDto> directionDtoList = DirectionDto.initCodeDirections(); |
| | | if (code.getData().contains("57")) { |
| | | directionDtoList = DirectionDto.initCodeDirections0(); |
| | | List<DirectionDto> directionDtoList; |
| | | if (!Cools.isEmpty(code.getDirRule())) { |
| | | directionDtoList = JSON.parseArray(code.getDirRule(), DirectionDto.class); |
| | | } else { |
| | | directionDtoList = DirectionDto.initCodeDirections(); |
| | | } |
| | | for (DirectionDto dto : directionDtoList) { |
| | | if (null != dto.getEnabled() && !dto.getEnabled()) { |