Orbit 使用指南 10|在机器人上安装传感器 | Isaac Sim | Omniverse

2024-03-24 08:20

本文主要是介绍Orbit 使用指南 10|在机器人上安装传感器 | Isaac Sim | Omniverse,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如是我闻: 资产类(asset classes)允许我们创建和模拟机器人,而传感器 (sensors) 则帮助我们获取关于环境的信息,获取不同的本体感知和外界感知信息。例如,摄像头传感器可用于获取环境的视觉信息,接触传感器可以用来获取机器人与环境的接触信息。

在本指南中,我们将看到如何给机器人添加不同的传感器。我们将在本指南中使用ANYmal-C机器人。ANYmal-C是一款四足机器人,拥有12个自由度,它有4条腿,每条腿有3个自由度。这款机器人配备了以下传感器:

  • 机器人头部的摄像头传感器,提供RGB-D图像
  • 提供地形高度信息的高度扫描传感器
  • 机器人脚部的接触传感器,提供接触信息

本指南对应于orbit/source/standalone/tutorials/04_sensors目录下的add_sensors_on_robot.py脚本。让我们先搂一眼完整的代码

# Copyright (c) 2022-2024, The ORBIT Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause"""
This script demonstrates how to add and simulate on-board sensors for a robot.We add the following sensors on the quadruped robot, ANYmal-C (ANYbotics):* USD-Camera: This is a camera sensor that is attached to the robot's base.
* Height Scanner: This is a height scanner sensor that is attached to the robot's base.
* Contact Sensor: This is a contact sensor that is attached to the robot's feet... code-block:: bash# Usage./orbit.sh -p source/standalone/tutorials/04_sensors/add_sensors_on_robot.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 adding sensors on a robot.")
parser.add_argument("--num_envs", type=int, default=2, help="Number of environments to spawn.")
# 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 torch
import tracebackimport carbimport omni.isaac.orbit.sim as sim_utils
from omni.isaac.orbit.assets import ArticulationCfg, AssetBaseCfg
from omni.isaac.orbit.scene import InteractiveScene, InteractiveSceneCfg
from omni.isaac.orbit.sensors import CameraCfg, ContactSensorCfg, RayCasterCfg, patterns
from omni.isaac.orbit.utils import configclass##
# Pre-defined configs
##
from omni.isaac.orbit_assets.anymal import ANYMAL_C_CFG  # isort: skip@configclass
class SensorsSceneCfg(InteractiveSceneCfg):"""Design the scene with sensors on the robot."""# ground planeground = AssetBaseCfg(prim_path="/World/defaultGroundPlane", spawn=sim_utils.GroundPlaneCfg())# lightsdome_light = AssetBaseCfg(prim_path="/World/Light", spawn=sim_utils.DomeLightCfg(intensity=3000.0, color=(0.75, 0.75, 0.75)))# robotrobot: ArticulationCfg = ANYMAL_C_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot")# sensorscamera = CameraCfg(prim_path="{ENV_REGEX_NS}/Robot/base/front_cam",update_period=0.1,height=480,width=640,data_types=["rgb", "distance_to_image_plane"],spawn=sim_utils.PinholeCameraCfg(focal_length=24.0, focus_distance=400.0, horizontal_aperture=20.955, clipping_range=(0.1, 1.0e5)),offset=CameraCfg.OffsetCfg(pos=(0.510, 0.0, 0.015), rot=(0.5, -0.5, 0.5, -0.5), convention="ros"),)height_scanner = RayCasterCfg(prim_path="{ENV_REGEX_NS}/Robot/base",update_period=0.02,offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),attach_yaw_only=True,pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),debug_vis=True,mesh_prim_paths=["/World/defaultGroundPlane"],)contact_forces = ContactSensorCfg(prim_path="{ENV_REGEX_NS}/Robot/.*_FOOT", update_period=0.0, history_length=6, debug_vis=True)def run_simulator(sim: sim_utils.SimulationContext,scene: InteractiveScene,
):"""Run the simulator."""# Define simulation steppingsim_dt = sim.get_physics_dt()sim_time = 0.0count = 0# Simulate physicswhile simulation_app.is_running():# Resetif count % 500 == 0:# reset countercount = 0# reset the scene entities# root state# we offset the root state by the origin since the states are written in simulation world frame# if this is not done, then the robots will be spawned at the (0, 0, 0) of the simulation worldroot_state = scene["robot"].data.default_root_state.clone()root_state[:, :3] += scene.env_originsscene["robot"].write_root_state_to_sim(root_state)# set joint positions with some noisejoint_pos, joint_vel = (scene["robot"].data.default_joint_pos.clone(),scene["robot"].data.default_joint_vel.clone(),)joint_pos += torch.rand_like(joint_pos) * 0.1scene["robot"].write_joint_state_to_sim(joint_pos, joint_vel)# clear internal buffersscene.reset()print("[INFO]: Resetting robot state...")# Apply default actions to the robot# -- generate actions/commandstargets = scene["robot"].data.default_joint_pos# -- apply action to the robotscene["robot"].set_joint_position_target(targets)# -- write data to simscene.write_data_to_sim()# perform stepsim.step()# update sim-timesim_time += sim_dtcount += 1# update buffersscene.update(sim_dt)# print information from the sensorsprint("-------------------------------")print(scene["camera"])print("Received shape of rgb   image: ", scene["camera"].data.output["rgb"].shape)print("Received shape of depth image: ", scene["camera"].data.output["distance_to_image_plane"].shape)print("-------------------------------")print(scene["height_scanner"])print("Received max height value: ", torch.max(scene["height_scanner"].data.ray_hits_w[..., -1]).item())print("-------------------------------")print(scene["contact_forces"])print("Received max contact force of: ", torch.max(scene["contact_forces"].data.net_forces_w).item())def main():"""Main function."""# Initialize the simulation contextsim_cfg = sim_utils.SimulationCfg(dt=0.005, substeps=1)sim = sim_utils.SimulationContext(sim_cfg)# Set main camerasim.set_camera_view(eye=[3.5, 3.5, 3.5], target=[0.0, 0.0, 0.0])# design scenescene_cfg = SensorsSceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0)scene = InteractiveScene(scene_cfg)# Play the simulatorsim.reset()# Now we are ready!print("[INFO]: Setup complete...")# Run the simulatorrun_simulator(sim, scene)if __name__ == "__main__":try:# run the main executionmain()except Exception as err:carb.log_error(err)carb.log_error(traceback.format_exc())raisefinally:# close sim appsimulation_app.close()

代码解析

与之前我们在场景中添加资产的教程类似,传感器也是通过场景配置添加到场景中的。所有的传感器都继承自sensors.SensorBase类,并通过各自的配置类进行配置。每个传感器实例都可以定义自己的更新周期,即传感器更新的频率。更新周期通过sensors.SensorBaseCfg.update_period属性以秒为单位指定。

根据指定的路径和传感器类型,传感器会被附加到场景中的原始图元(prims)上。传感器可能直接和在场景中已创建的原始图元关联,或者可能被附加到一个已存在的原始图元上。例如,摄像头传感器会附加在一个已经创建好的原始图元上,而对于接触传感器,激活中的接触报告是刚体原始图元上的一个属性。

接下来,我们将介绍如何使用不同的传感器以及如何配置。要了解更多关于它们的描述,请查看sensors模块。

摄像头传感器 (Camera sensor)

摄像头是使用sensors.CameraCfg类来定义的。它基于USD摄像头传感器,不同的数据类型由Omniverse Replicator API来捕获。由于摄像头在场景中有对应的原始图元(prim),所以在指定的原始图元路径上会创建原始图元。

摄像头传感器的配置包括以下参数:

  • spawn:创建的USD摄像头类型。可以是PinholeCameraCfg(针孔摄像头配置)或FisheyeCameraCfg(鱼眼摄像头配置)。

  • offset:摄像头传感器相对于父原始图元的偏移。

  • data_types:要捕获的数据类型。可以是rgb、distance_to_image_plane(到图像平面的距离)、normals(法线)或其他USD摄像头传感器支持的类型。

为了将RGB-D摄像头传感器附加到机器人的头部,我们指定了一个相对于机器人基座的偏移(offset)。偏移是相对于基座指定的平移和旋转,以及偏移的指定方式。

接下来,我们来看如何使用摄像头传感器配置。我们将更新周期设置为0.1秒,这意味着摄像头传感器以10Hz的频率更新。原始图元路径表达式设置为{ENV_REGEX_NS}/Robot/base/front_cam,其中{ENV_REGEX_NS}是环境命名空间,"Robot"是机器人的名称,"base"是摄像头附加的原始图元的名称,而"front_cam"是与摄像头传感器关联的原始图元的名称。

高度扫描仪(scanner)

高度扫描仪作为一种虚拟传感器,通过使用NVIDIA Warp的光线投射内核来实现。通过sensors.RayCasterCfg,我们可以指定要投射的光线模式以及要对哪些网格进行光线投射。由于它们是虚拟传感器,在场景中没有相应的原始物体(prims)被创建。相反,它们附加到场景中的一个原始物体上,这用于指定传感器的位置。

在本指南中,基于光线投射的高度扫描仪附加到机器人的基座上。光线的模式使用pattern属性指定。对于均匀网格模式,我们使用GridPatternCfg指定模式。由于我们只关心高度信息,我们不需要考虑机器人的滚转和俯仰。因此,我们将attach_yaw_only设置为true。

对于高度扫描仪,我们可以可视化光线击中网格的点。这是通过将debug_vis属性设置为true来完成的。

高度扫描仪的整个配置如下:

   height_scanner = RayCasterCfg(prim_path="{ENV_REGEX_NS}/Robot/base",update_period=0.02,offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),attach_yaw_only=True,pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),debug_vis=True,mesh_prim_paths=["/World/defaultGroundPlane"],)

接触传感器 (Contact sensor)

接触传感器利用PhysX的接触报告API来获取机器人与环境的接触信息。由于它依赖于PhysX,接触传感器期望在机器人的刚体上启用接触报告API。这可以通过在资产配置中设置activate_contact_sensors为true来完成。

通过sensors.ContactSensorCfg,可以指定我们想要获取接触信息的原始物体(prims)。可以设置额外的标志以获取更多关于接触的信息,例如接触空中时间、过滤原始物体之间的接触力等。

在本指南中,我们将接触传感器附加到机器人的脚上。机器人的脚被命名为"LF_FOOT"、“RF_FOOT”、“LH_FOOT"和"RF_FOOT”。我们传递一个正则表达式".*_FOOT"来简化原始物体路径的指定。这个正则表达式匹配所有以"_FOOT"结尾的原始物体。

我们将更新周期设置为0,以使传感器与模拟以相同的频率更新。此外,对于接触传感器,我们可以指定要存储的接触信息的历史长度。对于这个教程,我们将历史长度设置为6,这意味着存储了最后6个模拟步骤的接触信息。

接触传感器的整个配置如下:

    contact_forces = ContactSensorCfg(prim_path="{ENV_REGEX_NS}/Robot/.*_FOOT", update_period=0.0, history_length=6, debug_vis=True)

运行模拟循环

与使用资产时相似,传感器的缓冲区和物理句柄只有在播放模拟时才会初始化,即,在创建场景后调用sim.reset()是很重要的。

    # Play the simulatorsim.reset()

除此之外,模拟循环与之前的指南类似。传感器作为场景更新的一部分进行更新,它们内部处理基于它们更新周期的缓冲区更新。

可以通过它们的data属性访问传感器的数据。作为示例,我们展示如何访问本教程中创建的不同传感器的数据:

        # print information from the sensorsprint("-------------------------------")print(scene["camera"])print("Received shape of rgb   image: ", scene["camera"].data.output["rgb"].shape)print("Received shape of depth image: ", scene["camera"].data.output["distance_to_image_plane"].shape)print("-------------------------------")print(scene["height_scanner"])print("Received max height value: ", torch.max(scene["height_scanner"].data.ray_hits_w[..., -1]).item())print("-------------------------------")print(scene["contact_forces"])print("Received max contact force of: ", torch.max(scene["contact_forces"].data.net_forces_w).item())

代码运行

现在让我们运行脚本并查看结果:

./orbit.sh -p source/standalone/tutorials/04_sensors/add_sensors_on_robot.py --num_envs 2

在这里插入图片描述

这个命令应该会打开一个带有地面平面、灯光和两个四足机器人的舞台。在机器人周围,应该会看到红色的球体,这些球体表示光线击中网格的点。另外,你可以切换视口到摄像机视图,以查看摄像头传感器捕获的RGB图像。请查看这里以了解如何切换视口到摄像机视图的更多信息。

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

虽然在这个教程中,我们讲解了创建和使用不同的传感器,但在sensors模块中还有许多其他传感器可用。我们在source/standalone/tutorials/04_sensors目录中包含了使用这些传感器的示例。这些脚本可以使用以下命令运行:

# Frame Transformer
./orbit.sh -p source/standalone/tutorials/04_sensors/run_frame_transformer.py# Ray Caster
./orbit.sh -p source/standalone/tutorials/04_sensors/run_ray_caster.py# Ray Caster Camera
./orbit.sh -p source/standalone/tutorials/04_sensors/run_ray_caster_camera.py# USD Camera
./orbit.sh -p source/standalone/tutorials/04_sensors/run_usd_camera.py

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

以上

这篇关于Orbit 使用指南 10|在机器人上安装传感器 | Isaac Sim | Omniverse的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/840999

相关文章

ESP32 esp-idf esp-adf环境安装及.a库创建与编译

简介 ESP32 功能丰富的 Wi-Fi & 蓝牙 MCU, 适用于多样的物联网应用。使用freertos操作系统。 ESP-IDF 官方物联网开发框架。 ESP-ADF 官方音频开发框架。 文档参照 https://espressif-docs.readthedocs-hosted.com/projects/esp-adf/zh-cn/latest/get-started/index

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

VMware9.0详细安装

双击VMware-workstation-full-9.0.0-812388.exe文件: 直接点Next; 这里,我选择了Typical(标准安装)。 因为服务器上只要C盘,所以我选择安装在C盘下的vmware文件夹下面,然后点击Next; 这里我把√取消了,每次启动不检查更新。然后Next; 点击Next; 创建快捷方式等,点击Next; 继续Cont

vcpkg安装opencv中的特殊问题记录(无法找到opencv_corexd.dll)

我是按照网上的vcpkg安装opencv方法进行的(比如这篇:从0开始在visual studio上安装opencv(超详细,针对小白)),但是中间出现了一些别人没有遇到的问题,虽然原因没有找到,但是本人给出一些暂时的解决办法: 问题1: 我在安装库命令行使用的是 .\vcpkg.exe install opencv 我的电脑是x64,vcpkg在这条命令后默认下载的也是opencv2:x6

【服务器运维】CentOS6 minimal 离线安装MySQL5.7

1.准备安装包(版本因人而异,所以下面的命令中版本省略,实际操作中用Tab自动补全就好了) cloog-ppl-0.15.7-1.2.el6.x86_64.rpmcpp-4.4.7-23.el6.x86_64.rpmgcc-4.4.7-23.el6.x86_64.rpmgcc-c++-4.4.7-23.el6.x86_64.rpmglibc-2.12-1.212.el6.x86_64.r

【服务器运维】CentOS7 minimal 离线安装 gcc perl vmware-tools

0. 本机在有网的情况下,下载CentOS镜像 https://www.centos.org/download/ 1. 取出rpm 有的情况可能不需要net-tools,但是如果出现跟ifconfig相关的错误,就把它安装上。另外如果不想升级内核版本的话,就找对应内核版本的rpm版本安装 perl-Time-Local-1.2300-2.el7.noarch.rpmperl-Tim

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

Ubuntu20.04离线安装Docker

1.下载3个docker离线安装包,下载网址: https://download.docker.com/linux/ubuntu/dists/xenial/pool/stable/amd64/ 2.把3个离线安装包拷贝到ubuntu本地执行以下命令 sudo dpkg -i containerd.io_1.4.6-1_amd64.deb sudo dpkg -i docker-ce-c

雨量传感器的分类和选型建议

物理原理分类 机械降雨量计(雨量桶):最早使用的降雨量传感器,通过漏斗收集雨水并记录。主要用于长期降雨统计,故障率较低。电容式降雨量传感器:基于两个电极之间的电容变化来计算降雨量。当降雨时,水滴堵住电极空间,改变电容值,从而计算降雨量。超声波式降雨量传感器:利用超声波的反射来计算降雨量。适用于大降雨量的场合。激光雷达式降雨量传感器:利用激光技术测量雨滴的速度、大小和形状等参数,并计算降雨量。主

Windows中,.net framework 3.5安装

安装.net framework,目前已知2种方法,如下: 一、在MSDN下载对应的安装包,安装,这种可能无法安装成功,概率很大,不成功使用第二种方法,基本上没问题。 二、win8/8.1/10 下安装 .net framework 3.5.1: 1. 打开 win8/8.1/10 安装盘(这里指系统安装镜像文件),提取 sources\sxs 文件夹到 X:\sources\sxs (X代