機器人學習模擬框架 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博客

?分享完成~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896873.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896873.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896873.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

可終身授權的外國工具,不限次數使用!PDF轉CAD的軟件

最近有不少朋友問我有沒有好用的CAD轉換工具,今天就來給大家分享兩款超實用的小軟件,希望能幫到大家。 第一款軟件是一款國外開發的,它專門用來把PDF文件轉換成CAD格式,特別方便。 這款軟件的操作非常簡單,打開后無需安…

Ubuntu系統上部署Node.js項目的完整流程

以下是在Ubuntu系統上部署Node.js項目的完整流程,分為系統初始化、環境配置、項目部署三個部分: 一、系統初始化 & 環境準備 bash # 1. 更新系統軟件包 sudo apt update && sudo apt upgrade -y# 2. 安裝基礎工具 sudo apt install -y buil…

Android內存優化指南:從數據結構到5R法則的全面策略

目錄 一、APP 內存限制 二、內存的三大問題 2.1、內存抖動(Memory Churn) 2.1.1 頻繁創建短生命周期對象 2.1.2 系統API或第三方庫的不合理使用 2.1.3 Handler使用不當 2.2、內存泄漏(Memory Leak) 2.2.1 靜態變量持有Activity或Context引用 2.2.2 未取消的回調或…

ffmpeg源碼編譯支持cuda

1.安裝cuda CUDA Toolkit 11.3 Downloads | NVIDIA Developer 在選擇組件的時候,將CUDA中的Nsight VSE和Visual Studio Integration取消勾選 不然會安裝失敗 2.編譯ffmpeg 把cuda編譯宏定義開啟,再編譯avcodec 3.編譯livavutil報錯struct "Cuda…

Git強制覆蓋分支:將任意分支完全恢復為main分支內容

Git強制覆蓋分支:將任意分支完全恢復為main分支內容 場景背景完整操作步驟一、前置準備二、操作流程步驟 1:更新本地 main 分支步驟 2:強制重置目標分支步驟 3:強制推送至遠程倉庫 三、操作示意圖 關鍵風險提示(必讀&a…

【Java反序列化測試】

Java反序列化測試 1. 識別反序列化入口點2. 構造探測Payload3. 發送Payload并觀察結果4. 繞過可能的防護5. 自動化工具注意事項總結 Java反序列化測試: 1. 識別反序列化入口點 常見入口: HTTP請求參數(如POST數據、Cookie、Headers&#xff…

golang的io

https://www.bilibili.com/list/BV1gx4y1r7xb 1. 原生io包 io包是Go語言標準庫中底層的I/O接口層,定義了通用的讀寫規則和錯誤處理邏輯。每次讀寫都是直接調用底層系統 I/O,每次讀取1字節,系統調用次數多。適用于小數據量、實時性要求高。io…

【北京迅為】iTOP-RK3568OpenHarmony系統南向驅動開發-第4章 UART基礎知識

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工藝,搭載一顆四核Cortex-A55處理器和Mali G52 2EE 圖形處理器。RK3568 支持4K 解碼和 1080P 編碼,支持SATA/PCIE/USB3.0 外圍接口。RK3568內置獨立NPU,可用于輕量級人工…

【計算機網絡入門】初學計算機網絡(十)(重要)

目錄 1. 網絡層的作用 2. IPV4 2.1 IP 數據報格式 2.2 IP地址分類方案 2.3 數據的轉發 2.4 特殊用途的IP地址 3. 子網劃分和子網掩碼 3.1 子網劃分 3.2 子網掩碼 1. 網絡層的作用 按照教學五層模型,應用層、傳輸層、網絡層、數據鏈路層、物理層&#xff…

機器學習(五)

一,多類(Multiclass) 多類是指輸出不止有兩個輸出標簽,想要對多個種類進行分類。 Softmax回歸算法: Softmax回歸算法是Logistic回歸在多類問題上的推廣,和線性回歸一樣,將輸入的特征與權重進行…

基于 Vue 和 SSM 的前后端分離項目實戰:登錄與注冊功能實現

文章目錄 前言項目概述前端部分(Vue)1. 項目初始化2. 頁面布局Login.vueRegister.vue 3. 路由配置4. 主組件 后端部分(SSM)1. 項目結構2. 數據庫設計3. MyBatis 配置4. DAO 層5. Service 層6. Controller 層7. 配置文件8. Spring …

Windows安裝nvm【超詳細圖解】

目錄 前言 一、NVM下載 方式一:官網下載 方式二:GitHub 下載 二、NVM安裝 鏡像源配置 三、Node安裝 四、環境變量配置 前言 NVM(Node Version Manager)是一個命令行工具,用于在一臺計算機上輕松管理和切換多…

KVM虛擬機磁盤創建探究-2

使用 virt-install 命令自動創建磁盤鏡像和使用 qemu-img 手動創建磁盤鏡像,在磁盤鏡像本身格式和基本功能上是一致的,但在一些特性如初始占用磁盤空間、創建時的可配置性等方面存在區別,下面以 QCOW2 格式磁盤鏡像為例進行詳細說明。 初始占…

京準電鐘:NTP校時服務器于安防監控系統應用方案

京準電鐘:NTP校時服務器于安防監控系統應用方案 京準電鐘:NTP校時服務器于安防監控系統應用方案 NTP校時服務器在安防監控系統中的應用方案主要通過高精度時間同步技術,解決設備間時間差異問題,確保日志、錄像等數據的時間一致性…

遞歸遍歷目錄 和 普通文件的復制 [Java EE]

遞歸遍歷目錄 首先 先列出當前目錄所包含的內容 File[] files currentDir.listFiles();if (files null || files.length 0) {// 若是空目錄或非法目錄, 則直接返回return;} 然后 遍歷列出的文件, 分情況兩種討論 for (File f: files) {// 加個日志, 方便查看程序執行情…

NO.19十六屆藍橋杯模擬賽第三期上

1 如果一個數 p 是個質數&#xff0c;同時又是整數 a 的約數&#xff0c;則 p 稱為 a 的一個質因數。 請問&#xff0c; 2024 的最大的質因數是多少&#xff1f; 答&#xff1a;23 #include <bits/stdc.h> using namespace std;int main() {ios::sync_with_stdio(false)…

Linux網絡_應用層自定義協議與序列化_守護進程

一.協議 協議是一種 "約定". socket api 的接口, 在讀寫數據時, 都是按 "字符串" 的方式來發送接 收的. 如果我們要傳輸一些 "結構化的數據" 怎么辦呢? 其實&#xff0c;協議就是雙方約定好的結構化的數據 像下面&#xff0c;兩端都知道數據結構…

SQL命令詳解之多表查詢(連接查詢)

目錄 1 簡介 2 內連接查詢 2.1 內連接語法 2.2 內連接練習 3 外連接查詢 3.1 外連接語法 3.2 外連接練習 4 總結 1 簡介 連接的本質就是把各個表中的記錄都取出來依次匹配的組合加入結果集并返回給用戶。我們把 t1 和 t2 兩個表連接起來的過程如下圖所示&#xff1a; …

001-碼云操作

碼云操作 一、配置公鑰1.官網地址1.進入 git bash2.查看生成的公鑰3.設置到 Gitee4.測試 二、初始化一個項目1.新建倉庫 一、配置公鑰 方便后續提交代碼不用填寫密碼 1.官網地址 官網地址&#xff1a;https://gitee.com/Git碼云教程&#xff1a;https://gitee.com/help/arti…

30.[前端開發-JavaScript基礎]Day07-數組Array-高階函數-日期Date-DOM

JavaScript的DOM操作 &#xff08;一&#xff09; 1 什么是DOM&#xff1f; 認識DOM和BOM 深入理解DOM 2 認識DOM Tree DOM Tree的理解 3 DOM的整體結構 DOM的學習順序 DOM的繼承關系圖 document對象 4 節點、元素導航 節點&#xff08;Node&#xff09;之間的導航&…