Orbit 使用指南 03 | 与刚体交互 | Isaac Sim | Omniverse

如是我闻: “在之前的指南中,我们讨论了独立脚本( standalone script)的基本工作原理以及如何在模拟器中生成不同的对象(prims)。在指南03中,我们将展示如何创建并与刚体进行交互。为此,我们使用Orbit中提供的assets.RigidObject类。”

指南03 对应于orbit/source/standalone/tutorials/01_assets目录下的run_rigid_object.py 脚本,让我们先搂一眼完整的代码

# Copyright (c) 2022-2024, The ORBIT Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause"""
This script demonstrates how to create a rigid object and interact with it... code-block:: bash# Usage./orbit.sh -p source/standalone/tutorials/01_assets/run_rigid_object.py"""from __future__ import annotations"""Launch Isaac Sim Simulator first."""import argparsefrom omni.isaac.orbit.app import AppLauncher# add argparse arguments
parser = argparse.ArgumentParser(description="Tutorial on spawning and interacting with a rigid object.")
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args()# launch omniverse app
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app"""Rest everything follows."""import torchimport omni.isaac.core.utils.prims as prim_utilsimport omni.isaac.orbit.sim as sim_utils
import omni.isaac.orbit.utils.math as math_utils
from omni.isaac.orbit.assets import RigidObject, RigidObjectCfg
from omni.isaac.orbit.sim import SimulationContextdef design_scene():"""Designs the scene."""# Ground-planecfg = sim_utils.GroundPlaneCfg()cfg.func("/World/defaultGroundPlane", cfg)# Lightscfg = sim_utils.DomeLightCfg(intensity=2000.0, color=(0.8, 0.8, 0.8))cfg.func("/World/Light", cfg)# Create separate groups called "Origin1", "Origin2", "Origin3"# Each group will have a robot in itorigins = [[0.25, 0.25, 0.0], [-0.25, 0.25, 0.0], [0.25, -0.25, 0.0], [-0.25, -0.25, 0.0]]for i, origin in enumerate(origins):prim_utils.create_prim(f"/World/Origin{i}", "Xform", translation=origin)# Rigid Objectcone_cfg = RigidObjectCfg(prim_path="/World/Origin.*/Cone",spawn=sim_utils.ConeCfg(radius=0.1,height=0.2,rigid_props=sim_utils.RigidBodyPropertiesCfg(),mass_props=sim_utils.MassPropertiesCfg(mass=1.0),collision_props=sim_utils.CollisionPropertiesCfg(),visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0), metallic=0.2),),init_state=RigidObjectCfg.InitialStateCfg(),)cone_object = RigidObject(cfg=cone_cfg)# return the scene informationscene_entities = {"cone": cone_object}return scene_entities, originsdef run_simulator(sim: sim_utils.SimulationContext, entities: dict[str, RigidObject], origins: torch.Tensor):"""Runs the simulation loop."""# Extract scene entities# note: we only do this here for readability. In general, it is better to access the entities directly from#   the dictionary. This dictionary is replaced by the InteractiveScene class in the next tutorial.cone_object = entities["cone"]# Define simulation steppingsim_dt = sim.get_physics_dt()sim_time = 0.0count = 0# Simulate physicswhile simulation_app.is_running():# resetif count % 250 == 0:# reset counterssim_time = 0.0count = 0# reset root stateroot_state = cone_object.data.default_root_state.clone()# sample a random position on a cylinder around the originsroot_state[:, :3] += originsroot_state[:, :3] += math_utils.sample_cylinder(radius=0.1, h_range=(0.25, 0.5), size=cone_object.num_instances, device=cone_object.device)# write root state to simulationcone_object.write_root_state_to_sim(root_state)# reset bufferscone_object.reset()print("----------------------------------------")print("[INFO]: Resetting object state...")# apply sim datacone_object.write_data_to_sim()# perform stepsim.step()# update sim-timesim_time += sim_dtcount += 1# update bufferscone_object.update(sim_dt)# print the root positionif count % 50 == 0:print(f"Root position (in world): {cone_object.data.root_state_w[:, :3]}")def main():"""Main function."""# Load kit helpersim_cfg = sim_utils.SimulationCfg()sim = SimulationContext(sim_cfg)# Set main camerasim.set_camera_view(eye=[1.5, 0.0, 1.0], target=[0.0, 0.0, 0.0])# Design scenescene_entities, scene_origins = design_scene()scene_origins = torch.tensor(scene_origins, device=sim.device)# Play the simulatorsim.reset()# Now we are ready!print("[INFO]: Setup complete...")# Run the simulatorrun_simulator(sim, scene_entities, scene_origins)if __name__ == "__main__":# run the main functionmain()# close sim appsimulation_app.close()

代码解析

在这个脚本中,我们将主函数main分割成两个独立的函数,这两个函数是在模拟器中设置任何模拟的两个主要步骤:

  1. 场景设计:顾名思义,这部分负责将所有图元( prims)添加到场景中。

  2. 模拟运行:这部分负责步进模拟器,与场景中的原始物体进行互动,例如,改变它们的姿态,并对它们应用指令。

区别这两个步骤是必要的,因为第二步只有在第一步完成并且模拟器被重置后才会发生。一旦模拟器被重置(自动播放模拟),新的(启用物理的)原始物体(prims)不应该被添加到场景中,因为这可能会导致意外的行为。然而,可以通过它们各自的句柄(respective handles)与原始物体(prims)进行互动。

场景设计

与前一个指南类似,我们使用地面平面和光源填充场景。此外,我们使用assets.RigidObject类将一个刚体添加到场景中。这个类负责在输入路径处生成原始物体,并初始化它们对应的刚体物理句柄。

在本指南中,我们使用与“生成对象指南”中的刚体圆锥相似的生成配置,创建一个圆锥形的刚体对象。唯一的区别是,现在我们将生成配置包装进assets.RigidObjectCfg类中。这个类包含有关资产生成策略、默认初始状态和其他元信息的信息。当这个类传递给assets.RigidObject类时,它会在播放模拟时生成对象并初始化相应的物理句柄。

作为例子,关于多次生成刚体原始物体,我们创建了它们的父Xform原始物体,/World/Origin{i},这对应于不同的生成位置。当正则表达式/World/Origin*/Cone传递给assets.RigidObject类时,它会在每个/World/Origin{i}位置生成刚体原始物体。例如,如果场景中存在/World/Origin1/World/Origin2,则刚体原始物体分别在位置/World/Origin1/Cone/World/Origin2/Cone处生成。

    # Create separate groups called "Origin1", "Origin2", "Origin3"# Each group will have a robot in itorigins = [[0.25, 0.25, 0.0], [-0.25, 0.25, 0.0], [0.25, -0.25, 0.0], [-0.25, -0.25, 0.0]]for i, origin in enumerate(origins):prim_utils.create_prim(f"/World/Origin{i}", "Xform", translation=origin)# Rigid Objectcone_cfg = RigidObjectCfg(prim_path="/World/Origin.*/Cone",spawn=sim_utils.ConeCfg(radius=0.1,height=0.2,rigid_props=sim_utils.RigidBodyPropertiesCfg(),mass_props=sim_utils.MassPropertiesCfg(mass=1.0),collision_props=sim_utils.CollisionPropertiesCfg(),visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0), metallic=0.2),),init_state=RigidObjectCfg.InitialStateCfg(),)cone_object = RigidObject(cfg=cone_cfg)

由于我们是想与刚体进行互动,我们将这个实体返回给主函数。然后在模拟循环中使用这个实体与刚体进行互动。在后续的指南中,我们将看到使用scene.InteractiveScene类处理多个场景实体的更便捷方式。

    # return the scene informationscene_entities = {"cone": cone_object}return scene_entities, origins

运行模拟循环

我们修改模拟循环已进行与刚体的互动,包括三个步骤

  1. 在固定时间间隔重置模拟状态、
  2. 步进模拟
  3. 以及更新刚体的内部缓冲区。

为了简便一些,我们从场景的字典中提取出刚体的实体,并将其存储在一个变量中。

在固定时间间隔重置模拟状态

为了重置生成的刚体原始物体的模拟状态,我们需要设置它们的姿态和速度。这两者共同定义了生成的刚体对象的根状态。重要的是要注意,这个状态是在模拟世界框架中定义的,而不是它们的父Xform原始物体的框架。这是因为物理引擎只理解世界框架,而不理解父Xform原始物体的框架。因此,在设置之前,我们需要将刚体原始物体的期望状态转换到世界框架中。

我们使用assets.RigidObject.data.default_root_state属性来获取生成的刚体原始物体的默认根状态。这个默认状态可以从assets.RigidObjectCfg.init_state属性配置,我们在这个指南中将其保留为身份。然后,我们随机化根状态的平移,并使用assets.RigidObject.write_root_state_to_sim()方法设置刚体原始物体的期望状态。正如名称所示,这个方法将刚体原始物体的根状态写入到模拟缓冲区中。

            # reset root stateroot_state = cone_object.data.default_root_state.clone()# sample a random position on a cylinder around the originsroot_state[:, :3] += originsroot_state[:, :3] += math_utils.sample_cylinder(radius=0.1, h_range=(0.25, 0.5), size=cone_object.num_instances, device=cone_object.device)# write root state to simulationcone_object.write_root_state_to_sim(root_state)# reset bufferscone_object.reset()

PS:我这段真看了半天,就只能直译了,我现在的理解是,我们要是想刷新这个圆锥的状态,就必须找出他的根状态,在根状态上做改变,当然如果是单纯的图形的话,在上一级Xform上改动也就可以了,也就是这一段代码,对orbit同样绝望还必须得用的可以私信我,我们一起研究一下

 root_state = cone_object.data.default_root_state.clone()

步进模拟

在步进模拟之前,我们执行assets.RigidObject.write_data_to_sim()方法。这个方法将其他数据,比如外部力,写入模拟缓冲区。在本指南中,我们没有对刚体施加任何外部力,所以这个方法不是必需的。然而,为了完整性,我们将他写在这里。

        # apply sim datacone_object.write_data_to_sim()

更新状态

在步进模拟之后,我们更新刚体原始物体的内部缓冲区,以便在assets.RigidObject.data属性内反映它们的新状态。这是通过使用assets.RigidObject.update()方法完成的。

        # update bufferscone_object.update(sim_dt)

代码执行

现在我们已经讲解了代码,让我们运行脚本并查看结果:

./orbit.sh -p source/standalone/tutorials/01_assets/run_rigid_object.py

这应该会打开一个带有地面平面、灯光和几个绿色圆锥的舞台。圆锥必须从随机高度落下并落在地面上。

在这里插入图片描述

要停止模拟,可以关闭窗口,或在UI中按停止按钮,或在终端中按Ctrl+C。

本指南展示了如何生成刚体对象,并将它们包装在RigidObject类中以初始化它们的物理句柄,这允许设置和获取它们的状态。在下一个指南中,我们将看到如何与由关节连接的刚体对象集合即关节物体进行互动。

愿本文渡一切机器人模拟器苦

以上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/277915.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jmeter+ant,ant安装与配置

1.ant含义 ant:Ant翻译过来是蚂蚁的意思,在我们做接口测试的时候,是可以用来做JMeter接口测试生成测试报告的工具 2.ant下载 下载地址:Apache Ant - Ant Manual Distributions download中选择ant 下载安装最新版zip文件 3.…

解决分布式事务,Seata真香!

年IT寒冬,大厂都裁员或者准备裁员,作为开猿节流主要目标之一,我们更应该时刻保持竞争力。为了抱团取暖,林老师开通了《知识星球》,并邀请我阿里、快手、腾讯等的朋友加入,分享八股文、项目经验、管理经验等…

4、设计模式之建造者模式(Builder)

一、什么是建造者模式 建造者模式是一种创建型设计模式,也叫生成器模式。 定义:封装一个复杂对象构造过程,并允许按步骤构造。 解释:就是将复杂对象的创建过程拆分成多个简单对象的创建过程,并将这些简单对象组合起来…

Linux字符设备驱动开发一

linux字符设备驱动 0 驱动介绍1 字符设备驱动1.1 字符设备相关概念和结构体1.2 实现简单的字符设备模块1.3 创建字符设备1.4 总结 应用程序调用文件系统的API(open、close、read、write) -> 文件系统根据访问的设备类型,调用对应设备的驱动API -> 驱动对硬件进…

面试经典150题——随机链表的复制

​前两天断更了两天有点事情🤗 1. 题目描述 2. 题目分析与解析 2.1 思路一 开始还是没什么思路,没思路那就先把题目解决不管方法的好坏。如果不考虑复杂度,该怎么解决? 可以有这样的一种思路: 首先复制链表的所有节…

记OnlyOffice的两个大坑

开发版,容器部署,试用许可已安装。 word,ppt,excel均能正常浏览。 自带的下载菜单按钮能用。 但config里自定义的downloadAs方法却不一而足。 word能正常下载,excel和ppt都不行。 仔细比对调试了代码。发现app.js…

fetch,前端 面试题

Fetch Fetch API 是近年来被提及将要取代XHR的技术新标准,是一个 HTML5 的 API。 基于promise的设计,返回的是Promise对象 fetch()采用模块化设计,API 分散在多个对象上(Response 对象、Request 对象、Headers 对象)…

Java双非大二找实习记录

先说结论:2.22→3.6线上线下面了七家,最后oc两家小公司,接了其中一个。 本人bg: 真名不经传双非一本,无绩点无竞赛无奖项无实习,23年12月开始学java。若非要说一点相关的经历,就是有java基础&…

新手向-从VNCTF2024的一道题学习QEMU Escape

[F] 说在前面 本文的草稿是边打边学边写出来的,文章思路会与一个“刚打完用户态 pwn 题就去打 QEMU Escape ”的人的思路相似,在分析结束以后我又在部分比较模糊的地方加入了一些补充,因此阅读起来可能会相对轻松(当然也不排除这是…

Hadoop大数据应用:NFS网关 连接 HDFS集群

目录 一、实验 1.环境 2.NFS网关 连接 HDFS集群 3. NFS客户端挂载HDFS文件系统 二、问题 1.关闭服务报错 2.rsync 同步报错 3. mount挂载有哪些参数 一、实验 1.环境 (1)主机 表1 主机 主机架构软件版本IP备注hadoop NameNode (…

Ubuntu 20.04 系统如何优雅地安装NCL?

一、什么是NCL? NCAR Command Language(NCL)是由美国大气研究中心(NCAR)推出的一款用于科学数据计算和可视化的免费软件。 它有着非常强大的文件输入和输出功能,可读写netCDF-3、netCDF-4 classic、HDF4、b…

【遍历方法】浅析Java中字符串、数组、集合的遍历

目录 前言 字符串篇 1.1 使用 for 循环和 charAt 方法 1.2 使用增强 for 循环(forEach 循环) 1.3 使用 Java 8 的 Stream API 最终效果 数组篇 2.1 使用普通 for 循环 2.2 使用增强型 for 循环( forEach 循环) 2.3 使用 Arrays.asList 和 forE…

C#调用Halcon出现尝试读取或写入受保护的内存,这通常指示其他内存已损坏。System.AccessViolationException

一、现象 在C#中调用Halcon,出现异常提示:尝试读取或写入受保护的内存,这通常指示其他内存已损坏。System.AccessViolationException 二、原因 多个线程同时访问Halcon中的某个公共变量,导致程序报错 三、测试 3.1 Halcon代码 其中tsp_width…

用户视角的比特币和以太坊外围技术整理

1. 引言 要点: 比特币L2基本强调交易内容的隐蔽性,P2P交易(尤其是支付)成为主流,给用户带来一定负担(闪电网络)在以太坊 L2 中,一定程度上减少了交易的隐蔽性,主流是实…

C语言 数据在内存中的存储

目录 前言 一、整数在内存中的存储 二、大小端字节序和字节序判断 2.1.练习一 2.2 练习二 2.3 练习三 2.4 练习四 2.5 练习五 2.6 练习六 三、浮点数在内存中的存储 3.1 浮点数存的过程 3.2 浮点数取的过程 总结 前言 数据在内存中根据数据类型有不同的存储方式,今…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的火焰与烟雾检测系统详解(深度学习模型+UI界面升级版+训练数据集)

摘要:本研究详细介绍了一种集成了最新YOLOv8算法的火焰与烟雾检测系统,并与YOLOv7、YOLOv6、YOLOv5等早期算法进行性能评估对比。该系统能够在包括图像、视频文件、实时视频流及批量文件中准确识别火焰与烟雾。文章深入探讨了YOLOv8算法的原理&#xff0…

Parade Series - Web Streamer Low Latency

Parade Series - FFMPEG (Stable X64) 延时测试秒表计时器 ini/config.ini [system] homeserver storestore\nvr.db versionV20240312001 verbosefalse [monitor] listrtsp00,rtsp01,rtsp02 timeout30000 [rtsp00] typelocal deviceSurface Camera Front schemartsp ip127…

软件杯 深度学习 python opencv 动物识别与检测

文章目录 0 前言1 深度学习实现动物识别与检测2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存…

前端框架vue的样式操作,以及vue提供的属性功能应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

基于Springboot+Vue+Sercurity实现的大学生健康管理平台

1.项目介绍 大学生健康档案管理系统,通过电子健康档案管理系统这个平台,可以实现人员健康情况的信息化、网络化、系统化、规范化管理,从繁杂的数据查询和统计中解脱出来,更好的掌握人员健康状况。系统的主要功能包括:…