#
vincentlu
2026-04-07 1027b845bde5f9419b49d8db49cd452ab5081976
#
6个文件已修改
93 ■■■■ 已修改文件
version/db/rcs_ctu_stable_hik.sql 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/HkAgvDataService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/hik/HikOrderPublishService.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/utils/AgvAngleUtils.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/fake/AgvSimulatorTask.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
version/db/rcs_ctu_stable_hik.sql
@@ -1955,7 +1955,7 @@
LOCK TABLES `sys_config` WRITE;
/*!40000 ALTER TABLE `sys_config` DISABLE KEYS */;
INSERT INTO `sys_config` VALUES (1,'a','b','c',1,'dd','eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',0,1,NULL,NULL,'2024-09-03 03:23:14',NULL,'2024-09-03 03:23:14','aaavv'),(2,'1','2','3',2,'4','5',1,1,NULL,NULL,'2024-09-03 03:54:51',NULL,'2024-09-03 03:54:51',NULL),(3,'','vb','d',NULL,NULL,NULL,1,1,NULL,2,'2024-09-05 12:40:15',2,'2024-09-05 12:44:52',NULL),(4,NULL,'任务总线接收上限数量','busLimit',2,'1',NULL,1,1,NULL,2,'2024-09-10 05:02:36',2,'2024-09-10 05:02:36',NULL),(5,'3080437672968192','任务总线接收上限数量','busLimit',2,'1',NULL,1,0,NULL,2,'2024-09-10 05:03:35',2,'2024-09-10 05:03:35',NULL),(6,'3080530866208768','货架方向','storeDirection',4,'{\"key\":\"row\", \"acs\": 1}',NULL,1,0,NULL,2,'2024-09-10 05:03:57',2,'2024-09-10 05:03:57',NULL),(7,'3080602718830592','地图x轴偏移角度(默认顺时针0度)','mapAngleOffsetVal',2,'270',NULL,1,1,NULL,2,'2024-09-10 05:04:14',2,'2026-04-07 02:45:38',NULL),(8,'3080671664799744','取放货Agv方向','workDirection',2,'90',NULL,1,1,NULL,2,'2024-09-10 05:04:31',2,'2024-09-10 05:04:31',NULL),(9,'3080749704019968','Agv行走速度','agvSpeed',3,'5',NULL,1,0,NULL,2,'2024-09-10 05:04:49',2,'2024-09-10 05:04:49',NULL),(10,'3080876476858368','巷道坐标同组值','sameGroupXy',3,'X',NULL,1,0,NULL,2,'2024-09-10 05:05:19',2,'2024-11-09 07:46:10',NULL),(11,'5385822480039936','冗余数据转入历史档周期(天)','dataExpiredDays',2,'-1',NULL,1,0,NULL,2,'2024-10-14 04:00:47',2,'2024-11-13 04:20:43',NULL),(12,'7198705308336128','RCS启动任务分配状态','TaskAssignMode',1,'TRUE',NULL,1,0,NULL,2,'2024-10-19 04:04:32',2,'2024-10-19 04:11:08',NULL),(13,'0385233689903104','单巷道车辆容载数量','maxAgvCountInLane',2,'2',NULL,1,0,NULL,2,'2024-10-28 00:06:40',2,'2024-10-28 00:06:40',NULL),(14,'1171843016687616','自动回待机位','automaticStandbyPosition',1,'0',NULL,1,0,NULL,2,'2024-10-30 04:12:22',2,'2024-12-05 05:14:12',NULL),(15,'1174416499015680','自动回待机位间隔(秒)','intervalOfAutoStandby',2,'15',NULL,1,0,NULL,2,'2024-10-30 04:22:36',2,'2024-11-29 06:51:07',NULL),(16,'4749527806246912','虚拟运行','fakeSign',1,'TRUE',NULL,1,0,NULL,2,'2024-11-09 01:08:49',2,'2024-11-09 03:57:04',NULL),(17,'1487422084612096','算法延长时间(单位:毫秒)','algoExtensionTime',2,'0',NULL,1,0,NULL,2,'2024-12-25 05:39:13',2,'2024-12-25 05:39:39',NULL),(18,'7392066282651649','Dashboard-AGV角度偏移量','dashboardAgvAngleOffsetVal',2,'0',NULL,1,0,NULL,2,'2026-01-04 07:15:46',2,'2026-04-07 04:43:26',NULL),(19,'7392156325969920','Dashboard-监控图镜面翻转','dashMapMirror',1,'1',NULL,1,0,NULL,2,'2026-01-04 07:16:07',2,'2026-04-07 04:45:24',NULL),(20,'7405872845094912','移库','TaskAssignMode3',1,'0',NULL,1,0,NULL,2,'2026-01-04 08:10:37',2,'2026-01-06 05:50:13',NULL),(21,'3453459058524160','自动移动','TaskAssignRebootMode',1,'0',NULL,1,0,NULL,2,'2026-01-21 00:41:34',2,'2026-02-09 05:17:48',NULL),(22,'3453459058524161','取放','defaultShelfDepth',2,'0',NULL,1,0,NULL,NULL,'2026-01-26 23:18:15',NULL,'2026-01-26 23:18:15',NULL),(23,'8839085828079616','233223','maintainLocSts',1,'0',NULL,1,0,NULL,2,'2026-04-01 01:54:59',2,'2026-04-01 01:54:59',NULL);
INSERT INTO `sys_config` VALUES (1,'a','b','c',1,'dd','eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',0,1,NULL,NULL,'2024-09-03 03:23:14',NULL,'2024-09-03 03:23:14','aaavv'),(2,'1','2','3',2,'4','5',1,1,NULL,NULL,'2024-09-03 03:54:51',NULL,'2024-09-03 03:54:51',NULL),(3,'','vb','d',NULL,NULL,NULL,1,1,NULL,2,'2024-09-05 12:40:15',2,'2024-09-05 12:44:52',NULL),(4,NULL,'任务总线接收上限数量','busLimit',2,'1',NULL,1,1,NULL,2,'2024-09-10 05:02:36',2,'2024-09-10 05:02:36',NULL),(5,'3080437672968192','任务总线接收上限数量','busLimit',2,'1',NULL,1,0,NULL,2,'2024-09-10 05:03:35',2,'2024-09-10 05:03:35',NULL),(6,'3080530866208768','货架方向','storeDirection',4,'{\"key\":\"row\", \"acs\": 1}',NULL,1,0,NULL,2,'2024-09-10 05:03:57',2,'2024-09-10 05:03:57',NULL),(7,'3080602718830592','地图x轴偏移角度(默认顺时针0度)','mapAngleOffsetVal',2,'270',NULL,1,0,NULL,2,'2024-09-10 05:04:14',2,'2026-04-07 02:45:38',NULL),(8,'3080671664799744','取放货Agv方向','workDirection',2,'90',NULL,1,1,NULL,2,'2024-09-10 05:04:31',2,'2024-09-10 05:04:31',NULL),(9,'3080749704019968','Agv行走速度','agvSpeed',3,'5',NULL,1,0,NULL,2,'2024-09-10 05:04:49',2,'2024-09-10 05:04:49',NULL),(10,'3080876476858368','巷道坐标同组值','sameGroupXy',3,'X',NULL,1,0,NULL,2,'2024-09-10 05:05:19',2,'2024-11-09 07:46:10',NULL),(11,'5385822480039936','冗余数据转入历史档周期(天)','dataExpiredDays',2,'-1',NULL,1,0,NULL,2,'2024-10-14 04:00:47',2,'2024-11-13 04:20:43',NULL),(12,'7198705308336128','RCS启动任务分配状态','TaskAssignMode',1,'TRUE',NULL,1,0,NULL,2,'2024-10-19 04:04:32',2,'2024-10-19 04:11:08',NULL),(13,'0385233689903104','单巷道车辆容载数量','maxAgvCountInLane',2,'2',NULL,1,0,NULL,2,'2024-10-28 00:06:40',2,'2024-10-28 00:06:40',NULL),(14,'1171843016687616','自动回待机位','automaticStandbyPosition',1,'0',NULL,1,0,NULL,2,'2024-10-30 04:12:22',2,'2024-12-05 05:14:12',NULL),(15,'1174416499015680','自动回待机位间隔(秒)','intervalOfAutoStandby',2,'15',NULL,1,0,NULL,2,'2024-10-30 04:22:36',2,'2024-11-29 06:51:07',NULL),(16,'4749527806246912','虚拟运行','fakeSign',1,'TRUE',NULL,1,0,NULL,2,'2024-11-09 01:08:49',2,'2024-11-09 03:57:04',NULL),(17,'1487422084612096','算法延长时间(单位:毫秒)','algoExtensionTime',2,'0',NULL,1,0,NULL,2,'2024-12-25 05:39:13',2,'2024-12-25 05:39:39',NULL),(18,'7392066282651649','Dashboard-AGV角度偏移量','dashboardAgvAngleOffsetVal',2,'0',NULL,1,0,NULL,2,'2026-01-04 07:15:46',2,'2026-04-07 04:43:26',NULL),(19,'7392156325969920','Dashboard-监控图镜面翻转','dashMapMirror',1,'1',NULL,1,0,NULL,2,'2026-01-04 07:16:07',2,'2026-04-07 04:45:24',NULL),(20,'7405872845094912','移库','TaskAssignMode3',1,'0',NULL,1,0,NULL,2,'2026-01-04 08:10:37',2,'2026-01-06 05:50:13',NULL),(21,'3453459058524160','自动移动','TaskAssignRebootMode',1,'0',NULL,1,0,NULL,2,'2026-01-21 00:41:34',2,'2026-02-09 05:17:48',NULL),(22,'3453459058524161','取放','defaultShelfDepth',2,'0',NULL,1,0,NULL,NULL,'2026-01-26 23:18:15',NULL,'2026-01-26 23:18:15',NULL),(23,'8839085828079616','233223','maintainLocSts',1,'0',NULL,1,0,NULL,2,'2026-04-01 01:54:59',2,'2026-04-01 01:54:59',NULL);
/*!40000 ALTER TABLE `sys_config` ENABLE KEYS */;
UNLOCK TABLES;
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/HkAgvDataService.java
@@ -15,8 +15,10 @@
import com.zy.acs.manager.core.service.astart.MapDataDispatcher;
import com.zy.acs.manager.core.utils.AgvAngleUtils;
import com.zy.acs.manager.manager.entity.AgvDetail;
import com.zy.acs.manager.manager.entity.AgvModel;
import com.zy.acs.manager.manager.entity.Code;
import com.zy.acs.manager.manager.service.AgvDetailService;
import com.zy.acs.manager.manager.service.AgvModelService;
import com.zy.acs.manager.manager.service.AgvService;
import com.zy.acs.manager.manager.service.CodeService;
import com.zy.acs.manager.manager.service.JamService;
@@ -43,6 +45,8 @@
    private AgvService agvService;
    @Autowired
    private AgvDetailService agvDetailService;
    @Autowired
    private AgvModelService agvModelService;
    @Autowired
    private CodeService codeService;
    @Autowired
@@ -131,9 +135,14 @@
    private void syncPose(AgvDetail detail, HkState state) {
        HkStateAgvPosition agvPosition = state.getAgvPosition();
        HkStateVelocity velocity = state.getVelocity();
        AgvModel agvModel = agvModelService.getByAgvId(detail.getAgvId());
        if (agvPosition != null && agvPosition.getTheta() != null) {
            double angle = normalizeAngle(AgvAngleUtils.fromRadians(agvPosition.getTheta()));
            Double rcsAngle = AgvAngleUtils.fromProtocolRadians(agvPosition.getTheta(), agvModel);
            if (rcsAngle == null) {
                return;
            }
            double angle = normalizeAngle(rcsAngle);
            detail.setAgvAngle(angle);
            detail.setGyroAngle(angle);
            detail.setEncoderAngle(angle);
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
@@ -23,7 +23,6 @@
import com.zy.acs.manager.core.integrate.dto.OpenBusSubmitParam;
import com.zy.acs.manager.core.service.hik.HikOrderPublishService;
import com.zy.acs.manager.core.service.astart.MapDataDispatcher;
import com.zy.acs.manager.core.utils.AgvAngleUtils;
import com.zy.acs.manager.manager.entity.*;
import com.zy.acs.manager.manager.enums.*;
import com.zy.acs.manager.manager.service.*;
@@ -902,6 +901,7 @@
            if (Cools.isEmpty(agvId, segmentList)) { return pathTrace; }
            Date now = new Date();
            long actionPrepareSts = ActionStsType.PREPARE.val();
            int angleOffsetVal = configService.getVal("mapAngleOffsetVal", Integer.class);
//            Double defaultShelfDepth = configService.getVal("defaultShelfDepth", Double.class);
//            defaultShelfDepth = Optional.ofNullable(defaultShelfDepth).orElse((double) 0);
            String agvNo = agvService.getAgvNo(agvId);
@@ -950,7 +950,7 @@
                        Code nextCode = codeService.getCacheByData(next);
                        // 车头朝前的下一个行走方向
                        Double nextDirection = AgvAngleUtils.calculateDirection(lastCode, nextCode, agvModel);
                        Double nextDirection = mapService.calculateDirection(lastCode, nextCode, angleOffsetVal);
                        // 反向角
                        final double oppLastDir = (lastDirection + 180) % 360;
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/hik/HikOrderPublishService.java
@@ -24,6 +24,7 @@
import com.zy.acs.manager.manager.enums.ActionTypeType;
import com.zy.acs.manager.manager.service.AgvDetailService;
import com.zy.acs.manager.manager.service.CodeService;
import com.zy.acs.manager.system.service.ConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -48,6 +49,10 @@
    private CodeService codeService;
    @Autowired
    private AgvDetailService agvDetailService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private MapService mapService;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
@@ -108,7 +113,7 @@
        NodeCursor currentNode = createNode(actionGroupId, firstAction.getCode(), nodeIndex++, sequenceId++);
        Double currentDirection = resolveInitialNodeDirection(firstAction);
        applyNodeTheta(currentNode.node, currentDirection);
        applyNodeTheta(currentNode.node, currentDirection, agvModel);
        nodes.add(currentNode.node);
        for (int i = 0; i < actionList.size(); i++) {
@@ -124,21 +129,21 @@
            switch (actionType) {
                case TurnCorner:
                    currentDirection = parseDirectionDegrees(action.getParams());
                    currentNode.node.getActions().add(buildRotateAgvAction(action, currentDirection));
                    currentNode.node.getActions().add(buildRotateAgvAction(action, currentDirection, agvModel));
                    break;
                case StraightAheadTurnable:
                case StraightAheadUnturnable:
                case StraightBackTurnable:
                case StraightBackUnturnable:
                    String endCode = findNextMoveEndCode(actionList, i, currentNode.code);
                    Double travelDirection = calculateTravelDirection(currentNode.code, endCode, agvModel);
                    Double travelDirection = calculateTravelDirection(currentNode.code, endCode);
                    Double moveDirection = resolveMoveDirection(currentDirection, travelDirection, actionType, actionGroupId, currentNode.code, endCode);
                    Double edgeOrientation = resolveEdgeOrientation(moveDirection, travelDirection);
                    HkOrderEdge edge = createEdge(actionGroupId, edgeIndex++, sequenceId++, currentNode, endCode, edgeOrientation, action, agvModel);
                    edges.add(edge);
                    NodeCursor nextNode = createNode(actionGroupId, endCode, nodeIndex++, sequenceId++);
                    applyNodeTheta(nextNode.node, moveDirection);
                    applyNodeTheta(nextNode.node, moveDirection, agvModel);
                    nodes.add(nextNode.node);
                    currentNode = nextNode;
@@ -147,7 +152,7 @@
                case FinishPath:
                    break;
                default:
                    currentNode.node.getActions().add(buildNodeAction(action, actionType, toHikThetaRadians(currentDirection)));
                    currentNode.node.getActions().add(buildNodeAction(action, actionType, toHikThetaRadians(currentDirection, agvModel)));
                    break;
            }
        }
@@ -286,7 +291,7 @@
        return hkAction;
    }
    private HkAction buildRotateAgvAction(Action action, Double targetDirection) {
    private HkAction buildRotateAgvAction(Action action, Double targetDirection, AgvModel agvModel) {
        HkAction hkAction = new HkAction();
        hkAction.setActionId("A" + action.getId());
        hkAction.setActionDescription(ActionTypeType.TurnCorner.desc);
@@ -296,7 +301,7 @@
        List<HkActionParameter> parameters = new ArrayList<>();
        addParameter(parameters, "sourceActionType", ActionTypeType.TurnCorner.name());
        addParameter(parameters, "sourceActionId", action.getId());
        addParameter(parameters, "angle", toHikThetaRadians(targetDirection));
        addParameter(parameters, "angle", toHikThetaRadians(targetDirection, agvModel));
        hkAction.setActionParameters(parameters);
        return hkAction;
    }
@@ -375,24 +380,28 @@
        return parseDouble(params);
    }
    private Double toHikThetaRadians(Double thetaDegrees) {
        return AgvAngleUtils.toRadians(thetaDegrees);
    private Double toHikThetaRadians(Double rcsThetaDegrees, AgvModel agvModel) {
        return AgvAngleUtils.toProtocolRadians(rcsThetaDegrees, agvModel);
    }
    private void applyNodeTheta(HkOrderNode node, Double directionDegrees) {
    private void applyNodeTheta(HkOrderNode node, Double rcsDirectionDegrees, AgvModel agvModel) {
        if (node == null || node.getNodePosition() == null) {
            return;
        }
        node.getNodePosition().setTheta(toHikThetaRadians(directionDegrees));
        node.getNodePosition().setTheta(toHikThetaRadians(rcsDirectionDegrees, agvModel));
    }
    private Double calculateTravelDirection(String startCode, String endCode, AgvModel agvModel) {
    private Double calculateTravelDirection(String startCode, String endCode) {
        Code start = codeService.getCacheByData(startCode);
        Code end = codeService.getCacheByData(endCode);
        if (start == null || end == null) {
            throw new CoolException("hik order adaptation failed: code position missing");
        }
        return AgvAngleUtils.calculateDirection(start, end, agvModel);
        Integer angleOffsetVal = configService.getVal("mapAngleOffsetVal", Integer.class);
        if (angleOffsetVal == null) {
            angleOffsetVal = 0;
        }
        return mapService.calculateDirection(start, end, angleOffsetVal);
    }
    private Double resolveMoveDirection(Double currentDirection,
zy-acs-manager/src/main/java/com/zy/acs/manager/core/utils/AgvAngleUtils.java
@@ -2,57 +2,47 @@
import com.zy.acs.common.enums.ClockwiseType;
import com.zy.acs.manager.manager.entity.AgvModel;
import com.zy.acs.manager.manager.entity.Code;
/**
 * 车型角度工具:
 * 将地图物理方向(默认顺时针)转换为车型自身角度体系。
 * 仅用于在 RCS 统一角度系 与 车型/协议角度系 之间做转换。
 */
public final class AgvAngleUtils {
    private AgvAngleUtils() {
    }
    public static Double calculateDirection(Code startCode, Code endCode, AgvModel agvModel) {
        if (startCode == null || endCode == null) {
            return null;
        }
        double deltaX = endCode.getX() - startCode.getX();
        double deltaY = endCode.getY() - startCode.getY();
        double mapAngle = Math.toDegrees(Math.atan2(deltaX, deltaY));
        return toModelAngle(normalizeAngle(mapAngle), agvModel);
    }
    public static Double toModelAngle(Double mapAngleDegrees, AgvModel agvModel) {
        if (mapAngleDegrees == null) {
    public static Double toProtocolAngle(Double rcsAngleDegrees, AgvModel agvModel) {
        if (rcsAngleDegrees == null) {
            return null;
        }
        double factor = isClockwise(agvModel) ? 1D : -1D;
        double offset = getAngleOffsetDeg(agvModel);
        return normalizeAngle(factor * normalizeAngle(mapAngleDegrees) + offset);
        return normalizeAngle(factor * normalizeAngle(rcsAngleDegrees) + offset);
    }
    public static Double fromModelAngle(Double modelAngleDegrees, AgvModel agvModel) {
        if (modelAngleDegrees == null) {
    public static Double fromProtocolAngle(Double protocolAngleDegrees, AgvModel agvModel) {
        if (protocolAngleDegrees == null) {
            return null;
        }
        double factor = isClockwise(agvModel) ? 1D : -1D;
        double offset = getAngleOffsetDeg(agvModel);
        return normalizeAngle(factor * (normalizeAngle(modelAngleDegrees) - offset));
        return normalizeAngle(factor * (normalizeAngle(protocolAngleDegrees) - offset));
    }
    public static Double toRadians(Double angleDegrees) {
        if (angleDegrees == null) {
    public static Double toProtocolRadians(Double rcsAngleDegrees, AgvModel agvModel) {
        Double protocolAngleDegrees = toProtocolAngle(rcsAngleDegrees, agvModel);
        if (protocolAngleDegrees == null) {
            return null;
        }
        return Math.toRadians(normalizeAngle(angleDegrees));
        return Math.toRadians(protocolAngleDegrees);
    }
    public static Double fromRadians(Double angleRadians) {
        if (angleRadians == null) {
    public static Double fromProtocolRadians(Double protocolAngleRadians, AgvModel agvModel) {
        if (protocolAngleRadians == null) {
            return null;
        }
        return normalizeAngle(Math.toDegrees(angleRadians));
        return fromProtocolAngle(Math.toDegrees(protocolAngleRadians), agvModel);
    }
    public static Double normalizeAngle(Double angleDegrees) {
zy-acs-manager/src/main/java/com/zy/acs/manager/fake/AgvSimulatorTask.java
@@ -278,7 +278,8 @@
        AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
        if (agvDetail != null && agvDetail.getAgvAngle() != null) {
            position.setTheta(AgvAngleUtils.toRadians(agvDetail.getAgvAngle()));
            AgvModel agvModel = agvModelService.getByAgvId(agv.getId());
            position.setTheta(AgvAngleUtils.toProtocolRadians(agvDetail.getAgvAngle(), agvModel));
        }
        return position;
    }