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

机器人学习模拟框架 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、; 、.

示例代码


import argparse
import timeimport numpy as npimport robosuite as suite
from robosuite import load_composite_controller_config
from robosuite.controllers.composite.composite_controller import WholeBody
from robosuite.wrappers import VisualizationWrapperif __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.configelse: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 Keyboarddevice = 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 SpaceMousedevice = SpaceMouse(env=env, pos_sensitivity=args.pos_sensitivity, rot_sensitivity=args.rot_sensitivity)elif args.device == "mjgui":from robosuite.devices.mjgui import MJGUIdevice = MJGUI(env=env)else:raise Exception("无效的设备选择:请选择 'keyboard' 或 'spacemouse'。")while True:# 重置环境obs = env.reset()# 设置渲染cam_id = 0num_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.armsif 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:breakfrom copy import deepcopyaction_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_typeelse:controller_input_type = active_robot.part_controllers[arm].input_typeif 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() - startdiff = 1 / args.max_fr - elapsedif 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 执行动作并渲染环境。

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

备注信息:

***使用以下参数选择环境特定设置***--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 标志用于检测任务是否完成(例如:物体被成功抬起)。

示例代码


import time
import numpy as np
import robosuite as suite
from robosuite import ALL_GRIPPERSMAX_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() - startdiff = 1 / MAX_FR - elapsedif diff > 0:time.sleep(diff)# 关闭窗口env.close()

3、夹抓控制

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

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

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

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

 运行效果:

自动切换不同夹抓:

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

 

示例代码:

import xml.etree.ElementTree as ETfrom 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_jointif __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 = 0T = 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":continueprint("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 = planprint("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 包装环境,支持数据收集功能。

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

示例代码:


import argparse
import os
import time
from glob import globimport numpy as npimport robosuite as suite
from robosuite.wrappers import DataCollectionWrapperdef 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() - startdiff = 1 / max_fr - elapsedif 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 = 0for 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 += 1if t % 100 == 0:print(t)  # 每 100 步打印一次进度# 如果指定了最大帧率,则限制帧率if max_fr is not None:elapsed = time.time() - startdiff = 1 / max_fr - elapsedif 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 模型文件和状态文件。回放时从这些文件中加载数据并恢复环境状态。

运行效果:

打印信息:

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、多种机器人任务执行

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

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

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

示例代码:

# 导入移动机器人模块
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() - startdiff = 1 / MAX_FR - elapsedif 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博客

 分享完成~

相关文章:

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

Robosuite框架是一个用于机器人模拟和控制的强大工具,支持多种类型的机器人。 官方文档:Overview — robosuite 1.5 documentation 开源地址:https://github.com/ARISE-Initiative/robosuite 目录 1、通过键盘或SpaceMouse远程控制机器人…...

玩转python: 几个案例-掌握贪心算法

什么是贪心算法 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法策略。它不从整体最优上加以考虑,只做出在某种意义上的局部最优解。下面我们将通过几个案例…...

腾讯集团软件开发-后台开发方向内推

熟练掌握C/C/Java/Go等其中一门开发语言; TCP/UDP网络协议及相关编程、进程间通讯编程; 专业软件知识,包括算法、操作系统、软件工程、设计模式、数据结构、数据库系统、网络安全等 有一定了解的: 1、Python、Shell、Perl等脚本语…...

哈希碰撞攻防战——深入浅出Map/Set的底层实现

各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连,小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习Map/Set的底层实现 目录 问题一:hash会出现负数?数组越界 一:什么是二叉搜索树&#xff1f…...

深度解析Ant Design Pro 6开发实践

深度解析Ant Design Pro 6全栈开发实践:从架构设计到企业级应用落地 一、Ant Design Pro 6核心特性与生态定位(技术架构分析) 作为Ant Design生态体系的旗舰级企业应用中台框架,Ant Design Pro 6基于以下技术栈实现突破性升级&am…...

用大白话解释基础框架Spring Boot——像“装修套餐”一样简单

SpringBoot是什么(SpringBoot类似装修公司的全包套餐) SpringBoot是Java开发者的“装修神器”,可以快速搭建一个应用系统,不用自己亲自买钉子、水泥和瓷砖(相当于传统的Spring框架的复杂配置),…...

第十三届蓝桥杯大赛软件赛决赛C/C++ 大学 B 组

A 【2022——暴力DP / 优雅背包】-CSDN博客 B 【钟表——类日期问题】-CSDN博客 C 【卡牌——二分】-CSDN博客 D 【最大数字——DFS】-CSDN博客 E 【出差——Dijkstra】-CSDN博客 F 【费用报销——01背包】-CSDN博客 G 【故障——条件概率】-CSDN博客 H 【机房—…...

java后端开发day25--阶段项目(二)

(以下内容全部来自上述课程) 1.美化界面 private void initImage() {//路径分两种://1.绝对路径:从盘符开始写的路径 D:\\aaa\\bbb\\ccc.jpg//2.相对路径:从当前项目开始写的路径 aaa\\bbb\\ccc.jpg//添加图片的时…...

岚图汽车2月销售8013辆,岚图知音硬核引领智能出行

据官方消息,岚图汽车2月销售8013辆,同比增长152%,品牌势能持续提升。其中,岚图知音依靠强大的产品力,且在OTA 2.0之后,其AI大模型逍遥座舱为用户带来全新的出行体验。 业内专业人士表示,“汽车…...

【CSS—前端快速入门】CSS 常用样式

CSS 常用 CSS 样式 1. 前端样式查询网站: MDN Web Docs (mozilla.org) w3school 2. border 2.1 借助 MDN 了解 border 我们借助 MDN 网站来学习 border 样式的使用: 2.2 border 常见属性 保存代码,打开页面: 对于标签不同样式的…...

【软考-架构】1.3、磁盘-输入输出技术-总线

GitHub地址:https://github.com/tyronczt/system_architect 资料&文章更新 文章目录 存储系统💯考试真题输入输出技术💯考试真题第一题第二题 存储系统 寻道时间是指磁头移动到磁道所需的时间; 等待时间为等待读写的扇区转到…...

Linux软连接与时区日期

软连接 使用ln命令创建软连接。 在系统中创建软连接,可以将文件,文件夹连接到其他为止。 类似于Windows系统的快捷方式。 语法:ln -s 参数1 参数2 -s选项,创建软连接。 参数1,被链接的文件或文件夹。 参数2&#xff0…...

(十)Mapbox GL JS 中点击 Marker 时获取与该 Marker 相关的自定义数据的解决办法

在 Mapbox GL JS 中,如果你想在点击 Marker 时获取与该 Marker 相关的自定义数据,可以通过几种方式将数据绑定到 Marker 上,并在点击时获取这些数据。以下是详细的实现方法,包含代码示例和说明。 方法一:使用 JavaScript 对象属性绑定数据 你可以直接将自定义数据绑定到 …...

PyCharm怎么集成DeepSeek

PyCharm怎么集成DeepSeek 在PyCharm中集成DeepSeek等大语言模型(LLM)可以借助一些插件或通过代码调用API的方式实现,以下为你详细介绍两种方法: 方法一:使用JetBrains AI插件(若支持DeepSeek) JetBrains推出了AI插件来集成大语言模型,不过截至2024年7月,官方插件主要…...

(七)消息队列-Kafka 序列化avro(传递)

(七)消息队列-Kafka 序列化avro(传递) 客从远方来,遗我双鲤鱼。呼儿烹鲤鱼,中有尺素书。 ——佚名《饮马长城窟行》 本文已同步CSDN、掘金平台、知乎等多个平台,图片依然保持最初发布的水印&…...

js基础二

JavaScript基础下 1 事件处理 JS 事件(event)是当用户与网页进行交互时发生的事情,例如单机某个链接或按钮、在文本框中输入文本、按下键盘上的某个按键、移动鼠标等等。当事件发生时,您可以使用 JavaScript 中的事件处理程序&a…...

WSBDF レクチア 定义2 引理3 wsbdf的乘子

定义2 引理3 wsbdf的乘子 ここまで 寝みます❓...

Qt之QStateMachine等待

在项目中经常需要等待,我们模拟0-30的数,假如我们其中5, 25的数需要进行等待,等待用户处理完自己事情后,按下按钮继续,找Qt的项目中有一个 QStateMachineqstatemmachine类提供了一个分层有限状态机。 QSta…...

Wireshark 插件开发实战指南

Wireshark 插件开发实战指南 环境搭建流程图 #mermaid-svg-XpNibno7BIyfzNn5 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XpNibno7BIyfzNn5 .error-icon{fill:#552222;}#mermaid-svg-XpNibno7BIyfzNn5 .error-t…...

基于SpringBoot的“青少年心理健康教育网站”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“青少年心理健康教育网站”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体结构图 实体属性图 系统首页界…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...