#
vincentlu
2025-12-26 a4a7479ffbee57c642387baeca5783b943bb1af3
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
@@ -35,7 +35,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,7 +47,7 @@
 * Created by vincent on 2023/6/14
 */
@Slf4j
@Component("mainService")
@Service("mainService")
public class MainService {
    @Autowired
@@ -96,7 +96,8 @@
    private LaneService laneService;
    @Autowired
    private ActionSorter actionSorter;
    @Autowired
    private StaReserveService staReserveService;
    @SuppressWarnings("all")
    @Transactional
@@ -175,8 +176,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 +199,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,10 +231,12 @@
            );
            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;
            }
@@ -223,7 +245,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 check out agv which is idle...", task.getSeqNum());
                    continue;
                }
                task.setAgvId(agv.getId());
@@ -821,34 +843,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(),    // 总线
@@ -885,23 +892,7 @@
                        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 + "号小车方向错误,请推至转弯点手动调整");
                        }
                        // 暂存点取货货
                        actionList.add(new Action(
@@ -923,7 +914,7 @@
                        // 货架放货
                        Loc destLoc = locService.getById(task.getDestLoc());
                        // 计算左右方向
                        agvDirectionType = mapService.calculateAgvWorkDirection(destLoc, lastCode);
                        agvDirectionType = mapService.calculateAgvWorkDirectionByShelf(destLoc, lastCode);
                        actionList.add(new Action(
                                null,    // 编号
                                task.getBusId(),    // 总线
@@ -941,8 +932,128 @@
                        ));
                        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,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                    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    // 工作时间
                        ));
                        // 暂存点放货
                        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,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                    lastCode.getData(),    // 地面码
                                    String.valueOf(destStaWorkDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
                                    actionPrepareSts,    // 动作进度
                                    agvId,    // AGV
                                    now    // 工作时间
                            ));
                            lastDirection = destStaWorkDirection;
                        }
                        // 暂存点取货
                        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:
                        // 检验方向
@@ -985,7 +1096,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(
@@ -1050,6 +1178,7 @@
            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()));
@@ -1086,6 +1215,13 @@
            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);
@@ -1112,10 +1248,8 @@
                }
            }
            String agvNo = agvService.getAgvNo(actionList.get(0).getAgvId());
            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)
@@ -1149,6 +1283,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())
@@ -1158,6 +1299,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())))
@@ -1351,7 +1506,7 @@
            }
            if (taskComplete) {
                locService.taskCallBack(task);
//                locService.taskCallBack(task);
                task.setTaskSts(TaskStsType.COMPLETE.val());
                task.setEndTime(now);
@@ -1359,6 +1514,7 @@
                if (!taskService.updateById(task)) {
                    log.error("Task [{}] 更新失败 !!!", task.getSeqNum());
                } else {
                    taskService.maintainLocAndSta(task);
                    log.info("Task [{}] 作业完毕 ==========>> ", task.getSeqNum());
                }
@@ -1384,6 +1540,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());