zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/ShuttleCommandService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/command/ShuttleCommand.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/command/ShuttleRedisCommand.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/ShuttleCommandModeType.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/DeviceTimer.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/ShuttleProtocol.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SurayShuttleThread.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java
New file @@ -0,0 +1,181 @@ package com.zy.asrs.wcs.core.action; import com.alibaba.fastjson.JSON; 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.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; 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))) { 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; } //四向穿梭车空闲、有任务、标记为true、存在任务指令,需要执行任务的下一条指令 if (!shuttleProtocol.getIdle() || shuttleProtocol.getTaskNo() == 0 || !shuttleProtocol.getPakMk()) { 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.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;//禁止再下发命令 } } return true; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/ShuttleCommandService.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.exception.CoolException; import com.zy.asrs.wcs.core.action.ShuttleAction; import com.zy.asrs.wcs.core.entity.Loc; import com.zy.asrs.wcs.core.model.NavigateNode; import com.zy.asrs.wcs.core.model.command.ShuttleAssignCommand; @@ -50,6 +51,8 @@ private LocService locService; @Autowired private NavigateMapUtils navigateMapUtils; @Autowired private ShuttleAction shuttleAction; // 计算 public Boolean accept(Motion motion) { @@ -365,16 +368,14 @@ if (motion.getOrigin() != null && motion.getTarget() != null) { //所使用的路径进行锁定禁用 boolean lockResult = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(motion.getTarget()), Integer.parseInt(shuttleProtocol.getShuttleNo()), assignCommand.getNodes(), true);//所使用的路径进行锁定禁用 boolean lockResult = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(motion.getTarget()), shuttleProtocol.getShuttleNo(), assignCommand.getNodes(), true);//所使用的路径进行锁定禁用 if (!lockResult) { return false;//锁定失败 } // shuttleThread.assignWork(assignCommand); }else { // shuttleThread.assignWork(assignCommand); } return Boolean.TRUE; boolean result = shuttleAction.assignWork(shuttleThread.getDevice(), assignCommand); return result; } public Boolean finish(Motion motion) { zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/command/ShuttleCommand.java
@@ -1,6 +1,7 @@ package com.zy.asrs.wcs.core.model.command; import com.zy.asrs.wcs.core.model.NavigateNode; import com.zy.asrs.wcs.core.model.enums.ShuttleCommandModeType; import lombok.Data; import java.util.List; @@ -22,6 +23,16 @@ private Integer taskNo = 0; /** * 命令类型 */ private Integer mode = ShuttleCommandModeType.NONE.id; /** * 目标库位 */ private String targetLocNo; /** * 报文内容 */ private String body; zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/command/ShuttleRedisCommand.java
New file @@ -0,0 +1,28 @@ package com.zy.asrs.wcs.core.model.command; import lombok.Data; import java.io.Serializable; /** * 四向穿梭车命令-存储在redis */ @Data public class ShuttleRedisCommand implements Serializable { //四向穿梭车号 private Short shuttleNo; //工作号 private Short wrkNo; //命令执行步序 private Integer commandStep; //命令 private ShuttleAssignCommand assignCommand; //提升机安全锁定标记 private Boolean liftSecurityMk = false; } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/ShuttleCommandModeType.java
New file @@ -0,0 +1,51 @@ package com.zy.asrs.wcs.core.model.enums; /** * 四向穿梭车命令类型 */ public enum ShuttleCommandModeType { NONE(-1, "未知类型"), MOVE(1, "移动"), IN_LIFT(2, "进提升机"), OUT_LIFT(3, "出提升机"), CHARGE(4, "充电"), PALLET_LIFT(5, "托盘顶升"), PALLET_DOWN(6, "托盘下降"), RESET(8, "复位"), ; public Integer id; public String desc; ShuttleCommandModeType(Integer id, String desc) { this.id = id; this.desc = desc; } public static ShuttleCommandModeType get(Integer id) { if (null == id) { return null; } for (ShuttleCommandModeType type : ShuttleCommandModeType.values()) { if (type.id.equals(id)) { return type; } } return null; } public static ShuttleCommandModeType get(ShuttleCommandModeType type) { if (null == type) { return null; } for (ShuttleCommandModeType type1 : ShuttleCommandModeType.values()) { if (type1 == type) { return type1; } } return null; } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/DeviceTimer.java
@@ -1,10 +1,20 @@ package com.zy.asrs.wcs.core.timer; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.wcs.core.action.ShuttleAction; import com.zy.asrs.wcs.core.utils.RedisUtil; import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant; import com.zy.asrs.wcs.rcs.entity.Device; import com.zy.asrs.wcs.rcs.entity.DeviceType; import com.zy.asrs.wcs.rcs.model.enums.SlaveType; import com.zy.asrs.wcs.rcs.service.DeviceService; import com.zy.asrs.wcs.rcs.service.DeviceTypeService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.List; @Slf4j @Component @@ -12,10 +22,37 @@ @Autowired private RedisUtil redisUtil; @Autowired private DeviceService deviceService; @Autowired private DeviceTypeService deviceTypeService; @Autowired private ShuttleAction shuttleAction; @Scheduled(cron = "0/1 * * * * ? ") public synchronized void executeShuttle() { DeviceType deviceType = deviceTypeService.getOne(new LambdaQueryWrapper<DeviceType>() .eq(DeviceType::getFlag, String.valueOf(SlaveType.Shuttle)) .eq(DeviceType::getStatus, 1)); if (deviceType == null) { return; } List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>() .eq(Device::getStatus, 1) .eq(Device::getDeviceType, deviceType.getId())); for (Device device : list) { Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_FLAG + device.getDeviceNo()); if (object == null) { continue; } Integer taskNo = Integer.valueOf(String.valueOf(object)); if (taskNo != 0) { //存在任务需要执行 shuttleAction.executeWork(device, taskNo); } } } @Scheduled(cron = "0/1 * * * * ? ") zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/ShuttleProtocol.java
@@ -29,7 +29,7 @@ /** * 四向穿梭车号 */ private String shuttleNo; private Integer shuttleNo; /** * 任务号 @@ -89,6 +89,11 @@ * 是否顶升 */ private Boolean hasLift; /** * 是否有托盘 */ private Boolean hasPallet; /** * 行驶方向 @@ -230,6 +235,14 @@ return this.taskNo == null ? 0 : this.taskNo; } public void setTaskNo(Integer taskNo) { RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class); if (null != redisUtil) { redisUtil.set(DeviceRedisConstant.SHUTTLE_FLAG + this.shuttleNo, taskNo); this.taskNo = taskNo; } } //通过当前二维码获取当前库位号 public String getCurrentLocNo() { LocService locService = SpringUtils.getBean(LocService.class); zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SurayShuttleThread.java
@@ -9,6 +9,7 @@ import com.zy.asrs.framework.exception.CoolException; import com.zy.asrs.wcs.core.entity.Loc; import com.zy.asrs.wcs.core.model.command.ShuttleCommand; import com.zy.asrs.wcs.core.model.enums.ShuttleCommandModeType; import com.zy.asrs.wcs.core.service.LocService; import com.zy.asrs.wcs.rcs.News; import com.zy.asrs.wcs.rcs.cache.OutputQueue; @@ -81,24 +82,29 @@ if (data != null) { if (null == shuttleProtocol) { shuttleProtocol = new ShuttleProtocol(); shuttleProtocol.setShuttleNo(device.getDeviceNo()); shuttleProtocol.setShuttleNo(Integer.valueOf(device.getDeviceNo())); shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); shuttleProtocol.setDevice(device); } //----------读取四向穿梭车状态----------- //小车忙状态位 shuttleProtocol.setDeviceStatus(data.getInteger("deviceStatus")); //小车设备状态 Integer deviceStatus = data.getInteger("deviceStatus"); shuttleProtocol.setDeviceStatus(deviceStatus); //当前二维码 shuttleProtocol.setCurrentCode(data.getString("deviceLocation") == null ? "0" : data.getString("deviceLocation")); shuttleProtocol.setCurrentCode(data.getString("groundCode") == null ? "0" : data.getString("groundCode")); //电池电量 shuttleProtocol.setBatteryPower(data.getString("battery") == null ? "0%" : data.getString("battery")); //是否顶升 shuttleProtocol.setHasLift(data.getInteger("palletStatus") == 1 ? true : false); //是否有托盘 shuttleProtocol.setHasPallet(data.getInteger("hasPallet") != 2 ? true : false); //行驶方向 shuttleProtocol.setRunDirection(data.getString("direction") == null ? "none" : data.getString("direction")); //是否为充电状态 shuttleProtocol.setHasCharge((deviceStatus == 5 || deviceStatus == 13) ? true : false); ///读取四向穿梭车状态-end @@ -194,6 +200,8 @@ ShuttleCommand command = new ShuttleCommand(); command.setShuttleNo(Integer.parseInt(this.device.getDeviceNo())); command.setBody(JSON.toJSONString(body)); command.setMode(ShuttleCommandModeType.MOVE.id); command.setTargetLocNo(loc.getLocNo()); return command; }