From ab886689e2c4ef8db2b0767717d69ebbaf10326c Mon Sep 17 00:00:00 2001 From: luxiaotao1123 <t1341870251@163.com> Date: 星期五, 29 十一月 2024 16:37:20 +0800 Subject: [PATCH] # --- zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java | 191 +++++++++++++++++++---------------------------- 1 files changed, 77 insertions(+), 114 deletions(-) diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java index cb6fd28..3b6ad34 100644 --- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java +++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java @@ -15,15 +15,15 @@ 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; import com.zy.acs.framework.exception.CoolException; import com.zy.acs.manager.common.domain.TaskDto; +import com.zy.acs.manager.common.domain.param.HandlerPublishParam; 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; @@ -35,12 +35,11 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; /** @@ -49,10 +48,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; @@ -96,6 +91,8 @@ private TrafficService trafficService; @Autowired private AgvModelService agvModelService; + @Autowired + private LaneService laneService; @SuppressWarnings("all") @@ -223,7 +220,7 @@ for (Task task : taskList) { Agv agv = allocateService.execute(task); if (null == agv) { - log.warn("Task[{}] has an issue锛� because it failed to checkout agv which is idle...", task.getSeqNum()); +// log.warn("Task[{}] has an issue锛� because it failed to checkout agv which is idle...", task.getSeqNum()); continue; } task.setAgvId(agv.getId()); @@ -234,35 +231,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(); @@ -271,23 +239,24 @@ /** * 瑙f瀽鍙栨斁璐ч泦鍚堜换鍔�,杩涜鏈�浼樼殑鎺掑垪缁勫悎椤哄簭 ( 杞﹁締姝ゆ椂鏄┖闂蹭笖闈欐鐨� ) + * todo: {@link com.zy.acs.manager.core.HandlerController#controlAgv(String, HandlerPublishParam)} */ - @Transactional - public synchronized void buildMajorTask(Long agvId, List<Task> taskList) { - if (Cools.isEmpty(taskList)) { return; } - boolean lockAcquired = false; + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void buildMajorTask(Long agvId, List<Task> taskList) { + if (Cools.isEmpty(agvId, taskList)) { return; } try { - if (!(lockAcquired = this.lock.tryLock(LOCK_TIMEOUT, TimeUnit.SECONDS))) { - throw new CoolException("generate [task] action fail, cause can not acquire lock ..."); - } - // valid ----------------------------------------------- Agv agv = agvService.getById(agvId); if (!agvService.judgeEnable(agv.getId(), true)) { - throw new CoolException("AGV[" + agv.getUuid() + "]褰撳墠涓嶅彲鐢�..."); + return; +// throw new CoolException("AGV[" + agv.getUuid() + "]褰撳墠涓嶅彲鐢�..."); } if (!Cools.isEmpty(taskService.selectInSts(agvId, TaskStsType.ASSIGN, TaskStsType.PROGRESS))) { throw new CoolException("AGV[" + agv.getUuid() + "]鍒嗛厤浠诲姟澶辫触锛屽凡瀛樺湪鎵ц浠诲姟..."); + } + if (!Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.WAITING.toString())) + || !Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.RUNNING.toString()))) { + throw new CoolException("AGV[" + agv.getUuid() + "] failed to assign锛宐ecause already has the segment in running..."); } // execute ---------------------------------------------------- @@ -381,13 +350,19 @@ /** * 1.Map<String, List<TaskPosDto>> groups * - * key: 1000 + ORI_LOC + * key: 1000 + ORIGIN * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] * - * key: 3000 + ORI_LOC + * key: 3000 + ORIGIN * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] * - * key: 2000 + ORI_LOC + * key: 2000 + ORIGIN + * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] + * + * key: 1000 + DESTINATION + * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] + * + * key: 2000 + DESTINATION * val: [TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType), TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType),...] * * ...... @@ -405,6 +380,8 @@ * 瀵规墍鏈夊贩閬撹繘琛屾湁搴忔帓搴忥紝鍏堟槸閽堝List涓轰竴涓崟浣嶏紝瀵逛粬浠繘琛孎irstWeight鎺掑簭锛岀浉褰撲簬琛�1鐨刱ey鐨勬暟鍊艰繘琛屾湁搴忔帓搴� * List<TaskPosDto>: task list on the same lane * ArrayList<List<TaskPosDto>>: all the task list by one agv + * + * tip: ORI 鍜� DEST 姘歌繙涓嶄細瀛樺湪鍚屼竴涓� List */ ArrayList<List<TaskPosDto>> list = new ArrayList<>(groups.values()); list.sort((o1, o2) -> { @@ -421,45 +398,32 @@ Code currCode = codeService.getById(agvDetail.getRecentCode()); Double[] currPosition = new Double[] {currCode.getX(), currCode.getY()}; - List<TaskPosDto> theFirstOne = list.get(0); - List<TaskPosDto> theLastOne = list.get(list.size() - 1); + List<List<TaskPosDto>> pickGroups = new ArrayList<>(); + List<List<TaskPosDto>> dropGroups = new ArrayList<>(); - if (list.size() == 1) { - TaskPosDto head = theFirstOne.get(0); - TaskPosDto tail = theFirstOne.get(theFirstOne.size() - 1); - - int distanceByHead = CommonUtil.calcDistance(currPosition, head.getXy()); - int distanceByTail = CommonUtil.calcDistance(currPosition, tail.getXy()); - - if (distanceByTail < distanceByHead) { - Collections.reverse(theFirstOne); - } - - } else { - TaskPosDto headOfFirst = theFirstOne.get(0); - TaskPosDto tailOfFirst = theFirstOne.get(theFirstOne.size() - 1); - - TaskPosDto headOfLast = theLastOne.get(0); - TaskPosDto tailOfLast = theLastOne.get(theLastOne.size() - 1); - - int distanceByHeadOfFirst = CommonUtil.calcDistance(currPosition, headOfFirst.getXy()); - int distanceByTailOfFirst = CommonUtil.calcDistance(currPosition, tailOfFirst.getXy()); - - int distanceByHeadOfLast = CommonUtil.calcDistance(currPosition, headOfLast.getXy()); - int distanceByTailOfLast = CommonUtil.calcDistance(currPosition, tailOfLast.getXy()); - - if (Math.min(distanceByHeadOfLast, distanceByTailOfLast) < Math.min(distanceByHeadOfFirst, distanceByTailOfFirst)) { - Collections.reverse(list); - - if (distanceByTailOfLast < distanceByHeadOfLast) { - Collections.reverse(theLastOne); - } + for (List<TaskPosDto> group : list) { + // Assume 涓�涓换鍔$粍涓墍鏈塗askPosDto鐨凱osType.brief鐩稿悓 + TaskPosDto.PosType posType = group.get(0).getPosType(); + if (posType == TaskPosDto.PosType.ORI_LOC || posType == TaskPosDto.PosType.ORI_STA) { + pickGroups.add(group); + } else if (posType == TaskPosDto.PosType.DEST_LOC || posType == TaskPosDto.PosType.DEST_STA) { + dropGroups.add(group); } else { - if (distanceByTailOfFirst < distanceByHeadOfFirst) { - Collections.reverse(theFirstOne); - } + // import tip: the list must only contain ORIGIN and DESTINATION + log.error("the list must only contain ORIGIN and DESTINATION"); } } + + currPosition = allocateService.pac(currPosition, pickGroups); + currPosition = allocateService.pac(currPosition, dropGroups); + + List<List<TaskPosDto>> reorderedList = new ArrayList<>(); + reorderedList.addAll(pickGroups); + reorderedList.addAll(dropGroups); + + list.clear(); + list.addAll(reorderedList); + // generate travel Travel travel = new Travel(); @@ -516,33 +480,29 @@ } catch (Exception e) { - log.error("mainService.mergeMajorTask[task]", e); + log.error("mainService.buildMajorTask[task]", e); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); - } finally { - - if (lockAcquired) { - this.lock.unlock(); - } } } + /** * 鍏呯數 鍥炲緟鏈轰綅浠诲姟 */ - @Transactional - public synchronized boolean buildMinorTask(Agv agv, AgvDetail agvDetail, TaskTypeType taskType, String destination) { + @Transactional(propagation = Propagation.REQUIRES_NEW) // although there is a Transactional here that the lock is isolated, but we can't join the caller's Transactional + public boolean buildMinorTask(Agv agv, TaskTypeType taskType, String destination, Jam jam) { if (Cools.isEmpty(agv, taskType)) { return false; } - boolean lockAcquired = false; try { - if (!(lockAcquired = this.lock.tryLock(LOCK_TIMEOUT, TimeUnit.SECONDS))) { - throw new CoolException("generate [task] action fail, cause can not acquire lock ..."); - } - - if (null == agvDetail) { - agvDetail = agvDetailService.selectByAgvId(agv.getId()); - } + AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId()); if (!agvService.judgeEnable(agv.getId())) { return false; + } + if (!Cools.isEmpty(taskService.selectInSts(agv.getId(), TaskStsType.ASSIGN, TaskStsType.PROGRESS))) { + throw new CoolException("AGV[" + agv.getUuid() + "] failed to assign锛宐ecause already has the task in running..."); + } + if (!Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.WAITING.toString())) + || !Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.RUNNING.toString()))) { + throw new CoolException("AGV[" + agv.getUuid() + "] failed to assign锛宐ecause already has the segment in running..."); } Date now = new Date(); @@ -569,6 +529,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()); @@ -577,6 +540,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()); @@ -635,6 +603,10 @@ } if (!segmentService.save(next)) { throw new BusinessException("segment failed to save"); + } else { + if (null != jam && i == 0) { + jam.setAvoSeg(next.getId()); + } } } @@ -655,21 +627,12 @@ break; } -// if (taskType.equals(TaskTypeType.TO_STANDBY)) { -// redis.setObject(RedisConstant.AGV_TO_STANDBY_FLAG, agv.getUuid(), false); -// } - return true; } catch (Exception e) { log.error("mainService.buildMinorTask[task]", e); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return false; - } finally { - - if (lockAcquired) { - this.lock.unlock(); - } } } @@ -698,13 +661,12 @@ List<Action> actionList = new ArrayList<>(); // start node Code lastCode = codeService.getById(agvDetail.getRecentCode()); + Double lastDirection = agvDetail.getAgvAngle(); if (!lastCode.getData().equals(pathList.get(0))) { throw new CoolException("AGV[" + agv.getUuid() + "]瀹氫綅鍋忕Щ..."); } - Double lastDirection = agvDetail.getAgvAngle(); boolean first = true; - for (Segment segment : segmentList) { // 鍒嗘鎵�灞炵殑Task @@ -936,7 +898,7 @@ break; case TO_CHARGE: // 妫�楠屾柟鍚� - FuncSta chargeFuncSta = funcStaService.query(agvId, lastCode.getId(), FuncStaType.CHARGE.toString()); + FuncSta chargeFuncSta = funcStaService.query(lastCode.getId(), FuncStaType.CHARGE.toString()); Double chargeDirection = Double.parseDouble(chargeFuncSta.getAngle()); if (!lastDirection.equals(chargeDirection)) { actionList.add(new Action( @@ -1081,6 +1043,7 @@ for (Action action : actionList) { action.setActionSts(ActionStsType.ISSUED.val()); action.setStartTime(now); + action.setIoTime(now); action.setUpdateTime(now); if (!actionService.updateById(action)) { throw new BusinessException(action.getPriority() + " - " + action.getName() + "鍔ㄤ綔鏇存柊澶辫触"); @@ -1355,7 +1318,7 @@ } // segment call back - trafficService.callback(segmentList); + segmentService.processNext(segmentList); log.info("Agv [{}] {}浣滀笟瀹屾瘯 ==========>> ", protocol.getAgvNo(), serialNo); -- Gitblit v1.9.1