Skip to content

[FEATURE][BREAKING] Set contact friction for a pair of materials. - #3166

Draft
Milotrince wants to merge 6 commits into
Genesis-Embodied-AI:mainfrom
Milotrince:rigid-material-friction-pairs
Draft

[FEATURE][BREAKING] Set contact friction for a pair of materials.#3166
Milotrince wants to merge 6 commits into
Genesis-Embodied-AI:mainfrom
Milotrince:rigid-material-friction-pairs

Conversation

@Milotrince

@Milotrince Milotrince commented Aug 3, 2026

Copy link
Copy Markdown
Member

Description

  • scene.add_material(gs.materials.Rigid(...)) returns a handle that entities hold as their material. Passing one
    handle to several add_entity calls shares one surface; geom.set_material gives one entity more than one.
  • rubber.set_friction_pair(steel, sliding_friction=0.4) pins the coefficients for that pair of materials in place
    of the maximum over the two geoms. A coefficient left None keeps following the maximum. Re-declaring the same two
    materials retunes them, before or after build.
  • Materials stay an authoring concept. Declarations expand onto collision pairs at build, so no material indirection
    reaches a kernel; the override sits on ColliderInfo, keyed by the dense pair index collision_pair_idx already
    provides.
  • friction_ratio is per-coefficient: set_friction_ratio(sliding_ratio=..., torsional_ratio=..., rolling_ratio=...) writes only what is passed. The two new arguments are keyword-only. Coefficients and ratios
    read as <mode>_friction and <mode>_ratio throughout.
  • array_class.py loses three tensor fields. A geom's and a contact's friction coefficients are each packed into one
    vector, against the one field the override adds.

Breaking:

  • entity.material.friction and its torsional and rolling siblings are gone. Read material.options.friction for the
    declared value or geom.friction for what a geom carries.
  • get_geoms_friction / set_geoms_friction, the friction-ratio accessors, and RigidSolverState.friction_ratio
    carry the three coefficients on a trailing axis.
  • set_geoms_friction_torsional / _rolling are subsumed by the packed setter.
  • entity.set_friction_ratio's first argument is sliding_ratio and scales sliding friction alone, where
    friction_ratio scaled all three.

Out of scope: geom_priority, MJCF <pair> import, anisotropic (5-coefficient) friction, sol_params averaging, and
the couplers' own friction rules.

Related Issue

Addresses #2718. The geom_priority field proposed there is not added; a material
pair subsumes it without making users reason about which surface wins.

Motivation and Context

Friction is a property of a pair of surfaces, so the maximum over two geoms is arbitrary: no per-surface value plus a
symmetric rule reproduces a real table. It also hides single-sided changes, since lowering only a robot's friction
against a default-1.0 ground is a no-op. The issue reports a Go2 sweep that reproduced its own baseline that way.

How Has This Been / Can This Be Tested?

pytest tests/rigid/ -v
pytest tests/ipc/ -v -n0          # ipc needs a single worker on one GPU

tests/rigid/test_friction.py::test_friction_resolved_from_material_pair, over n_envs=[0, 2], asserts
deceleration == mu * g for eight boxes on a plane:

  • pair coefficients of 0.6 and 0.05 against surfaces that both declare 0.4, so neither a maximum nor a minimum over
    the two reproduces them
  • two boxes sharing one material, one taking its material on the geom, one scaled by a sliding ratio
  • distinct launch speeds, so the order broadphase reports the boxes in stops matching the order their pairs were
    numbered in

It is separate from test_kinetic_friction because that scene straddles the tipping threshold, where changing any one
coefficient flips an unrelated box between 176 and 0.1 degrees of tilt.

Locally tests/rigid/ is 426 passed and tests/ipc/ 47 passed. test_physics_parity and
test_robot_grasp_fem[external_articulation] fail identically on the merge-base.

Checklist:

  • I read the CONTRIBUTING document.
  • I followed the Submitting Code Changes section of CONTRIBUTING document.
  • I tagged the title correctly (including BUG FIX/FEATURE/MISC/BREAKING)
  • I updated the documentation accordingly or no change is needed.
  • I tested my changes and added instructions on how to test it for reviewers.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Resolves SIM-329

@Milotrince Milotrince changed the title [FEATURE] Set friction for rigid material pairs. [FEATURE][CHANGING] Set friction for rigid material pairs. Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not comfortable with modifying array_class. Make sure every single new field is ABSOLUTELY NECESSARY.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Friction information are geometry level should be removed if some extract material indirection is added.

@Milotrince
Milotrince force-pushed the rigid-material-friction-pairs branch from 8dece55 to 658b40e Compare August 3, 2026 21:16
@Milotrince
Milotrince force-pushed the rigid-material-friction-pairs branch 2 times, most recently from a196da7 to ea69adc Compare August 4, 2026 00:17
@Milotrince Milotrince changed the title [FEATURE][CHANGING] Set friction for rigid material pairs. [FEATURE][BREAKING] Set contact friction for a pair of materials. Aug 4, 2026
@Milotrince
Milotrince force-pushed the rigid-material-friction-pairs branch 4 times, most recently from c617536 to b96e75b Compare August 4, 2026 03:42
@Milotrince
Milotrince force-pushed the rigid-material-friction-pairs branch from b96e75b to 9a2c4f8 Compare August 4, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants