From 04136d65de3e21c7b9e1d0e9182f7a6afd5d8cce Mon Sep 17 00:00:00 2001 From: liuhanqing Date: Mon, 24 Nov 2025 14:24:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=8F=E8=BD=A6=E8=B0=83=E5=BA=A6=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/bas/srgvmap/domain/WcsSrgvMap.java | 274 +--------- .../bas/srgvmap/service/RoadCacheService.java | 38 ++ .../service/impl/AgvPathProcessor.java | 506 ++++++++++++++++++ .../service/impl/RoadCacheServiceImpl.java | 311 +++++++++++ .../scheduleTask/srgv/BaseSRgvThread.java | 358 ++++++------- .../schedule/scheduleTask/tsj/TsjThread.java | 104 ++-- 6 files changed, 1074 insertions(+), 517 deletions(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/RoadCacheService.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/impl/AgvPathProcessor.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/impl/RoadCacheServiceImpl.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/domain/WcsSrgvMap.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/domain/WcsSrgvMap.java index b26030d..fb092c0 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/domain/WcsSrgvMap.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/domain/WcsSrgvMap.java @@ -1,16 +1,26 @@ package com.ruoyi.bas.srgvmap.domain; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.domain.BaseEntity; +import javax.validation.constraints.NotNull; + /** * 小车点位地图表对象 wcs_srgv_map - * + * * @author ruoyi * @date 2025-11-21 */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ToString public class WcsSrgvMap extends BaseEntity { private static final long serialVersionUID = 1L; @@ -21,15 +31,15 @@ public class WcsSrgvMap extends BaseEntity /** 二维数组纵轴(从上至下) */ @Excel(name = "二维数组纵轴(从上至下)") - private Long x; + private Integer x; /** 二维数组横轴(从左至右) */ @Excel(name = "二维数组横轴(从左至右)") - private Long y; + private Integer y; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long z; + private Integer z; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") @@ -37,19 +47,19 @@ public class WcsSrgvMap extends BaseEntity /** 值 */ @Excel(name = "值") - private Long value; + private Integer value; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long ux; + private Integer ux; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long uy; + private Integer uy; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long uz; + private Integer uz; /** (0,0)表示墙体和墙体对应主通道 */ @Excel(name = "(0,0)表示墙体和墙体对应主通道") @@ -65,15 +75,15 @@ public class WcsSrgvMap extends BaseEntity /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long theRow; + private Integer theRow; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long theColumn; + private Integer theColumn; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long theLayer; + private Integer theLayer; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") @@ -81,15 +91,15 @@ public class WcsSrgvMap extends BaseEntity /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long plcRow; + private Integer plcRow; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long plcColumn; + private Integer plcColumn; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") - private Long plcLayer; + private Integer plcLayer; /** 仓库 */ @Excel(name = "仓库") @@ -99,241 +109,5 @@ public class WcsSrgvMap extends BaseEntity @Excel(name = "区域") private String spaceArea; - public void setGuid(String guid) - { - this.guid = guid; - } - public String getGuid() - { - return guid; - } - - public void setX(Long x) - { - this.x = x; - } - - public Long getX() - { - return x; - } - - public void setY(Long y) - { - this.y = y; - } - - public Long getY() - { - return y; - } - - public void setZ(Long z) - { - this.z = z; - } - - public Long getZ() - { - return z; - } - - public void setAxy(String axy) - { - this.axy = axy; - } - - public String getAxy() - { - return axy; - } - - public void setValue(Long value) - { - this.value = value; - } - - public Long getValue() - { - return value; - } - - public void setUx(Long ux) - { - this.ux = ux; - } - - public Long getUx() - { - return ux; - } - - public void setUy(Long uy) - { - this.uy = uy; - } - - public Long getUy() - { - return uy; - } - - public void setUz(Long uz) - { - this.uz = uz; - } - - public Long getUz() - { - return uz; - } - - public void setUxy(String uxy) - { - this.uxy = uxy; - } - - public String getUxy() - { - return uxy; - } - - public void setSpaceName(String spaceName) - { - this.spaceName = spaceName; - } - - public String getSpaceName() - { - return spaceName; - } - - public void setCargoSpaceId(String cargoSpaceId) - { - this.cargoSpaceId = cargoSpaceId; - } - - public String getCargoSpaceId() - { - return cargoSpaceId; - } - - public void setTheRow(Long theRow) - { - this.theRow = theRow; - } - - public Long getTheRow() - { - return theRow; - } - - public void setTheColumn(Long theColumn) - { - this.theColumn = theColumn; - } - - public Long getTheColumn() - { - return theColumn; - } - - public void setTheLayer(Long theLayer) - { - this.theLayer = theLayer; - } - - public Long getTheLayer() - { - return theLayer; - } - - public void setSiteId(String siteId) - { - this.siteId = siteId; - } - - public String getSiteId() - { - return siteId; - } - - public void setPlcRow(Long plcRow) - { - this.plcRow = plcRow; - } - - public Long getPlcRow() - { - return plcRow; - } - - public void setPlcColumn(Long plcColumn) - { - this.plcColumn = plcColumn; - } - - public Long getPlcColumn() - { - return plcColumn; - } - - public void setPlcLayer(Long plcLayer) - { - this.plcLayer = plcLayer; - } - - public Long getPlcLayer() - { - return plcLayer; - } - - public void setWarehouse(String warehouse) - { - this.warehouse = warehouse; - } - - public String getWarehouse() - { - return warehouse; - } - - public void setSpaceArea(String spaceArea) - { - this.spaceArea = spaceArea; - } - - public String getSpaceArea() - { - return spaceArea; - } - - @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("guid", getGuid()) - .append("x", getX()) - .append("y", getY()) - .append("z", getZ()) - .append("axy", getAxy()) - .append("value", getValue()) - .append("ux", getUx()) - .append("uy", getUy()) - .append("uz", getUz()) - .append("uxy", getUxy()) - .append("spaceName", getSpaceName()) - .append("remark", getRemark()) - .append("cargoSpaceId", getCargoSpaceId()) - .append("theRow", getTheRow()) - .append("theColumn", getTheColumn()) - .append("theLayer", getTheLayer()) - .append("siteId", getSiteId()) - .append("plcRow", getPlcRow()) - .append("plcColumn", getPlcColumn()) - .append("plcLayer", getPlcLayer()) - .append("warehouse", getWarehouse()) - .append("spaceArea", getSpaceArea()) - .toString(); - } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/RoadCacheService.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/RoadCacheService.java new file mode 100644 index 0000000..be913df --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/RoadCacheService.java @@ -0,0 +1,38 @@ +package com.ruoyi.bas.srgvmap.service; + + +import com.ruoyi.bas.srgvmap.domain.WcsSrgvMap; +import com.ruoyi.device.srgv.domain.DeviceSrgv; + +import java.util.List; +import java.util.Map; + +public interface RoadCacheService { + + + int[][] updateRoadCache(int floor, List grid ,int value); + + List findFullPath(int floor, int startX, int startY, int endX, int endY); + int[][] findFullMap(int floor, int startX, int startY, int endX, int endY); + int[][] findFullMap(int floor, int startX, int startY, int endX, int endY, DeviceSrgv srgvPlc); + + List findEmptyPath(int floor, int startX, int startY, int endX, int endY); + + int[][] findEmptyMap(int floor, int startX, int startY, int endX, int endY); + int[][] findEmptyMap(int floor, int startX, int startY, int endX, int endY, DeviceSrgv splc); + + Map getRoadSiteByArr(int floor); + + int[][] getRoadCache(int floor); + + Map getArrByRoadSite(int floor); + + List getRoadDataCache(int floor); + + + int[][] findMap(int floor); + + int[][] findFullMap(int floor, int startX, int startY, int endX, int endY,DeviceSrgv srgvPlc,List noSite); + + Map getSpaceDataCache(); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/impl/AgvPathProcessor.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/impl/AgvPathProcessor.java new file mode 100644 index 0000000..c9576b4 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/impl/AgvPathProcessor.java @@ -0,0 +1,506 @@ +package com.ruoyi.bas.srgvmap.service.impl; + +import com.ruoyi.bas.srgvmap.domain.WcsSrgvMap; +import com.ruoyi.bas.srgvmap.service.IWcsSrgvMapService; +import com.ruoyi.bas.srgvmap.service.RoadCacheService; +import com.ruoyi.device.srgv.domain.DeviceSrgv; +import com.ruoyi.device.srgv.service.IDeviceSrgvService; +import com.ruoyi.queue.srgv.service.IWcsSrgvQueueService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +@Component +public class AgvPathProcessor { + + @Autowired + private IDeviceSrgvService plcService; + + @Autowired + private IWcsSrgvQueueService wcsSagvQueueMapper; + + + @Autowired + private RoadCacheService roadCacheService; + + public void processNoSites(int[][] roadCache, int floor, List noSite) { + } + + public void processAgvPathInfo(int[][] ints, int floor) { + } + + public void processOnlineAgvSites(int[][] ints, int floor) { + } + + public void processOfflineAgvSites(int[][] ints, int floor) { + } + + /** + * 处理AGV路径信息和地图障碍 + *//* + public void processAgvPathInfo(int floor, List slots, IWcsSrgvMapService service) { + WcsSagvQueue wcsSagvQueue = new WcsSagvQueue(); + wcsSagvQueue.setTheFloor(floor + ""); + List wcsSagvQueues = wcsSagvQueueMapper.selectWcsSagvQueueList(wcsSagvQueue); + + if (wcsSagvQueues.isEmpty()) { + return; + } + + // 转为map,key为agvId ,value为pathInfo + Map agvPathMap = new HashMap<>(); + for (WcsSagvQueue queue : wcsSagvQueues) { + if (queue.getAgvId() != null && queue.getPathInfo() != null) { + agvPathMap.put(queue.getAgvId(), queue.getPathInfo()); + } + } + + if (agvPathMap.isEmpty()) { + return; + } + + // 获取Sagv位置 + List srgvPlcs = plcService.listSRGVPlcData(); + + // 处理路径信息,只保留当前站点及以后的路径 + updateAgvPathMap(agvPathMap, srgvPlcs); + + // 将路径拆分成站点,更新对应slot的value值 + updateSlotsWithValueFromPath(slots, agvPathMap); + } + + *//** + * 更新AGV路径映射,只保留当前站点及以后的路径 + *//* + private void updateAgvPathMap(Map agvPathMap, List srgvPlcs) { + for (SRGVPlc plc : srgvPlcs) { + com.ruoyi.plc.sagv.SRGVData agvData = plc.getAgvData(); + if (agvData != null && agvData.getAgvId() != null) { + String agvId = agvData.getAgvId(); + String currSite = agvData.getCurrSite(); + + // 如果这个agvId在agvPathMap中存在,且currSite不为空 + if (agvPathMap.containsKey(agvId) && currSite != null) { + String pathInfo = agvPathMap.get(agvId); + + // 处理路径信息,只保留当前站点及以后的路径 + if (pathInfo != null && !pathInfo.isEmpty()) { + String[] pathArray = pathInfo.split(","); + StringBuilder newPathBuilder = new StringBuilder(); + + boolean foundCurrentSite = false; + for (String site : pathArray) { + if (site.trim().equals(currSite.trim())) { + foundCurrentSite = true; + } + + if (foundCurrentSite) { + if (newPathBuilder.length() > 0) { + newPathBuilder.append(","); + } + newPathBuilder.append(site); + } + } + + // 如果找到了当前站点,更新路径信息 + if (foundCurrentSite) { + agvPathMap.put(agvId, newPathBuilder.toString()); + } + } + } + } + } + } + + *//** + * 根据路径信息更新slots的value值 + *//* + private void updateSlotsWithValueFromPath(List slots, Map agvPathMap) { + // 创建一个站点到AGV ID的映射 + Map siteToAgvMap = new HashMap<>(); + + for (Map.Entry entry : agvPathMap.entrySet()) { + String agvId = entry.getKey(); + String pathInfo = entry.getValue(); + + if (pathInfo != null && !pathInfo.isEmpty()) { + String[] sites = pathInfo.split(","); + for (String site : sites) { + String trimmedSite = site.trim(); + if (!trimmedSite.isEmpty()) { + siteToAgvMap.put(trimmedSite, agvId); + } + } + } + } + + // 遍历slots,更新匹配的元素 + for (WcsSrgvMap slot : slots) { + String siteId = slot.getSiteId(); + if (siteId != null && siteToAgvMap.containsKey(siteId)) { + String agvId = siteToAgvMap.get(siteId); + updateSlotValue(slot, agvId); + } + } + } + + *//** + * 处理在线AGV站点 + *//* + public void processOnlineAgvSites(List slots) { + List srgvPlcs = plcService.listSRGVPlcData(); + + // 创建siteId到slot的映射以提高查找性能 + Map siteSlotMap = new HashMap<>(); + for (WcsSrgvMap slot : slots) { + if (slot.getSiteId() != null) { + siteSlotMap.put(slot.getSiteId(), slot); + } + } + + for (SRGVPlc plc : srgvPlcs) { + com.ruoyi.plc.sagv.SRGVData agvData = plc.getAgvData(); + if (agvData != null) { + String currSite = agvData.getCurrSite(); + String agvId = agvData.getAgvId(); + + if (currSite != null && agvId != null && siteSlotMap.containsKey(currSite)) { + WcsSrgvMap slot = siteSlotMap.get(currSite); + updateSlotValue2(slot, agvId); + } + } + } + } + + *//** + * 处理离线AGV站点 + *//* + public void processOfflineAgvSites(int floor, List slots) { + WcsAgv wcsAgv = new WcsAgv(); + wcsAgv.setDefault01(floor + ""); + List wcsAgvs = wcsAgvMapper.selectWcsAgvList(wcsAgv); + + // 创建siteId到slot的映射以提高查找性能 + Map siteSlotMap = new HashMap<>(); + for (WcsSrgvMap slot : slots) { + if (slot.getSiteId() != null) { + siteSlotMap.put(slot.getSiteId(), slot); + } + } + + // 处理离线站点 + for (WcsAgv agv : wcsAgvs) { + String default02 = agv.getDefault02(); // 离线站点 + String agvId = String.valueOf(wcsAgv.getAgvId()); + + if (default02 != null && agvId != null && siteSlotMap.containsKey(default02)) { + WcsSrgvMap slot = siteSlotMap.get(default02); + updateSlotValue2(slot, agvId); + } + } + } + + *//** + * 更新slot的value值为(agvId + 100) + *//* + private void updateSlotValue(WcsSrgvMap slot, String agvId) { + try { + int agvIdNum = Integer.parseInt(agvId); + slot.setValue(agvIdNum + 100); + } catch (NumberFormatException e) { + // 如果agvId不是数字,设置默认值100 + // slot.setValue(100); + } + } + private void updateSlotValue2(WcsSrgvMap slot, String agvId) { + try { + int agvIdNum = Integer.parseInt(agvId); + slot.setValue(agvIdNum + 200); + } catch (NumberFormatException e) { + // 如果agvId不是数字,设置默认值100 + // slot.setValue(100); + } + } + + + *//* + * + * 剔除二维数组地图中不允许的站点 + * + * *//* + public void processAgvPathInfo(int[][] ints, int floor) { + + WcsSagvQueue wcsSagvQueue = new WcsSagvQueue(); + wcsSagvQueue.setTheFloor(floor + ""); + List wcsSagvQueues = wcsSagvQueueMapper.selectWcsSagvQueueList(wcsSagvQueue); + + if (wcsSagvQueues.isEmpty()) { + return; + } + + // 转为map,key为agvId ,value为pathInfo + Map agvPathMap = new HashMap<>(); + for (WcsSagvQueue queue : wcsSagvQueues) { + if (queue.getAgvId() != null && queue.getPathInfo() != null) { + agvPathMap.put(queue.getAgvId(), queue.getPathInfo()); + } + } + + if (agvPathMap.isEmpty()) { + return; + } + + // 获取Sagv位置 + List srgvPlcs = plcService.listSRGVPlcData(); + + // 处理路径信息,只保留当前站点及以后的路径 + updateAgvPathMap(agvPathMap, srgvPlcs); + // 将路径拆分成站点,更新对应slot的value值 + updateSlotsWithValueFromPath2(ints,agvPathMap,floor); + + + } + + public void processAgvPathInfo(int[][] ints, int floor,String agvId) { + + WcsSagvQueue wcsSagvQueue = new WcsSagvQueue(); + wcsSagvQueue.setTheFloor(floor + ""); + List wcsSagvQueueList = wcsSagvQueueMapper.selectWcsSagvQueueList(wcsSagvQueue); + + List wcsSagvQueues = wcsSagvQueueList.stream().filter(queue -> !Objects.equals(queue.getAgvId(), agvId)).collect(Collectors.toList()); + + if (wcsSagvQueues.isEmpty()) { + return; + } + + // 转为map,key为agvId ,value为pathInfo + Map agvPathMap = new HashMap<>(); + for (WcsSagvQueue queue : wcsSagvQueues) { + if (queue.getAgvId() != null && queue.getPathInfo() != null) { + agvPathMap.put(queue.getAgvId(), queue.getPathInfo()); + } + } + + if (agvPathMap.isEmpty()) { + return; + } + + // 获取Sagv位置 + List srgvPlcs = plcService.listSRGVPlcData(); + + // 处理路径信息,只保留当前站点及以后的路径 + updateAgvPathMap(agvPathMap, srgvPlcs); + // 将路径拆分成站点,更新对应slot的value值 + updateSlotsWithValueFromPath2(ints,agvPathMap,floor); + + + } + + private void updateSlotsWithValueFromPath2(int[][] arrMap, Map agvPathMap, int floor) { + // 在循环前获取一次站点坐标映射 + Map arrByRoadSite = roadCacheService.getArrByRoadSite(floor); + + for (Map.Entry entry : agvPathMap.entrySet()) { + String agvId = entry.getKey(); + String pathInfo = entry.getValue(); + + if (pathInfo != null && !pathInfo.isEmpty()) { + String[] sites = pathInfo.split(","); + for (String site : sites) { + String trimmedSite = site.trim(); + if (!trimmedSite.isEmpty()) { + int[] siteArr = arrByRoadSite.get(trimmedSite); // 格式{1,2,3}代表排列层 + + // 添加空值检查 + if (siteArr != null && siteArr.length >= 2) { + arrMap[siteArr[0]][siteArr[1]] = 0; // 建对应坐标更新为0,代表障碍物 + } + } + } + } + } + } + + *//** + * 处理在线AGV站点 + *//* + public void processOnlineAgvSites(int[][] arrMap, int floor) { + List srgvPlcs = plcService.listSRGVPlcData(); + + // 过滤出同层的当前站点,并处理空值情况 + List collect = srgvPlcs.stream() + .filter(plc -> plc.getAgvData() != null && plc.getAgvData().getCurrSite() != null) + .filter(plc -> floor == plc.getLayer()) + .map(plc -> plc.getAgvData().getCurrSite()) + .collect(Collectors.toList()); + + if (!collect.isEmpty()) { + // 在循环前获取一次站点坐标映射 + Map arrByRoadSite = roadCacheService.getArrByRoadSite(floor); + + for (String site : collect) { + String trimmedSite = site.trim(); + if (!trimmedSite.isEmpty()) { + int[] siteArr = arrByRoadSite.get(trimmedSite); // 格式{1,2,3}代表排列层 + + // 添加空值检查 + if (siteArr != null && siteArr.length >= 2) { + arrMap[siteArr[0]][siteArr[1]] = 0; // 对应坐标更新为0,代表障碍物 + } + } + } + } + } + + public void processOnlineAgvSites(int[][] arrMap, int floor,String selfSite) { + List srgvPlcs = plcService.listSRGVPlcData(); + + // 过滤出同层的当前站点,并处理空值情况 + List collect = srgvPlcs.stream() + .filter(plc -> plc.getAgvData() != null && plc.getAgvData().getCurrSite() != null) + .filter(plc -> floor == plc.getLayer()) + .filter(p ->!Objects.equals(p.getAgvData().getCurrSite(),selfSite)) + .map(plc -> plc.getAgvData().getCurrSite()) + .collect(Collectors.toList()); + + if (!collect.isEmpty()) { + // 在循环前获取一次站点坐标映射 + Map arrByRoadSite = roadCacheService.getArrByRoadSite(floor); + + for (String site : collect) { + String trimmedSite = site.trim(); + if (!trimmedSite.isEmpty()) { + int[] siteArr = arrByRoadSite.get(trimmedSite); // 格式{1,2,3}代表排列层 + + // 添加空值检查 + if (siteArr != null && siteArr.length >= 2) { + arrMap[siteArr[0]][siteArr[1]] = 0; // 对应坐标更新为0,代表障碍物 + } + } + } + } + } + + *//* + * + * 处理在线AGV站点,不包含自己 + * *//* + public void processOnlineAgvSitesNoSelf(int[][] arrMap, Integer floor, String srcSite) { + + List srgvPlcs = plcService.listSRGVPlcData(); + + // 过滤出同层的当前站点,并处理空值情况 + List collect = srgvPlcs.stream() + .filter(plc -> plc.getAgvData() != null && plc.getAgvData().getCurrSite() != null) + .filter(plc -> floor == plc.getLayer()) + .map(plc -> plc.getAgvData().getCurrSite()) + .collect(Collectors.toList()); + + if (!collect.isEmpty()) { + // 在循环前获取一次站点坐标映射 + Map arrByRoadSite = roadCacheService.getArrByRoadSite(floor); + + for (String site : collect) { + String trimmedSite = site.trim(); + if (!trimmedSite.isEmpty() && !Objects.equals(srcSite, trimmedSite)) { + int[] siteArr = arrByRoadSite.get(trimmedSite); // 格式{1,2,3}代表排列层 + + // 添加空值检查 + if (siteArr != null && siteArr.length >= 2) { + arrMap[siteArr[0]][siteArr[1]] = 0; // 对应坐标更新为0,代表障碍物 + } + } + } + } + } + + + + *//** + * 处理离线AGV站点 + *//* + public void processOfflineAgvSites(int[][] arrMap, int floor) { + WcsAgv wcsAgv = new WcsAgv(); + wcsAgv.setDefault01(floor + ""); + List wcsAgvs = wcsAgvMapper.selectWcsAgvList(wcsAgv); + // 根据站点获取二维数组坐标 + Map arrByRoadSite = roadCacheService.getArrByRoadSite(floor); + // 处理离线站点 + for (WcsAgv agv : wcsAgvs) { + // 添加空值检查 + if (agv != null && agv.getDefault02() != null && agv.getAgvId() != null) { + String default02 = agv.getDefault02(); // 离线站点 + String agvId = String.valueOf(wcsAgv.getAgvId()); + + + String trimmedSite = default02.trim(); + + if (!trimmedSite.isEmpty()) { + int[] siteArr = arrByRoadSite.get(trimmedSite); + + // 添加空值检查 + if (siteArr != null && siteArr.length >= 2) { + arrMap[siteArr[0]][siteArr[1]] = 0; // 对应坐标更新为0,代表障碍物 + } + } + } + } + } + + + *//* + * 离线站点占用目标的也排除 + * *//* + public void processOfflineAgvSites(int[][] arrMap, int floor,List tarSite) { + WcsAgv wcsAgv = new WcsAgv(); + wcsAgv.setDefault01(floor + ""); + List wcsAgvs = wcsAgvMapper.selectWcsAgvList(wcsAgv); + // 根据站点获取二维数组坐标 + Map arrByRoadSite = roadCacheService.getArrByRoadSite(floor); + // 处理离线站点 + for (WcsAgv agv : wcsAgvs) { + // 添加空值检查 + if (agv != null && agv.getDefault02() != null && agv.getAgvId() != null) { + String default02 = agv.getDefault02(); // 离线站点 + String agvId = String.valueOf(wcsAgv.getAgvId()); + + + String trimmedSite = default02.trim(); + + if (!trimmedSite.isEmpty()) { + int[] siteArr = arrByRoadSite.get(trimmedSite); + + // 添加空值检查 + if (siteArr != null && siteArr.length >= 2) { + arrMap[siteArr[0]][siteArr[1]] = 0; // 对应坐标更新为0,代表障碍物 + } + + //排除目标 + tarSite.remove(trimmedSite); + } + } + } + } + + + public void processNoSites(int[][] roadCache, int floor,List sites) { + // 根据站点获取二维数组坐标 + Map arrByRoadSite = roadCacheService.getArrByRoadSite(floor); + + for (String site : sites) { + if (!site.isEmpty()) { + int[] siteArr = arrByRoadSite.get(site); + + // 添加空值检查 + if (siteArr != null && siteArr.length >= 2) { + roadCache[siteArr[0]][siteArr[1]] = 0; // 对应坐标更新为0,代表障碍物 + } + } + } + }*/ +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/impl/RoadCacheServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/impl/RoadCacheServiceImpl.java new file mode 100644 index 0000000..fdc2f36 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/srgvmap/service/impl/RoadCacheServiceImpl.java @@ -0,0 +1,311 @@ +package com.ruoyi.bas.srgvmap.service.impl; + +import cn.hutool.core.convert.Convert; +import com.ruoyi.bas.srgvmap.domain.WcsSrgvMap; +import com.ruoyi.bas.srgvmap.mapper.WcsSrgvMapMapper; +import com.ruoyi.bas.srgvmap.service.RoadCacheService; +import com.ruoyi.device.srgv.domain.DeviceSrgv; +import com.ruoyi.schedule.plcRead.srgv.roadUtil.PathFinder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.*; + + +@Service +public class RoadCacheServiceImpl implements RoadCacheService { + + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + + @Autowired + private WcsSrgvMapMapper wcsSrgvMapMapper; + + @Autowired + private CacheManager cacheManager; + + + @Autowired + private RoadCacheService selfProxy; // 注入代理对象 + + + @Autowired + private AgvPathProcessor agvPathProcessor; + + + /* + * + * + * */ + @Autowired + @Cacheable(value = "CSpaceDataCache" ,key = "'CSpaceDataCacheKey_'") + public Map getSpaceDataCache() { + log.info("从数据库获取初始化地图数据"); + + WcsSrgvMap wcsSrgvMap = new WcsSrgvMap(); + List wcsSrgvMaps = wcsSrgvMapMapper.selectWcsSrgvMapList(wcsSrgvMap); + //将集合转为map, + Map siteMap = new HashMap<>(); + + for (WcsSrgvMap srgvMap : wcsSrgvMaps) { + String siteId = srgvMap.getSiteId(); + String warehouse = srgvMap.getWarehouse(); + if(!Objects.equals(siteId,"000")){ + siteMap.put(siteId,warehouse); + } + } + + + return siteMap; + } + + + @Cacheable(value = "RoadDataCache" ,key = "'RoadDataCacheKey_floor_' +#floor") + @Override + public List getRoadDataCache(int floor) { + log.info("从数据库获取初始化地图"); + + WcsSrgvMap wcsSrgvMap1 = new WcsSrgvMap(); + wcsSrgvMap1.setUz(floor); + List wcsSrgvMaps = wcsSrgvMapMapper.selectWcsSrgvMapList(wcsSrgvMap1); + + return wcsSrgvMaps; + } + + /* + * + * 每层二维地图 + * */ + @Override + @Cacheable(value = "RoadCache" ,key = "'RoadCacheKey_floor_' +#floor") + public int[][] getRoadCache(int floor) { + + List roadDataCache = selfProxy.getRoadDataCache(floor); + + //集合转为二维数组 + int[][] grid = new int[30][137]; + for (WcsSrgvMap roadMap : roadDataCache) { + grid[roadMap.getX().intValue()][roadMap.getY().intValue()] = roadMap.getValue().intValue(); + } + + return grid; + } + + + /* + * + * 每层 站点与二维数组关系 + * */ + @Override + @CachePut(value = "SiteCache" ,key = "'SiteKey_floor_' +#floor") + public Map getArrByRoadSite(int floor) { + List roadDataCache = selfProxy.getRoadDataCache(floor); + + //将集合转为map,key为siteId,value为x,y + Map siteMap = new HashMap<>(); + for (WcsSrgvMap map : roadDataCache) { + siteMap.put(map.getSiteId(), new int[]{map.getX(), map.getY(),floor}); + } + + return siteMap; + } + + /* + * + * + * */ + @Override + @CachePut(value = "ArrCache" ,key = "'ArrKey_floor_' +#floor") + public Map getRoadSiteByArr(int floor) { + List roadDataCache = selfProxy.getRoadDataCache(floor); + + //将集合转为map,key为x,y,value为siteId + Map siteMap = new HashMap<>(); + for (WcsSrgvMap map : roadDataCache) { + siteMap.put(map.getX()+","+map.getY(), map.getSiteId()); + } + + return siteMap; + } + + + + //更新地图 + @Override + @CachePut(value = "RoadCache" ,key = "'RoadCacheKey_floor_' +#floor") + public int[][] updateRoadCache(int floor, List grid,int value) { + + + int[][] roadCache = selfProxy.getRoadCache(floor); + + for (int[] ints : grid) { + roadCache[ints[0]][ints[1]] = value; + } + + return roadCache; + } + + + //获取载货路径 + @Override + public List findFullPath(int floor, int startX, int startY, int endX, int endY) { + + int[][] grid = selfProxy.getRoadCache(floor); + + //对二维数组 进行深拷贝 + int[][] roadCache = Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new); + + //剔除不允许站点 + extractInflectionPoints(roadCache,floor); + + // 调用路径规划算法 + return PathFinder.findShortestPathFrom2To2Or1(roadCache,startX,startY,endX,endY); + } + + + @Override + public int[][] findFullMap(int floor, int startX, int startY, int endX, int endY) { + + int[][] grid = selfProxy.getRoadCache(floor); + + //对二维数组 进行深拷贝 + int[][] roadCache = Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new); + + //剔除不允许站点 + extractInflectionPoints(roadCache,floor); + + // 调用路径规划算法 + return roadCache; + } + + @Override + public int[][] findFullMap(int floor, int startX, int startY, int endX, int endY,DeviceSrgv splc) { + + int[][] grid = selfProxy.getRoadCache(floor); + + //对二维数组 进行深拷贝 + int[][] roadCache = Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new); + + //剔除不允许站点(不包含自己) + extractInflectionPoints(roadCache,floor,splc); + + // 调用路径规划算法 + return roadCache; + } + + @Override + public int[][] findFullMap(int floor, int startX, int startY, int endX, int endY,DeviceSrgv splc,List noSite) { + + int[][] grid = selfProxy.getRoadCache(floor); + + //对二维数组 进行深拷贝 + int[][] roadCache = Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new); + + //剔除不允许站点(不包含自己) + extractInflectionPoints(roadCache,floor,splc); + + //将地图 roadCache 中的 所有站点noSite排除掉 + agvPathProcessor.processNoSites(roadCache,floor,noSite); + + // 调用路径规划算法 + return roadCache; + } + + + //获取空载路径 + @Override + public List findEmptyPath(int floor, int startX, int startY, int endX, int endY) { + + + int[][] grid = selfProxy.getRoadCache(floor); + + //对二维数组 进行深拷贝 + int[][] roadCache = Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new); + + //剔除不允许站点 + extractInflectionPoints(roadCache,floor); + + List shortestPath = PathFinder.findShortestPath(grid, startX, startY, endX, endY); + return shortestPath; + } + + + @Override + public int[][] findEmptyMap(int floor, int startX, int startY, int endX, int endY, DeviceSrgv splc) { + + + int[][] grid = selfProxy.getRoadCache(floor); + + //对二维数组 进行深拷贝 + int[][] roadCache = Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new); + + //剔除不允许站点(不包含自己) + extractInflectionPoints(roadCache,floor,splc); + + + return roadCache; + } + + @Override + public int[][] findEmptyMap(int floor, int startX, int startY, int endX, int endY) { + + + int[][] grid = selfProxy.getRoadCache(floor); + + //对二维数组 进行深拷贝 + int[][] roadCache = Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new); + + //剔除不允许站点 + extractInflectionPoints(roadCache,floor); + + + return roadCache; + } + + /* + * 剔除不可用站点,并返回新地图 + * + * */ + private int[][] extractInflectionPoints(int[][] ints,int floor){ + + + //所有车锁定路径 + agvPathProcessor.processAgvPathInfo(ints,floor); + //所有在线车当前站点 + agvPathProcessor.processOnlineAgvSites(ints,floor); + //所有离线车站点 + agvPathProcessor.processOfflineAgvSites(ints,floor); + + return ints; + } + + private int[][] extractInflectionPoints(int[][] ints, int floor, DeviceSrgv splc){ + + String agvId = String.valueOf(splc.getDeviceId()); + String currSite = splc.getCurrSite(); + //所有车锁定路径 + agvPathProcessor.processAgvPathInfo(ints,floor); + //所有在线车当前站点 + agvPathProcessor.processOnlineAgvSites(ints,floor); + //所有离线车站点 + agvPathProcessor.processOfflineAgvSites(ints,floor); + + return ints; + } + + @Override + public int[][] findMap(int floor) { + int[][] grid = selfProxy.getRoadCache(floor); + + //对二维数组 进行深拷贝 + int[][] roadCache = Arrays.stream(grid).map(int[]::clone).toArray(int[][]::new); + + return roadCache; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/srgv/BaseSRgvThread.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/srgv/BaseSRgvThread.java index bd9164b..42348da 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/srgv/BaseSRgvThread.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/srgv/BaseSRgvThread.java @@ -6,24 +6,29 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.util.StrUtil; import com.ruoyi.bas.port.domain.WcsPort; import com.ruoyi.bas.port.service.IWcsPortService; +import com.ruoyi.bas.srgvmap.service.RoadCacheService; import com.ruoyi.common.domain.SendData2; import com.ruoyi.device.srgv.domain.DeviceSrgv; -import com.ruoyi.job.charg.domain.SrgvChargingJob; +import com.ruoyi.device.ssj.domain.DeviceSsj; import com.ruoyi.job.charg.service.ISrgvChargingJobService; +import com.ruoyi.job.domain.MydoJob; +import com.ruoyi.job.service.IMydoJobService; import com.ruoyi.queue.srgv.domain.WcsSrgvQueue; import com.ruoyi.queue.srgv.domain.WcsSrgvQueueFinish; import com.ruoyi.queue.srgv.service.IWcsSrgvQueueFinishService; import com.ruoyi.queue.srgv.service.IWcsSrgvQueueService; import com.ruoyi.schedule.plcRead.srgv.PlcSrgvRead; import com.ruoyi.schedule.plcRead.srgv.roadUtil.PathFinder; +import com.ruoyi.schedule.plcRead.ssj.PlcSsjRead; import lombok.extern.slf4j.Slf4j; import java.util.*; import java.util.stream.Collectors; +import static com.ruoyi.schedule.plcRead.srgv.PlcSrgvRead.deviceSrgvMap; + @Slf4j public class BaseSRgvThread implements Runnable, SRgvThreadInterface { @@ -39,6 +44,9 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { public ISrgvChargingJobService srgvChargingJobMapper; + public IMydoJobService mydoJobService; + + public RoadCacheService roadCacheService; public void init() { @@ -58,6 +66,13 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { for (int i = 1; i <= 8; i++) { sRgvTask(deviceSrgv, i); } + + createCarInQueue(); + + callEmptySRgv(); + + createCarOutQueue(); + } else { log.error("堆垛机设备为空"); } @@ -88,172 +103,135 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { //小车发送任务 sendTask(deviceSrgv, floor); - //小车充电任务 - inCharging(deviceSrgv, floor); - - //小车离开充电桩 - outCharging(deviceSrgv, floor); } + /** - * 小车离开充电桩 + * 生成出库小车队列 */ - private void outCharging(DeviceSrgv deviceSrgv, int floor) { - SrgvChargingJob wcsChargingJob = new SrgvChargingJob(); - wcsChargingJob.setJobType("2");//离开充电 - //wcsChargingJob.setChargingStatus("0");//未接通 - List wcsChargingJobs = wcsChargingJobMapper.selectWcsChargingJobList(wcsChargingJob); + private void createCarOutQueue() { + MydoJob param = new MydoJob(); + param.setInOut("2"); + for (MydoJob mydoJob : mydoJobService.selectInOrOutMydoJobList(param)) { + if ("0".equals(mydoJob.getExecutionPhase())) { + //生成任务 + String roadwayId = mydoJob.getRoadwayId(); + //判断1层是否存在空车 + DeviceSrgv currSRgv = null; + for (String key : deviceSrgvMap.keySet()) { + DeviceSrgv deviceSrgv = deviceSrgvMap.get(key); + if (deviceSrgv.getCurrFloor().equals(Convert.toInt(roadwayId)) && deviceSrgv.getStatus() == 1) { + currSRgv = deviceSrgv; + } + } + //任务阶段是在入库ssj取货位置 + if (currSRgv == null) { + //无空车 + //修改任务阶段 为入库无空车 + //mydoJob.setTaskNo(Convert.toStr(ssj.getTaskNo())); + mydoJob.setStatus("3"); + mydoJob.setStartTime(DateUtil.formatDateTime(new Date())); + mydoJob.setExecutionPhase("21"); + mydoJobService.updateMydoJob(mydoJob); + } else { + //有空车 + //生成取货队列 + WcsSrgvQueue wcsSagvQueue = new WcsSrgvQueue(); + wcsSagvQueue.setGuid(IdUtil.simpleUUID()); + wcsSagvQueue.setTaskType("1"); + wcsSagvQueueMapper.insertWcsSrgvQueue(wcsSagvQueue); + //mydoJob.setTaskNo(Convert.toStr(ssj.getTaskNo())); + mydoJob.setStatus("3"); + mydoJob.setStartTime(DateUtil.formatDateTime(new Date())); + //取货 + mydoJob.setExecutionPhase("02"); + mydoJobService.updateMydoJob(mydoJob); - for (SrgvChargingJob chargingJob : wcsChargingJobs) { - String chargingStatus = chargingJob.getChargingStatus(); + } + } + } - String agvId = chargingJob.getAgvId(); - String chargingSite = chargingJob.getChargingSite();//充电桩站点 + } - String startDate = chargingJob.getStartDate(); + /** + * 呼叫空车 + */ + private void callEmptySRgv() { + MydoJob param = new MydoJob(); + param.setStatus("3"); + //入库无空车 + param.setExecutionPhase("11"); + for (MydoJob mydoJob : mydoJobService.selectMydoJobList(param)) { + String roadwayId = mydoJob.getRoadwayId(); + boolean existsEmptySRgv = false; + //校验对应楼层是否存在空车 + for (String key : deviceSrgvMap.keySet()) { + DeviceSrgv deviceSrgv = deviceSrgvMap.get(key); + if (deviceSrgv.getStatus() == 1 && deviceSrgv.getCurrFloor().equals(Convert.toInt(roadwayId))) { + //存在则跳过 + existsEmptySRgv = true; + break; + } + } - List rgvs = srgvPlcs.stream().filter(srgv -> Objects.equals(srgv.getAgvData().getAgvId(), agvId) && srgv.getAgvData().getStatus() != 3).collect(Collectors.toList()); - if ("1".equals(chargingStatus)) { - if (rgvs.size() > 0) { - SRGVPlc srgvPlc = rgvs.get(0); - String currSite = srgvPlc.getAgvData().getCurrSite(); - if (!Objects.equals(currSite, chargingSite)) { - wcsChargingJobMapper.deleteWcsChargingJobByGuid(chargingJob.getGuid());//删除任务 + } + } + + /** + * 生成入库小车队列 + */ + private void createCarInQueue() { + WcsPort param = new WcsPort(); + param.setPortRegion("1"); + param.setPortType("4"); + param.setSpare2("0"); + param.setStatus("1"); + List wcsPorts = wcsPortService.selectWcsPortList(param); + if (CollUtil.isNotEmpty(wcsPorts)) { + for (WcsPort wcsPort : wcsPorts) { + DeviceSsj ssj = PlcSsjRead.deviceSsjMap.get(wcsPort.getPortCode()); + if (ssj.getRkqq() == 1 && ssj.getDw() == 1 && ssj.getTaskNo() > 0) { + //判断1层是否存在空车 + DeviceSrgv currSRgv = null; + for (String key : deviceSrgvMap.keySet()) { + DeviceSrgv deviceSrgv = deviceSrgvMap.get(key); + if (deviceSrgv.getCurrFloor() == 1 && deviceSrgv.getStatus() == 1) { + currSRgv = deviceSrgv; + } + } + MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(ssj.getTaskNo())); + if ("01".equals(mydoJob.getExecutionPhase())) { + //任务阶段是在入库ssj取货位置 + if (currSRgv == null) { + //无空车 + //修改任务阶段 为入库无空车 + mydoJob.setTaskNo(Convert.toStr(ssj.getTaskNo())); + mydoJob.setStatus("3"); + mydoJob.setStartTime(DateUtil.formatDateTime(new Date())); + mydoJob.setExecutionPhase("11"); + mydoJobService.updateMydoJob(mydoJob); + } else { + //有空车 + //生成取货队列 + WcsSrgvQueue wcsSagvQueue = new WcsSrgvQueue(); + wcsSagvQueue.setGuid(IdUtil.simpleUUID()); + wcsSagvQueue.setTaskType("1"); + wcsSagvQueueMapper.insertWcsSrgvQueue(wcsSagvQueue); + mydoJob.setTaskNo(Convert.toStr(ssj.getTaskNo())); + mydoJob.setStatus("3"); + mydoJob.setStartTime(DateUtil.formatDateTime(new Date())); + //取货 + mydoJob.setExecutionPhase("02"); + mydoJobService.updateMydoJob(mydoJob); + + } } - } else { - //删除 } - continue; } - - //是否已经有任务 - WcsSrgvQueue wcsSagvQueue = new WcsSrgvQueue(); - wcsSagvQueue.setAgvId(agvId); - List wcsSagvQueues = wcsSagvQueueMapper.selectWcsSrgvQueueList(wcsSagvQueue); - if (wcsSagvQueues.size() > 0) { - - //时间大于30分钟,可以删除 - boolean overHalfHour = TimeCompareUtil.isOverHalfHour(startDate, 30); - if (overHalfHour) { - wcsChargingJobMapper.deleteWcsChargingJobByGuid(chargingJob.getGuid());//删除任务 - } - - - continue; - } - - - - String currSite = deviceSrgv.getCurrSite(); - - String endSite = null; - - if (!Objects.equals(currSite, chargingSite)) { - //已经在等待点 - srgvChargingJobMapper.deleteSrgvChargingJobByGuid(chargingJob.getGuid());//删除任务 - } - - - - - //获取所有待机点 - List collect = waitManager.listWcsFreeWait(floor).stream().map(wf -> wf.getSiteAddress()).collect(Collectors.toList()); - - //agv不在当前站点,不在待机点添加 - if (endSite != null && !Objects.equals(currSite, endSite) && !collect.contains(currSite)) { - - //生成去充电的任务 - WcsSrgvQueue wsq = new WcsSrgvQueue(); - wsq.setGuid(IdUtil.fastSimpleUUID()); - - /* HashMap map = new HashMap<>(); - map.put("type", "10"); - wcsIdMapper.getTask(map); - String taskNo = map.get("result");*/ - - wsq.setTaskNo(""); - wsq.setTaskType("1"); - wsq.setPriority(10L); - wsq.setCargo("2"); - wsq.setIssued("0"); - wsq.setPathInfo(null); - wsq.setExecutionStatus("1"); - wsq.setCargoPickSite(currSite); - wsq.setCargoPlaceSite(endSite); - wsq.setStartSite(currSite); - wsq.setEndSite(endSite); - wsq.setTheFloor(floor + ""); - wsq.setTrunPath(null); - wsq.setUpDownSite(currSite); - wsq.setCreateDate(DateUtil.now()); - wsq.setDefault06(chargingJob.getGuid()); - - wsq.setAgvId(agvId); - wsq.setDefault02("4");//点到点任务 - - wcsSagvQueueMapper.insertWcsSrgvQueue(wsq); - - - } - } } - /** - * 小车充电任务 - */ - private void inCharging(DeviceSrgv deviceSrgv, int floor) { - SrgvChargingJob wcsChargingJob = new SrgvChargingJob(); - wcsChargingJob.setJobType("1");//去充电任务 - wcsChargingJob.setJobStatus("1"); - //wcsChargingJob.setChargingStatus("1");//未接通 - List wcsChargingJobs = srgvChargingJobMapper.selectSrgvChargingJobList(wcsChargingJob); - for (SrgvChargingJob chargingJob : wcsChargingJobs) { - String agvId = chargingJob.getAgvId(); - String chargingSite = chargingJob.getChargingSite();//充电桩站点 - - String currSite = deviceSrgv.getCurrSite(); - if (!Objects.equals(currSite, chargingSite)) { - //是否已经有任务 - WcsSrgvQueue wcsSagvQueue = new WcsSrgvQueue(); - wcsSagvQueue.setAgvId(agvId); - List wcsSagvQueues = wcsSagvQueueMapper.selectWcsSrgvQueueList(wcsSagvQueue); - if (wcsSagvQueues.size() == 0) { - //生成去充电的任务 - WcsSrgvQueue wsq = new WcsSrgvQueue(); - wsq.setGuid(IdUtil.fastSimpleUUID()); - - /*HashMap map = new HashMap<>(); - map.put("type", "6"); - wcsIdMapper.getTask(map); - String taskNo = map.get("result");*/ - - wsq.setTaskNo(""); - wsq.setTaskType("1"); - wsq.setPriority(10L); - wsq.setCargo("2"); - wsq.setIssued("0"); - wsq.setPathInfo(null); - wsq.setExecutionStatus("1"); - wsq.setCargoPickSite(currSite); - wsq.setCargoPlaceSite(chargingSite); - wsq.setStartSite(currSite); - wsq.setEndSite(chargingSite); - wsq.setTheFloor(floor + ""); - wsq.setTrunPath(null); - wsq.setUpDownSite(currSite); - wsq.setCreateDate(DateUtil.now()); - wsq.setDefault06(chargingJob.getGuid()); - - wsq.setAgvId(agvId); - wsq.setDefault02("3");//3充电 - - wcsSagvQueueMapper.insertWcsSrgvQueue(wsq); - } - } - } - } /** * 小车发送任务 */ @@ -266,50 +244,25 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { return; } for (WcsSrgvQueue wcsSrgvQueue : wcsSrgvQueues) { - processPendingTask(wcsSrgvQueue, deviceSrgv, floor); - } - - } - - /** - * 处理队列下发 - */ - private void processPendingTask(WcsSrgvQueue wcsSrgvQueue, DeviceSrgv deviceSrgv, int floor) { - String agvId = wcsSrgvQueue.getAgvId(); - if (agvId.equals(Convert.toStr(deviceSrgv.getDeviceId())) && deviceSrgv.getWorkMode() == 5 && deviceSrgv.getAllowSend() == 1) { - String startSite = wcsSrgvQueue.getStartSite(); - String endSite = wcsSrgvQueue.getEndSite(); - String currSite = deviceSrgv.getCurrSite(); - - if (isSameFloor(startSite, endSite)) { - if (StrUtil.isNotEmpty(endSite)) { - handleUnspecifiedDestination(wcsSrgvQueue, startSite, floor, deviceSrgv); + String agvId = wcsSrgvQueue.getAgvId(); + if (agvId.equals(Convert.toStr(deviceSrgv.getDeviceId())) && deviceSrgv.getWorkMode() == 5 && deviceSrgv.getAllowSend() == 1) { + String startSite = wcsSrgvQueue.getStartSite(); + String endSite = wcsSrgvQueue.getEndSite(); + String currSite = deviceSrgv.getCurrSite(); + //判断是否可以下发任务 + if ("0".equals(wcsSrgvQueue.getIssued()) && deviceSrgv.getStatus() == 1) { + //判断小车是否在起始点 + if (currSite.equals(startSite)) { + //小车在起始点 + sendMainTask(deviceSrgv, wcsSrgvQueue, currSite, endSite, floor); + } else { + //小车不在起始点 + sendPointToPointTask(deviceSrgv, wcsSrgvQueue, currSite, startSite, floor); + } } } - - - //判断是否可以下发任务 - if ("0".equals(wcsSrgvQueue.getIssued()) && deviceSrgv.getStatus() == 1) { - handleUnissuedTask(deviceSrgv, wcsSrgvQueue, currSite, startSite, endSite, floor); - } } - - } - - /** - * 处理未下发的任务 - */ - private void handleUnissuedTask(DeviceSrgv deviceSrgv, WcsSrgvQueue wcsSrgvQueue, String currSite, String startSite, String endSite, int floor) { - - //判断小车是否在起始点 - if (currSite.equals(startSite)) { - //小车在起始点 - sendMainTask(deviceSrgv, wcsSrgvQueue, currSite, endSite, floor); - } else { - //小车不在起始点 - sendPointToPointTask(deviceSrgv, wcsSrgvQueue, currSite, startSite, floor); - } } /** @@ -320,7 +273,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { Map arrByRoadSite = roadCacheService.getArrByRoadSite(floor); //获取空载地图 - int[][] emptyMap = roadCacheService.findEmptyMap(floor, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1], splc); + int[][] emptyMap = roadCacheService.findEmptyMap(floor, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1], deviceSrgv); //计算最短路径 List shortestPath = PathFinder.findShortestPath(emptyMap, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1]); @@ -462,7 +415,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { int[][] fullMap = null; if (noTar0 == null && noTar1 == null) { - fullMap = roadCacheService.findFullMap(floor, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1], splc); + fullMap = roadCacheService.findFullMap(floor, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1], deviceSrgv); } else { List strings = new ArrayList<>();//排除站点 if (noTar0 != null) { @@ -472,7 +425,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { strings.add(noTar1); } - fullMap = roadCacheService.findFullMap(floor, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1], splc, strings); + fullMap = roadCacheService.findFullMap(floor, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1], deviceSrgv, strings); } //计算最短路径 @@ -590,7 +543,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { //获取当前地图 Map arrByRoadSite = roadCacheService.getArrByRoadSite(floor); //获取空载地图 - int[][] emptyMap = roadCacheService.findEmptyMap(floor, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1], splc); + int[][] emptyMap = roadCacheService.findEmptyMap(floor, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1], deviceSrgv); //计算最短路径 List shortestPath = PathFinder.findShortestPath(emptyMap, arrByRoadSite.get(startSite)[0], arrByRoadSite.get(startSite)[1], arrByRoadSite.get(endSite)[0], arrByRoadSite.get(endSite)[1]); @@ -818,7 +771,10 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { param.setPortCode(currSite); List wcsPorts = wcsPortService.selectWcsPortList(param); if (CollUtil.isNotEmpty(wcsPorts)){ - + WcsPort wcsPort = wcsPorts.get(0); + if ("2".equals(wcsPort.getPortType()) || "1".equals(wcsPort.getPortType())) { + return true; + } } } return false; @@ -839,10 +795,10 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface { param.setTaskNo(Convert.toStr(taskNo)); param.setIssued("0"); param.setAgvId(String.valueOf(deviceId)); - List wcsSagvQueues = wcsSagvQueueMapper.selectWcsSrgvQueueList(param); + List wcsSrgvQueues = wcsSagvQueueMapper.selectWcsSrgvQueueList(param); - if (CollUtil.isNotEmpty(wcsSagvQueues)){ - WcsSrgvQueue wcsSrgvQueue = wcsSagvQueues.get(0); + if (CollUtil.isNotEmpty(wcsSrgvQueues)) { + WcsSrgvQueue wcsSrgvQueue = wcsSrgvQueues.get(0); String startSite = wcsSrgvQueue.getStartSite(); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/tsj/TsjThread.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/tsj/TsjThread.java index 7c105f6..17c1b69 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/tsj/TsjThread.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/tsj/TsjThread.java @@ -26,6 +26,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.Date; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; @Slf4j public class TsjThread implements Runnable { @@ -97,61 +98,14 @@ public class TsjThread implements Runnable { sendTsj(); } - createLoadQueue(tsj); + createQueue(tsj); - createUnLoadQueue(tsj); - - } - - /** - * 创建装车队列 - */ - private void createUnLoadQueue(DeviceTsj tsj) { - //根据提升机入口点位循环如果提升机在某个占用的入口点位楼层,则锁定提升机否则生成提升机队列 - List tsjDeviceExecutionQueues = tsjDeviceExecutionQueueService.selectTsjDeviceExecutionQueueList(new TsjDeviceExecutionQueue()); - if (CollUtil.isNotEmpty(tsjDeviceExecutionQueues)) { - // 提升机存在任务 - return; - } - WcsPort param = new WcsPort(); - param.setPortType("1"); - param.setStatus("1"); - param.setSpare2("0"); - List wcsPorts = wcsPortService.selectWcsPortList(param); - DeviceTsj deviceTsj = deviceTsjService.selectDeviceTsjById(tsj.getId()); - if (CollUtil.isNotEmpty(wcsPorts) && deviceTsj.getSpare1() == 0) { - //todo 按时间顺序 或者是按提升机最近顺序 - Optional existCurrentPort = wcsPorts.stream().filter(x -> x.getPortRegion().equals(Convert.toStr(deviceTsj.getDqcs()))).findFirst(); - if (existCurrentPort.isPresent()) { - //修改承载锁定 - deviceTsj.setSpare1(1); - deviceTsjService.updateDeviceTsj(deviceTsj); - log.info("提升机任务锁定提升机承载 任务类型:{}", "提升机任务"); - } else { - WcsPort wcsPort = wcsPorts.get(0); - TsjDeviceExecutionQueue tsjDeviceExecutionQueue = new TsjDeviceExecutionQueue(); - tsjDeviceExecutionQueue.setGuid(IdUtil.simpleUUID()); - tsjDeviceExecutionQueue.setDeviceId(tsj.getId()); - tsjDeviceExecutionQueue.setDeviceName(tsj.getName()); - tsjDeviceExecutionQueue.setTaskNo(Convert.toLong(wcsPort.getSpare1())); - tsjDeviceExecutionQueue.setSrcRow("0"); - tsjDeviceExecutionQueue.setSrcLayer("0"); - tsjDeviceExecutionQueue.setTarRow(wcsPort.getPortType()); - tsjDeviceExecutionQueue.setTarLayer(wcsPort.getPortRegion()); - tsjDeviceExecutionQueue.setSendFlag("0"); - tsjDeviceExecutionQueue.setSendType("1"); - tsjDeviceExecutionQueue.setRwlx("1"); - tsjDeviceExecutionQueue.setCreateDate(DateUtil.formatDateTime(new Date())); - tsjDeviceExecutionQueueService.insertTsjDeviceExecutionQueue(tsjDeviceExecutionQueue); - } - - } } /** * 创建卸车队列 */ - private void createLoadQueue(DeviceTsj tsj) { + private void createQueue(DeviceTsj tsj) { //todo 根据当前楼层和执行阶段查询任务 获取目标队列 生成提升机队列 当小车出去后 解锁提升机 List tsjDeviceExecutionQueues = tsjDeviceExecutionQueueService.selectTsjDeviceExecutionQueueList(new TsjDeviceExecutionQueue()); if (CollUtil.isNotEmpty(tsjDeviceExecutionQueues)) { @@ -159,35 +113,53 @@ public class TsjThread implements Runnable { return; } - DeviceTsj deviceTsj = deviceTsjService.selectDeviceTsjById(1L); + DeviceTsj deviceTsj = PlcTsjRead.deviceTsjMap.get("1"); //判断提升机锁定 并且 小车已进入提升机 if (deviceTsj.getSpare1() == 1 && tsj.getSbzt() == 3 && tsj.getYxxf() == 1) { + WcsPort param = new WcsPort(); + param.setStatus("1"); + List wcsPorts = wcsPortService.selectWcsPortList(param); + wcsPorts = wcsPorts.stream().filter(x-> "1".equals(x.getStatus()) &&("1".equals(x.getPortType()) || "2".equals(x.getPortType()))).collect(Collectors.toList()); - //查询进入提升机的任务 - MydoJob param = new MydoJob(); - param.setRoadwayId("1"); - List mydoJobs = mydoJobService.selectMydoJobList(param); - - if (CollUtil.isNotEmpty(mydoJobs)){ - MydoJob mydoJob = mydoJobs.get(0); - BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId()); + for (WcsPort wcsPort : wcsPorts) { //生成提升机队列 TsjDeviceExecutionQueue tsjDeviceExecutionQueue = new TsjDeviceExecutionQueue(); + + MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(wcsPort.getSpare1())); + BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId()); + if (ObjUtil.isNull(mydoJob)){ + continue; + } + if (ObjUtil.isNull(basCargoSpace)){ + continue; + } + if (Convert.toInt(mydoJob.getInOrOut())<20){ + //入库 + if (mydoJob.getRoadwayId().equals(wcsPort.getPortCode())){ + //从1层到对应楼层 + tsjDeviceExecutionQueue.setSrcRow("0"); + tsjDeviceExecutionQueue.setSrcLayer("0"); + tsjDeviceExecutionQueue.setTarRow(Convert.toStr(basCargoSpace.getThePlatoon())); + tsjDeviceExecutionQueue.setTarLayer(Convert.toStr(basCargoSpace.getTheFloor())); + } + }else { + if (mydoJob.getRoadwayId().equals(wcsPort.getPortCode())){ + //从对应楼层到指定楼层 + tsjDeviceExecutionQueue.setSrcRow("0"); + tsjDeviceExecutionQueue.setSrcLayer("0"); + tsjDeviceExecutionQueue.setTarRow(Convert.toStr(basCargoSpace.getThePlatoon())); + tsjDeviceExecutionQueue.setTarLayer(Convert.toStr(basCargoSpace.getTheFloor())); + } + } tsjDeviceExecutionQueue.setGuid(IdUtil.simpleUUID()); tsjDeviceExecutionQueue.setDeviceId(tsj.getId()); tsjDeviceExecutionQueue.setDeviceName(tsj.getName()); tsjDeviceExecutionQueue.setTaskNo(Convert.toLong(mydoJob.getTaskNo())); - tsjDeviceExecutionQueue.setSrcRow("0"); - tsjDeviceExecutionQueue.setSrcLayer("0"); - tsjDeviceExecutionQueue.setTarRow(Convert.toStr(basCargoSpace.getThePlatoon())); - tsjDeviceExecutionQueue.setTarLayer(Convert.toStr(basCargoSpace.getTheFloor())); tsjDeviceExecutionQueue.setSendFlag("0"); tsjDeviceExecutionQueue.setSendType("1"); tsjDeviceExecutionQueue.setRwlx("1"); tsjDeviceExecutionQueue.setCreateDate(DateUtil.formatDateTime(new Date())); tsjDeviceExecutionQueueService.insertTsjDeviceExecutionQueue(tsjDeviceExecutionQueue); - - } } } @@ -261,13 +233,13 @@ public class TsjThread implements Runnable { tsjDeviceExecutionQueueFinishService.insertTsjDeviceExecutionQueueFinish(tsjDeviceExecutionQueueFinish); tsjDeviceExecutionQueueService.deleteTsjDeviceExecutionQueueByGuid(tsjDeviceExecutionQueue.getGuid()); log.info("提升机任务下发完成 taskNo{} 任务类型:{}", taskNo, "提升机任务"); - if ("1".equals(tsjDeviceExecutionQueue.getRwlx())) { + /*if ("1".equals(tsjDeviceExecutionQueue.getRwlx())) { //锁定提升机承载 DeviceTsj deviceTsj = deviceTsjService.selectDeviceTsjById(tsjDeviceExecutionQueue.getDeviceId()); deviceTsj.setSpare1(1); deviceTsjService.updateDeviceTsj(deviceTsj); log.info("提升机任务锁定提升机承载 taskNo{} 任务类型:{}", taskNo, "提升机任务"); - } + }*/ } }