revive transition rules for parallel envs

This commit is contained in:
Chengshu Li 2024-06-27 15:29:39 -07:00
parent c062869158
commit a26c8c6bd9
27 changed files with 551 additions and 634 deletions

View File

@ -55,7 +55,6 @@ def clear():
from omnigibson.object_states.update_state_mixin import GlobalUpdateStateMixin
from omnigibson.prims.material_prim import MaterialPrim
from omnigibson.sensors.vision_sensor import VisionSensor
from omnigibson.transition_rules import TransitionRuleAPI
from omnigibson.utils.python_utils import clear as clear_python_utils
from omnigibson.utils.usd_utils import clear as clear_usd_utils
@ -90,10 +89,6 @@ def clear():
# Clear all materials
MaterialPrim.clear()
if gm.ENABLE_TRANSITION_RULES:
# Clear all transition rules
TransitionRuleAPI.clear()
# Clear uniquely named items and other internal states
clear_python_utils()
clear_usd_utils()

View File

@ -527,7 +527,7 @@ class SymbolicSemanticActionPrimitives(StarterSemanticActionPrimitives):
added_obj_attrs += output.add
removed_objs += output.remove
TransitionRuleAPI.execute_transition(added_obj_attrs=added_obj_attrs, removed_objs=removed_objs)
obj.scene.transition_rule_api.execute_transition(added_obj_attrs=added_obj_attrs, removed_objs=removed_objs)
yield from self._settle_robot()
def _place_near_heating_element(self, heat_source_obj):

View File

@ -115,7 +115,7 @@ class BaseController(Serializable, Registerable, Recreatable):
# Generate goal information
self._goal_shapes = self._get_goal_shapes()
self._goal_dim = int(np.sum([np.product(shape) for shape in self._goal_shapes.values()]))
self._goal_dim = int(np.sum([np.prod(shape) for shape in self._goal_shapes.values()]))
# Initialize some other variables that will be filled in during runtime
self._control = None
@ -339,7 +339,7 @@ class BaseController(Serializable, Registerable, Recreatable):
idx = 1
goal = dict()
for key, shape in self._goal_shapes.items():
length = np.product(shape)
length = np.prod(shape)
goal[key] = state[idx : idx + length].reshape(shape)
idx += length
else:

View File

@ -43,7 +43,7 @@ class Covered(RelativeObjectState, BooleanStateMixin):
"""
Utility function to destroy all corresponding attachment groups for this object
"""
for system in self.obj.scene.get_active_systems():
for system in self.obj.scene.active_systems.values():
if isinstance(system, VisualParticleSystem) and self._visual_particle_group in system.groups:
system.remove_attachment_group(self._visual_particle_group)

View File

@ -688,14 +688,6 @@ class ParticleModifier(IntrinsicObjectState, LinkBasedStateMixin, UpdateStateMix
"""
raise NotImplementedError()
@property
def supported_active_systems(self):
"""
Returns:
dict: Maps system names to corresponding systems used in this state that are active, dynamic across time
"""
return {system.name: system for system in self.obj.scene.get_active_systems()}
@property
def systems_to_check(self):
"""
@ -703,7 +695,7 @@ class ParticleModifier(IntrinsicObjectState, LinkBasedStateMixin, UpdateStateMix
tuple of str: System names that should be actively checked for particle modification at the current timestep
"""
# Default is all supported active systems
return tuple(self.supported_active_systems.keys())
return tuple(self.obj.scene.active_systems.keys())
@property
def projection_is_active(self):
@ -1027,7 +1019,7 @@ class ParticleApplier(ParticleModifier):
system_name = list(self.conditions.keys())[0]
# This will initialize the system if it's not initialized already.
system = self.obj.scene.system_registry("name", system_name)
system = self.obj.scene.get_system(system_name)
if self.visualize:
assert self._projection_mesh_params["type"] in {
@ -1221,7 +1213,7 @@ class ParticleApplier(ParticleModifier):
# Create an attachment group if necessary
if group not in system.groups:
system.create_attachment_group(obj=self.obj)
avg_scale = np.cbrt(np.product(self.obj.scale))
avg_scale = np.cbrt(np.prod(self.obj.scale))
scales = system.sample_scales_by_group(group=group, n=len(start_points))
cuboid_dimensions = scales * system.particle_object.aabb_extent.reshape(1, 3) * avg_scale
else:
@ -1278,7 +1270,7 @@ class ParticleApplier(ParticleModifier):
# Generate particle info -- maps group name to particle info for that group,
# i.e.: positions, orientations, and link_prim_paths
particles_info = defaultdict(lambda: defaultdict(lambda: []))
modifier_avg_scale = np.cbrt(np.product(self.obj.scale))
modifier_avg_scale = np.cbrt(np.prod(self.obj.scale))
for hit, scale in zip(hits[:n_particles], scales[:n_particles]):
# Infer which object was hit
hit_obj = self.obj.scene.object_registry("prim_path", "/".join(hit[3].split("/")[:-1]), None)
@ -1294,9 +1286,7 @@ class ParticleApplier(ParticleModifier):
# (in the USD hierarchy) underneath the in_contact object, we need to compensate for the relative
# scale differences between the two objects, so that "moving" the particle to the new object won't
# cause it to unexpectedly shrink / grow based on that parent's (potentially) different scale
particles_info[group]["scales"].append(
scale * modifier_avg_scale / np.cbrt(np.product(hit_obj.scale))
)
particles_info[group]["scales"].append(scale * modifier_avg_scale / np.cbrt(np.prod(hit_obj.scale)))
particles_info[group]["link_prim_paths"].append(hit[3])
# Generate all the particles for each group
for group, particle_info in particles_info.items():
@ -1325,7 +1315,6 @@ class ParticleApplier(ParticleModifier):
else -self._initial_speed * np.array([hit[1] for hit in hits[:n_particles]])
)
system.generate_particles(
scene=self.obj.scene,
positions=np.array([hit[0] for hit in hits[:n_particles]]),
velocities=velocities,
)
@ -1367,7 +1356,6 @@ class ParticleApplier(ParticleModifier):
if n_particles > 0:
velocities = None if self._initial_speed == 0 else self._initial_speed * directions[:n_particles]
system.generate_particles(
scene=self.obj.scene,
positions=points[:n_particles],
velocities=velocities,
)

View File

@ -78,7 +78,7 @@ class ModifiedParticles(RelativeObjectState):
np.concatenate(
[
(
self.obj.scene.system_registry("name", system_name).uuid,
self.obj.scene.get_system(system_name, force_active=False).uuid,
state[system_name],
)
for system_name in system_names
@ -168,7 +168,7 @@ class Saturated(RelativeObjectState, BooleanStateMixin):
colors = []
for system_name in self._limits.keys():
system = self.obj.scene.system_registry("name", system_name)
system = self.obj.scene.get_system(system_name)
if self.get_value(system):
colors.append(system.color)
@ -236,7 +236,7 @@ class Saturated(RelativeObjectState, BooleanStateMixin):
np.concatenate(
[
(
self.obj.scene.system_registry("name", system_name).uuid,
self.obj.scene.get_system(system_name, force_active=False).uuid,
state[system_name],
)
for system_name in system_names

View File

@ -165,8 +165,8 @@ class TensorizedValueState(AbsoluteObjectState, GlobalUpdateStateMixin):
@property
def state_size(self):
# This is the flattened size of @self.value_shape
# Note that np.product(()) returns 1, which is also correct for a non-arrayed value
return int(np.product(self.value_shape))
# Note that np.prod(()) returns 1, which is also correct for a non-arrayed value
return int(np.prod(self.value_shape))
# For this state, we simply store its value.
def _dump_state(self):
@ -185,7 +185,7 @@ class TensorizedValueState(AbsoluteObjectState, GlobalUpdateStateMixin):
return val.flatten().astype(float)
def deserialize(self, state):
value_length = int(np.product(self.value_shape))
value_length = int(np.prod(self.value_shape))
value = state[:value_length].reshape(self.value_shape) if len(self.value_shape) > 0 else state[0]
return {self.value_name: value}, value_length

View File

@ -441,7 +441,7 @@ class StatefulObject(BaseObject):
state = self.states[state_type]
if state_type in get_texture_change_states():
if state_type == Saturated:
for particle_system in self.scene.get_active_systems():
for particle_system in self.scene.active_systems.values():
if state.get_value(particle_system):
texture_change_states.append(state)
# Only need to do this once, since soaked handles all fluid systems

View File

@ -111,7 +111,7 @@ class ClothPrim(GeomPrim):
* max(min(true_aabb[1][1], keypoint_aabb[1][1]) - max(true_aabb[0][1], keypoint_aabb[0][1]), 0)
* max(min(true_aabb[1][2], keypoint_aabb[1][2]) - max(true_aabb[0][2], keypoint_aabb[0][2]), 0)
)
true_vol = np.product(true_aabb[1] - true_aabb[0])
true_vol = np.prod(true_aabb[1] - true_aabb[0])
if true_vol == 0.0 or overlap_vol / true_vol > m.KEYPOINT_COVERAGE_THRESHOLD:
success = True
break
@ -603,7 +603,7 @@ class ClothPrim(GeomPrim):
idx += 2
for key, size in zip(keys, sizes):
length = np.product(size)
length = np.prod(size)
state_dict[key] = state[idx : idx + length].reshape(size)
idx += length

View File

@ -212,7 +212,7 @@ class RigidPrim(XFormPrim):
volume, com = get_mesh_volume_and_com(mesh_prim)
# We need to transform the volume and CoM from the mesh's local frame to the link's local frame
local_pos, local_orn = mesh.get_local_pose()
vols.append(volume * np.product(mesh.scale))
vols.append(volume * np.prod(mesh.scale))
coms.append(T.quat2mat(local_orn) @ (com * mesh.scale) + local_pos)
# If the ratio between the max extent and min radius is too large (i.e. shape too oblong), use
# boundingCube approximation for the underlying collision approximation for GPU compatibility

View File

@ -24,6 +24,7 @@ from omnigibson.systems.system_base import (
VisualParticleSystem,
create_system_from_metadata,
)
from omnigibson.transition_rules import TransitionRuleAPI
from omnigibson.utils.constants import STRUCTURE_CATEGORIES
from omnigibson.utils.python_utils import (
Recreatable,
@ -83,6 +84,7 @@ class Scene(Serializable, Registerable, Recreatable, ABC):
self._floor_plane_visible = floor_plane_visible
self._floor_plane_color = floor_plane_color
self._use_skybox = use_skybox
self._transition_rule_api = None
# Call super init
super().__init__()
@ -207,6 +209,10 @@ class Scene(Serializable, Registerable, Recreatable, ABC):
def use_floor_plane(self):
return self._use_floor_plane
@property
def transition_rule_api(self):
return self._transition_rule_api
def prebuild(self):
"""
Prebuild the scene USD before loading it into the simulator. This is useful for caching the scene USD for faster
@ -390,6 +396,9 @@ class Scene(Serializable, Registerable, Recreatable, ABC):
if self.scene_file is not None:
self._load_metadata_from_scene_file()
if gm.ENABLE_TRANSITION_RULES:
self._transition_rule_api = TransitionRuleAPI(scene=self)
# Always stop the sim if we started it internally
if not og.sim.is_stopped():
og.sim.stop()
@ -401,7 +410,7 @@ class Scene(Serializable, Registerable, Recreatable, ABC):
Clears any internal state before the scene is destroyed
"""
# Clears systems so they can be re-initialized.
for system in self.get_active_systems():
for system in self.active_systems.values():
system.clear()
# Remove all of the scene's objects.
@ -410,6 +419,10 @@ class Scene(Serializable, Registerable, Recreatable, ABC):
# Remove the scene prim.
self._scene_prim.remove()
if gm.ENABLE_TRANSITION_RULES:
# Clear the transition rule API
self._transition_rule_api.clear()
def _initialize(self):
"""
Initializes state of this scene and sets up any references necessary post-loading. Should be implemented by
@ -649,25 +662,16 @@ class Scene(Serializable, Registerable, Recreatable, ABC):
}
def is_system_active(self, system_name):
system = self.system_registry("name", system_name)
if system is None:
return False
return system.initialized
return self.get_system(system_name, force_active=False).initialized
def is_visual_particle_system(self, system_name):
system = self.system_registry("name", system_name)
assert system is not None, f"System {system_name} not in system registry."
return isinstance(system, VisualParticleSystem)
return isinstance(self.get_system(system_name, force_active=False), VisualParticleSystem)
def is_physical_particle_system(self, system_name):
system = self.system_registry("name", system_name)
assert system is not None, f"System {system_name} not in system registry."
return isinstance(system, PhysicalParticleSystem)
return isinstance(self.get_system(system_name, force_active=False), PhysicalParticleSystem)
def is_fluid_system(self, system_name):
system = self.system_registry("name", system_name)
assert system is not None, f"System {system_name} not in system registry."
return isinstance(system, FluidSystem)
return isinstance(self.get_system(system_name, force_active=False), FluidSystem)
def get_system(self, system_name, force_active=True):
# Make sure scene exists
@ -679,8 +683,25 @@ class Scene(Serializable, Registerable, Recreatable, ABC):
system.initialize(scene=self)
return system
def get_active_systems(self):
return [system for system in self.systems if system.initialized]
@property
def active_visual_particle_systems(self):
return {
system.name: system
for system in self.systems
if system.initialized and self.is_visual_particle_system(system.name)
}
@property
def active_physical_particle_systems(self):
return {
system.name: system
for system in self.systems
if system.initialized and self.is_physical_particle_system(system.name)
}
@property
def active_systems(self):
return dict(**self.active_visual_particle_systems, **self.active_physical_particle_systems)
def get_random_floor(self):
"""

View File

@ -30,7 +30,6 @@ from omnigibson.prims.material_prim import MaterialPrim
from omnigibson.scenes import Scene
from omnigibson.sensors.vision_sensor import VisionSensor
from omnigibson.systems.macro_particle_system import MacroPhysicalParticleSystem
from omnigibson.transition_rules import TransitionRuleAPI
from omnigibson.utils.config_utils import NumpyEncoder
from omnigibson.utils.constants import LightingMode
from omnigibson.utils.python_utils import Serializable
@ -669,20 +668,23 @@ def launch_simulator(*args, **kwargs):
# One physics timestep will elapse
self.step_physics()
scenes_modified = set()
for ob in objs:
scenes_modified.add(ob.scene)
self._remove_object(ob)
if self.is_playing():
# Update all handles that are now broken because objects have changed
self.update_handles()
if gm.ENABLE_TRANSITION_RULES:
# Prune the transition rules that are currently active
for scene in scenes_modified:
scene.transition_rule_api.prune_active_rules()
# Load the state back
self.load_state(state)
if gm.ENABLE_TRANSITION_RULES:
# Refresh all current rules
TransitionRuleAPI.prune_active_rules()
def _remove_object(self, obj):
"""
Remove a non-robot object from the simulator. Should not be called directly by the user.
@ -747,7 +749,7 @@ def launch_simulator(*args, **kwargs):
# Only need to update if object is already initialized as well
if obj.initialized:
obj.update_handles()
for system in scene.get_active_systems():
for system in scene.active_systems.values():
if isinstance(system, MacroPhysicalParticleSystem):
system.refresh_particles_view()
@ -779,9 +781,11 @@ def launch_simulator(*args, **kwargs):
# For this same reason, after we finish the loop, we keep any objects that are yet to be initialized
# First call zero-physics step update, so that handles are properly propagated
og.sim.pi.update_simulation(elapsedStep=0, currentTime=og.sim.current_time)
scenes_modified = set()
for i in range(n_objects_to_initialize):
obj = self._objects_to_initialize[i]
obj.initialize()
scenes_modified.add(obj.scene)
if len(obj.states.keys() & self.object_state_types_on_contact) > 0:
self._objects_require_contact_callback = True
if len(obj.states.keys() & self.object_state_types_on_joint_break) > 0:
@ -793,12 +797,13 @@ def launch_simulator(*args, **kwargs):
self.update_handles()
if gm.ENABLE_TRANSITION_RULES:
# Also refresh the transition rules that are currently active
TransitionRuleAPI.refresh_all_rules()
# Refresh the transition rules
for scene in scenes_modified:
scene.transition_rule_api.refresh_all_rules()
# Update any system-related state
for scene in self.scenes:
for system in scene.get_active_systems():
for system in scene.active_systems.values():
system.update()
# Propagate states if the feature is enabled
@ -823,7 +828,8 @@ def launch_simulator(*args, **kwargs):
# Possibly run transition rule step
if gm.ENABLE_TRANSITION_RULES:
TransitionRuleAPI.step()
for scene in self.scenes:
scene.transition_rule_api.step()
def _omni_update_step(self):
"""
@ -875,8 +881,10 @@ def launch_simulator(*args, **kwargs):
for robot in scene.robots:
if robot.initialized:
robot.update_controller_mode()
if gm.ENABLE_TRANSITION_RULES:
TransitionRuleAPI.refresh_all_rules()
# Also refresh any transition rules that became stale while sim was stopped
if gm.ENABLE_TRANSITION_RULES:
scene.transition_rule_api.refresh_all_rules()
# Additionally run non physics things
self._non_physics_step()

View File

@ -61,7 +61,7 @@ class MacroParticleSystem(BaseSystem):
self._particle_counter = 0
# Create the system prim -- this is merely a scope prim
og.sim.stage.DefinePrim(f"/World/scene_{self._scene.idx}/{self.name}", "Scope")
og.sim.stage.DefinePrim(f"/World/scene_{scene.idx}/{self.name}", "Scope")
# Load the particle template, and make it kinematic only because it's not interacting with anything
particle_template = self._create_particle_template()
@ -220,7 +220,7 @@ class MacroParticleSystem(BaseSystem):
)
self._color = color
def add_particle(self, scene, relative_prim_path, scale, idn=None):
def add_particle(self, relative_prim_path, scale, idn=None):
"""
Adds a particle to this system.
@ -239,9 +239,7 @@ class MacroParticleSystem(BaseSystem):
assert (
self.particles is None or name not in self.particles.keys()
), f"Cannot create particle with name {name} because it already exists!"
new_particle = self._load_new_particle(
scene=scene, relative_prim_path=f"{relative_prim_path}/{name}", name=name
)
new_particle = self._load_new_particle(relative_prim_path=f"{relative_prim_path}/{name}", name=name)
# Set the scale and make sure the particle is visible
new_particle.scale *= scale
@ -273,7 +271,6 @@ class MacroParticleSystem(BaseSystem):
def generate_particles(
self,
scene,
positions,
orientations=None,
scales=None,
@ -292,12 +289,12 @@ class MacroParticleSystem(BaseSystem):
# Add particles
for scale in scales:
self.add_particle(scene=scene, relative_prim_path=f"{self.relative_prim_path}/particles", scale=scale)
self.add_particle(relative_prim_path=f"{self.relative_prim_path}/particles", scale=scale)
# Set the tfs
self.set_particles_position_orientation(positions=positions, orientations=orientations)
def _load_new_particle(self, scene, relative_prim_path, name):
def _load_new_particle(self, relative_prim_path, name):
"""
Loads a new particle into the current stage, leveraging @self.particle_object as a template for the new particle
to load. This function should be implemented by any subclasses.
@ -458,10 +455,10 @@ class MacroVisualParticleSystem(MacroParticleSystem, VisualParticleSystem):
group=group, positions=positions, orientations=orientations
)
def _load_new_particle(self, scene, relative_prim_path, name):
def _load_new_particle(self, relative_prim_path, name):
# We copy the template prim and generate the new object if the prim doesn't already exist, otherwise we
# reference the pre-existing one
prim_path = scene_relative_prim_path_to_absolute(scene, relative_prim_path)
prim_path = scene_relative_prim_path_to_absolute(self.scene, relative_prim_path)
if not lazy.omni.isaac.core.utils.prims.get_prim_at_path(prim_path):
lazy.omni.kit.commands.execute(
"CopyPrim",
@ -475,7 +472,7 @@ class MacroVisualParticleSystem(MacroParticleSystem, VisualParticleSystem):
type_label="class",
)
result = VisualGeomPrim(relative_prim_path=relative_prim_path, name=name)
result.load(scene)
result.load(self.scene)
return result
def _clear(self):
@ -573,8 +570,7 @@ class MacroVisualParticleSystem(MacroParticleSystem, VisualParticleSystem):
# Create particle
particle_prim_path = obj.prim_path if is_cloth else link_prim_path
particle = self.add_particle(
scene=obj.scene,
relative_prim_path=absolute_prim_path_to_scene_relative(obj.scene, particle_prim_path),
relative_prim_path=absolute_prim_path_to_scene_relative(self.scene, particle_prim_path),
scale=scale,
)
@ -605,7 +601,7 @@ class MacroVisualParticleSystem(MacroParticleSystem, VisualParticleSystem):
scales = self.sample_scales_by_group(group=group, n=max_samples)
# For sampling particle positions, we need the global bbox extents, NOT the local extents
# which is what we would get naively if we directly use @scales
avg_scale = np.cbrt(np.product(obj.scale))
avg_scale = np.cbrt(np.prod(obj.scale))
bbox_extents_global = scales * self.particle_object.aabb_extent.reshape(1, 3) * avg_scale
@ -972,7 +968,7 @@ class MacroVisualParticleSystem(MacroParticleSystem, VisualParticleSystem):
# Create any groups we don't already have
for name in groups_to_create:
obj = self._scene.object_registry("name", name)
obj = self.scene.object_registry("name", name)
info = name_to_info_mapping[name]
self.create_attachment_group(obj=obj)
is_cloth = self._is_cloth_obj(obj=obj)
@ -982,8 +978,7 @@ class MacroVisualParticleSystem(MacroParticleSystem, VisualParticleSystem):
# Use scale (1,1,1) since it will get overridden anyways when loading state
particle_prim_path = obj.prim_path if is_cloth else obj.links[reference].prim_path
particle = self.add_particle(
scene=obj.scene,
relative_prim_path=absolute_prim_path_to_scene_relative(obj.scene, particle_prim_path),
relative_prim_path=absolute_prim_path_to_scene_relative(self.scene, particle_prim_path),
scale=np.ones(3),
idn=int(particle_idn),
)
@ -1055,7 +1050,7 @@ class MacroVisualParticleSystem(MacroParticleSystem, VisualParticleSystem):
indices_to_remove = np.array([], dtype=int)
for info in state["groups"].values():
obj = self._scene.object_registry("uuid", info["particle_attached_obj_uuid"])
obj = self.scene.object_registry("uuid", info["particle_attached_obj_uuid"])
# obj will be None if an object with an attachment group is removed between dump_state() and load_state()
if obj is not None:
group_objects.append(obj)
@ -1109,7 +1104,7 @@ class MacroVisualParticleSystem(MacroParticleSystem, VisualParticleSystem):
idx = 1
for i in range(n_groups):
obj_uuid, n_particles = int(state[idx]), int(state[idx + 1])
obj = self._scene.object_registry("uuid", obj_uuid)
obj = self.scene.object_registry("uuid", obj_uuid)
assert obj is not None, f"Object with UUID {obj_uuid} not found in the scene"
is_cloth = self._is_cloth_obj(obj=obj)
group_obj_id2link = {i: link_name for i, link_name in enumerate(obj.links.keys())}
@ -1203,10 +1198,10 @@ class MacroPhysicalParticleSystem(MacroParticleSystem, PhysicalParticleSystem):
if og.sim.is_playing():
self.refresh_particles_view()
def _load_new_particle(self, scene, relative_prim_path, name):
def _load_new_particle(self, relative_prim_path, name):
# We copy the template prim and generate the new object if the prim doesn't already exist, otherwise we
# reference the pre-existing one
prim_path = scene_relative_prim_path_to_absolute(scene, relative_prim_path)
prim_path = scene_relative_prim_path_to_absolute(self.scene, relative_prim_path)
if not lazy.omni.isaac.core.utils.prims.get_prim_at_path(prim_path):
lazy.omni.kit.commands.execute(
"CopyPrim",
@ -1222,7 +1217,7 @@ class MacroPhysicalParticleSystem(MacroParticleSystem, PhysicalParticleSystem):
type_label="class",
)
result = CollisionVisualGeomPrim(relative_prim_path=relative_prim_path, name=name)
result.load(scene)
result.load(self.scene)
return result
def process_particle_object(self):
@ -1275,9 +1270,9 @@ class MacroPhysicalParticleSystem(MacroParticleSystem, PhysicalParticleSystem):
# Refresh particles view
self.refresh_particles_view()
def add_particle(self, scene, relative_prim_path, scale, idn=None):
def add_particle(self, relative_prim_path, scale, idn=None):
# Run super first
particle = super().add_particle(scene=scene, relative_prim_path=relative_prim_path, scale=scale, idn=idn)
particle = super().add_particle(relative_prim_path=relative_prim_path, scale=scale, idn=idn)
# Refresh particles view
self.refresh_particles_view()
@ -1410,7 +1405,6 @@ class MacroPhysicalParticleSystem(MacroParticleSystem, PhysicalParticleSystem):
def generate_particles(
self,
scene,
positions,
orientations=None,
velocities=None,
@ -1435,7 +1429,6 @@ class MacroPhysicalParticleSystem(MacroParticleSystem, PhysicalParticleSystem):
"""
# Call super first
super().generate_particles(
scene=self._scene,
positions=positions,
orientations=orientations,
scales=scales,
@ -1480,9 +1473,7 @@ class MacroPhysicalParticleSystem(MacroParticleSystem, PhysicalParticleSystem):
if n_particles_to_generate > 0:
for i in range(n_particles_to_generate):
# Min scale == max scale, so no need for sampling
self.add_particle(
scene=None, relative_prim_path=f"{self.relative_prim_path}/particles", scale=self.max_scale
)
self.add_particle(relative_prim_path=f"{self.relative_prim_path}/particles", scale=self.max_scale)
else:
# Remove excess particles
self.remove_particles(idxs=np.arange(-n_particles_to_generate))

View File

@ -109,9 +109,9 @@ class PhysxParticleInstancer(BasePrim):
def remove(self):
# We need to create this parent prim to avoid calling the low level omniverse delete prim method
parent_absolute_path = self.prim.GetParent().GetPath().pathString
parent_relative_path = absolute_prim_path_to_scene_relative(self._scene, parent_absolute_path)
parent_relative_path = absolute_prim_path_to_scene_relative(self.scene, parent_absolute_path)
self._parent_prim = BasePrim(relative_prim_path=parent_relative_path, name=f"{self._name}_parent")
self._parent_prim.load(self._scene)
self._parent_prim.load(self.scene)
super().remove()
self._parent_prim.remove()
@ -358,12 +358,15 @@ class PhysxParticleInstancer(BasePrim):
local_positions = np.array(state["particle_positions"])
local_orientations = np.array(state["particle_orientations"])
global_positions, global_orientations = zip(
*[
T.pose_transform(*self.scene.prim.get_position_orientation(), local_pos, local_ori)
for local_pos, local_ori in zip(local_positions, local_orientations)
]
)
if local_positions.size == 0 and local_orientations.size == 0:
global_positions, global_orientations = [], []
else:
global_positions, global_orientations = zip(
*[
T.pose_transform(*self.scene.prim.get_position_orientation(), local_pos, local_ori)
for local_pos, local_ori in zip(local_positions, local_orientations)
]
)
setattr(self, "particle_positions", np.array(global_positions))
setattr(self, "particle_orientations", np.array(global_orientations))
@ -423,7 +426,7 @@ class PhysxParticleInstancer(BasePrim):
idx = 3
for key, size in zip(keys, sizes):
length = np.product(size)
length = np.prod(size)
state_dict[key] = state[idx : idx + length].reshape(size)
idx += length
@ -552,7 +555,7 @@ class MicroParticleSystem(BaseSystem):
"""
# Default is PBR material
return MaterialPrim.get_material(
scene=self._scene,
scene=self.scene,
prim_path=self.mat_path,
name=self.mat_name,
load_config={
@ -685,10 +688,10 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
self._particle_density = particle_density
# Particle prototypes -- will be list of mesh prims to use as particle prototypes for this system
self.particle_prototypes = None
self.particle_prototypes = list()
# Particle instancers -- maps name to particle instancer prims (dict)
self.particle_instancers = None
self.particle_instancers = dict()
self._particle_contact_offset = particle_contact_offset
@ -706,11 +709,7 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
@property
def n_particles(self):
return (
sum([instancer.n_particles for instancer in self.particle_instancers.values()])
if self.particle_instancers is not None
else 0
)
return sum([instancer.n_particles for instancer in self.particle_instancers.values()])
@property
def n_instancers(self):
@ -718,7 +717,7 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
Returns:
int: Number of active particles in this system
"""
return len(self.particle_instancers) if self.particle_instancers is not None else 0
return len(self.particle_instancers)
@property
def instancer_idns(self):
@ -726,7 +725,7 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
Returns:
int: Number of active particles in this system
"""
return [inst.idn for inst in self.particle_instancers.values()] if self.particle_instancers is not None else []
return [inst.idn for inst in self.particle_instancers.values()]
@property
def self_collision(self):
@ -771,8 +770,8 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
super()._clear()
self.particle_prototypes = None
self.particle_instancers = None
self.particle_prototypes = list()
self.particle_instancers = dict()
@property
def next_available_instancer_idn(self):
@ -795,14 +794,9 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
# We have the number of particle instancers (1), the instancer groups, particle groups, and,
# number of particles in each instancer (3n),
# and the corresponding states in each instancer (X)
if self.particle_instancers is None:
return 1
else:
return (
1
+ 3 * len(self.particle_instancers)
+ sum(inst.state_size for inst in self.particle_instancers.values())
)
return (
1 + 3 * len(self.particle_instancers) + sum(inst.state_size for inst in self.particle_instancers.values())
)
@property
def default_particle_instancer(self):
@ -815,7 +809,7 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
# NOTE: Cannot use dict.get() call for some reason; it messes up IDE introspection
return (
self.particle_instancers[name]
if self.particle_instancers and name in self.particle_instancers
if name in self.particle_instancers
else self.generate_particle_instancer(n_particles=0, idn=self.default_instancer_idn)
)
@ -875,7 +869,6 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
def generate_particles(
self,
scene,
positions,
instancer_idn=None,
particle_group=0,
@ -1031,16 +1024,13 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
enabled=not self.visual_only,
)
if self.particle_instancers is None:
self.particle_instancers = dict()
# Create the instancer object that wraps the raw prim
instancer = PhysxParticleInstancer(
relative_prim_path=absolute_prim_path_to_scene_relative(self._scene, instance.GetPrimPath().pathString),
relative_prim_path=absolute_prim_path_to_scene_relative(self.scene, instance.GetPrimPath().pathString),
name=name,
idn=idn,
)
instancer.load(self._scene)
instancer.load(self.scene)
instancer.initialize()
self.particle_instancers[name] = instancer
@ -1227,7 +1217,7 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
idn_to_info_mapping = {
idn: {"group": group, "count": count} for idn, group, count in zip(idns, particle_groups, particle_counts)
}
current_instancer_names = set(self.particle_instancers.keys()) if self.particle_instancers else set()
current_instancer_names = set(self.particle_instancers.keys())
desired_instancer_names = set(self.particle_instancer_idn_to_name(idn=idn) for idn in idns)
instancers_to_delete = current_instancer_names - desired_instancer_names
instancers_to_create = desired_instancer_names - current_instancer_names
@ -1262,16 +1252,10 @@ class MicroPhysicalParticleSystem(MicroParticleSystem, PhysicalParticleSystem):
return dict(
n_instancers=self.n_instancers,
instancer_idns=self.instancer_idns,
instancer_particle_groups=(
[inst.particle_group for inst in self.particle_instancers.values()] if self.particle_instancers else []
),
instancer_particle_counts=(
[inst.n_particles for inst in self.particle_instancers.values()] if self.particle_instancers else []
),
particle_states=(
dict(((name, inst.dump_state(serialized=False)) for name, inst in self.particle_instancers.items()))
if self.particle_instancers
else dict()
instancer_particle_groups=[inst.particle_group for inst in self.particle_instancers.values()],
instancer_particle_counts=[inst.n_particles for inst in self.particle_instancers.values()],
particle_states=dict(
((name, inst.dump_state(serialized=False)) for name, inst in self.particle_instancers.items())
),
)
@ -1472,7 +1456,7 @@ class FluidSystem(MicroPhysicalParticleSystem):
def _get_particle_material_template(self):
# We use a template from OmniPresets if @_material_mtl_name is specified, else the default OmniSurface
return MaterialPrim.get_material(
scene=self._scene,
scene=self.scene,
prim_path=self.mat_path,
name=self.mat_name,
load_config={

View File

@ -123,21 +123,26 @@ class BaseSystem(Serializable):
"""
assert not self.initialized, f"Already initialized system {self.name}!"
self._scene = scene
self.initialized = True
og.sim.stage.DefinePrim(self.prim_path, "Scope")
self.initialized = True
# Avoid circular import
if og.sim.is_playing() and gm.ENABLE_TRANSITION_RULES:
from omnigibson.transition_rules import TransitionRuleAPI
TransitionRuleAPI.refresh_all_rules()
scene.transition_rule_api.refresh_all_rules()
# Run any callbacks
for callback in og.sim.get_callbacks_on_system_init():
callback(self)
@property
def scene(self):
"""
Returns:
Scene or None: Scene object that this prim is loaded into
"""
assert self.initialized, f"System {self.name} has not been initialized yet!"
return self._scene
def update(self):
"""
Executes any necessary system updates, once per og.sim._non_physics_step
@ -167,7 +172,6 @@ class BaseSystem(Serializable):
def generate_particles(
self,
scene,
positions,
orientations=None,
scales=None,
@ -177,7 +181,6 @@ class BaseSystem(Serializable):
Generates new particles
Args:
scene (Scene): Scene object to generate particles in
positions (np.array): (n_particles, 3) shaped array specifying per-particle (x,y,z) positions
orientations (None or np.array): (n_particles, 4) shaped array specifying per-particle (x,y,z,w) quaternion
orientations. If not specified, all will be set to canonical orientation (0, 0, 0, 1)
@ -196,19 +199,17 @@ class BaseSystem(Serializable):
self._clear()
def _clear(self):
for callback in og.sim.get_callbacks_on_system_clear():
callback(self)
self.reset()
lazy.omni.isaac.core.utils.prims.delete_prim(self.prim_path)
self.initialized = False
# Avoid circular import
if og.sim.is_playing() and gm.ENABLE_TRANSITION_RULES:
from omnigibson.transition_rules import TransitionRuleAPI
self.scene.transition_rule_api.prune_active_rules()
TransitionRuleAPI.refresh_all_rules()
self.initialized = False
self._scene = None
def reset(self):
"""
@ -626,12 +627,11 @@ class VisualParticleSystem(BaseSystem):
# since the particles have a relative rotation w.r.t the object, the scale between the two don't align. As a
# heuristics, we divide it by the avg_scale, which is the cubic root of the product of the scales along 3 axes.
obj = self._group_objects[group]
avg_scale = np.cbrt(np.product(obj.scale))
avg_scale = np.cbrt(np.prod(obj.scale))
return scales / avg_scale
def generate_particles(
self,
scene,
positions,
orientations=None,
scales=None,
@ -897,7 +897,6 @@ class PhysicalParticleSystem(BaseSystem):
]
return self.generate_particles(
scene=self._scene,
positions=particle_positions,
**kwargs,
)
@ -956,7 +955,6 @@ class PhysicalParticleSystem(BaseSystem):
# If we generated a sufficient number of points, generate them in the simulator
if success:
self.generate_particles(
scene=self._scene,
positions=particle_positions,
**kwargs,
)

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,6 @@ from omnigibson.object_states.factory import _KINEMATIC_STATE_SET, get_system_st
from omnigibson.object_states.object_state_base import AbsoluteObjectState, RelativeObjectState
from omnigibson.objects.dataset_object import DatasetObject
from omnigibson.robots import BaseRobot
from omnigibson.scenes.interactive_traversable_scene import InteractiveTraversableScene
from omnigibson.utils.asset_utils import (
get_all_object_categories,
get_all_object_category_models_with_abilities,
@ -569,9 +568,7 @@ class BDDLSampler:
def __init__(self, env, activity_conditions, object_scope, backend):
# Store internal variables from inputs
self._env = env
self._scene_model = (
self._env.scene.scene_model if isinstance(self._env.scene, InteractiveTraversableScene) else None
)
self._scene_model = self._env.scene.scene_model
self._agent = self._env.robots[0]
self._backend = backend
self._activity_conditions = activity_conditions
@ -1015,8 +1012,8 @@ class BDDLSampler:
rigid_conditions = [c for c in conditions_to_sample if c[2].prim_type != PrimType.CLOTH]
cloth_conditions = [c for c in conditions_to_sample if c[2].prim_type == PrimType.CLOTH]
conditions_to_sample = list(
reversed(sorted(rigid_conditions, key=lambda x: np.product(x[2].aabb_extent)))
) + list(reversed(sorted(cloth_conditions, key=lambda x: np.product(x[2].aabb_extent))))
reversed(sorted(rigid_conditions, key=lambda x: np.prod(x[2].aabb_extent)))
) + list(reversed(sorted(cloth_conditions, key=lambda x: np.prod(x[2].aabb_extent))))
# Sample!
for condition, positive, entity, child_scope_name in conditions_to_sample:
@ -1213,9 +1210,7 @@ class BDDLSampler:
self._object_scope[obj_inst] = BDDLEntity(
bddl_inst=obj_inst,
entity=(
None
if obj_inst in self._future_obj_instances
else self._env.scene.system_registry("name", system_name)
None if obj_inst in self._future_obj_instances else self._env.scene.get_system(system_name)
),
)
else:
@ -1368,8 +1363,8 @@ class BDDLSampler:
rigid_conditions = [c for c in conditions_to_sample if c[2].prim_type != PrimType.CLOTH]
cloth_conditions = [c for c in conditions_to_sample if c[2].prim_type == PrimType.CLOTH]
conditions_to_sample = list(
reversed(sorted(rigid_conditions, key=lambda x: np.product(x[2].aabb_extent)))
) + list(reversed(sorted(cloth_conditions, key=lambda x: np.product(x[2].aabb_extent))))
reversed(sorted(rigid_conditions, key=lambda x: np.prod(x[2].aabb_extent)))
) + list(reversed(sorted(cloth_conditions, key=lambda x: np.prod(x[2].aabb_extent))))
# Sample!
for condition, positive, entity, child_scope_name in conditions_to_sample:

View File

@ -412,7 +412,7 @@ def generate_points_in_volume_checker_function(obj, volume_link, use_visual_mesh
mesh.visible = True
# Determine equally-spaced sampling distance to achieve this minimum particle count
aabb_volume = np.product(volume_link.visual_aabb_extent)
aabb_volume = np.prod(volume_link.visual_aabb_extent)
sampling_distance = np.cbrt(aabb_volume / min_n_particles)
low, high = volume_link.visual_aabb
n_particles_per_axis = ((high - low) / sampling_distance).astype(int) + 1

View File

@ -63,9 +63,9 @@ def benchmark_scene(scene_name, non_rigid_simulation=False, import_robot=True):
)
scene.add_object(cloth)
og.sim.step()
water_system = scene.system_registry("name", "water")
water_system = scene.get_system("water")
for i in range(100):
water_system.generate_particles(scene=scene, positions=[np.array([0.5, 0, 0.5]) + np.random.randn(3) * 0.1])
water_system.generate_particles(positions=[np.array([0.5, 0, 0.5]) + np.random.randn(3) * 0.1])
og.sim.step()
og.sim.play()

View File

@ -147,7 +147,7 @@ def main():
)
knife.keep_still()
if args.fluids:
table.states[Covered].set_value(env.scene.system_registry("name", "water"), True)
table.states[Covered].set_value(env.scene.get_system("water"))
output, results = [], []

View File

@ -15,7 +15,7 @@ def test_dump_load(env):
if issubclass(system_class, VisualParticleSystem):
assert breakfast_table.states[Covered].set_value(system, True)
else:
system.generate_particles(scene=env.scene, positions=[[0, 0, 1]])
system.generate_particles(positions=[[0, 0, 1]])
assert system.n_particles > 0
system.remove_all_particles()
@ -23,7 +23,7 @@ def test_dump_load(env):
og.sim.load_state(state)
for system_name, system_class in SYSTEM_EXAMPLES.items():
system = env.scene.system_registry("name", system_name)
system = env.scene.get_system(system_name)
system.clear()
@ -36,12 +36,12 @@ def test_dump_load_serialized(env):
if issubclass(system_class, VisualParticleSystem):
assert breakfast_table.states[Covered].set_value(system, True)
else:
system.generate_particles(scene=env.scene, positions=[[0, 0, 1]])
system.generate_particles(positions=[[0, 0, 1]])
assert system.n_particles > 0
state = og.sim.dump_state(serialized=True)
og.sim.load_state(state, serialized=True)
for system_name, system_class in SYSTEM_EXAMPLES.items():
system = env.scene.system_registry("name", system_name)
system = env.scene.get_system(system_name)
system.clear()

View File

@ -788,7 +788,7 @@ def test_particle_sink(env):
assert water_system.n_particles == 0
sink_pos = sink.states[ParticleSink].link.get_position()
water_system.generate_particles(scene=env.scene, positions=[sink_pos + np.array([0, 0, 0.05])])
water_system.generate_particles(positions=[sink_pos + np.array([0, 0, 0.05])])
# There should be exactly 1 water particle.
assert water_system.n_particles == 1
@ -883,7 +883,7 @@ def test_particle_remover(env):
water_system = env.scene.get_system("water")
# Place single particle of water on middle of table
water_system.generate_particles(
scene=env.scene, positions=[np.array([0, 0, breakfast_table.aabb[1][2] + water_system.particle_radius])]
positions=[np.array([0, 0, breakfast_table.aabb[1][2] + water_system.particle_radius])]
)
assert water_system.n_particles > 0
@ -910,7 +910,7 @@ def test_particle_remover(env):
og.sim.step()
# Place single particle of water on middle of table
water_system.generate_particles(
scene=env.scene, positions=[np.array([0, 0, breakfast_table.aabb[1][2] + water_system.particle_radius])]
positions=[np.array([0, 0, breakfast_table.aabb[1][2] + water_system.particle_radius])]
)
# Water should be present
@ -946,7 +946,6 @@ def test_saturated(env):
n_particles = 5
remover_dishtowel.states[Saturated].set_limit(water_system, n_particles)
water_system.generate_particles(
scene=env.scene,
positions=[
np.array([0, 0, remover_dishtowel.aabb[1][2] + water_system.particle_radius * (1 + 2 * i)])
for i in range(n_particles)
@ -1123,7 +1122,7 @@ def test_contains(env):
# Sample single particle
if env.scene.is_physical_particle_system(system_name=system.name):
system.generate_particles(scene=env.scene, positions=[np.array([0, 0, stockpot.aabb[1][2] - 0.1])])
system.generate_particles(positions=[np.array([0, 0, stockpot.aabb[1][2] - 0.1])])
else:
if system.get_group_name(stockpot) not in system.groups:
system.create_attachment_group(stockpot)

View File

@ -22,7 +22,7 @@ def test_seg(env):
# Sample two particles for each system
pos = np.array([-0.2 + i * 0.2, 0, 0.55])
if env.scene.is_physical_particle_system(system_name=system.name):
system.generate_particles(scene=env.scene, positions=[pos, pos + np.array([0.1, 0.0, 0.0])])
system.generate_particles(positions=[pos, pos + np.array([0.1, 0.0, 0.0])])
else:
if system.get_group_name(breakfast_table) not in system.groups:
system.create_attachment_group(breakfast_table)

View File

@ -218,7 +218,7 @@ class TestSymbolicPrimitives:
@pytest.mark.skip(reason="primitives are broken")
def test_soak_under(self, env, prim_gen, robot, sponge, sink):
water_system = env.scene.system_registry("name", "water", force_active=True)
water_system = env.scene.get_system("water")
assert not sponge.states[object_states.Saturated].get_value(water_system)
assert not sink.states[object_states.ToggledOn].get_value()
@ -243,12 +243,12 @@ class TestSymbolicPrimitives:
@pytest.mark.skip(reason="primitives are broken")
def test_wipe(self, env, prim_gen, sponge, sink, countertop):
# Some pre-assertions
water_system = env.scene.system_registry("name", "water", force_active=True)
water_system = env.scene.get_system("water")
assert not sponge.states[object_states.Saturated].get_value(water_system)
assert not sink.states[object_states.ToggledOn].get_value()
# Dirty the countertop as the setup
mud_system = env.scene.system_registry("name", "mud", force_active=True)
mud_system = env.scene.get_system("mud")
countertop.states[object_states.Covered].set_value(mud_system, True)
assert countertop.states[object_states.Covered].get_value(mud_system)

View File

@ -16,7 +16,7 @@ def test_system_clear(env):
if issubclass(system_class, VisualParticleSystem):
assert breakfast_table.states[Covered].set_value(system, True)
else:
system.generate_particles(scene=env.scene, positions=[[0, 0, 1]])
system.generate_particles(positions=[[0, 0, 1]])
assert system.n_particles > 0
og.sim.step()
system.clear()

View File

@ -19,8 +19,6 @@ from omnigibson.transition_rules import REGISTERED_RULES
from omnigibson.utils.constants import PrimType
from omnigibson.utils.physx_utils import apply_force_at_pos, apply_torque
pytestmark = pytest.mark.skip("Skip all transition rule tests for multiple-envs PR; will fix in a follow-up")
@og_test
def test_dryer_rule(env):
@ -28,7 +26,7 @@ def test_dryer_rule(env):
clothes_dryer = env.scene.object_registry("name", "clothes_dryer")
remover_dishtowel = env.scene.object_registry("name", "remover_dishtowel")
bowl = env.scene.object_registry("name", "bowl")
water = env.scene.system_registry("name", "water")
water = env.scene.get_system("water")
place_obj_on_floor_plane(clothes_dryer)
og.sim.step()
@ -73,7 +71,7 @@ def test_dryer_rule(env):
assert not clothes_dryer.states[Contains].get_value(water)
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -83,13 +81,13 @@ def test_washer_rule(env):
washer = env.scene.object_registry("name", "washer")
remover_dishtowel = env.scene.object_registry("name", "remover_dishtowel")
bowl = env.scene.object_registry("name", "bowl")
water = env.scene.system_registry("name", "water")
dust = env.scene.system_registry("name", "dust") # always remove
salt = env.scene.system_registry("name", "salt") # always remove (not explicitly specified)
rust = env.scene.system_registry("name", "rust") # never remove
spray_paint = env.scene.system_registry("name", "spray_paint") # requires acetone
acetone = env.scene.system_registry("name", "acetone") # solvent for spray paint
cooking_oil = env.scene.system_registry("name", "cooking_oil") # requires vinegar, lemon_juice, vinegar, etc.
water = env.scene.get_system("water")
dust = env.scene.get_system("dust") # always remove
salt = env.scene.get_system("salt") # always remove (not explicitly specified)
rust = env.scene.get_system("rust") # never remove
spray_paint = env.scene.get_system("spray_paint") # requires acetone
acetone = env.scene.get_system("acetone") # solvent for spray paint
cooking_oil = env.scene.get_system("cooking_oil") # requires vinegar, lemon_juice, vinegar, etc.
place_obj_on_floor_plane(washer)
og.sim.step()
@ -142,7 +140,7 @@ def test_washer_rule(env):
assert bowl.states[Covered].get_value(water)
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -199,7 +197,7 @@ def test_dicing_rule_cooked(env):
assert len(REGISTERED_RULES) > 0, "No rules registered!"
half_apple = env.scene.object_registry("name", "half_apple")
table_knife = env.scene.object_registry("name", "table_knife")
cooked_diced_apple = env.scene.system_registry("name", "cooked__diced__apple")
cooked_diced_apple = env.scene.get_system("cooked__diced__apple")
deleted_objs = [half_apple]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -232,7 +230,7 @@ def test_dicing_rule_cooked(env):
og.sim.step()
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
@ -245,7 +243,7 @@ def test_dicing_rule_uncooked(env):
assert len(REGISTERED_RULES) > 0, "No rules registered!"
half_apple = env.scene.object_registry("name", "half_apple")
table_knife = env.scene.object_registry("name", "table_knife")
diced_apple = env.scene.system_registry("name", "diced__apple")
diced_apple = env.scene.get_system("diced__apple")
deleted_objs = [half_apple]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -276,7 +274,7 @@ def test_dicing_rule_uncooked(env):
og.sim.step()
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
@ -290,7 +288,7 @@ def test_melting_rule(env):
stove = env.scene.object_registry("name", "stove")
stockpot = env.scene.object_registry("name", "stockpot")
swiss_cheese = env.scene.object_registry("name", "swiss_cheese")
melted_swiss_cheese = env.scene.system_registry("name", "melted__swiss_cheese")
melted_swiss_cheese = env.scene.get_system("melted__swiss_cheese")
deleted_objs = [swiss_cheese]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -326,7 +324,7 @@ def test_melting_rule(env):
assert env.scene.object_registry("name", obj.name) is None
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
@ -339,10 +337,10 @@ def test_cooking_physical_particle_rule_failure_recipe_systems(env):
assert len(REGISTERED_RULES) > 0, "No rules registered!"
stove = env.scene.object_registry("name", "stove")
stockpot = env.scene.object_registry("name", "stockpot")
arborio_rice = env.scene.system_registry("name", "arborio_rice")
water = env.scene.system_registry("name", "water")
cooked_water = env.scene.system_registry("name", "cooked__water")
cooked_arborio_rice = env.scene.system_registry("name", "cooked__arborio_rice")
arborio_rice = env.scene.get_system("arborio_rice")
water = env.scene.get_system("water")
cooked_water = env.scene.get_system("cooked__water")
cooked_arborio_rice = env.scene.get_system("cooked__arborio_rice")
place_obj_on_floor_plane(stove)
og.sim.step()
@ -371,7 +369,7 @@ def test_cooking_physical_particle_rule_failure_recipe_systems(env):
assert cooked_arborio_rice.n_particles == 0
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -379,10 +377,10 @@ def test_cooking_physical_particle_rule_success(env):
assert len(REGISTERED_RULES) > 0, "No rules registered!"
stove = env.scene.object_registry("name", "stove")
stockpot = env.scene.object_registry("name", "stockpot")
arborio_rice = env.scene.system_registry("name", "arborio_rice")
water = env.scene.system_registry("name", "water")
cooked_water = env.scene.system_registry("name", "cooked__water")
cooked_arborio_rice = env.scene.system_registry("name", "cooked__arborio_rice")
arborio_rice = env.scene.get_system("arborio_rice")
water = env.scene.get_system("water")
cooked_water = env.scene.get_system("cooked__water")
cooked_arborio_rice = env.scene.get_system("cooked__arborio_rice")
place_obj_on_floor_plane(stove)
og.sim.step()
@ -418,7 +416,7 @@ def test_cooking_physical_particle_rule_success(env):
assert cooked_arborio_rice.n_particles > 0
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -426,11 +424,11 @@ def test_mixing_rule_failure_recipe_systems(env):
assert len(REGISTERED_RULES) > 0, "No rules registered!"
bowl = env.scene.object_registry("name", "bowl")
tablespoon = env.scene.object_registry("name", "tablespoon")
water = env.scene.system_registry("name", "water")
granulated_sugar = env.scene.system_registry("name", "granulated_sugar")
lemon_juice = env.scene.system_registry("name", "lemon_juice")
lemonade = env.scene.system_registry("name", "lemonade")
sludge = env.scene.system_registry("name", "sludge")
water = env.scene.get_system("water")
granulated_sugar = env.scene.get_system("granulated_sugar")
lemon_juice = env.scene.get_system("lemon_juice")
lemonade = env.scene.get_system("lemonade")
sludge = env.scene.get_system("sludge")
place_obj_on_floor_plane(bowl)
og.sim.step()
@ -459,7 +457,7 @@ def test_mixing_rule_failure_recipe_systems(env):
assert granulated_sugar.n_particles == 0
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -467,12 +465,12 @@ def test_mixing_rule_failure_nonrecipe_systems(env):
assert len(REGISTERED_RULES) > 0, "No rules registered!"
bowl = env.scene.object_registry("name", "bowl")
tablespoon = env.scene.object_registry("name", "tablespoon")
water = env.scene.system_registry("name", "water")
granulated_sugar = env.scene.system_registry("name", "granulated_sugar")
lemon_juice = env.scene.system_registry("name", "lemon_juice")
lemonade = env.scene.system_registry("name", "lemonade")
salt = env.scene.system_registry("name", "salt")
sludge = env.scene.system_registry("name", "sludge")
water = env.scene.get_system("water")
granulated_sugar = env.scene.get_system("granulated_sugar")
lemon_juice = env.scene.get_system("lemon_juice")
lemonade = env.scene.get_system("lemonade")
salt = env.scene.get_system("salt")
sludge = env.scene.get_system("sludge")
place_obj_on_floor_plane(bowl)
og.sim.step()
@ -505,7 +503,7 @@ def test_mixing_rule_failure_nonrecipe_systems(env):
assert salt.n_particles == 0
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -513,10 +511,10 @@ def test_mixing_rule_success(env):
assert len(REGISTERED_RULES) > 0, "No rules registered!"
bowl = env.scene.object_registry("name", "bowl")
tablespoon = env.scene.object_registry("name", "tablespoon")
water = env.scene.system_registry("name", "water")
granulated_sugar = env.scene.system_registry("name", "granulated_sugar")
lemon_juice = env.scene.system_registry("name", "lemon_juice")
lemonade = env.scene.system_registry("name", "lemonade")
water = env.scene.get_system("water")
granulated_sugar = env.scene.get_system("granulated_sugar")
lemon_juice = env.scene.get_system("lemon_juice")
lemonade = env.scene.get_system("lemonade")
place_obj_on_floor_plane(bowl)
og.sim.step()
@ -543,7 +541,7 @@ def test_mixing_rule_success(env):
assert lemon_juice.n_particles == 0
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -552,12 +550,12 @@ def test_cooking_system_rule_failure_recipe_systems(env):
stove = env.scene.object_registry("name", "stove")
stockpot = env.scene.object_registry("name", "stockpot")
chicken = env.scene.object_registry("name", "chicken")
chicken_broth = env.scene.system_registry("name", "chicken_broth")
diced_carrot = env.scene.system_registry("name", "diced__carrot")
diced_celery = env.scene.system_registry("name", "diced__celery")
salt = env.scene.system_registry("name", "salt")
rosemary = env.scene.system_registry("name", "rosemary")
chicken_soup = env.scene.system_registry("name", "cooked__chicken_soup")
chicken_broth = env.scene.get_system("chicken_broth")
diced_carrot = env.scene.get_system("diced__carrot")
diced_celery = env.scene.get_system("diced__celery")
salt = env.scene.get_system("salt")
rosemary = env.scene.get_system("rosemary")
chicken_soup = env.scene.get_system("cooked__chicken_soup")
place_obj_on_floor_plane(stove)
og.sim.step()
@ -598,7 +596,7 @@ def test_cooking_system_rule_failure_recipe_systems(env):
assert env.scene.object_registry("name", "chicken") is not None
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -607,13 +605,13 @@ def test_cooking_system_rule_failure_nonrecipe_systems(env):
stove = env.scene.object_registry("name", "stove")
stockpot = env.scene.object_registry("name", "stockpot")
chicken = env.scene.object_registry("name", "chicken")
water = env.scene.system_registry("name", "water")
chicken_broth = env.scene.system_registry("name", "chicken_broth")
diced_carrot = env.scene.system_registry("name", "diced__carrot")
diced_celery = env.scene.system_registry("name", "diced__celery")
salt = env.scene.system_registry("name", "salt")
rosemary = env.scene.system_registry("name", "rosemary")
chicken_soup = env.scene.system_registry("name", "cooked__chicken_soup")
water = env.scene.get_system("water")
chicken_broth = env.scene.get_system("chicken_broth")
diced_carrot = env.scene.get_system("diced__carrot")
diced_celery = env.scene.get_system("diced__celery")
salt = env.scene.get_system("salt")
rosemary = env.scene.get_system("rosemary")
chicken_soup = env.scene.get_system("cooked__chicken_soup")
place_obj_on_floor_plane(stove)
og.sim.step()
@ -657,7 +655,7 @@ def test_cooking_system_rule_failure_nonrecipe_systems(env):
assert env.scene.object_registry("name", "chicken") is not None
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -667,12 +665,12 @@ def test_cooking_system_rule_failure_nonrecipe_objects(env):
stockpot = env.scene.object_registry("name", "stockpot")
chicken = env.scene.object_registry("name", "chicken")
bowl = env.scene.object_registry("name", "bowl")
chicken_broth = env.scene.system_registry("name", "chicken_broth")
diced_carrot = env.scene.system_registry("name", "diced__carrot")
diced_celery = env.scene.system_registry("name", "diced__celery")
salt = env.scene.system_registry("name", "salt")
rosemary = env.scene.system_registry("name", "rosemary")
chicken_soup = env.scene.system_registry("name", "cooked__chicken_soup")
chicken_broth = env.scene.get_system("chicken_broth")
diced_carrot = env.scene.get_system("diced__carrot")
diced_celery = env.scene.get_system("diced__celery")
salt = env.scene.get_system("salt")
rosemary = env.scene.get_system("rosemary")
chicken_soup = env.scene.get_system("cooked__chicken_soup")
place_obj_on_floor_plane(stove)
og.sim.step()
@ -716,7 +714,7 @@ def test_cooking_system_rule_failure_nonrecipe_objects(env):
assert env.scene.object_registry("name", "bowl") is not None
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -725,12 +723,12 @@ def test_cooking_system_rule_success(env):
stove = env.scene.object_registry("name", "stove")
stockpot = env.scene.object_registry("name", "stockpot")
chicken = env.scene.object_registry("name", "chicken")
chicken_broth = env.scene.system_registry("name", "chicken_broth")
diced_carrot = env.scene.system_registry("name", "diced__carrot")
diced_celery = env.scene.system_registry("name", "diced__celery")
salt = env.scene.system_registry("name", "salt")
rosemary = env.scene.system_registry("name", "rosemary")
chicken_soup = env.scene.system_registry("name", "cooked__chicken_soup")
chicken_broth = env.scene.get_system("chicken_broth")
diced_carrot = env.scene.get_system("diced__carrot")
diced_celery = env.scene.get_system("diced__celery")
salt = env.scene.get_system("salt")
rosemary = env.scene.get_system("rosemary")
chicken_soup = env.scene.get_system("cooked__chicken_soup")
deleted_objs = [chicken]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -775,7 +773,7 @@ def test_cooking_system_rule_success(env):
assert env.scene.object_registry("name", obj.name) is None
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
@ -791,7 +789,7 @@ def test_cooking_object_rule_failure_wrong_container(env):
stockpot = env.scene.object_registry("name", "stockpot")
bagel_dough = env.scene.object_registry("name", "bagel_dough")
raw_egg = env.scene.object_registry("name", "raw_egg")
sesame_seed = env.scene.system_registry("name", "sesame_seed")
sesame_seed = env.scene.get_system("sesame_seed")
initial_bagels = env.scene.object_registry("category", "bagel", set()).copy()
@ -823,7 +821,7 @@ def test_cooking_object_rule_failure_wrong_container(env):
assert len(final_bagels) == len(initial_bagels)
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -834,7 +832,7 @@ def test_cooking_object_rule_failure_recipe_objects(env):
baking_sheet = env.scene.object_registry("name", "baking_sheet")
bagel_dough = env.scene.object_registry("name", "bagel_dough")
raw_egg = env.scene.object_registry("name", "raw_egg")
sesame_seed = env.scene.system_registry("name", "sesame_seed")
sesame_seed = env.scene.get_system("sesame_seed")
initial_bagels = env.scene.object_registry("category", "bagel", set()).copy()
@ -865,7 +863,7 @@ def test_cooking_object_rule_failure_recipe_objects(env):
assert len(final_bagels) == len(initial_bagels)
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -876,7 +874,7 @@ def test_cooking_object_rule_failure_unary_states(env):
baking_sheet = env.scene.object_registry("name", "baking_sheet")
bagel_dough = env.scene.object_registry("name", "bagel_dough")
raw_egg = env.scene.object_registry("name", "raw_egg")
sesame_seed = env.scene.system_registry("name", "sesame_seed")
sesame_seed = env.scene.get_system("sesame_seed")
initial_bagels = env.scene.object_registry("category", "bagel", set()).copy()
@ -908,7 +906,7 @@ def test_cooking_object_rule_failure_unary_states(env):
assert len(final_bagels) == len(initial_bagels)
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -919,7 +917,7 @@ def test_cooking_object_rule_failure_binary_system_states(env):
baking_sheet = env.scene.object_registry("name", "baking_sheet")
bagel_dough = env.scene.object_registry("name", "bagel_dough")
raw_egg = env.scene.object_registry("name", "raw_egg")
sesame_seed = env.scene.system_registry("name", "sesame_seed")
sesame_seed = env.scene.get_system("sesame_seed")
initial_bagels = env.scene.object_registry("category", "bagel", set()).copy()
@ -951,7 +949,7 @@ def test_cooking_object_rule_failure_binary_system_states(env):
assert len(final_bagels) == len(initial_bagels)
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -962,7 +960,7 @@ def test_cooking_object_rule_failure_binary_object_states(env):
baking_sheet = env.scene.object_registry("name", "baking_sheet")
bagel_dough = env.scene.object_registry("name", "bagel_dough")
raw_egg = env.scene.object_registry("name", "raw_egg")
sesame_seed = env.scene.system_registry("name", "sesame_seed")
sesame_seed = env.scene.get_system("sesame_seed")
initial_bagels = env.scene.object_registry("category", "bagel", set()).copy()
@ -994,7 +992,7 @@ def test_cooking_object_rule_failure_binary_object_states(env):
assert len(final_bagels) == len(initial_bagels)
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -1005,7 +1003,7 @@ def test_cooking_object_rule_failure_wrong_heat_source(env):
baking_sheet = env.scene.object_registry("name", "baking_sheet")
bagel_dough = env.scene.object_registry("name", "bagel_dough")
raw_egg = env.scene.object_registry("name", "raw_egg")
sesame_seed = env.scene.system_registry("name", "sesame_seed")
sesame_seed = env.scene.get_system("sesame_seed")
initial_bagels = env.scene.object_registry("category", "bagel", set()).copy()
@ -1040,7 +1038,7 @@ def test_cooking_object_rule_failure_wrong_heat_source(env):
assert len(final_bagels) == len(initial_bagels)
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -1051,7 +1049,7 @@ def test_cooking_object_rule_success(env):
baking_sheet = env.scene.object_registry("name", "baking_sheet")
bagel_dough = env.scene.object_registry("name", "bagel_dough")
raw_egg = env.scene.object_registry("name", "raw_egg")
sesame_seed = env.scene.system_registry("name", "sesame_seed")
sesame_seed = env.scene.get_system("sesame_seed")
deleted_objs = [bagel_dough, raw_egg]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -1101,7 +1099,7 @@ def test_cooking_object_rule_success(env):
assert bagel.states[Inside].get_value(oven)
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
og.sim.remove_object(new_bagels)
og.sim.step()
@ -1117,10 +1115,10 @@ def test_single_toggleable_machine_rule_output_system_failure_wrong_container(en
assert len(REGISTERED_RULES) > 0, "No rules registered!"
food_processor = env.scene.object_registry("name", "food_processor")
ice_cream = env.scene.object_registry("name", "scoop_of_ice_cream")
milk = env.scene.system_registry("name", "whole_milk")
chocolate_sauce = env.scene.system_registry("name", "chocolate_sauce")
milkshake = env.scene.system_registry("name", "milkshake")
sludge = env.scene.system_registry("name", "sludge")
milk = env.scene.get_system("whole_milk")
chocolate_sauce = env.scene.get_system("chocolate_sauce")
milkshake = env.scene.get_system("milkshake")
sludge = env.scene.get_system("sludge")
deleted_objs = [ice_cream]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -1154,7 +1152,7 @@ def test_single_toggleable_machine_rule_output_system_failure_wrong_container(en
assert env.scene.object_registry("name", obj.name) is None
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
@ -1167,10 +1165,10 @@ def test_single_toggleable_machine_rule_output_system_failure_recipe_systems(env
assert len(REGISTERED_RULES) > 0, "No rules registered!"
blender = env.scene.object_registry("name", "blender")
ice_cream = env.scene.object_registry("name", "scoop_of_ice_cream")
milk = env.scene.system_registry("name", "whole_milk")
chocolate_sauce = env.scene.system_registry("name", "chocolate_sauce")
milkshake = env.scene.system_registry("name", "milkshake")
sludge = env.scene.system_registry("name", "sludge")
milk = env.scene.get_system("whole_milk")
chocolate_sauce = env.scene.get_system("chocolate_sauce")
milkshake = env.scene.get_system("milkshake")
sludge = env.scene.get_system("sludge")
deleted_objs = [ice_cream]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -1202,7 +1200,7 @@ def test_single_toggleable_machine_rule_output_system_failure_recipe_systems(env
assert env.scene.object_registry("name", obj.name) is None
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
@ -1215,10 +1213,10 @@ def test_single_toggleable_machine_rule_output_system_failure_recipe_objects(env
assert len(REGISTERED_RULES) > 0, "No rules registered!"
blender = env.scene.object_registry("name", "blender")
ice_cream = env.scene.object_registry("name", "scoop_of_ice_cream")
milk = env.scene.system_registry("name", "whole_milk")
chocolate_sauce = env.scene.system_registry("name", "chocolate_sauce")
milkshake = env.scene.system_registry("name", "milkshake")
sludge = env.scene.system_registry("name", "sludge")
milk = env.scene.get_system("whole_milk")
chocolate_sauce = env.scene.get_system("chocolate_sauce")
milkshake = env.scene.get_system("milkshake")
sludge = env.scene.get_system("sludge")
place_obj_on_floor_plane(blender)
og.sim.step()
@ -1247,7 +1245,7 @@ def test_single_toggleable_machine_rule_output_system_failure_recipe_objects(env
assert chocolate_sauce.n_particles == 0
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
@og_test
@ -1255,11 +1253,11 @@ def test_single_toggleable_machine_rule_output_system_failure_nonrecipe_systems(
assert len(REGISTERED_RULES) > 0, "No rules registered!"
blender = env.scene.object_registry("name", "blender")
ice_cream = env.scene.object_registry("name", "scoop_of_ice_cream")
milk = env.scene.system_registry("name", "whole_milk")
chocolate_sauce = env.scene.system_registry("name", "chocolate_sauce")
milkshake = env.scene.system_registry("name", "milkshake")
sludge = env.scene.system_registry("name", "sludge")
water = env.scene.system_registry("name", "water")
milk = env.scene.get_system("whole_milk")
chocolate_sauce = env.scene.get_system("chocolate_sauce")
milkshake = env.scene.get_system("milkshake")
sludge = env.scene.get_system("sludge")
water = env.scene.get_system("water")
deleted_objs = [ice_cream]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -1294,7 +1292,7 @@ def test_single_toggleable_machine_rule_output_system_failure_nonrecipe_systems(
assert water.n_particles == 0
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
env.scene.add_object(obj)
@ -1307,10 +1305,10 @@ def test_single_toggleable_machine_rule_output_system_failure_nonrecipe_objects(
blender = env.scene.object_registry("name", "blender")
ice_cream = env.scene.object_registry("name", "scoop_of_ice_cream")
bowl = env.scene.object_registry("name", "bowl")
milk = env.scene.system_registry("name", "whole_milk")
chocolate_sauce = env.scene.system_registry("name", "chocolate_sauce")
milkshake = env.scene.system_registry("name", "milkshake")
sludge = env.scene.system_registry("name", "sludge")
milk = env.scene.get_system("whole_milk")
chocolate_sauce = env.scene.get_system("chocolate_sauce")
milkshake = env.scene.get_system("milkshake")
sludge = env.scene.get_system("sludge")
deleted_objs = [ice_cream, bowl]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -1344,7 +1342,7 @@ def test_single_toggleable_machine_rule_output_system_failure_nonrecipe_objects(
assert chocolate_sauce.n_particles == 0
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
env.scene.add_object(obj)
@ -1356,10 +1354,10 @@ def test_single_toggleable_machine_rule_output_system_success(env):
assert len(REGISTERED_RULES) > 0, "No rules registered!"
blender = env.scene.object_registry("name", "blender")
ice_cream = env.scene.object_registry("name", "scoop_of_ice_cream")
milk = env.scene.system_registry("name", "whole_milk")
chocolate_sauce = env.scene.system_registry("name", "chocolate_sauce")
milkshake = env.scene.system_registry("name", "milkshake")
sludge = env.scene.system_registry("name", "sludge")
milk = env.scene.get_system("whole_milk")
chocolate_sauce = env.scene.get_system("chocolate_sauce")
milkshake = env.scene.get_system("milkshake")
sludge = env.scene.get_system("sludge")
deleted_objs = [ice_cream]
deleted_objs_cfg = [retrieve_obj_cfg(obj) for obj in deleted_objs]
@ -1392,7 +1390,7 @@ def test_single_toggleable_machine_rule_output_system_success(env):
assert env.scene.object_registry("name", obj.name) is None
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
@ -1406,13 +1404,13 @@ def test_single_toggleable_machine_rule_output_object_failure_unary_states(env):
electric_mixer = env.scene.object_registry("name", "electric_mixer")
raw_egg = env.scene.object_registry("name", "raw_egg")
another_raw_egg = env.scene.object_registry("name", "another_raw_egg")
flour = env.scene.system_registry("name", "flour")
granulated_sugar = env.scene.system_registry("name", "granulated_sugar")
vanilla = env.scene.system_registry("name", "vanilla")
melted_butter = env.scene.system_registry("name", "melted__butter")
baking_powder = env.scene.system_registry("name", "baking_powder")
salt = env.scene.system_registry("name", "salt")
sludge = env.scene.system_registry("name", "sludge")
flour = env.scene.get_system("flour")
granulated_sugar = env.scene.get_system("granulated_sugar")
vanilla = env.scene.get_system("vanilla")
melted_butter = env.scene.get_system("melted__butter")
baking_powder = env.scene.get_system("baking_powder")
salt = env.scene.get_system("salt")
sludge = env.scene.get_system("sludge")
initial_doughs = env.scene.object_registry("category", "sugar_cookie_dough", set()).copy()
@ -1466,7 +1464,7 @@ def test_single_toggleable_machine_rule_output_object_failure_unary_states(env):
assert sludge.n_particles > 0
# Clean up
remove_all_systems()
remove_all_systems(env.scene)
for obj_cfg in deleted_objs_cfg:
obj = DatasetObject(**obj_cfg)
@ -1480,13 +1478,13 @@ def test_single_toggleable_machine_rule_output_object_success(env):
electric_mixer = env.scene.object_registry("name", "electric_mixer")
raw_egg = env.scene.object_registry("name", "raw_egg")
another_raw_egg = env.scene.object_registry("name", "another_raw_egg")
flour = env.scene.system_registry("name", "flour")
granulated_sugar = env.scene.system_registry("name", "granulated_sugar")
vanilla = env.scene.system_registry("name", "vanilla")
melted_butter = env.scene.system_registry("name", "melted__butter")
baking_powder = env.scene.system_registry("name", "baking_powder")
salt = env.scene.system_registry("name", "salt")
sludge = env.scene.system_registry("name", "sludge")
flour = env.scene.get_system("flour")
granulated_sugar = env.scene.get_system("granulated_sugar")
vanilla = env.scene.get_system("vanilla")
melted_butter = env.scene.get_system("melted__butter")
baking_powder = env.scene.get_system("baking_powder")
salt = env.scene.get_system("salt")
sludge = env.scene.get_system("sludge")
initial_doughs = env.scene.object_registry("category", "sugar_cookie_dough", set()).copy()

View File

@ -182,8 +182,7 @@ def assert_test_env():
gm.ENABLE_OBJECT_STATES = True
gm.USE_GPU_DYNAMICS = True
gm.ENABLE_FLATCACHE = False
# TODO: temporarily disable transition rules; fix later
gm.ENABLE_TRANSITION_RULES = False
gm.ENABLE_TRANSITION_RULES = True
else:
# Make sure sim is stopped
og.sim.stop()
@ -242,6 +241,6 @@ def place_obj_on_floor_plane(obj, x_offset=0.0, y_offset=0.0, z_offset=0.01):
def remove_all_systems(scene):
for system in scene.get_active_systems():
for system in scene.active_systems.values():
system.remove_all_particles()
og.sim.step()