AI2-THOR 居家任务:机器人的“模拟人生”

AI2-THOR官网:
https://ai2thor.allenai.org/
代码地址:
https://github.com/allenai/ai2thor
这是个什么项目?
AI2-THOR 由艾伦人工智能研究所(Allen Institute for AI,简称 AI2)开发,全称是 The House Of inteRactions(家庭交互模拟器)。
你可以把它理解成一个高度逼真的"虚拟房子",里面有厨房、客厅、卧室、浴室,有超过 200 种可以被拿起、打开、关闭的物体,而你要做的,是训练一个 AI 智能体在这个房子里完成各种任务,比如"把苹果放进冰箱"或者"找到遥控器"。
下图展示了 AI2-THOR 系统的核心结构:智能体(Agent)在 AI2-THOR 环境中感知视觉信息,输出动作,环境反馈新的状态,最终积累出研究成果。

搭建环境
在正式开始之前,先了解一下系统要求。AI2-THOR 使用 Unity 引擎作为后端渲染器,因此对系统有一定要求。
操作系统:Ubuntu 20.04+ / macOS 11+ / Windows 10+
Python:3.8 – 3.10
GPU:非必须,有 GPU 会更快
内存:8GB 以上
磁盘:预留 2GB+
第一步:创建虚拟环境
强烈推荐使用 conda 或 venv 创建独立的虚拟环境,避免污染系统 Python 包,这也是日后复现或迁移项目时最省心的做法。
# 使用 conda(推荐)
conda create -n ai2thor_env python=3.9
conda activate ai2thor_env
# 或使用 venv
python -m venv ai2thor_env
source ai2thor_env/bin/activate # Linux/Mac
ai2thor_env\Scripts\activate # Windows第二步:安装 ai2thor 包
AI2-THOR 已发布到 PyPI,直接用 pip 安装即可。安装本身很快,真正耗时的是第一次运行时自动下载的 Unity 构建包。
pip install ai2thor
# 可选:同时安装常用依赖
pip install numpy pillow matplotlib注意网络问题:第一次运行时,程序会自动从 GitHub Releases 下载约 800MB 的 Unity 构建包
写你的第一段代码
环境装好后,我们来写第一个真正能跑起来的程序。AI2-THOR 的交互方式非常直观:创建一个 Controller(控制器),指定一个场景,然后通过 controller.step(action=...) 发送动作,每次都会返回一个 event 对象,里面包含了当前帧的所有信息。
from ai2thor.controller import Controller
# 创建控制器,FloorPlan1 是厨房场景
controller = Controller(
scene="FloorPlan1",
gridSize=0.25, # 每步移动距离(米)
renderDepthImage=True, # 开启深度图
width=640, height=480 # 渲染分辨率
)
# 向前走一步
event = controller.step(action="MoveAhead")
# 查看返回的 RGB 图像(numpy array)
frame = event.frame # shape: (480, 640, 3)# 查看智能体当前位置
pos = event.metadata["agent"]["position"]
print(f"Agent position: {pos}")
# 列出当前场景中所有可见物体for obj in event.metadata["objects"]:
if obj["visible"]:
print(obj["objectType"], obj["objectId"])
# 结束后关闭控制器(释放内存)
controller.stop()在 AI2-THOR 中,所有行为都遵循一个标准循环:智能体感知环境状态,策略网络输出动作,环境执行动作并返回新状态,这就是强化学习中经典的"观测—动作—奖励"循环。下图直观地展示了这个过程:

常用的动作
AI2-THOR 的动作系统非常丰富,新手最常用的动作分为以下几类:
### 移动类 ###
controller.step("MoveAhead") # 向前一步
controller.step("MoveBack") # 向后一步
controller.step("RotateLeft") # 左转 90°
controller.step("RotateRight") # 右转 90°
controller.step("LookUp") # 仰头
controller.step("LookDown") # 俯头### 交互类(需指定 objectId)###
controller.step(
action="PickupObject",
objectId="Apple|-01.00|+00.90|-01.00"
)
controller.step(action="OpenObject", objectId="Fridge|...")
controller.step(action="PutObject", objectId="Fridge|...")
controller.step(action="ToggleObjectOn", objectId="Stove|...")
### 传送(开发调试时很有用)###
controller.step(
action="Teleport",
position=dict(x=-2.0, y=0.9, z=-1.5)
)新手技巧:使用 Teleport 快速定位,在早期调试阶段,与其让智能体一步步移动到目标附近,不如直接用 Teleport 动作把智能体传送到目标位置,这样可以专注测试交互逻辑而不被导航问题干扰。
居家任务是怎么运作的?
理解了基础 API 之后,我们来看 AI2-THOR 中"居家任务"的核心逻辑。
最经典的任务框架叫做 iTHOR,任务通常由三个要素定义:初始状态(Initial State)、目标状态(Goal State)、以及成功条件(Success Condition)。
"把苹果放进冰箱"任务
这是一个标准的物体重定位(Object Rearrangement)任务。初始状态下苹果在桌子上,目标是让苹果最终位于冰箱内部。智能体需要完成:找到苹果 → 走近 → 拿起 → 走到冰箱 → 打开冰箱 → 放入 → 关闭冰箱,共约六七个子步骤。
from ai2thor.controller import Controller
controller = Controller(scene="FloorPlan1")
# 1. 找到场景中的苹果 objectId
event = controller.step("Pass") # Pass 不做任何动作,只刷新状态
apple_id = None
fridge_id = Nonefor obj in event.metadata["objects"]:
if obj["objectType"] == "Apple":
apple_id = obj["objectId"]
if obj["objectType"] == "Fridge":
fridge_id = obj["objectId"]
# 2. 传送到苹果附近(简化导航)
controller.step(action="Teleport", position=dict(x=-1.0, y=0.9, z=-1.0))
# 3. 拾取苹果
event = controller.step(action="PickupObject", objectId=apple_id)
print("拾取成功?", event.metadata["lastActionSuccess"])
# 4. 传送到冰箱附近
controller.step(action="Teleport", position=dict(x=-2.0, y=0.9, z=0.0))
# 5. 打开冰箱
controller.step(action="OpenObject", objectId=fridge_id)
# 6. 将苹果放入冰箱
event = controller.step(action="PutObject", objectId=fridge_id)
print("放入成功?", event.metadata["lastActionSuccess"])
controller.stop()常见任务类型
如果你完成了“把苹果放进冰箱”任务,还可以尝试着完成以下任务。
物体导航:找到目标物体并走到其附近,例如 ObjectNav 任务。
语言指令跟随:根据自然语言指令完成任务,如 ALFRED 数据集。
多智能体协作:两个或更多 agent 合作完成复杂任务。
避坑指南
首次运行卡在下载,超时失败
解决方法:在运行前设置好代理,或者手动从 AI2-THOR 的 GitHub Releases 页面下载对应版本的构建包,放到 ~/.ai2thor/releases/ 目录下,再运行程序。
动作执行后 lastActionSuccess 为 False,但不报错
解决方法:每次 step() 之后都要检查 event.metadata["lastActionSuccess"] 和 event.metadata["errorMessage"]。最常见的原因是智能体和目标物体之间距离太远,或者目标物体处于不可见状态。
objectId 写错导致交互失败
解决方法:不要手写或猜 objectId。每次都从 event.metadata["objects"] 中动态查找,根据 objectType 筛选,再取 objectId 字段使用。同一类物体在不同场景中的 ID 是不同的。
内存泄露,程序反复运行后越来越慢
解决方法:每个脚本结束时务必调用 controller.stop(),或者使用 with Controller(...) as c: 的上下文管理器写法,这样会自动关闭 Unity 进程,释放内存。
拿起物体后视野里"什么都看不见"
解决方法:拿起物体后,物体会跟随摄像头移动,部分动作(如低头 LookDown)可以在视野中看到持有的物体。此外,可以通过检查event.metadata["inventoryObjects"] 来确认智能体当前持有的物体。
AI2-THOR 的动作是离散的、基于网格的(grid-based)。智能体不能移动到任意坐标,只能按 gridSize(默认 0.25m)的倍数移动。这意味着你不能期待智能体精确地"走到某个坐标",而是要先用 GetReachablePositions 动作获取所有可到达的网格点,再做路径规划。
总结
你会真正理解"让 AI 在三维空间里做决策"是怎么一回事,包括强化学习、视觉感知、动作规划这几块知识如何拼在一起工作。同时你也会获得一套具身 AI 的实战直觉:知道模型为什么会失败、瓶颈在哪里,这比单纯刷论文要值钱得多。
