Skip to content

Commit 59db13f

Browse files
authored
Merge branch 'main' into sensors
2 parents e72688e + eded4f8 commit 59db13f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1162
-561
lines changed

.github/workflows/production.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ jobs:
2525
GENESIS_IMAGE_VER: "1_1"
2626
TIMEOUT_MINUTES: 180
2727
MADRONA_DISABLE_CUDA_HEAP_SIZE: "1"
28+
OMNI_KIT_ACCEPT_EULA: "yes"
29+
OMNI_KIT_ALLOW_ROOT: "1"
2830

2931
steps:
3032
- name: Checkout code
@@ -48,6 +50,9 @@ jobs:
4850
NODELIST="--nodelist=$IDLE_NODES"
4951
fi
5052
53+
# TODO: USD baking does not currently support Python 3.11 since
54+
# NVIDIA does not currently release `omniverse-kit==107.3` on PyPI.
55+
# See: https://github.com/Genesis-Embodied-AI/Genesis/pull/1300
5156
srun \
5257
--container-image="/mnt/data/images/genesis-v${GENESIS_IMAGE_VER}.sqsh" \
5358
--container-mounts=\
@@ -60,7 +65,8 @@ jobs:
6065
--partition=hpc-mid ${NODELIST} --nodes=1 --time="${TIMEOUT_MINUTES}" \
6166
--job-name=${SLURM_JOB_NAME} \
6267
bash -c "
63-
pip install -e '.[dev,render]' && \
68+
pip install --extra-index-url https://pypi.nvidia.com/ omniverse-kit && \
69+
pip install -e '.[dev,render,usd]' && \
6470
pytest -v --forked ./tests
6571
"
6672

examples/rigid/single_franka_batch_render.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def main():
1515
parser.add_argument("-r", "--render_all_cameras", action="store_true", default=False)
1616
parser.add_argument("-o", "--output_dir", type=str, default="img_output/test")
1717
parser.add_argument("-u", "--use_rasterizer", action="store_true", default=False)
18+
parser.add_argument("-d", "--debug", action="store_true", default=False)
1819
args = parser.parse_args()
1920

2021
########################## init ##########################
@@ -37,6 +38,14 @@ def main():
3738
)
3839

3940
########################## cameras ##########################
41+
debug_cam = scene.add_camera(
42+
res=(720, 1280),
43+
pos=(1.5, -0.5, 1.0),
44+
lookat=(0.0, 0.0, 0.5),
45+
fov=60,
46+
GUI=args.vis,
47+
debug=True,
48+
)
4049
cam_0 = scene.add_camera(
4150
res=(512, 512),
4251
pos=(1.5, 0.5, 1.5),
@@ -75,14 +84,20 @@ def main():
7584
# Create an image exporter
7685
exporter = FrameImageExporter(args.output_dir)
7786

87+
if args.debug:
88+
debug_cam.start_recording()
7889
for i in range(args.n_steps):
7990
scene.step()
91+
if args.debug:
92+
debug_cam.render()
8093
if args.render_all_cameras:
8194
rgba, depth, _, _ = scene.render_all_cameras(rgb=True, depth=True)
8295
exporter.export_frame_all_cameras(i, rgb=rgba, depth=depth)
8396
else:
8497
rgba, depth, _, _ = cam_1.render(rgb=True, depth=True)
8598
exporter.export_frame_single_camera(i, cam_1.idx, rgb=rgba, depth=depth)
99+
if args.debug:
100+
debug_cam.stop_recording("debug_cam.mp4")
86101

87102

88103
if __name__ == "__main__":

genesis/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ def init(
5656
if _initialized:
5757
raise_exception("Genesis already initialized.")
5858

59+
# Make sure evertything is properly destroyed, just in case initialization failed previously
60+
destroy()
61+
5962
# genesis._theme
6063
global _theme
6164
is_theme_valid = theme in ("dark", "light", "dumb")

genesis/assets/tests/chopper.glb

-2.3 MB
Binary file not shown.
-167 KB
Binary file not shown.
-63.8 KB
Binary file not shown.

genesis/engine/entities/particle_entity.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ def sample(self):
247247
self._vfaces = np.array([], dtype=gs.np_float)
248248
elif isinstance(self._morph, gs.options.morphs.MeshSet):
249249
for i in range(len(self._morph.files)):
250-
pos_i, euler_i = map(np.asarray, (self._morph.poss[i], self._morph.eulers[i]))
250+
pos_i = np.asarray(self._morph.poss[i], dtype=gs.np_float)
251+
euler_i = np.asarray(self._morph.eulers[i], dtype=gs.np_float)
251252
quat_i = gs.utils.geom.xyz_to_quat(euler_i, rpy=True, degrees=True)
252253
self._vmesh[i].apply_transform(gu.trans_quat_to_T(pos_i, quat_i))
253254

@@ -284,7 +285,8 @@ def sample(self):
284285
origin = np.mean(self._morph.poss, dtype=gs.np_float)
285286
else:
286287
# transform vmesh
287-
pos, quat = map(np.asarray, (self._morph.pos, self._morph.quat))
288+
pos = np.asarray(self._morph.pos, dtype=gs.np_float)
289+
quat = np.asarray(self._morph.quat, dtype=gs.np_float)
288290
self._vmesh.apply_transform(gu.trans_quat_to_T(pos, quat))
289291
# transform particles
290292
particles = gu.transform_by_trans_quat(

genesis/engine/materials/MPM/elasto_plastic.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ class ElastoPlastic(Base):
1212
1313
Note
1414
----
15-
Default yield ratio comes from the SNOW material in taichi's MPM implementation: https://github.com/taichi-dev/taichi_elements/blob/d19678869a28b09a32ef415b162e35dc929b792d/engine/mpm_solver.py#L434
15+
Default yield ratio comes from the SNOW material in taichi's MPM implementation:
16+
https://github.com/taichi-dev/taichi_elements/blob/d19678869a28b09a32ef415b162e35dc929b792d/engine/mpm_solver.py#L434
1617
1718
Parameters
1819
----------

genesis/engine/mesh.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from genesis.options.surfaces import Surface
1414
import genesis.utils.mesh as mu
1515
import genesis.utils.gltf as gltf_utils
16-
import genesis.utils.usda as usda_utils
1716
import genesis.utils.particle as pu
1817
from genesis.repr_base import RBC
1918

@@ -229,6 +228,7 @@ def from_trimesh(
229228
"""
230229
if surface is None:
231230
surface = gs.surfaces.Default()
231+
surface.update_texture()
232232
else:
233233
surface = surface.copy()
234234
mesh = mesh.copy(include_cache=True)
@@ -341,22 +341,20 @@ def from_morph_surface(cls, morph, surface=None):
341341
If the morph is a Mesh morph (morphs.Mesh), it could contain multiple submeshes, so we return a list.
342342
"""
343343
if isinstance(morph, gs.options.morphs.Mesh):
344-
if morph.file.endswith(("obj", "ply", "stl")):
344+
if morph.is_format(gs.options.morphs.MESH_FORMATS):
345345
meshes = mu.parse_mesh_trimesh(morph.file, morph.group_by_material, morph.scale, surface)
346-
347-
elif morph.file.endswith(("glb", "gltf")):
346+
elif morph.is_format(gs.options.morphs.GLTF_FORMATS):
348347
if morph.parse_glb_with_trimesh:
349348
meshes = mu.parse_mesh_trimesh(morph.file, morph.group_by_material, morph.scale, surface)
350349
else:
351350
meshes = gltf_utils.parse_mesh_glb(morph.file, morph.group_by_material, morph.scale, surface)
351+
elif morph.is_format(gs.options.morphs.USD_FORMATS):
352+
import genesis.utils.usda as usda_utils
352353

353-
elif morph.file.endswith(("usd", "usda", "usdc", "usdz")):
354354
meshes = usda_utils.parse_mesh_usd(morph.file, morph.group_by_material, morph.scale, surface)
355-
356355
elif isinstance(morph, gs.options.morphs.MeshSet):
357356
assert all(isinstance(mesh, trimesh.Trimesh) for mesh in morph.files)
358357
meshes = [mu.trimesh_to_mesh(mesh, morph.scale, surface) for mesh in morph.files]
359-
360358
else:
361359
gs.raise_exception(
362360
f"File type not supported (yet). Submit a feature request if you need this: {morph.file}."

genesis/engine/scene.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import pickle
3+
import sys
34
import time
45

56
import numpy as np
@@ -531,8 +532,9 @@ def add_camera(
531532
focus_dist=None,
532533
GUI=False,
533534
spp=256,
534-
denoise=True,
535+
denoise=None,
535536
env_idx=None,
537+
debug=False,
536538
):
537539
"""
538540
Add a camera to the scene.
@@ -569,16 +571,24 @@ def add_camera(
569571
Samples per pixel. Only available when using RayTracer renderer. Defaults to 256.
570572
denoise : bool
571573
Whether to denoise the camera's rendered image. Only available when using the RayTracer renderer. Defaults
572-
to True. If OptiX denoiser is not available in your platform, consider enabling the OIDN denoiser option
573-
when building the RayTracer.
574+
to True on Linux, otherwise False. If OptiX denoiser is not available in your platform, consider enabling
575+
the OIDN denoiser option when building the RayTracer.
576+
debug : bool
577+
Whether to use the debug camera. It enables to create cameras that can used to monitor / debug the
578+
simulation without being part of the "sensors". Their output is rendered by the usual simple Rasterizer
579+
systematically, no matter if BatchRender and RayTracer is enabled. This way, it is possible to record the
580+
simulation with arbitrary resolution and camera pose, without interfering with what robots can perceive
581+
from their environment. Defaults to False.
574582
575583
Returns
576584
-------
577585
camera : genesis.Camera
578586
The created camera object.
579587
"""
588+
if denoise is None:
589+
denoise = sys.platform != "darwin"
580590
return self._visualizer.add_camera(
581-
res, pos, lookat, up, model, fov, aperture, focus_dist, GUI, spp, denoise, env_idx
591+
res, pos, lookat, up, model, fov, aperture, focus_dist, GUI, spp, denoise, env_idx, debug
582592
)
583593

584594
@gs.assert_unbuilt

0 commit comments

Comments
 (0)