package com.zy.acs.manager.core.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.zy.acs.framework.common.Cools;
|
import com.zy.acs.manager.common.utils.LocUtils;
|
import com.zy.acs.manager.manager.entity.Agv;
|
import com.zy.acs.manager.manager.entity.AgvModel;
|
import com.zy.acs.manager.manager.entity.Task;
|
import com.zy.acs.manager.manager.enums.TaskStsType;
|
import com.zy.acs.manager.manager.service.AgvModelService;
|
import com.zy.acs.manager.manager.service.AgvService;
|
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;
|
|
import java.util.*;
|
|
/**
|
* Created by vincent on 8/12/2024
|
*/
|
@Slf4j
|
@Service
|
public class AllocateService {
|
|
@Autowired
|
private AgvService agvService;
|
@Autowired
|
private AgvModelService agvModelService;
|
@Autowired
|
private ConfigService configService;
|
@Autowired
|
private TaskService taskService;
|
@Autowired
|
private LaneService laneService;
|
|
/**
|
* get available agv list which is idle
|
*/
|
private List<Agv> getAvailableAgv() {
|
List<Agv> result = new ArrayList<>();
|
List<Agv> agvList = agvService.list(new LambdaQueryWrapper<Agv>().eq(Agv::getStatus, 1));
|
Collections.shuffle(agvList);
|
for (Agv agv : agvList) {
|
|
// 1. without running tasks
|
if (0 < taskService.count(new LambdaQueryWrapper<Task>()
|
.eq(Task::getAgvId, agv.getId())
|
.and(i ->
|
i.eq(Task::getTaskSts, TaskStsType.ASSIGN.val())
|
.or().eq(Task::getTaskSts, TaskStsType.PROGRESS.val())
|
)
|
)) {
|
continue;
|
}
|
|
// 2. in idle status
|
if (!agvService.judgeEnable(agv.getId(), true)) {
|
continue;
|
}
|
|
result.add(agv);
|
}
|
|
return result;
|
}
|
|
public synchronized Agv execute(Task task) {
|
List<Agv> availableAgvList = getAvailableAgv();
|
if (Cools.isEmpty(availableAgvList)) {
|
log.warn("No available agv to assign the task[{}]", task.getSeqNum());
|
return null;
|
}
|
|
Integer maxAgvCountInLane = configService.getVal("maxAgvCountInLane", Integer.class);
|
|
|
/**
|
* 1. 判断task的起始点和目的点所在的巷道承载任务数量,
|
* 如果数量已经达到负载,则判断负载任务的AGV是否还有空背篓,如果有则优先派发给它,
|
* 如果没有了,那么则阻塞任务,直到该巷道释放
|
*
|
* 2. 轮询空闲小车,目标是让每台小车都动起来
|
* 判断逻辑:背篓数量最少的小车轮询的时候,优先级最高
|
*/
|
|
return null;
|
}
|
|
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);
|
|
Agv hit = null;
|
|
List<Agv> agvList = agvService.list(new LambdaQueryWrapper<Agv>().eq(Agv::getStatus, 1));
|
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();
|
}
|
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;
|
}
|
|
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;
|
}
|
|
}
|