Separate spawners and object types.#593
Conversation
Greptile SummaryThis PR separates the
Confidence Score: 4/5Safe to merge for existing USD-based objects; the new Sphere class will silently break in any placement scenario with spatial relations. One P1 finding remains: Sphere.get_bounding_box() will crash with an opaque AssertionError the first time it is used in a placement context, which is the natural use case for an object tagged [object] with type RIGID. Prior P0/P1 concerns from the previous review round are resolved. isaaclab_arena/assets/object.py (bounding-box/contact-sensor gaps) and isaaclab_arena/assets/object_library.py (Sphere missing bounding-box support). Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["Object.__init__(usd_path, spawner_cfg, object_type)"] --> B{usd_path AND spawner_cfg None?}
B -- yes --> C[raise ValueError]
B -- no --> D{object_type None?}
D -- yes --> E{usd_path is None?}
E -- yes --> F[assert / clear error]
E -- no --> G[detect_object_type usd_path]
D -- no --> H[use provided object_type]
G --> H
H --> I[_init_object_cfg]
I --> J{object_type?}
J -- RIGID --> K[_generate_rigid_cfg]
J -- ARTICULATION --> L[_generate_articulation_cfg]
J -- BASE --> M[_generate_base_cfg]
K --> N["_get_spawn_cfg(activate_contact_sensors=True)"]
L --> N
M --> O["_get_spawn_cfg()"]
N --> P{spawner_cfg set?}
O --> P
P -- yes --> Q["return spawner_cfg as-is ⚠️ activate_contact_sensors ignored"]
P -- no --> R["UsdFileCfg(usd_path, scale, activate_contact_sensors)"]
|
There was a problem hiding this comment.
🤖 Isaac Lab Review Bot
Summary
This PR cleanly separates the SPAWNER concept from ObjectType, addressing issue #592. Objects like GroundPlane, Sphere, and DomeLight now use their correct semantic types (BASE, RIGID) while passing a custom spawner_cfg for spawn configuration. The design is sound, but there's a critical prim path regression for global objects and a missing type annotation worth addressing.
Design Assessment
Design is sound. Decoupling the spawning mechanism from the object type is the right call — it eliminates the ObjectType.SPAWNER hack where objects had to pretend to be a different type just because they used a custom spawn function. The new _get_spawn_cfg() dispatch method is clean and minimal.
Findings
🔴 Critical: Prim path regression for GroundPlane and DomeLight — isaaclab_arena/assets/object.py:180
_generate_base_cfg() hardcodes the prim path to "{ENV_REGEX_NS}/" + self.name, but GroundPlane and DomeLight set global prim paths (/World/GroundPlane and /World/Light respectively) that should NOT be scoped per-environment.
Previously, these objects used _generate_spawner_cfg() which correctly used self.prim_path. Now that they route through _generate_base_cfg(), their custom prim paths are silently ignored.
Impact: GroundPlane and DomeLight will be spawned at {ENV_REGEX_NS}/ground_plane and {ENV_REGEX_NS}/light instead of /World/GroundPlane and /World/Light — duplicating global scene elements per environment and likely breaking rendering/physics.
Suggested fix: Use self.prim_path in _generate_base_cfg():
object_cfg = AssetBaseCfg(
prim_path=self.prim_path,
spawn=self._get_spawn_cfg(),
**self.asset_cfg_addon,
)
Note: This changes behavior for existing BASE objects that rely on the {ENV_REGEX_NS}/ prefix. If that's intentional, the fix should be conditional — e.g., only use self.prim_path when it's explicitly set by the caller (not the default).
🟡 Warning: spawner_cfg parameter lacks type annotation — isaaclab_arena/assets/object.py:36
The new spawner_cfg parameter has no type hint:
spawner_cfg=None,The codebase follows a consistent pattern of typing all constructor parameters. The spawner config accepts various Isaac Sim spawn config types.
Suggested fix:
spawner_cfg: sim_utils.SpawnerCfg | None = None,
(Or the appropriate base type from isaaclab.sim.spawners if SpawnerCfg isn't the correct parent.)
🟡 Warning: detect_object_type will crash if spawner_cfg is provided without object_type — isaaclab_arena/assets/object.py:46
When creating an Object with spawner_cfg and no usd_path, if object_type is omitted, the code calls detect_object_type(usd_path=None) which asserts that at least one of usd_path or stage is provided. This produces an unhelpful AssertionError instead of guiding the user.
Currently all library objects set object_type explicitly, so this doesn't bite today — but it's a trap for future callers.
Suggested fix: Add a guard before detection:
if object_type is None:
if usd_path is not None:
object_type = detect_object_type(usd_path=usd_path)
else:
raise ValueError(
f"Object '{name}' with spawner_cfg must specify object_type explicitly"
)🔵 Suggestion: Docker volume mount is unrelated to this refactor — docker/run_docker.sh:135
The .config/gh volume mount is a separate concern from the spawner/object-type refactoring. Consider splitting this into its own PR to keep the refactoring commit focused.
Test Coverage
- Bug fix PR: N/A — this is a refactoring PR
- New code: No new tests included
- Gaps: The refactoring changes runtime behavior for
GroundPlane,Sphere, andDomeLight. Given the prim path regression identified above, at minimum a smoke test verifying that these objects produce the expected config (correctprim_path, correctspawntype, correctobject_type) would prevent regressions. Existing integration tests may catch the prim path issue at runtime, but explicit unit tests for config generation would be more reliable.
CI Status
⏳ Pre-commit check is pending.
Verdict
Significant concerns
The separation of ObjectType and spawner config is well-designed and addresses a real architectural problem. However, the prim path regression for GroundPlane and DomeLight (routed through _generate_base_cfg which ignores self.prim_path) is a correctness issue that will break these global scene objects. This should be fixed before merging.
Summary
Refactors how we handle spawner objects, to separate their specification from object type
Detailed description
ObjectTypeandSPAWNER