package com.zy.core.thread; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; 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.model.NyShuttleOperaResult; import com.zy.common.service.CommonService; import com.zy.common.utils.*; import com.zy.core.News; import com.zy.core.ThreadHandler; import com.zy.core.cache.MessageQueue; 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.*; 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; import javax.swing.*; import java.io.IOException; import java.net.Socket; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * 牛眼四向穿梭车线程 */ @Data @Slf4j public class NyShuttleThread implements Runnable, ThreadHandler { private ShuttleSlave slave; private NyShuttleProtocol shuttleProtocol; private RedisUtil redisUtil; private Socket socket; public NyShuttleThread(ShuttleSlave slave,RedisUtil redisUtil) { this.slave = slave; this.redisUtil = redisUtil; } @Override public void run() { this.connect(); while (true) { try { int step = 1; Task task = MessageQueue.poll(SlaveType.Shuttle, slave.getId()); if (task != null) { step = task.getStep(); } switch (step) { // 读数据 case 1: read(); break; // // 写入数据 // case 2: // write((NyShuttleHttpCommand) task.getData()); // break; //下发任务 case 3: assignWork((ShuttleAssignCommand) task.getData()); break; default: break; } Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } } private void read() { try { if (this.socket == null || this.socket.isClosed()) { //链接断开重新链接 this.connect(); } readStatus(); //四向穿梭车空闲、有任务、标记为true、存在任务指令,需要执行任务的下一条指令 if (shuttleProtocol.getFree() == ShuttleStatusType.IDLE.id && shuttleProtocol.getTaskNo() != 0 && !shuttleProtocol.getPakMk()) { //执行下一步指令 executeWork(shuttleProtocol.getTaskNo().shortValue()); } //小车空闲且有跑库程序 if (shuttleProtocol.isIdle() && shuttleProtocol.getMoveLoc()) { moveLoc(); } } catch (Exception e) { e.printStackTrace(); OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); } } private void readStatus() { try { if (null == shuttleProtocol) { shuttleProtocol = new NyShuttleProtocol(); shuttleProtocol.setShuttleNo(slave.getId().shortValue()); shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); } //----------读取四向穿梭车状态----------- NyShuttleHttpCommand readStatusCommand = NyHttpUtils.getReadStatusCommand(slave.getId()); JSONObject jsonObject = NyHttpUtils.requestCommand(socket, readStatusCommand); if (jsonObject == null) { shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.OFFLINE); OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车Socket状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); }else { //手动状态/自动状态 shuttleProtocol.setWorkingMode(jsonObject.getInteger("workingMode")); //允许状态 0:运行中1:空闲 shuttleProtocol.setFree(jsonObject.getInteger("free")); //当前速度 shuttleProtocol.setSpeed(jsonObject.getInteger("speed")); //负载状态 shuttleProtocol.setLoadState(jsonObject.getInteger("loadState")); //管制状态 shuttleProtocol.setSuspendState(jsonObject.getInteger("suspendState")); //顶升位置 shuttleProtocol.setLiftPosition(jsonObject.getInteger("liftPosition")); //运行方向 shuttleProtocol.setRunDir(jsonObject.getInteger("runDir")); //运行方向 shuttleProtocol.setRunDir2(jsonObject.getInteger("runDir2")); //充电状态 shuttleProtocol.setChargState(jsonObject.getInteger("chargState")); //电池电量 shuttleProtocol.setPowerPercent(jsonObject.getInteger("powerPercent")); //最高电芯电压(mV) shuttleProtocol.setMaxCellVoltage(jsonObject.getInteger("maxCellVoltage")); //最低电芯电压(mV) shuttleProtocol.setMinCellVoltage(jsonObject.getInteger("minCellVoltage")); //电池电压 shuttleProtocol.setVoltage(jsonObject.getInteger("voltage")); //充放电循环次数 shuttleProtocol.setChargeCycleTimes(jsonObject.getInteger("chargeCycleTimes")); //剩余电量 shuttleProtocol.setSurplusQuantity(jsonObject.getInteger("surplusQuantity")); //总电量 shuttleProtocol.setCountQuantity(jsonObject.getInteger("countQuantity")); //实际库位xyz shuttleProtocol.setPoint(jsonObject.getObject("point", NyShuttleProtocol.NyShuttlePointClass.class)); //实际坐标xyz shuttleProtocol.setCoord(jsonObject.getObject("coord", NyShuttleProtocol.NyShuttlePointClass.class)); //任务目的库位 shuttleProtocol.setTask(jsonObject.getObject("task", NyShuttleProtocol.TaskClass.class)); //任务状态 shuttleProtocol.setTaskState(jsonObject.getInteger("taskState")); //故障状态 shuttleProtocol.setErrState(jsonObject.getInteger("errState")); ArrayList errCode = new ArrayList<>(); for (Object o : jsonObject.getJSONArray("errCode")) { errCode.add(Integer.parseInt(o.toString())); } //故障码 shuttleProtocol.setErrCode(errCode.get(0)); //总里程数 shuttleProtocol.setStatusSum(jsonObject.getObject("statusSum", NyShuttleProtocol.StatusSumClass.class)); //非自动状态时间计时 shuttleProtocol.setErrTime(jsonObject.getInteger("errTime")); //小车处于运行中,将标记置为false if (shuttleProtocol.getFree() == 0) { shuttleProtocol.setPakMk(false); } //将四向穿梭车状态保存至数据库 BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); BasShuttle basShuttle = shuttleService.selectById(slave.getId()); if (basShuttle == null) { basShuttle = new BasShuttle(); //四向穿梭车号 basShuttle.setShuttleNo(slave.getId()); shuttleService.insert(basShuttle); } //工作模式 basShuttle.setWorkingMode(shuttleProtocol.getWorkingMode()); //运行状态 basShuttle.setFree(shuttleProtocol.getFree()); //当前速度 basShuttle.setSpeed(shuttleProtocol.getSpeed()); //负载状态 basShuttle.setLoadState(shuttleProtocol.getLoadState()); //管制状态 basShuttle.setSuspendState(shuttleProtocol.getSuspendState()); //顶升位置 basShuttle.setLiftPosition(shuttleProtocol.getLiftPosition()); //运行方向 basShuttle.setRunDir(shuttleProtocol.getRunDir()); //运行方向 basShuttle.setRunDir2(shuttleProtocol.getRunDir2()); //充电状态 basShuttle.setChargState(shuttleProtocol.getChargState()); //电池电量 basShuttle.setPowerPercent(shuttleProtocol.getPowerPercent()); //最高电芯电压 basShuttle.setMaxCellVoltage(shuttleProtocol.getMaxCellVoltage()); //电池电压 basShuttle.setVoltage(shuttleProtocol.getVoltage()); //充放电循环次数 basShuttle.setChargeCycleTimes(shuttleProtocol.getChargeCycleTimes()); //剩余电量 basShuttle.setSurplusQuantity(shuttleProtocol.getSurplusQuantity()); //总电量 basShuttle.setCountQuantity(shuttleProtocol.getCountQuantity()); //实际库位 basShuttle.setPoint(JSONObject.toJSONString(shuttleProtocol.getPoint())); //实际坐标 basShuttle.setCoord(JSONObject.toJSONString(shuttleProtocol.getCoord())); //任务目的库位 basShuttle.setTask(JSONObject.toJSONString(shuttleProtocol.getTask())); //任务状态 basShuttle.setTaskState(shuttleProtocol.getTaskState()); //故障状态 basShuttle.setErrState(shuttleProtocol.getErrState()); //总里程数 basShuttle.setStatusSum(JSONObject.toJSONString(shuttleProtocol.getStatusSum())); //非自动状态时间计时 basShuttle.setErrTime(shuttleProtocol.getErrTime()); //任务号 basShuttle.setWrkNo(shuttleProtocol.getTaskNo().intValue()); //修改时间 basShuttle.setUpdateTime(new Date()); //作业标记 basShuttle.setPakMk(shuttleProtocol.getPakMk()); if (shuttleService.updateById(basShuttle)) { OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // log.info(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); } } } catch (Exception e) { e.printStackTrace(); OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车Socket状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); try { this.socket.close(); this.socket = null; Thread.sleep(1000); this.connect(); } catch (IOException | InterruptedException exception) { e.printStackTrace(); } } } @Override public boolean connect() { try { Socket socket = new Socket(slave.getIp(),slave.getPort()); socket.setSoTimeout(60000); socket.setKeepAlive(true); this.socket = socket; log.info(MessageFormat.format("【{0}】四向穿梭车Socket链接成功 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); } catch (IOException e) { OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车Socket链接失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); } return true; } @Override public void close() { } private boolean write(NyShuttleHttpCommand command, ShuttleAssignCommand assignCommand) { if (null == command) { News.error("四向穿梭车写入命令为空"); return false; } BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); if (shuttleService == null) { News.error("系统错误"); return false; } BasShuttle basShuttle = shuttleService.selectById(slave.getId().shortValue()); if (basShuttle == null) { News.error("四向穿梭车不存在"); return false; } //发出请求 JSONObject result = null; try { result = NyHttpUtils.requestCommand(socket, command); } catch (IOException e) { try { this.socket.close(); this.socket = null; Thread.sleep(1000); this.connect(); } catch (IOException exception) { exception.printStackTrace(); } catch (InterruptedException ex) { throw new RuntimeException(ex); } } //保存数据到数据库做流水 BasShuttleOptService shuttleOptService = SpringUtils.getBean(BasShuttleOptService.class); BasShuttleOpt opt = null; if (shuttleOptService != null) { opt = new BasShuttleOpt( assignCommand.getTaskNo().intValue(), assignCommand.getShuttleNo().intValue(), new Date(), ShuttleTaskModeType.get(assignCommand.getTaskMode()).desc, assignCommand.getSourceLocNo(), assignCommand.getLocNo(), null, null, null, JSON.toJSONString(command), null, JSON.toJSONString(shuttleProtocol) ); opt.setSend(1);//已下发 opt.setResponse(JSON.toJSONString(result));//请求响应 opt.setDeviceWrk(command.getWrkNo().toString());//设备工作号 shuttleOptService.insert(opt); } if (result == null) { return false;//请求失败 } return true; } //分配任务 private void assignWork(ShuttleAssignCommand assignCommand) { ShuttleRedisCommand redisCommand = new ShuttleRedisCommand(); redisCommand.setShuttleNo(assignCommand.getShuttleNo());//四向穿梭车号 redisCommand.setWrkNo(assignCommand.getTaskNo());//工作号 redisCommand.setCommandStep(0);//命令执行步序 redisCommand.setAssignCommand(assignCommand);//命令 shuttleProtocol.setTaskNo(assignCommand.getTaskNo().intValue()); shuttleProtocol.setAssignCommand(assignCommand); shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WORKING); //任务数据保存到redis redisUtil.set("shuttle_wrk_no_" + assignCommand.getTaskNo(), JSON.toJSONString(redisCommand)); //执行下发任务 executeWork(assignCommand.getTaskNo()); } //执行下发的指令 private boolean executeWork(Short wrkNo) { //读取redis数据 if (wrkNo == null) { return false; } WrkMastMapper wrkMastMapper = SpringUtils.getBean(WrkMastMapper.class); WrkMast wrkMast = wrkMastMapper.selectByWorkNo(wrkNo.intValue()); Object o = redisUtil.get("shuttle_wrk_no_" + wrkNo); if (o == null) { return false; } ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class); ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); List commands = redisCommand.getAssignCommand().getCommands(); //当前步序 int commandStep = redisCommand.getCommandStep(); if (commands.size() == 0) { return false; } NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(shuttleProtocol.getCurrentLocNo())); boolean isLock = false;//是否解锁路径 //取出命令 NyShuttleHttpCommand command = null; if (commandStep < commands.size()) { 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 nodes = lastCommand.getNodes(); // //解锁当前路径 // if (command != null && command.getNodes() != null) { // nodes.addAll(command.getNodes()); // } if (nodes != null) { navigateMapData.writeNavigateNodeToRedisMap(nodes, false);//解锁路径 isLock = true;//解锁过路径 } } }else { lastCommand.setComplete(true);//其他命令默认认为完成 } //任务数据保存到redis redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand)); if (!lastCommand.getComplete()) { //上一条任务未完成,禁止下发命令 return false; } //判断是否为最后一条命令且命令执行完成,抛出等待确认状态 NyShuttleHttpCommand endCommand = commands.get(commands.size() - 1); if (endCommand.getComplete()) { //删除redis redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo()); if (!assignCommand.getCharge()) { //对主线程抛出等待确认状态waiting shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING); }else { shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING); } News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(commands)); return false;//禁止再下发命令 } } List nextNodes = null;//下一步命令行走路径 if (commandStep + 1 < commands.size()) { NyShuttleHttpCommand nextCommand = commands.get(commandStep + 1);//下一步命令 nextNodes = nextCommand.getNodes();//下一步命令行走路径 } if (shuttleProtocol.getFree() == ShuttleStatusType.BUSY.id) { String requestType = command.getRequest().getBody().get("requestType").toString(); //停止充电 管制命令 if(!(requestType.equals("stopCharge") && shuttleProtocol.getChargState() == 1) && !requestType.equals("resume")){ return false;//小车状态忙,禁止执行命令 } } // //检测小车是否要进提升机,如需要进提升机则调度提升机 // if (!checkLiftStation(wrkNo)) { // return false; // } //检测穿梭车是否在提升机内 if (!checkShuttleInTheLift(wrkNo)) { return false; } if (command.getRequest().getBody().get("requestType").equals("move")) { ArrayList whiteList = new ArrayList<>();//设置节点的白名单 if (wrkMast != null && ((wrkMast.getIoType() > 100 && wrkMast.getIoType() < 200) || wrkMast.getIoType() == 11)) { //出库任务,不检测首节点 int[] startArr = NavigatePositionConvert.positionToXY(wrkMast.getSourceLocNo());//开始节点 whiteList.add(startArr); } //解锁过路径,只检测下一段路径是否可走(当前路径已经被锁定无需再检测) if (isLock) { //只检测下一段路径是否可走(当前路径已经被锁定无需再检测) //检测路径是否可行走 if (!checkPath(nextNodes == null ? command.getNodes() : nextNodes, null, whiteList)) { return false; } }else { //检测当前路径和下一段路径 //检测路径是否可行走 if (!checkPath(command.getNodes(), nextNodes, whiteList)) { return false; } } //锁定路径,锁定当前路径和下一步路径 List nodes = command.getNodes(); if (nextNodes != null) { nodes.addAll(nextNodes); } if (nodes != null) { navigateMapData.writeNavigateNodeToRedisMap(nodes, true);//所使用的路径进行锁定禁用 } } //可执行命令 if (!write(command, assignCommand)) { News.error("四向穿梭车命令下发失败,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); return false; } News.info("四向穿梭车命令下发成功,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); //将标记置为false(防止重发) shuttleProtocol.setPakMk(true); String requestType = command.getRequest().getBody().get("requestType").toString(); if (requestType.equals("updateFloor")) { //更新楼层命令 shuttleProtocol.setPakMk(false);//恢复标记 } commandStep++; //更新redis数据 redisCommand.setCommandStep(commandStep); //任务数据保存到redis redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand)); return true; } //检测小车是否要进提升机,如需要进提升机则调度提升机 private boolean checkLiftStation(Short wrkNo) { //读取redis数据 if (wrkNo == null) { return false; } Object o = redisUtil.get("shuttle_wrk_no_" + wrkNo); if (o == null) { return false; } WrkMastMapper wrkMastMapper = SpringUtils.getBean(WrkMastMapper.class); ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class); //当前步序 int commandStep = redisCommand.getCommandStep(); //检测是否存在提升机口的指令 List commands = redisCommand.getAssignCommand().getCommands(); 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 (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 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; } Integer liftX = basLift.getPoint$().getX(); Integer liftY = basLift.getPoint$().getY(); if (liftX.equals(shuttleProtocol.getPoint().getX()) && liftY.equals(shuttleProtocol.getPoint().getY())) { //小车在提升机内 //判断提升机是否空闲 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; } }else { return true;//不在提升机内,放行 } } return false;//默认不放行 } /** * 检测路径是否可行走 * 如果路径为目标库位,但不可行走,系统将尝试重新计算路径 */ private boolean checkPath(List currentNodes, List nextNodes, List whitePoints) { //检测路径是否可行走(检查路径锁定状态,检测路径是否有其他小车) //检测当前行走路径,和下一步路径 boolean checkPathIsAvailable = NavigateUtils.checkPathIsAvailable(currentNodes, shuttleProtocol.getShuttleNo().intValue(), Utils.getLev(shuttleProtocol.getCurrentLocNo()), whitePoints); if (nextNodes == null) { if (checkPathIsAvailable) { return true;//可行走 } return false; }else { boolean checkPathIsAvailable2 = NavigateUtils.checkPathIsAvailable(nextNodes, shuttleProtocol.getShuttleNo().intValue(), Utils.getLev(shuttleProtocol.getCurrentLocNo()), whitePoints); if (checkPathIsAvailable && checkPathIsAvailable2) { return true;//可行走 } } // ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); // NavigateNode currentTarget = currentNodes.get(currentNodes.size() - 1); // String currentLocNo = NavigatePositionConvert.nodeToLocNo(currentTarget); // NavigateNode nextTarget = nextNodes.get(nextNodes.size() - 1); // String nextLocNo = NavigatePositionConvert.nodeToLocNo(nextTarget); // if (assignCommand.getLocNo().equals(currentLocNo) || assignCommand.getLocNo().equals(nextLocNo)) { // //当前路径最后一个节点是目标库位,进行路径检测,如果不可行走,重新计算路径 // //不可行走,重新计算路径 // NyShuttleOperaResult result = NyShuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getShuttleNo().intValue(), shuttleProtocol.getTaskNo(), shuttleProtocol.getCurrentLocNo(), assignCommand.getLocNo()); // if (result == null) { // return false;//路径计算失败,不可行走 // } // // List newCommands = result.getCommands();//新路径 // // //当前步序 // int commandStep = redisCommand.getCommandStep(); // List commands = assignCommand.getCommands(); // // commands.remove(commandStep);//移除当前步序指令 // if (assignCommand.getLocNo().equals(currentLocNo)) { // //当前路径,需要再多移除下一步指令 // commands.remove(commandStep + 1); // } // // //将新路径添加进指令集合 // commands.addAll(commandStep, newCommands); // assignCommand.setCommands(commands); // redisCommand.setAssignCommand(assignCommand); // //任务数据保存到redis // redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand)); // return false;//当前不可行走,等待下一次执行走新路径 // } return false;//不可行走 } /** * 跑库程序 */ private void moveLoc() { LocMastService locMastService = SpringUtils.getBean(LocMastService.class); ShuttleDispatchUtils shuttleDispatchUtils = SpringUtils.getBean(ShuttleDispatchUtils.class); CommonService commonService = SpringUtils.getBean(CommonService.class); WrkMastMapper wrkMastMapper = SpringUtils.getBean(WrkMastMapper.class); int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//小车当前楼层 if (!shuttleProtocol.isIdle()) { return; } WrkMast wrkMast = wrkMastMapper.selectShuttleHasMoveWorking(shuttleProtocol.getShuttleNo().intValue()); if (wrkMast != null) { return; } if (shuttleProtocol.getYCurrent() > shuttleProtocol.getYTarget()) { //跑库结束 shuttleProtocol.setMoveLoc(false); shuttleProtocol.setMoveType(0); shuttleProtocol.setXStart(0); shuttleProtocol.setXTarget(0); shuttleProtocol.setXCurrent(0); shuttleProtocol.setYStart(0); shuttleProtocol.setYTarget(0); shuttleProtocol.setYCurrent(0); return; } if (shuttleProtocol.getMoveType() == 0) {//跑轨道 ArrayList locs = new ArrayList<>(); for (int i = shuttleProtocol.getXCurrent(); i <= shuttleProtocol.getXTarget(); i++) { String locNo = Utils.getLocNo(i, shuttleProtocol.getYCurrent(), lev); locs.add(locNo); } List locMasts = locMastService.selectEmptyLocNos(locs); if (locMasts.isEmpty()) { //空库位 shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1); return; } LocMast start = locMasts.get(0); LocMast target = locMasts.get(locMasts.size() - 1); //判断小车是否在起点位置 if (!shuttleProtocol.getCurrentLocNo().equals(start.getLocNo())) {//不在起点位置,调度去起点位置 shuttleDispatchUtils.dispatchShuttle(commonService.getWorkNo(3), start.getLocNo()); }else { //在起点位置,调度去目标位置 if (shuttleProtocol.getCurrentLocNo().equals(target.getLocNo())) { shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1);//小车和目标位置一致,跳过 }else { boolean result = shuttleDispatchUtils.dispatchShuttle(commonService.getWorkNo(3), target.getLocNo()); if (result) {//调度成功 shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1); } } } }else {//跑库位 Integer xCurrent = shuttleProtocol.getXCurrent(); if (xCurrent > shuttleProtocol.getXTarget()) {//当X值大于X目标值,进行归零且Y方向+1 shuttleProtocol.setXCurrent(shuttleProtocol.getXStart()); shuttleProtocol.setYCurrent(shuttleProtocol.getYCurrent() + 1); return; } Integer yCurrent = shuttleProtocol.getYCurrent(); String locNo = Utils.getLocNo(xCurrent, yCurrent, lev); LocMast target = locMastService.selectById(locNo); if (target == null) { shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1); return; } if (!target.getLocSts().equals("O")) { shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1); return; } //调度去目标位置 if (shuttleProtocol.getCurrentLocNo().equals(target.getLocNo())) { shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1);//小车和目标位置一致,跳过 }else { boolean result = shuttleDispatchUtils.dispatchShuttle(commonService.getWorkNo(3), target.getLocNo()); if (result) {//调度成功 shuttleProtocol.setXCurrent(shuttleProtocol.getXCurrent() + 1); } } } } }