| | |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.core.common.SpringUtils; |
| | | import com.core.exception.CoolException; |
| | | import com.zy.asrs.entity.BasShuttle; |
| | | import com.zy.asrs.entity.DeviceConfig; |
| | | import com.zy.asrs.service.BasShuttleService; |
| | | import com.zy.asrs.service.DeviceConfigService; |
| | | import com.zy.asrs.utils.Utils; |
| | | import com.zy.common.model.MapNode; |
| | |
| | | import com.zy.core.cache.SlaveConnection; |
| | | import com.zy.core.dispatcher.ShuttleDispatchUtils; |
| | | import com.zy.core.enums.MapNodeType; |
| | | import com.zy.core.enums.RedisKeyType; |
| | | import com.zy.core.enums.ShuttleRunDirection; |
| | | import com.zy.core.enums.SlaveType; |
| | | import com.zy.core.model.command.ShuttleAssignCommand; |
| | |
| | | public class ShuttleOperaUtils { |
| | | |
| | | @Autowired |
| | | private BasShuttleService basShuttleService; |
| | | @Autowired |
| | | private NavigateUtils navigateUtils; |
| | | @Autowired |
| | | private NavigateMapUtils navigateMapUtils; |
| | | @Autowired |
| | | private NavigateMapData navigateMapData; |
| | | @Autowired |
| | |
| | | private ShuttleDispatchUtils shuttleDispatchUtils; |
| | | @Autowired |
| | | private DeviceConfigService deviceConfigService; |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | public synchronized List<ShuttleCommand> getStartToTargetCommands(String startLocNo, String endLocNo, List<NavigationMapType> mapTypes, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) { |
| | | return getStartToTargetCommands(startLocNo, endLocNo, mapTypes, null, assignCommand, shuttleThread, "move"); |
| | |
| | | } |
| | | Integer shuttleNo = shuttleProtocol.getShuttleNo(); |
| | | //获取小车移动速度 |
| | | Integer runSpeed = Optional.ofNullable(basShuttleService.selectOne(new EntityWrapper<BasShuttle>().eq("shuttle_no", shuttleNo)).getRunSpeed()).orElse(1000); |
| | | Integer runSpeed = 1000; |
| | | Object speedObj = redisUtil.get(RedisKeyType.SHUTTLE_SPEED_MAP.key); |
| | | if (speedObj != null) { |
| | | HashMap<Integer, Integer> shuttleSpeedMap = (HashMap<Integer, Integer>) speedObj; |
| | | Integer speed = shuttleSpeedMap.get(shuttleNo); |
| | | if (speed != null) { |
| | | runSpeed = speed; |
| | | } |
| | | } |
| | | |
| | | long calcStartTime = System.currentTimeMillis(); |
| | | List<NavigateNode> nodeList = navigateUtils.calc(startLocNo, endLocNo, mapTypes, Utils.getShuttlePoints(shuttleNo, Utils.getLev(startLocNo)), whites); |
| | | if (nodeList == null) { |
| | | News.error("{} dash {} can't find navigate path!", startLocNo, endLocNo); |
| | | shuttleThread.offerSystemMsg("{} dash {} can't find navigate path!", startLocNo, endLocNo); |
| | | return null; |
| | | } |
| | | News.info("[RCS Debug] Calc path time:{}", (System.currentTimeMillis() - calcStartTime)); |
| | | |
| | | List<NavigateNode> allNode = new ArrayList<>(); |
| | | List<NavigateNode> lockNode = new ArrayList<>(); |
| | |
| | | //获取分段路径 |
| | | List<List<NavigateNode>> data = navigateUtils.getSectionPath(nodeList); |
| | | long endTime = System.currentTimeMillis(); |
| | | News.info("getSection path time:{}", (endTime - startTime)); |
| | | News.info("[RCS Debug] getSection path time:{}", (endTime - startTime)); |
| | | |
| | | long startGetSectionCommandTime = System.currentTimeMillis(); |
| | | //将每一段路径分成command指令 |
| | | for (int i = 0; i < data.size(); i++) { |
| | | long startGetStartAndEndPathTime = System.currentTimeMillis(); |
| | | List<NavigateNode> nodes = data.get(i); |
| | | |
| | | //开始路径 |
| | | NavigateNode startPath = nodes.get(0); |
| | | |
| | | //目标路径 |
| | | NavigateNode endPath = nodes.get(nodes.size() - 1); |
| | | News.info("[RCS Debug] getStartAndEndPath idx:{} time:{}", i, (System.currentTimeMillis() - startGetStartAndEndPathTime)); |
| | | |
| | | long startAllDistanceTime = System.currentTimeMillis(); |
| | | Integer allDistance = navigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 |
| | | News.info("[RCS Debug] getAllDistance idx:{} time:{}", i, (System.currentTimeMillis() - startAllDistanceTime)); |
| | | |
| | | long startGetPosition = System.currentTimeMillis(); |
| | | //通过xy坐标小车二维码 |
| | | String startCodeNum = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ()); |
| | | //通过xy坐标小车二维码 |
| | | String distCodeNum = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ()); |
| | | News.info("[RCS Debug] xyToPosition idx:{} time:{}", i, (System.currentTimeMillis() - startGetPosition)); |
| | | |
| | | long startGetMoveCommandTime = System.currentTimeMillis(); |
| | | //获取移动命令 |
| | | ShuttleCommand command = shuttleThread.getMoveCommand(assignCommand.getDeviceTaskNo(), startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id.intValue(), runSpeed, nodes); |
| | | News.info("[RCS Debug] getMoveCommand idx:{} time:{}", i, (System.currentTimeMillis() - startGetMoveCommandTime)); |
| | | |
| | | if (i + 1 == data.size()) { |
| | | long startGetInOutLiftTime = System.currentTimeMillis(); |
| | | if (moveType.equals("inLift")) { |
| | | command = shuttleThread.getMoveLiftCommand(assignCommand.getDeviceTaskNo(), startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id.intValue(), runSpeed, nodes, true); |
| | | }else if (moveType.equals("outLift")) { |
| | | command = shuttleThread.getMoveLiftCommand(assignCommand.getDeviceTaskNo(), startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id.intValue(), runSpeed, nodes, false); |
| | | } |
| | | News.info("[RCS Debug] getInOutLiftTime idx:{} time:{}", i, (System.currentTimeMillis() - startGetInOutLiftTime)); |
| | | } |
| | | |
| | | command.setNodes(nodes);//将行走节点添加到每一步命令中 |
| | | commands.add(command); |
| | | } |
| | | News.info("[RCS Debug] getSectionCommand path time:{}", (System.currentTimeMillis() - startGetSectionCommandTime)); |
| | | |
| | | assignCommand.setNodes(allNode);//当前任务所占用的节点list |
| | | assignCommand.setMapTypes(mapTypes); |
| | | |
| | | //小车移动连续下发指令 |
| | | boolean shuttleMoveCommandsContinuously = false; |
| | | Config shuttleMoveCommandsContinuouslyConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "shuttleMoveCommandsContinuously")); |
| | | if (shuttleMoveCommandsContinuouslyConfig != null) { |
| | | if (shuttleMoveCommandsContinuouslyConfig.getValue().equals("Y")) { |
| | | Object object = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key); |
| | | if (object != null) { |
| | | HashMap<String, String> systemConfigMap = (HashMap<String, String>) object; |
| | | String shuttleMoveCommandsContinuouslyConfig = systemConfigMap.get("shuttleMoveCommandsContinuously"); |
| | | if (shuttleMoveCommandsContinuouslyConfig != null && shuttleMoveCommandsContinuouslyConfig.equals("Y")) { |
| | | shuttleMoveCommandsContinuously = true; |
| | | } |
| | | } |
| | | assignCommand.setShuttleMoveCommandsContinuously(shuttleMoveCommandsContinuously); |
| | | |
| | | News.info("{}任务,{}小车,{} - {} 路径命令包计算成功,耗时:{}ms", assignCommand.getTaskNo(), shuttleProtocol.getShuttleNo(), startLocNo, endLocNo, System.currentTimeMillis() - startTime); |
| | | return commands; |
| | | } |
| | | |
| | |
| | | return commands; |
| | | } |
| | | |
| | | //检测障碍物车 |
| | | public synchronized boolean checkObstacle(String locNo, List<Integer> whiteShuttles, List<NavigateNode> whiteNodes) { |
| | | /** |
| | | * 检测障碍物车 |
| | | * @return 0:无障碍 1:有障碍调度成功 2:有障碍调度失败 |
| | | */ |
| | | public synchronized int checkObstacle(String locNo, List<Integer> whiteShuttles, List<NavigateNode> whiteNodes) { |
| | | int innerCircle = 0; |
| | | int outerCircle = 3; |
| | | Config avoidInnerCircleConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "avoidInnerCircle")); |
| | |
| | | List<NavigateNode> innerNodes = getInnerNodes(locNo, innerCircle, whiteShuttlePointList); |
| | | List<Integer> nodesCar = findNodesCar(innerNodes); |
| | | if (nodesCar.isEmpty()) { |
| | | return false;//内圈中无车 |
| | | return 0;//内圈中无车 |
| | | } |
| | | |
| | | //获取外圈节点 |
| | |
| | | if (targetLocNo == null) { |
| | | continue; |
| | | } |
| | | shuttleDispatchUtils.dispatchShuttle(null, targetLocNo, shuttleNo); |
| | | boolean dispatched = shuttleDispatchUtils.dispatchShuttle(null, targetLocNo, shuttleNo); |
| | | return dispatched ? 1 : 2; |
| | | } |
| | | |
| | | return true;//内圈中有车 |
| | | return 2;//内圈中有车 |
| | | } |
| | | |
| | | private HashMap<String, Integer> findCarMap() { |