iflow-mcp_xrds76354_sumo-mcp 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/METADATA +402 -0
- iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/RECORD +27 -0
- iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/WHEEL +4 -0
- iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/entry_points.txt +2 -0
- iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/licenses/LICENSE +21 -0
- mcp_tools/__init__.py +0 -0
- mcp_tools/analysis.py +33 -0
- mcp_tools/network.py +94 -0
- mcp_tools/py.typed +0 -0
- mcp_tools/rl.py +425 -0
- mcp_tools/route.py +91 -0
- mcp_tools/signal.py +96 -0
- mcp_tools/simulation.py +79 -0
- mcp_tools/vehicle.py +52 -0
- resources/__init__.py +0 -0
- server.py +493 -0
- utils/__init__.py +0 -0
- utils/connection.py +145 -0
- utils/output.py +26 -0
- utils/sumo.py +185 -0
- utils/timeout.py +364 -0
- utils/traci.py +82 -0
- workflows/__init__.py +0 -0
- workflows/py.typed +0 -0
- workflows/rl_train.py +34 -0
- workflows/signal_opt.py +210 -0
- workflows/sim_gen.py +70 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iflow-mcp_xrds76354_sumo-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: SUMO-MCP: Autonomous Traffic Simulation Platform with Model Context Protocol
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: mcp[cli]>=1.0.0
|
|
8
|
+
Requires-Dist: pandas>=2.0.0
|
|
9
|
+
Requires-Dist: requests>=2.31.0
|
|
10
|
+
Requires-Dist: sumo-rl>=1.4.3
|
|
11
|
+
Requires-Dist: sumolib>=1.20.0
|
|
12
|
+
Requires-Dist: traci>=1.20.0
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: flake8>=7.0.0; extra == 'dev'
|
|
15
|
+
Requires-Dist: mypy>=1.8.0; extra == 'dev'
|
|
16
|
+
Requires-Dist: pandas-stubs>=2.0.0; extra == 'dev'
|
|
17
|
+
Requires-Dist: psutil>=5.9.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
19
|
+
Requires-Dist: types-requests>=2.31.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: types-setuptools>=69.0.0; extra == 'dev'
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# SUMO-MCP: 智能交通仿真与控制的 MCP 平台
|
|
24
|
+
|
|
25
|
+
<div align="center">
|
|
26
|
+
<img src="doc/sumo-mcp.jpg" alt="SUMO-MCP Logo" width="200" />
|
|
27
|
+
<br />
|
|
28
|
+
<br />
|
|
29
|
+
<p align="center">
|
|
30
|
+
<a href="https://github.com/XRDS76354/SUMO-MCP-Server"><img src="https://img.shields.io/badge/Status-Active-success" alt="Status" /></a>
|
|
31
|
+
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/Python-3.10+-blue" alt="Python" /></a>
|
|
32
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green" alt="License" /></a>
|
|
33
|
+
<a href="https://deepwiki.com/XRDS76354/SUMO-MCP-Server"><img src="https://deepwiki.com/badge.svg" alt="DeepWiki" /></a>
|
|
34
|
+
<a href="https://github.com/XRDS76354/SUMO-MCP-Server"><img src="https://img.shields.io/github/last-commit/XRDS76354/SUMO-MCP-Server" alt="Last Commit" /></a>
|
|
35
|
+
<a href="doc/API.md"><img src="https://img.shields.io/badge/API-Docs-blue" alt="API Docs" /></a>
|
|
36
|
+
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey" alt="Platform" />
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
SUMO-MCP 是一个连接大语言模型 (LLM) 与 [Eclipse SUMO](https://www.eclipse.org/sumo/) 交通仿真的中间件。通过 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/),它允许 AI 智能体(如 Claude, Cursor, TRAE等)直接调用 SUMO 的核心功能,实现从**OpenStreetMap 数据获取**、**路网生成**、**需求建模**到**仿真运行**与**信号优化**的全流程自动化。
|
|
41
|
+
|
|
42
|
+
系统支持**离线仿真**(基于文件的工作流)和**在线交互**(实时 TraCI 控制)两种模式,满足从宏观规划到微观控制的多样化需求。
|
|
43
|
+
|
|
44
|
+
API 参考见 `doc/API.md`(唯一真相源以 `src/server.py` 的工具注册为准)。
|
|
45
|
+
|
|
46
|
+
## 🚀 核心功能特性
|
|
47
|
+
|
|
48
|
+
### 1. 全面的工具链集成
|
|
49
|
+
聚合符合直觉的核心 MCP 接口,简化 SUMO 复杂操作:
|
|
50
|
+
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
* **路网管理 (`manage_network`)**: 支持路网生成 (`generate`)、OSM 地图下载 (`download_osm`) 与格式转换 (`convert`)。
|
|
54
|
+
* **需求管理 (`manage_demand`)**: 提供随机行程生成 (`generate_random`)、OD 矩阵转换 (`convert_od`) 和路径计算 (`compute_routes`)。
|
|
55
|
+
* **信号优化 (`optimize_traffic_signals`)**: 集成周期自适应 (`cycle_adaptation`) 和绿波协调 (`coordination`) 算法;其中 `cycle_adaptation` 输出为 SUMO `<additional>` 信号方案文件(由工作流自动挂载到 `<additional-files>`)。
|
|
56
|
+
* **仿真与分析**: 支持标准配置文件仿真 (`run_simple_simulation`) 与 FCD 轨迹数据分析 (`run_analysis`)。
|
|
57
|
+
|
|
58
|
+
部分聚合工具支持在 `params` 中传入 `options: list[str]`,用于将额外参数按 token 透传到底层 SUMO 二进制/脚本(详见 `doc/API.md` 的“通用约定”)。
|
|
59
|
+
|
|
60
|
+
### 2. 在线实时交互 (Online Interaction)
|
|
61
|
+
支持通过 TraCI 协议与运行中的仿真实例进行实时交互,赋予 LLM 微观控制与感知能力:
|
|
62
|
+
|
|
63
|
+
* **仿真控制 (`control_simulation`)**: 提供启动连接 (`connect`)、单步推演 (`step`) 和安全断开 (`disconnect`)。
|
|
64
|
+
* **状态查询 (`query_simulation_state`)**: 实时获取车辆列表 (`vehicle_list`)、车辆细节变量 (`vehicle_variable`) 及全局仿真统计。
|
|
65
|
+
|
|
66
|
+
### 3. 自动化智能工作流
|
|
67
|
+
内置端到端的自动化工作流 (`run_workflow`),简化复杂科研与工程任务:
|
|
68
|
+
|
|
69
|
+
* **Sim Gen & Eval (`sim_gen_eval`)**: 一键执行 "生成路网 -> 生成需求 -> 路径计算 -> 仿真运行 -> 结果分析" 的完整闭环。
|
|
70
|
+
- 参数:`grid_number`(别名:`grid_size`,`size`), `sim_seconds`(别名:`steps`,`duration`,`end_time`), `output_dir`
|
|
71
|
+
* **Signal Optimization (`signal_opt`)**: 自动执行 "基线仿真 -> 信号优化 -> 优化仿真 -> 效果对比" 的全流程,并自动处理优化工具输出的 `<additional>` 文件挂载。
|
|
72
|
+
- 参数:`net_file`(必填), `route_file`(必填), `sim_seconds`(别名:`steps`,`duration`), `use_coordinator`, `output_dir`
|
|
73
|
+
* **RL Training (`rl_train`)**: 针对内置场景的强化学习训练;自定义路网训练使用 `manage_rl_task/train_custom`(底层基于开源项目 [sumo-rl](https://github.com/LucasAlegre/sumo-rl);要求路网包含信号灯,且运行建议显式设置 `SUMO_HOME`)。
|
|
74
|
+
- 参数:`scenario_name`(别名:`scenario`), `episodes`(别名:`num_episodes`), `steps`(别名:`steps_per_episode`), `output_dir`
|
|
75
|
+
|
|
76
|
+
> 💡 **提示**: 关于各工具的详细参数说明与调用示例,请参考 [API 详细文档](doc/API.md)。
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 🛠️ 环境要求
|
|
81
|
+
|
|
82
|
+
* **操作系统**: Windows / Linux / macOS
|
|
83
|
+
* **Python**: 3.10+ (强制要求,以支持最新的类型系统与 MCP SDK)
|
|
84
|
+
* **SUMO**: [Eclipse SUMO](https://www.eclipse.org/sumo/)(需配置 `SUMO_HOME` 环境变量,并确保其二进制目录在 `PATH` 中)
|
|
85
|
+
|
|
86
|
+
### Python 依赖
|
|
87
|
+
|
|
88
|
+
**运行时依赖**(安装后即可使用所有 MCP 工具):
|
|
89
|
+
- `mcp[cli]>=1.0.0` - 官方 Model Context Protocol SDK
|
|
90
|
+
- `sumolib>=1.20.0` - SUMO Python 库(路网操作、二进制调用)
|
|
91
|
+
- `traci>=1.20.0` - Traffic Control Interface(在线实时控制)
|
|
92
|
+
- `sumo-rl>=1.4.3` - SUMO 强化学习环境(RL 训练功能)
|
|
93
|
+
- `pandas>=2.0.0` - 数据分析(FCD 轨迹处理)
|
|
94
|
+
- `requests>=2.31.0` - HTTP 请求(OSM 数据下载)
|
|
95
|
+
|
|
96
|
+
**开发依赖**(可选,用于测试和代码质量检查):
|
|
97
|
+
- `mypy>=1.8.0` - 静态类型检查
|
|
98
|
+
- `flake8>=7.0.0` - 代码风格检查
|
|
99
|
+
- `pytest>=8.0.0` - 单元测试框架
|
|
100
|
+
- `psutil>=5.9.0` - 系统资源监控(性能测试)
|
|
101
|
+
- `types-*` - 类型存根包(mypy 支持)
|
|
102
|
+
|
|
103
|
+
使用 `.\install_deps.ps1 -NoDev` 可以跳过开发依赖的安装。
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 📦 安装指南
|
|
108
|
+
|
|
109
|
+
### 1. 获取代码
|
|
110
|
+
|
|
111
|
+
您可以通过以下方式获取项目:
|
|
112
|
+
|
|
113
|
+
**方式 A:通过 Git 克隆 (推荐)**
|
|
114
|
+
```bash
|
|
115
|
+
git clone https://github.com/XRDS76354/SUMO-MCP-Server.git
|
|
116
|
+
cd sumo-mcp
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**方式 B:下载压缩包**
|
|
120
|
+
1. 访问 [GitHub 项目主页](https://github.com/XRDS76354/SUMO-MCP-Server)。
|
|
121
|
+
2. 点击 **Code** 按钮,选择 **Download ZIP**。
|
|
122
|
+
3. 解压并进入项目目录。
|
|
123
|
+
|
|
124
|
+
**方式 C:作为依赖安装 (WIP)**
|
|
125
|
+
如果您想在其他项目中使用,可以尝试:
|
|
126
|
+
```bash
|
|
127
|
+
pip install git+https://github.com/XRDS76354/SUMO-MCP-Server.git
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 2. 安装与配置 SUMO
|
|
131
|
+
|
|
132
|
+
本系统依赖于 [Eclipse SUMO](https://www.eclipse.org/sumo/) 仿真引擎。
|
|
133
|
+
|
|
134
|
+
#### 重要提示 (Important Notes)
|
|
135
|
+
* **仅使用 SUMO 二进制工具**(`sumo` / `netconvert` / `netgenerate` / `duarouter` / `od2trips` 等):保证命令在 `PATH` 中即可。
|
|
136
|
+
* **使用 SUMO tools 脚本**(`randomTrips.py` / `osmGet.py` / `tls*.py` 等):需要能定位到 `<SUMO_HOME>/tools`,推荐设置 `SUMO_HOME` 指向 SUMO 安装目录,并把 `$SUMO_HOME/bin` 加入 `PATH`。
|
|
137
|
+
|
|
138
|
+
#### 各平台安装步骤
|
|
139
|
+
* **Windows**:
|
|
140
|
+
1. 安装 SUMO:使用官方安装包(文档:https://sumo.dlr.de/)。
|
|
141
|
+
2. 设置环境变量(示例):
|
|
142
|
+
- CMD:`setx SUMO_HOME "C:\Program Files\Eclipse\sumo"`,`setx PATH "%SUMO_HOME%\bin;%PATH%"`
|
|
143
|
+
- PowerShell:`$env:SUMO_HOME="C:\Program Files\Eclipse\sumo"; $env:PATH="$env:SUMO_HOME\bin;$env:PATH"`
|
|
144
|
+
3. 验证:`sumo --version`
|
|
145
|
+
* **Linux (Ubuntu/Debian)**:
|
|
146
|
+
1. 安装:`sudo apt-get install sumo sumo-tools`
|
|
147
|
+
2. 可选(使用 tools 脚本时推荐):`export SUMO_HOME=/usr/share/sumo` 并把 `$SUMO_HOME/bin` 加入 `PATH`
|
|
148
|
+
3. 验证:`sumo --version`
|
|
149
|
+
* **macOS (Homebrew)**:
|
|
150
|
+
1. 安装:`brew install sumo`
|
|
151
|
+
2. Homebrew 通常会自动把 `sumo` 加到 `PATH`;如需 tools 脚本,可设置 `SUMO_HOME` 指向 `.../share/sumo`(例如 `/usr/local/share/sumo` 或 `/opt/homebrew/share/sumo`)
|
|
152
|
+
3. 验证:`sumo --version`
|
|
153
|
+
|
|
154
|
+
> � **更多说明**: 更多关于 SUMO 安装与配置的详细信息,请参考 [SUMO 官方文档](https://sumo.dlr.de/docs/)。
|
|
155
|
+
|
|
156
|
+
### 3. Python 环境配置
|
|
157
|
+
|
|
158
|
+
#### Windows 一键安装
|
|
159
|
+
|
|
160
|
+
在 Windows 上可以直接使用仓库自带脚本创建 `.venv` 并安装依赖(默认包含开发依赖 `.[dev]`)。
|
|
161
|
+
|
|
162
|
+
**方式 A:PowerShell(推荐)**
|
|
163
|
+
|
|
164
|
+
```powershell
|
|
165
|
+
.\install_deps.ps1
|
|
166
|
+
|
|
167
|
+
# 可选参数:
|
|
168
|
+
.\install_deps.ps1 -NoDev # 仅安装运行依赖
|
|
169
|
+
.\install_deps.ps1 -IndexUrl https://pypi.tuna.tsinghua.edu.cn/simple # 使用国内镜像
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**方式 B:CMD(命令提示符)**
|
|
173
|
+
```bat
|
|
174
|
+
install_deps.bat
|
|
175
|
+
|
|
176
|
+
REM 可选参数:
|
|
177
|
+
install_deps.bat -NoDev
|
|
178
|
+
install_deps.bat -IndexUrl https://pypi.tuna.tsinghua.edu.cn/simple
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
脚本会自动:
|
|
182
|
+
- 检测并验证 Python 3.10+ 版本
|
|
183
|
+
- 创建虚拟环境 `.venv`(如不存在)
|
|
184
|
+
- 升级 pip/setuptools/wheel
|
|
185
|
+
- 安装项目依赖(editable mode)
|
|
186
|
+
|
|
187
|
+
您可以选择以下任一方式手动配置开发环境。
|
|
188
|
+
|
|
189
|
+
#### 方式1:使用 uv (推荐 - 极速)
|
|
190
|
+
|
|
191
|
+
[uv](https://github.com/astral-sh/uv) 是目前最快的 Python 包管理工具,支持一键同步依赖。
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# 1. 安装 uv (如果尚未安装)
|
|
195
|
+
pip install uv
|
|
196
|
+
|
|
197
|
+
# 2. 同步项目环境 (自动创建虚拟环境并安装依赖)
|
|
198
|
+
uv sync
|
|
199
|
+
|
|
200
|
+
# 3. 激活环境
|
|
201
|
+
# Windows:
|
|
202
|
+
.venv\Scripts\activate
|
|
203
|
+
# Linux/macOS:
|
|
204
|
+
source .venv/bin/activate
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### 方式2:使用 Conda + Pip
|
|
208
|
+
|
|
209
|
+
如果您习惯使用 Conda 管理环境,可以按照以下步骤操作:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# 1. 创建并激活 Conda 环境
|
|
213
|
+
conda create -n sumo-mcp python=3.10 -y
|
|
214
|
+
conda activate sumo-mcp
|
|
215
|
+
|
|
216
|
+
# 2. 安装项目依赖
|
|
217
|
+
# 推荐国内用户使用镜像源加速,一键安装项目及开发工具
|
|
218
|
+
pip install -e ".[dev]" -i https://pypi.tuna.tsinghua.edu.cn/simple
|
|
219
|
+
|
|
220
|
+
# 或者仅安装基础依赖
|
|
221
|
+
pip install -r requirements.txt
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 🚦 启动与配置
|
|
227
|
+
|
|
228
|
+
### 1. 本地直接启动 (用于测试)
|
|
229
|
+
|
|
230
|
+
服务器基于官方 `mcp.server.fastmcp.FastMCP` 实现,通过标准输入输出 (stdio) 传输 JSON-RPC 2.0 消息。
|
|
231
|
+
|
|
232
|
+
使用 Python 直接启动 MCP 服务器:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
python src/server.py
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
或者使用仓库自带的启动脚本(会自动处理环境检测与 `PATH` 挂载):
|
|
239
|
+
|
|
240
|
+
* **Linux/macOS**: `./start_server.sh`
|
|
241
|
+
* **Windows (PowerShell)**: `.\start_server.ps1`
|
|
242
|
+
* **Windows (CMD)**: `start_server.bat`
|
|
243
|
+
|
|
244
|
+
### 2. MCP 服务配置 (关键 - 用于 AI 宿主)
|
|
245
|
+
|
|
246
|
+
配置 MCP 服务器到宿主应用(如 Claude Desktop, Trae, Cursor)时,**必须使用绝对路径**。
|
|
247
|
+
|
|
248
|
+
#### A. 查找必要路径
|
|
249
|
+
在终端中激活您的环境后,运行以下命令:
|
|
250
|
+
|
|
251
|
+
* **Python 绝对路径**:
|
|
252
|
+
- Windows (PS): `(Get-Command python).Source`
|
|
253
|
+
- Linux/macOS: `which python`
|
|
254
|
+
* **SUMO_HOME 路径**:
|
|
255
|
+
- Windows: `echo %SUMO_HOME%`
|
|
256
|
+
- Linux/macOS: `echo $SUMO_HOME`
|
|
257
|
+
|
|
258
|
+
#### B. 宿主应用配置示例
|
|
259
|
+
将以下 JSON 添加到宿主应用的配置文件中(例如 Claude Desktop 的 `claude_desktop_config.json`):
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
{
|
|
263
|
+
"mcpServers": {
|
|
264
|
+
"sumo-mcp": {
|
|
265
|
+
"command": "/path/to/your/env/python",
|
|
266
|
+
"args": ["/path/to/sumo-mcp/src/server.py"],
|
|
267
|
+
"env": {
|
|
268
|
+
"SUMO_HOME": "/your/actual/sumo/path",
|
|
269
|
+
"PYTHONPATH": "/path/to/sumo-mcp/src"
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
> **⚠️ 重要提示**:
|
|
277
|
+
> 1. `command`: 必须替换为您找到的 **Python 解释器绝对路径**。
|
|
278
|
+
> 2. `args`: 必须替换为项目 `src/server.py` 的 **绝对路径**。
|
|
279
|
+
> 3. `env`: 显式设置 `SUMO_HOME` 和 `PYTHONPATH` 可以有效避免 `ModuleNotFoundError` 或环境识别错误。
|
|
280
|
+
|
|
281
|
+
工具清单与参数约定请以 `src/server.py` 或 `doc/API.md` 为准。
|
|
282
|
+
|
|
283
|
+
更多配置示例见 `mcp_config_examples.json`。
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## 💡 使用示例 (Prompt)
|
|
288
|
+
|
|
289
|
+
在配置了 MCP 的 AI 助手中,您可以尝试以下自然语言指令:
|
|
290
|
+
|
|
291
|
+
* **工作流任务**:
|
|
292
|
+
|
|
293
|
+
> "生成一个 3x3 的网格路网,模拟 100 秒的交通流,并告诉我平均车速。"
|
|
294
|
+
> *(AI 将调用 `run_workflow("sim_gen_eval", {"grid_number": 3, "sim_seconds": 100})`)*
|
|
295
|
+
|
|
296
|
+
* **在线交互任务**:
|
|
297
|
+
> "启动这个配置文件的仿真,每运行一步就告诉我 ID 为 'v_0' 的车辆速度,如果速度低于 5m/s 就提醒我。"
|
|
298
|
+
> *(AI 将调用 `control_simulation` 和 `query_simulation_state`)*
|
|
299
|
+
* **强化学习任务**:
|
|
300
|
+
|
|
301
|
+
> "列出所有内置的强化学习场景,然后选择一个简单的路口场景训练 5 个回合。"
|
|
302
|
+
> *(AI 将调用 `manage_rl_task("list_scenarios")` 和 `run_workflow("rl_train", {"scenario_name": "...", "episodes": 5})`)*
|
|
303
|
+
- **复杂综合场景示例 (推荐测试)**:
|
|
304
|
+
|
|
305
|
+
> "使用工具中的sumo-mcp完成下面操作:生成一个4x4的网格路网,要求所有节点均为交叉路口,设置网格间距为100米(默认值)确保所有交叉口都配置交通信号灯,设置车辆总数为200辆,运行进行1000秒的交通仿真,启用车辆轨迹记录功能,提取所有车辆的速度数据计算整个仿真期间所有车辆的平均速度,结果精确到小数点后两位。"
|
|
306
|
+
>
|
|
307
|
+
> **AI 内部执行逻辑**:
|
|
308
|
+
>
|
|
309
|
+
> 1. 调用 `manage_network(action="generate", output_file="grid.net.xml", params={"grid": true, "grid_number": 4})`
|
|
310
|
+
> 2. 调用 `manage_demand(action="random_trips", net_file="grid.net.xml", output_file="trips.xml", params={"end_time": 1000, "period": 5.0})` (计算: 1000s / 200辆 = 每5秒一辆)
|
|
311
|
+
> 3. 调用 `run_workflow("sim_gen_eval", {"grid_number": 4, "sim_seconds": 1000, "output_dir": "results"})` 或手动组合 `control_simulation`
|
|
312
|
+
> 4. 调用 `run_analysis(fcd_file="results/fcd.xml")` 获取平均速度统计。
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## 🧰 Troubleshooting
|
|
317
|
+
|
|
318
|
+
* **提示找不到 `sumo`**(例如:`Error: Could not locate SUMO executable (`sumo`).`):
|
|
319
|
+
1. 先在终端执行 `sumo --version`,确认 SUMO 二进制可用。
|
|
320
|
+
2. 若不可用:把 SUMO 的 `bin/` 加入 `PATH`,或设置 `SUMO_HOME` 并把 `$SUMO_HOME/bin` 加入 `PATH`。
|
|
321
|
+
* **提示找不到 tools 脚本**(例如:`randomTrips.py` / `osmGet.py` / `tls*.py`):
|
|
322
|
+
1. 确认 `SUMO_HOME` 指向 SUMO 安装目录。
|
|
323
|
+
2. 确认 `<SUMO_HOME>/tools` 目录存在且包含对应脚本。
|
|
324
|
+
* **MCP 调用卡住 / 响应显示 `undefined`**:
|
|
325
|
+
1. 该项目通过 stdio 传输 JSON-RPC,任何子进程(SUMO / tools 脚本)向标准输出打印的非 JSON 文本都可能污染通信,导致宿主无法解析响应。
|
|
326
|
+
2. 升级到最新版本(已将 TraCI 启动的 SUMO stdout 做隔离),或确保相关子进程输出被捕获/重定向。
|
|
327
|
+
* **MCP 客户端无法继承环境变量**:
|
|
328
|
+
1. 在 MCP 客户端配置中显式传入 `env`(参考 `mcp_config_examples.json`)。
|
|
329
|
+
|
|
330
|
+
## 📂 项目结构
|
|
331
|
+
|
|
332
|
+
```text
|
|
333
|
+
sumo-mcp/
|
|
334
|
+
├── doc/
|
|
335
|
+
│ ├── API.md # MCP 工具 API 参考(与 src/server.py 对齐)
|
|
336
|
+
│ └── sumo-mcp.jpg # 项目图片
|
|
337
|
+
├── src/
|
|
338
|
+
│ ├── server.py # MCP 服务器入口 (FastMCP 实现,聚合接口)
|
|
339
|
+
│ ├── utils/ # 通用工具
|
|
340
|
+
│ │ ├── connection.py # TraCI 连接管理器
|
|
341
|
+
│ │ ├── output.py # 输出处理工具
|
|
342
|
+
│ │ ├── sumo.py # SUMO 配置工具
|
|
343
|
+
│ │ ├── timeout.py # 超时管理工具
|
|
344
|
+
│ │ └── traci.py # TraCI 封装工具
|
|
345
|
+
│ ├── mcp_tools/ # 核心工具模块
|
|
346
|
+
│ │ ├── analysis.py # 分析工具
|
|
347
|
+
│ │ ├── network.py # 网络工具
|
|
348
|
+
│ │ ├── route.py # 路径工具
|
|
349
|
+
│ │ ├── signal.py # 信号工具
|
|
350
|
+
│ │ ├── simulation.py # 仿真控制工具
|
|
351
|
+
│ │ ├── vehicle.py # 车辆工具
|
|
352
|
+
│ │ └── rl.py # 强化学习工具
|
|
353
|
+
│ ├── resources/ # 资源文件
|
|
354
|
+
│ └── workflows/ # 自动化工作流
|
|
355
|
+
│ ├── sim_gen.py # 仿真生成工作流
|
|
356
|
+
│ ├── signal_opt.py # 信号优化工作流
|
|
357
|
+
│ └── rl_train.py # RL 训练工作流
|
|
358
|
+
├── pyproject.toml # 项目配置与依赖管理
|
|
359
|
+
├── requirements.lock # 锁定依赖版本
|
|
360
|
+
└── README.md # 项目文档
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## 📄 许可证
|
|
364
|
+
|
|
365
|
+
MIT License
|
|
366
|
+
|
|
367
|
+
## 📣 媒体支持
|
|
368
|
+
|
|
369
|
+
感谢以下媒体平台对项目的支持:
|
|
370
|
+
|
|
371
|
+
- BigTrans 公众号 - [重磅开源!SUMO-MCP让大模型助力交通仿真](https://mp.weixin.qq.com/s/fJ_W0zEQlgA-1bAfmjki-A)
|
|
372
|
+
|
|
373
|
+
## 贡献者 ✨
|
|
374
|
+
|
|
375
|
+
<table>
|
|
376
|
+
<tr>
|
|
377
|
+
<td align="center">
|
|
378
|
+
<a href="https://github.com/2217173240">
|
|
379
|
+
<img src="https://github.com/2217173240.png?size=100" width="100px;" alt=""/><br />
|
|
380
|
+
<sub><b>2217173240</b></sub>
|
|
381
|
+
</a>
|
|
382
|
+
</td>
|
|
383
|
+
<td align="center">
|
|
384
|
+
<a href="https://github.com/gateblues">
|
|
385
|
+
<img src="https://github.com/gateblues.png?size=100" width="100px;" alt=""/><br />
|
|
386
|
+
<sub><b>gateblues</b></sub>
|
|
387
|
+
</a>
|
|
388
|
+
</td>
|
|
389
|
+
<td align="center">
|
|
390
|
+
<a href="https://github.com/Hiners">
|
|
391
|
+
<img src="https://github.com/Hiners.png?size=100" width="100px;" alt=""/><br />
|
|
392
|
+
<sub><b>Hiners</b></sub>
|
|
393
|
+
</a>
|
|
394
|
+
</td>
|
|
395
|
+
<td align="center">
|
|
396
|
+
<a href="https://github.com/Zpzp1997">
|
|
397
|
+
<img src="https://github.com/Zpzp1997.png?size=100" width="100px;" alt=""/><br />
|
|
398
|
+
<sub><b>Zpzp1997</b></sub>
|
|
399
|
+
</a>
|
|
400
|
+
</td>
|
|
401
|
+
</tr>
|
|
402
|
+
</table>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
server.py,sha256=c64Y9qkLo1UzE7gW04hLIFhE1kUoeD0PxLIhYbkBsjE,20306
|
|
2
|
+
mcp_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
mcp_tools/analysis.py,sha256=Msh2lcDATMAXsoT0ZGy8YcTS1mxVv7vMG1EEhS1TCO4,1083
|
|
4
|
+
mcp_tools/network.py,sha256=AujAMLaK0cxewyvv_FXQ9W_YBQrCkA7e389NZSjx3YA,3633
|
|
5
|
+
mcp_tools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
mcp_tools/rl.py,sha256=FFomFwGZRONq8n7u8hq_puG8docyMP1k2V4lpH8TOYs,16864
|
|
7
|
+
mcp_tools/route.py,sha256=p3kW4pjVoZMX1TRgbtrZnAywWNe7VwaPXeLeuBTSHPQ,3505
|
|
8
|
+
mcp_tools/signal.py,sha256=t3DpaOLDzZKKy0slzhVEkNDaYZSw_pmqnEm7j34kDm0,3507
|
|
9
|
+
mcp_tools/simulation.py,sha256=WAaW13csdlob4CH4WK2FmUlZCuFiJk2uWE8jydqC9aI,2911
|
|
10
|
+
mcp_tools/vehicle.py,sha256=7gyaYIUvdhkIhdFEZECk7s4w4ZOU_Pvq6LB7luhsDG0,2211
|
|
11
|
+
resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
utils/connection.py,sha256=su1m-3SmhSHJFtE6-z9LKet8yeKafGxj7TRSjOf_H4g,5051
|
|
14
|
+
utils/output.py,sha256=yLnU0rqAf_YI-ycalXpwdaSKeZdjFrnQTfZE1zloG9k,660
|
|
15
|
+
utils/sumo.py,sha256=nvif01kGrfs_Pv3w_0yqpP0ydBWqdHDffejqtxnXmxA,5789
|
|
16
|
+
utils/timeout.py,sha256=S2VM4CrLg5XhjyBJyc6pDINkM72xMM1dF4GJe5uXZow,12454
|
|
17
|
+
utils/traci.py,sha256=epejDxkljHCfmJ3kKbWT2SqWeOq8i464pxBB0uaFfXI,2221
|
|
18
|
+
workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
workflows/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
workflows/rl_train.py,sha256=qTHToU3E8SbjSJzlrpLySZrP8zMUL8P9UCvfIvXGZac,1034
|
|
21
|
+
workflows/signal_opt.py,sha256=RyXGsE9MbAXr_VcfTAYej62LqPdQ3mUaKUvo30Iddjs,7506
|
|
22
|
+
workflows/sim_gen.py,sha256=4nTa3wr4esuA48msQoRjR0FvRTgOk3OEBHBL6Uxo1rM,2449
|
|
23
|
+
iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/METADATA,sha256=zgJsnVJy0FL6eYo7jbX-TNV-Qr_k3Iz3xyBqTa7A_NY,17908
|
|
24
|
+
iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
25
|
+
iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/entry_points.txt,sha256=Hdh89w8I0T1JWEGKbb9HC8CTR96qkav3LwJcMbhh4sk,41
|
|
26
|
+
iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/licenses/LICENSE,sha256=Lwf-W-fYhlzHcggU_u0umDOaqe2B5kdQViz-lE9RZBw,1066
|
|
27
|
+
iflow_mcp_xrds76354_sumo_mcp-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 XuDong Wu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
mcp_tools/__init__.py
ADDED
|
File without changes
|
mcp_tools/analysis.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import sumolib
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
def analyze_fcd(fcd_file: str) -> str:
|
|
6
|
+
"""
|
|
7
|
+
Analyze FCD (Floating Car Data) output XML to compute basic statistics.
|
|
8
|
+
"""
|
|
9
|
+
if not os.path.exists(fcd_file):
|
|
10
|
+
return f"Error: File {fcd_file} not found."
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
speeds = []
|
|
14
|
+
vehicle_counts = 0
|
|
15
|
+
|
|
16
|
+
# sumolib.output.parse returns a generator
|
|
17
|
+
for timestep in sumolib.output.parse(fcd_file, 'timestep'):
|
|
18
|
+
if timestep.vehicle:
|
|
19
|
+
for vehicle in timestep.vehicle:
|
|
20
|
+
speeds.append(float(vehicle.speed))
|
|
21
|
+
vehicle_counts += 1
|
|
22
|
+
|
|
23
|
+
if not speeds:
|
|
24
|
+
return "No vehicle data found in FCD output."
|
|
25
|
+
|
|
26
|
+
avg_speed = sum(speeds) / len(speeds)
|
|
27
|
+
|
|
28
|
+
df = pd.DataFrame({'speed': speeds})
|
|
29
|
+
desc = df.describe().to_string()
|
|
30
|
+
|
|
31
|
+
return f"Analysis Result:\nTotal Data Points: {vehicle_counts}\nAverage Speed: {avg_speed:.2f} m/s\n\nStatistics:\n{desc}"
|
|
32
|
+
except Exception as e:
|
|
33
|
+
return f"Analysis error: {str(e)}"
|
mcp_tools/network.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sumolib
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from typing import Optional, List
|
|
6
|
+
|
|
7
|
+
from utils.sumo import build_sumo_diagnostics, find_sumo_tool_script
|
|
8
|
+
from utils.output import truncate_text
|
|
9
|
+
from utils.timeout import subprocess_run_with_timeout
|
|
10
|
+
|
|
11
|
+
def netconvert(osm_file: str, output_file: str, options: Optional[List[str]] = None) -> str:
|
|
12
|
+
"""
|
|
13
|
+
Wrapper for SUMO netconvert. Converts OSM files to SUMO network files.
|
|
14
|
+
"""
|
|
15
|
+
try:
|
|
16
|
+
binary = sumolib.checkBinary('netconvert')
|
|
17
|
+
except (SystemExit, Exception) as e:
|
|
18
|
+
return f"Error finding netconvert: {e}"
|
|
19
|
+
|
|
20
|
+
cmd = [binary, "--osm-files", osm_file, "-o", output_file]
|
|
21
|
+
if options:
|
|
22
|
+
cmd.extend(options)
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
result = subprocess_run_with_timeout(cmd, operation="netconvert", check=True)
|
|
26
|
+
return f"Netconvert successful.\nStdout: {truncate_text(result.stdout)}"
|
|
27
|
+
except subprocess.CalledProcessError as e:
|
|
28
|
+
return f"Netconvert failed.\nStderr: {truncate_text(e.stderr)}\nStdout: {truncate_text(e.stdout)}"
|
|
29
|
+
except Exception as e:
|
|
30
|
+
return f"Netconvert execution error: {str(e)}"
|
|
31
|
+
|
|
32
|
+
def netgenerate(output_file: str, grid: bool = True, grid_number: int = 3, options: Optional[List[str]] = None) -> str:
|
|
33
|
+
"""
|
|
34
|
+
Wrapper for SUMO netgenerate. Generates abstract networks.
|
|
35
|
+
"""
|
|
36
|
+
try:
|
|
37
|
+
binary = sumolib.checkBinary('netgenerate')
|
|
38
|
+
except (SystemExit, Exception) as e:
|
|
39
|
+
return f"Error finding netgenerate: {e}"
|
|
40
|
+
|
|
41
|
+
cmd = [binary, "-o", output_file]
|
|
42
|
+
if grid:
|
|
43
|
+
cmd.extend(["--grid", "--grid.number", str(grid_number)])
|
|
44
|
+
|
|
45
|
+
if options:
|
|
46
|
+
cmd.extend(options)
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
result = subprocess_run_with_timeout(cmd, operation="netgenerate", check=True)
|
|
50
|
+
return f"Netgenerate successful.\nStdout: {truncate_text(result.stdout)}"
|
|
51
|
+
except subprocess.CalledProcessError as e:
|
|
52
|
+
return f"Netgenerate failed.\nStderr: {truncate_text(e.stderr)}\nStdout: {truncate_text(e.stdout)}"
|
|
53
|
+
except Exception as e:
|
|
54
|
+
return f"Netgenerate execution error: {str(e)}"
|
|
55
|
+
|
|
56
|
+
def osm_get(bbox: str, output_dir: str, prefix: str = "osm", options: Optional[List[str]] = None) -> str:
|
|
57
|
+
"""
|
|
58
|
+
Wrapper for osmGet.py. Downloads OSM data.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
bbox: Bounding box "west,south,east,north".
|
|
62
|
+
output_dir: Directory to save the data.
|
|
63
|
+
prefix: Prefix for output files.
|
|
64
|
+
"""
|
|
65
|
+
script = find_sumo_tool_script("osmGet.py")
|
|
66
|
+
if not script:
|
|
67
|
+
return "\n".join(
|
|
68
|
+
[
|
|
69
|
+
"Error: Could not locate SUMO tool script `osmGet.py`.",
|
|
70
|
+
build_sumo_diagnostics("sumo"),
|
|
71
|
+
"Please set `SUMO_HOME` to your SUMO installation directory "
|
|
72
|
+
"(so that `$SUMO_HOME/tools/osmGet.py` exists).",
|
|
73
|
+
]
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
77
|
+
|
|
78
|
+
# osmGet.py writes to current dir or specified prefix.
|
|
79
|
+
# We should run it in the output_dir or handle paths carefully.
|
|
80
|
+
# It seems osmGet.py uses --prefix to specify output filename prefix.
|
|
81
|
+
|
|
82
|
+
cmd = [sys.executable, script, "--bbox", bbox, "--prefix", prefix]
|
|
83
|
+
|
|
84
|
+
if options:
|
|
85
|
+
cmd.extend(options)
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
# Run in output_dir so files are saved there
|
|
89
|
+
result = subprocess_run_with_timeout(cmd, operation="osmGet", check=True, cwd=output_dir)
|
|
90
|
+
return f"osmGet successful.\nStdout: {truncate_text(result.stdout)}"
|
|
91
|
+
except subprocess.CalledProcessError as e:
|
|
92
|
+
return f"osmGet failed.\nStderr: {truncate_text(e.stderr)}\nStdout: {truncate_text(e.stdout)}"
|
|
93
|
+
except Exception as e:
|
|
94
|
+
return f"osmGet execution error: {str(e)}"
|
mcp_tools/py.typed
ADDED
|
File without changes
|