You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
newton/_src/utils/import_usd_deformable_cable.py:624-628 (single cable) and :397-401 (welded graph).
Every other contact field -- ke, kd, kf, ka, mu, margin, gap -- is inherited from ModelBuilder.default_shape_cfg, so contact attributes authored on a cable are silently ignored. The rigid path already resolves the same fields per shape:
newton:contactStiffness, newton:contactDamping, newton:contactFrictionGain, newton:contactAdhesion from the bound NewtonMaterialAPI material (import_usd.py:2483-2486, applied at :3389-3407)
newton:contactMargin, newton:contactGap from NewtonCollisionAPI on the collider prim (import_usd.py:3330-3344)
Request: resolve those same attributes in the cable path, at per-cable granularity. Concretely, one ShapeConfig per cable prim, derived from that cable's own bound material and collider prim, falling back to default_shape_cfg field by field when an attribute is unauthored. For welded graphs this means one config per component, matching how the importer already flattens a component to a representative material and warns when members disagree (import_usd_deformable_cable.py:352-372).
This keeps the existing structure: the two replace(builder.default_shape_cfg, ...) sites stay, they just gain the resolved contact fields alongside density. No change to add_rod / add_rod_graph is needed.
Cable behaviour is contact-dominated: routing through clips, sliding in a gripper, coiling on a surface. Those scenarios are tuned with friction and the contact penalty parameters, and none of them are reachable per cable today.
The only available lever is setting builder.default_shape_cfg before import. That default is shared with every other shape in the scene that has no bound material, so raising a cable's friction also raises it for unrelated colliders. Isaac Lab surfaces exactly this global as NewtonCfg.default_shape_cfg and runs into the same coupling.
Alternatives Considered
default_shape_cfg before import. Works, but is import-wide, so it cannot express two cables with different contact properties, nor a cable that differs from the rest of the scene.
Mutating model.shape_material_* after finalize(). Reachable via path_cable_map plus body_shapes, but it reaches past the importer and reimplements attribute resolution that already exists for rigid shapes.
PR Fix USD cable contact materials #3663 (open). Adds physics:dynamicFriction and physics:restitution from the base UsdPhysicsMaterialAPI to cable capsules. That covers mu, but not the penalty parameters or margin/gap, and it does not go through the NewtonMaterialAPI resolution the rigid path uses (added in Parse contact response attributes from NewtonMaterialAPI #3005). This request is the remaining set, and is complementary rather than a duplicate.
Per-segment granularity. Deliberately not requested: it would require a builder change, since add_rod and add_rod_graph accept a single cfg for the whole rod (builder.py:7600, :7829) and pass it to every capsule (:8020). Per-cable needs no such change and covers the use cases above.
Description
The USD cable importer builds a single
ShapeConfigper curve and overrides only three fields on the import-wide default:newton/_src/utils/import_usd_deformable_cable.py:624-628(single cable) and:397-401(welded graph).Every other contact field --
ke,kd,kf,ka,mu,margin,gap-- is inherited fromModelBuilder.default_shape_cfg, so contact attributes authored on a cable are silently ignored. The rigid path already resolves the same fields per shape:newton:contactStiffness,newton:contactDamping,newton:contactFrictionGain,newton:contactAdhesionfrom the boundNewtonMaterialAPImaterial (import_usd.py:2483-2486, applied at:3389-3407)newton:contactMargin,newton:contactGapfromNewtonCollisionAPIon the collider prim (import_usd.py:3330-3344)Request: resolve those same attributes in the cable path, at per-cable granularity. Concretely, one
ShapeConfigper cable prim, derived from that cable's own bound material and collider prim, falling back todefault_shape_cfgfield by field when an attribute is unauthored. For welded graphs this means one config per component, matching how the importer already flattens a component to a representative material and warns when members disagree (import_usd_deformable_cable.py:352-372).This keeps the existing structure: the two
replace(builder.default_shape_cfg, ...)sites stay, they just gain the resolved contact fields alongsidedensity. No change toadd_rod/add_rod_graphis needed.Reproduction script
Output (newton 1.5.0.dev0). Identical contact authoring; the rigid capsule takes all seven values, the cable takes none:
Motivation / Use Case
Cable behaviour is contact-dominated: routing through clips, sliding in a gripper, coiling on a surface. Those scenarios are tuned with friction and the contact penalty parameters, and none of them are reachable per cable today.
The only available lever is setting
builder.default_shape_cfgbefore import. That default is shared with every other shape in the scene that has no bound material, so raising a cable's friction also raises it for unrelated colliders. Isaac Lab surfaces exactly this global asNewtonCfg.default_shape_cfgand runs into the same coupling.Alternatives Considered
default_shape_cfgbefore import. Works, but is import-wide, so it cannot express two cables with different contact properties, nor a cable that differs from the rest of the scene.model.shape_material_*afterfinalize(). Reachable viapath_cable_mapplusbody_shapes, but it reaches past the importer and reimplements attribute resolution that already exists for rigid shapes.physics:dynamicFrictionandphysics:restitutionfrom the baseUsdPhysicsMaterialAPIto cable capsules. That coversmu, but not the penalty parameters or margin/gap, and it does not go through theNewtonMaterialAPIresolution the rigid path uses (added in Parse contact response attributes from NewtonMaterialAPI #3005). This request is the remaining set, and is complementary rather than a duplicate.add_rodandadd_rod_graphaccept a singlecfgfor the whole rod (builder.py:7600,:7829) and pass it to every capsule (:8020). Per-cable needs no such change and covers the use cases above.