Ver Fonte

新增环境信息,电量信息

hwt há 2 semanas atrás
pai
commit
1e048321fb

+ 281 - 0
brain/PlannerNode2/README.md

@@ -0,0 +1,281 @@
+# PlannerNode2 机器人决策系统
+
+机器人智能决策系统,基于 ROS2 构建,包含配置管理、环境感知、导航模拟和大模型服务等核心节点。
+
+---
+
+## 目录结构
+
+```
+PlannerNode2/
+├── config_node/          # 配置管理节点
+├── environment_node/     # 环境感知节点
+├── nav_simulator/        # 导航模拟节点
+├── largemodel/           # 大模型服务节点
+├── README.md             # 本文档
+```
+
+---
+
+## 节点概述
+
+### 1. config_node (配置管理节点)
+
+**功能说明**
+
+- 从 MySQL 数据库读取配置(当前版本使用模拟数据)
+- 定时刷新配置并发布到 `/ai/config` topic
+- 支持 YAML 文件作为 fallback 配置
+
+**发布话题**
+
+| 话题名称 | 类型 | 说明 |
+|---------|------|------|
+| `/ai/config` | `std_msgs/String` | 配置数据 (JSON 格式) |
+
+**配置内容**
+
+- ASR 语音识别配置
+- Action Service 动作服务配置
+- Model Service 模型服务配置
+- 大模型接口配置(阿里百炼、百度 TTS 等)
+- Topic 配置
+- Environment 节点配置
+
+**启动方式**
+
+```bash
+ros2 launch config_node config_node.launch.py
+```
+
+**参数说明**
+
+| 参数名 | 类型 | 默认值 | 说明 |
+|-------|------|--------|------|
+| `config_file` | string | `config/database.yaml` | 数据库配置文件路径 |
+| `refresh_interval` | double | `1.0` | 配置刷新间隔 (秒) |
+| `use_mock_data` | bool | `True` | 是否使用模拟数据 |
+| `use_yaml_fallback` | bool | `True` | 是否使用 YAML fallback |
+| `topic_name` | string | `/ai/config` | 配置发布话题 |
+
+---
+
+### 2. environment_node (环境感知节点)
+
+**功能说明**
+
+- 订阅 `config_node` 获取配置
+- 统一发布机器人环境相关数据
+- 支持电池、温度、天气、地图导航点等数据
+- 使用模拟数据进行测试
+
+**订阅话题**
+
+| 话题名称 | 类型 | 说明 |
+|---------|------|------|
+| `/ai/config` | `std_msgs/String` | 配置数据 (来自 config_node) |
+
+**发布话题**
+
+| 话题名称 | 类型 | 说明 |
+|---------|------|------|
+| `/ai/env` | `std_msgs/String` | 环境数据 (JSON 格式) |
+
+**环境数据结构**
+
+```json
+{
+  "timestamp": "2026-05-12T15:02:26",
+  "battery": {
+    "level": 85,
+    "voltage": 12.6,
+    "is_charging": false,
+    "capacity_wh": 5000,
+    "current_ma": -500
+  },
+  "temperature": {
+    "indoor": 25.5,
+    "outdoor": 28.0,
+    "unit": "celsius",
+    "humidity": 60
+  },
+  "weather": {
+    "condition": "sunny",
+    "description": "晴",
+    "temperature": 28,
+    "humidity": 65,
+    "wind_speed": 3.5
+  },
+  "map": {
+    "points": [
+      {"id": "A", "name": "办公室", "position": {"x": 1.633, "y": 3.490, "z": 0.0}},
+      {"id": "B", "name": "酒店大堂", "position": {"x": 2.436, "y": -0.574, "z": 0.0}},
+      {"id": "C", "name": "园区", "position": {"x": 0.024, "y": -1.820, "z": 0.0}}
+    ]
+  }
+}
+```
+
+**启动方式**
+
+```bash
+ros2 launch environment_node environment.launch.py
+```
+
+**参数说明**
+
+| 参数名 | 类型 | 默认值 | 说明 |
+|-------|------|--------|------|
+| `config_topic` | string | `/ai/config` | 配置订阅话题 |
+| `environment_topic` | string | `/ai/env` | 环境发布话题 |
+| `use_mock_data` | bool | `True` | 是否使用模拟数据 |
+
+---
+
+### 3. nav_simulator (导航模拟节点)
+
+**功能说明**
+
+- 模拟 TF 变换 (map → base_footprint)
+- 提供 NavigateToPose Action Server
+- 模拟机器人移动过程
+- 加载 `map_mapping.yaml` 中的导航点配置
+- 用于在没有真实机器人/定位系统时测试导航功能
+
+**发布话题**
+
+| 话题名称 | 类型 | 说明 |
+|---------|------|------|
+| `/tf` | `tf2_msgs/TFMessage` | TF 变换 |
+
+**服务/动作**
+
+| 名称 | 类型 | 说明 |
+|------|------|------|
+| `/navigate_to_pose` | `nav2_msgs/NavigateToPose` | 导航到目标点 |
+
+**动作请求格式**
+
+使用 `geometry_msgs/PoseStamped` 指定目标位置和朝向。
+
+**启动方式**
+
+```bash
+ros2 launch nav_simulator nav_simulator.launch.py
+```
+
+**参数说明**
+
+| 参数名 | 类型 | 默认值 | 说明 |
+|-------|------|--------|------|
+| `map_mapping_file` | string | `largemodel/config/map_mapping.yaml` | 地图导航点配置文件 |
+| `initial_x` | double | `0.0` | 初始 X 坐标 |
+| `initial_y` | double | `0.0` | 初始 Y 坐标 |
+| `initial_z` | double | `0.0` | 初始 Z 坐标 |
+| `initial_yaw` | double | `0.0` | 初始朝向角 (弧度) |
+| `move_speed` | double | `0.5` | 移动速度 (m/s) |
+| `tf_publish_rate` | double | `10.0` | TF 发布频率 (Hz) |
+| `simulate_move` | bool | `True` | 是否模拟移动过程 |
+
+**地图配置文件格式**
+
+```yaml
+A:
+  position:
+    x: 1.633
+    y: 3.490
+    z: 0.0
+  orientation:
+    yaw: 0.0
+
+B:
+  position:
+    x: 2.436
+    y: -0.574
+    z: 0.0
+  orientation:
+    yaw: 1.57
+```
+
+---
+
+### 4. largemodel (大模型服务节点)
+
+**功能说明**
+
+- 对接大模型 API(阿里百炼等)
+- 订阅 ASR 语音识别结果
+- 发布动作指令
+- 支持对话聊天和动作任务执行
+
+**相关文档**
+
+详见 `largemodel/README.md`
+
+---
+
+## 快速启动
+
+### 一键启动所有节点
+
+```bash
+# 启动 config_node
+ros2 launch config_node config_node.launch.py
+
+# 启动 environment_node
+ros2 launch environment_node environment.launch.py
+
+# 启动 nav_simulator
+ros2 launch nav_simulator nav_simulator.launch.py
+
+# 启动 largemodel
+ros2 launch largemodel largemodel_control.launch.py 
+```
+
+### 测试环境数据发布
+
+```bash
+# 查看发布的环境数据
+ros2 topic echo /ai/env
+```
+
+### 测试配置发布
+
+```bash
+# 查看发布的配置
+ros2 topic echo /ai/config
+```
+
+### 测试导航模拟
+
+```bash
+# 使用命令行发送导航目标
+ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{pose: {header: {frame_id: 'map'}, pose: {position: {x: 1.633, y: 3.490, z: 0.0}, orientation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}}}}"
+```
+
+---
+
+## 依赖说明
+
+- ROS2 (Humble 或更高版本)
+- Python 3.8+
+- rclpy
+- std_msgs
+- nav2_msgs
+- geometry_msgs
+- tf2_ros
+- ament_index_python
+
+---
+
+## 作者
+
+sunrise
+
+---
+
+## 更新日志
+
+| 日期 | 版本 | 更新内容 |
+|------|------|---------|
+| 2026-05-12 | 1.0.0 | 初始版本,包含 config_node、environment_node、nav_simulator |

+ 4 - 1
brain/PlannerNode2/largemodel/largemodel/model_service.py

@@ -7,7 +7,7 @@ from std_msgs.msg import String
 from utils import large_model_interface
 from rclpy.action import ActionClient
 from ament_index_python.packages import get_package_share_directory
-from utils.promot import get_prompt, get_map_mapping, set_map_mapping, set_large_model_config, set_model_paths, set_system_config
+from utils.promot import get_prompt, get_map_mapping, set_map_mapping, set_large_model_config, set_model_paths, set_system_config, set_environment_data
 import time
 import re
 import functools
@@ -235,6 +235,9 @@ class LargeModelService(Node):
             env_json = json.loads(msg.data)
             self.environment_data = env_json
 
+            # 更新环境数据缓存(供提示词使用)
+            set_environment_data(env_json)
+
             # 更新地图映射数据
             map_data = env_json.get('map', {})
             if map_data:

+ 70 - 2
brain/PlannerNode2/largemodel/utils/promot.py

@@ -7,6 +7,7 @@ _map_mapping_cache = ""  # 地图映射缓存
 _large_model_config_cache = {}  # 大模型配置缓存
 _model_paths_cache = {}  # 模型路径缓存
 _system_config_cache = {}  # 系统配置缓存
+_environment_data_cache = {}  # 环境数据缓存(电池、温度、天气)
 
 def set_map_mapping(data):
     """
@@ -45,6 +46,72 @@ def set_system_config(config):
     global _system_config_cache
     _system_config_cache = config
 
+def set_environment_data(data):
+    """
+    设置环境数据缓存(电池、温度、天气)
+    """
+    global _environment_data_cache
+    _environment_data_cache = data
+
+def get_environment_data():
+    """
+    获取环境数据缓存
+    """
+    return _environment_data_cache
+
+def _format_environment_info():
+    """
+    将环境数据格式化为中文文字描述
+    """
+    if not _environment_data_cache:
+        return "# 环境感知\n\n(暂无环境数据)\n"
+
+    env = _environment_data_cache
+
+    info = "# 环境感知\n\n"
+
+    # 电池信息
+    battery = env.get('battery', {})
+    if battery:
+        level = battery.get('level', 0)
+        voltage = battery.get('voltage', 0)
+        is_charging = battery.get('is_charging', False)
+        charging_status = "充电中" if is_charging else "未充电"
+
+        info += "## 机器人状态\n"
+        info += f"- 电量:{level}%\n"
+        info += f"- 电压:{voltage}V\n"
+        info += f"- 充电状态:{charging_status}\n"
+
+    # 温度信息
+    temperature = env.get('temperature', {})
+    if temperature:
+        indoor = temperature.get('indoor', 0)
+        humidity = temperature.get('humidity', 0)
+        if battery:  # 如果有电池信息,追加到机器人状态
+            info += f"- 室内温度:{indoor}°C\n"
+            info += f"- 室内湿度:{humidity}%\n"
+        else:
+            info += "## 环境温度\n"
+            info += f"- 室内温度:{indoor}°C\n"
+            info += f"- 室内湿度:{humidity}%\n"
+
+    # 天气信息
+    weather = env.get('weather', {})
+    if weather:
+        description = weather.get('description', '未知')
+        temp = weather.get('temperature', 0)
+        weather_humidity = weather.get('humidity', 0)
+        wind_speed = weather.get('wind_speed', 0)
+
+        info += "## 天气情况\n"
+        info += f"- 天气:{description}\n"
+        info += f"- 温度:{temp}°C\n"
+        info += f"- 湿度:{weather_humidity}%\n"
+        info += f"- 风速:{wind_speed}m/s\n"
+
+    return info
+
 def get_large_model_config():
     """
     获取大模型配置
@@ -175,9 +242,10 @@ def get_prompt():
   '''
   获取拼接后的prompt提示语
   '''
-  # 从缓存获取地图映射
+  # 从缓存获取环境信息和地图映射
+  environment_info = _format_environment_info()
   map_mapping = _map_mapping_cache if _map_mapping_cache else "#地图映射\n\n(暂无地图数据)\n"
-  return default_prompt+action_function_library+map_mapping+sample_library
+  return default_prompt+action_function_library+environment_info+map_mapping+sample_library
 
 def get_map_mapping():
   '''