五种感知,一个数据库
将多模态机器人感知统一到单一记忆中
视觉。触觉。听觉。本体感觉。程序性。
五种感知类型。一个 API。一个数据库。
大多数机器人系统将不同的感知类型存储在不同的地方 — 图像在一个文件夹,力传感器读数在 CSV 文件,关节角度在 ROS bag 包,动作序列在 JSON 日志中。当你需要回忆"抓取那个杯子时发生了什么",你需要查询五个不同的系统。
我们把它们全部放在了一张表里。
问题:碎片化的感知
一个典型的机器人操作流水线会生成:
- 视觉 — 相机图像、边界框、目标检测结果
- 触觉 — 力/扭矩传感器读数、接触事件
- 听觉 — 电机声音、碰撞噪声、环境音频
- 本体感觉 — 关节角度、末端执行器位姿、速度
- 程序性 — 动作序列、轨迹、技能参数
每种模态通常都有自己的存储系统、查询接口和检索逻辑。跨模态查询 — "找到我看到红色杯子的那次抓取中的力传感器读数" — 需要在系统之间手动关联。
这就是碎片化。而且随着传感器的增加,问题会越来越严重。
解决方案:统一 API 处理所有感知
在 robotmem 中,所有感知都通过同一个函数:
from robotmem import save_perception
# 视觉 — 看到红色杯子
save_perception("saw red cup at [120, 200]",
perception_type="visual",
data='{"bbox": [120, 200, 50, 50], "confidence": 0.94}')
# 触觉 — 感受到接触力
save_perception("felt 12.5N contact force",
perception_type="tactile",
data='{"force_N": 12.5, "contact_area_mm2": 45}')
# 听觉 — 听到咔嗒声
save_perception("heard click during insertion",
perception_type="auditory",
data='{"frequency_hz": 440, "duration_ms": 12}')
# 本体感觉 — 手臂位置
save_perception("arm at joint angles [0.1, 0.8, -0.3, 1.2, 0.0, -0.5, 0.2]",
perception_type="proprioceptive",
data='{"joint_angles": [0.1, 0.8, -0.3, 1.2, 0.0, -0.5, 0.2]}')
# 程序性 — 动作序列
save_perception("push then lift: approach → push → lift",
perception_type="procedural",
data='{"steps": ["approach", "push", "lift"], "duration_s": 3.2}')
五种感知全部进入同一张 memories 表。相同的 schema。相同的搜索索引。相同的 API。
为什么一张表就够了
关键设计决策:将描述与数据分离。
| 字段 | 用途 | 可搜索 |
|---|---|---|
description | 人类可读的文本 | BM25 + 向量 |
perception_type | 模态标签 | 过滤 |
data | 原始传感器 JSON | JSON 路径查询 |
context | 任务/空间元数据 | 上下文过滤 + 空间排序 |
description 始终是文本 — 可通过关键词和语义相似度搜索。data 字段以 JSON 格式存储原始感知数据,由 perception_type 标记类型。这意味着你可以跨模态进行语义搜索("抓取过程中发生了什么?"),然后从结果中访问特定类型的数据。
新增传感器类型无需修改 schema。添加 LiDAR?只需使用 perception_type="lidar"。数据库不在乎 — 这只是一个新标签,不是一张新表。
跨模态检索
由于所有感知共享相同的搜索索引,你可以自然地跨模态查询:
from robotmem import recall
# 查找所有与"抓取"相关的感知 — 视觉、触觉、程序性
result = recall("grasp red cup")
for m in result["memories"]:
print(f"[{m['perception_type']}] {m['content']}")
# 输出:
# [visual] saw red cup at [120, 200]
# [tactile] felt 12.5N contact force
# [procedural] push then lift: approach → push → lift
一次查询即可返回视觉检测、力传感器读数和动作序列 — 全部来自同一次抓取事件。无需关联。无需跨系统查询。
试一试
pip install robotmem
python -c "
from robotmem import save_perception, recall
save_perception('felt 12.5N force', perception_type='tactile', data='{\"force\": 12.5}')
save_perception('saw red cup', perception_type='visual', data='{\"bbox\": [100,200,50,50]}')
result = recall('grasp')
for m in result['memories']:
print(f\"[{m['perception_type']}] {m['content']}\")
"