机器人学习模拟框架 robosuite (3) 机器人控制代码示例

Robosuite框架是一个用于机器人模拟和控制的强大工具,支持多种类型的机器人。

官方文档:Overview --- robosuite 1.5 documentation

开源地址:https://github.com/ARISE-Initiative/robosuite

目录

1、通过键盘或SpaceMouse远程控制机器人

2、选择机器人夹抓

3、夹抓控制

4、记录轨迹数据并回放

5、多种机器人任务执行


1、通过键盘或SpaceMouse远程控制机器人

主要功能包括:

  • 远程控制:通过键盘或 SpaceMouse 远程控制机器人的末端执行器。

  • 多臂支持:支持单臂和双臂环境,适应不同的任务需求。

  • 控制器选择:支持多种控制器,适应不同的控制策略。

  • 设备灵敏度调整:通过参数调整输入设备的灵敏度,适应不同的操作需求。

运行效果:

控制机械臂移动的键盘按键:H、Y、P、O、; 、.

示例代码

python 复制代码
import argparse
import time

import numpy as np

import robosuite as suite
from robosuite import load_composite_controller_config
from robosuite.controllers.composite.composite_controller import WholeBody
from robosuite.wrappers import VisualizationWrapper

if __name__ == "__main__":

    parser = argparse.ArgumentParser()
    parser.add_argument("--environment", type=str, default="Lift")  # 环境名称
    parser.add_argument("--robots", nargs="+", type=str, default="Panda", help="使用的机器人")  # 机器人名称
    parser.add_argument(
        "--config", type=str, default="default", help="指定环境配置(如果需要)"
    )  # 环境配置
    parser.add_argument("--arm", type=str, default="right", help="控制的臂(例如双臂)'right' 或 'left'")  # 控制的臂
    parser.add_argument("--switch-on-grasp", action="store_true", help="在抓手动作时切换抓手控制")  # 抓手切换
    parser.add_argument("--toggle-camera-on-grasp", action="store_true", help="在抓手动作时切换相机角度")  # 相机切换
    parser.add_argument(
        "--controller",
        type=str,
        default=None,
        help="选择控制器。可以是通用名称(例如 'BASIC' 或 'WHOLE_BODY_MINK_IK')或 json 文件(参见 robosuite/controllers/config 示例)或 None(使用机器人的默认控制器(如果存在))",
    )  # 控制器选择
    parser.add_argument("--device", type=str, default="keyboard")  # 输入设备
    parser.add_argument("--pos-sensitivity", type=float, default=1.0, help="位置输入的缩放比例")  # 位置灵敏度
    parser.add_argument("--rot-sensitivity", type=float, default=1.0, help="旋转输入的缩放比例")  # 旋转灵敏度
    parser.add_argument(
        "--max_fr",
        default=20,
        type=int,
        help="当模拟运行速度超过指定帧率时暂停;20 fps 为实时。",
    )  # 最大帧率

    args = parser.parse_args()

    # 加载控制器配置
    controller_config = load_composite_controller_config(
        controller=args.controller,
        robot=args.robots[0],
    )

    # 创建参数配置
    config = {
        "env_name": args.environment,
        "robots": args.robots,
        "controller_configs": controller_config,
    }

    # 检查是否使用多臂环境,并设置环境配置
    if "TwoArm" in args.environment:
        config["env_configuration"] = args.config
    else:
        args.config = None

    # 创建环境
    env = suite.make(
        **config,
        has_renderer=True,
        has_offscreen_renderer=False,
        render_camera="agentview",
        ignore_done=True,
        use_camera_obs=False,
        reward_shaping=True,
        control_freq=20,
        hard_reset=False,
    )

    # 使用可视化包装器包装环境
    env = VisualizationWrapper(env, indicator_configs=None)

    # 设置数字打印选项
    np.set_printoptions(formatter={"float": lambda x: "{0:0.3f}".format(x)})

    # 初始化设备
    if args.device == "keyboard":
        from robosuite.devices import Keyboard

        device = Keyboard(env=env, pos_sensitivity=args.pos_sensitivity, rot_sensitivity=args.rot_sensitivity)
        env.viewer.add_keypress_callback(device.on_press)
    elif args.device == "spacemouse":
        from robosuite.devices import SpaceMouse

        device = SpaceMouse(env=env, pos_sensitivity=args.pos_sensitivity, rot_sensitivity=args.rot_sensitivity)
    elif args.device == "mjgui":
        from robosuite.devices.mjgui import MJGUI

        device = MJGUI(env=env)
    else:
        raise Exception("无效的设备选择:请选择 'keyboard' 或 'spacemouse'。")

    while True:
        # 重置环境
        obs = env.reset()

        # 设置渲染
        cam_id = 0
        num_cam = len(env.sim.model.camera_names)
        env.render()

        # 初始化在重置之间需要维护的变量
        last_grasp = 0

        # 初始化设备控制
        device.start_control()
        all_prev_gripper_actions = [
            {
                f"{robot_arm}_gripper": np.repeat([0], robot.gripper[robot_arm].dof)
                for robot_arm in robot.arms
                if robot.gripper[robot_arm].dof > 0
            }
            for robot in env.robots
        ]

        # 循环直到从输入中获得重置或任务完成
        while True:
            start = time.time()

            # 设置活动机器人
            active_robot = env.robots[device.active_robot]

            # 获取最新的动作
            input_ac_dict = device.input2action()

            # 如果动作为空,则这是一个重置,应该退出
            if input_ac_dict is None:
                break

            from copy import deepcopy

            action_dict = deepcopy(input_ac_dict)  # {}
            # 设置臂动作
            for arm in active_robot.arms:
                if isinstance(active_robot.composite_controller, WholeBody):  # 输入类型传递给关节动作策略
                    controller_input_type = active_robot.composite_controller.joint_action_policy.input_type
                else:
                    controller_input_type = active_robot.part_controllers[arm].input_type

                if controller_input_type == "delta":
                    action_dict[arm] = input_ac_dict[f"{arm}_delta"]
                elif controller_input_type == "absolute":
                    action_dict[arm] = input_ac_dict[f"{arm}_abs"]
                else:
                    raise ValueError

            # 维护每个机器人的抓手状态,但只更新活动机器人的动作
            env_action = [robot.create_action_vector(all_prev_gripper_actions[i]) for i, robot in enumerate(env.robots)]
            env_action[device.active_robot] = active_robot.create_action_vector(action_dict)
            env_action = np.concatenate(env_action)
            for gripper_ac in all_prev_gripper_actions[device.active_robot]:
                all_prev_gripper_actions[device.active_robot][gripper_ac] = action_dict[gripper_ac]

            env.step(env_action)
            env.render()

            # 如果必要,限制帧率
            if args.max_fr is not None:
                elapsed = time.time() - start
                diff = 1 / args.max_fr - elapsed
                if diff > 0:
                    time.sleep(diff)

代码关键要点:

  1. 输入设备

    • 支持键盘和 SpaceMouse 两种输入设备。

    • 键盘提供 6 自由度(6-DoF)控制命令,通过按键实现。

    • SpaceMouse 提供 6 自由度(6-DoF)控制命令,通过鼠标移动实现。

  2. 控制器选择

    • 可以选择逆运动学控制器(ik)或操作空间控制器(osc)。

    • ik 的旋转输入相对于末端执行器坐标系,osc 的旋转输入相对于全局坐标系(即:静态/相机坐标系)。

  3. 环境配置

    • 支持单臂和双臂环境。

    • 双臂环境可以配置为平行(parallel)或相对(opposed)。

    • 可以选择控制的臂(right 或 left)。

  4. 设备灵敏度 :通过 --pos_sensitivity--rot_sensitivity 参数调整位置和旋转输入的灵敏度。

  5. 主循环

    • 通过设备获取用户输入,转换为机器人动作。

    • 使用 env.step 执行动作并渲染环境。

    • 限制帧率以确保实时运行。

备注信息:

python 复制代码
***使用以下参数选择环境特定设置***

    --environment:要执行的任务,例如:"Lift"、"TwoArmPegInHole"、"NutAssembly" 等。

    --robots:执行任务的机器人。可以是以下之一:
        {"Panda", "Sawyer", "IIWA", "Jaco", "Kinova3", "UR5e", "Baxter"}。
        注意,环境包含合理性检查,"TwoArm..." 环境只接受两个机器人名称的元组或一个双臂机器人名称,
        其他环境只接受一个单臂机器人名称。

    --config:仅适用于 "TwoArm..." 环境。指定任务所需的机器人配置。选项有 {"parallel" 和 "opposed"}

        - "parallel":设置环境,使两个机器人并排站立,面向同一方向。
            需要在 --robots 参数中指定两个机器人名称的元组。

        - "opposed":设置环境,使两个机器人相对站立,面向彼此。
            需要在 --robots 参数中指定两个机器人名称的元组。

    --arm:仅适用于 "TwoArm..." 环境。指定要控制的多个臂中的哪一个。
        其他(被动)臂将保持静止。选项有 {"right", "left"}(从机器人面向观众的方向看)

    --switch-on-grasp:仅适用于 "TwoArm..." 环境。如果启用,每次按下抓手输入时将切换当前控制的臂。

    --toggle-camera-on-grasp:如果启用,抓手输入将切换可用的相机角度。

示例:

    对于普通单臂环境:
        $ python demo_device_control.py --environment PickPlaceCan --robots Sawyer --controller osc

    对于双臂双臂环境:
        $ python demo_device_control.py --environment TwoArmLift --robots Baxter --config bimanual --arm left --controller osc

    对于双臂多单臂机器人环境:
        $ python demo_device_control.py --environment TwoArmLift --robots Sawyer Sawyer --config parallel --controller osc

2、选择机器人夹抓

涉及的关键点概括

  1. 整体流程

    • 遍历所有可用的抓手类型,并通过 gripper_types 参数将它们应用到环境中。

    • 在每个环境中运行一个随机策略,模拟抓手的操作。

  2. 主要功能

    • suite.make:用于创建模拟环境,配置环境参数(如机器人型号、抓手类型、渲染选项等)。

    • 动作空间 :通过 env.action_spec 获取动作的上下界,并生成随机动作。

    • 渲染 :通过 env.render() 将模拟动画显示在窗口中。

    • 帧率限制:通过时间计算确保模拟的帧率保持在指定范围内,防止运行过于流畅或迟钝。

  3. 技术细节

    • robosuite.ALL_GRIPPERS 包含了所有可用的抓手类型,程序会逐个测试这些抓手。

    • control_freq=50 参数定义了控制频率,确保模拟的帧率足够高。

    • done 标志用于检测任务是否完成(例如:物体被成功抬起)。

示例代码

python 复制代码
import time
import numpy as np
import robosuite as suite
from robosuite import ALL_GRIPPERS

MAX_FR = 25  # 模拟中运行的最大帧率

if __name__ == "__main__":

    for gripper in ALL_GRIPPERS:

        # 通知用户正在使用哪种抓手
        print(f"使用抓手 {gripper}...")

        # 创建环境并使用选定的抓手类型
        env = suite.make(
            "Lift",
            robots="Panda",
            gripper_types=gripper,
            has_renderer=True,  # 确保我们可以在屏幕上渲染
            has_offscreen_renderer=False,  # 不需要离屏渲染,因为我们没有使用像素观察
            use_camera_obs=False,  # 不使用像素观察
            control_freq=50,  # 控制应该足够快,这样模拟看起来会更流畅
            camera_names="frontview",
        )

        # 重置环境
        env.reset()

        # 获取动作范围
        low, high = env.action_spec

        # 运行随机策略
        for t in range(300):
            start = time.time()
            env.render()  # 渲染环境
            action = np.random.uniform(low, high)  # 随机动作
            observation, reward, done, info = env.step(action)  # 执行动作
            if done:
                print("Episode 在 {} 个时间步后结束".format(t + 1))
                break

            # 如果需要,限制帧率
            elapsed = time.time() - start
            diff = 1 / MAX_FR - elapsed
            if diff > 0:
                time.sleep(diff)

        # 关闭窗口
        env.close()

3、夹抓控制

  • 抓手控制: 抓手可以在设定的高度范围内移动,并通过开合手指抓取物体。

  • 物体交互: 模拟物体与抓手的接触,监测接触的物理信息(如摩擦力、法向量等)。

  • 地面检测: 避免物体与地面的重复检测。

  • 视觉呈现: 使用 OpenCV 渲染模拟动画,展示抓手和物体的交互过程。

运行效果:

自动切换不同夹抓:

通过上面的演示,最终我们选择合适抓取当前物体的夹抓~

示例代码:

python 复制代码
import xml.etree.ElementTree as ET

from robosuite.models import MujocoWorldBase
from robosuite.models.arenas.table_arena import TableArena
from robosuite.models.grippers import PandaGripper, RethinkGripper
from robosuite.models.objects import BoxObject
from robosuite.utils import OpenCVRenderer
from robosuite.utils.binding_utils import MjRenderContextOffscreen, MjSim
from robosuite.utils.mjcf_utils import new_actuator, new_joint

if __name__ == "__main__":

    # 创建空的世界
    world = MujocoWorldBase()

    # 添加桌子
    arena = TableArena(table_full_size=(0.4, 0.4, 0.05), table_offset=(0, 0, 1.1), has_legs=False)
    world.merge(arena)

    # 添加抓手
    gripper = RethinkGripper()
    # 创建一个新的身体,用滑动关节连接抓手
    gripper_body = ET.Element("body", name="gripper_base")
    gripper_body.set("pos", "0 0 1.3")  # 设置抓手位置
    gripper_body.set("quat", "0 0 1 0")  # 翻转 z 轴
    gripper_body.append(new_joint(name="gripper_z_joint", type="slide", axis="0 0 1", damping="50"))  # 添加滑动关节
    # 将抓手基座添加到世界中
    world.worldbody.append(gripper_body)
    # 将抓手合并进抓手基座
    world.merge(gripper, merge_body="gripper_base")
    # 添加执行器以控制滑动关节
    world.actuator.append(new_actuator(joint="gripper_z_joint", act_type="position", name="gripper_z", kp="500"))

    # 添加一个可抓取的物体
    mujoco_object = BoxObject(
        name="box", size=[0.02, 0.02, 0.02], rgba=[1, 0, 0, 1], friction=[1, 0.005, 0.0001]
    ).get_obj()
    # 设置物体位置
    mujoco_object.set("pos", "0 0 1.11")
    # 将物体添加到世界
    world.worldbody.append(mujoco_object)

    # 添加 x 轴和 y 轴的参考物(视觉辅助)
    x_ref = BoxObject(
        name="x_ref", size=[0.01, 0.01, 0.01], rgba=[0, 1, 0, 1], obj_type="visual", joints=None
    ).get_obj()
    x_ref.set("pos", "0.2 0 1.105")
    world.worldbody.append(x_ref)
    y_ref = BoxObject(
        name="y_ref", size=[0.01, 0.01, 0.01], rgba=[0, 0, 1, 1], obj_type="visual", joints=None
    ).get_obj()
    y_ref.set("pos", "0 0.2 1.105")
    world.worldbody.append(y_ref)

    # 启动模拟
    model = world.get_model(mode="mujoco")

    sim = MjSim(model)
    viewer = OpenCVRenderer(sim)
    render_context = MjRenderContextOffscreen(sim, device_id=-1)
    sim.add_render_context(render_context)

    sim_state = sim.get_state()

    # 用于重力补偿
    gravity_corrected = ["gripper_z_joint"]
    _ref_joint_vel_indexes = [sim.model.get_joint_qvel_addr(x) for x in gravity_corrected]

    # 设置抓手参数
    gripper_z_id = sim.model.actuator_name2id("gripper_z")
    gripper_z_low = 0.07  # 抓手低位置
    gripper_z_high = -0.02  # 抓手高位置
    gripper_z_is_low = False  # 抓手是否处于低位置

    gripper_jaw_ids = [sim.model.actuator_name2id(x) for x in gripper.actuators]
    gripper_open = [-0.0115, 0.0115]  # 抓手打开时的关节角度
    gripper_closed = [0.020833, -0.020833]  # 抓手关闭时的关节角度
    gripper_is_closed = True  # 抓手是否关闭

    # 硬编码的抓手轨迹序列
    seq = [(False, False), (True, False), (True, True), (False, True)]

    sim.set_state(sim_state)
    step = 0
    T = 500  # 每隔 T 步循环轨迹序列
    while True:
        if step % 100 == 0:
            print("step: {}".format(step))

            # 获取接触信息
            for contact in sim.data.contact[0 : sim.data.ncon]:
                geom_name1 = sim.model.geom_id2name(contact.geom1)
                geom_name2 = sim.model.geom_id2name(contact.geom2)
                if geom_name1 == "floor" and geom_name2 == "floor":
                    continue

                print("geom1: {}, geom2: {}".format(geom_name1, geom_name2))
                print("contact id {}".format(id(contact)))
                print("friction: {}".format(contact.friction))
                print("normal: {}".format(contact.frame[0:3]))

        # 循环抓手轨迹序列
        if step % T == 0:
            plan = seq[int(step / T) % len(seq)]
            gripper_z_is_low, gripper_is_closed = plan
            print("changing plan: gripper low: {}, gripper closed {}".format(gripper_z_is_low, gripper_is_closed))

        # 控制抓手
        if gripper_z_is_low:
            sim.data.ctrl[gripper_z_id] = gripper_z_low  # 设置抓手到低位置
        else:
            sim.data.ctrl[gripper_z_id] = gripper_z_high  # 设置抓手到高位置
        if gripper_is_closed:
            sim.data.ctrl[gripper_jaw_ids] = gripper_closed  # 关闭抓手
        else:
            sim.data.ctrl[gripper_jaw_ids] = gripper_open  # 打开抓手

        # 更新模拟
        sim.step()
        sim.data.qfrc_applied[_ref_joint_vel_indexes] = sim.data.qfrc_bias[_ref_joint_vel_indexes]
        viewer.render()  # 渲染模拟动画
        step += 1

代码解析:

  1. MujocoWorldBaseMujocoSim:

    • MujocoWorldBase 用于创建一个Mujoco模拟世界的基础。

    • MujocoSim 则是负责运行穆乔科模拟的核心类。

  2. 抓手的添加和控制:

    • 使用 RethinkGripper 创建抓手模型。

    • 通过定义 gripper_z_joint 和对应的执行器 new_actuator,实现抓手的高度控制。

  3. 物体的添加:

    • 使用 BoxObject 定义了一个红色的立方体小物体,用于抓取演示。

    • 物体的物理属性(如摩擦力)通过 friction 参数设置。

  4. 视觉辅助: 通过添加绿色和蓝色的方块作为参考,方便观察物体的位置和方向。

  5. 模拟控制 : 使用 sim.step() 更新模拟状态。使用 viewer.render() 渲染模拟图像到窗口。

  6. 接触信息 : 通过 sim.data.contact 获取接触信息,可用于调试和分析抓手与物体的交互情况。

运行效果:

抓起物体:

4、记录轨迹数据并回放

  • 数据收集:通过随机策略生成轨迹数据并保存。

  • 数据回放:从保存的数据中加载轨迹并回放。

  • 环境包装 :使用 DataCollectionWrapper 包装环境,支持数据收集功能。

  • 实时渲染:在数据收集和回放过程中实时渲染环境动画。

示例代码:

python 复制代码
import argparse
import os
import time
from glob import glob

import numpy as np

import robosuite as suite
from robosuite.wrappers import DataCollectionWrapper


def collect_random_trajectory(env, timesteps=1000, max_fr=None):
    """运行随机策略以收集轨迹数据。

    轨迹数据以 npz 格式保存到文件中。
    修改 DataCollectionWrapper 包装器以添加新字段或更改数据格式。

    参数:
        env (MujocoEnv): 用于收集轨迹的环境实例
        timesteps (int): 每个轨迹运行的环境时间步数
        max_fr (int): 如果指定,当模拟运行速度超过最大帧率时暂停
    """
    env.reset()  # 重置环境
    dof = env.action_dim  # 获取动作维度

    for t in range(timesteps):
        start = time.time()
        action = np.random.randn(dof)  # 生成随机动作
        env.step(action)  # 执行动作
        env.render()  # 渲染环境
        if t % 100 == 0:
            print(t)  # 每 100 步打印一次进度

        # 如果指定了最大帧率,则限制帧率
        if max_fr is not None:
            elapsed = time.time() - start
            diff = 1 / max_fr - elapsed
            if diff > 0:
                time.sleep(diff)


def playback_trajectory(env, ep_dir, max_fr=None):
    """回放某一集的数据。

    参数:
        env (MujocoEnv): 用于回放轨迹的环境实例
        ep_dir (str): 包含某一集数据的目录路径
    """
    # 从 XML 文件重新加载模型
    xml_path = os.path.join(ep_dir, "model.xml")
    with open(xml_path, "r") as f:
        env.reset_from_xml_string(f.read())  # 从 XML 字符串重置环境

    state_paths = os.path.join(ep_dir, "state_*.npz")  # 获取状态文件路径

    # 逐个加载状态文件并回放
    t = 0
    for state_file in sorted(glob(state_paths)):
        print(state_file)
        dic = np.load(state_file)  # 加载状态文件
        states = dic["states"]  # 获取状态数据
        for state in states:
            start = time.time()
            env.sim.set_state_from_flattened(state)  # 设置模拟状态
            env.sim.forward()  # 更新模拟
            env.viewer.update()  # 更新视图
            env.render()  # 渲染环境
            t += 1
            if t % 100 == 0:
                print(t)  # 每 100 步打印一次进度

            # 如果指定了最大帧率,则限制帧率
            if max_fr is not None:
                elapsed = time.time() - start
                diff = 1 / max_fr - elapsed
                if diff > 0:
                    time.sleep(diff)
    env.close()  # 关闭环境


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--environment", type=str, default="Door")  # 环境名称
    parser.add_argument("--robots", nargs="+", type=str, default="Panda", help="使用的机器人")  # 机器人名称
    parser.add_argument("--directory", type=str, default="/tmp/")  # 数据保存目录
    parser.add_argument("--timesteps", type=int, default=1000)  # 时间步数
    parser.add_argument(
        "--max_fr",
        default=20,
        type=int,
        help="当模拟运行速度超过指定帧率时暂停;20 fps 为实时。",
    )  # 最大帧率
    args = parser.parse_args()

    # 创建原始环境
    env = suite.make(
        args.environment,
        robots=args.robots,
        ignore_done=True,
        use_camera_obs=False,
        has_renderer=True,
        has_offscreen_renderer=False,
        control_freq=20,
    )
    data_directory = args.directory  # 数据保存目录

    # 使用数据收集包装器包装环境
    env = DataCollectionWrapper(env, data_directory)

    # 测试多次调用 env.reset 是否会创建多个目录
    env.reset()
    env.reset()
    env.reset()

    # 收集一些数据
    print("正在收集随机数据...")
    collect_random_trajectory(env, timesteps=args.timesteps, max_fr=args.max_fr)

    # 回放数据
    _ = input("按下任意键开始回放...")
    print("正在回放数据...")
    data_directory = env.ep_directory  # 获取当前集的目录
    playback_trajectory(env, data_directory, args.max_fr)

代码分析:

  1. DataCollectionWrapper 包装器 :用于包装环境,以便在运行过程中收集数据。收集的数据以 npz 格式保存到指定目录中。

  2. 数据收集:使用随机策略生成动作,运行环境并收集轨迹数据。数据包括环境状态、动作、观察值等。

  3. 数据回放 :从保存的数据中加载状态,并逐帧回放。通过 env.sim.set_state_from_flattened(state) 设置模拟状态。

  4. 帧率控制 :如果指定了最大帧率 (max_fr),则通过 time.sleep 控制模拟速度,避免运行过快。

  5. 数据保存和加载:数据保存在指定目录中,包括 XML 模型文件和状态文件。回放时从这些文件中加载数据并恢复环境状态。

运行效果:

打印信息:

python 复制代码
DataCollectionWrapper: making folder at /tmp/ep_1740881381_0772326
0
100
200
300
400
500
600
700
800
900
按下任意键开始回放...
正在回放数据...
/tmp/ep_1740881381_0772326/state_1740881386_010901.npz
100
/tmp/ep_1740881381_0772326/state_1740881391_0270681.npz
200
/tmp/ep_1740881381_0772326/state_1740881396_0425832.npz
300
/tmp/ep_1740881381_0772326/state_1740881401_0576134.npz
400
/tmp/ep_1740881381_0772326/state_1740881406_0732286.npz
500
/tmp/ep_1740881381_0772326/state_1740881411_0889266.npz
600
/tmp/ep_1740881381_0772326/state_1740881416_1048322.npz
700
/tmp/ep_1740881381_0772326/state_1740881421_1204755.npz
800
/tmp/ep_1740881381_0772326/state_1740881426_135585.npz
900
/tmp/ep_1740881381_0772326/state_1740881431_1502776.npz
1000
Xlib:  extension "NV-GLX" missing on display ":1".

5、多种机器人任务执行

  • 环境自定义:支持选择不同的环境和机器人组合,适应多种模拟场景。

  • 领域随机化:通过随机化环境参数,提高机器人在不同条件下的适应能力。

  • 可视化:实时渲染模拟过程,方便观察机器人的行为和环境交互。

示例代码:

python 复制代码
# 导入移动机器人模块
from robosuite.robots import MobileRobot

# 导入 RoboSuite 的输入工具
from robosuite.utils.input_utils import *
import time

# 定义最大帧率,用于控制模拟的运行速度
MAX_FR = 25

# 主程序入口
if __name__ == "__main__":
    options = {}  # 保存创建环境的选项

    # 欢迎信息
    print("欢迎使用 RoboSuite v{}!".format(suite.__version__))
    print(suite.__logo__)  # 打印 RoboSuite 的标志

    # 用户选择环境
    options["env_name"] = choose_environment()

    # 如果是多臂环境,默认选择机器人
    if "TwoArm" in options["env_name"]:
        options["env_configuration"] = choose_multi_arm_config()

        if options["env_configuration"] == "single-robot":
            options["robots"] = choose_robots(
                exclude_bimanual=False,  # 不排除双臂机器人
                use_humanoids=True,      # 允许使用人形机器人
                exclude_single_arm=True  # 排除单臂机器人
            )
        else:
            options["robots"] = []
            # 循环选择两个机器人
            for i in range(2):
                print("请选择机器人 {}...\n".format(i + 1))
                options["robots"].append(
                    choose_robots(exclude_bimanual=False, use_humanoids=True)
                )
    # 如果是人形机器人环境,选择人形机器人
    elif "Humanoid" in options["env_name"]:
        options["robots"] = choose_robots(use_humanoids=True)
    else:
        options["robots"] = choose_robots(
            exclude_bimanual=False,  # 不排除双臂机器人
            use_humanoids=True       # 允许使用人形机器人
        )

    # 初始化环境
    env = suite.make(
        **options,            # 使用用户选择的选项
        has_renderer=True,    # 启用视觉渲染
        has_offscreen_renderer=False,  # 不启用离屏渲染
        ignore_done=True,     # 忽略任务完成信号
        use_camera_obs=False, # 不使用相机观测
        control_freq=20,      # 控制频率为 20Hz
    )
    env.reset()  # 重置环境

    env.viewer.set_camera(camera_id=0)  # 设置摄像头

    # 禁用移动机器人的腿部和底座控制
    for robot in env.robots:
        if isinstance(robot, MobileRobot):
            robot.enable_parts(legs=False, base=False)

    # 开始渲染环境
    for i in range(10000):
        start = time.time()  # 记录当前时间

        # 随机生成动作并执行
        action = np.random.randn(*env.action_spec[0].shape)
        obs, reward, done, _ = env.step(action)
        env.render()  # 渲染环境

        # 控制帧率
        elapsed = time.time() - start
        diff = 1 / MAX_FR - elapsed
        if diff > 0:
            time.sleep(diff)  # 确保帧率在限制范围内

运行代码后,首先选择"环境",也就是执行任务的种类

Here is a list of environments in the suite:

0\] Door \[1\] Lift \[2\] NutAssembly \[3\] NutAssemblyRound \[4\] NutAssemblySingle \[5\] NutAssemblySquare \[6\] PickPlace \[7\] PickPlaceBread \[8\] PickPlaceCan \[9\] PickPlaceCereal \[10\] PickPlaceMilk \[11\] PickPlaceSingle \[12\] Stack \[13\] ToolHang \[14\] TwoArmHandover \[15\] TwoArmLift \[16\] TwoArmPegInHole \[17\] TwoArmTransport \[18\] Wipe Choose an environment to run (enter a number from 0 to 18):

然后选择执行的机器人类型

Here is a list of available robots:

0\] Baxter \[1\] GR1ArmsOnly \[2\] IIWA \[3\] Jaco \[4\] Kinova3 \[5\] Panda \[6\] Sawyer \[7\] SpotWithArmFloating \[8\] Tiago \[9\] UR5e Choose a robot (enter a number from 0 to 9):

运行效果,第二个机器人选择7(SpotWithArmFloating)

相关文章推荐:

机器人学习模拟框架 robosuite 支持强化学习和模仿学习 (1) 快速入门_机械臂模仿学习入门-CSDN博客

机器人学习模拟框架 robosuite (2)支持多种机器人、夹抓和底座 工作流程-CSDN博客

分享完成~

相关推荐
Olivia0514051436 分钟前
Voohu:音频变压器的屏蔽接地技术对50Hz工频噪声抑制的影响
网络·机器人·信息与通信
xp_fangfei2 小时前
通过 Marker(视觉标记)获取机器人位姿
opencv·机器人
机器觉醒时代3 小时前
英伟达GR00T N系列四代模型演进解析
人工智能·机器人·具身智能·vla模型
爆打维c4 小时前
详解 ROS计算图资源的命名与解析
机器人
Alphapeople4 小时前
夸父机器人使用案例
机器人
沫儿笙4 小时前
机器人焊接混合气智能节气装置
人工智能·机器人
红色星际5 小时前
进军具身机器人和Robotaxi的智驾公司
大数据·人工智能·机器人
云上码厂5 小时前
ANSYS Electronics 2025 R2(64 位):电磁与多物理场仿真全栈解决方案详解
仿真
kobesdu5 小时前
连接大模型与物理机器人-RoboNeuron让机器人真正“听懂人话”
机器人·开源·ros·人形机器人
yzk_20175 小时前
OpenClaw 完整部署指南:安装 + 三大 Coding Plan 配置 + CC Switch + 飞书机器人
arcgis·机器人·飞书