fix(topology): count rigid bodies in compute_mobility, expand hyperedges as cliques - #55
Merged
Merged
Conversation
…ges as cliques compute_mobility counted every edge and hyperedge as a link and every node as a joint, which only holds for the catalog's hyperedge-only graphs; a coupler four-bar reported 8 DOF, a Jansen leg 17. Links are now rigid bodies (ground, edges, hyperedges, merged when they share two nodes), joints are counted per node as bodies - 1, and a PRISMATIC node is a slider block with a prismatic joint to its guide. Catalog counts are unchanged. to_simple_graph expanded a hyperedge to a chain of N - 1 edges, so to_mechanism could not solve a ternary link written as a hyperedge alone; it now expands to the clique, as isomorphism and assur already did.
This was referenced Sep 12, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves the hyperedge convention mismatch the 1.2.0 graph tutorial documented instead of fixing.
What was wrong
compute_mobility/compute_dofcounted1 + len(edges) + len(hyperedges)links andlen(nodes)joints. That is only true of the topology catalog's hyperedge-only graphs. For any geometric graph — a coupler point, aHyperedgelabelling a triangle of edges,Linkage.to_hypergraph()output for aFixedDyad, every classical walker leggedsnake ships (Walker.dofwraps this) — the answer was nonsense:to_hypergraph()of a four-bar +FixedDyadSeparately,
to_simple_graph()expanded a hyperedge to a chain of N−1 edges whiletopology.isomorphismandassur.from_hypergraphexpand to a clique — soto_mechanism()raised "could not determine solve order" for a ternary link written as a hyperedge alone, unless the caller repeated its edges by hand (which the tutorial told them to do).The fix
GROUNDnodes), one body per edge and per hyperedge, merged whenever two share ≥ 2 nodes (two links pinned at two points are one link). A node inkbodies isk − 1one-DOF joints: coupler points are not joints, multiple joints count. APRISMATICnode is a slider block with a prismatic joint to its guide hyperedge. Three edges closing a triangle without a hyperedge still count as three bars — the DOF is identical, onlynum_linksdiffers — documented.to_simple_graph()expands to the clique, keeping (not duplicating) pairs already joined by an edge.Hyperedge.to_edges()is public and keeps its documented chain.FixedDyadround trip, catalog invariance, andto_mechanismon a hyperedge-only ternary link in every node order.2608 passed, ruff and mypy clean, the graph tutorial page executes. leggedsnake against this branch: 627 pass, 1 fails —
test_triangle_dof_is_three, which pinned the old wrong value (a triangle pinned at one ground node is 1 DOF); to be updated there after release.Found on the way, not fixed here:
RRPDyad → to_hypergraph() → to_mechanism()builds the slider as an RRR dyad —from_sim_linkageonly tagsLinearActuatornodesPRISMATICandto_mechanismnever sets a slide axis — so a slider-crank round trip raisesUnbuildableErrora few steps in. Issue to follow.