# MQTT 通信协议文档 ## 1. 概述 PlannerNode2 机器人决策系统使用 MQTT 协议实现智能体与外部业务模块(屏幕、机械臂、人脸识别等)之间的通信。 **依赖安装**: ```bash pip install paho-mqtt ``` --- ## 2. Topic 定义 ### 2.1 发布 (Publish) Topic | Topic 名称 | 方向 | 说明 | |-----------|------|------| | `/ai/agent/command` | 智能体 → 外部模块 | 发布命令消息 | ### 2.2 订阅 (Subscribe) Topic | Topic 名称 | 方向 | 说明 | |-----------|------|------| | `/ai/module/status` | 外部模块 → 智能体 | 接收外部模块状态更新 | | `/ai/module/event` | 外部模块 → 智能体 | 接收外部模块事件通知(如人脸识别结果) | --- ## 3. 消息格式 ### 3.1 命令消息结构 (Command Message) 所有通过 MQTT 发送的命令消息统一使用以下 JSON 格式: ```json { "msg_id": "agent_", "source": "agent", "target": "<目标模块>", "module": "<模块类型>", "action": "<动作名称>", "page": "<页面标识>", "payload": { // 额外参数 }, "timestamp": } ``` ### 3.2 字段说明 | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `msg_id` | string | 是 | 消息唯一 ID,格式:`agent_<毫秒时间戳>` | | `source` | string | 是 | 消息来源,固定为 `"agent"` | | `target` | string | 是 | 目标模块(见下方模块列表) | | `module` | string | 是 | 模块类型 | | `action` | string | 是 | 动作名称 | | `page` | string | 否 | 页面标识,用于 UI 相关操作 | | `payload` | object | 否 | 额外参数 | | `timestamp` | int | 是 | Unix 时间戳(秒) | --- ## 4. 目标模块 (target) | target 值 | 说明 | 接收方 | |-----------|------|--------| | `all` | 所有模块(广播) | 全系统 | | `screen` | 屏幕/UI 模块 | 屏幕控制系统 | | `face` | 人脸识别模块 | 人脸识别服务 | | `nav` | 导航模块 | 导航控制系统 | | `visitor` | 访客管理模块 | 访客登记系统 | | `customer_service` | 客服模块 | 客服呼叫系统 | | `advertisement` | 广告模块 | 广告播放系统 | | `arm` | 机械臂模块 | 机械臂控制系统 | --- ## 5. 已实现的业务函数 ### 5.1 global_pause - 全局暂停 **功能**:通知所有外部模块暂停当前业务。 **使用场景**: - 机器人被唤醒时 - 进入语音交互前 - 欢迎语播放前 - 业务页面切换时 **调用方式**: ```python self.mqtt_client.publish_command( target="all", module="system", action="pause", page="", payload={ "reason": "wakeup", "source_behavior": "agent_wakeup" } ) ``` **示例消息**: ```json { "msg_id": "agent_1747734123000", "source": "agent", "target": "all", "module": "system", "action": "pause", "page": "", "payload": { "reason": "wakeup", "source_behavior": "agent_wakeup" }, "timestamp": 1747734123 } ``` --- ### 5.2 open_visitor_register_page - 访客登记页面 **功能**:唤醒访客登记页面。 **调用方式**: ```python self.mqtt_client.publish_command( target="screen", module="visitor", action="open_page", page="visitor_register", payload={ "title": "访客登记", "input_mode": "touch_and_voice" } ) ``` **示例消息**: ```json { "msg_id": "agent_1747734123001", "source": "agent", "target": "screen", "module": "visitor", "action": "open_page", "page": "visitor_register", "payload": { "title": "访客登记", "input_mode": "touch_and_voice" }, "timestamp": 1747734123 } ``` --- ### 5.3 open_appointment_confirm_page - 预约确认页面 **功能**:唤醒预约确认页面。 **调用方式**: ```python self.mqtt_client.publish_command( target="screen", module="visitor", action="open_page", page="appointment_confirm", payload={ "title": "预约确认", "input_mode": "touch" } ) ``` **示例消息**: ```json { "msg_id": "agent_1747734123002", "source": "agent", "target": "screen", "module": "visitor", "action": "open_page", "page": "appointment_confirm", "payload": { "title": "预约确认", "input_mode": "touch" }, "timestamp": 1747734123 } ``` --- ### 5.4 open_navigation_page - 导航页面 **功能**:唤醒导航页面。 **调用方式**: ```python self.mqtt_client.publish_command( target="screen", module="nav", action="open_page", page="navigation", payload={ "title": "导航服务", "mode": "select_destination" } ) ``` **示例消息**: ```json { "msg_id": "agent_1747734123003", "source": "agent", "target": "screen", "module": "nav", "action": "open_page", "page": "navigation", "payload": { "title": "导航服务", "mode": "select_destination" }, "timestamp": 1747734123 } ``` --- ### 5.5 open_customer_service_page - 呼叫客服页面 **功能**:唤醒呼叫客服页面。 **调用方式**: ```python self.mqtt_client.publish_command( target="screen", module="customer_service", action="open_page", page="customer_service", payload={ "title": "呼叫客服", "mode": "call_service" } ) ``` **示例消息**: ```json { "msg_id": "agent_1747734123004", "source": "agent", "target": "screen", "module": "customer_service", "action": "open_page", "page": "customer_service", "payload": { "title": "呼叫客服", "mode": "call_service" }, "timestamp": 1747734123 } ``` --- ### 5.6 open_face_recognition_page - 人脸识别页面 **功能**:唤醒人脸识别页面并启动识别。此函数发送两条 MQTT 消息。 **调用方式**: ```python # 第一条 - 打开页面 self.mqtt_client.publish_command( target="screen", module="face", action="open_page", page="face_recognition", payload={ "title": "人脸识别", "tips": "请面向摄像头", "mode": "whitelist" } ) # 第二条 - 启动识别 self.mqtt_client.publish_command( target="face", module="face", action="start", page="", payload={ "mode": "whitelist", "timeout_ms": 10000, "threshold": 0.65 } ) ``` **示例消息 1(打开页面)**: ```json { "msg_id": "agent_1747734123005", "source": "agent", "target": "screen", "module": "face", "action": "open_page", "page": "face_recognition", "payload": { "title": "人脸识别", "tips": "请面向摄像头", "mode": "whitelist" }, "timestamp": 1747734123 } ``` **示例消息 2(启动识别)**: ```json { "msg_id": "agent_1747734123006", "source": "agent", "target": "face", "module": "face", "action": "start", "page": "", "payload": { "mode": "whitelist", "timeout_ms": 10000, "threshold": 0.65 }, "timestamp": 1747734123 } ``` --- ## 6. 订阅消息处理 ### 6.1 状态消息 (status) 订阅 `/ai/module/status` 接收外部模块的状态更新。 **回调注册**: ```python mqtt_client.on_status_callback = self.on_status_received def on_status_received(self, data): # 处理状态数据 pass ``` ### 6.2 事件消息 (event) 订阅 `/ai/module/event` 接收外部模块的事件通知(如人脸识别结果)。 **回调注册**: ```python mqtt_client.on_event_callback = self.on_event_received def on_event_received(self, data): # 处理事件数据 pass ``` --- ## 7. MQTT 配置格式 MQTT 配置来自 `/ai/config` 中的 `mqtt` 字段: ```json { "mqtt": { "enable": true, "broker_host": "192.168.0.30", "broker_port": 1883, "username": "", "password": "", "client_id": "rdk_agent", "keepalive": 60, "command_topic": "/ai/agent/command", "status_topic": "/ai/module/status", "event_topic": "/ai/module/event" } } ``` ### 7.1 配置参数说明 | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `enable` | bool | `false` | 是否启用 MQTT | | `broker_host` | string | `"127.0.0.1"` | MQTT Broker 地址 | | `broker_port` | int | `1883` | MQTT Broker 端口 | | `username` | string | `""` | 用户名(可选) | | `password` | string | `""` | 密码(可选) | | `client_id` | string | `"rdk_agent"` | 客户端唯一标识 | | `keepalive` | int | `60` | 保活时间(秒) | | `command_topic` | string | `/ai/agent/command` | 命令发布话题 | | `status_topic` | string | `/ai/module/status` | 状态订阅话题 | | `event_topic` | string | `/ai/module/event` | 事件订阅话题 | --- ## 8. 使用示例 ### 8.1 MQTT 客户端初始化 ```python from utils.mqttclient import MQTTClient # 创建 MQTT 客户端 self.mqtt_client = MQTTClient(logger=self.get_logger()) # 从配置初始化 mqtt_config = { "enable": True, "broker_host": "192.168.0.30", "broker_port": 1883, "client_id": "rdk_agent" } self.mqtt_client.init(mqtt_config) # 注册回调 self.mqtt_client.on_status_callback = self.on_status_received self.mqtt_client.on_event_callback = self.on_event_received ``` ### 8.2 发送命令 ```python # 使用 publish_command 发送命令 ok = self.mqtt_client.publish_command( target="screen", module="nav", action="open_page", page="navigation", payload={ "title": "导航服务", "mode": "select_destination" } ) if ok: self.get_logger().info("命令发送成功") else: self.get_logger().warn("命令发送失败") ``` ### 8.3 扩展新的 MQTT 业务函数 在 `CustomActionServer` 类中新增成员函数即可被大模型调用(通过 `hasattr` 判断)。 ```python def open_xxx_page(self): """ 打开XXX页面 """ try: ok = self.mqtt_client.publish_command( target="screen", module="xxx", action="open_page", page="xxx_page", payload={ "title": "XXX", "mode": "xxx" } ) self.get_logger().info( f"[MQTT业务] open_xxx_page sent, ok={ok}" ) except Exception as e: self.get_logger().warn( f"[MQTT业务] open_xxx_page failed: {e}" ) ``` --- ## 9. 注意事项 1. **MQTT 初始化时机**:MQTT 客户端在收到 `/ai/config` 配置后初始化,仅初始化一次,后续配置更新不会重新初始化。 2. **发布失败不影响主流程**:所有业务函数内部已做异常捕获,MQTT 发布失败只会打印 warning 日志,不影响原有 ROS2 逻辑。 3. **日志前缀**:所有 MQTT 业务日志使用 `[MQTT业务]` 前缀,方便排查。 4. **唤醒时自动暂停**:`wakeup_callback` 收到唤醒信号后会自动调用 `global_pause("wakeup")`,通知全车暂停。 --- ## 10. 更新日志 | 日期 | 版本 | 更新内容 | |------|------|---------| | 2026-05-20 | 1.0 | 初始版本,支持 MQTT 客户端模块及基础业务函数 |