zhang
8 天以前 4ad3a6e5540c5ca9d6042fc2fb7d72fa18c49c15
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
@@ -96,6 +96,10 @@
    private LaneService laneService;
    @Autowired
    private ActionSorter actionSorter;
    @Autowired
    private TaskReportService taskReportService;
    @Autowired
    private AgvDurationService agvDurationService;
    @SuppressWarnings("all")
    @Transactional
@@ -249,10 +253,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;
            }
@@ -284,7 +290,9 @@
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void buildMajorTask(Long agvId, List<Task> taskList) {
        if (Cools.isEmpty(agvId, taskList)) { return; }
        if (Cools.isEmpty(agvId, taskList)) {
            return;
        }
        try {
            // valid -----------------------------------------------
            Agv agv = agvService.getById(agvId);
@@ -324,16 +332,18 @@
             * 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) {
                backpackLev ++;
                backpackLev++;
                Code startCode = null;
                Code endCode = null;
                Loc oriLoc = null; Loc destLoc = null;
                Sta oriSta = null; Sta destSta = null;
                Loc oriLoc = null;
                Loc destLoc = null;
                Sta oriSta = null;
                Sta destSta = null;
                switch (Objects.requireNonNull(TaskTypeType.get(task.getTaskTypeEl()))) {
                    case LOC_TO_LOC:
                        oriLoc = locService.getById(task.getOriLoc());
@@ -436,7 +446,7 @@
            // re-order by agv current position
            Code currCode = codeService.getCacheById(agvDetail.getRecentCode());
            Double[] currPosition = new Double[] {currCode.getX(), currCode.getY()};
            Double[] currPosition = new Double[]{currCode.getX(), currCode.getY()};
            List<List<TaskPosDto>> pickGroups = new ArrayList<>();
            List<List<TaskPosDto>> dropGroups = new ArrayList<>();
@@ -482,7 +492,7 @@
            List<Segment> segmentList = new ArrayList<>();
            for (List<TaskPosDto> dtoList : list) {
                for (TaskPosDto taskPosDto : dtoList) {
                    segSerial ++;
                    segSerial++;
                    AgvBackpackType backpackType = AgvBackpackDto.find(backpackDtoList, taskPosDto.getTaskId());
                    assert null != backpackType;
@@ -530,9 +540,12 @@
    /**
     * 充电 回待机位任务
     */
    @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
    @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(Long agvId, TaskTypeType taskType, String destination, Jam jam) {
        if (Cools.isEmpty(agvId, taskType)) { return false; }
        if (Cools.isEmpty(agvId, taskType)) {
            return false;
        }
        try {
            String agvNo = agvService.getAgvNo(agvId);
            if (!agvService.judgeEnable(agvId)) {
@@ -579,7 +592,7 @@
            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.setSeqNum(Utils.generateSeqNum(Cools.isEmpty(lastTasks) ? null : lastTasks.get(0).getSeqNum()));
            task.setOriCode(agvDetail.getCode());
            task.setDestCode(endCode.getId());
            // lane
@@ -587,7 +600,7 @@
            if (null != destLane) {
                task.setDestLaneHash(destLane.getHashCode());
            }
            task.setPriority(taskType.equals(TaskTypeType.TO_CHARGE)?2:1);
            task.setPriority(taskType.equals(TaskTypeType.TO_CHARGE) ? 2 : 1);
            task.setTaskSts(TaskStsType.ASSIGN.val());
            task.setTaskType(taskType.val());
            task.setIoTime(now);
@@ -595,6 +608,7 @@
            if (!taskService.save(task)) {
                throw new BusinessException(task.getSeqNum() + " failed to save");
            }
            // generate travel
            Travel travel = new Travel();
@@ -609,13 +623,20 @@
            }
            // generate segment
            int segSerial = 0;     segSerial ++;
            int segSerial = 0;
            segSerial++;
            List<Segment> segmentList = new ArrayList<>();
            String posType = "";
            switch (taskType){
            switch (taskType) {
                case TO_CHARGE:
                    posType = TaskPosDto.PosType.TO_CHARGE.toString();
                    //插入充电任务
                    AgvDuration agvDuration = new AgvDuration();
                    agvDuration.setHappenTime(now);
                    agvDuration.setAgvId(agvId);
                    agvDuration.setTaskNo(task.getId());
                    agvDurationService.save(agvDuration);
                    break;
                case TO_STANDBY:
                    posType = TaskPosDto.PosType.TO_STANDBY.toString();
@@ -685,7 +706,9 @@
    @Transactional
    public synchronized void generateAction(Long agvId, List<Segment> segmentList, List<String> pathList, Date algoStartTime) {
        try {
            if (Cools.isEmpty(agvId, segmentList)) { return; }
            if (Cools.isEmpty(agvId, segmentList)) {
                return;
            }
            Date now = new Date();
            long actionPrepareSts = ActionStsType.PREPARE.val();
//            JSONObject storeDirection = configService.getVal("storeDirection", JSONObject.class);
@@ -727,7 +750,9 @@
                    List<String> pathListPart = pathList.subList(pathList.indexOf(lastCode.getData()), pathList.indexOf(code.getData()) + 1);
                    for (int i = 0; i < pathListPart.size(); i++) {
                        if (i == 0) { continue; }
                        if (i == 0) {
                            continue;
                        }
                        String next = pathListPart.get(i);
@@ -859,6 +884,7 @@
                // 作业点动作
                AgvDirectionType agvDirectionType;
                Double staWorkDirection;
                AgvBackpackType backpackType = AgvBackpackType.query(segment.getBackpack());
                switch (Objects.requireNonNull(TaskPosDto.queryPosType(segment.getPosType()))) {
                    case ORI_LOC:
@@ -935,7 +961,7 @@
                                task.getBusId(),    // 总线
                                task.getId(),    // 任务
                                null,    // 动作号
                                 null,    // 优先级
                                null,    // 优先级
                                ActionTypeType.ReadyReleaseToShelvesLoc.desc,    // 名称
                                (double) agvDirectionType.val,    // 属性值
                                lastCode.getData(),    // 地面码
@@ -963,7 +989,7 @@
                                    null,    // 动作号
                                    null,    // 优先级
                                    ActionTypeType.TurnCorner.desc,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性값
                                    lastCode.getData(),    // 地面码
                                    String.valueOf(oriStaWorkDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -974,18 +1000,18 @@
                            lastDirection = oriStaWorkDirection;
                        }
                        // 计算货叉工作方向
                        agvDirectionType = mapService.calculateAgvWorkDirectionByStation(oriSta, lastCode);
                        staWorkDirection = mapService.calculateAgvWorkDirectionByStation(oriStaWorkDirection, lastDirection);
                        actionList.add(new Action(
                                null,    // 编号
                                task.getBusId(),    // 总线
                                task.getId(),    // 任务
                                null,    // 动作号
                                null,    // 优先级
                                ActionTypeType.ReadyTakeFromShelvesLoc.desc,    // 名称
                                (double) agvDirectionType.val,    // 属性值
                                ActionTypeType.ReadyTakeFromConveyorSta.desc,    // 名称
                                staWorkDirection,    // 属性值
                                lastCode.getData(),    // 地面码
                                String.valueOf(oriSta.getOffset()),   // 动作参数
                                ActionTypeType.ReadyTakeFromShelvesLoc.val(),    // 动作类型
                                ActionTypeType.ReadyTakeFromConveyorSta.val(),    // 动作类型
                                actionPrepareSts,    // 动作进度
                                agvId,    // AGV
                                now    // 工作时间
@@ -999,7 +1025,7 @@
                                null,    // 动作号
                                null,    // 优先级
                                ActionTypeType.ReadyReleaseToAgvSite.desc,    // 名称
                                (double) backpackType.lev,    // 属性值
                                (double) backpackType.lev,    // 属性값
                                lastCode.getData(),    // 地面码
                                String.valueOf(backpackType.height),   // 动作参数
                                ActionTypeType.ReadyReleaseToAgvSite.val(),    // 动作类型
@@ -1025,7 +1051,7 @@
                                    null,    // 动作号
                                    null,    // 优先级
                                    ActionTypeType.TurnCorner.desc,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性값
                                    lastCode.getData(),    // 地面码
                                    String.valueOf(destStaWorkDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -1044,7 +1070,7 @@
                                null,    // 动作号
                                null,    // 优先级
                                ActionTypeType.ReadyTakeFromAgvSite.desc,    // 名称
                                (double) backpackType.lev,    // 属性值
                                (double) backpackType.lev,    // 属性값
                                lastCode.getData(),    // 地面码
                                String.valueOf(backpackType.height),   // 动作参数
                                ActionTypeType.ReadyTakeFromAgvSite.val(),    // 动作类型
@@ -1053,18 +1079,18 @@
                                now    // 工作时间
                        ));
                        // 计算货叉工作方向
                        agvDirectionType = mapService.calculateAgvWorkDirectionByStation(destSta, lastCode);
                        staWorkDirection = mapService.calculateAgvWorkDirectionByStation(destStaWorkDirection, lastDirection);
                        actionList.add(new Action(
                                null,    // 编号
                                task.getBusId(),    // 总线
                                task.getId(),    // 任务
                                null,    // 动作号
                                null,    // 优先级
                                ActionTypeType.ReadyReleaseToShelvesLoc.desc,    // 名称
                                (double) agvDirectionType.val,    // 属性值
                                ActionTypeType.ReadyReleaseToConveyorSta.desc,    // 名称
                                staWorkDirection,    // 属性값
                                lastCode.getData(),    // 地面码
                                String.valueOf(destSta.getOffset()),   // 动作参数
                                ActionTypeType.ReadyReleaseToShelvesLoc.val(),    // 动作类型
                                ActionTypeType.ReadyReleaseToConveyorSta.val(),    // 动作类型
                                actionPrepareSts,    // 动作进度
                                agvId,    // AGV
                                now    // 工作时间
@@ -1082,7 +1108,7 @@
                                    null,    // 动作号
                                    null,    // 优先级
                                    ActionTypeType.TurnCorner.desc,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性값
                                    lastCode.getData(),    // 地面码
                                    String.valueOf(chargeDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -1101,7 +1127,7 @@
                                null,    // 动作号
                                null,    // 优先级
                                ActionTypeType.DockingCharge.desc,    // 名称
                                null,    // 属性值
                                null,    // 属性값
                                lastCode.getData(),    // 地面码
                                null,   // 动作参数
                                ActionTypeType.DockingCharge.val(),    // 动作类型
@@ -1121,7 +1147,7 @@
//                                    null,    // 动作号
//                                    null,    // 优先级
//                                    ActionTypeType.TurnCorner.desc,    // 名称
//                                    null,    // 属性值
//                                    null,    // 属性값
//                                    lastCode.getData(),    // 地面码
//                                    String.valueOf(standByDirection),   // 动作参数
//                                    ActionTypeType.TurnCorner.val(),    // 动作类型
@@ -1131,6 +1157,36 @@
//                            ));
//                            lastDirection = standByDirection;
//                        }
                        String runToWaitHeightFlag = configService.getVal("RunToWaitHeightFlag", String.class);
                        if (!Cools.isEmpty(runToWaitHeightFlag) && runToWaitHeightFlag.contains(agvId.toString())) {
                            String runToWaitHeight = configService.getVal("RunToWaitHeight", String.class);
                            if (Cools.isEmpty(runToWaitHeight)) {
                                runToWaitHeight = "800";
                            }
                            Double runToWaitHeightValue = configService.getVal("RunToWaitHeightValue", Double.class);
                            if (Cools.isEmpty(runToWaitHeight) || runToWaitHeightValue == 0) {
                                runToWaitHeightValue = 1D;
                            }
                            // 修复空指针异常:检查lastCode是否为null
                            if (lastCode == null) {
                                throw new BusinessException("AGV定位信息异常,无法生成待机动作");
                            }
                            actionList.add(new Action(
                                    null,    // 编号
                                    task.getBusId(),    // 总线
                                    task.getId(),    // 任务
                                    null,    // 动作号
                                    null,    // 优先级
                                    ActionTypeType.RunToWaitHeight.desc,    // 名称
                                    runToWaitHeightValue,    // 属性값
                                    lastCode.getData(),    // 地面码
                                    runToWaitHeight,   // 动作参数
                                    ActionTypeType.RunToWaitHeight.val(),    // 动作类型
                                    actionPrepareSts,    // 动作进度
                                    agvId,    // AGV
                                    now    // 工作时间
                            ));
                        }
                        break;
                    case MOVE:
                        break;
@@ -1212,6 +1268,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);
@@ -1238,10 +1301,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)
@@ -1275,6 +1336,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())
@@ -1289,11 +1357,25 @@
                                .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())))
                        );
                        break;
                    case ReadyReleaseToAgvSite:
                        agvAction.add(new AgvActionItem<>(ReadyReleaseToAgvSite.class)
                                .setVal(action.getVal().intValue())
                                .setQrCode(action.getCode())
                                .bodySync(body -> body.setDepth((short) Double.parseDouble(action.getParams())))
                        );
                        break;
                    case RunToWaitHeight:
                        agvAction.add(new AgvActionItem<>(RunToWaitHeight.class)
                                .setVal(action.getVal().intValue())
                                .setQrCode(action.getCode())
                                .bodySync(body -> body.setHeight((short) Double.parseDouble(action.getParams())))
                        );
                        break;
                    case FinishPath:
@@ -1417,9 +1499,9 @@
                // segment list
                List<Segment> segmentList = segmentService.list(new LambdaQueryWrapper<Segment>()
                        .eq(Segment::getGroupId, serialNo)
                                .eq(Segment::getGroupId, serialNo)
//                        .eq(Segment::getState, SegmentStateType.RUNNING.toString())
                        .orderByAsc(Segment::getSerial)
                                .orderByAsc(Segment::getSerial)
                );
                // settlement
@@ -1449,8 +1531,10 @@
        for (Segment segment : segmentList) {
            boolean taskComplete = false;
            Task task = taskService.getById(segment.getTaskId());   assert null != task;
            TaskTypeType typeType = TaskTypeType.get(task.getTaskTypeEl());     assert null != typeType;
            Task task = taskService.getById(segment.getTaskId());
            assert null != task;
            TaskTypeType typeType = TaskTypeType.get(task.getTaskTypeEl());
            assert null != typeType;
            TaskPosDto.PosType posType = TaskPosDto.queryPosType(segment.getPosType());
            switch (Objects.requireNonNull(posType)) {
@@ -1486,6 +1570,21 @@
                    log.error("Task [{}] 更新失败 !!!", task.getSeqNum());
                } else {
                    log.info("Task [{}] 作业完毕 ==========>> ", task.getSeqNum());
                    // TODO 插入一条上报记录
                    TaskReport taskReport = new TaskReport();
                    taskReport.setAgvId(task.getAgvId());
                    taskReport.setBusNo(task.getBusId$());
                    taskReport.setCreateTime(new Date());
                    taskReport.setDestLoc(task.getDestLoc());
                    taskReport.setDestSta(task.getDestSta());
                    taskReport.setSeqNum(task.getSeqNum());
                    taskReport.setTaskSts(task.getTaskSts());
                    taskReport.setOriLoc(task.getOriLoc());
                    taskReport.setOriSta(task.getOriSta());
                    taskReport.setZpallet(task.getZpallet());
                    if (!taskReportService.save(taskReport)) {
                        log.info("TaskReport [{}] 插入失败 ==========>> ", JSON.toJSONString(taskReport));
                    }
                }
            }