测试过程问题修改
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
I will implement collision avoidance logic in `BaseSRgvThread.java` to handle scenarios where a path is blocked by another SRGV.
|
||||||
|
|
||||||
|
**Implementation Plan:**
|
||||||
|
1. **Modify `sendPointToPointTask` method in `BaseSRgvThread.java`**:
|
||||||
|
* Locate the block where `shortestPath` is null or empty (indicating a blocked path).
|
||||||
|
* After the existing specific logic for "Floor 1", add a generic avoidance strategy.
|
||||||
|
* **Avoidance Strategy**:
|
||||||
|
1. Query `WcsSrgvMap` for all sites with `remark="cache"` (avoidance points) on the current floor.
|
||||||
|
2. Filter out sites that are currently occupied by other SRGVs.
|
||||||
|
3. Find the nearest reachable avoidance point to the current car.
|
||||||
|
4. **Task Splitting (Yielding Logic)**:
|
||||||
|
* **Create a new "Continuation" Queue**: Clone the current task but set its `StartSite` to the avoidance point and keep the original `EndSite`. Insert this as a new pending task.
|
||||||
|
* **Update Current Queue**: Change the `EndSite` of the current blocked task to the **Avoidance Point**. This effectively converts the current task into a "Yielding" task.
|
||||||
|
5. Return `false` to allow the scheduler to pick up the modified task in the next cycle.
|
||||||
|
|
||||||
|
**Technical Details:**
|
||||||
|
* Use `wcsSrgvMapService` to fetch avoidance points.
|
||||||
|
* Use `PathFinder` to verify reachability of the avoidance point.
|
||||||
|
* Use `BeanUtil` (Hutool) or manual setters to clone the queue.
|
||||||
|
* Ensure the new logic does not interfere with the existing "Floor 1" logic (put it after or as an `else` condition).
|
||||||
|
|
||||||
|
This approach ensures that when blocked, the car moves to a safe spot (Yielding Queue) and then resumes its original journey (Continuation Queue).
|
||||||
47
.trae/documents/实现“调度阻挡车避让”的优化方案.md
Normal file
47
.trae/documents/实现“调度阻挡车避让”的优化方案.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# 优化避让策略:优先调度阻挡车避让
|
||||||
|
|
||||||
|
针对您提出的 "让B小车(障碍物)避让" 的合理建议,我设计了如下优化后的调度逻辑。新逻辑将优先尝试移开挡路车,只有在无法移开时才让当前车自己避让。
|
||||||
|
|
||||||
|
## 核心逻辑流程
|
||||||
|
|
||||||
|
当小车 A (当前调度车辆) 路径规划失败时,按以下步骤处理:
|
||||||
|
|
||||||
|
1. **识别阻挡者 (Find Blocker)**
|
||||||
|
* 构建一张**纯净的静态地图** (忽略所有小车位置)。
|
||||||
|
* 在静态地图上为 A 规划一条**理想路径**。
|
||||||
|
* 沿着理想路径检查,找到第一辆占据路径的小车 **B**。
|
||||||
|
|
||||||
|
2. **判断阻挡者状态 (Check Blocker Status)**
|
||||||
|
* **如果 B 正在执行任务 (Busy)**:
|
||||||
|
* 说明 B 只是暂时路过或正在工作。
|
||||||
|
* **策略**:A 小车暂时等待 (本次不生成指令),等待 B 自行移开。
|
||||||
|
* **如果 B 空闲 (Idle)**:
|
||||||
|
* 说明 B 停在路上挡住了 A。
|
||||||
|
* **策略**:调度 B 去避让。
|
||||||
|
|
||||||
|
3. **执行避让调度 (Execute Avoidance)**
|
||||||
|
* **场景 1:调度 B 避让 (优先)**
|
||||||
|
* 为 B 寻找一个最近的**避让点** (Cache Point)。
|
||||||
|
* *关键条件*:避让点不能在 A 的理想路径上 (防止 B 躲到 A 的下一步去)。
|
||||||
|
* 生成一条给 B 的**移动任务** (点到点移动)。
|
||||||
|
* A 小车保持等待,直到 B 移开。
|
||||||
|
* **场景 2:A 自己避让 (兜底)**
|
||||||
|
* 如果 B 无法移动 (例如 B 也被堵死,或找不到合适的避让点),则回退到原有的逻辑:**A 自己去避让点**,并在之后生成后续任务回来。
|
||||||
|
|
||||||
|
## 代码实现计划
|
||||||
|
|
||||||
|
将在 `BaseSRgvThread.java` 中现有的避让逻辑前插入新的判断块:
|
||||||
|
|
||||||
|
1. **新增 helper 方法**:
|
||||||
|
* `getStaticMap()`: 获取不含动态障碍物的地图。
|
||||||
|
* `isAgvIdle(String agvCode)`: 检查某小车是否空闲。
|
||||||
|
2. **修改 `sendPointToPointTask`**:
|
||||||
|
* 在路径规划失败后,先执行 "寻找阻挡车并调度其避让" 的逻辑。
|
||||||
|
* 如果成功调度了 B,则 `return false` (结束本次 A 的调度)。
|
||||||
|
* 如果未成功,则继续执行原有的 "A 去避让" 逻辑。
|
||||||
|
|
||||||
|
## 预期效果
|
||||||
|
|
||||||
|
* **更智能**:不再傻傻地让正在干活的车去绕路,而是把闲置的挡路车移开。
|
||||||
|
* **防止死锁**:通过主动疏通路径,减少多车拥堵的概率。
|
||||||
|
* **兼容性**:保留了原有的 A 避让逻辑作为兜底方案,确保任何情况下都有路可走。
|
||||||
@@ -23,6 +23,8 @@ public interface RoadCacheService {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int[][] handleMap(Map<String, WcsSrgvMap> arrByRoadSite, DeviceSrgv deviceSrgv);
|
int[][] handleMap(Map<String, WcsSrgvMap> arrByRoadSite, DeviceSrgv deviceSrgv);
|
||||||
|
|
||||||
|
int[][] handleMap1(Map<String, WcsSrgvMap> arrByRoadSite, DeviceSrgv deviceSrgv);
|
||||||
/**
|
/**
|
||||||
* 根据x y z 获取指定位置的缓存
|
* 根据x y z 获取指定位置的缓存
|
||||||
* @param x
|
* @param x
|
||||||
|
|||||||
@@ -61,7 +61,25 @@ public class RoadCacheServiceImpl implements RoadCacheService {
|
|||||||
//3.锁定离线小车当前位置
|
//3.锁定离线小车当前位置
|
||||||
lockedOfflineCarCurrSite(maps, deviceSrgv);
|
lockedOfflineCarCurrSite(maps, deviceSrgv);
|
||||||
|
|
||||||
int[][] mapsInt = new int[29][15];
|
int[][] mapsInt = new int[29][16];
|
||||||
|
for (String site : maps.keySet()) {
|
||||||
|
WcsSrgvMap wcsSrgvMap = maps.get(site);
|
||||||
|
mapsInt[wcsSrgvMap.getX()][wcsSrgvMap.getY()] = wcsSrgvMap.getValue();
|
||||||
|
}
|
||||||
|
return mapsInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[][] handleMap1(Map<String, WcsSrgvMap> maps, DeviceSrgv deviceSrgv) {
|
||||||
|
|
||||||
|
// //1.锁定其他车任务路径
|
||||||
|
// lockedOtherCarQueuePath(maps, deviceSrgv);
|
||||||
|
// //2.锁定无任务小车当前位置
|
||||||
|
// lockedOtherCarCurrSite(maps, deviceSrgv);
|
||||||
|
//3.锁定离线小车当前位置
|
||||||
|
// lockedOfflineCarCurrSite(maps, deviceSrgv);
|
||||||
|
|
||||||
|
int[][] mapsInt = new int[29][16];
|
||||||
for (String site : maps.keySet()) {
|
for (String site : maps.keySet()) {
|
||||||
WcsSrgvMap wcsSrgvMap = maps.get(site);
|
WcsSrgvMap wcsSrgvMap = maps.get(site);
|
||||||
mapsInt[wcsSrgvMap.getX()][wcsSrgvMap.getY()] = wcsSrgvMap.getValue();
|
mapsInt[wcsSrgvMap.getX()][wcsSrgvMap.getY()] = wcsSrgvMap.getValue();
|
||||||
@@ -141,7 +159,9 @@ public class RoadCacheServiceImpl implements RoadCacheService {
|
|||||||
//添加其他小车路径列表
|
//添加其他小车路径列表
|
||||||
HashSet<String> otherCarSiteList = new HashSet<>();
|
HashSet<String> otherCarSiteList = new HashSet<>();
|
||||||
for (WcsSrgvQueue wcsSrgvQueue : otherCarQueue) {
|
for (WcsSrgvQueue wcsSrgvQueue : otherCarQueue) {
|
||||||
otherCarSiteList.addAll(Arrays.asList(wcsSrgvQueue.getPathInfo().split(",")));
|
if (wcsSrgvQueue.getPathInfo()!=null) {
|
||||||
|
otherCarSiteList.addAll(Arrays.asList(wcsSrgvQueue.getPathInfo().split(",")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//锁定其他小车路径
|
//锁定其他小车路径
|
||||||
if (CollUtil.isNotEmpty(otherCarSiteList)) {
|
if (CollUtil.isNotEmpty(otherCarSiteList)) {
|
||||||
|
|||||||
@@ -149,14 +149,14 @@ public class ScheduleThread {
|
|||||||
plcSsjReadCustomThread = new CustomThread<PlcSsjRead>(plcSsjReadThread, plcSsjRead);
|
plcSsjReadCustomThread = new CustomThread<PlcSsjRead>(plcSsjReadThread, plcSsjRead);
|
||||||
|
|
||||||
//plc充电桩读取线程
|
//plc充电桩读取线程
|
||||||
// ConcurrentHashMap<String, DeviceCdz> cdzList = new ConcurrentHashMap<>();
|
ConcurrentHashMap<String, DeviceCdz> cdzList = new ConcurrentHashMap<>();
|
||||||
// List<DeviceCdz> deviceCdzList = deviceCdzService.selectDeviceCdzList(new DeviceCdz());
|
List<DeviceCdz> deviceCdzList = deviceCdzService.selectDeviceCdzList(new DeviceCdz());
|
||||||
// for (DeviceCdz deviceCdz : deviceCdzList) {
|
for (DeviceCdz deviceCdz : deviceCdzList) {
|
||||||
// cdzList.put(String.valueOf(deviceCdz.getId()), deviceCdz);
|
cdzList.put(String.valueOf(deviceCdz.getId()), deviceCdz);
|
||||||
// }
|
}
|
||||||
// PlcCdzRead plcCdzRead = new PlcCdzRead(cdzList, new PlcConnectInfo("192.168.10.100", 502));
|
PlcCdzRead plcCdzRead = new PlcCdzRead(cdzList, new PlcConnectInfo("192.168.10.100", 502));
|
||||||
// Thread plcCdzReadThread = new Thread(plcCdzRead, "plcCdzjReadCustomThread");
|
Thread plcCdzReadThread = new Thread(plcCdzRead, "plcCdzjReadCustomThread");
|
||||||
// plcCdzjReadCustomThread = new CustomThread<PlcCdzRead>(plcCdzReadThread, plcCdzRead);
|
plcCdzjReadCustomThread = new CustomThread<PlcCdzRead>(plcCdzReadThread, plcCdzRead);
|
||||||
|
|
||||||
|
|
||||||
ConcurrentHashMap<String, DeviceTsj> tsjList = new ConcurrentHashMap<>();
|
ConcurrentHashMap<String, DeviceTsj> tsjList = new ConcurrentHashMap<>();
|
||||||
@@ -197,7 +197,7 @@ public class ScheduleThread {
|
|||||||
|
|
||||||
public void refreshThreadMap() {
|
public void refreshThreadMap() {
|
||||||
registerThread("plcSsjReadCustomThread", plcSsjReadCustomThread, "PLC输送机读取线程", "read");
|
registerThread("plcSsjReadCustomThread", plcSsjReadCustomThread, "PLC输送机读取线程", "read");
|
||||||
// registerThread("plcCdzjReadCustomThread", plcCdzjReadCustomThread, "PLC充电桩读取线程", "read");
|
registerThread("plcCdzjReadCustomThread", plcCdzjReadCustomThread, "PLC充电桩读取线程", "read");
|
||||||
registerThread("plcTsjReadCustomThread", plcTsjReadCustomThread, "PLC提升机读取线程", "read");
|
registerThread("plcTsjReadCustomThread", plcTsjReadCustomThread, "PLC提升机读取线程", "read");
|
||||||
registerThread("plcSrgvReadCustomThread1", plcSrgvReadCustomThread1, "PLC四向车1读取线程", "read");
|
registerThread("plcSrgvReadCustomThread1", plcSrgvReadCustomThread1, "PLC四向车1读取线程", "read");
|
||||||
registerThread("plcSrgvReadCustomThread2", plcSrgvReadCustomThread2, "PLC四向车2读取线程", "read");
|
registerThread("plcSrgvReadCustomThread2", plcSrgvReadCustomThread2, "PLC四向车2读取线程", "read");
|
||||||
@@ -226,7 +226,7 @@ public class ScheduleThread {
|
|||||||
plcTsjReadCustomThread.getThread().start();
|
plcTsjReadCustomThread.getThread().start();
|
||||||
monitoringCustomThread.getThread().start();
|
monitoringCustomThread.getThread().start();
|
||||||
//充电桩读取线程
|
//充电桩读取线程
|
||||||
// plcCdzjReadCustomThread.getThread().start();
|
plcCdzjReadCustomThread.getThread().start();
|
||||||
isRun = true;
|
isRun = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,8 +90,11 @@ public class PlcCdzRead implements Runnable {
|
|||||||
if (read1.IsSuccess) {
|
if (read1.IsSuccess) {
|
||||||
cdzDevice.setModel(Convert.toInt(byteTransform.TransInt16(read1.Content, 0)));
|
cdzDevice.setModel(Convert.toInt(byteTransform.TransInt16(read1.Content, 0)));
|
||||||
cdzDevice.setStatus(Convert.toInt(byteTransform.TransInt16(read1.Content, 2)));
|
cdzDevice.setStatus(Convert.toInt(byteTransform.TransInt16(read1.Content, 2)));
|
||||||
|
if (cdzDevice.getStatus()==0){
|
||||||
|
cdzDevice.setSpare1("0");
|
||||||
|
}
|
||||||
log.info("=====读取到充电桩充电模式:{}======", Convert.toInt(byteTransform.TransInt16(read1.Content, 0)));
|
log.info("=====读取到充电桩充电模式:{}======", Convert.toInt(byteTransform.TransInt16(read1.Content, 0)));
|
||||||
log.info("=====读取到充电桩充电状态:{}======", Convert.toInt(byteTransform.TransInt16(read1.Content, 0)));
|
log.info("=====读取到充电桩充电状态:{}======", Convert.toInt(byteTransform.TransInt16(read1.Content, 2)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class CdzThread implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
void dispatch() {
|
void dispatch() {
|
||||||
|
SrgvChargingJob srgvChargingJobParam = new SrgvChargingJob();
|
||||||
//获取低电量小车
|
//获取低电量小车
|
||||||
List<DeviceSrgv> littleBatterySRgv = new ArrayList<>();
|
List<DeviceSrgv> littleBatterySRgv = new ArrayList<>();
|
||||||
//获取中电量小车
|
//获取中电量小车
|
||||||
@@ -98,7 +98,6 @@ public class CdzThread implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
//充电任务下发
|
//充电任务下发
|
||||||
SrgvChargingJob srgvChargingJobParam = new SrgvChargingJob();
|
|
||||||
srgvChargingJobParam.setChargingStatus("1");
|
srgvChargingJobParam.setChargingStatus("1");
|
||||||
srgvChargingJobParam.setJobType("1");
|
srgvChargingJobParam.setJobType("1");
|
||||||
srgvChargingJobParam.setJobStatus("4");
|
srgvChargingJobParam.setJobStatus("4");
|
||||||
@@ -145,6 +144,24 @@ public class CdzThread implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//充电桩关闭 完成充电任务
|
||||||
|
DeviceCdz deviceCdz = deviceCdzService.selectDeviceCdzById(1L);
|
||||||
|
if (deviceCdz.getStatus()==0){
|
||||||
|
SrgvChargingJob srgvChargingJobDdParam = new SrgvChargingJob();
|
||||||
|
srgvChargingJobDdParam.setChargingStatus("2");
|
||||||
|
srgvChargingJobDdParam.setJobStatus("4");
|
||||||
|
List<SrgvChargingJob> srgvChargingJobDds = chargingJobService.selectSrgvChargingJobList(srgvChargingJobDdParam);
|
||||||
|
if (CollUtil.isNotEmpty(srgvChargingJobDds)) {
|
||||||
|
for (SrgvChargingJob job :srgvChargingJobDds){
|
||||||
|
job.setChargingStatus("1");
|
||||||
|
job.setChargingDate(DateUtil.formatDateTime(DateUtil.date()));
|
||||||
|
chargingJobService.updateSrgvChargingJob(job);
|
||||||
|
//插入历史
|
||||||
|
chargingJobService.insertHistory(job.getGuid());
|
||||||
|
chargingJobService.deleteSrgvChargingJobByGuid(job.getGuid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//断电任务下发
|
//断电任务下发
|
||||||
@@ -191,19 +208,19 @@ public class CdzThread implements Runnable {
|
|||||||
if (CollUtil.isNotEmpty(cdzList)) {
|
if (CollUtil.isNotEmpty(cdzList)) {
|
||||||
//寻找最接近的充电桩
|
//寻找最接近的充电桩
|
||||||
Integer floor = deviceSrgv.getCurrFloor();
|
Integer floor = deviceSrgv.getCurrFloor();
|
||||||
DeviceCdz cdz = null;
|
DeviceCdz cdz = cdzList.get(0);
|
||||||
Optional<DeviceCdz> min = cdzList.stream().filter(c -> c.getSzcs().equals(floor)).min((o1, o2) -> {
|
// Optional<DeviceCdz> min = cdzList.stream().filter(c -> c.getSzcs().equals(floor)).min((o1, o2) -> {
|
||||||
Integer distance1 = Math.abs(o1.getSzcs());
|
// Integer distance1 = Math.abs(o1.getSzcs());
|
||||||
Integer distance2 = Math.abs(o2.getSzcs());
|
// Integer distance2 = Math.abs(o2.getSzcs());
|
||||||
return distance1 - distance2;
|
// return distance1 - distance2;
|
||||||
});
|
// });
|
||||||
if (min.isPresent()) {
|
// if (min.isPresent()) {
|
||||||
cdz = min.get();
|
// cdz = min.get();
|
||||||
}
|
// }
|
||||||
if (ObjUtil.isNotNull(cdz)) {
|
if (ObjUtil.isNotNull(cdz)) {
|
||||||
//生成充电任务
|
//生成充电任务
|
||||||
SrgvChargingJob srgvChargingJobParam = new SrgvChargingJob();
|
SrgvChargingJob srgvChargingJobParam = new SrgvChargingJob();
|
||||||
srgvChargingJobParam.setAgvId(deviceSrgv.getDeviceId().toString());
|
// srgvChargingJobParam.setAgvId(deviceSrgv.getDeviceId().toString());
|
||||||
srgvChargingJobParam.setChargingSite(cdz.getSiteId());
|
srgvChargingJobParam.setChargingSite(cdz.getSiteId());
|
||||||
srgvChargingJobParam.setChargingId(cdz.getId().toString());
|
srgvChargingJobParam.setChargingId(cdz.getId().toString());
|
||||||
List<SrgvChargingJob> wcsChargingJobs = chargingJobService.selectSrgvChargingJobList(srgvChargingJobParam);
|
List<SrgvChargingJob> wcsChargingJobs = chargingJobService.selectSrgvChargingJobList(srgvChargingJobParam);
|
||||||
@@ -231,7 +248,7 @@ public class CdzThread implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建充电任务
|
* 创建断电任务
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private void createChargingOutJob(DeviceSrgv deviceSrgv, DeviceCdz cdz) {
|
private void createChargingOutJob(DeviceSrgv deviceSrgv, DeviceCdz cdz) {
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ public class MonitoringThread implements Runnable {
|
|||||||
deviceSsjService.updateDeviceSsj(deviceSsj);
|
deviceSsjService.updateDeviceSsj(deviceSsj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (String cdzName : PlcCdzRead.deviceCdzMap.keySet()) {
|
for (String cdzName : PlcCdzRead.deviceCdzMap.keySet()) {
|
||||||
// DeviceCdz deviceCdz = PlcCdzRead.deviceCdzMap.get(cdzName);
|
DeviceCdz deviceCdz = PlcCdzRead.deviceCdzMap.get(cdzName);
|
||||||
// deviceCdzService.updateDeviceCdz(deviceCdz);
|
deviceCdzService.updateDeviceCdz(deviceCdz);
|
||||||
// }
|
}
|
||||||
|
|
||||||
for (String sRgv : PlcSrgvRead.deviceSrgvMap.keySet()) {
|
for (String sRgv : PlcSrgvRead.deviceSrgvMap.keySet()) {
|
||||||
deviceSrgvService.updateDeviceSrgv(PlcSrgvRead.deviceSrgvMap.get(sRgv));
|
deviceSrgvService.updateDeviceSrgv(PlcSrgvRead.deviceSrgvMap.get(sRgv));
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.ruoyi.schedule.scheduleTask.srgv;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.ruoyi.bas.port.service.IWcsPortService;
|
import com.ruoyi.bas.port.service.IWcsPortService;
|
||||||
@@ -72,6 +73,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
|
|
||||||
public JobCallBackServiceImpl jobCallBackService;
|
public JobCallBackServiceImpl jobCallBackService;
|
||||||
|
|
||||||
|
private int taskCache = 450001;
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
sRgvCodeList = new HashMap<>();
|
sRgvCodeList = new HashMap<>();
|
||||||
@@ -149,8 +151,8 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
//下发断电任务
|
//下发断电任务
|
||||||
// int i = PlcCdzRead.writeToCdz("2");
|
// int i = PlcCdzRead.writeToCdz("2");
|
||||||
// if (i == 1) {
|
// if (i == 1) {
|
||||||
srgvChargingJobMapper.insertHistory(srgvChargingJob.getGuid());
|
srgvChargingJobMapper.insertHistory(srgvChargingJob.getGuid());
|
||||||
srgvChargingJobMapper.deleteSrgvChargingJobByGuid(srgvChargingJob.getGuid());
|
srgvChargingJobMapper.deleteSrgvChargingJobByGuid(srgvChargingJob.getGuid());
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +180,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
String chargingId = srgvChargingJob.getChargingId();
|
String chargingId = srgvChargingJob.getChargingId();
|
||||||
DeviceSrgv srgv = PlcSrgvRead.deviceSrgvMap.get(agvId);
|
DeviceSrgv srgv = PlcSrgvRead.deviceSrgvMap.get(agvId);
|
||||||
// DeviceCdz cdz = PlcCdzRead.deviceCdzMap.get(chargingId);
|
// DeviceCdz cdz = PlcCdzRead.deviceCdzMap.get(chargingId);
|
||||||
if (srgv.getCurrFloor()==1) {
|
if (srgv.getCurrFloor() == 1) {
|
||||||
//生成四向小车充电队列
|
//生成四向小车充电队列
|
||||||
String chargingSite = srgvChargingJob.getChargingSite();//充电桩站点
|
String chargingSite = srgvChargingJob.getChargingSite();//充电桩站点
|
||||||
WcsSrgvQueue wcsSrgvQueueParam = new WcsSrgvQueue();
|
WcsSrgvQueue wcsSrgvQueueParam = new WcsSrgvQueue();
|
||||||
@@ -198,8 +200,8 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
List<WcsSrgvQueue> wcsSrgvQueues = wcsSagvQueueMapper.selectWcsSrgvQueueList(wcsSrgvQueueParam);
|
List<WcsSrgvQueue> wcsSrgvQueues = wcsSagvQueueMapper.selectWcsSrgvQueueList(wcsSrgvQueueParam);
|
||||||
if (CollUtil.isEmpty(wcsSrgvQueues)) {
|
if (CollUtil.isEmpty(wcsSrgvQueues)) {
|
||||||
createSrgvChargingQueue(deviceSrgv, chargingSite, "8", srgvChargingJob.getTaskNo());
|
createSrgvChargingQueue(deviceSrgv, chargingSite, "8", srgvChargingJob.getTaskNo());
|
||||||
srgvChargingJob.setJobStatus("2");
|
// srgvChargingJob.setJobStatus("2");
|
||||||
srgvChargingJobMapper.updateSrgvChargingJob(srgvChargingJob);
|
// srgvChargingJobMapper.updateSrgvChargingJob(srgvChargingJob);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -212,7 +214,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
WcsSrgvQueue wcsSrgvQueue = new WcsSrgvQueue();
|
WcsSrgvQueue wcsSrgvQueue = new WcsSrgvQueue();
|
||||||
wcsSrgvQueue.setGuid(UUID.randomUUID().toString());
|
wcsSrgvQueue.setGuid(UUID.randomUUID().toString());
|
||||||
wcsSrgvQueue.setTaskNo(taskNo);
|
wcsSrgvQueue.setTaskNo(taskNo);
|
||||||
wcsSrgvQueue.setTaskType("3");
|
wcsSrgvQueue.setTaskType(type);
|
||||||
wcsSrgvQueue.setPriority(Long.parseLong("2"));
|
wcsSrgvQueue.setPriority(Long.parseLong("2"));
|
||||||
wcsSrgvQueue.setCargo("0");
|
wcsSrgvQueue.setCargo("0");
|
||||||
wcsSrgvQueue.setIssued("0");
|
wcsSrgvQueue.setIssued("0");
|
||||||
@@ -223,14 +225,15 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
WcsSrgvMap wcsSrgvMap = wcsSrgvMapService.selectWcsSrgvMapBySiteId(chargingSite);
|
WcsSrgvMap wcsSrgvMap = wcsSrgvMapService.selectWcsSrgvMapBySiteId(chargingSite);
|
||||||
if ("8".equals(type)) {
|
if ("8".equals(type)) {
|
||||||
wcsSrgvQueue.setEndSite("tsj");
|
wcsSrgvQueue.setEndSite("tsj");
|
||||||
|
wcsSrgvQueue.setDefault03("040601");
|
||||||
} else if ("3".equals(type)) {
|
} else if ("3".equals(type)) {
|
||||||
wcsSrgvQueue.setEndSite(chargingSite);
|
wcsSrgvQueue.setEndSite(chargingSite);
|
||||||
|
wcsSrgvQueue.setDefault03(wcsSrgvQueue.getStartSite());
|
||||||
}
|
}
|
||||||
wcsSrgvQueue.setTheFloor(deviceSrgv.getCurrFloor().toString());
|
wcsSrgvQueue.setTheFloor(deviceSrgv.getCurrFloor().toString());
|
||||||
wcsSrgvQueue.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
wcsSrgvQueue.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||||
wcsSrgvQueue.setAgvId(deviceSrgv.getDeviceId().toString());
|
wcsSrgvQueue.setAgvId(deviceSrgv.getDeviceId().toString());
|
||||||
wcsSrgvQueue.setDefault02("3");
|
wcsSrgvQueue.setDefault02("3");
|
||||||
wcsSrgvQueue.setDefault03(wcsSrgvQueue.getStartSite());
|
|
||||||
wcsSrgvQueue.setDefault07(Convert.toStr(wcsSrgvMap.getZ()));
|
wcsSrgvQueue.setDefault07(Convert.toStr(wcsSrgvMap.getZ()));
|
||||||
wcsSagvQueueMapper.insertWcsSrgvQueue(wcsSrgvQueue);
|
wcsSagvQueueMapper.insertWcsSrgvQueue(wcsSrgvQueue);
|
||||||
}
|
}
|
||||||
@@ -255,7 +258,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
* 生成入库小车队列
|
* 生成入库小车队列
|
||||||
*/
|
*/
|
||||||
private void createCarQueue(DeviceSrgv deviceSrgv) {
|
private void createCarQueue(DeviceSrgv deviceSrgv) {
|
||||||
|
//充电队列处理
|
||||||
if (deviceSrgv.getWorkMode() == 5 && deviceSrgv.getStatus() == 1) {
|
if (deviceSrgv.getWorkMode() == 5 && deviceSrgv.getStatus() == 1) {
|
||||||
WcsSrgvQueue wcsSrgvQueue = wcsSagvQueueMapper.selectWcsSrgvQueueByAgvId(deviceSrgv.getDeviceId().toString());
|
WcsSrgvQueue wcsSrgvQueue = wcsSagvQueueMapper.selectWcsSrgvQueueByAgvId(deviceSrgv.getDeviceId().toString());
|
||||||
if (wcsSrgvQueue == null) {
|
if (wcsSrgvQueue == null) {
|
||||||
@@ -331,6 +334,12 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if ("1".equals(wcsSrgvQueue.getIssued())) {
|
if ("1".equals(wcsSrgvQueue.getIssued())) {
|
||||||
|
if (wcsSrgvQueue.getDefault08()!=null&&wcsSrgvQueue.getDefault08().equals("1")){
|
||||||
|
if (deviceSrgv.getCurrSite().equals(wcsSrgvQueue.getEndSite()) && "4".equals(wcsSrgvQueue.getTaskType())){
|
||||||
|
wcsSagvQueueMapper.insertHistory(wcsSrgvQueue.getTaskNo());
|
||||||
|
wcsSagvQueueMapper.deleteWcsSrgvQueueByGuid(wcsSrgvQueue.getGuid());
|
||||||
|
}
|
||||||
|
}
|
||||||
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(wcsSrgvQueue.getTaskNo()));
|
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Convert.toLong(wcsSrgvQueue.getTaskNo()));
|
||||||
if (mydoJob != null) {
|
if (mydoJob != null) {
|
||||||
if (deviceSrgv.getCurrSite().equals(wcsSrgvQueue.getEndSite()) && "1".equals(wcsSrgvQueue.getTaskType())) {
|
if (deviceSrgv.getCurrSite().equals(wcsSrgvQueue.getEndSite()) && "1".equals(wcsSrgvQueue.getTaskType())) {
|
||||||
@@ -395,6 +404,25 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
deviceCdzService.updateDeviceCdz(deviceCdz1);
|
deviceCdzService.updateDeviceCdz(deviceCdz1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
srgvChargingJob.setAgvId(String.valueOf(wcsSrgvQueue.getAgvId()));
|
||||||
|
srgvChargingJob.setTaskNo(wcsSrgvQueue.getTaskNo());
|
||||||
|
srgvChargingJob.setJobStatus("1");
|
||||||
|
srgvChargingJob.setJobType("1");
|
||||||
|
List<SrgvChargingJob> srgvChargingJobs1 = srgvChargingJobMapper.selectSrgvChargingJobList(srgvChargingJob);
|
||||||
|
if (!srgvChargingJobs1.isEmpty()) {
|
||||||
|
SrgvChargingJob srgvChargingJob1 = srgvChargingJobs1.get(0);
|
||||||
|
if (deviceSrgv.getCurrSite().equals(wcsSrgvQueue.getDefault03()) && "8".equals(wcsSrgvQueue.getTaskType())) {
|
||||||
|
wcsSagvQueueMapper.insertHistory(wcsSrgvQueue.getTaskNo());
|
||||||
|
wcsSagvQueueMapper.deleteWcsSrgvQueueByGuid(wcsSrgvQueue.getGuid());
|
||||||
|
// srgvChargingJob1.setJobStatus("4");
|
||||||
|
// srgvChargingJobMapper.updateSrgvChargingJob(srgvChargingJob1);
|
||||||
|
// DeviceCdz deviceCdz = new DeviceCdz();
|
||||||
|
// DeviceCdz deviceCdz1 = deviceCdzService.selectDeviceCdzById(1L);
|
||||||
|
// deviceCdz1.setSpare1(String.valueOf(deviceSrgv.getDeviceId()));
|
||||||
|
// deviceCdzService.updateDeviceCdz(deviceCdz1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -506,6 +534,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小车发送点对点任务
|
* 小车发送点对点任务
|
||||||
*/
|
*/
|
||||||
@@ -522,6 +551,232 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
|
|
||||||
//判断是否能规划出最短路径
|
//判断是否能规划出最短路径
|
||||||
if (shortestPath == null || shortestPath.isEmpty()) {
|
if (shortestPath == null || shortestPath.isEmpty()) {
|
||||||
|
// =========================================================
|
||||||
|
// 特殊优先策略:若目标点被其他小车占用,直接调度占用车到缓存点
|
||||||
|
// 场景示例:1号车目标为 040701,但 2号车正停在 040701
|
||||||
|
// 处理思路:不等待、不绕行,直接把占用目标点的小车移开
|
||||||
|
// =========================================================
|
||||||
|
try {
|
||||||
|
// 查找占用目标点的阻挡车(排除当前车)
|
||||||
|
String endBlockAgv = null;
|
||||||
|
DeviceSrgv endBlockDevice = null;
|
||||||
|
for (Map.Entry<String, DeviceSrgv> entry : PlcSrgvRead.deviceSrgvMap.entrySet()) {
|
||||||
|
DeviceSrgv other = entry.getValue();
|
||||||
|
if (other == null) continue;
|
||||||
|
if (Objects.equals(other.getCurrSite(), endSite)
|
||||||
|
&& !Objects.equals(Convert.toStr(deviceSrgv.getDeviceId()), entry.getKey())) {
|
||||||
|
endBlockAgv = entry.getKey();
|
||||||
|
endBlockDevice = other;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WcsSrgvQueue wcsSrgvQueue1 =new WcsSrgvQueue();
|
||||||
|
wcsSrgvQueue1.setAgvId(endBlockAgv);
|
||||||
|
List<WcsSrgvQueue> wcsSrgvQueues = wcsSagvQueueMapper.selectWcsSrgvQueueList(wcsSrgvQueue1);
|
||||||
|
if (endBlockDevice != null&&wcsSrgvQueues.isEmpty()) {
|
||||||
|
// 选择当前层最近且可达的缓存点(避让点)
|
||||||
|
WcsSrgvMap cacheParam = new WcsSrgvMap();
|
||||||
|
cacheParam.setRemark("cache");
|
||||||
|
cacheParam.setTheLayer(floor);
|
||||||
|
List<WcsSrgvMap> cacheMaps = wcsSrgvMapService.selectWcsSrgvMapList(cacheParam);
|
||||||
|
// 生成阻挡车的避让任务(点到点,高优先级,未下发)
|
||||||
|
WcsSrgvQueue taskB = new WcsSrgvQueue();
|
||||||
|
taskB.setGuid(UUID.randomUUID().toString());
|
||||||
|
// 生成纯数字任务号(PLC要求),9 + HHmmss
|
||||||
|
taskB.setTaskNo(String.valueOf(taskCache));
|
||||||
|
taskB.setAgvId(endBlockAgv);
|
||||||
|
taskB.setTaskType("4"); // 点到点移动
|
||||||
|
taskB.setDefault02("4"); // 业务类型标识为点到点
|
||||||
|
taskB.setPriority(9L); // 高优先级,尽快避让
|
||||||
|
taskB.setIssued("0"); // 未下发
|
||||||
|
taskB.setExecutionStatus("1");// 初始状态
|
||||||
|
taskB.setStartSite(endBlockDevice.getCurrSite());
|
||||||
|
taskB.setEndSite("050501");
|
||||||
|
taskB.setTheFloor(floor.toString());
|
||||||
|
taskB.setDefault03(endBlockDevice.getCurrSite());
|
||||||
|
taskB.setDefault07(floor.toString());
|
||||||
|
taskB.setDefault08("1");//避让任务,直接完成
|
||||||
|
taskB.setCreateDate(DateUtil.now());
|
||||||
|
wcsSagvQueueMapper.insertWcsSrgvQueue(taskB);
|
||||||
|
taskCache++;
|
||||||
|
log.info("目标点 {} 被小车 {} 占用,已调度其前往避让点 {}", endSite, endBlockAgv, "050501");
|
||||||
|
// 当前车等待下一轮调度(待阻挡车移开后自然可达)
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
log.warn("目标点 {} 被小车 {} 占用,但无可用避让点", endSite, endBlockAgv);
|
||||||
|
// 无法直接移开阻挡车,后续进入常规策略(寻找阻挡者或自身避让)
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("终点占用直接避让策略执行异常", e);
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// 策略1:尝试调度阻挡车避让 (新增逻辑)
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
try {
|
||||||
|
// 1. 获取纯净静态地图 (不含动态障碍物)
|
||||||
|
int[][] staticMap = new int[29][16];
|
||||||
|
for (WcsSrgvMap site : arrByRoadSite.values()) {
|
||||||
|
if (site.getX() != null && site.getY() != null) {
|
||||||
|
staticMap[site.getX()][site.getY()] = site.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2. 规划理想路径 (忽略其他小车)
|
||||||
|
int sx = arrByRoadSite.get(startSite).getX();
|
||||||
|
int sy = arrByRoadSite.get(startSite).getY();
|
||||||
|
int ex = arrByRoadSite.get(endSite).getX();
|
||||||
|
int ey = arrByRoadSite.get(endSite).getY();
|
||||||
|
staticMap[sx][sy] = 2;
|
||||||
|
staticMap[ex][ey] = 2;
|
||||||
|
List<int[]> idealPath = PathFinder.findShortestPath(
|
||||||
|
staticMap,
|
||||||
|
sx, sy,
|
||||||
|
ex, ey
|
||||||
|
);
|
||||||
|
// 3. 寻找阻挡车
|
||||||
|
String blockingAgv = null;
|
||||||
|
if (idealPath == null || idealPath.isEmpty()) {
|
||||||
|
log.warn("理想路径为空,sx={},sy={},ex={},ey={},startVal={},endVal={}",
|
||||||
|
sx, sy, ex, ey, staticMap[sx][sy], staticMap[ex][ey]);
|
||||||
|
}
|
||||||
|
if (idealPath != null && !idealPath.isEmpty()) {
|
||||||
|
for (int[] point : idealPath) {
|
||||||
|
// 通过坐标反查站点 (简单遍历)
|
||||||
|
// 注意:这里假设同一层坐标唯一
|
||||||
|
String pointSiteId = null;
|
||||||
|
for (Map.Entry<String, WcsSrgvMap> entry : arrByRoadSite.entrySet()) {
|
||||||
|
WcsSrgvMap s = entry.getValue();
|
||||||
|
if (s.getX() == point[0] && s.getY() == point[1]) {
|
||||||
|
pointSiteId = s.getSiteId();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointSiteId != null) {
|
||||||
|
// 检查是否有其他车在这个点
|
||||||
|
for (Map.Entry<String, DeviceSrgv> entry : PlcSrgvRead.deviceSrgvMap.entrySet()) {
|
||||||
|
String otherAgvCode = entry.getKey();
|
||||||
|
DeviceSrgv otherAgv = entry.getValue();
|
||||||
|
|
||||||
|
if (!otherAgvCode.equals(wcsSrgvQueue.getAgvId()) && // 不是自己
|
||||||
|
pointSiteId.equals(otherAgv.getCurrSite())) { // 是别人
|
||||||
|
|
||||||
|
blockingAgv = otherAgvCode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (blockingAgv != null) break; // 找到第一个阻挡者即可
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 调度阻挡车
|
||||||
|
if (blockingAgv != null) {
|
||||||
|
log.info("发现阻挡车: {}, 尝试调度避让", blockingAgv);
|
||||||
|
|
||||||
|
// 检查 B 是否忙碌 (是否有未完成任务)
|
||||||
|
WcsSrgvQueue blockingParam = new WcsSrgvQueue();
|
||||||
|
blockingParam.setAgvId(blockingAgv); // 注意:这里用 AgvId 还是 SrgvCode 需要确认,假设是一致的
|
||||||
|
// 通常数据库存的是 ID,这里 blockingAgv 来自 deviceSrgvMap 的 key,通常是 code
|
||||||
|
// 如果 code != id,需要转换。假设 code 就是 id。
|
||||||
|
|
||||||
|
List<WcsSrgvQueue> tasks = wcsSagvQueueMapper.selectWcsSrgvQueueList(blockingParam);
|
||||||
|
boolean isBusy = CollUtil.isNotEmpty(tasks);
|
||||||
|
// 这里简化判断:只要有队列记录就算忙。更精细的判断可以看 status。
|
||||||
|
|
||||||
|
if (isBusy) {
|
||||||
|
log.info("阻挡车 {} 正在执行任务,当前车 {} 等待", blockingAgv, wcsSrgvQueue.getAgvId());
|
||||||
|
return false; // B 忙,A 等待 (不做任何操作,下一轮循环再试)
|
||||||
|
} else {
|
||||||
|
// B 空闲,寻找避让点
|
||||||
|
// 获取当前层所有避让点
|
||||||
|
WcsSrgvMap cacheParam = new WcsSrgvMap();
|
||||||
|
cacheParam.setRemark("cache");
|
||||||
|
cacheParam.setTheLayer(floor);
|
||||||
|
List<WcsSrgvMap> cacheMaps = wcsSrgvMapService.selectWcsSrgvMapList(cacheParam);
|
||||||
|
|
||||||
|
// 获取所有小车位置 (用于避让点占用检查)
|
||||||
|
Set<String> occupiedSites = new HashSet<>();
|
||||||
|
for (DeviceSrgv d : PlcSrgvRead.deviceSrgvMap.values()) {
|
||||||
|
occupiedSites.add(d.getCurrSite());
|
||||||
|
}
|
||||||
|
|
||||||
|
String bestCacheForB = null;
|
||||||
|
int minLenForB = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
DeviceSrgv deviceB = PlcSrgvRead.deviceSrgvMap.get(blockingAgv);
|
||||||
|
if (deviceB != null) {
|
||||||
|
WcsSrgvMap startNodeB = arrByRoadSite.get(deviceB.getCurrSite());
|
||||||
|
|
||||||
|
for (WcsSrgvMap cache : cacheMaps) {
|
||||||
|
String siteId = cache.getSiteId();
|
||||||
|
if (occupiedSites.contains(siteId)) continue; // 已被占
|
||||||
|
|
||||||
|
// 关键:避让点不能在 A 的理想路径上
|
||||||
|
boolean onIdealPath = false;
|
||||||
|
for (int[] p : idealPath) {
|
||||||
|
if (p[0] == cache.getX() && p[1] == cache.getY()) {
|
||||||
|
onIdealPath = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (onIdealPath) continue;
|
||||||
|
|
||||||
|
// 检查 B 到避让点的可达性 (在静态地图上即可,因为其他车可能就是 A)
|
||||||
|
// 此时 A 还没动,所以 B 应该能动。
|
||||||
|
// 为了安全,还是用 emptyMap (含 A) 检查 B 的路径?
|
||||||
|
// 不,用 emptyMap 检查 B 的路径,因为 A 还在原位。
|
||||||
|
if (startNodeB != null && cache.getX() != null && cache.getY() != null) {
|
||||||
|
List<int[]> pathB = PathFinder.findShortestPath(emptyMap,
|
||||||
|
startNodeB.getX(), startNodeB.getY(),
|
||||||
|
cache.getX(), cache.getY());
|
||||||
|
|
||||||
|
if (pathB != null && !pathB.isEmpty() && pathB.size() < minLenForB) {
|
||||||
|
minLenForB = pathB.size();
|
||||||
|
bestCacheForB = siteId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestCacheForB != null) {
|
||||||
|
// 生成 B 的避让任务
|
||||||
|
WcsSrgvQueue taskB = new WcsSrgvQueue();
|
||||||
|
taskB.setGuid(UUID.randomUUID().toString());
|
||||||
|
// 生成纯数字任务号,避免 PLC 解析错误
|
||||||
|
// 格式:9 + HHmmss + 随机位 (防止重复)
|
||||||
|
String timeStr = DateUtil.format(new Date(), "HHmmss");
|
||||||
|
taskB.setTaskNo(String.valueOf(taskCache));
|
||||||
|
taskB.setAgvId(blockingAgv);
|
||||||
|
taskB.setTaskType("4"); // 点到点
|
||||||
|
taskB.setPriority(9L); // 高优先级
|
||||||
|
taskB.setIssued("0");
|
||||||
|
taskB.setExecutionStatus("1");
|
||||||
|
taskB.setStartSite(deviceB.getCurrSite());
|
||||||
|
taskB.setEndSite(bestCacheForB);
|
||||||
|
taskB.setTheFloor(floor.toString());
|
||||||
|
taskB.setCreateDate(DateUtil.now());
|
||||||
|
taskB.setDefault02("4");
|
||||||
|
taskB.setDefault03(deviceB.getCurrSite()); // 默认值填充
|
||||||
|
taskB.setDefault07(floor.toString());
|
||||||
|
taskB.setDefault08("1");
|
||||||
|
wcsSagvQueueMapper.insertWcsSrgvQueue(taskB);
|
||||||
|
taskCache++;
|
||||||
|
log.info("成功调度阻挡车 {} 前往避让点 {}", blockingAgv, bestCacheForB);
|
||||||
|
return false; // A 等待
|
||||||
|
} else {
|
||||||
|
log.warn("阻挡车 {} 无可用避让点", blockingAgv);
|
||||||
|
// Fallback to Strategy 2 (A moves)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("调度阻挡车避让逻辑异常", e);
|
||||||
|
// Fallback to Strategy 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// 策略2:自己避让 (原有逻辑)
|
||||||
|
// ---------------------------------------------------------
|
||||||
//判断是否是1层 空车取货 或者 满车放货
|
//判断是否是1层 空车取货 或者 满车放货
|
||||||
if (floor == 1) {
|
if (floor == 1) {
|
||||||
if ("2".equals(wcsSrgvQueue.getDefault02()) && "tsj".equals(wcsSrgvQueue.getStartSite()) && wcsSrgvQueue.getEndSite().equals(wcsSrgvQueue.getCargoPlaceSite())) {
|
if ("2".equals(wcsSrgvQueue.getDefault02()) && "tsj".equals(wcsSrgvQueue.getStartSite()) && wcsSrgvQueue.getEndSite().equals(wcsSrgvQueue.getCargoPlaceSite())) {
|
||||||
@@ -659,7 +914,7 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
} else {
|
} else {
|
||||||
SendData2 path = new SendData2();
|
SendData2 path = new SendData2();
|
||||||
path.setAddress("4004");//地址
|
path.setAddress("4004");//地址
|
||||||
path.setData(startSite + "," + endSite+",0,0,0,0,0,0");
|
path.setData(startSite + "," + endSite + ",0,0,0,0,0,0");
|
||||||
path.setType(2);
|
path.setType(2);
|
||||||
sendDataList.add(path);
|
sendDataList.add(path);
|
||||||
}
|
}
|
||||||
@@ -982,8 +1237,8 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
startSite = wcsSrgvQueue.getStartSite();
|
startSite = wcsSrgvQueue.getStartSite();
|
||||||
if (startSite.equals("tsj")){
|
if (startSite.equals("tsj")) {
|
||||||
startSite=getSite(wcsSrgvQueue.getStartSite(),wcsSrgvQueue.getTheFloor(),wcsSrgvQueue.getTaskType());
|
startSite = getSite(wcsSrgvQueue.getStartSite(), wcsSrgvQueue.getTheFloor(), wcsSrgvQueue.getTaskType());
|
||||||
}
|
}
|
||||||
if (!startSite.equals(currSite)) {
|
if (!startSite.equals(currSite)) {
|
||||||
wcsSrgvQueue.setIssued("1");
|
wcsSrgvQueue.setIssued("1");
|
||||||
@@ -994,18 +1249,20 @@ public class BaseSRgvThread implements Runnable, SRgvThreadInterface {
|
|||||||
mydoJob.setExecutionPhase("4");//小车搬运
|
mydoJob.setExecutionPhase("4");//小车搬运
|
||||||
mydoJobService.updateMydoJob(mydoJob);
|
mydoJobService.updateMydoJob(mydoJob);
|
||||||
}
|
}
|
||||||
String endSite = wcsSrgvQueue.getEndSite();
|
String endSite = wcsSrgvQueue.getEndSite();
|
||||||
if (endSite.equals("tsj")){
|
if (endSite.equals("tsj")) {
|
||||||
endSite=getSite(wcsSrgvQueue.getEndSite(),wcsSrgvQueue.getTheFloor(),wcsSrgvQueue.getTaskType());
|
endSite = getSite(wcsSrgvQueue.getEndSite(), wcsSrgvQueue.getTheFloor(), wcsSrgvQueue.getTaskType());
|
||||||
}
|
}
|
||||||
if (endSite.equals(currSite)) {
|
if (endSite.equals(currSite)) {
|
||||||
wcsSrgvQueue.setIssued("1");
|
if (!wcsSrgvQueue.getTaskType().equals("8")) {
|
||||||
wcsSrgvQueue.setExecutionStatus("3");
|
wcsSrgvQueue.setIssued("1");
|
||||||
wcsSrgvQueue.setStartDate(DateUtil.now());
|
wcsSrgvQueue.setExecutionStatus("3");
|
||||||
wcsSagvQueueMapper.updateWcsSrgvQueue(wcsSrgvQueue);
|
wcsSrgvQueue.setStartDate(DateUtil.now());
|
||||||
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Long.valueOf(wcsSrgvQueue.getTaskNo()));
|
wcsSagvQueueMapper.updateWcsSrgvQueue(wcsSrgvQueue);
|
||||||
mydoJob.setExecutionPhase("4");//小车搬运
|
MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Long.valueOf(wcsSrgvQueue.getTaskNo()));
|
||||||
mydoJobService.updateMydoJob(mydoJob);
|
mydoJob.setExecutionPhase("4");//小车搬运
|
||||||
|
mydoJobService.updateMydoJob(mydoJob);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</select>
|
</select>
|
||||||
<select id="selectDeviceCdzListNoSRgvId" resultMap="DeviceCdzResult">
|
<select id="selectDeviceCdzListNoSRgvId" resultMap="DeviceCdzResult">
|
||||||
<include refid="selectDeviceCdzVo"/>
|
<include refid="selectDeviceCdzVo"/>
|
||||||
where spare1 is null
|
where spare1 ='0'
|
||||||
</select>
|
</select>
|
||||||
<select id="selectDeviceCdzHasSRgvList" resultMap="DeviceCdzResult">
|
<select id="selectDeviceCdzHasSRgvList" resultMap="DeviceCdzResult">
|
||||||
<include refid="selectDeviceCdzVo"/>
|
<include refid="selectDeviceCdzVo"/>
|
||||||
where spare1 is not null
|
where spare1 <> '0'
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<insert id="insertDeviceCdz" parameterType="DeviceCdz">
|
<insert id="insertDeviceCdz" parameterType="DeviceCdz">
|
||||||
|
|||||||
Reference in New Issue
Block a user