Skip to content
Draft
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b135f84
SAP-style IPC coupling: predicted-pose coupling + velocity output
ACMLCZH Mar 5, 2026
ad8cbca
Update two way
ACMLCZH Mar 5, 2026
b3cf8b8
Update unittest
ACMLCZH Mar 5, 2026
4936854
Update collider logic
ACMLCZH Mar 5, 2026
d95ba5c
Update set qpos
ACMLCZH Mar 6, 2026
67ce1bb
Merge upstream/main into feature/ipc-sap-style-coupling
ACMLCZH Mar 6, 2026
ed4dc07
Update review
ACMLCZH Mar 6, 2026
f4fa441
Update test_ipc.py
ACMLCZH Mar 6, 2026
d4757f2
Update coupler.py
ACMLCZH Mar 6, 2026
0b8fa5a
Update refactor
ACMLCZH Mar 7, 2026
58328f8
update review
ACMLCZH Mar 7, 2026
29b64d4
Update review
ACMLCZH Mar 7, 2026
78f9d37
Merge branch 'main' into feature/ipc-sap-style-coupling
ACMLCZH Mar 7, 2026
0508682
Update cloth
ACMLCZH Mar 7, 2026
4c1110a
Address PR review: restore set_qpos/set_dofs_position, shared utils, …
ACMLCZH Mar 8, 2026
5eb3b5b
Revert conftest.py changes
ACMLCZH Mar 8, 2026
2608dce
Move constraint_strength to per-entity coup_stiffness on RigidMaterial
ACMLCZH Mar 8, 2026
7a75fb1
Add set_qpos/set_dofs_position tests, fix CUDA device and overlap shr…
ACMLCZH Mar 8, 2026
0cea049
Use named friction constants and add force estimate FIXME in biaxial …
ACMLCZH Mar 8, 2026
5afdc45
Add traceability comments for test tolerance and parameter changes
ACMLCZH Mar 8, 2026
9afb8d0
Minor cleanup.
duburcqa Mar 9, 2026
a669b08
Add IPC restitution with one-shot impulse to fix per-frame compounding
ACMLCZH Mar 9, 2026
1a718d5
Per-frame restitution + per-link ABD dirty tracking
ACMLCZH Mar 10, 2026
d592bed
Update ipc_abd_momentum.py
ACMLCZH Mar 10, 2026
aa0ff0a
Update ipc_abd_momentum.py
ACMLCZH Mar 10, 2026
747c881
Update grasp abd
ACMLCZH Mar 11, 2026
9fbff06
primary fix
alanray-tech Mar 11, 2026
980430a
Merge branch 'feature/ipc-sap-style-coupling' of https://github.com/A…
alanray-tech Mar 11, 2026
a1749f9
fix format
alanray-tech Mar 11, 2026
06f2c66
Update init - build
ACMLCZH Mar 12, 2026
f6166f6
Merge remote-tracking branch 'upstream/main' into feature/ipc-sap-sty…
ACMLCZH Mar 12, 2026
deacd6d
Refactor: move heterogeneous variant tracking from Entity to Link
ACMLCZH Mar 12, 2026
e4b9340
Merge branch 'refactor/move-heterogeneous-variants-to-link' into feat…
ACMLCZH Mar 12, 2026
508afaf
Merge upstream/main: resolve collider and IPC coupler options conflicts
ACMLCZH Mar 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion examples/IPC_Solver/ipc_objects_falling.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ def main():
)

# Ground plane
scene.add_entity(gs.morphs.Plane())
scene.add_entity(
gs.morphs.Plane(),
material=gs.materials.Rigid(
coup_type="ipc_only",
),
)

# Cloth using Cloth material
# Note: Using coarse grid mesh to avoid IPC thickness violations
Expand Down
9 changes: 8 additions & 1 deletion examples/IPC_Solver/ipc_robot_cloth_teleop.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def main():
default="two_way_soft_constraint",
choices=["two_way_soft_constraint", "external_articulation"],
)
parser.add_argument("--vis_ipc", action="store_true", default=False, help="Show IPC GUI")
Comment thread
ACMLCZH marked this conversation as resolved.
Outdated
args = parser.parse_args()

scene = gs.Scene(
Expand All @@ -58,6 +59,7 @@ def main():
enable_rigid_rigid_contact=True,
contact_d_hat=0.001,
contact_resistance=1e7,
_show_ipc_gui=args.vis_ipc,
),
viewer_options=gs.options.ViewerOptions(
camera_pos=(2.0, -1.0, 1.5),
Expand All @@ -68,7 +70,12 @@ def main():
)

# Add flat floor
scene.add_entity(gs.morphs.Plane())
scene.add_entity(
gs.morphs.Plane(),
material=gs.materials.Rigid(
coup_type="ipc_only",
),
)

# Add Franka robot
franka_material_kwargs = dict(
Expand Down
11 changes: 8 additions & 3 deletions examples/IPC_Solver/ipc_robot_grasp_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ def main():
show_viewer=args.vis,
)

scene.add_entity(gs.morphs.Plane())
scene.add_entity(
gs.morphs.Plane(),
material=gs.materials.Rigid(
coup_type="ipc_only",
),
)

franka_material_kwargs = dict(
coup_friction=0.8,
Expand Down Expand Up @@ -85,9 +90,9 @@ def main():
franka.set_dofs_kp([4500.0, 4500.0, 3500.0, 3500.0, 2000.0, 2000.0, 2000.0, 500.0, 500.0])

qpos = franka.inverse_kinematics(link=end_effector, pos=[0.65, 0.0, 0.4], quat=[0.0, 1.0, 0.0, 0.0])
qpos[fingers_dof] = 0.04
if not args.no_ipc or args.coup_type == "external_articulation":
franka.control_dofs_position(qpos[motors_dof], dofs_idx_local=motors_dof)
franka.control_dofs_position(0.04, dofs_idx_local=fingers_dof)
franka.control_dofs_position(qpos)
Comment thread
ACMLCZH marked this conversation as resolved.
Outdated
for _ in range(200 if "PYTEST_VERSION" not in os.environ else 1):
scene.step()
else:
Expand Down
446 changes: 311 additions & 135 deletions genesis/engine/couplers/ipc_coupler/coupler.py

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions genesis/engine/couplers/ipc_coupler/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,13 @@ class ArticulatedEntityData:

articulation_slots: list[GeometrySlot]

ref_dof_prev: np.ndarray
qpos_stored: np.ndarray
qpos_current: np.ndarray
qpos_new: np.ndarray
delta_theta_tilde: np.ndarray
delta_theta_ipc: np.ndarray

# Previous timestep link transforms for ref_dof_prev computation {(joint, env_idx): transform_matrix_4x4}
# Previous timestep link transforms for IPC ABD ref_dof_prev sync {(joint, env_idx): transform_matrix_4x4}
Comment thread
ACMLCZH marked this conversation as resolved.
Outdated
prev_links_transform: list[list[np.ndarray | None]]


Expand Down
3 changes: 1 addition & 2 deletions genesis/engine/couplers/ipc_coupler/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ def find_target_link_for_fixed_merge(link):
if link.parent_idx < 0:
break

# Check if there is any non-fixed joint
# Stop if the link has any non-fixed joint (non-fixed joints define separate bodies)
if any(joint.type != gs.JOINT_TYPE.FIXED for joint in link.joints):
# Found a link with non-FIXED joint, this is our target
break

# All joints are FIXED, move up to parent
Expand Down
10 changes: 6 additions & 4 deletions genesis/engine/entities/rigid_entity/rigid_entity.py
Comment thread
ACMLCZH marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -3321,10 +3321,11 @@ def set_qpos(self, qpos, qs_idx_local=None, envs_idx=None, *, zero_velocity=True
"""
from genesis.engine.couplers import IPCCoupler

if isinstance(self.sim.coupler, IPCCoupler) and self.material.coup_type == "external_articulation":
gs.raise_exception("This method is not supported by `RigidMaterial.coup_type='external_articulation'`.")
super().set_qpos(qpos, qs_idx_local, envs_idx, zero_velocity=zero_velocity, skip_forward=skip_forward)

if isinstance(self.sim.coupler, IPCCoupler):
self.sim.coupler.set_qpos_changed(self)
Comment thread
ACMLCZH marked this conversation as resolved.
Outdated

@gs.assert_built
def set_dofs_kp(self, kp, dofs_idx_local=None, envs_idx=None):
"""
Expand Down Expand Up @@ -3446,10 +3447,11 @@ def set_dofs_position(self, position, dofs_idx_local=None, envs_idx=None, *, zer
"""
from genesis.engine.couplers import IPCCoupler

if isinstance(self.sim.coupler, IPCCoupler) and self.material.coup_type == "external_articulation":
gs.raise_exception("This method is not supported by `RigidMaterial.coup_type='external_articulation'`.")
super().set_dofs_position(position, dofs_idx_local, envs_idx, zero_velocity=zero_velocity)

if isinstance(self.sim.coupler, IPCCoupler):
self.sim.coupler.set_qpos_changed(self)
Comment thread
ACMLCZH marked this conversation as resolved.
Outdated

# ------------------------------------------------------------------------------------
# ---------------------------------- PD control --------------------------------------
# ------------------------------------------------------------------------------------
Expand Down
8 changes: 3 additions & 5 deletions genesis/engine/materials/rigid.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,12 @@ class Rigid(Kinematic):
Compensation factor for gravity. 1.0 cancels gravity. Default is 0.
coup_type : str or None, optional
Coupling mode for this entity. Only used by the IPC coupler. Requires ``needs_coup=True``.
If None, auto-selected based on entity type: ``'external_articulation'`` for fixed-base
articulated robots, ``'two_way_soft_constraint'`` for floating-base robots, and
``'ipc_only'`` for non-articulated objects. Valid values:
Must be explicitly set when ``needs_coup=True``. Valid values:
- 'two_way_soft_constraint': Two-way soft coupling.
- 'external_articulation': Joint-level coupling for articulated bodies. Joint positions will be coupled at
the DOF level.
- 'ipc_only': IPC controls entity, transforms copied to Genesis (one-way). Only supported by rigid
non-articulated objects.
- 'ipc_only': IPC controls entity, transforms copied to Genesis (one-way). Not supported for
entities with constrained joints (revolute, prismatic, etc.).
Comment thread
ACMLCZH marked this conversation as resolved.
Outdated
Default is None.
coup_links : tuple of str or None, optional
Tuple of link names to include in coupling. When set, only the named links participate
Expand Down
Loading