-
Notifications
You must be signed in to change notification settings - Fork 138
Open
Labels
enhancementNew feature or requestNew feature or request
Description
implement constraint islands
Island Discovery Implementation Plan
Objective
Discover disjoint constraint subgraphs by analyzing the constraint Jacobian structure.
PR Breakdown
| PR | Branch | Description |
|---|---|---|
| #1100 | tree_structure |
Add tree structure to types.Model, import in io.py |
| #1101 | edge_discovery |
Edge discovery kernel in island.py |
| #1102 | dfs_discovery |
Data fields, DFS island assignment + forward.py integration |
Tree Structure
Files: types.py, io.py
Add kinematic tree metadata to Model:
| Field | Dimension | Description |
|---|---|---|
ntree |
scalar | Number of kinematic trees |
tree_dofadr |
(ntree,) |
First DOF of each tree |
tree_dofnum |
(ntree,) |
DOFs per tree |
body_treeid |
(nbody,) |
Tree ID for each body (-1 for static) |
dof_treeid |
(nv,) |
Tree ID for each DOF |
Edge Discovery
Files: island.py
MuJoCo Reference: engine_island.c:L341-395 (findEdges())
Scan Jacobian rows to find tree pairs sharing constraints:
@wp.kernel
def _find_tree_edges(efc_J, dof_treeid, edges, nedge):
"""Find edges between trees that share constraints."""
efcid = wp.tid()
# Find first and last non-zero tree in this Jacobian row
# Add edge if they differOutput: Sparse adjacency list (tree1, tree2) pairs.
DFS Island Discovery
Files: island.py, types.py, forward.py
MuJoCo Reference: engine_island.c:L97-137 (mj_floodFill())
Algorithm: DFS (matching MuJoCo)
Uses edges from PR 1.2 to build CSR adjacency, then runs DFS to assign island IDs:
def _flood_fill(rownnz, rowadr, colind, tree_island, ntree):
"""DFS flood fill matching mj_floodFill."""
nisland = 0
stack = []
for tree in range(ntree):
if tree_island[tree] >= 0: # already visited
continue
if rownnz[tree] == 0: # unconstrained tree
continue
# Start new island
stack.append(tree)
while stack:
t = stack.pop()
if tree_island[t] >= 0:
continue
tree_island[t] = nisland
# Add unvisited neighbors
for j in range(rownnz[t]):
neighbor = colind[rowadr[t] + j]
if tree_island[neighbor] < 0:
stack.append(neighbor)
nisland += 1
return nislandData Fields
| Field | Dimension | Description |
|---|---|---|
nisland |
(nworld,) |
Number of islands |
tree_island |
(nworld, ntree) |
Island ID per tree (-1 if unconstrained) |
island_ntree |
(nworld, max_nisland) |
Trees per island |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request