#
luxiaotao1123
2024-11-14 9f19c2ea1a1d4e94460eb2d881b7cf8cc10e66df
#
6个文件已修改
215 ■■■■■ 已修改文件
zy-acs-framework/src/main/java/com/zy/acs/framework/common/Cools.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AllocateService.java 117 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/PatrolService.java 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/TaskService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/TaskServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-framework/src/main/java/com/zy/acs/framework/common/Cools.java
@@ -299,6 +299,8 @@
    }
    private final static char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    public static String md5(String string){
        try{
            MessageDigest md5 = MessageDigest.getInstance("MD5");
@@ -315,8 +317,6 @@
            throw new RuntimeException("md5加密失败,str=".concat(string));
        }
    }
    private static char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    public static Map<String, Object> translate(Object obj){
        Class<?> cls = obj.getClass();
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AllocateService.java
@@ -3,7 +3,6 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.manager.common.utils.CommonUtil;
import com.zy.acs.manager.common.utils.LocUtils;
import com.zy.acs.manager.core.domain.Lane;
import com.zy.acs.manager.manager.entity.*;
import com.zy.acs.manager.manager.enums.StatusType;
@@ -103,7 +102,8 @@
        List<String> availableAgvNosByOriLane = new ArrayList<>(availableAgvNos);
        if (null != originLane) {
            List<String> agvNosByOriLane = findAgvNosByLane(originLane);    // the agv list that had tasks in this lane
            if (!Cools.isEmpty(agvNosByOriLane) && agvNosByOriLane.size() >= maxAgvCountInLane) {
            // if full lane
            if (agvNosByOriLane.size() >= maxAgvCountInLane) {
                availableAgvNosByOriLane = Cools.getIntersection(agvNosByOriLane, availableAgvNos);
            }
@@ -116,7 +116,7 @@
        List<String> availableAgvNosByDestLane = new ArrayList<>(availableAgvNos);
        if (null != destinationLane) {
            List<String> agvNosByDestLane = findAgvNosByLane(destinationLane);
            if (!Cools.isEmpty(agvNosByDestLane) && agvNosByDestLane.size() >= maxAgvCountInLane) {
            if (agvNosByDestLane.size() >= maxAgvCountInLane) {
                availableAgvNosByDestLane = Cools.getIntersection(agvNosByDestLane, availableAgvNos);
            }
@@ -132,7 +132,6 @@
            log.warn("No available agv to assign the task destination[{}]", task.getSeqNum());
            return null;
        }
        List<String> actualAvailableAgvNos = Cools.getIntersection(availableAgvNosByOriLane, availableAgvNosByDestLane);
        if (Cools.isEmpty(actualAvailableAgvNos)) {
            log.warn("No available agv to assign the task[{}]", task.getSeqNum());
@@ -158,17 +157,18 @@
        return agvService.selectByUuid(actualAvailableAgvNos.stream().findFirst().orElse(null));
    }
    private List<String> findAgvNosByLane(Lane lane) {
    public List<String> findAgvNosByLane(Lane lane) {
        if (null == lane) {
            return null;
            return new ArrayList<>();
        }
        List<Task> taskList = taskService.findRunningTasksByLaneHash(lane.getHashCode());
        if (Cools.isEmpty(taskList)) {
            return null;
            return new ArrayList<>();
        }
        return taskList.stream().map(task -> {
            return agvService.getById(task.getAgvId()).getUuid();
        }).distinct().collect(Collectors.toList());
        return taskList.stream()
                .map(task -> agvService.getById(task.getAgvId()).getUuid())
                .distinct()
                .collect(Collectors.toList());
    }
    private List<String> validBackpackLimit(List<String> agvNoList) {
@@ -178,8 +178,8 @@
        return agvNoList.stream().filter(agvNo -> {
            Agv agv = agvService.selectByUuid(agvNo);
            AgvModel agvModel = agvModelService.getById(agv.getAgvModel());
            List<Task> runningTasks = taskService.findRunningTasksByAgv(agv.getId());
            return runningTasks.size() < agvModel.getBackpack();
            List<Task> transportTasks = taskService.findTransportTasksByAgv(agv.getId());
            return transportTasks.size() < agvModel.getBackpack();
        }).collect(Collectors.toList());
    }
@@ -189,9 +189,9 @@
        Agv agv = agvService.selectByUuid(agvNo);
        // backpack
        List<Task> runningTasks = taskService.findRunningTasksByAgv(agv.getId());
        if (!Cools.isEmpty(runningTasks)) {
            weight = weight + runningTasks.size() * 100000;
        List<Task> transportTasks = taskService.findTransportTasksByAgv(agv.getId());
        if (!Cools.isEmpty(transportTasks)) {
            weight = weight + transportTasks.size() * 100000;
        }
        // distance
@@ -231,89 +231,20 @@
        return -weight;
    }
    public synchronized Agv execute(Task task, Map<String, List<Long>> taskAllot, List<Long> taskIds) {
        String oriLocNo = task.getOriLoc$();
        int oriLocRow = LocUtils.getRow(oriLocNo);
        String destLocNo = task.getDestLoc$();
        int destLocRow = LocUtils.getRow(destLocNo);
    public Boolean validCapacityOfLane(Agv agv, Code code) {
        Lane lane = laneService.search(code.getData());
        if (null != lane) {
            Integer maxAgvCountInLane = configService.getVal("maxAgvCountInLane", Integer.class);
        Agv hit = null;
        List<Agv> agvList = agvService.list(new LambdaQueryWrapper<Agv>().eq(Agv::getStatus, StatusType.ENABLE.val));
        Collections.shuffle(agvList);
        for (Agv agv : agvList) {
            AgvModel agvModel = agvModelService.getById(agv.getAgvModel());
            int allotTaskCount = 0;
            List<Long> allotTaskIds = taskAllot.get(agv.getUuid());
            if (!Cools.isEmpty(allotTaskIds)) {
                allotTaskCount = allotTaskIds.size();
            List<String> agvNosByLane = this.findAgvNosByLane(lane);
            agvNosByLane.remove(agv.getUuid());
            if (agvNosByLane.size() >= maxAgvCountInLane) {
                return false;
            }
            if (allotTaskCount >= agvModel.getBackpack()) {
                continue;
            }
            if (taskService.count(new LambdaQueryWrapper<Task>()
                    .eq(Task::getAgvId, agv.getId())
                    .notIn(Task::getId, taskIds)
                    .and(i -> {
                        i.eq(Task::getTaskSts, TaskStsType.WAITING.val())   // 已经有waiting任务的车不能再分配
                                .or().eq(Task::getTaskSts, TaskStsType.ASSIGN.val())
                                .or().eq(Task::getTaskSts, TaskStsType.PROGRESS.val());
                    })) > 0) {
                log.info(agv.getUuid() + "号AGV不可用,已经存在进行中的任务...");
                continue;
            }
            if (!agvService.judgeEnable(agv.getId(), true)) {
                log.info(agv.getUuid() + "号AGV不可用," + task.getSeqNum() + "任务无法计算...");
                continue;
            }
            hit = agv;
            break;
        }
        return hit;
        return true;
    }
    public synchronized Agv execute1(Task task, Map<String, List<Long>> taskAllot, List<Long> taskIds) {
        String oriLocNo = task.getOriLoc$();
        int oriLocRow = LocUtils.getRow(oriLocNo);
        String destLocNo = task.getDestLoc$();
        int destLocRow = LocUtils.getRow(destLocNo);
        Agv agv = null;
        if (oriLocRow <= 2 && destLocRow <= 2) {
            agv = agvService.selectByUuid(String.valueOf(1));
        }
        if (oriLocRow > 2 && destLocRow > 2) {
            agv = agvService.selectByUuid(String.valueOf(2));
        }
        assert agv != null;
        AgvModel agvModel = agvModelService.getById(agv.getAgvModel());
        int allotTaskCount = 0;
        List<Long> allotTaskIds = taskAllot.get(agv.getUuid());
        if (!Cools.isEmpty(allotTaskIds)) {
            allotTaskCount = allotTaskIds.size();
        }
        if (allotTaskCount >= agvModel.getBackpack()) {
            return null;
        }
        if (taskService.count(new LambdaQueryWrapper<Task>()
                .eq(Task::getAgvId, agv.getId())
                .notIn(Task::getId, taskIds)
                .and(i -> {
                    i.eq(Task::getTaskSts, TaskStsType.WAITING.val())   // 已经有waiting任务的车不能再分配
                            .or().eq(Task::getTaskSts, TaskStsType.ASSIGN.val())
                            .or().eq(Task::getTaskSts, TaskStsType.PROGRESS.val());
                })) > 0) {
            log.info(agv.getUuid() + "号AGV不可用,已经存在进行中的任务...");
            return null;
        }
        if (!agvService.judgeEnable(agv.getId(), true)) {
            log.info(agv.getUuid() + "号AGV不可用," + task.getSeqNum() + "任务无法计算...");
            return null;
        }
        return agv;
    }
}
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
@@ -15,7 +15,6 @@
import com.zy.acs.common.enums.AgvCompleteType;
import com.zy.acs.common.enums.AgvDirectionType;
import com.zy.acs.common.enums.AgvSpeedType;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.common.utils.Utils;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.SnowflakeIdWorker;
@@ -25,6 +24,7 @@
import com.zy.acs.manager.common.exception.BusinessException;
import com.zy.acs.manager.common.utils.CommonUtil;
import com.zy.acs.manager.core.domain.AgvBackpackDto;
import com.zy.acs.manager.core.domain.Lane;
import com.zy.acs.manager.core.domain.TaskPosDto;
import com.zy.acs.manager.core.service.astart.MapDataDispatcher;
import com.zy.acs.manager.manager.controller.param.OpenBusSubmitParam;
@@ -41,7 +41,6 @@
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/**
@@ -50,10 +49,6 @@
@Slf4j
@Component("mainService")
public class MainService {
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    private static final int LOCK_TIMEOUT = 5;
    private final ReentrantLock lock = new ReentrantLock(Boolean.TRUE);
    @Autowired
    private BusService busService;
@@ -97,6 +92,8 @@
    private TrafficService trafficService;
    @Autowired
    private AgvModelService agvModelService;
    @Autowired
    private LaneService laneService;
    @SuppressWarnings("all")
@@ -235,35 +232,6 @@
                    throw new BusinessException("seqNum: " + task.getSeqNum() + " failed to update");
                }
            }
            // ------------------------------------------
//
//            Map<String, List<Long>> taskAllot = new HashMap<>();
//            for (Task task : taskList) {
//                Agv agv = missionAssignService.execute(task, taskAllot, taskIds);
//                if (null == agv) {
//                    log.warn("Task[{}] has an issue, because it failed to checkout agv which is idle...", task.getSeqNum());
//                    continue;
//                }
//
//
//                task.setAgvId(agv.getId());
//                task.setTaskSts(TaskStsType.WAITING.val());
//                task.setIoTime(now);
//                task.setUpdateTime(now);
//                if (!taskService.updateById(task)) {
//                    throw new BusinessException("seqNum: " + task.getSeqNum() + " failed to update");
//                }
//
//                if (taskAllot.containsKey(agv.getUuid())) {
//                    taskAllot.get(agv.getUuid()).add(task.getId());
//                } else {
//                    taskAllot.put(agv.getUuid(), Utils.singletonList(task.getId()));
//                }
//            }
        } catch (Exception e) {
            log.error("mainService.infuseAgvForTask", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@@ -560,6 +528,9 @@
            if (null == endCode) {
                return false;
            }
            if (!allocateService.validCapacityOfLane(agv, endCode)) {
                throw new BusinessException("the lane with code:" + endCode.getData() + " is full of AGV[" + agv.getUuid() + "]!!!");
            }
            Task task = new Task();
            task.setAgvId(agv.getId());
@@ -568,6 +539,11 @@
            task.setSeqNum(Utils.generateSeqNum(Cools.isEmpty(lastTasks)?null:lastTasks.get(0).getSeqNum()));
            task.setOriCode(agvDetail.getCode());
            task.setDestCode(endCode.getId());
            // lane
            Lane destLane = laneService.search(endCode.getData());
            if (null != destLane) {
                task.setDestLaneHash(destLane.getHashCode());
            }
            task.setPriority(taskType.equals(TaskTypeType.TO_CHARGE)?2:1);
            task.setTaskSts(TaskStsType.ASSIGN.val());
            task.setTaskType(taskType.val());
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/PatrolService.java
@@ -14,6 +14,7 @@
import com.zy.acs.manager.manager.service.AgvService;
import com.zy.acs.manager.manager.service.CodeService;
import com.zy.acs.manager.manager.service.TaskService;
import com.zy.acs.manager.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -47,14 +48,18 @@
    private AgvDetailService agvDetailService;
    @Autowired
    private TaskService taskService;
//    @Autowired
//    private MainService mainService;
    @Autowired
    private MainLockWrapService mainLockWrapService;
    @Autowired
    private CodeService codeService;
    @Autowired
    private MapService mapService;
    @Autowired
    private LaneService laneService;
    @Autowired
    private AllocateService allocateService;
    @Autowired
    private ConfigService configService;
    private void executePatrolLogic(String agvNo) {
        this.patrolOfMove(agvNo);
@@ -75,30 +80,55 @@
        if (!agvService.judgeEnable(agv.getId())) {
            return;
        }
        Code randomCode = this.getRandomCode(agvDetail);
        if (null == randomCode) {
        Code destinationCode = this.getDestinationCode(agv, agvDetail);
        if (null == destinationCode) {
            return;
        }
        if (mainLockWrapService.buildMinorTask(agv, agvDetail, TaskTypeType.MOVE, randomCode.getData())) {
        if (mainLockWrapService.buildMinorTask(agv, agvDetail, TaskTypeType.MOVE, destinationCode.getData())) {
            log.info(agv.getUuid() + "开始走行演示...");
        }
    }
    public Code getRandomCode(AgvDetail agvDetail) {
    /**
     * buildMinorTask 没有设置lane,lane只需要关注起始点(走行只需要关注终点)
     * 4个地方调用了buildMinorTask,在什么时候、哪里设置task的lane
     * (
         * HandlerController, 手动  (手动是否需要判断lane)
         * MaintainScheduler, 自动  (一般不需要考虑 lane)
         * PatrolService,     自动  (需要预处理 lane) ✔
         * TrafficService,    自动  (寻址时已经处理过 lane) ✔
     * )
     * 评估HandlerController没有调用buildMajorTask,手动创建task的可行性
     * patrolOfMove没有判断lane的容量
     * 抢占待机位
     * agv地图图标变化
     */
    public Code getDestinationCode(Agv agv, AgvDetail agvDetail) {
        Integer maxAgvCountInLane = configService.getVal("maxAgvCountInLane", Integer.class);
        Code startCode = codeService.getById(agvDetail.getRecentCode());
        List<String> notInCodeList = new ArrayList<>();
        notInCodeList.add("00000151");
        List<Code> list = codeService.list(new LambdaQueryWrapper<Code>().notIn(Code::getData, notInCodeList));
        Collections.shuffle(list);
        for (Code endCode : list) {
            // valid lane
            if (!allocateService.validCapacityOfLane(agv, endCode)) {
                continue;
            }
            // valid path length
            List<String> pathList = mapService.validFeasibility(startCode, endCode);
            if (pathList.size() >= 5) {
                return endCode;
            }
        }
        return list.stream().findFirst().orElse(null);
    }
    // ---------------------------------------------------------------------------
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/TaskService.java
@@ -32,7 +32,7 @@
    List<Task> findRunningTasksByLaneHash(String laneHash);
    List<Task> findRunningTasksByAgv(Long agvId);
    List<Task> findTransportTasksByAgv(Long agvId);
    Task findLatestTask(Long agvId, TaskStsType taskSts);
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/TaskServiceImpl.java
@@ -176,7 +176,7 @@
    }
    @Override
    public List<Task> findRunningTasksByAgv(Long agvId) {
    public List<Task> findTransportTasksByAgv(Long agvId) {
        if (null == agvId) {
            return new ArrayList<>();
        }