小车调度部分代码

This commit is contained in:
liuhanqing
2025-11-24 14:24:38 +08:00
parent 23633601cf
commit 04136d65de
6 changed files with 1074 additions and 517 deletions

View File

@@ -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();
}
}

View File

@@ -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<int[]> grid ,int value);
List<int[]> 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<int[]> 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<String, String> getRoadSiteByArr(int floor);
int[][] getRoadCache(int floor);
Map<String, int[]> getArrByRoadSite(int floor);
List<WcsSrgvMap> getRoadDataCache(int floor);
int[][] findMap(int floor);
int[][] findFullMap(int floor, int startX, int startY, int endX, int endY,DeviceSrgv srgvPlc,List<String> noSite);
Map<String, String> getSpaceDataCache();
}

View File

@@ -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<String> 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<WcsSrgvMap> slots, IWcsSrgvMapService service) {
WcsSagvQueue wcsSagvQueue = new WcsSagvQueue();
wcsSagvQueue.setTheFloor(floor + "");
List<WcsSagvQueue> wcsSagvQueues = wcsSagvQueueMapper.selectWcsSagvQueueList(wcsSagvQueue);
if (wcsSagvQueues.isEmpty()) {
return;
}
// 转为map,key为agvId ,value为pathInfo
Map<String, String> 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<SRGVPlc> srgvPlcs = plcService.listSRGVPlcData();
// 处理路径信息,只保留当前站点及以后的路径
updateAgvPathMap(agvPathMap, srgvPlcs);
// 将路径拆分成站点,更新对应slot的value值
updateSlotsWithValueFromPath(slots, agvPathMap);
}
*//**
* 更新AGV路径映射,只保留当前站点及以后的路径
*//*
private void updateAgvPathMap(Map<String, String> agvPathMap, List<SRGVPlc> 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<WcsSrgvMap> slots, Map<String, String> agvPathMap) {
// 创建一个站点到AGV ID的映射
Map<String, String> siteToAgvMap = new HashMap<>();
for (Map.Entry<String, String> 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<WcsSrgvMap> slots) {
List<SRGVPlc> srgvPlcs = plcService.listSRGVPlcData();
// 创建siteId到slot的映射以提高查找性能
Map<String, WcsSrgvMap> 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<WcsSrgvMap> slots) {
WcsAgv wcsAgv = new WcsAgv();
wcsAgv.setDefault01(floor + "");
List<WcsAgv> wcsAgvs = wcsAgvMapper.selectWcsAgvList(wcsAgv);
// 创建siteId到slot的映射以提高查找性能
Map<String, WcsSrgvMap> 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<WcsSagvQueue> wcsSagvQueues = wcsSagvQueueMapper.selectWcsSagvQueueList(wcsSagvQueue);
if (wcsSagvQueues.isEmpty()) {
return;
}
// 转为map,key为agvId ,value为pathInfo
Map<String, String> 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<SRGVPlc> 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<WcsSagvQueue> wcsSagvQueueList = wcsSagvQueueMapper.selectWcsSagvQueueList(wcsSagvQueue);
List<WcsSagvQueue> wcsSagvQueues = wcsSagvQueueList.stream().filter(queue -> !Objects.equals(queue.getAgvId(), agvId)).collect(Collectors.toList());
if (wcsSagvQueues.isEmpty()) {
return;
}
// 转为map,key为agvId ,value为pathInfo
Map<String, String> 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<SRGVPlc> srgvPlcs = plcService.listSRGVPlcData();
// 处理路径信息,只保留当前站点及以后的路径
updateAgvPathMap(agvPathMap, srgvPlcs);
// 将路径拆分成站点,更新对应slot的value值
updateSlotsWithValueFromPath2(ints,agvPathMap,floor);
}
private void updateSlotsWithValueFromPath2(int[][] arrMap, Map<String, String> agvPathMap, int floor) {
// 在循环前获取一次站点坐标映射
Map<String, int[]> arrByRoadSite = roadCacheService.getArrByRoadSite(floor);
for (Map.Entry<String, String> 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<SRGVPlc> srgvPlcs = plcService.listSRGVPlcData();
// 过滤出同层的当前站点,并处理空值情况
List<String> 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<String, int[]> 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<SRGVPlc> srgvPlcs = plcService.listSRGVPlcData();
// 过滤出同层的当前站点,并处理空值情况
List<String> 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<String, int[]> 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<SRGVPlc> srgvPlcs = plcService.listSRGVPlcData();
// 过滤出同层的当前站点,并处理空值情况
List<String> 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<String, int[]> 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<WcsAgv> wcsAgvs = wcsAgvMapper.selectWcsAgvList(wcsAgv);
// 根据站点获取二维数组坐标
Map<String, int[]> 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<String> tarSite) {
WcsAgv wcsAgv = new WcsAgv();
wcsAgv.setDefault01(floor + "");
List<WcsAgv> wcsAgvs = wcsAgvMapper.selectWcsAgvList(wcsAgv);
// 根据站点获取二维数组坐标
Map<String, int[]> 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<String> sites) {
// 根据站点获取二维数组坐标
Map<String, int[]> 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,代表障碍物
}
}
}
}*/
}

View File

@@ -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<String,String> getSpaceDataCache() {
log.info("从数据库获取初始化地图数据");
WcsSrgvMap wcsSrgvMap = new WcsSrgvMap();
List<WcsSrgvMap> wcsSrgvMaps = wcsSrgvMapMapper.selectWcsSrgvMapList(wcsSrgvMap);
//将集合转为map,
Map<String, String> 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<WcsSrgvMap> getRoadDataCache(int floor) {
log.info("从数据库获取初始化地图");
WcsSrgvMap wcsSrgvMap1 = new WcsSrgvMap();
wcsSrgvMap1.setUz(floor);
List<WcsSrgvMap> wcsSrgvMaps = wcsSrgvMapMapper.selectWcsSrgvMapList(wcsSrgvMap1);
return wcsSrgvMaps;
}
/*
*
* 每层二维地图
* */
@Override
@Cacheable(value = "RoadCache" ,key = "'RoadCacheKey_floor_' +#floor")
public int[][] getRoadCache(int floor) {
List<WcsSrgvMap> 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<String, int[]> getArrByRoadSite(int floor) {
List<WcsSrgvMap> roadDataCache = selfProxy.getRoadDataCache(floor);
//将集合转为map,key为siteId,value为x,y
Map<String, int[]> 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<String, String> getRoadSiteByArr(int floor) {
List<WcsSrgvMap> roadDataCache = selfProxy.getRoadDataCache(floor);
//将集合转为map,key为x,y,value为siteId
Map<String, String> 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<int[]> grid,int value) {
int[][] roadCache = selfProxy.getRoadCache(floor);
for (int[] ints : grid) {
roadCache[ints[0]][ints[1]] = value;
}
return roadCache;
}
//获取载货路径
@Override
public List<int[]> 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<String> 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<int[]> 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<int[]> 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;
}
}

View File

@@ -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<SrgvChargingJob> 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<SRGVPlc> 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<WcsPort> 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<WcsSrgvQueue> 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<String> 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<String, String> 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<SrgvChargingJob> 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<WcsSrgvQueue> wcsSagvQueues = wcsSagvQueueMapper.selectWcsSrgvQueueList(wcsSagvQueue);
if (wcsSagvQueues.size() == 0) {
//生成去充电的任务
WcsSrgvQueue wsq = new WcsSrgvQueue();
wsq.setGuid(IdUtil.fastSimpleUUID());
/*HashMap<String, String> 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<String, int[]> 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<int[]> 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<String> 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<String, int[]> 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<int[]> 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<WcsPort> 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<WcsSrgvQueue> wcsSagvQueues = wcsSagvQueueMapper.selectWcsSrgvQueueList(param);
List<WcsSrgvQueue> 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();

View File

@@ -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<TsjDeviceExecutionQueue> tsjDeviceExecutionQueues = tsjDeviceExecutionQueueService.selectTsjDeviceExecutionQueueList(new TsjDeviceExecutionQueue());
if (CollUtil.isNotEmpty(tsjDeviceExecutionQueues)) {
// 提升机存在任务
return;
}
WcsPort param = new WcsPort();
param.setPortType("1");
param.setStatus("1");
param.setSpare2("0");
List<WcsPort> wcsPorts = wcsPortService.selectWcsPortList(param);
DeviceTsj deviceTsj = deviceTsjService.selectDeviceTsjById(tsj.getId());
if (CollUtil.isNotEmpty(wcsPorts) && deviceTsj.getSpare1() == 0) {
//todo 按时间顺序 或者是按提升机最近顺序
Optional<WcsPort> 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<TsjDeviceExecutionQueue> 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<WcsPort> 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<MydoJob> 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, "提升机任务");
}
}*/
}
}