zc
2025-10-16 3c9b9886fc9e9a26dac4e8b5dd4cc0db0b8fce82
创建分支
8个文件已修改
737 ■■■■ 已修改文件
zy-acs-gateway/src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/common/domain/PageParam.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java 577 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Loc.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/FuncStaServiceImpl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/resources/application-dev.yml 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/resources/application.yml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-gateway/src/main/resources/application.yml
@@ -8,7 +8,7 @@
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/jbly?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: xltys1995
    password: 34821015
eureka:
  client:
@@ -18,7 +18,7 @@
#redis的相关配置
redis:
  host: localhost
  host: 127.0.0.1
  password: xltys1995
  port: 6379
  max: 30
zy-acs-manager/src/main/java/com/zy/acs/manager/common/domain/PageParam.java
@@ -108,11 +108,19 @@
                if (this.isToUnderlineCase) {
                    key = Utils.toSymbolCase(key, '_');
                }
                if (like) {
                    queryWrapper.like(key, val);
                String finalKey = key;
                if (like && key.contains(timeField)) {
                    queryWrapper.and(wrapper -> wrapper.like("`" + finalKey + "`", val));
//                    queryWrapper.like("`" +  key + "`", val);
                } else {
                    queryWrapper.eq(key, val);
                    queryWrapper.and(wrapper -> wrapper.eq("`" + finalKey + "`", val));
//                    queryWrapper.eq("`" +  key + "`", val);
                }
//                if (like) {
//                    queryWrapper.like(key, val);
//                } else {
//                    queryWrapper.eq(key, val);
//                }
            }
        }
@@ -163,7 +171,7 @@
                    String condition = where.getCondition();
                    if (i == 0) {
                        queryWrapper.and(wrapper -> wrapper.like(column, condition));
                        queryWrapper.and(wrapper -> wrapper.like("`" + column + "`", condition));
                    } else {
                        queryWrapper.or().like(column, condition);
                    }
@@ -200,9 +208,9 @@
                    key = Utils.toSymbolCase(key, '_');
                }
                if (like) {
                    queryWrapper.like(key, val);
                    queryWrapper.like("`" + key + "`", val);
                } else {
                    queryWrapper.eq(key, val);
                    queryWrapper.eq("`" + key + "`", val);
                }
            }
        }
@@ -254,9 +262,9 @@
                    String condition = where.getCondition();
                    if (i == 0) {
                        queryWrapper.and(wrapper -> wrapper.like(column, condition));
                        queryWrapper.and(wrapper -> wrapper.like("`" + column + "`", condition));
                    } else {
                        queryWrapper.or().like(column, condition);
                        queryWrapper.or().like("`" + column + "`", condition);
                    }
                }
            }
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
@@ -1288,6 +1288,583 @@
    }
    /**
     * 根据分片生成动作 ( 车辆可能已经做过一些任务了,正在等待下一段任务 )
     */
    @Transactional
    public synchronized void generateActionV2(Long agvId, List<Segment> segmentList, List<String> pathList, Date algoStartTime) {
        try {
            if (Cools.isEmpty(agvId, segmentList)) {
                return;
            }
            Date now = new Date();
            long actionPrepareSts = ActionStsType.PREPARE.val();
//            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 + "]当前不可用...");
//            }
            AgvModel agvModel = agvModelService.getByAgvId(agvId);
            Double workDirection = agvModel.getWorkDirection();
            AgvSpeedType agvSpeedType = AgvSpeedType.query(agvModel.getTravelSpeed());
            assert agvSpeedType != null;
            AgvDetail agvDetail = agvDetailService.selectMajorByAgvId(agvId);
            List<Action> actionList = new ArrayList<>();
            // start node
            Code lastCode = codeService.getCacheById(agvDetail.getRecentCode());
            Double lastDirection = MapService.mapToNearest(agvDetail.getAgvAngle());
            if (!lastCode.getData().equals(pathList.get(0))) {
                throw new CoolException("AGV[" + agvNo + "]定位偏移...");
            }
            String lastCorner = null;
            for (int i =  pathList.size(); i <0; i++) {
                Code nextCode = codeService.getCacheByData(pathList.get(i - 1));
                if (nextCode!=null&&nextCode.getCornerBool()){
                    lastCorner =pathList.get(i - 1);
                }
            }
            boolean first = true;
            for (Segment segment : segmentList) {
                // 分段所属的Task
                Task task = taskService.getById(segment.getTaskId());
                // 节点条码
                Code code = codeService.getCacheById(segment.getEndNode());
                // 需要走行
                if (!lastCode.getData().equals(code.getData())) {
                    // 走行路径节点
//                    List<String> pathList = mapService.checkoutPath(agv.getUuid(), lastCode, code);
                    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;
                        }
                        String next = pathListPart.get(i);
                        Code nextCode = codeService.getCacheByData(next);
                        Double nextDirection = mapService.calculateDirection(lastCode, nextCode, angleOffsetVal);
                        boolean reverse = false;
                        if (lastCorner.equals(lastCode)){
                            // DOTO
                        }else {
                            // 第一步:如果下一个方向正好是作业方向的相反方向,则重置下一个方向为作业方向,标记 reverse = true
                            if (nextDirection.equals((workDirection + 180) % 360)) {
                                nextDirection = workDirection;
                                reverse = true;
                            }
                            // 第二步:判断当前节点是否可以旋转
                            if (!lastCode.getCornerBool()) {
                                // 如果是作业方向,但是小车在巷道内方向错误,则停止
                                if (reverse && !lastDirection.equals(nextDirection)) {
//                                throw new CoolException(agvNo + "号小车方向错误,请推至转弯点手动调整");
                                }
                                // 如果不是作业方向,判断是否相反方向,如果反方向则倒退行走
                                if (nextDirection.equals((lastDirection + 180) % 360)) {
                                    nextDirection = lastDirection;
                                    reverse = true;
                                }
                            } else {
                                if (!lastDirection.equals(nextDirection)) {
                                    // 如果下个节点方向与当前agv方向相反,则倒退行走,但是如果当前agv方向正好与工作方向相反,则旋转至工作方向
                                    if (nextDirection.equals((lastDirection + 180) % 360) && !workDirection.equals((lastDirection + 180) % 360)) {
                                        nextDirection = lastDirection;
                                        reverse = true;
                                    } else {
                                        // turn
                                        actionList.add(new Action(
                                                null,    // 编号s
                                                task.getBusId(),    // 总线
                                                task.getId(),    // 任务
                                                null,    // 动作号
                                                null,    // 优先级
                                                ActionTypeType.TurnCorner.desc,    // 名称
                                                mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性值
                                                lastCode.getData(),    // 地面码
                                                String.valueOf(nextDirection),   // 动作参数
                                                ActionTypeType.TurnCorner.val(),    // 动作类型
                                                actionPrepareSts,    // 动作进度
                                                agvId,    // AGV
                                                now    // 工作时间
                                        ));
                                        lastDirection = nextDirection;
                                    }
                                }
                            }
                        }
                        // 第一个动作一定是 turn
                        if (actionList.isEmpty()) {
                            // 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(nextDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
                                    actionPrepareSts,    // 动作进度
                                    agvId,    // AGV
                                    now    // 工作时间
                            ));
                            lastDirection = nextDirection;
                        }
                        // run
                        ActionTypeType actionType = ActionTypeType.StraightAheadTurnable;
                        if (reverse) {
                            actionType = ActionTypeType.StraightBackTurnable;
                        }
                        CodeGap gap = codeGapService.findByCodeOfBoth(lastCode.getId(), nextCode.getId());
                        actionList.add(new Action(
                                null,    // 编号
                                task.getBusId(),    // 总线
                                task.getId(),    // 任务
                                null,    // 动作号
                                null,    // 优先级
                                actionType.desc,    // 名称
                                (double) agvSpeedType.val,    // 属性值
                                lastCode.getData(),    // 地面码
                                String.valueOf(gap.getDistance()),   // 动作参数
                                actionType.val(),    // 动作类型
                                actionPrepareSts,    // 动作进度
                                agvId,    // AGV
                                now    // 工作时间
                        ));
                        lastCode = nextCode;
                    }
                }
                // 初始方向值补丁
                if (first) {
                    if (Cools.isEmpty(actionList) || !actionList.get(0).getActionType().equals(ActionTypeType.TurnCorner.val())) {
                        // 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;
                    }
                    first = false;
                }
                // 作业点动作
                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)) {
                            throw new CoolException(agvNo + "号小车方向错误,请推至转弯点手动调整");
                        }
                        // 货架取货
                        Loc oriLoc = locService.getById(task.getOriLoc());
                        // 计算左右方向
                        agvDirectionType = mapService.calculateAgvWorkDirectionByShelf(oriLoc, lastCode);
                        actionList.add(new Action(
                                null,    // 编号
                                task.getBusId(),    // 总线
                                task.getId(),    // 任务
                                null,    // 动作号
                                null,    // 优先级
                                ActionTypeType.ReadyTakeFromShelvesLoc.desc,    // 名称
                                (double) agvDirectionType.val,    // 属性值
                                lastCode.getData(),    // 地面码
                                String.valueOf(oriLoc.getOffset()),   // 动作参数
                                ActionTypeType.ReadyTakeFromShelvesLoc.val(),    // 动作类型
                                actionPrepareSts,    // 动作进度
                                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)) {
                            throw new CoolException(agvNo + "号小车方向错误,请推至转弯点手动调整");
                        }
                        // 暂存点取货货
                        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.calculateAgvWorkDirectionByShelf(destLoc, lastCode);
                        actionList.add(new Action(
                                null,    // 编号
                                task.getBusId(),    // 总线
                                task.getId(),    // 任务
                                null,    // 动作号
                                null,    // 优先级
                                ActionTypeType.ReadyReleaseToShelvesLoc.desc,    // 名称
                                (double) agvDirectionType.val,    // 属性值
                                lastCode.getData(),    // 地面码
                                String.valueOf(destLoc.getOffset()),   // 动作参数
                                ActionTypeType.ReadyReleaseToShelvesLoc.val(),    // 动作类型
                                actionPrepareSts,    // 动作进度
                                agvId,    // AGV
                                now    // 工作时间
                        ));
                        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,    // 工作时间
                                oriSta.getStaTypeIsCheck() == 1 ? 1 : 0,
                                oriSta.getStaNo()
                        ));
                        // 暂存点放货
                        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,    // 工作时间
                                destSta.getStaTypeIsCheck() == 1 ? 2 : 0,
                                destSta.getStaNo()
                        ));
                        break;
                    case TO_CHARGE:
                        // 检验方向
                        FuncSta chargeFuncSta = funcStaService.query(lastCode.getId(), FuncStaType.CHARGE.toString());
                        Double chargeDirection = Double.parseDouble(chargeFuncSta.getAngle());
                        if (!lastDirection.equals(chargeDirection)) {
                            actionList.add(new Action(
                                    null,    // 编号
                                    null,    // 总线
                                    task.getId(),    // 任务
                                    null,    // 动作号
                                    null,    // 优先级
                                    ActionTypeType.TurnCorner.desc,    // 名称
                                    mapService.isTurnCorner(lastCode.getData()) ? 1D : 0D,    // 属性값
                                    lastCode.getData(),    // 地面码
                                    String.valueOf(chargeDirection),   // 动作参数
                                    ActionTypeType.TurnCorner.val(),    // 动作类型
                                    actionPrepareSts,    // 动作进度
                                    agvId,    // AGV
                                    now    // 工作时间
                            ));
                            lastDirection = chargeDirection;
                        }
                        // charge
                        actionList.add(new Action(
                                null,    // 编号
                                null,    // 总线
                                task.getId(),    // 任务
                                null,    // 动作号
                                null,    // 优先级
                                ActionTypeType.DockingCharge.desc,    // 名称
                                null,    // 属性값
                                lastCode.getData(),    // 地面码
                                null,   // 动作参数
                                ActionTypeType.DockingCharge.val(),    // 动作类型
                                actionPrepareSts,    // 动作进度
                                agvId,    // AGV
                                now    // 工作时间
                        ));
                        break;
                    case TO_STANDBY:
//                        FuncSta standByFuncSta = funcStaService.query(agvId, lastCode.getId(), 2);
//                        Double standByDirection = Double.parseDouble(standByFuncSta.getAngle());
//                        if (!lastDirection.equals(standByDirection)) {
//                            actionList.add(new Action(
//                                    null,    // 编号
//                                    null,    // 总线
//                                    task.getId(),    // 任务
//                                    null,    // 动作号
//                                    null,    // 优先级
//                                    ActionTypeType.TurnCorner.desc,    // 名称
//                                    null,    // 属性값
//                                    lastCode.getData(),    // 地面码
//                                    String.valueOf(standByDirection),   // 动作参数
//                                    ActionTypeType.TurnCorner.val(),    // 动作类型
//                                    actionPrepareSts,    // 动作进度
//                                    agvId,    // AGV
//                                    now    // 工作时间
//                            ));
//                            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 (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;
                    default:
                        break;
                }
            }
            // finish
            actionList.add(new Action(
                    null,    // 编号
                    null,    // 总线
                    null,    // 任务
                    null,    // 动作号
                    null,    // 优先级
                    ActionTypeType.FinishPath.desc,    // 名称
                    null,    // 属性值
                    lastCode.getData(),    // 地面码
                    null,   // 动作参数
                    ActionTypeType.FinishPath.val(),    // 动作类型
                    actionPrepareSts,    // 动作进度
                    agvId,    // AGV
                    now    // 工作时间
            ));
            List<Action> newActionList = actionSorter.optimizeSort(actionList);
            String groupId = String.valueOf(snowflakeIdWorker.nextId()).substring(3);
            // save action
            int i = newActionList.size();
            for (Action action : newActionList) {
//                action.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
                action.setGroupId(groupId);
                action.setPriority(i);
                i -= 1;
            }
            if (!actionService.saveBatch(newActionList)) {
                throw new BusinessException("group[" + groupId + "] 动作保存失败");
            }
            // 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失败");
                }
            }
            log.info("{}号Agv动作组装完成,指令数量:{}", agvNo, newActionList.size());
        } catch (Exception e) {
            log.error("mainService.generateAction", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            if (!Cools.isEmpty(pathList)) {
                pathList.remove(0);
                List<int[]> codeMatrixIdxList = mapDataDispatcher.getCodeMatrixIdxList(null, pathList);
                mapDataDispatcher.clearDynamicMatrixByCodeList(null, codeMatrixIdxList);
            }
            throw new RuntimeException("generateAction method caught an exception, rolling back transaction.", e);
        }
    }
    @Transactional
    public void publishAction(String actionGroupId) {
        try {
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java
@@ -154,6 +154,21 @@
        return angle;
    }
    public static void main(String[] args) {
        Double x0 = 2D;
        Double y0 = 2D;
        Double x1 = 2D;
        Double y1 = 1D;
        double deltaX = x1 - x0;
        double deltaY = y1 - y0;
        double angle = Math.atan2(deltaX, deltaY);
        angle = Math.toDegrees(angle) + 0;
        angle = (angle + 360) % 360; // 将角度转换为正值
        System.out.println(angle);
    }
    // 坐标货架阈值 todo:luxiaotao
    public AgvDirectionType calculateAgvWorkDirectionByShelf(Loc loc, Code code) {
        Integer compDirect = loc.getCompDirect();
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/entity/Loc.java
@@ -1,6 +1,7 @@
package com.zy.acs.manager.manager.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zy.acs.framework.common.Cools;
@@ -80,6 +81,7 @@
     * 排
     */
    @ApiModelProperty(value= "排")
    @TableField("`row`")
    private Integer row;
    /**
zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/FuncStaServiceImpl.java
@@ -61,16 +61,16 @@
        }
        // area limit
        List<String> areaCodeList = agvAreaDispatcher.getAreaCodeListByAgvNo(agvService.getAgvNo(agvId));
        if (Cools.isEmpty(areaCodeList)) {
            funcStaList.clear();
        } else {
            funcStaList.removeIf(funcSta -> {
                Code code = codeService.getCacheById(funcSta.getCode());
                if (Cools.isEmpty(code, code.getData())) { return true; }
                return !areaCodeList.contains(code.getData());
            });
        }
//        List<String> areaCodeList = agvAreaDispatcher.getAreaCodeListByAgvNo(agvService.getAgvNo(agvId));
//        if (Cools.isEmpty(areaCodeList)) {
//            funcStaList.clear();
//        } else {
//            funcStaList.removeIf(funcSta -> {
//                Code code = codeService.getCacheById(funcSta.getCode());
//                if (Cools.isEmpty(code, code.getData())) { return true; }
//                return !areaCodeList.contains(code.getData());
//            });
//        }
        if (!Cools.isEmpty(funcStaList)) {
            Collections.shuffle(funcStaList);
zy-acs-manager/src/main/resources/application-dev.yml
@@ -1,87 +0,0 @@
server:
  port: 8088
spring:
  application:
    name: @pom.artifactId@
  mvc:
    static-path-pattern: /**
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jbly?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: xltys1995
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      max-wait: 30000
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      test-while-idle: true
      test-on-borrow: true
      test-on-return: false
      remove-abandoned: true
      remove-abandoned-timeout: 1800
      #pool-prepared-statements: false
      #max-pool-prepared-statement-per-connection-size: 20
      filters: stat, wall
      validation-query: SELECT 'x'
      aop-patterns: com.zy.*.*.service.*
      stat-view-servlet:
        url-pattern: /druid/*
        reset-enable: true
        login-username: admin
        login-password: admin
        enabled: true
  servlet:
    multipart:
      maxFileSize: 100MB
      maxRequestSize: 100MB
  jmx:
    enabled: false
redis:
  host: 127.0.0.1
  password: xltys1995
  port: 6379
  max: 30
  min: 10
  timeout: 5000
  index: 4
floyd:
  enable: false
eureka:
  client:
    enabled: false
    serviceUrl:
      defaultZone: http://192.168.2.46:8765/eureka/
mybatis-plus:
  mapper-locations: classpath:mapper/*/*.xml
  #  global-config:
  #    field-strategy: 0
  configuration:
    #    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
    cache-enabled: true
  global-config:
    :banner: false
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0
logging:
  file:
    path: stock/out/rcs-manager/logs
config:
  open-office-home: C
  swagger-base-package: com.zy.acs
  swagger-title: ACS API文档
  swagger-version: 1.0
  token-key: KUHSMcYQ4lePt3r6bckz0P13cBJyoonYqInThvQlUnbsFCIcCcZZAbWZ6UNFztYNYPhGdy6eyb8WdIz8FU2Cz396TyTJk3NI2rtXMHBOehRb4WWJ4MdYVVg2oWPyqRQ2
zy-acs-manager/src/main/resources/application.yml
@@ -4,13 +4,15 @@
spring:
  application:
    name: @pom.artifactId@
  profiles:
    active: dev
  mvc:
    static-path-pattern: /**
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://10.10.10.200:3306/jbly?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    url: jdbc:mysql://127.0.0.1:3306/ybly?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: xltys1995
    password: 34821015
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
@@ -43,7 +45,7 @@
    enabled: false
redis:
  host: 10.10.10.200
  host: 127.0.0.1
  password: xltys1995
  port: 6379
  max: 30