警告 此代码由ai创建
ROSBag MCP服务器
该代码的灵感来自 ROSBag MCP服务器:使用LLM分析机器人数据,用于代理栓塞AI应用.
MCP(模型上下文协议)服务器,用于使用LLM分析ROS和ROS 2包文件。实现与机器人数据集的自然语言交互,用于调试、性能评估和提取见解。
特性
核心数据访问和管理
| 工具 | 说明 |
|---|
set_bag_path | 设置rosbag文件或目录的路径 |
list_bags | 列出目录中所有可用的rosbag文件 |
bag_info | 检索行李元数据:主题、消息计数、持续时间、时间范围 |
get_topic_schema | 使用示例数据检查消息结构/模式 |
消息检索
| 工具 | 说明 |
|---|
get_message_at_time | 在特定时间戳从主题获取消息 |
get_messages_in_range | 获取某一时间范围内某一主题的所有消息 |
search_messages | 使用条件(正则表达式、等号、near_position、阈值)搜索消息 |
数据过滤和导出
| 工具 | 说明 |
|---|
filter_bag | 按主题、时间或采样率创建行李文件的筛选副本 |
export_to_csv | 将主题数据导出到CSV文件以供外部分析 |
领域特定分析
| 工具 | 说明 |
|---|
analyze_trajectory | 计算轨迹度量:总距离、平均/最大速度、位置界限 |
analyze_lidar_scan | 分析激光雷达扫描的障碍物、间隙和统计数据 |
analyze_imu | 分析IMU数据:加速度、角速度、方向统计 |
analyze_logs | 解析和分析ROS日志;按级别或节点筛选 |
get_tf_tree | 获取坐标系关系的TF树 |
get_image_at_time | 提取特定时间的相机图像(返回base64 JPEG) |
导航分析
| 工具 | 说明 |
|---|
analyze_path_tracking | 计算计划路径和实际姿态之间的交叉跟踪误差(AMCL/odm) |
analyze_costmap_violations | 检查机器人是否进入成本图中的障碍物/致命单元 |
analyze_navigation_health | 汇总导航错误、恢复事件和健康评估的目标结果 |
analyze_wheel_slip | 将指令速度与实际速度进行比较,以检测牵引力损失和车轮打滑 |
统计和事件检测
| 工具 | 说明 |
|---|
analyze_topic_stats | 分析主题频率、延迟、消息间隔和间隔 |
compare_topics | 比较两个主题字段:相关性、差异性、RMSE |
detect_events | 检测阈值交叉、低于阈值、突然变化、异常、停机 |
analyze_lidar_timeseries | 随时间跟踪LiDAR统计数据:最小距离、障碍物数量、最近距离 |
可视化和绘图
| 工具 | 说明 |
|---|
plot_timeseries | 绘制具有多个字段/样式的时间序列数据 |
plot_2d | 创建二维轨迹图(XY位置) |
plot_lidar_scan | 将激光雷达扫描可视化为极坐标图 |
plot_comparison | 两个主题字段的叠加图,突出显示差异 |
支持格式
| 格式 | 扩展名 | 描述 |
|---|
| ROS 1 | .bag | 标准ROS 1袋格式 |
| ROS 2 | .db3 | 基于SQLite的ROS 2格式 |
| ROS 2 | .mcap | Foxglove的现代容器格式 |
安装
来自PyPI
# Using uv (recommended)
uv pip install rosbag-mcp
# Using pip
pip install rosbag-mcp
来自GitHub
# Using uv
uv pip install "rosbag-mcp @ git+https://github.com/cjh1995-ros/rosbag-mcp.git"
# Using pip
pip install "rosbag-mcp @ git+https://github.com/cjh1995-ros/rosbag-mcp.git"
来源(开发)
git clone https://github.com/cjh1995-ros/rosbag-mcp.git
cd rosbag-mcp
uv pip install -e ".[dev]"
需求
- Python>=3.10
- 主控程序 >= 1.0.0
- 玫瑰花包 >= 0.9.0
- numpy、matplotlib、枕头
用法
克劳德桌面/克劳德代码
增添 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)或 %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"rosbag": {
"command": "rosbag-mcp"
}
}
}
或跑步 uvx 不安装:
{
"mcpServers": {
"rosbag": {
"command": "uvx",
"args": ["rosbag-mcp"]
}
}
}
作为MCP服务器(stdio)
rosbag-mcp
程序化使用(Python)
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def analyze_bag():
server_params = StdioServerParameters(
command="python",
args=["-m", "rosbag_mcp.server"],
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# Set bag path
await session.call_tool("set_bag_path", {
"path": "/path/to/your/bag.bag"
})
# Get bag info
result = await session.call_tool("bag_info", {})
print(result.content[0].text)
# Analyze trajectory
result = await session.call_tool("analyze_trajectory", {
"pose_topic": "/odom"
})
print(result.content[0].text)
asyncio.run(analyze_bag())
查询示例
一旦连接到Claude或另一个支持MCP的LLM:
"What bags do you have in /path/to/rosbags?"
"Show me the bag info for test.bag"
"What's the message structure of /odom topic?"
"Plot the robot's trajectory from the /odom topic"
"What was the robot's maximum velocity between t=10s and t=30s?"
"Has the robot ever passed close to position (x=2, y=-2) within 0.5 meters?"
"Analyze the LiDAR scan at t=15s - are there any obstacles within 2 meters?"
"Plot the commanded vs actual velocities for the first 30 seconds"
"Show me the TF tree - what are all the coordinate frames?"
"Filter the bag to only include /odom and /cmd_vel topics"
"Analyze the IMU data - what's the average acceleration?"
"Did the robot ever hit the costmap during navigation?"
"How well did the robot follow the planned path? What was the cross-track error?"
"Compare the commanded velocity vs actual velocity - what's the correlation?"
"When did the robot stop moving? Detect all stoppages."
"What's the publishing frequency of /odom? Are there any gaps?"
"Export the odometry data to CSV for analysis in Python"
"Is the robot experiencing wheel slip? Compare commanded vs actual velocity."
"Give me a navigation health report - any errors, recoveries, or planning failures?"
"Track the LiDAR minimum distance over time - when was the closest approach?"
"Plot a comparison of commanded velocity vs actual velocity with the difference."
"Detect all events where velocity dropped below -0.05 m/s (backward motion)."
输出示例
行李信息
{
"path": "/data/robot_nav.bag",
"duration": 73.97,
"start_time": 1769892473.39,
"end_time": 1769892547.36,
"message_count": 191336,
"topics": [
{"name": "/odom", "type": "nav_msgs/msg/Odometry", "count": 4429},
{"name": "/scan", "type": "sensor_msgs/msg/LaserScan", "count": 1108},
{"name": "/tf", "type": "tf2_msgs/msg/TFMessage", "count": 27955}
]
}
轨迹分析
{
"total_distance_m": 38.26,
"duration_s": 73.87,
"x_range": {"min": -19.75, "max": 5.21},
"y_range": {"min": -4.20, "max": 6.53},
"linear_speed": {"mean": 0.518, "max": 0.905, "min": 0.0},
"angular_speed": {"mean": 0.178, "max": 1.058, "min": 0.0}
}
激光雷达分析
{
"timestamp": 1769892483.52,
"total_rays": 689,
"valid_rays": 426,
"statistics": {
"min_distance": 4.12,
"max_distance": 21.98,
"mean_distance": 9.89
},
"obstacles": {
"threshold_m": 2.0,
"count": 0,
"closest_distance": null
}
}
IMU分析
{
"topic": "/base_board/imu",
"message_count": 7386,
"duration_s": 73.88,
"sample_rate_hz": 99.97,
"linear_acceleration": {
"x": {"mean": -0.0015, "std": 0.0205, "min": -0.2256, "max": 0.2467},
"y": {"mean": -0.0018, "std": 0.0409, "min": -0.3311, "max": 0.4044},
"z": {"mean": -0.0307, "std": 0.0916, "min": -0.9011, "max": 0.7922},
"magnitude": {"mean": 0.0657, "max": 0.9559}
},
"angular_velocity": {
"x": {"mean": 0.002, "std": 0.0459, "max_abs": 0.5867},
"y": {"mean": 0.0001, "std": 0.0204, "max_abs": 0.2222},
"z": {"mean": 0.0828, "std": 0.2694, "max_abs": 1.061}
}
}
路径跟踪分析
{
"path_topic": "/move_base/GlobalPlanner/plan",
"pose_topic": "/amcl_pose",
"tracking_samples": 641,
"cross_track_error": {
"mean_m": 0.0161,
"std_m": 0.0125,
"min_m": 0.0,
"max_m": 0.0817,
"median_m": 0.0132,
"p95_m": 0.0377
},
"path_completion": {
"final_progress": 1.0,
"max_progress": 1.0
}
}
主题统计
{
"topic": "/odom",
"message_count": 4429,
"duration_s": 73.873,
"frequency": {
"mean_hz": 59.94,
"std_hz": 53116.3,
"min_hz": 5.54,
"max_hz": 419430.4
},
"interval": {
"mean_ms": 16.683,
"std_ms": 11.203,
"min_ms": 0.002,
"max_ms": 180.384
},
"gaps": {
"count": 92,
"threshold_ms": 50.049,
"largest_gap_ms": 180.384
}
}
成本图违规检查
{
"costmap_topic": "/move_base/local_costmap/costmap",
"pose_topic": "/amcl_pose",
"cost_threshold": 253,
"violations": {"count": 0, "samples": []},
"cost_distribution": {"0-49": 626, "50-99": 15},
"summary": "No costmap violations detected - Robot stayed in free space"
}
可视化示例
二维轨迹图
Trajectory
激光雷达扫描(极坐标图)
LiDAR
速度时间序列
Velocity
建筑
┌─────────────────┐ stdio ┌──────────────────┐
│ MCP Client │◄──────────────►│ ROSBag MCP │
│ (Claude, etc) │ JSON-RPC │ Server │
└─────────────────┘ └────────┬─────────┘
│
▼
┌──────────────────┐
│ rosbags library │
│ (Python) │
└────────┬─────────┘
│
┌───────────────────────┼───────────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ .bag │ │ .mcap │ │ .db3 │
│ (ROS 1) │ │ (ROS 2) │ │ (ROS 2) │
└──────────┘ └──────────┘ └──────────┘
工具架构示例
{
"name": "get_messages_in_range",
"description": "Get all messages from a topic within a time range",
"inputSchema": {
"type": "object",
"properties": {
"topic": {
"type": "string",
"description": "ROS topic name"
},
"start_time": {
"type": "number",
"description": "Start unix timestamp in seconds"
},
"end_time": {
"type": "number",
"description": "End unix timestamp in seconds"
},
"max_messages": {
"type": "integer",
"description": "Maximum messages to return (default: 100)"
},
"bag_path": {
"type": "string",
"description": "Optional: specific bag file"
}
},
"required": ["topic", "start_time", "end_time"]
}
}
参考文献
许可证
MIT许可证