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

news/2025/2/27 5:51:37

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

python">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. 效果

<a class=ITHOR场景切换、导航" />
在这里插入图片描述


http://www.niftyadmin.cn/n/5869570.html

相关文章

Python在实际工作中的运用-通用格式CSV文件自动转换XLSX

继续上篇《Python在实际工作中的运用-CSV无损转XLSX的几个方法》我们对特定的CSV实现了快速转换XLSX的目标&#xff0c;但是运行Py脚本前还是需要编辑表格创建脚本和数据插入脚本&#xff0c;自动化程度很低&#xff0c;实用性不强&#xff0c;为提供工作效率&#xff0c;实现输…

kafka consumer 手动 ack

在消费 Kafka 消息时&#xff0c;手动确认&#xff08;acknowledge&#xff09;消息的消费&#xff0c;可以通过使用 KafkaConsumer 类中的 commitSync() 或 commitAsync() 方法来实现。这些方法将提交当前偏移量&#xff0c;确保在消费者崩溃时不会重新消费已处理的消息。 以…

HBase与MapReduce结合(二)——对HBase表中字段进行WordCount

目录 1. 数据文本2. pom.xml中依赖配置3. 工具类Util4. 导入数据ImportData5. 对HBase表进行WordCount6. 配置Job7. 结果参考 1. 数据文本 1_song1_2016-1-11 song1 singer1 man slow pc 2_song2_2016-1-11 song2 singer2 woman slow ios 3_song3_2016-1-11 song3 singer3 man…

Project #0 - C++ Primer前置知识学习

这次的Lab0主要以熟悉C 11和C 17的新特性。这里先把相关新特性分析一下。 目录 一、Doxygen注释 二、函数签名分析 三、构造函数与delete、explicit 四、static constexpr 解释 五、各种cast转换(重点) 5.1 const_cast与reinterpret_cast 5.2 static_cast与dynamic_cas…

eclipse 4.4.2 m2eclipse apache-maven-3.2.1

apache-maven-3.2.1-CSDN博客 eclipse 4.4.2 m2eclipse

Java SE与Java EE

Java SE&#xff08;Java 平台标准版&#xff09; Java SE 是 Java 平台的核心&#xff0c;提供了 Java 语言的基础功能。它包含了 Java 开发工具包&#xff08;JDK&#xff09;&#xff0c;其中有 Java 编译器&#xff08;javac&#xff09;、Java 虚拟机&#xff08;JVM&…

营销过程乌龟图模版

营销过程乌龟图模版 输入 公司现状产品服务客户问询客户期望电话、电脑系统品牌软件硬件材料 售前 - 沟通 - 确定需求 - 满足需求 - 售后 机料环 电话、电脑等设备软件硬件、系统品牌等工具材料 人 责任人协助者生产者客户 法 订单由谁评审控制程序营销过程控制程序顾客满意度…

SOC-ATF 安全启动BL1流程分析(1)

一、ATF 源码下载链接 1. ARM Trusted Firmware (ATF) 官方 GitHub 仓库 GitHub 地址: https://github.com/ARM-software/arm-trusted-firmware 这是 ATF 的官方源码仓库&#xff0c;包含最新的代码、文档和示例。 下载方式&#xff1a; 使用 Git 克隆仓库&#xff1a; git…