|  |  |  | 
|---|
|  |  |  | import com.core.common.DateUtils; | 
|---|
|  |  |  | import com.core.common.SpringUtils; | 
|---|
|  |  |  | import com.zy.asrs.entity.*; | 
|---|
|  |  |  | import com.zy.asrs.mapper.WrkMastMapper; | 
|---|
|  |  |  | import com.zy.asrs.service.*; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import com.zy.asrs.utils.Utils; | 
|---|
|  |  |  | import com.zy.common.model.NavigateNode; | 
|---|
|  |  |  | import com.zy.common.utils.*; | 
|---|
|  |  |  | import com.zy.core.News; | 
|---|
|  |  |  | 
|---|
|  |  |  | import com.zy.core.cache.OutputQueue; | 
|---|
|  |  |  | import com.zy.core.cache.SlaveConnection; | 
|---|
|  |  |  | import com.zy.core.enums.*; | 
|---|
|  |  |  | import com.zy.core.model.LiftSlave; | 
|---|
|  |  |  | import com.zy.core.model.ShuttleSlave; | 
|---|
|  |  |  | import com.zy.core.model.Task; | 
|---|
|  |  |  | import com.zy.core.model.command.NyShuttleHttpCommand; | 
|---|
|  |  |  | import com.zy.core.model.command.ShuttleAssignCommand; | 
|---|
|  |  |  | import com.zy.core.model.command.ShuttleCommand; | 
|---|
|  |  |  | import com.zy.core.model.command.ShuttleRedisCommand; | 
|---|
|  |  |  | import com.zy.core.model.command.*; | 
|---|
|  |  |  | import com.zy.core.model.protocol.LiftProtocol; | 
|---|
|  |  |  | import com.zy.core.model.protocol.NyShuttleProtocol; | 
|---|
|  |  |  | import com.zy.core.properties.SlaveProperties; | 
|---|
|  |  |  | import lombok.Data; | 
|---|
|  |  |  | import lombok.extern.slf4j.Slf4j; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | if (commands.size() == 0) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(shuttleProtocol.getCurrentLocNo())); | 
|---|
|  |  |  | //取出命令 | 
|---|
|  |  |  | NyShuttleHttpCommand command = commands.get(commandStep); | 
|---|
|  |  |  | NyShuttleHttpCommand command = commands.get(commandStep);//当前命令 | 
|---|
|  |  |  | if (commandStep != 0) { | 
|---|
|  |  |  | //判断上一条指令是否完成 | 
|---|
|  |  |  | NyShuttleHttpCommand lastCommand = commands.get(commandStep - 1); | 
|---|
|  |  |  | String requestType = lastCommand.getRequest().getBody().get("requestType").toString(); | 
|---|
|  |  |  | if (requestType.equals("move") || requestType.equals("intoLift") || requestType.equals("outLift")) { | 
|---|
|  |  |  | //移动命令、出入提升机命令 | 
|---|
|  |  |  | NyShuttleProtocol.NyShuttlePointClass target = JSON.parseObject(lastCommand.getRequest().getBody().get("target").toString(), NyShuttleProtocol.NyShuttlePointClass.class); | 
|---|
|  |  |  | if (shuttleProtocol.getPoint().equals(target)) { | 
|---|
|  |  |  | //上一条指令的目标位置和当前小车位置相同,则认定上一条任务完成 | 
|---|
|  |  |  | lastCommand.setComplete(true); | 
|---|
|  |  |  | //解锁锁定路径,上一条路径和当前路径 | 
|---|
|  |  |  | List<NavigateNode> nodes = lastCommand.getNodes(); | 
|---|
|  |  |  | nodes.addAll(command.getNodes()); | 
|---|
|  |  |  | navigateMapData.writeNavigateNodeToRedisMap(nodes, false);//解锁路径 | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | lastCommand.setComplete(true);//其他命令默认认为完成 | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //任务数据保存到redis | 
|---|
|  |  |  | redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand)); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!lastCommand.getComplete()) { | 
|---|
|  |  |  | //上一条任务未完成,禁止下发命令 | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | List<NavigateNode> nextNodes = null;//下一步命令行走路径 | 
|---|
|  |  |  | if (commandStep + 1 < commands.size()) { | 
|---|
|  |  |  | NyShuttleHttpCommand nextCommand = commands.get(commandStep + 1);//下一步命令 | 
|---|
|  |  |  | nextNodes = nextCommand.getNodes();//下一步命令行走路径 | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (shuttleProtocol.getFree() == ShuttleStatusType.BUSY.id) { | 
|---|
|  |  |  | return false;//小车状态忙,禁止执行命令 | 
|---|
|  |  |  | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //检查路径是否可行走(检查路径锁定状态,检测路径是否有其他小车) | 
|---|
|  |  |  | //检测穿梭车是否在提升机内 | 
|---|
|  |  |  | if (!checkShuttleInTheLift(wrkNo)) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //检查路径是否可行走(检查路径锁定状态,检测路径是否有其他小车) | 
|---|
|  |  |  | //检测当前行走路径,和下一步路径 | 
|---|
|  |  |  | boolean checkPathIsAvailable = NavigateUtils.checkPathIsAvailable(command.getNodes(), shuttleProtocol.getShuttleNo().intValue(), Utils.getLev(shuttleProtocol.getCurrentLocNo())); | 
|---|
|  |  |  | boolean checkPathIsAvailable2 = NavigateUtils.checkPathIsAvailable(nextNodes, shuttleProtocol.getShuttleNo().intValue(), Utils.getLev(shuttleProtocol.getCurrentLocNo())); | 
|---|
|  |  |  | if (!checkPathIsAvailable && !checkPathIsAvailable2) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //锁定路径,锁定当前路径和下一步路径 | 
|---|
|  |  |  | List<NavigateNode> nodes = command.getNodes(); | 
|---|
|  |  |  | nodes.addAll(nextNodes); | 
|---|
|  |  |  | navigateMapData.writeNavigateNodeToRedisMap(nodes, true);//所使用的路径进行锁定禁用 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //可执行命令 | 
|---|
|  |  |  | if (!write(command)) { | 
|---|
|  |  |  | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | //已执行完成 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //            if (redisCommand.getLiftSecurityMk()) { | 
|---|
|  |  |  | //                //曾锁定过提升机,需要进行解锁 | 
|---|
|  |  |  | //                if (liftProtocol != null) { | 
|---|
|  |  |  | //                    liftProtocol.setSecurityMk(false); | 
|---|
|  |  |  | //                } | 
|---|
|  |  |  | //            } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //            String locNo = shuttleProtocol.getLocNo() == null ? shuttleProtocol.getSourceLocNo() : shuttleProtocol.getLocNo(); | 
|---|
|  |  |  | //            if (locNo != null) { | 
|---|
|  |  |  | //                //解除锁定的库位路径 | 
|---|
|  |  |  | //                NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(locNo)); | 
|---|
|  |  |  | //                navigateMapData.writeNavigateNodeToRedisMap(redisCommand.getAssignCommand().getNodes(), false); | 
|---|
|  |  |  | //            } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //删除redis | 
|---|
|  |  |  | redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //拿到提升机线程 | 
|---|
|  |  |  | LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1); | 
|---|
|  |  |  | if (liftThread == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | LiftProtocol liftProtocol = liftThread.getLiftProtocol(); | 
|---|
|  |  |  | if (liftProtocol == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | WrkMastMapper wrkMastMapper = SpringUtils.getBean(WrkMastMapper.class); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class); | 
|---|
|  |  |  | //当前步序 | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //检测是否存在提升机口的指令 | 
|---|
|  |  |  | List<NyShuttleHttpCommand> commands = redisCommand.getAssignCommand().getCommands(); | 
|---|
|  |  |  | if (commands.size() == 0) { | 
|---|
|  |  |  | if (commands.isEmpty()) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | NyShuttleHttpCommand command = commands.get(commandStep);//当前命令 | 
|---|
|  |  |  | if (!command.getMsgType().equals("intoLift")) { | 
|---|
|  |  |  | return true;//不是入提升机命令,直接放行 | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取起点(输送站点) | 
|---|
|  |  |  | NyShuttleProtocol.NyShuttlePointClass start = JSON.parseObject(command.getRequest().getBody().get("start").toString(), NyShuttleProtocol.NyShuttlePointClass.class); | 
|---|
|  |  |  | //将牛眼坐标转换成WCS库位号 | 
|---|
|  |  |  | String startLocNo = NavigatePositionConvert.nyXyzToLocNo(start.getX(), start.getY(), start.getZ()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); | 
|---|
|  |  |  | BasDevp basDevp = basDevpService.queryByLocNo(startLocNo); | 
|---|
|  |  |  | if (basDevp == null) { | 
|---|
|  |  |  | return false;//查不到站点,禁止下发 | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //拿到提升机线程 | 
|---|
|  |  |  | LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, basDevp.getLiftNo()); | 
|---|
|  |  |  | if (liftThread == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | LiftProtocol liftProtocol = liftThread.getLiftProtocol(); | 
|---|
|  |  |  | if (liftProtocol == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!liftProtocol.isIdle()) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!commands.get(commandStep).getMsgType().equals("move")) { | 
|---|
|  |  |  | return true;//不是行走命令,直接放行 | 
|---|
|  |  |  | if (liftProtocol.getLev().intValue() == Utils.getLev(shuttleProtocol.getCurrentLocNo())) { | 
|---|
|  |  |  | return true;//提升机达到小车楼层,放行 | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //搜索是否有其他任务占用了提升机,如果占用提升机的任务和当前任务相同,则运行执行 | 
|---|
|  |  |  | WrkMast wrkMast1 = wrkMastMapper.selectLiftWrkMast(liftProtocol.getLiftNo().intValue()); | 
|---|
|  |  |  | if (wrkMast1 != null && wrkMast1.getWrkNo() != wrkNo.intValue()) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //提升机未到达小车楼层,呼叫提升机 | 
|---|
|  |  |  | //获取提升机命令 | 
|---|
|  |  |  | NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_CAR.id, null, basDevp.getDevNo(), wrkNo.intValue()); | 
|---|
|  |  |  | ArrayList<NyLiftCommand> liftCommands = new ArrayList<>(); | 
|---|
|  |  |  | liftCommands.add(liftCommand); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //提交到线程去工作 | 
|---|
|  |  |  | LiftAssignCommand assignCommand = new LiftAssignCommand(); | 
|---|
|  |  |  | assignCommand.setCommands(liftCommands); | 
|---|
|  |  |  | assignCommand.setLiftNo(liftProtocol.getLiftNo()); | 
|---|
|  |  |  | assignCommand.setTaskNo(wrkNo); | 
|---|
|  |  |  | assignCommand.setTaskMode(NyLiftTaskModelType.MOVE_CAR.id.shortValue()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //下发任务 | 
|---|
|  |  |  | MessageQueue.offer(SlaveType.Lift, liftProtocol.getLiftNo().intValue(), new Task(3, assignCommand)); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return false;//默认不放行 | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 检测穿梭车是否在提升机内 | 
|---|
|  |  |  | * 如穿梭车在提升机内,必须等待提升机空闲才可执行穿梭车命令 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private boolean checkShuttleInTheLift(Short wrkNo) { | 
|---|
|  |  |  | //读取redis数据 | 
|---|
|  |  |  | if (wrkNo == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Object o = redisUtil.get("shuttle_wrk_no_" + wrkNo); | 
|---|
|  |  |  | if (o == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | SlaveProperties slaveProperties = SpringUtils.getBean(SlaveProperties.class); | 
|---|
|  |  |  | BasLiftService liftService = SpringUtils.getBean(BasLiftService.class); | 
|---|
|  |  |  | for (LiftSlave liftSlave : slaveProperties.getLift()) { | 
|---|
|  |  |  | BasLift basLift = liftService.selectById(liftSlave.getId()); | 
|---|
|  |  |  | if (basLift == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (basLift.getPoint().equals(shuttleProtocol.getPoint())) { | 
|---|
|  |  |  | //小车在提升机内 | 
|---|
|  |  |  | //判断提升机是否空闲 | 
|---|
|  |  |  | LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftSlave.getId()); | 
|---|
|  |  |  | if (liftThread == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | LiftProtocol liftProtocol = liftThread.getLiftProtocol(); | 
|---|
|  |  |  | if (liftProtocol == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (liftProtocol.isIdle()) { | 
|---|
|  |  |  | //提升机处于空闲,放行 | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false;//默认不放行 | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|