当前位置: 首页 > news >正文

仿真环境下实现场景切换、定位物体和导航行走

1. 代码(以微波炉为例)

from ai2thor.controller import Controller
import math
import random

def distance_2d(pos1, pos2):
    """计算两点之间的二维欧几里得距离(忽略Z轴)"""
    return math.sqrt((pos1['x'] - pos2['x']) ** 2 + (pos1['y'] - pos2['y']) ** 2)

def get_reachable_positions(controller):
    """获取所有可达位置"""
    reachable_positions = controller.step(
        action="GetReachablePositions"
    ).metadata["actionReturn"]
    return [{k: pos[k] for k in ['x', 'y']} for pos in reachable_positions]

def move_towards_target_2d(controller, target_position):
    """导航到目标位置(仅考虑X和Y坐标)"""
    max_attempts = 5
    attempt = 0
    while attempt < max_attempts:
        current_position = {k: controller.last_event.metadata["agent"]["position"][k] for k in ['x', 'y']}
        if distance_2d(current_position, target_position) <= 0.5:  # 目标精度为0.5米
            print("到达目标附近")
            return True
        
        diff_x = target_position['x'] - current_position['x']
        diff_y = target_position['y'] - current_position['y']

        if abs(diff_x) > abs(diff_y):
            action = "MoveRight" if diff_x > 0 else "MoveLeft"
        else:
            action = "MoveAhead" if diff_y > 0 else "MoveBack"

        event = controller.step(action=action, moveMagnitude=0.5)
        print(f"移动:{action}{event.metadata['lastActionSuccess']}")
        if not event.metadata["lastActionSuccess"]:
            print(f"移动失败:{event.metadata['errorMessage']}")
            possible_actions = ["MoveRight", "MoveLeft", "MoveAhead", "MoveBack"]
            possible_actions.remove(action)  # 移除当前尝试失败的动作
            random_action = random.choice(possible_actions)
            event = controller.step(action=random_action, moveMagnitude=0.5)
            if not event.metadata["lastActionSuccess"]:
                print(f"尝试反方向移动也失败了:{event.metadata['errorMessage']}")
                back_action = "MoveBack" if diff_y > 0 else "MoveAhead"
                controller.step(action=back_action, moveMagnitude=0.5)
                attempt += 1
                continue
            else:
                print(f"新方向移动成功:{random_action}")
    print("不知道如何抵达")
    return False

def manual_movement(controller):
    """手动控制移动"""
    while True:
        user_input = input("请输入移动指令(WASD键分别代表上、左、下、右),输入Q退出手动模式:").upper()
        if user_input == 'Q':
            print("退出手动模式")
            break
        elif user_input in ['W', 'A', 'S', 'D']:
            action_map = {'W': 'MoveAhead', 'A': 'MoveLeft', 'S': 'MoveBack', 'D': 'MoveRight'}
            action = action_map[user_input]
            event = controller.step(action=action, moveMagnitude=0.5)
            if event.metadata["lastActionSuccess"]:
                print(f"{action} 成功!")
            else:
                print(f"{action} 失败:{event.metadata['errorMessage']}")
        else:
            print("无效输入,请重新输入")

controller = Controller(
    width=1280,
    height=720,
    fieldOfView=110,
    visibilityDistance=5,
    renderInstanceSegmentation=True
)

scenes = ["FloorPlan1", "FloorPlan201", "FloorPlan301", "FloorPlan401"]
scene_names = ["厨房", "客厅", "卧室", "浴室"]

while True:
    scene_choice = input("请输入场景编号(1-厨房,2-客厅,3-卧室,4-浴室),输入'Q'进入手动模式:")
       
    if scene_choice.lower() == 'q':
        print("进入手动模式")
        manual_movement(controller)
        continue
    
    try:
        scene_number = int(scene_choice)
        if scene_number < 1 or scene_number > 4:
            raise ValueError()
    except ValueError:
        print("无效的输入,请重新输入")
        continue

    selected_scene = scenes[scene_number - 1]
    selected_scene_name = scene_names[scene_number - 1]
    
    controller.reset(selected_scene)
    reachable_positions = get_reachable_positions(controller)

    microwaves = [obj for obj in controller.last_event.metadata["objects"] if obj["objectType"] == "Microwave"]

    if len(microwaves) > 0:
        target = microwaves[0]
        target_position = {'x': target["position"]['x'], 'y': target["position"]['y']}
        print(f"{selected_scene_name}中目标微波炉位置: {target_position}")
        success = move_towards_target_2d(controller, target_position)
        if success:
            # 抓取动作
            event = controller.step(action="PickupObject", objectId=target["objectId"])
            if event.metadata["lastActionSuccess"]:
                print(f"{selected_scene_name}中抓取成功!")
            else:
                print(f"{selected_scene_name}中抓取失败:{event.metadata['errorMessage']}")
    else:
        print(f"{selected_scene_name}中没有微波炉")

controller.stop()

2. 效果

ITHOR场景切换、导航

ITHOR场景切换、导航
在这里插入图片描述

http://www.dtcms.com/a/39514.html

相关文章:

  • RK3588--MIPI屏幕选型以及底板设计要点
  • JUC (java. util.concurrent) 的常见类及创建新线程的方法等 [Java EE 初阶]
  • Springboot快速接入豆包大模型
  • 【二分查找 图论】P8794 [蓝桥杯 2022 国 A] 环境治理|普及
  • C++中的多重继承
  • 品牌设计分析模版
  • DeepSeek的100个实用提示词模板
  • 如何让 Git 管理本地项目
  • 使用Jenkins实现Windows服务器下C#应用程序发布
  • Deepseek开源周,第二天:Deep EP
  • OkHttp、Retrofit、RxJava:一文讲清楚
  • Wasserstein 距离(Wasserstein Distance)
  • adb的安装
  • 数据如何安全“过桥”?分类分级与风险评估,守护数据流通安全
  • 软件工程(复习折磨题目版)
  • 墨刀:Axure托管插件登录/注册时出现空白页
  • 解锁状态模式:Java 编程中的行为魔法
  • 什么限制了LLM:空间复杂度限制
  • 【人工智能】数据挖掘与应用题库(1-100)
  • 初阶数据结构(C语言实现)——2算法的时间复杂度和空间复杂度
  • HDFS数据多目录、异构存储、回收站
  • 方法的有关知识(含递归)
  • 爬虫反爬:CSS位置偏移反爬案例分析与实战案例
  • Tornado框架内存马学习
  • PyTorch 源码学习:GPU 内存管理之它山之石——TensorFlow BFC 算法
  • HarmonyOS学习第7天: 文本组件点亮界面的文字魔法棒
  • 【蓝桥杯】每天一题,理解逻辑(1/90)【Leetcode 移动零】
  • 【错误记录】Arrays.asList 的坑
  • 安装react报错
  • Vue 中,使用模板(Template) 和 Render 函数编写组件的区别