| package com.zy.asrs.wcs.core.action; | 
|   | 
| import com.alibaba.fastjson.JSON; | 
| import com.alibaba.fastjson.JSONObject; | 
| import com.zy.asrs.wcs.core.entity.BasShuttle; | 
| import com.zy.asrs.wcs.core.model.NavigateNode; | 
| import com.zy.asrs.wcs.core.model.command.ShuttleAssignCommand; | 
| import com.zy.asrs.wcs.core.model.command.ShuttleCommand; | 
| import com.zy.asrs.wcs.core.model.command.ShuttleRedisCommand; | 
| import com.zy.asrs.wcs.core.model.enums.ShuttleCommandModeType; | 
| import com.zy.asrs.wcs.core.service.BasShuttleService; | 
| import com.zy.asrs.wcs.core.utils.NavigateMapUtils; | 
| import com.zy.asrs.wcs.core.utils.RedisUtil; | 
| import com.zy.asrs.wcs.core.utils.Utils; | 
| import com.zy.asrs.wcs.rcs.News; | 
| import com.zy.asrs.wcs.rcs.cache.SlaveConnection; | 
| import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant; | 
| import com.zy.asrs.wcs.rcs.entity.Device; | 
| import com.zy.asrs.wcs.rcs.model.enums.ShuttleProtocolStatusType; | 
| import com.zy.asrs.wcs.rcs.model.enums.SlaveType; | 
| import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol; | 
| import com.zy.asrs.wcs.rcs.thread.ShuttleThread; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.stereotype.Component; | 
|   | 
| import java.util.List; | 
|   | 
| @Component | 
| public class ShuttleAction { | 
|   | 
|     @Autowired | 
|     private RedisUtil redisUtil; | 
|     @Autowired | 
|     private NavigateMapUtils navigateMapUtils; | 
|     @Autowired | 
|     private BasShuttleService basShuttleService; | 
|   | 
|     public synchronized boolean assignWork(Device device, ShuttleAssignCommand assignCommand) { | 
|         ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); | 
|         if (shuttleThread == null) { | 
|             return false; | 
|         } | 
|   | 
|         ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); | 
|         if (shuttleProtocol == null) { | 
|             return false; | 
|         } | 
|   | 
|         ShuttleRedisCommand redisCommand = new ShuttleRedisCommand(); | 
|   | 
|         redisCommand.setShuttleNo(assignCommand.getShuttleNo());//四向穿梭车号 | 
|         redisCommand.setWrkNo(assignCommand.getTaskNo());//工作号 | 
|         redisCommand.setCommandStep(0);//命令执行步序 | 
|         redisCommand.setAssignCommand(assignCommand);//命令 | 
|         //任务数据保存到redis | 
|         if (redisUtil.set(DeviceRedisConstant.SHUTTLE_WORK_FLAG + assignCommand.getTaskNo(), JSON.toJSONString(redisCommand))) { | 
|             //下发行驶路径 | 
|             boolean result = shuttleThread.movePath(assignCommand.getNodes(), assignCommand.getTaskNo().intValue()); | 
|             if (!result) { | 
|                 return false; | 
|             } | 
|             shuttleProtocol.setTaskNo(assignCommand.getTaskNo().intValue()); | 
|             return true; | 
|         } | 
|         return false; | 
|     } | 
|   | 
|     public synchronized boolean executeWork(Device device, Integer taskNo) { | 
|         Object obj = redisUtil.get(DeviceRedisConstant.SHUTTLE_WORK_FLAG + taskNo); | 
|         if (obj == null) { | 
|             return false; | 
|         } | 
|         ShuttleRedisCommand redisCommand = JSON.parseObject(obj.toString(), ShuttleRedisCommand.class); | 
|         if (redisCommand == null) { | 
|             return false; | 
|         } | 
|   | 
|         ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); | 
|         if (shuttleThread == null) { | 
|             return false; | 
|         } | 
|   | 
|         ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); | 
|         if (shuttleProtocol == null) { | 
|             return false; | 
|         } | 
|   | 
|         //判断设备是否空闲 | 
|         if (!shuttleThread.isIdle()) { | 
|             return false; | 
|         } | 
|   | 
|         List<ShuttleCommand> commands = redisCommand.getAssignCommand().getCommands(); | 
|         if (commands.isEmpty()) { | 
|             return false; | 
|         } | 
|   | 
|         ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); | 
|         int commandStep = redisCommand.getCommandStep(); | 
|   | 
|         // 完结上一条命令 | 
|         if (commandStep != 0) { | 
|             ShuttleCommand command = commands.get(commandStep - 1); | 
|             if (command.getMode() == ShuttleCommandModeType.MOVE.id) { | 
|                 // 正常移动 | 
|                 if (command.getTargetLocNo().equals(shuttleProtocol.getCurrentLocNo())) { | 
|                     command.setComplete(true); | 
|                     //解锁锁定路径,上一条路径 | 
|                     List<NavigateNode> nodes = JSON.parseArray(JSON.toJSONString(command.getNodes()), NavigateNode.class);//进行深度copy | 
|                     if (nodes != null) { | 
|                         NavigateNode targetNode = assignCommand.getNodes().get(assignCommand.getNodes().size() - 1);//最终节点 | 
|                         NavigateNode node = nodes.get(nodes.size() - 1); | 
|                         if (!(targetNode.getX() == node.getX() && targetNode.getY() == node.getY())) { | 
|                             nodes.remove(nodes.size() - 1);//剔除尾节点 | 
|                         } | 
|                         boolean result = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(shuttleProtocol.getCurrentLocNo()), shuttleProtocol.getShuttleNo(), nodes, false);//解锁路径 | 
|                         if (!result) { | 
|                             return false;//解锁失败 | 
|                         } | 
|                     } | 
|                 } | 
|             } else if (command.getMode() == ShuttleCommandModeType.PALLET_LIFT.id) { | 
|                 // 托盘顶升 | 
|                 //判断是否顶升到位 | 
|                 if (shuttleProtocol.getHasLift()) { | 
|                     //判断是否有物 | 
|                     if (shuttleProtocol.getHasPallet()) { | 
|                         command.setComplete(true); | 
|                     } | 
|                 } | 
|             } else if (command.getMode() == ShuttleCommandModeType.PALLET_DOWN.id) { | 
|                 // 托盘下降命令 | 
|                 // 判断是否下降到位 | 
|                 if (!shuttleProtocol.getHasLift()) { | 
|                     command.setComplete(true); | 
|                 } | 
|             } else if (command.getMode() == ShuttleCommandModeType.CHARGE_OPEN.id) { | 
|                 // 充电开 | 
|                 //判断小车充电状态 | 
|                 if (shuttleProtocol.getHasCharge()) { | 
|                     command.setComplete(true); | 
|                 } | 
|             }else { | 
|                 command.setComplete(true);//其他命令默认认为完成 | 
|             } | 
|   | 
|             // 更新redis数据 | 
|             redisUtil.set(DeviceRedisConstant.SHUTTLE_WORK_FLAG + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand)); | 
|   | 
|             if (!command.getComplete()) { | 
|                 return false; | 
|             } | 
|   | 
|             //判断是否为最后一条命令且命令执行完成,抛出等待确认状态 | 
|             ShuttleCommand endCommand = commands.get(commands.size() - 1); | 
|             if (endCommand.getComplete()) { | 
|                 News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(commands)); | 
|   | 
|                 // 系统任务 | 
|                 if (assignCommand.getAuto()) { | 
|                     if (!assignCommand.getCharge()) { | 
|                         //对主线程抛出等待确认状态waiting | 
|                         shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING); | 
|                     }else { | 
|                         shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING); | 
|                     } | 
|                     News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); | 
|   | 
|                     // 手动任务 | 
|                 } else { | 
|                     //手动模式不抛出等待状态,直接复位空闲状态 | 
|                     shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); | 
|                     //任务号清零 | 
|                     shuttleProtocol.setTaskNo(0); | 
|                     //标记复位 | 
|                     shuttleProtocol.setPakMk(true); | 
|                     News.info("四向穿梭车手动任务执行完成,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); | 
|                 } | 
|   | 
|                 //删除redis | 
|                 redisUtil.del(DeviceRedisConstant.SHUTTLE_WORK_FLAG + redisCommand.getWrkNo()); | 
|                 return false;//禁止再下发命令 | 
|             } | 
|         } | 
|   | 
|         //取出命令 | 
|         ShuttleCommand command = commands.get(commandStep); | 
|   | 
|         // 下发命令 | 
|         if (!write(command, device)) { | 
|             News.error("四向穿梭车命令下发失败,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); | 
|             return false; | 
|         } | 
|   | 
|         return true; | 
|     } | 
|   | 
|     private synchronized boolean write(ShuttleCommand command, Device device) { | 
|         if (null == command) { | 
|             News.error("四向穿梭车写入命令为空"); | 
|             return false; | 
|         } | 
|         ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); | 
|         boolean result = false; | 
|         if (command.getMode() == ShuttleCommandModeType.MOVE.id | 
|                 || command.getMode() == ShuttleCommandModeType.IN_LIFT.id | 
|                 || command.getMode() == ShuttleCommandModeType.OUT_LIFT.id) {//移动 | 
|             result = shuttleThread.move(command); | 
|         } else if (command.getMode() == ShuttleCommandModeType.PALLET_LIFT.id | 
|                 || command.getMode() == ShuttleCommandModeType.PALLET_DOWN.id) {//顶升 | 
|             result = shuttleThread.lift(command); | 
|         } else if (command.getMode() == ShuttleCommandModeType.CHARGE_OPEN.id | 
|                 || command.getMode() == ShuttleCommandModeType.CHARGE_CLOSE.id) {//充电 | 
|             result = shuttleThread.charge(command); | 
|         } else if (command.getMode() == ShuttleCommandModeType.RESET.id) {//复位 | 
|             result = shuttleThread.reset(command); | 
|         } | 
|         return result; | 
|     } | 
|   | 
| } |