[BUG FIX] Fix IPC coupler auto-detecting wrong coup_type for Plane entities.#2877
Conversation
…tities Primitive morphs (Plane, Box, Sphere, etc.) always create one joint in the rigid entity tree, even when that joint is FIXED (zero DOFs). The previous auto-detection logic used `entity.n_joints > 0` to identify articulated entities, which incorrectly classified a fixed Plane (1 FIXED joint, 0 DOFs) as `external_articulation`. PLANE geoms only support `ipc_only`, so this raised GenesisException at build time whenever a Plane was added to a scene with `IPCCouplerOptions(two_way_coupling=True)` and no explicit `coup_type`. Fix: replace `n_joints > 0` with `n_dofs > 0` in `_setup_coupling_config` so that fixed entities with no actual DOFs (Plane, fixed Box, etc.) correctly receive `ipc_only` rather than `external_articulation`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6560c23 to
2b6c929
Compare
|
LGTM now, but need an deep investigation into the whole structure |
…test Auto-detect and the external_articulation validation both decided whether an entity is articulated, but each used its own predicate. Auto-detect used n_dofs > 0 while the validation still used n_joints == 0, which is the same root cause the previous fix addressed: primitive morphs always keep one FIXED base joint (n_joints == 1, n_dofs == 0), so n_joints cannot express "has dynamic DOFs". Introduce has_articulation_dofs and default_coup_type in ipc_coupler/utils.py so both sites share a single discriminator. Route auto-detect through default_coup_type and the external_articulation guard through has_articulation_dofs, so an explicit external_articulation on a fixed primitive (n_dofs == 0) is now correctly rejected instead of silently building an empty articulation. Add test_auto_coup_type_from_dofs covering Plane, fixed Box, free Box and a fixed-base articulated robot in one scene, asserting the resolved coup_type and the underlying n_joints/n_dofs/is_fixed invariants.
|
Took a deeper look at the whole coup_type detection path as discussed, and pushed a follow-up commit (2d3bbc6) that keeps the original fix but removes the remaining inconsistency and adds a regression test. AnalysisThe bug is real and the original one-line fix (
So a
Remaining inconsistency this addressesAuto-detect and the Changes
VerificationRan on an RTX 5090 (CUDA backend,
No new heuristic or workaround was introduced; this only unifies the existing decision into a single predicate. |
alanray-tech
left a comment
There was a problem hiding this comment.
Approving. After reviewing the whole coup_type detection path, this is a real bug with the correct fix, not a workaround: primitive morphs always keep one FIXED base joint, so n_joints cannot express "is articulated" while n_dofs can. The follow-up unifies the discriminator into a single has_articulation_dofs util (also fixing the sibling n_joints == 0 guard) and adds a regression test covering Plane / fixed Box / free Box / fixed-base robot. Verified locally: full tests/ipc/test_api.py passes (12 tests).
Description
A
Planeentity added to a scene withIPCCouplerOptions(two_way_coupling=True)crashed atscene.build()with:Root Cause
Primitive morphs (Plane, Box, Sphere, etc.) always create one joint in the rigid entity tree, even when that joint is FIXED (zero DOFs). The auto-detection logic in
_setup_coupling_configusedentity.n_joints > 0to identify articulated entities, which incorrectly classified a Plane (1 FIXED joint, 0 DOFs) asexternal_articulation(enum value 1). PLANE geoms only supportipc_only, triggering the exception.Fix
Changed
entity.n_joints > 0→entity.n_dofs > 0in_setup_coupling_config. This correctly distinguishes:ipc_onlyexternal_articulationtwo_way_soft_constraintTo Reproduce
Crashes before the fix, runs successfully after.