Genesis - First Taste: Genesis的简单上手与测试

简介

近日开源的Genesis仿真平台引发大量关注,尤其是其宣称将会整合AI场景生成与任务生成的能力,于是本人在此对该平台进行了一次简单测试,模仿RoboCAS中的拾取与操作任务测试了Genesis的仿真能力(未完待续)。
项目主页
体验总结:

  • 仿真速度快,资源占用少于IsaacSim
  • 物理仿真真实,碰撞、交互等物理效果真实
  • 代码风格简洁,上手难度低
  • 可以对环境配置方面的代码进行进一步的整合,方便场景的复用,参考IsaacLab风格
  • 部分宣传的内容没有release,尤其是AI自动任务生成等具有广泛应用前景的内容

Genesis

Genesis 是一个物理平台,专为通用机器人/具身 AI/物理 AI应用而设计。它同时具有多种功能:

  • 从头开始重新构建的通用物理引擎,能够模拟各种材料和物理现象。
  • 一个轻量级、超快、Python 风格且用户友好的机器人模拟平台。
  • 强大而快速的照片级真实感渲染系统。
  • 将用户提示的自然语言描述转换为各种数据模式的生成数据引擎。(尚未公布)

Genesis 的建立和不断发展将遵循以下长期使命:

  • 降低使用物理模拟的门槛,让每个人都能参与机器人研究。(参见Genesis的承诺)
  • 将各种最先进的物理求解器统一到一个框架中,使用最先进的模拟技术在虚拟领域中以最高的物理、视觉和感官保真度重新创建整个物理世界。
  • 最大限度地减少人类在机器人和其他领域收集和生成数据方面的努力,让数据飞轮自行旋转。

主要特点

  • 速度:Genesis 提供了前所未有的模拟速度——使用单个 RTX 4090 模拟 Franka 机械臂时速度超过 4300 万 FPS(比实时快 430,000 倍)。
  • 跨平台:Genesis 可在不同的系统(Linux、MacOS、Windows)和不同的计算后端(CPU、Nvidia GPU、AMD GPU、Apple Metal)上本地运行。
  • 各种物理求解器的统一:Genesis开发了一个统一的模拟框架,集成了各种物理求解器:刚体、MPM、SPH、FEM、PBD、稳定流体。
  • 支持广泛的材料模型:Genesis 支持刚体和铰接体、各种类型的液体、气体现象、可变形物体、薄壳物体和颗粒材料的模拟(和耦合)。
  • 支持各种各样的机器人:机械臂、腿式机器人、无人机、软机器人等,并广泛支持加载不同的文件类型:MJCF (.xml), URDF, .obj, .glb, .ply, .stl等
  • 逼真且高性能的光线追踪器:Genesis 支持基于原生光线追踪的渲染。
  • 可微分性:Genesis 的设计完全兼容可微分模拟。目前,我们的 MPM 求解器和工具求解器都是可微分的,其他求解器的可微分性将很快添加(从刚体模拟开始)。
  • 基于物理的触觉传感器:Genesis 涉及基于物理且可微分的触觉传感器模拟模块。这将很快集成到公开版本中(预计在 0.3.0 版本中)。
  • 用户友好性:Genesis 的设计方式使使用模拟尽可能简单。从安装到 API 设计,如果您发现任何违反直觉或难以使用的地方,请告诉我们
    Genesis提供的高速仿真

先前工作

RoboGen

一个通过自然语言描述自动在环境中生成物体操作代码的项目,可能会在后期合并到Genesis所提到的数据自动生成框架中。但是在我们先前的测试中,发现该项目并不重视某个物体的操作在物理上可行性,仅重视整体流程上的合理性,比如在“移动椅子”任务中,该框架将抓取动作简化为吸取,将椅子直接固定在二指夹爪上并进行移动,而今后如果将代码合并到Genesis之后可能会对该问题有所修复。
RoboGen

RoboGen生成的操作轨迹

ThinShellLab

一个针对柔性物体的操作与数据生成框架
在这里插入图片描述

使用笔记

测试环境:

  • 系统:ubuntu 20.04
  • 显卡:RTX 3070, 8GB
  • python 3.10
  • cuda 11.8
  • pytorch 2.5.1

安装

创建conda环境,并按照官方文档安装Genesis

conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia
pip install open3d
git clone https://github.com/Genesis-Embodied-AI/Genesis.git

如果需要光追渲染,需要编译Luisa Compute相关模块,参考

git submodule update --init --recursive
sudo apt install build-essential manpages-dev software-properties-common

sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update && sudo apt install gcc-11 g++-11
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 110
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 110

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo apt-get install patchelf
sudo apt install libvulkan-dev
sudo apt-get install zlib1g-dev
sudo apt-get install xorg-dev libglu1-mesa-dev
pip install "pybind11[global]"
sudo apt-get install libsnappy-dev

cd genesis/ext/LuisaRender
cmake -S . -B build -D CMAKE_BUILD_TYPE=Release -D PYTHON_VERSIONS=3.9 -D LUISA_COMPUTE_DOWNLOAD_NVCOMP=ON -D LUISA_COMPUTE_ENABLE_GUI=OFF 
cmake --build build -j $(nproc)

cd $(dirname $(which python))/../lib
mv libstdc++.so.6 libstdc++.so.6.old
ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6 libstdc++.so.6

Genesis基于OMPL实现无碰撞运动路径规划,使用前需要自行下载并安装,参考

可以直接下载预编译的wheel并使用pip安装

wget https://github.com/ompl/ompl/releases/download/prerelease/ompl-1.6.0-cp310-cp310-manylinux_2_28_x86_64.whl		# 根据系统选择正确的版本
pip install ompl-1.6.0-cp310-cp310-manylinux_2_28_x86_64.whl

如果在代码运行过程中出现段错误等问题,可以尝试从源码安装ompl

# 由于需要再conda中安装,所以不使用官方的安装脚本
sudo apt-get -y install g++ cmake pkg-config libboost-serialization-dev libboost-filesystem-dev libboost-system-dev libboost-program-options-dev libboost-test-dev libeigen3-dev libode-dev wget libyaml-cpp-dev
export CXX=g++
export MAKEFLAGS="-j `nproc`"
pip install -vU https://github.com/CastXML/pygccxml/archive/develop.zip pyplusplus
sudo apt-get -y install castxml libboost-python-dev libboost-numpy-dev pypy3

git clone --recurse-submodules https://github.com/ompl/ompl.git -b 1.6.0
mkdir -p ompl/build
cd ompl/build

cmake ../.. -DPYTHON_EXEC=$(which python) -DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX" -DBOOST_ROOT="$CONDA_PREFIX" -DPYTHONPATH=$CONDA_PREFIX/lib/python3.10/site-packages		# 注意根据python版本修改路径
make update_bindings
# 如果在make update_bindings过程中出现报错:“No rule for update_bindings”,请检查系统中的boost_python是否正确安装并适配当前python版本(参考https://blog.csdn.net/qq_41854911/article/details/119454212)
make -j8
sudo make install

使用笔记

场景渲染与相机图像获取

创建场景

官方文档:👋🏻 Hello, Genesis

import genesis as gs
# 初始化引擎
gs.init(backend=gs.cpu)	# 可以选择多种bakcend以适应不同的平台以及设备, 详见官方文档
# 创建场景
scene = gs.Scene()
# 加载模型以及机器人
# 在 Genesis 中,所有对象和机器人都表示为Entity。Genesis 的设计完全面向对象,因此您将能够直接通过它们的方法与这些实体对象进行交互,而不是使用分配给它们的句柄或全局 ID
plane = scene.add_entity(gs.morphs.Plane())
franka = scene.add_entity(
    gs.morphs.MJCF(file='xml/franka_emika_panda/panda.xml'),
)
# 创建场景,每次添加、删除场景中的物体时都需要重新创建场景
scene.build()
# 运行仿真
for i in range(1000):
    scene.step()

Genesis 中的morphs是一个混合概念,封装了实体的几何和姿势信息。通过使用不同的变形,您可以从形状基元、网格、URDF、MJCF、地形或软机器人描述文件中实例化 Genesis 实体。

在使用URDF格式的机器人/模型配置文件时,机器人并不会自动与世界坐标系进行固定,所以,如果需要进行固定,则需要在morphs.URDF或者morphs.Mesh设置fixed=True

If you want to load a Franka arm using an external URDF file, you can simply change the morph to gs.morphs.URDF(file=‘urdf/panda_bullet/panda.urdf’, fixed=True). Note that unlike MJCF file which already specifies the joint type connecting the robot’s base link and the world, URDF file doesn’t come with this information. Therefore, by default, the base link of a URDF robot tree is disconnected from the world (or more precisely, connected to world via a free 6-dof joint). Therefore, we need to additionally specify fixed=True for morphs.URDF and morphs.Mesh if we want the base link to be fixed.

该仿真器默认将物体模型进行凸优化,但是同样支持非凸物体的仿真,参考官方示例

tank = scene.add_entity(
        gs.morphs.Mesh(
            file="meshes/tank.obj",
            convexify=False,		# 非凸物体
            scale=5.0,
            fixed=True,
            euler=(90, 0, 0),
        ),
    )

在这里插入图片描述

创建并使用相机

官方文档:📸 Visualization & Rendering

当前Genesis中相机支持渲染 rgb 图像、深度、分割mask和表面法线。
在这里插入图片描述

需要在场景build之前对相机进行定义,而build之后可以对相机位姿进行改变。但是并未找到直接的API以将相机固定到机器人的某个link上。

...

# 创建相机
cam = scene.add_camera(
    res    = (1280, 960),		# 分辨率
    pos    = (3.5, 0.0, 2.5),		# 相机位置
    lookat = (0, 0, 0.5),				# 相机视角方向
    fov    = 30,
    GUI    = False	# 不显示相机内容可视化窗口
)
scene.build()

# 设置需要渲染的内容,默认只有RGB
# 每次调用render函数时均需要设置渲染内容,否则仅rgb存在内容,其他均为None
rgb, depth, segmentation, normal = cam.render(depth=True, segmentation=True, normal=True)

# 开始记录场景
cam.start_recording()
for i in range(120):
    scene.step()
    # 改变相机位置
    cam.set_pose(
        pos    = (3.0 * np.sin(i / 60), 3.0 * np.cos(i / 60), 2.5),
        lookat = (0, 0, 0.5),
    )
    # 获取相机RGB图像,depth, segmentation, normal均为None
    cam.render()
# 停止记录场景并将记录内容保存到文件
cam.stop_recording(save_to_filename='video.mp4', fps=60)

光追渲染

Genesis使用Luisa Compute进行光追计算。要开启光追渲染,需要首先获取并安装相关组件,参考安装章节

scene = gs.Scene(
  viewer_options=gs.options.ViewerOptions(
    camera_pos=(3.5, 0.0, 2.5),
    camera_lookat=(0.0, 0.0, 0.5),
    camera_fov=40,
  ),
  show_viewer=args.vis,
  rigid_options=gs.options.RigidOptions(),
  # renderer=gs.renderers.Rasterizer(),
  renderer=gs.renderers.RayTracer()			# 在scene中切换render即可启用光追
)

对比测试

  • 模型:20个高质量obj模型,模型来源
  • 物理仿真:开启
  • 关闭光追:速度14fps
    在这里插入图片描述
  • 开启光追:测试中

其他传感器

💥 Collision, Contacts & Forces

该仿真器同样支持碰撞事件检测、接触力测量等多种形式的数据获取,但是目前并未给出相应说明。

机器人控制

🕹️ Control Your Robot

Genesis中使用PD控制器来控制机器人关节,仿真器中所有位姿控制最终均需要转换为关节的控制。此外,Genesis框架中也可以使用该方法来控制任意物体的位置移动。

示例代码

...
# 设置场景
plane = scene.add_entity(
  gs.morphs.Plane(),
)
franka = scene.add_entity(
  gs.morphs.MJCF(file="xml/franka_emika_panda/panda.xml"),
)
scene.build()

# ===================================================================================
# 从xml/urdf等机器人描述文件中获取要控制的关节名称
jnt_names = [
  "joint1",
  "joint2",
  "joint3",
  "joint4",
  "joint5",
  "joint6",
  "joint7",
  "finger_joint1",
  "finger_joint2",
]
# 这里使用.dof_idx_local来获取相对于机器人实体本身的自由度的本地 idx。还可以使用它joint.dof_idx来访问场景中每个关节的全局自由度索引。
dofs_idx = [franka.get_joint(name).dof_idx_local for name in jnt_names]

# Optional: 设置关节控制参数
franka.set_dofs_kp(
  np.array([4500, 4500, 3500, 3500, 2000, 2000, 2000, 100, 100]),
  dofs_idx,
)
franka.set_dofs_kv(
  np.array([450, 450, 350, 350, 200, 200, 200, 10, 10]),
  dofs_idx,
)
franka.set_dofs_force_range(
  np.array([-87, -87, -87, -87, -12, -12, -12, -100, -100]),
  np.array([87, 87, 87, 87, 12, 12, 12, 100, 100]),
  dofs_idx,
)

# 不经过物理仿真,直接设置关节状态
# 可以使用dofs_idx来指定要控制的关节
franka.set_dofs_position(np.array([1, 1, 0, 0, 0, 0, 0, 0.04, 0.04]), dofs_idx)
scene.step()

# 使用物理仿真控制关节运动到相应位置
franka.control_dofs_position(
  np.array([-1, 0.8, 1, -2, 1, 0.5, -0.5, 0.04, 0.04]),
  dofs_idx,
)
# Optional: 可以设置某一个关节的目标速度,这里以第一个关节为例
franka.control_dofs_velocity(
  np.array([1.0, 0, 0, 0, 0, 0, 0, 0, 0])[:1],
  dofs_idx[:1],
)
# Optional: 控制关节驱动力
franka.control_dofs_force(
  np.array([0, 0, 0, 0, 0, 0, 0, 0, 0]),
  dofs_idx,
)
scene.step()

逆运动学

🦾 Inverse Kinematics & Motion Planning

注意,Genesis中所有quat的顺序均为[w, x, y, z]

可以通过以下代码获取机器人某个link的位姿

ee_link = robot.get_link("hand")
ee_link.get_pos()		# link当前位置,torch.Tensor, device:cuda, shape: [3]
ee_link.get_quat()	# link当前旋转(四元数), torch.Tensor, device:cuda, shape: [4]

Genesis提供了一个快速的逆运动学求解接口robot.inverse_kinematics,用于将6D位姿转换为关节角度, 同时返回求解误差。此外,该接口支持不完整位姿的求解,即仅关心目标位姿的某些维度(如仅关心z轴的方向)

ee_link = robot.get_link("hand")

for i in range(0, 2000):
  target_pos = center + np.array([np.cos(i / 360 * np.pi), np.sin(i / 360 * np.pi), 0]) * r

  target_entity.set_qpos(np.concatenate([target_pos, target_quat]))
  q, err = robot.inverse_kinematics(
    link=ee_link,
    pos=target_pos,
    quat=target_quat,
    return_error=True,
    rot_mask=[False, False, True],  # for demo purpose: only care about direction of z-axis
  )

此外,Genesis可以支持多个末端同时进行IK求解,例如多臂机器人的多个末端执行器,或者一个夹爪的多个手指

🧗 Advanced and Parallel IK

...
left_finger = robot.get_link('left_finger')
right_finger = robot.get_link('right_finger')

for i in range(0, 2000):
    target_pos_left = center + np.array([np.cos(i/360*np.pi), np.sin(i/360*np.pi), 0]) * r
    target_pos_right = target_pos_left + np.array([0.0, 0.03, 0])

    target_left.set_qpos(np.concatenate([target_pos_left, target_quat]))
    target_right.set_qpos(np.concatenate([target_pos_right, target_quat]))
    
    q = robot.inverse_kinematics_multilink(
        links    = [left_finger, right_finger],					# 多个目标link
        poss     = [target_pos_left, target_pos_right],	# 各link的位置
        quats    = [target_quat, target_quat],					# 各link的旋转
        rot_mask = [False, False, True], # only restrict direction of z-axis
    )

运动规划

Genesis使用OMPL进行无碰撞路径规划,需要提前编译OMPL,参考安装章节。Genesis目前仅提供了到一个目标关节位姿的路径规划接口,所以如果要实现到某个位姿的运动规划,则需要首先使用IK求解出相应的关节位置。

qpos = franka.inverse_kinematics(
    link = end_effector,
    pos  = np.array([0.65, 0.0, 0.25]),
    quat = np.array([0, 1, 0, 0]),
)
# gripper open pos
qpos[-2:] = 0.04
path = franka.plan_path(
    qpos_goal     = qpos,
    num_waypoints = 200, # 2s duration
)
# execute the planned path
for waypoint in path:
    franka.control_dofs_position(waypoint)
    scene.step()

# allow robot to reach the last waypoint
for i in range(100):
    scene.step()

并行仿真

Genesis支持利用GPU进行大量场景的并行仿真,进需要在构建场景时增加一个n_envs参数,并且在控制机器人时在目标关节位置上增加一个batch维度
在这里插入图片描述

...
B = 20
scene.build(n_envs=B, env_spacing=(1.0, 1.0))

# control all the robots
franka.control_dofs_position(
    torch.tile(
        torch.tensor([0, 0, 0, -1.0, 0, 0, 0, 0.02, 0.02], device=gs.device), (B, 1)
    ),
)
# control only 3 environments: 1, 5, and 7.
franka.control_dofs_position(
    position = torch.zeros(3, 9, device=gs.device),
    envs_idx = torch.tensor([1, 5, 7], device=gs.device),
)

软体仿真

Genesis整合了多个物理模拟求解器,获得了高性能的软体材料以及软体机器人、模拟肌肉的仿真能力。
在这里插入图片描述
在这里插入图片描述

实际使用测试

这里使用Genesis使用RoboCAS中的模型,生成其类似的任务,来对Genesis进行测试。
(待更新)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值