#
vincentlu
2026-03-25 8137724b0b7325b0a68f2c9726ec4e437b6ee478
#
5个文件已添加
4个文件已修改
215 ■■■■■ 已修改文件
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkConnectionMessage.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkMessageHeader.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkNodePosition.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkOrderEdge.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkOrderMessage.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkOrderNode.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/mqtt/HkTopicBuilder.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/mqtt/publisher/HkOrderPublisher.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/mqtt/type/HkSubTopicType.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkConnectionMessage.java
@@ -1,9 +1,12 @@
package com.zy.acs.common.hk;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class HkConnectionMessage extends HkMessageHeader {
    // 连接状态:ONLINE、OFFLINE、CONNECTIONBROKEN
    private HkConnectionStateType connectionState;
}
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkMessageHeader.java
@@ -5,13 +5,18 @@
@Data
public class HkMessageHeader {
    // 消息头 ID
    private Long headerId;
    // 消息时间戳,ISO 8601 UTC 格式
    private String timestamp;
    // 协议版本号
    private String version;
    // AGV 制造商
    private String manufacturer;
    // AGV 车号
    private String serialNumber;
}
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkNodePosition.java
New file
@@ -0,0 +1,17 @@
package com.zy.acs.common.hk;
import lombok.Data;
@Data
public class HkNodePosition {
    // 节点在地图坐标系上的 x 坐标,单位 m
    private Double x;
    // 节点在地图坐标系上的 y 坐标,单位 m
    private Double y;
    // 节点在地图坐标系上的绝对角度,单位 rad
    private Double theta;
}
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkOrderEdge.java
New file
@@ -0,0 +1,57 @@
package com.zy.acs.common.hk;
import lombok.Data;
import java.util.List;
@Data
public class HkOrderEdge {
    // 路径段唯一标识
    private String edgeId;
    // 路径段编号,用于确定节点和路径段顺序
    private Long sequenceId;
    // 路径段描述
    private String edgeDescription;
    // 路径段是否被释放发布
    private Boolean released;
    // 起始节点 ID
    private String startNodeId;
    // 终点节点 ID
    private String endNodeId;
    // 允许 AGV 在该路径段的最大速度
    private Double maxSpeed;
    // AGV 在路径段上的朝向角度
    private Double orientation;
    // 朝向类型,例如 GLOBAL、TANGENTIAL
    private String orientationType;
    // 是否允许旋转
    private Boolean rotationAllowed;
    // 最大旋转速度
    private Double maxRotationSpeed;
    // 车辆最大限高
    private Double maxHeight;
    // 执行机构最低限高
    private Double minHeight;
    // 执行机构姿态信息,待协议细化
    private Object actuator;
    // 轨迹对象,待协议细化
    private Object trajectory;
    // 路径上的动作列表,待协议细化
    private List<Object> actions;
}
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkOrderMessage.java
New file
@@ -0,0 +1,26 @@
package com.zy.acs.common.hk;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Data
public class HkOrderMessage extends HkMessageHeader {
    // 任务 ID
    private String orderId;
    // 任务更新 ID
    private Long orderUpdateId;
    // 区域地图集唯一标识
    private String zoneSetId;
    // 任务节点数组
    private List<HkOrderNode> nodes;
    // 任务路径段数组
    private List<HkOrderEdge> edges;
}
zy-acs-common/src/main/java/com/zy/acs/common/hk/HkOrderNode.java
New file
@@ -0,0 +1,42 @@
package com.zy.acs.common.hk;
import lombok.Data;
import java.util.List;
@Data
public class HkOrderNode {
    // 节点唯一标识
    private String nodeId;
    // 节点编号,用于确定节点和路径段顺序
    private Long sequenceId;
    // 节点描述
    private String nodeDescription;
    // 节点是否被释放发布
    private Boolean released;
    // 节点位置
    private HkNodePosition nodePosition;
    // 节点 xy 方向精度范围,单位 m
    private Double allowedDeviationXY;
    // 节点角度精度范围,单位 rad
    private Double allowedDeviationTheta;
    // 节点所在地图 ID
    private String mapId;
    // 地图描述
    private String mapDescription;
    // 执行机构姿态信息,待协议细化
    private Object actuator;
    // 节点上的动作列表,待协议细化
    private List<Object> actions;
}
zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/mqtt/HkTopicBuilder.java
@@ -18,6 +18,9 @@
    public List<String> buildSubscribeTopics() {
        List<String> topics = new ArrayList<>();
        for (HkSubTopicType subTopicEnum : HkSubTopicType.values()) {
            if (!subTopicEnum.isSubscribe()) {
                continue;
            }
            topics.add(buildTopic("+", subTopicEnum.getCode()));
        }
        return topics;
zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/mqtt/publisher/HkOrderPublisher.java
New file
@@ -0,0 +1,47 @@
package com.zy.acs.hk.latent.mqtt.publisher;
import com.zy.acs.common.hk.HkOrderMessage;
import com.zy.acs.common.utils.GsonUtils;
import com.zy.acs.hk.latent.mqtt.EmqxMqttClient;
import com.zy.acs.hk.latent.mqtt.HkTopicBuilder;
import com.zy.acs.hk.latent.mqtt.type.HkSubTopicType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Slf4j
@Component
public class HkOrderPublisher {
    @Autowired
    private EmqxMqttClient emqxMqttClient;
    @Autowired
    private HkTopicBuilder hkTopicBuilder;
    public void publish(HkOrderMessage orderMessage) {
        if (orderMessage == null) {
            throw new IllegalArgumentException("orderMessage can not be null");
        }
        if (!StringUtils.hasText(orderMessage.getSerialNumber())) {
            throw new IllegalArgumentException("orderMessage.serialNumber can not be blank");
        }
        if (!StringUtils.hasText(orderMessage.getOrderId())) {
            throw new IllegalArgumentException("orderMessage.orderId can not be blank");
        }
        if (orderMessage.getOrderUpdateId() == null) {
            throw new IllegalArgumentException("orderMessage.orderUpdateId can not be null");
        }
        String topic = hkTopicBuilder.buildTopic(orderMessage.getSerialNumber(), HkSubTopicType.ORDER.getCode());
        String payload = GsonUtils.toJson(orderMessage);
        emqxMqttClient.publish(topic, payload);
        log.info("publish hk order message, agvNo={}, orderId={}, orderUpdateId={}, topic={}",
                orderMessage.getSerialNumber(),
                orderMessage.getOrderId(),
                orderMessage.getOrderUpdateId(),
                topic);
    }
}
zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/mqtt/type/HkSubTopicType.java
@@ -6,15 +6,20 @@
@Getter
public enum HkSubTopicType {
    STATE("state"),
    VISUALIZATION("visualization"),
    CONNECTION("connection"),
    FACTSHEET("factsheet");
    STATE("state", true),
    VISUALIZATION("visualization", true),
    CONNECTION("connection", true),
    FACTSHEET("factsheet", true),
    ORDER("order", false),
    INSTANT_ACTIONS("instantActions", false);
    private final String code;
    HkSubTopicType(String code) {
    private final boolean subscribe;
    HkSubTopicType(String code, boolean subscribe) {
        this.code = code;
        this.subscribe = subscribe;
    }
    public static HkSubTopicType fromCode(String code) {