| | |
| | | News.error("四向穿梭车写入命令为空"); |
| | | return false; |
| | | } |
| | | |
| | | BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); |
| | | if (shuttleService == null) { |
| | | News.error("系统错误"); |
| | |
| | | News.error("四向穿梭车不存在"); |
| | | return false; |
| | | } |
| | | |
| | | command.setShuttleNo(slave.getId().shortValue()); |
| | | short[] array = getCommandArr(command);//获取命令报文 |
| | | OperateResult result = modbusTcpNet.Write("0", array);; |
| | | if (result != null && result.IsSuccess) { |
| | | try { |
| | | Thread.sleep(3000);//命令下发后休眠1s |
| | | } catch (InterruptedException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | News.info("四向穿梭车命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command)); |
| | | OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command))); |
| | | return true; |
| | | } else { |
| | | OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】写入四向穿梭车plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); |
| | | News.error("写入四向穿梭车plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | //获取命令报文 |
| | | private short[] getCommandArr(ShuttleCommand command) { |
| | | // 开始任务 |
| | | short[] array = new short[17]; |
| | | //控制指令字 |
| | |
| | | array[7] = middleToDistDistances[1]; |
| | | } |
| | | |
| | | array[8] = basShuttle.getRunSpeed().shortValue();//四向穿梭车运行速度,从系统数据库读出 |
| | | if (command.getRunDirection() != null) { |
| | | //小车运行方向 |
| | | array[8] = command.getRunDirection(); |
| | |
| | | //小车雷达备用 |
| | | array[15] = command.getRadarTmp(); |
| | | } |
| | | |
| | | //指令结束位 |
| | | array[16] = command.getCommandEnd(); |
| | | |
| | | OperateResult result = modbusTcpNet.Write("0", array);; |
| | | if (result != null && result.IsSuccess) { |
| | | try { |
| | | Thread.sleep(3000);//命令下发后休眠1s |
| | | } catch (InterruptedException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | News.info("四向穿梭车命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command)); |
| | | OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command))); |
| | | return true; |
| | | } else { |
| | | OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】写入四向穿梭车plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); |
| | | News.error("写入四向穿梭车plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); |
| | | return false; |
| | | } |
| | | return array; |
| | | } |
| | | |
| | | /** |
| | | * 初始化四向穿梭车 |
| | | */ |
| | | private void initShuttle() { |
| | | this.connect(); |
| | | if (null == shuttleProtocol) { |
| | | shuttleProtocol = new ShuttleProtocol(); |
| | | } |
| | |
| | | Short liftArrival = liftProtocol.getPositionArrivalFeedback();//提升机位置反馈 |
| | | String liftSiteLocNo = Utils.liftArrivalToOutInStaLocNo(liftArrival); |
| | | LocMast locMast1 = locMastService.selectById(liftSiteLocNo); |
| | | ShuttleCommand moveCommand = getMoveCommand(liftProtocol.getBarcode(), Short.parseShort(locMast1.getQrCodeValue()), 1400, ShuttleRunDirection.BOTTOM.id, liftProtocol.getBarcode(), 1400, runSpeed); |
| | | ShuttleCommand moveCommand = getMoveCommand(liftProtocol.getBarcode(), Short.parseShort(locMast1.getQrCodeValue()), 1600, ShuttleRunDirection.BOTTOM.id, null, null, runSpeed); |
| | | commands.add(moveCommand); |
| | | |
| | | //起始位置修改为提升机口站点位置 |
| | |
| | | } |
| | | |
| | | //增加移动进提升机命令 |
| | | ShuttleCommand moveCommand = getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1400, ShuttleRunDirection.TOP.id, endStartCode, 1400, runSpeed); |
| | | ShuttleCommand moveCommand = getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, null, null, runSpeed); |
| | | commands.add(moveCommand); |
| | | break; |
| | | default: |
| | |
| | | return false; |
| | | } |
| | | |
| | | WrkMastService wrkMastService = SpringUtils.getBean(WrkMastService.class); |
| | | |
| | | Object o = redisUtil.get("shuttle_wrk_no_" + wrkNo); |
| | | if (o == null) { |
| | | return false; |
| | | } |
| | | ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class); |
| | | |
| | | if (shuttleProtocol.getBusyStatus().intValue() == ShuttleStatusType.BUSY.id) { |
| | | return false;//小车状态忙 |
| | | } |
| | | |
| | | if (!checkLiftStation(wrkNo)) {//检测是否有提升机站点,有则调度提升机 |
| | | return false; |
| | | } |
| | | |
| | | // List<ShuttleCommand> errorCommands = redisCommand.getErrorCommands(); |
| | | // if (errorCommands.size() > 0) { |
| | | // //优先执行该指令 |
| | | // ShuttleCommand errorCommand = errorCommands.get(0);//取出指令 |
| | | // |
| | | // if(errorCommand.getCommandWord() == 1){//正常行走命令,需要先执行完找库位命令后,再执行 |
| | | // LocMastService locMastService = SpringUtils.getBean(LocMastService.class); |
| | | // LocMast locMast = locMastService.queryByQrCode(shuttleProtocol.getCurrentCode().toString()); |
| | | // LocMast distLocMast = locMastService.queryByQrCode(errorCommand.getStartCodeNum().toString()); |
| | | // if (shuttleProtocol.getCurrentCode().equals(errorCommand.getStartCodeNum())) { |
| | | // //起点和终点属于同一库位,无需再执行移动操作 |
| | | // errorCommands.remove(0);//移除该命令 |
| | | // redisCommand.setErrorCommands(new ArrayList<ShuttleCommand>()); |
| | | // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WORKING); |
| | | // //当前步序 |
| | | // int commandStep = redisCommand.getCommandStep(); |
| | | // //步序回退 |
| | | // commandStep--; |
| | | // redisCommand.setCommandStep(commandStep); |
| | | // //任务数据保存到redis |
| | | // redisUtil.set("shuttle_wrk_no_" + wrkNo, JSON.toJSONString(redisCommand)); |
| | | // shuttleProtocol.setPakMk(true); |
| | | // return true; |
| | | // }else { |
| | | // List<NavigateNode> result = NavigateUtils.calc(locMast.getLocNo(), distLocMast.getLocNo(), NavigationMapType.DFX.id, Utils.getShuttlePoints(errorCommand.getShuttleNo().intValue()));//错误恢复,使用DFX地图 |
| | | // if (result != null) { |
| | | // //获取分段路径 |
| | | // ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(result); |
| | | // //将每一段路径分成command指令 |
| | | // for (ArrayList<NavigateNode> nodes : data) { |
| | | // //开始路径 |
| | | // NavigateNode startPath = nodes.get(0); |
| | | // //目标路径 |
| | | // NavigateNode endPath = nodes.get(nodes.size() - 1); |
| | | // Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 |
| | | // |
| | | // String qrCodeValue = distLocMast.getQrCodeValue(); |
| | | // errorCommand.setCommandWord((short) 1); |
| | | // errorCommand.setStartCodeNum(shuttleProtocol.getCurrentCode()); |
| | | // errorCommand.setMiddleCodeNum((short) 1); |
| | | // errorCommand.setDistCodeNum((short) Integer.parseInt(qrCodeValue)); |
| | | // errorCommand.setStartToDistDistance(allDistance); |
| | | // errorCommand.setRunSpeed((short) 1000); |
| | | // errorCommand.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id); |
| | | // errorCommand.setForceMoveDistance(0); |
| | | // errorCommand.setIOControl((short) 0); |
| | | // errorCommand.setCommandEnd((short) 1); |
| | | // break; |
| | | // } |
| | | // } |
| | | // } |
| | | // |
| | | // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WORKING); |
| | | // //当前步序 |
| | | // int commandStep = redisCommand.getCommandStep(); |
| | | // //步序回退 |
| | | // commandStep--; |
| | | // redisCommand.setCommandStep(commandStep); |
| | | // } |
| | | // |
| | | // if (!write(errorCommand)) { |
| | | // News.error("四向穿梭车命令下发失败,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(errorCommand)); |
| | | // return false; |
| | | // } else { |
| | | // News.info("四向穿梭车命令下发成功,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(errorCommand)); |
| | | // errorCommands.remove(0); |
| | | // redisCommand.setErrorCommands(errorCommands); |
| | | // //任务数据保存到redis |
| | | // redisUtil.set("shuttle_wrk_no_" + wrkNo, JSON.toJSONString(redisCommand)); |
| | | // return true; |
| | | // } |
| | | // } |
| | | |
| | | LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1); |
| | | LiftProtocol liftProtocol = liftThread.getLiftProtocol(); |
| | |
| | | //上一条指令起点是提升机二维码,则清零提升机任务号 |
| | | if (command.getStartCodeNum().intValue() == liftProtocol.getBarcode().intValue()) { |
| | | //判断提升机是否处于空闲 |
| | | if (liftProtocol.isIdleNoTask()) { |
| | | if (liftProtocol.isIdleNoTask() && liftProtocol.getTaskNo().intValue() == redisCommand.getWrkNo().intValue()) { |
| | | liftProtocol.setTaskNo((short) 0);//清空任务号 |
| | | WrkMast wrkMast = wrkMastService.selectById(wrkNo); |
| | | if (wrkMast != null) { |
| | | wrkMast.setLiftNo(null);//解锁提升机 |
| | | wrkMastService.updateById(wrkMast); |
| | | } |
| | | } |
| | | } |
| | | |
| | | //入库命令,当小车取完货后,需要将提升机释放 |
| | | if (assignCommand.getTaskMode().intValue() == ShuttleTaskModeType.PAK_IN.id) { |
| | | //判断上一条指令的起点是否为输送站点且目标点不是提升机内部二维码 |
| | | Short startCodeNum = command.getStartCodeNum(); |
| | | BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); |
| | | BasDevp basDevp = basDevpService.queryByQrCode(startCodeNum.intValue());//目标站点 |
| | | if (basDevp != null && command.getDistCodeNum().intValue() != liftProtocol.getBarcode().intValue()) { |
| | | //上一条指令的起点为输送站点且目标点不是提升机内部二维码 |
| | | //此时小车应该已经离开输送站点,判断提升机是否空闲且有工作号 |
| | | if (liftProtocol.isIdleNoTask() && liftProtocol.getTaskNo().intValue() == redisCommand.getWrkNo().intValue()) { |
| | | liftProtocol.setTaskNo((short) 0);//清空任务号 |
| | | WrkMast wrkMast = wrkMastService.selectById(wrkNo); |
| | | if (wrkMast != null) { |
| | | wrkMast.setLiftNo(null);//解锁提升机 |
| | | wrkMastService.updateById(wrkMast); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } else if (command.getCommandWord().intValue() == 2) { |
| | | //托盘顶升命令 |
| | |
| | | //上一条任务未完成,禁止下发命令 |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | if (commands.size() == 0) { |
| | | return false; |
| | | } |
| | | |
| | | //取出命令 |
| | |
| | | //保存数据到数据库做流水 |
| | | BasShuttleOptService shuttleOptService = SpringUtils.getBean(BasShuttleOptService.class); |
| | | if (shuttleOptService != null) { |
| | | short[] commandArr = getCommandArr(command);//获取命令报文 |
| | | BasShuttleOpt opt = new BasShuttleOpt( |
| | | assignCommand.getTaskNo().intValue(), |
| | | assignCommand.getShuttleNo().intValue(), |
| | |
| | | null, |
| | | null, |
| | | null, |
| | | JSON.toJSONString(command) |
| | | JSON.toJSONString(command), |
| | | JSON.toJSONString(commandArr) |
| | | ); |
| | | shuttleOptService.insert(opt); |
| | | } |
| | |
| | | if (commands.get(0).getStartCodeNum() == null) { |
| | | return false; |
| | | } |
| | | //命令起始位置就是提升机二维码,则不进行校验 |
| | | if (commands.get(0).getStartCodeNum().intValue() == liftProtocol.getBarcode().intValue()) { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | //当前等待执行的指令 |
| | | ShuttleCommand command = commands.get(commandStep); |
| | | |
| | | BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); |
| | | ArrayList<Short> qrCodeValues = new ArrayList<>(); |
| | |
| | | qrCodeValues.add(Short.parseShort(basDevp.getQrCodeValue())); |
| | | } |
| | | |
| | | //遍历所有指令,判断是否有到提升机口的指令或从提升机口前往提升机内的指令,并获取到达该提升机口所需步序 |
| | | int step = 0; |
| | | Integer siteNo = null;//站点号 |
| | | ShuttleCommand command = null; |
| | | for (int i = 0; i < commands.size(); i++) { |
| | | command = commands.get(i); |
| | | for (Short qrCodeValue : qrCodeValues) { |
| | | //目标位置是提升机口,或起点位置是提升机口且目标是去提升机内 |
| | | if (command.getDistCodeNum() == null || command.getStartCodeNum() == null) { |
| | | continue; |
| | | } |
| | | for (Short qrCodeValue : qrCodeValues) { |
| | | //目标位置是提升机口,或起点位置是提升机口且目标是去提升机内 |
| | | if (command.getDistCodeNum() == null || command.getStartCodeNum() == null) { |
| | | continue; |
| | | } |
| | | |
| | | if (qrCodeValue.intValue() == command.getDistCodeNum().intValue() || (qrCodeValue.intValue() == command.getStartCodeNum().intValue() && command.getDistCodeNum().intValue() == liftProtocol.getBarcode().intValue())) { |
| | | //存在 |
| | | step = i + 1; |
| | | BasDevp basDevp = basDevpService.queryByQrCode(qrCodeValue.intValue()); |
| | | siteNo = basDevp.getDevNo(); |
| | | break; |
| | | } |
| | | if (qrCodeValue.intValue() == command.getDistCodeNum().intValue() || (qrCodeValue.intValue() == command.getStartCodeNum().intValue() && command.getDistCodeNum().intValue() == liftProtocol.getBarcode().intValue())) { |
| | | //存在 |
| | | BasDevp basDevp = basDevpService.queryByQrCode(qrCodeValue.intValue()); |
| | | siteNo = basDevp.getDevNo(); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (step == 0) { |
| | | //无需后续检测,直接放行 |
| | | if (siteNo == null) { |
| | | //找不到站点,说明还未到提升机 |
| | | return true; |
| | | } |
| | | |
| | | |
| | | // //遍历所有指令,判断是否有到提升机口的指令或从提升机口前往提升机内的指令,并获取到达该提升机口所需步序 |
| | | // int step = 0; |
| | | // Integer siteNo = null;//站点号 |
| | | // ShuttleCommand command = null; |
| | | // for (int i = 0; i < commands.size(); i++) { |
| | | // command = commands.get(i); |
| | | // for (Short qrCodeValue : qrCodeValues) { |
| | | // //目标位置是提升机口,或起点位置是提升机口且目标是去提升机内 |
| | | // if (command.getDistCodeNum() == null || command.getStartCodeNum() == null) { |
| | | // continue; |
| | | // } |
| | | // |
| | | // if (qrCodeValue.intValue() == command.getDistCodeNum().intValue() || (qrCodeValue.intValue() == command.getStartCodeNum().intValue() && command.getDistCodeNum().intValue() == liftProtocol.getBarcode().intValue())) { |
| | | // //存在 |
| | | // step = i + 1; |
| | | // BasDevp basDevp = basDevpService.queryByQrCode(qrCodeValue.intValue()); |
| | | // siteNo = basDevp.getDevNo(); |
| | | // break; |
| | | // } |
| | | // } |
| | | // } |
| | | // |
| | | // if (step == 0) { |
| | | // //无需后续检测,直接放行 |
| | | // return true; |
| | | // } |
| | | |
| | | //判断下一步是否为提升机口或提升机内 |
| | | if (commandStep < commands.size()) { |
| | |
| | | } |
| | | } |
| | | } |
| | | // if (commandStep + 1 != step) { |
| | | // //下一步不是提升机口,跳过后续流程 |
| | | // return true; |
| | | // } |
| | | |
| | | //获取四向穿梭车当前楼层 |
| | | String shuttleLocNo = shuttleProtocol.getCurrentLocNo();//二维码对应库位号 |
| | |
| | | } |
| | | |
| | | //判断输送线站点是否给出提升机到位信号 |
| | | if (siteNo != null) { |
| | | SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); |
| | | StaProtocol staProtocol = siemensDevpThread.getStation().get(siteNo); |
| | | if (!staProtocol.isLiftArrival()) { |
| | | //输送线反馈提升机没有到位 |
| | | executeLift(liftThread, liftProtocol, redisCommand, shuttleLocNoLev);//调度提升机 |
| | | return false; |
| | | } |
| | | |
| | | if (shuttleProtocol.getCurrentCode().intValue() == liftProtocol.getBarcode().intValue()) { |
| | | //小车处于提升机内 |
| | | return true; |
| | | }else { |
| | | if (liftProtocol.getPositionArrivalFeedback$() == shuttleLocNoLev) { |
| | | liftProtocol.setTaskNo(wrkNo);//给提升机写工作号,防止被占用 |
| | | return true;//提升机到位 |
| | | } |
| | | executeLift(liftThread, liftProtocol, redisCommand, shuttleLocNoLev);//调度提升机 |
| | | return false;//提升机没有到位 |
| | | } |
| | | SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); |
| | | StaProtocol staProtocol = siemensDevpThread.getStation().get(siteNo); |
| | | if (!staProtocol.isLiftArrival()) { |
| | | //输送线反馈提升机没有到位 |
| | | executeLift(liftThread, liftProtocol, redisCommand, shuttleLocNoLev);//调度提升机 |
| | | return false; |
| | | } |
| | | |
| | | return false; |
| | | if (shuttleProtocol.getCurrentCode().intValue() == liftProtocol.getBarcode().intValue()) { |
| | | //小车处于提升机内 |
| | | return true; |
| | | }else { |
| | | if (liftProtocol.getPositionArrivalFeedback$() == shuttleLocNoLev) { |
| | | //判断提升机是否有任务号 |
| | | if (liftProtocol.getTaskNo().intValue() != 0) { |
| | | //判断任务号是否和当前小车任务一致 |
| | | if (liftProtocol.getTaskNo().intValue() != wrkNo.intValue()) { |
| | | return false;//任务号不一致,且提升机任务号不为0 |
| | | } |
| | | } |
| | | liftProtocol.setTaskNo(wrkNo);//给提升机写工作号,防止被占用 |
| | | WrkMastService wrkMastService = SpringUtils.getBean(WrkMastService.class); |
| | | WrkMast wrkMast = wrkMastService.selectById(shuttleProtocol.getTaskNo()); |
| | | if (wrkMast != null) { |
| | | wrkMast.setLiftNo(liftProtocol.getLiftNo().intValue());//锁定提升机,防止被抢占 |
| | | wrkMastService.updateById(wrkMast); |
| | | } |
| | | return true;//提升机到位 |
| | | } |
| | | executeLift(liftThread, liftProtocol, redisCommand, shuttleLocNoLev);//调度提升机 |
| | | return false;//提升机没有到位 |
| | | } |
| | | |
| | | } |
| | | |
| | | private boolean executeLift(LiftThread liftThread, LiftProtocol liftProtocol, ShuttleRedisCommand redisCommand, Integer shuttleLocNoLev) {//调度提升机 |
| | | if (liftProtocol.getRunning()) { |
| | | //提升机运行中,禁止下发 |
| | | if (!liftProtocol.isIdle()) { |
| | | //提升机不空闲禁止下发 |
| | | return false; |
| | | } |
| | | |
| | | if (liftProtocol.getPlatShuttleCheck()) { |
| | | //提升机内有车禁止下发 |
| | | return false; |
| | | } |
| | | |
| | |
| | | return false; |
| | | } |
| | | |
| | | WrkMastService wrkMastService = SpringUtils.getBean(WrkMastService.class); |
| | | WrkMast wrkMast = wrkMastService.selectById(shuttleProtocol.getTaskNo()); |
| | | if (wrkMast != null) { |
| | | wrkMast.setLiftNo(liftProtocol.getLiftNo().intValue());//锁定提升机,防止被抢占 |
| | | wrkMastService.updateById(wrkMast); |
| | | } |
| | | |
| | | //给提升机分配任务 |
| | | liftProtocol.setTaskNo(shuttleProtocol.getTaskNo());//设置任务号 |
| | | liftProtocol.setShuttleNo(shuttleProtocol.getShuttleNo());//设置四向穿梭车号 |