#
luxiaotao1123
2024-11-01 a681fcad83bfcaec7c79a273659c53ba9c5502ae
#
3个文件已修改
1个文件已添加
205 ■■■■ 已修改文件
zy-acs-manager/src/main/java/com/zy/acs/manager/core/domain/ReservedTimeWindow.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/domain/TimeWindow.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TimeWindowService.java 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TwTrafficService.java 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/domain/ReservedTimeWindow.java
New file
@@ -0,0 +1,23 @@
package com.zy.acs.manager.core.domain;
import lombok.Data;
/**
 * Created by vincent on 11/1/2024
 */
@Data
public class ReservedTimeWindow {
    private String twKey;
    private TimeWindow timeWindow;
    public ReservedTimeWindow() {
    }
    public ReservedTimeWindow(String twKey, TimeWindow timeWindow) {
        this.twKey = twKey;
        this.timeWindow = timeWindow;
    }
}
zy-acs-manager/src/main/java/com/zy/acs/manager/core/domain/TimeWindow.java
@@ -8,11 +8,20 @@
@Data
public class TimeWindow {
    private long startTime; // 开始时间
    private long startTime;
    private long endTime;   // 结束时间
    private long endTime;
    private String agvId;   // 预定的AGV
    private String agvNo;
    public TimeWindow() {
    }
    public TimeWindow(long startTime, long endTime, String agvNo) {
        this.startTime = startTime;
        this.endTime = endTime;
        this.agvNo = agvNo;
    }
    public boolean isConflict(TimeWindow other) {
        return this.endTime > other.startTime && this.startTime < other.endTime;
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TimeWindowService.java
@@ -1,5 +1,7 @@
package com.zy.acs.manager.core.service;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.manager.core.domain.ReservedTimeWindow;
import com.zy.acs.manager.core.domain.TimeWindow;
import org.springframework.stereotype.Service;
@@ -17,10 +19,46 @@
    public static final Map<String, List<TimeWindow>> TIME_WINDOW_MAP = new ConcurrentHashMap<>();
    // 预定时间窗口
    public synchronized boolean reserve(String key, TimeWindow window, String vehicle) {
    // reserve --------------------------------------------------------------------
        List<TimeWindow> windows = TIME_WINDOW_MAP.getOrDefault(key, new ArrayList<>());
    public synchronized boolean reserveTimeWindows(String agvNo, List<String> pathList) {
        if (Cools.isEmpty(agvNo, pathList)) {
            return false;
        }
        long estimatedTime = System.currentTimeMillis();
        List<ReservedTimeWindow> reservedWindows = new ArrayList<>();
        for (int i = 0; i < pathList.size() - 1; i++) {
            String fromCode = pathList.get(i);
            String toCode = pathList.get(i + 1);
            String twKey = fromCode + "_" + toCode;
            long twStartTime = estimatedTime;
            long twEndTime = estimatedTime + estimateTravelTime(fromCode, toCode, agvNo);
            TimeWindow timeWindow = new TimeWindow(twStartTime, twEndTime, agvNo);
            boolean success = reserveTimeWindow(twKey, timeWindow);
            if (!success) {
                // 预定失败,释放已预定的时间窗口
                releaseReservedTimeWindows(reservedWindows);
                return false;
            }
            reservedWindows.add(new ReservedTimeWindow(twKey, timeWindow));
            estimatedTime = twEndTime;
        }
        return true;
    }
    // 预定时间窗口
    public synchronized boolean reserveTimeWindow(String twKey, TimeWindow window) {
        List<TimeWindow> windows = TIME_WINDOW_MAP.getOrDefault(twKey, new ArrayList<>());
        for (TimeWindow reservedWindow : windows) {
            if (reservedWindow.isConflict(window)) {
@@ -29,19 +67,47 @@
        }
        windows.add(window);
        TIME_WINDOW_MAP.put(key, windows);
        TIME_WINDOW_MAP.put(twKey, windows);
        return true;
    }
    // 释放时间窗口
    public synchronized void release(String key, TimeWindow window, String vehicle) {
        List<TimeWindow> windows = TIME_WINDOW_MAP.get(key);
    // release ------------------------------------------------------------------
    public synchronized void releasePathTimeWindows(String agvNo, List<String> pathList) {
        for (int i = 0; i < pathList.size() - 1; i++) {
            String fromCode = pathList.get(i);
            String toCode = pathList.get(i + 1);
            String twKey = fromCode + "_" + toCode;
            // 查找并释放时间窗口
            releaseTimeWindow(twKey, agvNo);
        }
    }
    public synchronized void releaseTimeWindow(String twKey, String agvNo) {
        List<TimeWindow> windows = TIME_WINDOW_MAP.get(twKey);
        if (windows != null) {
            windows.remove(window);
            windows.removeIf(window -> window.getAgvNo().equals(agvNo));
            if (windows.isEmpty()) {
                TIME_WINDOW_MAP.remove(key);
                TIME_WINDOW_MAP.remove(twKey);
            }
        }
    }
    private void releaseReservedTimeWindows(List<ReservedTimeWindow> reservedWindows) {
        for (ReservedTimeWindow reserved : reservedWindows) {
            releaseTimeWindow(reserved.getTwKey(), reserved.getTimeWindow().getAgvNo());
        }
    }
    // util --------------------------------------------------------------------------------------
    private long estimateTravelTime(String fromCode, String toCode, String agvNo) {
        // 根据距离和AGV速度估算行驶时间
        double distance = 1000;
        double speed = 2; // 获取AGV速度,单位:米/秒
        return (long) (distance / speed * 1000); // 转换为毫秒
    }
}
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TwTrafficService.java
@@ -1,15 +1,12 @@
package com.zy.acs.manager.core.service;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.acs.common.constant.RedisConstant;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.SnowflakeIdWorker;
import com.zy.acs.framework.exception.CoolException;
import com.zy.acs.manager.common.utils.MapDataUtils;
import com.zy.acs.manager.core.domain.TaskPosDto;
import com.zy.acs.manager.core.domain.TrafficJamDto;
import com.zy.acs.manager.core.service.astart.DynamicNodeType;
import com.zy.acs.manager.core.service.astart.MapDataDispatcher;
import com.zy.acs.manager.core.service.astart.RetreatNavigateNode;
@@ -26,7 +23,10 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
 * Wavefront
@@ -188,28 +188,6 @@
        }
    }
    public void callback(List<Segment> segmentList) {
        Date now = new Date();
        segmentList.stream().max(Comparator.comparingInt(Segment::getSerial)).ifPresent(segment -> {
            Segment nextSegment = segmentService.getNextStepOfInit(segment.getTravelId(), segment.getSerial());
            if (null != nextSegment) {
                nextSegment.setState(SegmentStateType.WAITING.toString());
                nextSegment.setUpdateTime(now);
                if (!segmentService.updateById(nextSegment)) {
                    log.error("Segment [{}] 更新失败 !!!", nextSegment.getGroupId() + " - " + nextSegment.getSerial());
                }
            } else {
                travelService.checkFinish(segment.getTravelId());
            }
        });
    }
    private List<String> checkoutPath(Agv agv, Code startCode, Code endCode, Segment segment) {
        Integer lev = null;
        String agvNo = agv.getUuid();
@@ -223,6 +201,41 @@
        List<String> unlockPathList = mapService.checkoutPath(agvNo, startCode, endCode, false);
        // 避让解
        List<String> lockPathList = mapService.checkoutPath(agvNo, startCode, endCode, true);
        if (Cools.isEmpty(lockPathList)) {
            return pathList;
        }
        pathList = lockPathList;
        long currentTime = System.currentTimeMillis();
        long estimatedTime = currentTime;
        for (int i = 0; i < pathList.size() - 1; i++) {
            String fromCode = pathList.get(i);
            String toCode = pathList.get(i + 1);
            String key = fromCode + "_" + toCode;
        }
        if (!Cools.isEmpty(lockPathList) && // 存在避让解
            Math.abs(lockPathList.size() - unlockPathList.size()) <= Arrays.stream(mapDataDispatcher.getCodeMatrix(lev)).mapToInt(row -> row.length).sum() / 10
@@ -451,24 +464,6 @@
        }
        return jamVehicleList;
    }
    private String hasEvent(String agvNo) {
        List<Agv> agvList = agvService.list(new LambdaQueryWrapper<>());
        for (Agv agv : agvList) {
            if (agvNo.equals(agv.getUuid())) {
                continue;
            }
            String jamStr = redis.getValue(RedisConstant.AGV_TRAFFIC_JAM_FLAG, agv.getUuid());
            if (!Cools.isEmpty(jamStr)) {
                TrafficJamDto jamDto = JSON.parseObject(jamStr, TrafficJamDto.class);
            }
        }
        return null;
    }
    /**