From 6cbb420754e6e29fa134a6afca4514b8dfd62918 Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期二, 13 一月 2026 16:14:49 +0800
Subject: [PATCH] #
---
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java | 983 +++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 805 insertions(+), 178 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 6dd57dd..90f5fe9 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
@@ -2,19 +2,17 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.zy.acs.common.constant.RedisConstant;
import com.zy.acs.common.domain.AgvAction;
import com.zy.acs.common.domain.AgvActionItem;
import com.zy.acs.common.domain.AgvProtocol;
import com.zy.acs.common.domain.BaseResult;
-import com.zy.acs.common.domain.protocol.AGV_11_UP;
-import com.zy.acs.common.domain.protocol.AGV_70_UP;
-import com.zy.acs.common.domain.protocol.IMessageBody;
+import com.zy.acs.common.domain.protocol.*;
import com.zy.acs.common.domain.protocol.action.*;
-import com.zy.acs.common.enums.AgvBackpackType;
-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.enums.*;
import com.zy.acs.common.utils.GsonUtils;
+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;
@@ -23,8 +21,9 @@
import com.zy.acs.manager.common.domain.param.HandlerPublishParam;
import com.zy.acs.manager.common.exception.BusinessException;
import com.zy.acs.manager.core.domain.AgvBackpackDto;
-import com.zy.acs.manager.core.domain.Lane;
+import com.zy.acs.manager.core.domain.LaneDto;
import com.zy.acs.manager.core.domain.TaskPosDto;
+import com.zy.acs.manager.core.integrate.conveyor.ConveyorStationService;
import com.zy.acs.manager.core.service.astart.MapDataDispatcher;
import com.zy.acs.manager.manager.controller.param.OpenBusSubmitParam;
import com.zy.acs.manager.manager.entity.*;
@@ -35,7 +34,7 @@
import com.zy.acs.manager.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
@@ -47,8 +46,10 @@
* Created by vincent on 2023/6/14
*/
@Slf4j
-@Component("mainService")
+@Service("mainService")
public class MainService {
+
+ private final RedisSupport redis = RedisSupport.defaultRedisSupport;
@Autowired
private BusService busService;
@@ -89,14 +90,17 @@
@Autowired
private SegmentService segmentService;
@Autowired
- private TrafficService trafficService;
+ private LaneService laneService;
@Autowired
private AgvModelService agvModelService;
@Autowired
- private LaneService laneService;
+ private LaneBuilder laneBuilder;
@Autowired
private ActionSorter actionSorter;
-
+ @Autowired
+ private StaReserveService staReserveService;
+ @Autowired
+ private ConveyorStationService conveyorStationService;
@SuppressWarnings("all")
@Transactional
@@ -175,8 +179,18 @@
if (!locService.updateById(oriLoc)) {
throw new BusinessException("oriLoc锛�" + task.getOriLoc$() + " failed to update");
}
+
+ destSta = staService.getById(task.getDestSta());
+ if (null == staReserveService.reserveStaIn(destSta, task, 1)) {
+ throw new BusinessException("destSta锛�" + task.getDestSta$() + " failed to reserve");
+ }
break;
case STA_TO_LOC:
+ oriSta = staService.getById(task.getOriSta());
+ if (null == staReserveService.reserveStaOut(oriSta, task, 1)) {
+ throw new BusinessException("oriSta锛�" + task.getOriSta$() + " failed to reserve");
+ }
+
destLoc = locService.getById(task.getDestLoc());
if (!destLoc.getLocSts().equals(LocStsType.IDLE.val())) {
throw new BusinessException("destLoc锛�" + task.getDestLoc$() + " is not in IDLE status");
@@ -188,6 +202,15 @@
}
break;
case STA_TO_STA:
+ oriSta = staService.getById(task.getOriSta());
+ if (null == staReserveService.reserveStaOut(oriSta, task, 1)) {
+ throw new BusinessException("oriSta锛�" + task.getOriSta$() + " failed to reserve");
+ }
+
+ destSta = staService.getById(task.getDestSta());
+ if (null == staReserveService.reserveStaIn(destSta, task, 1)) {
+ throw new BusinessException("destSta锛�" + task.getDestSta$() + " failed to reserve");
+ }
break;
default:
break;
@@ -211,28 +234,247 @@
);
if (Cools.isEmpty(taskList)) {
- bus.setBusSts(BusStsType.PROGRESS.val());
- bus.setUpdateTime(now);
- if (!busService.updateById(bus)) {
- log.error("Bus [{}] failed to Update 锛侊紒锛�", bus.getUuid());
+ if (bus.getBusSts().equals(BusStsType.RECEIVE.val())) {
+ bus.setBusSts(BusStsType.PROGRESS.val());
+ bus.setUpdateTime(now);
+ if (!busService.updateById(bus)) {
+ log.error("Bus [{}] failed to Update 锛侊紒锛�", bus.getUuid());
+ }
}
return;
}
- List<Long> taskIds = taskList.stream().map(Task::getId).distinct().collect(Collectors.toList());
- 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());
- 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");
- }
+// List<Long> taskIds = taskList.stream().map(Task::getId).distinct().collect(Collectors.toList());
+ for (Task t : taskList) {
+ String resultAgvNo = allocateService.execute(t
+ // inbound
+ , (task, agvNo, sta) -> {
+ Long agvId = agvService.getAgvId(agvNo);
+
+// List<Travel> travelList = travelService.list(new LambdaQueryWrapper<Travel>()
+// .eq(Travel::getAgvId, agvId)
+// .eq(Travel::getState, TravelStateType.RUNNING.toString())
+// .orderByDesc(Travel::getCreateTime));
+// if (Cools.isEmpty(travelList)) {
+// throw new BusinessException("[Agv: " + agvNo + "]allocate inbound failed to find travel");
+// }
+// Travel travel = travelList.get(0);
+//
+// List<Segment> currSegments = segmentService.list(new LambdaQueryWrapper<Segment>()
+// .eq(Segment::getAgvId, agvId)
+// .eq(Segment::getTravelId, travel.getId())
+// );
+ // load segment
+ Segment currSeg = segmentService.getRollerWaiting(agvId, sta.getCode(), TaskPosDto.PosType.ORI_STA);
+ if (null == currSeg) {
+ throw new BusinessException("[Agv:" + agvNo + "] allocate inbound failed: no roller waiting segment");
+ }
+
+ // get backpack lev
+ int backpackLev = 0;
+ int backpack = agvService.getBackpack(agvId);
+ List<Integer> usedBackpacks = segmentService.selectUsedBackpacks(currSeg.getTravelId(), agvId);
+ if (usedBackpacks.size() >= backpack) {
+ throw new CoolException("[Agv:" + agvNo + "] allocate inbound segment failed: no idle backpack to use");
+ }
+ for (int lev = 1; lev <= backpack; lev++) {
+ if (!usedBackpacks.contains(lev)) {
+ backpackLev = lev;
+ break;
+ }
+ }
+ if (backpackLev == 0) {
+ throw new BusinessException("[Agv:" + agvNo + "] backpack full, can't allocate inbound");
+ }
+
+ // update curr seg
+ currSeg.setState(SegmentStateType.INIT.toString());
+ currSeg.setUpdateTime(now);
+ if (!segmentService.updateById(currSeg)) {
+// log.error("Segment [{}] failed to update 锛侊紒锛�", currSeg.getGroupId() + " - " + currSeg.getSerial());
+ throw new CoolException("failed to update segment [" + currSeg.getGroupId() + "-" + currSeg.getSerial() + "] failed");
+ }
+
+ // new oriSta seg
+ Segment loadSeg = new Segment();
+ loadSeg.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
+ loadSeg.setTravelId(currSeg.getTravelId());
+ loadSeg.setAgvId(agvId);
+ loadSeg.setTaskId(task.getId());
+ loadSeg.setSerial(currSeg.getSerial() - 1);
+ loadSeg.setEndNode(sta.getCode());
+ loadSeg.setPosType(TaskPosDto.PosType.ORI_STA.toString());
+ loadSeg.setState(SegmentStateType.WAITING.toString());
+ loadSeg.setBackpack(backpackLev);
+ loadSeg.setCreateTime(now);
+ loadSeg.setUpdateTime(now);
+ if (!segmentService.save(loadSeg)) {
+// log.error("Segment [{}] failed to save 锛侊紒锛�", loadSeg.getTravelId() + " - " + loadSeg.getSerial());
+ throw new CoolException("failed to save segment [" + loadSeg.getGroupId() + "-" + loadSeg.getSerial() + "] failed");
+ }
+
+ // place segment
+ TaskTypeType taskType = Objects.requireNonNull(TaskTypeType.get(task.getTaskTypeEl()));
+ TaskPosDto.PosType posType;
+ Code endCode;
+ switch (taskType) {
+ case STA_TO_LOC:
+ posType = TaskPosDto.PosType.DEST_LOC;
+ Loc destLoc = locService.getById(task.getDestLoc());
+ endCode = codeService.getCacheById(destLoc.getCode());
+ break;
+ case STA_TO_STA:
+ posType = TaskPosDto.PosType.DEST_STA;
+ Sta destSta = staService.getById(task.getDestSta());
+ endCode = codeService.getCacheById(destSta.getCode());
+ break;
+ default:
+ throw new BusinessException("[Agv:" + agvNo + "] allocate inbound only supports STA_TO_LOC/STA_TO_STA");
+ }
+
+ // calc placeSeg serial, through code position
+ List<Segment> destSegList = segmentService.list(new LambdaQueryWrapper<Segment>()
+ .eq(Segment::getAgvId, agvId)
+ .eq(Segment::getTravelId, currSeg.getTravelId())
+ .ne(Segment::getState, SegmentStateType.FINISH.toString())
+ .in(Segment::getPosType,
+ TaskPosDto.PosType.DEST_LOC.toString(),
+ TaskPosDto.PosType.DEST_STA.toString())
+ .orderByAsc(Segment::getSerial)
+ );
+
+ // build destPosList and sort
+ List<TaskPosDto> destPosList = new ArrayList<>();
+ for (Segment destSeg : destSegList) {
+ Code code = codeService.getCacheById(destSeg.getEndNode());
+ if (code == null) continue;
+
+ TaskPosDto dto = new TaskPosDto(destSeg.getTaskId(), new Double[]{code.getX(), code.getY()}, TaskPosDto.PosType.DEST_LOC);
+ dto.setCodeId(code.getId());
+ dto.setSegId(destSeg.getId());
+ destPosList.add(dto);
+ }
+ TaskPosDto newDto = new TaskPosDto(task.getId(), new Double[]{endCode.getX(), endCode.getY()}, TaskPosDto.PosType.DEST_LOC);
+ newDto.setCodeId(endCode.getId());
+ destPosList.add(newDto);
+
+ // sort - reference to buildMarjoTask
+ final String sameGroupXy = configService.getVal("sameGroupXy", String.class);
+
+ // DEST-only sort
+ destPosList.sort((a, b) -> {
+
+ // 涓昏酱
+ double aFirst = a.getFirstWeight(sameGroupXy);
+ double bFirst = b.getFirstWeight(sameGroupXy);
+ int c = Double.compare(aFirst, bFirst);
+ if (c != 0) return c;
+
+ // 鍓酱
+ double aSecond = a.getSecondWeight(sameGroupXy);
+ double bSecond = b.getSecondWeight(sameGroupXy);
+ c = Double.compare(aSecond, bSecond);
+ if (c != 0) return c;
+
+ return Long.compare(a.getTaskId(), b.getTaskId());
+ });
+
+ // get placeSeg serial
+ int placeSegSerial;
+ // query placeSeg idx
+ int idx = -1;
+ for (int i = 0; i < destPosList.size(); i++) {
+ if (Objects.equals(destPosList.get(i).getCodeId(), newDto.getCodeId())
+ && Objects.equals(destPosList.get(i).getTaskId(), newDto.getTaskId())) {
+ idx = i;
+ break;
+ }
+ }
+ if (idx < 0) {
+ throw new BusinessException("failed to locate new destination in sorted list");
+ }
+
+ // 鍚庣户鐐�
+ if (idx + 1 == destPosList.size()) {
+ placeSegSerial = destSegList.get(destSegList.size() - 1).getSerial() + 1;
+ } else {
+ TaskPosDto afterTaskPos = destPosList.get(idx + 1);
+ Segment afterSeg = destSegList.stream()
+ .filter(destSeg -> Objects.equals(destSeg.getId(), afterTaskPos.getSegId()))
+ .findFirst()
+ .orElse(null);
+ if (null == afterSeg) {
+ placeSegSerial = destSegList.get(destSegList.size() - 1).getSerial() + 1;
+ } else {
+ placeSegSerial = afterSeg.getSerial();
+ }
+ }
+// placeSegSerial = Math.max(placeSegSerial, currSeg.getSerial() + 1);
+
+ // shift serial after
+ segmentService.update(new LambdaUpdateWrapper<Segment>()
+ .eq(Segment::getAgvId, agvId)
+ .eq(Segment::getTravelId, currSeg.getTravelId())
+ .ge(Segment::getSerial, placeSegSerial)
+ .ne(Segment::getState, SegmentStateType.FINISH.toString())
+ .setSql("serial = serial + 1")
+ .set(Segment::getUpdateTime, now)
+ );
+
+ // save place segment
+ Segment placeSeg = new Segment();
+ placeSeg.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
+ placeSeg.setTravelId(currSeg.getTravelId());
+ placeSeg.setAgvId(agvId);
+ placeSeg.setTaskId(task.getId());
+ placeSeg.setSerial(placeSegSerial);
+ placeSeg.setEndNode(endCode.getId());
+ placeSeg.setPosType(posType.toString());
+ placeSeg.setState(SegmentStateType.INIT.toString());
+ placeSeg.setBackpack(backpackLev);
+ placeSeg.setCreateTime(now);
+ placeSeg.setUpdateTime(now);
+ if (!segmentService.save(placeSeg)) {
+// log.error("Segment [{}] failed to save 锛侊紒锛�", placeSeg.getTravelId() + " - " + placeSeg.getSerial());
+ throw new CoolException("failed to save segment [" + placeSeg.getGroupId() + "-" + placeSeg.getSerial() + "] failed");
+ }
+
+ // update task
+ task.setAgvId(agvId);
+ task.setTaskSts(TaskStsType.ASSIGN.val());
+ task.setIoTime(now);
+ task.setUpdateTime(now);
+ if (!taskService.updateById(task)) {
+ throw new BusinessException("seqNum: " + task.getSeqNum() + " failed to update");
+ }
+ // update reserve
+ staReserveService.allocateCallBack(task, agvId);
+ }
+ // normal
+ , (task, agvNo, sta) -> {
+ Long agvId = agvService.getAgvId(agvNo);
+ // update task
+ task.setAgvId(agvId);
+ task.setTaskSts(TaskStsType.WAITING.val());
+ task.setIoTime(now);
+ task.setUpdateTime(now);
+ if (!taskService.updateById(task)) {
+ throw new BusinessException("seqNum: " + task.getSeqNum() + " failed to update");
+ }
+ // update reserve
+ staReserveService.allocateCallBack(task, agvId);
+ });
+// if (Cools.isEmpty(agvNo)) {
+//// log.warn("Task[{}] has an issue锛� because it failed to check out agv which is idle...", task.getSeqNum());
+// continue;
+// }
+// task.setAgvId(agvService.getAgvId(agvNo));
+// task.setTaskSts(TaskStsType.WAITING.val());
+// task.setIoTime(now);
+// task.setUpdateTime(now);
+// if (!taskService.updateById(task)) {
+// throw new BusinessException("seqNum: " + task.getSeqNum() + " failed to update");
+// }
}
} catch (Exception e) {
log.error("mainService.infuseAgvForTask", e);
@@ -250,7 +492,7 @@
try {
// valid -----------------------------------------------
Agv agv = agvService.getById(agvId);
- if (!agvService.judgeEnable(agv.getId(), true)) {
+ if (!agvService.judgeEnable(agv.getId(), false)) {
return;
}
if (!Cools.isEmpty(taskService.selectInSts(agvId, TaskStsType.ASSIGN, TaskStsType.PROGRESS))) {
@@ -270,7 +512,7 @@
return o2.getPriority() - o1.getPriority();
}
});
- Integer backpack = agvService.getBackpack(agv);
+ Integer backpack = agvService.getBackpack(agvId);
if (taskList.size() > backpack) {
taskList = taskList.subList(0, backpack);
}
@@ -286,7 +528,7 @@
* val: new TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType)
*/
Map<String, List<TaskPosDto>> groups = new HashMap<>();
- final String sameGroupXy = configService.getVal( "sameGroupXy", String.class);
+ final String sameGroupXy = configService.getVal("sameGroupXy", String.class);
int backpackLev = 0;
for (Task task : taskList) {
@@ -301,8 +543,8 @@
oriLoc = locService.getById(task.getOriLoc());
destLoc = locService.getById(task.getDestLoc());
- startCode = codeService.getById(oriLoc.getCode());
- endCode = codeService.getById(destLoc.getCode());
+ startCode = codeService.getCacheById(oriLoc.getCode());
+ endCode = codeService.getCacheById(destLoc.getCode());
TaskPosDto.packagePosGroup(groups, task, startCode, TaskPosDto.PosType.ORI_LOC, sameGroupXy);
TaskPosDto.packagePosGroup(groups, task, endCode, TaskPosDto.PosType.DEST_LOC, sameGroupXy);
@@ -311,8 +553,8 @@
oriLoc = locService.getById(task.getOriLoc());
destSta = staService.getById(task.getDestSta());
- startCode = codeService.getById(oriLoc.getCode());
- endCode = codeService.getById(destSta.getCode());
+ startCode = codeService.getCacheById(oriLoc.getCode());
+ endCode = codeService.getCacheById(destSta.getCode());
TaskPosDto.packagePosGroup(groups, task, startCode, TaskPosDto.PosType.ORI_LOC, sameGroupXy);
TaskPosDto.packagePosGroup(groups, task, endCode, TaskPosDto.PosType.DEST_STA, sameGroupXy);
@@ -321,8 +563,8 @@
oriSta = staService.getById(task.getOriSta());
destLoc = locService.getById(task.getDestLoc());
- startCode = codeService.getById(oriSta.getCode());
- endCode = codeService.getById(destLoc.getCode());
+ startCode = codeService.getCacheById(oriSta.getCode());
+ endCode = codeService.getCacheById(destLoc.getCode());
TaskPosDto.packagePosGroup(groups, task, startCode, TaskPosDto.PosType.ORI_STA, sameGroupXy);
TaskPosDto.packagePosGroup(groups, task, endCode, TaskPosDto.PosType.DEST_LOC, sameGroupXy);
@@ -331,8 +573,8 @@
oriSta = staService.getById(task.getOriSta());
destSta = staService.getById(task.getDestSta());
- startCode = codeService.getById(oriSta.getCode());
- endCode = codeService.getById(destSta.getCode());
+ startCode = codeService.getCacheById(oriSta.getCode());
+ endCode = codeService.getCacheById(destSta.getCode());
TaskPosDto.packagePosGroup(groups, task, startCode, TaskPosDto.PosType.ORI_STA, sameGroupXy);
TaskPosDto.packagePosGroup(groups, task, endCode, TaskPosDto.PosType.DEST_STA, sameGroupXy);
@@ -397,7 +639,7 @@
}
// re-order by agv current position
- Code currCode = codeService.getById(agvDetail.getRecentCode());
+ Code currCode = codeService.getCacheById(agvDetail.getRecentCode());
Double[] currPosition = new Double[] {currCode.getX(), currCode.getY()};
List<List<TaskPosDto>> pickGroups = new ArrayList<>();
@@ -428,6 +670,7 @@
// generate travel
+ travelService.finishAll(agvId);
Travel travel = new Travel();
travel.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
travel.setTravelId(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
@@ -435,6 +678,8 @@
travel.setTaskContent(JSON.toJSONString(list));
travel.setTaskIds(JSON.toJSONString(taskList.stream().map(Task::getId).collect(Collectors.toList())));
travel.setState(TravelStateType.RUNNING.toString());
+ travel.setCreateTime(now);
+ travel.setUpdateTime(now);
if (!travelService.save(travel)) {
throw new BusinessException("浠诲姟缁勪繚瀛樺け璐�");
}
@@ -458,6 +703,8 @@
segment.setPosType(taskPosDto.getPosType().toString());
segment.setBackpack(backpackType.lev);
segment.setState(SegmentStateType.INIT.toString());
+ segment.setCreateTime(now);
+ segment.setUpdateTime(now);
segmentList.add(segment);
}
}
@@ -493,33 +740,34 @@
* 鍏呯數 鍥炲緟鏈轰綅浠诲姟
*/
@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; }
+ public boolean buildMinorTask(Long agvId, TaskTypeType taskType, String destination, Jam jam) {
+ if (Cools.isEmpty(agvId, taskType)) { return false; }
try {
- AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
- if (!agvService.judgeEnable(agv.getId())) {
+ String agvNo = agvService.getAgvNo(agvId);
+ if (!agvService.judgeEnable(agvId)) {
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(taskService.selectInSts(agvId, TaskStsType.ASSIGN, TaskStsType.PROGRESS))) {
+ throw new CoolException("AGV[" + agvNo + "] 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...");
+ if (!Cools.isEmpty(segmentService.getByAgvAndState(agvId, SegmentStateType.WAITING.toString()))
+ || !Cools.isEmpty(segmentService.getByAgvAndState(agvId, SegmentStateType.RUNNING.toString()))) {
+ throw new CoolException("AGV[" + agvNo + "] failed to assign锛宐ecause already has the segment in running...");
}
Date now = new Date();
+ AgvDetail agvDetail = agvDetailService.selectMajorByAgvId(agvId);
Code endCode = null;
switch (taskType) {
case TO_CHARGE:
case TO_STANDBY:
- List<FuncSta> idleFunStaList = funcStaService.findInIdleStatus(FuncStaType.query(taskType), agv.getId());
+ List<FuncSta> idleFunStaList = funcStaService.findInIdleStatus(FuncStaType.query(taskType), agvId);
if (!Cools.isEmpty(idleFunStaList)) {
FuncSta funcSta = funcStaService.checkoutClosestFunSta(agvDetail.getRecentCode(), idleFunStaList);
- endCode = codeService.getById(funcSta.getCode());
+ endCode = codeService.getCacheById(funcSta.getCode());
}
if (null == endCode) {
- log.warn("AGV[{}] failed to search destination锛宼here hadn't any idle funSta锛孴askTypeType锛歿}", agv.getUuid(), taskType.toString());
+ log.warn("AGV[{}] failed to search destination锛宼here hadn't any idle funSta锛孴askTypeType锛歿}", agvNo, taskType.toString());
}
break;
case MOVE:
@@ -532,21 +780,21 @@
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() + "]!!!");
+ if (!allocateService.validCapacityOfLane(agvNo, endCode)) {
+ throw new BusinessException("the lane with code:" + endCode.getData() + " is full of AGV[" + agvNo + "]!!!");
}
Task task = new Task();
- task.setAgvId(agv.getId());
+ task.setAgvId(agvId);
task.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
List<Task> lastTasks = taskService.list(new LambdaQueryWrapper<Task>().orderByDesc(Task::getId));
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());
+ LaneDto destLaneDto = laneBuilder.search(endCode.getData());
+ if (null != destLaneDto) {
+ task.setDestLaneHash(destLaneDto.getHashCode());
}
task.setPriority(taskType.equals(TaskTypeType.TO_CHARGE)?2:1);
task.setTaskSts(TaskStsType.ASSIGN.val());
@@ -558,10 +806,11 @@
}
// generate travel
+ travelService.finishAll(agvId);
Travel travel = new Travel();
travel.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
travel.setTravelId(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
- travel.setAgvId(agv.getId());
+ travel.setAgvId(agvId);
// travel.setTaskContent(JSON.toJSONString(list));
travel.setTaskIds(GsonUtils.toJson(Utils.singletonList(task.getId())));
travel.setState(TravelStateType.RUNNING.toString());
@@ -591,7 +840,7 @@
Segment segment = new Segment();
segment.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
segment.setTravelId(travel.getId());
- segment.setAgvId(agv.getId());
+ segment.setAgvId(agvId);
segment.setTaskId(task.getId());
segment.setSerial(segSerial);
segment.setEndNode(endCode.getId());
@@ -652,12 +901,15 @@
// JSONObject storeDirection = configService.getVal("storeDirection", JSONObject.class);
int angleOffsetVal = configService.getVal("mapAngleOffsetVal", Integer.class);
String agvNo = agvService.getAgvNo(agvId);
- if (!agvService.judgeEnable(agvId)) {
- throw new CoolException("AGV[" + agvNo + "]褰撳墠涓嶅彲鐢�...");
- }
+// if (!agvService.judgeEnable(agvId)) {
+// throw new CoolException("AGV[" + agvNo + "]褰撳墠涓嶅彲鐢�...");
+// }
AgvModel agvModel = agvModelService.getByAgvId(agvId);
Double workDirection = agvModel.getWorkDirection();
+ final double oppWorkDir = (workDirection + 180) % 360;
+ boolean backupAction = null != agvModel.getBackupAction() && agvModel.getBackupActionBool();
+ boolean needUndocking = null != agvModel.getNeedUndocking() && agvModel.getNeedUndockingBool();
AgvSpeedType agvSpeedType = AgvSpeedType.query(agvModel.getTravelSpeed());
assert agvSpeedType != null;
@@ -665,8 +917,8 @@
List<Action> actionList = new ArrayList<>();
// start node
- Code lastCode = codeService.getById(agvDetail.getRecentCode());
- Double lastDirection = agvDetail.getAgvAngle();
+ Code lastCode = codeService.getCacheById(agvDetail.getRecentCode());
+ Double lastDirection = MapService.mapToNearest(agvDetail.getAgvAngle());
if (!lastCode.getData().equals(pathList.get(0))) {
throw new CoolException("AGV[" + agvNo + "]瀹氫綅鍋忕Щ...");
}
@@ -678,7 +930,7 @@
Task task = taskService.getById(segment.getTaskId());
// 鑺傜偣鏉$爜
- Code code = codeService.getById(segment.getEndNode());
+ Code code = codeService.getCacheById(segment.getEndNode());
// 闇�瑕佽蛋琛�
if (!lastCode.getData().equals(code.getData())) {
@@ -693,14 +945,114 @@
String next = pathListPart.get(i);
Code nextCode = codeService.getCacheByData(next);
+ // 杞﹀ご鏈濆墠鐨勪笅涓�涓璧版柟鍚�
Double nextDirection = mapService.calculateDirection(lastCode, nextCode, angleOffsetVal);
+ // 鍙嶅悜瑙�
+ final double oppLastDir = (lastDirection + 180) % 360;
+ // 鏄惁鍊掗��琛岃蛋
boolean reverse = false;
- if (nextDirection.equals((workDirection + 180) % 360)) {
- nextDirection = workDirection;
- reverse = true;
+
+ // 宸烽亾閫昏緫
+ if (!laneBuilder.isInitialized()) {
+ throw new CoolException("lanes are not initialized");
}
- if (!lastDirection.equals(nextDirection) || actionList.isEmpty()) {
+ LaneDto lastLaneDto = laneBuilder.search(lastCode.getData());
+ LaneDto nextLaneDto = laneBuilder.search(nextCode.getData());
+ // 杩涘叆宸烽亾瑙掑害
+ Double lastLaneDir = laneService.getLaneDirection(lastLaneDto);
+ Double nextLaneDir = laneService.getLaneDirection(nextLaneDto);
+
+ // 宸烽亾寮哄埗杞集锛屼紭鍏堢骇 > workDirection
+ if (null != nextLaneDir) {
+ nextDirection = nextLaneDir;
+
+ if (!lastDirection.equals(nextDirection)) {
+ if (!lastCode.getCornerBool()) {
+ throw new CoolException(agvNo + "鍙峰皬杞﹁繘鍏ュ贩閬撻渶璋冩暣鏂瑰悜涓� " + nextDirection + "掳锛岃鎺ㄨ嚦杞集鐐规墜鍔ㄨ皟鏁�");
+ }
+ // turn
+ actionList.add(new Action(
+ null, // 缂栧彿s
+ task.getBusId(), // 鎬荤嚎
+ task.getId(), // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.TurnCorner.desc, // 鍚嶇О
+ (double) mapService.spinDirection(lastCode).val, // 灞炴�у��
+ lastCode.getData(), // 鍦伴潰鐮�
+ String.valueOf(nextDirection), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.TurnCorner.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
+ lastDirection = nextDirection;
+ }
+ } else if (null != lastLaneDir) {
+ nextDirection = lastLaneDir;
+
+ if (!lastDirection.equals(nextDirection)) {
+ if (!lastCode.getCornerBool()) {
+ throw new CoolException(agvNo + "鍙峰皬杞︾寮�宸烽亾闇�璋冩暣鏂瑰悜涓� " + nextDirection + "掳锛岃鎺ㄨ嚦杞集鐐规墜鍔ㄨ皟鏁�");
+ }
+ }
+ } else {
+
+ // 濡傛灉涓嬩竴涓柟鍚戞濂芥槸浣滀笟鏂瑰悜鐨勭浉鍙嶆柟鍚戯紝鍒欓噸缃笅涓�涓柟鍚戜负浣滀笟鏂瑰悜锛屾爣璁� reverse = true
+ if (nextDirection.equals(oppWorkDir)) {
+ nextDirection = workDirection;
+ reverse = true;
+ }
+
+ // 鍒ゆ柇褰撳墠鑺傜偣鏄惁鍙互鏃嬭浆
+ if (!lastCode.getCornerBool()) {
+ // 濡傛灉鏄綔涓氭柟鍚戯紝浣嗘槸灏忚溅鍦ㄥ贩閬撳唴鏂瑰悜閿欒锛屽垯鍋滄
+ if (reverse && !lastDirection.equals(nextDirection)) {
+ throw new CoolException(agvNo + "鍙峰皬杞︽柟鍚戦敊璇紝璇锋帹鑷宠浆寮偣鎵嬪姩璋冩暣");
+ }
+ // 濡傛灉涓嶆槸浣滀笟鏂瑰悜锛堝彟涓�缁勭浉鍙嶆柟鍚戯級锛屽垽鏂槸鍚︾浉鍙嶆柟鍚戯紝濡傛灉鍙嶆柟鍚戝垯鍊掗��琛岃蛋
+ if (nextDirection.equals(oppLastDir)) {
+ // 鍊掗��鏃讹紝鍥犱负agv鏂瑰悜娌″彉锛屾墍浠ヤ笅涓�涓柟鍚戣繕鏄痑gv鏂瑰悜锛屾晠nextDirection = lastDirection;
+ nextDirection = lastDirection;
+ reverse = true;
+ }
+ // 鎬荤粨锛�1.濡傛灉鏄綔涓氱粍锛堝樊180掳锛夋柟鍚戯紝閭d箞agv鏂瑰悜蹇呴』鏄綔涓氭柟鍚戯紝濡傛灉 reverse 鍒欒鏄庡�掗��锛岃繖鏃跺�檔extDirection鑲畾浼氱瓑浜庝綔涓氭柟鍚戯紙鍓嶉潰璧嬪�间簡锛夛紝濡傛灉涓嶇浉鍚岋紝鍒欐姤閿�
+ // 2.濡傛灉涓嶆槸浣滀笟缁勬柟鍚戯紙鍙︿竴缁勭浉鍙嶆柟鍚戝樊180掳锛夛紝鍥犱负姝ゅ嚱鏁颁笉鑳芥棆杞紝鎵�浠ュ樊180掳鏃跺彧鑳藉�掗��锛屽�掗��鐨勬椂鍊欏洜涓篴gv涓嶄細鏃嬭浆锛屾墍浠extDirection瑕佸彉鎴恆gv鏂瑰悜
+ } else {
+ if (!lastDirection.equals(nextDirection)) {
+ // 濡傛灉涓嬩竴涓柟鍚戜笌agv鏂瑰悜鐩稿弽锛屽垯鍊掗��琛岃蛋锛岄伩鍏嶈繘琛屾鏃犳剰涔夌殑杞集鍔ㄤ綔銆�
+ // 浣嗘槸瑕佹敞鎰忥細濡傛灉agv鏂瑰悜涓庡伐浣滄柟鍚戞濂界浉鍙嶏紝鍒欓渶瑕佹棆杞嚦宸ヤ綔鏂瑰悜锛屼篃灏辨槸涓轰粈涔堣鍔�!workDirection.equals(oppLastDir)鍒ゆ柇
+ if (nextDirection.equals(oppLastDir) && !workDirection.equals(oppLastDir)) {
+ // 鍊掗��鏃讹紝鍥犱负agv鏂瑰悜娌″彉锛屾墍浠ヤ笅涓�涓柟鍚戣繕鏄痑gv鏂瑰悜锛屾晠nextDirection = lastDirection;
+ nextDirection = lastDirection;
+ reverse = true;
+ } else {
+ // turn
+ actionList.add(new Action(
+ null, // 缂栧彿s
+ task.getBusId(), // 鎬荤嚎
+ task.getId(), // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.TurnCorner.desc, // 鍚嶇О
+ (double) mapService.spinDirection(lastCode).val, // 灞炴�у��
+ lastCode.getData(), // 鍦伴潰鐮�
+ String.valueOf(nextDirection), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.TurnCorner.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
+
+ lastDirection = nextDirection;
+ }
+ }
+ }
+ }
+
+ // 绗竴涓姩浣滀竴瀹氭槸 turn
+ if (actionList.isEmpty()) {
// turn
actionList.add(new Action(
null, // 缂栧彿
@@ -709,7 +1061,7 @@
null, // 鍔ㄤ綔鍙�
null, // 浼樺厛绾�
ActionTypeType.TurnCorner.desc, // 鍚嶇О
- mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D, // 灞炴�у��
+ (double) mapService.spinDirection(lastCode).val, // 灞炴�у��
lastCode.getData(), // 鍦伴潰鐮�
String.valueOf(nextDirection), // 鍔ㄤ綔鍙傛暟
ActionTypeType.TurnCorner.val(), // 鍔ㄤ綔绫诲瀷
@@ -719,14 +1071,10 @@
));
lastDirection = nextDirection;
-
}
// run
- ActionTypeType actionType = ActionTypeType.StraightAheadTurnable;
- if (reverse) {
- actionType = ActionTypeType.StraightBackTurnable;
- }
+ ActionTypeType actionType = reverse ? ActionTypeType.StraightBackTurnable : ActionTypeType.StraightAheadTurnable;
CodeGap gap = codeGapService.findByCodeOfBoth(lastCode.getId(), nextCode.getId());
actionList.add(new Action(
null, // 缂栧彿
@@ -753,6 +1101,25 @@
// 鍒濆鏂瑰悜鍊艰ˉ涓�
if (first) {
if (Cools.isEmpty(actionList) || !actionList.get(0).getActionType().equals(ActionTypeType.TurnCorner.val())) {
+ Double firstTurnDir = workDirection;
+
+ // 宸烽亾閫昏緫
+ if (!laneBuilder.isInitialized()) {
+ throw new CoolException("lanes are not initialized");
+ }
+ LaneDto lastLaneDto = laneBuilder.search(lastCode.getData());
+ // 杩涘叆宸烽亾瑙掑害
+ Double lastLaneDir = laneService.getLaneDirection(lastLaneDto);
+ if (lastLaneDir != null) {
+ firstTurnDir = lastLaneDir;
+ }
+
+ if (!lastDirection.equals(firstTurnDir)) {
+ if (!lastCode.getCornerBool()) {
+ throw new CoolException(agvNo + "鍙峰皬杞︽柟鍚戦敊璇紝璇锋帹鑷宠浆寮偣鎵嬪姩璋冩暣");
+ }
+ }
+
// turn
actionList.add(new Action(
null, // 缂栧彿
@@ -761,16 +1128,16 @@
null, // 鍔ㄤ綔鍙�
null, // 浼樺厛绾�
ActionTypeType.TurnCorner.desc, // 鍚嶇О
- mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D, // 灞炴�у��
+ (double) mapService.spinDirection(lastCode).val, // 灞炴�у��
lastCode.getData(), // 鍦伴潰鐮�
- String.valueOf(workDirection), // 鍔ㄤ綔鍙傛暟
+ String.valueOf(firstTurnDir), // 鍔ㄤ綔鍙傛暟
ActionTypeType.TurnCorner.val(), // 鍔ㄤ綔绫诲瀷
actionPrepareSts, // 鍔ㄤ綔杩涘害
agvId, // AGV
now // 宸ヤ綔鏃堕棿
));
- lastDirection = workDirection;
+ lastDirection = firstTurnDir;
}
first = false;
@@ -778,34 +1145,19 @@
// 浣滀笟鐐瑰姩浣�
AgvDirectionType agvDirectionType;
+ Double staWorkDirection;
AgvBackpackType backpackType = AgvBackpackType.query(segment.getBackpack());
switch (Objects.requireNonNull(TaskPosDto.queryPosType(segment.getPosType()))) {
case ORI_LOC:
assert backpackType != null;
// 妫�楠屾柟鍚�
if (!lastDirection.equals(workDirection)) {
- // turn
- actionList.add(new Action(
- null, // 缂栧彿
- task.getBusId(), // 鎬荤嚎
- task.getId(), // 浠诲姟
- null, // 鍔ㄤ綔鍙�
- null, // 浼樺厛绾�
- ActionTypeType.TurnCorner.desc, // 鍚嶇О
- mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D, // 灞炴�у��
- lastCode.getData(), // 鍦伴潰鐮�
- String.valueOf(workDirection), // 鍔ㄤ綔鍙傛暟
- ActionTypeType.TurnCorner.val(), // 鍔ㄤ綔绫诲瀷
- actionPrepareSts, // 鍔ㄤ綔杩涘害
- agvId, // AGV
- now // 宸ヤ綔鏃堕棿
- ));
- lastDirection = workDirection;
+ throw new CoolException(agvNo + "鍙峰皬杞︽柟鍚戦敊璇紝璇锋帹鑷宠浆寮偣鎵嬪姩璋冩暣");
}
// 璐ф灦鍙栬揣
Loc oriLoc = locService.getById(task.getOriLoc());
// 璁$畻宸﹀彸鏂瑰悜
- agvDirectionType = mapService.calculateAgvWorkDirection(oriLoc, lastCode);
+ agvDirectionType = mapService.calculateAgvWorkDirectionByShelf(oriLoc, lastCode);
actionList.add(new Action(
null, // 缂栧彿
task.getBusId(), // 鎬荤嚎
@@ -821,66 +1173,54 @@
agvId, // AGV
now // 宸ヤ綔鏃堕棿
));
- // 鏆傚瓨鐐规斁璐�
- actionList.add(new Action(
- null, // 缂栧彿
- task.getBusId(), // 鎬荤嚎
- task.getId(), // 浠诲姟
- null, // 鍔ㄤ綔鍙�
- null, // 浼樺厛绾�
- ActionTypeType.ReadyReleaseToAgvSite.desc, // 鍚嶇О
- (double) backpackType.lev, // 灞炴�у��
- lastCode.getData(), // 鍦伴潰鐮�
- String.valueOf(backpackType.height), // 鍔ㄤ綔鍙傛暟
- ActionTypeType.ReadyReleaseToAgvSite.val(), // 鍔ㄤ綔绫诲瀷
- actionPrepareSts, // 鍔ㄤ綔杩涘害
- agvId, // AGV
- now // 宸ヤ綔鏃堕棿
- ));
- break;
- case DEST_LOC:
- assert backpackType != null;
- // 妫�楠屾柟鍚�
- if (!lastDirection.equals(workDirection)) {
- // turn
+ // 鑳岀瘬鏀捐揣
+ if (backupAction) {
actionList.add(new Action(
null, // 缂栧彿
task.getBusId(), // 鎬荤嚎
task.getId(), // 浠诲姟
null, // 鍔ㄤ綔鍙�
null, // 浼樺厛绾�
- ActionTypeType.TurnCorner.desc, // 鍚嶇О
- mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D, // 灞炴�у��
+ ActionTypeType.ReadyReleaseToAgvSite.desc, // 鍚嶇О
+ (double) backpackType.lev, // 灞炴�у��
lastCode.getData(), // 鍦伴潰鐮�
- String.valueOf(workDirection), // 鍔ㄤ綔鍙傛暟
- ActionTypeType.TurnCorner.val(), // 鍔ㄤ綔绫诲瀷
+ String.valueOf(backpackType.height), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.ReadyReleaseToAgvSite.val(), // 鍔ㄤ綔绫诲瀷
actionPrepareSts, // 鍔ㄤ綔杩涘害
agvId, // AGV
now // 宸ヤ綔鏃堕棿
));
- lastDirection = workDirection;
}
- // 鏆傚瓨鐐瑰彇璐ц揣
- actionList.add(new Action(
- null, // 缂栧彿
- task.getBusId(), // 鎬荤嚎
- task.getId(), // 浠诲姟
- null, // 鍔ㄤ綔鍙�
- null, // 浼樺厛绾�
- ActionTypeType.ReadyTakeFromAgvSite.desc, // 鍚嶇О
- (double) backpackType.lev, // 灞炴�у��
- lastCode.getData(), // 鍦伴潰鐮�
- String.valueOf(backpackType.height), // 鍔ㄤ綔鍙傛暟
- ActionTypeType.ReadyTakeFromAgvSite.val(), // 鍔ㄤ綔绫诲瀷
- actionPrepareSts, // 鍔ㄤ綔杩涘害
- agvId, // AGV
- now // 宸ヤ綔鏃堕棿
- ));
+ break;
+ case DEST_LOC:
+ assert backpackType != null;
+ // 妫�楠屾柟鍚�
+ if (!lastDirection.equals(workDirection)) {
+ throw new CoolException(agvNo + "鍙峰皬杞︽柟鍚戦敊璇紝璇锋帹鑷宠浆寮偣鎵嬪姩璋冩暣");
+ }
+ // 鑳岀瘬鍙栬揣
+ if (backupAction) {
+ actionList.add(new Action(
+ null, // 缂栧彿
+ task.getBusId(), // 鎬荤嚎
+ task.getId(), // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.ReadyTakeFromAgvSite.desc, // 鍚嶇О
+ (double) backpackType.lev, // 灞炴�у��
+ lastCode.getData(), // 鍦伴潰鐮�
+ String.valueOf(backpackType.height), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.ReadyTakeFromAgvSite.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
+ }
// 璐ф灦鏀捐揣
Loc destLoc = locService.getById(task.getDestLoc());
// 璁$畻宸﹀彸鏂瑰悜
- agvDirectionType = mapService.calculateAgvWorkDirection(destLoc, lastCode);
+ agvDirectionType = mapService.calculateAgvWorkDirectionByShelf(destLoc, lastCode);
actionList.add(new Action(
null, // 缂栧彿
task.getBusId(), // 鎬荤嚎
@@ -898,8 +1238,132 @@
));
break;
case ORI_STA:
+ // 绔欑偣鍙栬揣
+ Sta oriSta = staService.getById(task.getOriSta());
+ Double oriStaWorkDirection = mapService.getStaAngle(oriSta, workDirection);
+ // 妫�楠屾柟鍚�
+ if (!lastDirection.equals(oriStaWorkDirection)) {
+ if (!lastCode.getCornerBool()) {
+ throw new CoolException(agvNo + "鍙峰皬杞︽柟鍚戦敊璇紝璇锋帹鑷宠浆寮偣鎵嬪姩璋冩暣");
+ }
+ // turn
+ actionList.add(new Action(
+ null, // 缂栧彿
+ task.getBusId(), // 鎬荤嚎
+ task.getId(), // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.TurnCorner.desc, // 鍚嶇О
+ (double) mapService.spinDirection(lastCode).val, // 灞炴�у��
+ lastCode.getData(), // 鍦伴潰鐮�
+ String.valueOf(oriStaWorkDirection), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.TurnCorner.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
+ lastDirection = oriStaWorkDirection;
+ }
+ // 璁$畻璐у弶宸ヤ綔鏂瑰悜
+ staWorkDirection = mapService.calculateAgvWorkDirectionByStation(oriStaWorkDirection, lastDirection);
+ actionList.add(new Action(
+ null, // 缂栧彿
+ task.getBusId(), // 鎬荤嚎
+ task.getId(), // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.ReadyTakeFromConveyorSta.desc, // 鍚嶇О
+ staWorkDirection, // 灞炴�у��
+ lastCode.getData(), // 鍦伴潰鐮�
+ String.valueOf(oriSta.getOffset()), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.ReadyTakeFromConveyorSta.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
+ // 鑳岀瘬鏀捐揣
+ if (backupAction) {
+ assert backpackType != null;
+ actionList.add(new Action(
+ null, // 缂栧彿
+ task.getBusId(), // 鎬荤嚎
+ task.getId(), // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.ReadyReleaseToAgvSite.desc, // 鍚嶇О
+ (double) backpackType.lev, // 灞炴�у��
+ lastCode.getData(), // 鍦伴潰鐮�
+ String.valueOf(backpackType.height), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.ReadyReleaseToAgvSite.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
+ }
break;
case DEST_STA:
+ // 绔欑偣鏀捐揣
+ Sta destSta = staService.getById(task.getDestSta());
+ Double destStaWorkDirection = mapService.getStaAngle(destSta, workDirection);
+ // 妫�楠屾柟鍚�
+ if (!lastDirection.equals(destStaWorkDirection)) {
+ if (!lastCode.getCornerBool()) {
+ throw new CoolException(agvNo + "鍙峰皬杞︽柟鍚戦敊璇紝璇锋帹鑷宠浆寮偣鎵嬪姩璋冩暣");
+ }
+ // turn
+ actionList.add(new Action(
+ null, // 缂栧彿
+ task.getBusId(), // 鎬荤嚎
+ task.getId(), // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.TurnCorner.desc, // 鍚嶇О
+ (double) mapService.spinDirection(lastCode).val, // 灞炴�у��
+ lastCode.getData(), // 鍦伴潰鐮�
+ String.valueOf(destStaWorkDirection), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.TurnCorner.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
+ lastDirection = destStaWorkDirection;
+ }
+ // 鑳岀瘬鍙栬揣
+ if (backupAction) {
+ assert backpackType != null;
+ actionList.add(new Action(
+ null, // 缂栧彿
+ task.getBusId(), // 鎬荤嚎
+ task.getId(), // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.ReadyTakeFromAgvSite.desc, // 鍚嶇О
+ (double) backpackType.lev, // 灞炴�у��
+ lastCode.getData(), // 鍦伴潰鐮�
+ String.valueOf(backpackType.height), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.ReadyTakeFromAgvSite.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
+ }
+ // 璁$畻璐у弶宸ヤ綔鏂瑰悜
+ staWorkDirection = mapService.calculateAgvWorkDirectionByStation(destStaWorkDirection, lastDirection);
+ actionList.add(new Action(
+ null, // 缂栧彿
+ task.getBusId(), // 鎬荤嚎
+ task.getId(), // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.ReadyReleaseToConveyorSta.desc, // 鍚嶇О
+ staWorkDirection, // 灞炴�у��
+ lastCode.getData(), // 鍦伴潰鐮�
+ String.valueOf(destSta.getOffset()), // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.ReadyReleaseToConveyorSta.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
break;
case TO_CHARGE:
// 妫�楠屾柟鍚�
@@ -913,7 +1377,7 @@
null, // 鍔ㄤ綔鍙�
null, // 浼樺厛绾�
ActionTypeType.TurnCorner.desc, // 鍚嶇О
- mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D, // 灞炴�у��
+ (double) mapService.spinDirection(lastCode).val, // 灞炴�у��
lastCode.getData(), // 鍦伴潰鐮�
String.valueOf(chargeDirection), // 鍔ㄤ綔鍙傛暟
ActionTypeType.TurnCorner.val(), // 鍔ㄤ綔绫诲瀷
@@ -942,7 +1406,24 @@
));
break;
case TO_STANDBY:
-// FuncSta standByFuncSta = funcStaService.query(agvId, lastCode.getId(), 2);
+ // load lift
+// actionList.add(new Action(
+// null, // 缂栧彿
+// null, // 鎬荤嚎
+// task.getId(), // 浠诲姟
+// null, // 鍔ㄤ綔鍙�
+// null, // 浼樺厛绾�
+// ActionTypeType.LoadPlatformLift.desc, // 鍚嶇О
+// null, // 灞炴�у��
+// lastCode.getData(), // 鍦伴潰鐮�
+// String.valueOf(0), // 鍔ㄤ綔鍙傛暟
+// ActionTypeType.LoadPlatformLift.val(), // 鍔ㄤ綔绫诲瀷
+// actionPrepareSts, // 鍔ㄤ綔杩涘害
+// agvId, // AGV
+// now // 宸ヤ綔鏃堕棿
+// ));
+ // turn
+// FuncSta standByFuncSta = funcStaService.query(lastCode.getId(), FuncStaType.STANDBY.toString());
// Double standByDirection = Double.parseDouble(standByFuncSta.getAngle());
// if (!lastDirection.equals(standByDirection)) {
// actionList.add(new Action(
@@ -971,6 +1452,27 @@
}
+ // 濡傛灉鍏呯數涓紝鍒欏厛鏂紑鍏呯數
+ if (needUndocking && agvDetail.getAgvStatus().equals(AgvStatusType.CHARGE)) {
+ String undockingCode = Cools.isEmpty(actionList) ? lastCode.getData() : actionList.get(0).getCode();
+ // undocking charge
+ actionList.add(0, new Action(
+ null, // 缂栧彿
+ null, // 鎬荤嚎
+ null, // 浠诲姟
+ null, // 鍔ㄤ綔鍙�
+ null, // 浼樺厛绾�
+ ActionTypeType.UndockingCharge.desc, // 鍚嶇О
+ null, // 灞炴�у��
+ undockingCode, // 鍦伴潰鐮�
+ null, // 鍔ㄤ綔鍙傛暟
+ ActionTypeType.UndockingCharge.val(), // 鍔ㄤ綔绫诲瀷
+ actionPrepareSts, // 鍔ㄤ綔杩涘害
+ agvId, // AGV
+ now // 宸ヤ綔鏃堕棿
+ ));
+ }
+
// finish
actionList.add(new Action(
null, // 缂栧彿
@@ -988,39 +1490,53 @@
now // 宸ヤ綔鏃堕棿
));
-// List<Action> newActionList = new ArrayList<>(actionList);
-
-// List<Action> optimizeList = actionService.optimizeSort(actionList);
-
- List<Action> optimizeList = actionSorter.optimizeSort(actionList);
- List<Action> newActionList = new ArrayList<>(optimizeList);
-
-
String groupId = String.valueOf(snowflakeIdWorker.nextId()).substring(3);
+
+ // update segment
+ for (Segment item : segmentList) {
+ LambdaUpdateWrapper<Segment> uw = new LambdaUpdateWrapper<Segment>()
+ .eq(Segment::getId, item.getId())
+ .eq(Segment::getState, item.getState())
+ .set(Segment::getGroupId, groupId)
+ .set(Segment::getState, SegmentStateType.RUNNING.toString())
+ .set(Segment::getStartTime, now)
+ .set(Segment::getUpdateTime, now);
+ if (algoStartTime != null) {
+ uw.set(Segment::getAlgoTime, (int) (now.getTime() - algoStartTime.getTime()));
+ }
+ if (!segmentService.update(uw)) {
+ // segment 鍘熷瓙鎬т繚璇�
+ throw new CoolException("鏇存柊Segment澶辫触: segmentId=" + item.getId() + " state not WAITING");
+ }
+ }
+
+ // update segment
+// for (Segment item : segmentList) {
+// item.setGroupId(groupId);
+// item.setState(SegmentStateType.RUNNING.toString());
+// item.setStartTime(now);
+// item.setUpdateTime(now);
+// if (null != algoStartTime) {
+// item.setAlgoTime((int) (now.getTime() - algoStartTime.getTime()));
+// }
+// if (!segmentService.updateById(item)) {
+// throw new CoolException("鏇存柊Segment澶辫触");
+// }
+// }
+
+ // optimize action list, must have backpack
+ List<Action> newActionList = backupAction ? actionSorter.optimizeSort(actionList) : actionList;
// save action
int i = newActionList.size();
for (Action action : newActionList) {
- action.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
+// action.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
action.setGroupId(groupId);
action.setPriority(i);
- if (!actionService.save(action)) {
- throw new BusinessException(action.getName() + "鍔ㄤ綔淇濆瓨澶辫触");
- }
i -= 1;
}
-
- // update segment
- for (Segment item : segmentList) {
- item.setGroupId(groupId);
- item.setState(SegmentStateType.RUNNING.toString());
- item.setUpdateTime(now);
- if (null != algoStartTime) {
- item.setAlgoTime((int) (now.getTime() - algoStartTime.getTime()));
- }
- if (!segmentService.updateById(item)) {
- throw new CoolException("鏇存柊Segment澶辫触");
- }
+ if (!actionService.saveBatch(newActionList)) {
+ throw new BusinessException("group[" + groupId + "] 鍔ㄤ綔淇濆瓨澶辫触");
}
log.info("{}鍙稟gv鍔ㄤ綔缁勮瀹屾垚锛屾寚浠ゆ暟閲忥細{}", agvNo, newActionList.size());
@@ -1050,15 +1566,22 @@
if (Cools.isEmpty(actionList)) {
return;
}
+
+ Long agvId = actionList.get(0).getAgvId();
+ String agvNo = agvService.getAgvNo(agvId);
+ if (!agvService.judgeOnline(agvId)) {
+ return;
+ }
+
long actionIssuedSts = ActionStsType.ISSUED.val();
for (Action action : actionList) {
action.setActionSts(actionIssuedSts);
action.setStartTime(now);
action.setIoTime(now);
action.setUpdateTime(now);
- if (!actionService.updateById(action)) {
- throw new BusinessException(action.getPriority() + " - " + action.getName() + "鍔ㄤ綔鏇存柊澶辫触");
- }
+ }
+ if (!actionService.updateBatchById(actionList)) {
+ throw new BusinessException("failed to update action batch !!!");
}
// task
@@ -1076,10 +1599,8 @@
}
}
- Agv agv = agvService.getById(actionList.get(0).getAgvId());
- AgvAction agvAction = new AgvAction(agv.getUuid(), actionGroupId);
+ AgvAction agvAction = new AgvAction(agvNo, actionGroupId);
for (Action action : actionList) {
-
switch (Objects.requireNonNull(ActionTypeType.get(action.getActionTypeEl()))) {
case TurnCorner:
agvAction.add(new AgvActionItem<>(TurnCornerAction.class)
@@ -1113,6 +1634,13 @@
.bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
);
break;
+ case ReadyTakeFromConveyorSta:
+ agvAction.add(new AgvActionItem<>(ReadyTakeFromConveyorSta.class)
+ .setVal(action.getVal().intValue())
+ .setQrCode(action.getCode())
+ .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
+ );
+ break;
case ReadyTakeFromAgvSite:
agvAction.add(new AgvActionItem<>(ReadyTakeFromAgvSite.class)
.setVal(action.getVal().intValue())
@@ -1122,6 +1650,20 @@
break;
case ReadyReleaseToShelvesLoc:
agvAction.add(new AgvActionItem<>(ReadyReleaseToShelvesLoc.class)
+ .setVal(action.getVal().intValue())
+ .setQrCode(action.getCode())
+ .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
+ );
+ break;
+ case LoadPlatformLift:
+ agvAction.add(new AgvActionItem<>(LoadPlatformLift.class)
+ .setVal(action.getVal().intValue())
+ .setQrCode(action.getCode())
+ .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
+ );
+ break;
+ case ReadyReleaseToConveyorSta:
+ agvAction.add(new AgvActionItem<>(ReadyReleaseToConveyorSta.class)
.setVal(action.getVal().intValue())
.setQrCode(action.getCode())
.bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
@@ -1141,6 +1683,11 @@
break;
case DockingCharge:
agvAction.add(new AgvActionItem<>(DockingChargeAction.class)
+ .setQrCode(action.getCode())
+ );
+ break;
+ case UndockingCharge:
+ agvAction.add(new AgvActionItem<>(UndockingChargeAction.class)
.setQrCode(action.getCode())
);
break;
@@ -1268,6 +1815,86 @@
}
}
+ // 鍙栨斁璐ц姹傚寘
+ if (msgBody instanceof AGV_06_UP) {
+ AGV_06_UP agv_06_up = (AGV_06_UP) msgBody;
+ log.info("Agv [{}] 鍙栨斁璐ц姹傚寘 ===>> {}", protocol.getAgvNo(), JSON.toJSONString(agv_06_up));
+
+ boolean success = false;
+
+ try {
+ Code code = codeService.getCacheByData(agv_06_up.getQrCode());
+
+ // query current segment
+ Segment currSeg = segmentService.getCurrRunningSeg(agv.getId(), code.getId());
+ if (null == currSeg) {
+ log.error("failed to find curr segment [{}]", agv.getUuid());
+ } else {
+
+ // query current task
+ Task currTask = taskService.getById(currSeg.getTaskId());
+ if (currTask == null || !currTask.getTaskSts().equals(TaskStsType.PROGRESS.val())) {
+
+ log.error("agv[{}] task invalid, task={}", protocol.getAgvNo(), currSeg.getTaskId());
+ } else {
+
+ Sta sta;
+ TaskPosDto.PosType posType = TaskPosDto.PosType.of(currSeg.getPosType());
+ assert null != posType;
+ switch (posType) {
+ case ORI_LOC:
+ case DEST_LOC:
+ success = true;
+ break;
+ case ORI_STA:
+ // load from sta
+ sta = staService.getById(currTask.getOriSta());
+ // reserve to be waiting
+ if (!staReserveService.waitingStaReserve(sta, currTask, 1, StaReserveType.OUT)) {
+ break;
+ }
+ // convey plc valid
+ if (!conveyorStationService.allowAgvWork(sta, currTask, currSeg, StaReserveType.OUT)) {
+ // reserve rollback
+ staReserveService.rollbackWaitingToReserved(sta, currTask, StaReserveType.OUT);
+ break;
+ }
+ success = true;
+ break;
+ case DEST_STA:
+ // place to sta
+ sta = staService.getById(currTask.getDestSta());
+ // reserve to be waiting
+ if (!staReserveService.waitingStaReserve(sta, currTask, 1, StaReserveType.IN)) {
+ break;
+ }
+ // convey plc valid
+ if (!conveyorStationService.allowAgvWork(sta, currTask, currSeg, StaReserveType.IN)) {
+ // reserve rollback
+ staReserveService.rollbackWaitingToReserved(sta, currTask, StaReserveType.IN);
+ break;
+ }
+ success = true;
+ break;
+ default:
+ log.error("agv[{}] has wrong posType [{}], segment [{}]", protocol.getAgvNo(), posType.toString(), currSeg.getId());
+ break;
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ log.error("agv[{}] failed to deal with action request, qrCode={}", agv.getUuid(), agv_06_up.getVal(), e);
+ }
+
+ AGV_06_DOWN agv_06_down = new AGV_06_DOWN();
+ agv_06_down.setSerialNo(agv_06_up.getSerialNo());
+ agv_06_down.setActionCode(agv_06_up.getActionCode());
+ //agv_06_down.setResult(success ? 1 : 0);
+ agv_06_down.setResult(1);
+ redis.push(RedisConstant.AGV_PATH_DOWN_FLAG, AgvProtocol.build(protocol.getAgvNo()).setMessageBody(agv_06_down));
+ }
+
// 鏂欎粨淇℃伅鍖�
if (msgBody instanceof AGV_70_UP) {
AGV_70_UP agv_70_up = (AGV_70_UP) msgBody;
@@ -1315,14 +1942,13 @@
}
if (taskComplete) {
- locService.taskCallBack(task);
-
task.setTaskSts(TaskStsType.COMPLETE.val());
task.setEndTime(now);
task.setUpdateTime(now);
if (!taskService.updateById(task)) {
log.error("Task [{}] 鏇存柊澶辫触 锛侊紒锛�", task.getSeqNum());
} else {
+ taskService.maintainLocAndSta(task);
log.info("Task [{}] 浣滀笟瀹屾瘯 ==========>> ", task.getSeqNum());
}
@@ -1348,6 +1974,7 @@
// segment
for (Segment segment : segmentList) {
segment.setState(SegmentStateType.FINISH.toString());
+ segment.setEndTime(now);
segment.setUpdateTime(now);
if (!segmentService.updateById(segment)) {
log.error("Segment [{}] 鏇存柊澶辫触 锛侊紒锛�", segment.getGroupId() + " - " + segment.getSerial());
--
Gitblit v1.9.1