1. 目标
- 随意指定场景
- 场景里找物品(微波炉为例)
- 找到后传送到物品前面
2. 代码
import math
from ai2thor.controller import Controller
# 将值四舍五入到最近的网格点
def round_to_grid(value, grid_size=0.25):
return max(grid_size,round(value / grid_size) * grid_size)
#验证场景编号是否有效
def check_scene_number(scene_number):
return scene_number in range(1, 31) or scene_number in range(201, 231) or \
scene_number in range(301, 331) or scene_number in range(401, 431);
# 在当前场景中搜索指定类型的物体
def search_for_object(controller, object_type="Microwave"):
objects = [obj for obj in controller.last_event.metadata["objects"] if obj["objectType"] == object_type]
if len(objects) > 0:
print(f"找到{len(objects)}个{object_type}(s)")
for obj in objects:
print(f"{object_type}位置: {obj['position']}")
return objects[0] # 返回第一个找到的物体
else:
print(f"没有找到{object_type}")
return None
# 计算目标位置并传送到目标物体面前
def teleport_to_object(controller, target_object):
agent_position = controller.last_event.metadata['agent']['position']
target_rotation = (target_object['rotation']['y'] + 180) % 360 # 面向目标物体
new_position = {
'x': round_to_grid(target_object['position']['x'] - 1),
'y': round_to_grid(target_object['position']['y'] - 1),
'z': agent_position['z']
}
# 使用Teleport动作传送
event = controller.step(
action="Teleport",
position=new_position,
rotation=dict(x=0,y=target_rotation,z=0),
horizon=0, # 直视前方
standing=True
)
if event.metadata["lastActionSuccess"]:
print(f"成功传送到{new_position},面朝{rotation_y}度")
else:
tmpIdx = event.metadata['errorMessage'].find("trace:")
print(f"传送失败:{event.metadata['errorMessage'][:tmpIdx]}")
# 初始化控制器
controller = Controller(
width=1280,
height=720,
fieldOfView=110,
visibilityDistance=5,
renderInstanceSegmentation=True
)
while True:
try:
scene_choice = input("请输入场景编号(1-30, 201-230, 301-330, 401-430):")
scene_number = int(scene_choice)
if not check_scene_number(scene_number):
raise ValueError("无效的场景编号,请重新输入。")
selected_scene = f"FloorPlan{scene_number}"
# 重置到选定的场景
controller.reset(selected_scene)
print(f"加载场景: {selected_scene}")
# 搜索物体
found_object = search_for_object(controller)
if found_object is not None:
teleport_to_object(controller, found_object)
except ValueError as e:
print(e)
controller.stop()
3. 最终成果
场景切换,传送