Skip to content

Commit

Permalink
Merge pull request #575 from StanfordVL/avg-specs
Browse files Browse the repository at this point in the history
Fix avg_obj_dims, remove fit_avg_dim_volume
  • Loading branch information
cgokmen authored Jan 27, 2024
2 parents 681ab24 + d3a9bfd commit e142994
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 42 deletions.
1 change: 0 additions & 1 deletion omnigibson/examples/objects/load_object_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ def main(random_selection=False, headless=False, short_exec=False):
category=obj_category,
model=obj_model,
bounding_box=avg_category_spec.get(obj_category),
fit_avg_dim_volume=True,
position=[0, 0, 50.0],
)

Expand Down
2 changes: 0 additions & 2 deletions omnigibson/examples/robots/grasping_mode_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def main(random_selection=False, headless=False, short_exec=False):
category="breakfast_table",
model="lcsizg",
bounding_box=[0.5, 0.5, 0.8],
fit_avg_dim_volume=False,
fixed_base=True,
position=[0.7, -0.1, 0.6],
orientation=[0, 0, 0.707, 0.707],
Expand All @@ -58,7 +57,6 @@ def main(random_selection=False, headless=False, short_exec=False):
category="straight_chair",
model="amgwaw",
bounding_box=None,
fit_avg_dim_volume=True,
fixed_base=False,
position=[0.45, 0.65, 0.425],
orientation=[0, 0, -0.9990215, -0.0442276],
Expand Down
33 changes: 6 additions & 27 deletions omnigibson/objects/dataset_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ def __init__(
abilities=None,
include_default_states=True,
bounding_box=None,
fit_avg_dim_volume=False,
in_rooms=None,
**kwargs,
):
Expand Down Expand Up @@ -98,8 +97,6 @@ def __init__(
bounding_box (None or 3-array): If specified, will scale this object such that it fits in the desired
(x,y,z) object-aligned bounding box. Note that EITHER @bounding_box or @scale may be specified
-- not both!
fit_avg_dim_volume (bool): whether to fit the object to have the same volume as the average dimension
while keeping the aspect ratio. Note that if this is set, it will override both @scale and @bounding_box
in_rooms (None or str or list): If specified, sets the room(s) that this object should belong to. Either
a list of room type(s) or a single room type
kwargs (dict): Additional keyword arguments that are used for other super() calls from subclasses, allowing
Expand All @@ -117,7 +114,6 @@ def __init__(
# Add info to load config
load_config = dict() if load_config is None else load_config
load_config["bounding_box"] = bounding_box
load_config["fit_avg_dim_volume"] = fit_avg_dim_volume

# Infer the correct usd path to use
if model is None:
Expand Down Expand Up @@ -223,19 +219,8 @@ def recursive_light_update(child_prim):
joint.friction = friction

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
# Set the scale of this prim according to its bounding box
if self._load_config["fit_avg_dim_volume"]:
# By default, we assume scale does not change if no avg obj specs are given, otherwise, scale accordingly
scale = np.ones(3)
if self.avg_obj_dims is not None and self.avg_obj_dims["size"] is not None:
# Find the average volume, and scale accordingly relative to the native volume based on the bbox
volume_ratio = np.product(self.avg_obj_dims["size"]) / np.product(self.native_bbox)
size_ratio = np.cbrt(volume_ratio)
scale *= size_ratio
# Otherwise, if manual bounding box is specified, scale based on ratio between that and the native bbox
elif self._load_config["bounding_box"] is not None:
# If manual bounding box is specified, scale based on ratio between that and the native bbox
if self._load_config["bounding_box"] is not None:
scale = np.ones(3)
valid_idxes = self.native_bbox > 1e-4
scale[valid_idxes] = np.array(self._load_config["bounding_box"])[valid_idxes] / self.native_bbox[valid_idxes]
Expand All @@ -259,22 +244,16 @@ def _post_load(self):
material.shader_update_asset_paths_with_root_path(root_path)

# Assign realistic density and mass based on average object category spec
if self.avg_obj_dims is not None and self.avg_obj_dims["size"] is not None and self.avg_obj_dims["mass"] is not None:
# Assume each link has the same density
v_ratio = (np.product(self.native_bbox) * np.product(self.scale)) / np.product(self.avg_obj_dims["size"])
mass = self.avg_obj_dims["mass"] * v_ratio
if self.avg_obj_dims is not None and self.avg_obj_dims["density"] is not None:
if self._prim_type == PrimType.RIGID:
density = mass / self.volume
for link in self._links.values():
# If not a meta (virtual) link, set the density based on avg_obj_dims and a zero mass (ignored)
if link.has_collision_meshes:
link.mass = 0.0
link.density = density
link.density = self.avg_obj_dims["density"]

elif self._prim_type == PrimType.CLOTH:
# Cloth cannot set density. Internally omni evenly distributes the mass to each particle
mass = self.avg_obj_dims["mass"] * v_ratio
self.root_link.mass = mass
self.root_link.mass = self.avg_obj_dims["density"] * self.root_link.volume

def _update_texture_change(self, object_state):
"""
Expand Down Expand Up @@ -617,7 +596,7 @@ def avg_obj_dims(self):
return AVERAGE_CATEGORY_SPECS.get(self.category, None)

def _create_prim_with_same_kwargs(self, prim_path, name, load_config):
# Add additional kwargs (fit_avg_dim_volume and bounding_box are already captured in load_config)
# Add additional kwargs (bounding_box is already captured in load_config)
return self.__class__(
prim_path=prim_path,
name=name,
Expand Down
2 changes: 1 addition & 1 deletion omnigibson/objects/light_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ def texture_file_path(self, texture_file_path):


def _create_prim_with_same_kwargs(self, prim_path, name, load_config):
# Add additional kwargs (fit_avg_dim_volume and bounding_box are already captured in load_config)
# Add additional kwargs (bounding_box is already captured in load_config)
return self.__class__(
prim_path=prim_path,
light_type=self.light_type,
Expand Down
2 changes: 1 addition & 1 deletion omnigibson/objects/primitive_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def size(self, size):
geom.GetExtentAttr().Set(lazy.pxr.Vt.Vec3fArray([lazy.pxr.Gf.Vec3f(*(-self._extents / 2.0)), lazy.pxr.Gf.Vec3f(*(self._extents / 2.0))]))

def _create_prim_with_same_kwargs(self, prim_path, name, load_config):
# Add additional kwargs (fit_avg_dim_volume and bounding_box are already captured in load_config)
# Add additional kwargs (bounding_box is already captured in load_config)
return self.__class__(
prim_path=prim_path,
primitive_type=self._primitive_type,
Expand Down
1 change: 0 additions & 1 deletion omnigibson/utils/bddl_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,6 @@ def _import_sampleable_objects(self):
name=f"{category}_{len(og.sim.scene.objects)}",
category=category,
model=model,
fit_avg_dim_volume=True,
prim_type=PrimType.CLOTH if "cloth" in OBJECT_TAXONOMY.get_abilities(obj_synset) else PrimType.RIGID,
)
num_new_obj += 1
Expand Down
15 changes: 8 additions & 7 deletions tests/test_object_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,23 +1146,24 @@ def test_covered():
)
for obj in (bracelet, oyster, breakfast_table):
for system in systems:
print(f"Testing Covered {obj.name} with {system.name}")
sampleable = is_visual_particle_system(system.name) or np.all(obj.aabb_extent > (2 * system.particle_radius))
obj.set_position_orientation(position=np.ones(3) * 50.0, orientation=[0, 0, 0, 1.0])
place_obj_on_floor_plane(obj)

for _ in range(5):
og.sim.step()

assert obj.states[Covered].set_value(system, True) == sampleable

for _ in range(5):
for _ in range(10):
og.sim.step()

assert obj.states[Covered].get_value(system) == sampleable
obj.states[Covered].set_value(system, False)

for _ in range(5):
og.sim.step()
assert obj.states[Covered].set_value(system, False)

# We don't call og.sim.step() here because it's possible for the "second" layer of particles to fall down
# and make Covered to be True again. Instead, we clear the caches and check that Covered is False.
obj.states[Covered].clear_cache()
obj.states[ContactParticles].clear_cache()
assert not obj.states[Covered].get_value(system)

system.remove_all_particles()
Expand Down
5 changes: 3 additions & 2 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def get_obj_cfg(name, category, model, prim_type=PrimType.RIGID, scale=None, bou
}

def assert_test_scene():
if og.sim.scene is None:
if og.sim is None or og.sim.scene is None:
cfg = {
"scene": {
"type": "Scene",
Expand Down Expand Up @@ -88,7 +88,8 @@ def assert_test_scene():
}

# Make sure sim is stopped
og.sim.stop()
if og.sim is not None:
og.sim.stop()

# Make sure GPU dynamics are enabled (GPU dynamics needed for cloth) and no flatcache
gm.ENABLE_OBJECT_STATES = True
Expand Down

0 comments on commit e142994

Please sign in to comment.