Skip to content

Commit

Permalink
Merge pull request #265 from StanfordVL/fix/systems-and-trs
Browse files Browse the repository at this point in the history
Fix/systems and trs
  • Loading branch information
cremebrule authored Aug 29, 2023
2 parents ca0265f + 77155a9 commit aa8b870
Show file tree
Hide file tree
Showing 33 changed files with 480 additions and 305 deletions.
2 changes: 1 addition & 1 deletion omnigibson/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import nest_asyncio
nest_asyncio.apply()

__version__ = "0.2.0"
__version__ = "0.2.1"

log.setLevel(logging.DEBUG if gm.DEBUG else logging.INFO)

Expand Down
2 changes: 1 addition & 1 deletion omnigibson/object_states/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from omnigibson.object_states.next_to import NextTo
from omnigibson.object_states.on_fire import OnFire
from omnigibson.object_states.on_top import OnTop
from omnigibson.object_states.open import Open
from omnigibson.object_states.open_state import Open
from omnigibson.object_states.overlaid import Overlaid
from omnigibson.object_states.particle_modifier import ParticleRemover, ParticleApplier
from omnigibson.object_states.particle_source_or_sink import ParticleSource, ParticleSink
Expand Down
10 changes: 10 additions & 0 deletions omnigibson/object_states/contains.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ def _get_value(self, system):
# Grab value from Contains state; True if value is greater than 0
return self.obj.states[ContainedParticles].get_value(system=system).n_in_volume > 0

def _set_value(self, system, new_value):
if new_value:
# Cannot set contains = True, only False
raise NotImplementedError(f"{self.__class__.__name__} does not support set_value(system, True)")
else:
# Remove all particles from inside the volume
system.remove_particles(idxs=self.obj.states[ContainedParticles].get_value(system).in_volume.nonzero()[0])

return True

@classmethod
def get_dependencies(cls):
deps = super().get_dependencies()
Expand Down
6 changes: 3 additions & 3 deletions omnigibson/object_states/filled.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def _get_value(self, system):
return value

def _set_value(self, system, new_value):
# Sanity check to manke sure system is valid
# Sanity check to make sure system is valid
assert is_physical_particle_system(system_name=system.name), \
"Can only set Filled state with a valid PhysicalParticleSystem!"

Expand All @@ -52,8 +52,8 @@ def _set_value(self, system, new_value):
check_contact=True,
)
else:
# Going from True --> False, remove all particles inside the volume
system.remove_particles(idxs=contained_particles_state.get_value(system).in_volume.nonzero()[0])
# Cannot set False
raise NotImplementedError(f"{self.__class__.__name__} does not support set_value(system, False)")

return True

Expand Down
2 changes: 1 addition & 1 deletion omnigibson/object_states/heat_source_or_sink.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from omnigibson.object_states.inside import Inside
from omnigibson.object_states.link_based_state_mixin import LinkBasedStateMixin
from omnigibson.object_states.object_state_base import AbsoluteObjectState
from omnigibson.object_states.open import Open
from omnigibson.object_states.open_state import Open
from omnigibson.object_states.toggle import ToggledOn
from omnigibson.utils.python_utils import classproperty
import omnigibson.utils.transform_utils as T
Expand Down
10 changes: 6 additions & 4 deletions omnigibson/object_states/inside.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from omnigibson.object_states.object_state_base import BooleanStateMixin, RelativeObjectState
from omnigibson.utils.object_state_utils import sample_kinematics
from omnigibson.utils.usd_utils import BoundingBoxAPI
from omnigibson.utils.object_state_utils import m as os_m


class Inside(RelativeObjectState, KinematicsMixin, BooleanStateMixin):
Expand All @@ -20,10 +21,11 @@ def _set_value(self, other, new_value):

state = og.sim.dump_state(serialized=False)

if sample_kinematics("inside", self.obj, other) and self.get_value(other):
return True
else:
og.sim.load_state(state, serialized=False)
for _ in range(os_m.DEFAULT_HIGH_LEVEL_SAMPLING_ATTEMPTS):
if sample_kinematics("inside", self.obj, other) and self.get_value(other):
return True
else:
og.sim.load_state(state, serialized=False)

return False

Expand Down
13 changes: 8 additions & 5 deletions omnigibson/object_states/on_top.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from omnigibson.object_states.object_state_base import BooleanStateMixin, RelativeObjectState
from omnigibson.object_states.touching import Touching
from omnigibson.utils.object_state_utils import sample_kinematics
from omnigibson.utils.object_state_utils import m as os_m


class OnTop(KinematicsMixin, RelativeObjectState, BooleanStateMixin):
Expand All @@ -20,10 +21,11 @@ def _set_value(self, other, new_value):

state = og.sim.dump_state(serialized=False)

if sample_kinematics("onTop", self.obj, other) and self.get_value(other):
return True
else:
og.sim.load_state(state, serialized=False)
for _ in range(os_m.DEFAULT_HIGH_LEVEL_SAMPLING_ATTEMPTS):
if sample_kinematics("onTop", self.obj, other) and self.get_value(other):
return True
else:
og.sim.load_state(state, serialized=False)

return False

Expand All @@ -33,4 +35,5 @@ def _get_value(self, other):
return False

adjacency = self.obj.states[VerticalAdjacency].get_value()
return other in adjacency.negative_neighbors and other not in adjacency.positive_neighbors
other_adjacency = other.states[VerticalAdjacency].get_value()
return other in adjacency.negative_neighbors and other not in adjacency.positive_neighbors and self.obj not in other_adjacency.negative_neighbors
File renamed without changes.
4 changes: 2 additions & 2 deletions omnigibson/object_states/particle_modifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,11 +524,11 @@ def _update(self):
# Check if all conditions are met
if np.all([condition(self.obj) for condition in conditions]):
system = get_system(system_name)
# Update saturation limit if it's not the desired one
# Update saturation limit if it's not specified yet
limit = self.visual_particle_modification_limit \
if is_visual_particle_system(system_name=system.name) \
else self.physical_particle_modification_limit
if limit != self.obj.states[Saturated].get_limit(system=system):
if system not in self.obj.states[Saturated].limits:
self.obj.states[Saturated].set_limit(system=system, limit=limit)
# Sanity check for oversaturation
if self.obj.states[Saturated].get_value(system=system):
Expand Down
13 changes: 11 additions & 2 deletions omnigibson/object_states/saturated.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def _dump_state(self):
return state

def _load_state(self, state):
self.particle_counts = {REGISTERED_SYSTEMS[system_name]: val for system_name, val in state.items() if system_name != "n_systems"}
self.particle_counts = {REGISTERED_SYSTEMS[system_name]: val for system_name, val in state.items() if system_name != "n_systems" and val > 0}

def _serialize(self, state):
state_flat = np.array([state["n_systems"]], dtype=float)
Expand Down Expand Up @@ -107,6 +107,14 @@ def _initialize(self):
# Set internal variables
self._limits = dict()

@property
def limits(self):
"""
Returns:
dict: Maps system to limit count for that system, if it exists
"""
return self._limits

def get_limit(self, system):
"""
Grabs the internal particle limit for @system
Expand Down Expand Up @@ -202,7 +210,8 @@ def _load_state(self, state):
continue
elif k == "default_limit":
self._default_limit = v
else:
# TODO: Make this an else once fresh round of sampling occurs (i.e.: no more outdated systems stored)
elif k in REGISTERED_SYSTEMS:
self._limits[REGISTERED_SYSTEMS[k]] = v

def _serialize(self, state):
Expand Down
1 change: 1 addition & 0 deletions omnigibson/object_states/toggle.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def _initialize(self):
self.visual_marker = VisualGeomPrim(prim_path=mesh_prim_path, name=f"{self.obj.name}_visual_marker")
self.visual_marker.scale = self.scale
self.visual_marker.initialize()
self.visual_marker.visible = True

# Make sure the marker isn't translated at all
self.visual_marker.set_local_pose(translation=np.zeros(3), orientation=np.array([0, 0, 0, 1.0]))
Expand Down
13 changes: 7 additions & 6 deletions omnigibson/object_states/touching.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ def _get_value(self, other):
return self._check_contact(other, self.obj)
elif other.prim_type == PrimType.CLOTH:
return self._check_contact(self.obj, other)
elif not self.obj.kinematic_only and not other.kinematic_only:
# Use optimized check for rigid bodies
return RigidContactAPI.in_contact(
prim_paths_a=[link.prim_path for link in self.obj.links.values()],
prim_paths_b=[link.prim_path for link in other.links.values()],
)
# elif not self.obj.kinematic_only and not other.kinematic_only:
# # Use optimized check for rigid bodies
# # TODO: Use once NVIDIA fixes their absolutely broken API
# return RigidContactAPI.in_contact(
# prim_paths_a=[link.prim_path for link in self.obj.links.values()],
# prim_paths_b=[link.prim_path for link in other.links.values()],
# )
else:
return self._check_contact(other, self.obj) and self._check_contact(self.obj, other)
13 changes: 8 additions & 5 deletions omnigibson/object_states/under.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from omnigibson.object_states.kinematics_mixin import KinematicsMixin
from omnigibson.object_states.object_state_base import BooleanStateMixin, RelativeObjectState
from omnigibson.utils.object_state_utils import sample_kinematics
from omnigibson.utils.object_state_utils import m as os_m


class Under(RelativeObjectState, KinematicsMixin, BooleanStateMixin):
Expand All @@ -18,13 +19,15 @@ def _set_value(self, other, new_value):

state = og.sim.dump_state(serialized=False)

if sample_kinematics("under", self.obj, other) and self.get_value(other):
return True
else:
og.sim.load_state(state, serialized=False)
for _ in range(os_m.DEFAULT_HIGH_LEVEL_SAMPLING_ATTEMPTS):
if sample_kinematics("under", self.obj, other) and self.get_value(other):
return True
else:
og.sim.load_state(state, serialized=False)

return False

def _get_value(self, other):
adjacency = self.obj.states[VerticalAdjacency].get_value()
return other not in adjacency.negative_neighbors and other in adjacency.positive_neighbors
other_adjacency = other.states[VerticalAdjacency].get_value()
return other not in adjacency.negative_neighbors and other in adjacency.positive_neighbors and self.obj not in other_adjacency.positive_neighbors
20 changes: 3 additions & 17 deletions omnigibson/objects/dataset_object.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import itertools
import math
import os
import tempfile
import stat
import cv2
import numpy as np
Expand All @@ -16,7 +15,7 @@
from omnigibson.utils.constants import AVERAGE_CATEGORY_SPECS, DEFAULT_JOINT_FRICTION, SPECIAL_JOINT_FRICTIONS, JointType
import omnigibson.utils.transform_utils as T
from omnigibson.utils.usd_utils import BoundingBoxAPI
from omnigibson.utils.asset_utils import decrypt_file, get_all_object_category_models
from omnigibson.utils.asset_utils import get_all_object_category_models
from omnigibson.utils.constants import PrimType
from omnigibson.macros import gm, create_module_macros
from omnigibson.utils.ui_utils import create_module_logger
Expand Down Expand Up @@ -128,6 +127,7 @@ def __init__(
super().__init__(
prim_path=prim_path,
usd_path=usd_path,
encrypted=True,
name=name,
category=category,
class_id=class_id,
Expand Down Expand Up @@ -217,21 +217,6 @@ def recursive_light_update(child_prim):
if joint.joint_type != JointType.JOINT_FIXED:
joint.friction = friction

def _load(self):
# Create a temporary file to store the decrytped asset, load it, and then delete it.
original_usd_path = self._usd_path
encrypted_filename = original_usd_path.replace(".usd", ".encrypted.usd")
decrypted_fd, decrypted_filename = tempfile.mkstemp(os.path.basename(original_usd_path), dir=og.tempdir)
decrypt_file(encrypted_filename, decrypted_filename)
self._usd_path = decrypted_filename
prim = super()._load()
os.close(decrypted_fd)
# On Windows, Isaac Sim won't let go of the file until the prim is removed, so we can't delete it.
if os.name == "posix":
os.remove(decrypted_filename)
self._usd_path = original_usd_path
return prim

def _post_load(self):
# We run this post loading first before any others because we're modifying the load config that will be used
# downstream
Expand Down Expand Up @@ -323,6 +308,7 @@ def _update_texture_change(self, object_state):
# else:
# print(f"Warning: DatasetObject [{self.prim_path}] does not have texture map: "
# f"[{target_texture_path}]. Falling back to directly updating albedo value.")

self._update_albedo_value(object_state, material)

def set_bbox_center_position_orientation(self, position=None, orientation=None):
Expand Down
8 changes: 8 additions & 0 deletions omnigibson/objects/light_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from omnigibson.utils.python_utils import assert_valid_key
from omnigibson.utils.constants import PrimType
from omnigibson.utils.ui_utils import create_module_logger
import numpy as np

# Create module logger
log = create_module_logger(module_name=__name__)
Expand Down Expand Up @@ -137,6 +138,13 @@ def _initialize(self):
# Initialize light link
self._light_link.initialize()

@property
def aabb(self):
# This is a virtual object (with no associated visual mesh), so omni returns an invalid AABB.
# Therefore we instead return a hardcoded small value
return np.ones(3) * -0.001, np.ones(3) * 0.001


@property
def light_link(self):
"""
Expand Down
13 changes: 9 additions & 4 deletions omnigibson/objects/stateful_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,11 +444,16 @@ def _update_albedo_value(object_state, material):
# Query the object state for the parameters
albedo_add, diffuse_tint = object_state.get_texture_change_params()

if material.albedo_add != albedo_add:
material.albedo_add = albedo_add
if material.is_glass:
if not np.allclose(material.glass_color, diffuse_tint):
material.glass_color = diffuse_tint

if not np.allclose(material.diffuse_tint, diffuse_tint):
material.diffuse_tint = diffuse_tint
else:
if material.albedo_add != albedo_add:
material.albedo_add = albedo_add

if not np.allclose(material.diffuse_tint, diffuse_tint):
material.diffuse_tint = diffuse_tint

def remove(self):
"""
Expand Down
25 changes: 24 additions & 1 deletion omnigibson/objects/usd_object.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import os
import tempfile

import omnigibson as og
from omnigibson.objects.stateful_object import StatefulObject
from omnigibson.utils.constants import PrimType
from omnigibson.utils.usd_utils import add_asset_to_stage
from omnigibson.utils.asset_utils import decrypt_file


class USDObject(StatefulObject):
Expand All @@ -13,6 +18,7 @@ def __init__(
self,
name,
usd_path,
encrypted=False,
prim_path=None,
category="object",
class_id=None,
Expand All @@ -32,6 +38,7 @@ def __init__(
Args:
name (str): Name for the object. Names need to be unique per scene
usd_path (str): global path to the USD file to load
encrypted (bool): whether this file is encrypted (and should therefore be decrypted) or not
prim_path (None or str): global path in the stage to this object. If not specified, will automatically be
created at /World/<name>
category (str): Category for the object. Defaults to "object".
Expand Down Expand Up @@ -59,6 +66,7 @@ def __init__(
that kwargs are only shared between all SUBclasses (children), not SUPERclasses (parents).
"""
self._usd_path = usd_path
self._encrypted = encrypted
super().__init__(
prim_path=prim_path,
name=name,
Expand All @@ -81,7 +89,22 @@ def _load(self):
"""
Load the object into pybullet and set it to the correct pose
"""
return add_asset_to_stage(asset_path=self._usd_path, prim_path=self._prim_path)
usd_path = self._usd_path
if self._encrypted:
# Create a temporary file to store the decrytped asset, load it, and then delete it
encrypted_filename = self._usd_path.replace(".usd", ".encrypted.usd")
decrypted_fd, usd_path = tempfile.mkstemp(os.path.basename(self._usd_path), dir=og.tempdir)
decrypt_file(encrypted_filename, usd_path)

prim = add_asset_to_stage(asset_path=usd_path, prim_path=self._prim_path)

if self._encrypted:
os.close(decrypted_fd)
# On Windows, Isaac Sim won't let go of the file until the prim is removed, so we can't delete it.
if os.name == "posix":
os.remove(usd_path)

return prim

def _create_prim_with_same_kwargs(self, prim_path, name, load_config):
# Add additional kwargs
Expand Down
Loading

0 comments on commit aa8b870

Please sign in to comment.