Skip to content

Commit ffcbaa9

Browse files
authored
Integrate canonical Mechanics baseline FABRIK/LBS execution (#364)
Original V6 reference Mechanics solver and rest qualification. Six-file mainline-only review, 7 focused tests and 10/10 broad CI checks. No new research solver or product ModelRelease authority.
1 parent 99b40dd commit ffcbaa9

6 files changed

Lines changed: 1074 additions & 0 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: v6-main-mechanics-baseline-integration-v1
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- 'compiler/realsas_compiler_core/canonical_mechanics_ir_v1.py'
7+
- 'compiler/realsas_compiler_core/mechanics_control_solver_v1.py'
8+
- 'tests/compiler/test_mechanics_control_solver_v1.py'
9+
- 'tests/compiler/test_canonical_mechanics_ir_v1.py'
10+
- 'tests/compiler/test_v6_mechanics_main_integration_v1.py'
11+
- '.github/workflows/v6_main_mechanics_baseline_integration_v1.yml'
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: read
16+
17+
concurrency:
18+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
19+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
20+
21+
jobs:
22+
mechanics-baseline-contract-courts:
23+
runs-on: ubuntu-latest
24+
timeout-minutes: 20
25+
steps:
26+
- uses: actions/checkout@v4
27+
- uses: actions/setup-python@v5
28+
with:
29+
python-version: '3.11'
30+
- name: Install independent CPU compiler requirements
31+
run: python -m pip install --no-input --progress-bar off -r requirements/mainline-ci.txt
32+
- name: Compile imported original mechanics modules
33+
run: |
34+
python -m py_compile \
35+
compiler/realsas_compiler_core/mechanics_control_solver_v1.py \
36+
compiler/realsas_compiler_core/canonical_mechanics_ir_v1.py
37+
- name: Run original V6 and main-integration Mechanics regressions
38+
run: |
39+
python -m pytest -q \
40+
tests/compiler/test_mechanics_control_solver_v1.py \
41+
tests/compiler/test_canonical_mechanics_ir_v1.py \
42+
tests/compiler/test_v6_mechanics_main_integration_v1.py
43+
- name: Preserve deliberate research and product barriers
44+
run: |
45+
python - <<'PY'
46+
from compiler.realsas_compiler_core.canonical_mechanics_ir_v1 import CanonicalMechanicsIRV1
47+
from compiler.realsas_compiler_core.mechanics_control_solver_v1 import solve_control_pose_v1
48+
assert CanonicalMechanicsIRV1.__module__.endswith('canonical_mechanics_ir_v1')
49+
assert solve_control_pose_v1.__module__.endswith('mechanics_control_solver_v1')
50+
print('PASS_V6_MECHANICS_REST_AND_REFERENCE_SOLVER_NO_MODEL_OR_PRODUCT_RELEASE')
51+
PY
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
from __future__ import annotations
2+
3+
"""Canonical Mechanics authority for a control-ready Rig + Skin pair.
4+
5+
The Compiler does not invent mechanical behavior here. It qualifies that the
6+
already-canonical AXIS rig program is executable by the declared deterministic
7+
Mechanics semantics, that zero-control rest is stable, and that CanonicalSkin can
8+
be deformed without lineage or numeric failure. The canonical output seals that
9+
execution contract for runtime/Motion consumers.
10+
"""
11+
12+
from dataclasses import asdict, dataclass, field, replace
13+
from typing import Any
14+
import math
15+
16+
import numpy as np
17+
18+
from .canonical_mesh_ir_v1 import CanonicalMeshIR, canonical_mesh_lineage_hash_v1
19+
from .canonical_rig_ir_v2 import CanonicalRigIRV2, canonical_rig_lineage_hash_v2
20+
from .canonical_skin_ir_v2 import CanonicalSkinIRV2, canonical_skin_lineage_hash_v2
21+
from .hashing import content_sha256
22+
from .mechanics_control_solver_v1 import deform_mesh_lbs_v1, solve_control_pose_v1
23+
from .rig_constraint_schema_v1 import RIG_CONSTRAINT_OPERATOR_IDS_V1, validate_rig_constraint_operator_v1
24+
from .types import QualificationError
25+
26+
Json = dict[str, Any]
27+
28+
29+
@dataclass(frozen=True)
30+
class CanonicalMechanicsIRV1:
31+
mesh_lineage_hash: str
32+
rig_lineage_hash: str
33+
deform_structure_hash: str
34+
control_program_hash: str
35+
skin_lineage_hash: str
36+
constraint_schedule: tuple[str, ...]
37+
executable_operator_ids: tuple[str, ...]
38+
rest_pose_hash: str
39+
qualification_hash: str
40+
mechanics_lineage_hash: str
41+
schema_version: str = "RealSaS.CanonicalMechanicsIR.v1"
42+
metadata: Json = field(default_factory=dict)
43+
44+
def to_dict(self) -> dict:
45+
return asdict(self)
46+
47+
48+
def canonical_mechanics_lineage_hash_v1(value: CanonicalMechanicsIRV1) -> str:
49+
payload = value.to_dict()
50+
payload.pop("mechanics_lineage_hash", None)
51+
return content_sha256(payload)
52+
53+
54+
def _validate_local_frames(rig: CanonicalRigIRV2) -> None:
55+
by_joint = {f.canonical_joint_id: f for f in rig.local_frames}
56+
joint_ids = {j.canonical_joint_id for j in rig.joints}
57+
if set(by_joint) != joint_ids:
58+
raise QualificationError("MECHANICS_FRAME_COVERAGE_DRIFT")
59+
for jid, frame in by_joint.items():
60+
basis = np.asarray(frame.basis, dtype=np.float64)
61+
if basis.shape != (3, 3) or not np.isfinite(basis).all():
62+
raise QualificationError("MECHANICS_FRAME_INVALID")
63+
gram = basis @ basis.T
64+
if float(np.max(np.abs(gram - np.eye(3)))) > 1e-4:
65+
raise QualificationError(f"MECHANICS_FRAME_NOT_ORTHONORMAL:{jid}")
66+
det = float(np.linalg.det(basis))
67+
if not math.isfinite(det) or abs(det - 1.0) > 1e-4:
68+
raise QualificationError(f"MECHANICS_FRAME_NOT_RIGHT_HANDED:{jid}")
69+
70+
71+
def mint_canonical_mechanics_v1(
72+
mesh: CanonicalMeshIR,
73+
rig: CanonicalRigIRV2,
74+
skin: CanonicalSkinIRV2,
75+
*,
76+
rest_position_tolerance: float = 1e-5,
77+
rest_constraint_tolerance: float = 1e-4,
78+
) -> CanonicalMechanicsIRV1:
79+
if mesh.mesh_lineage_hash != canonical_mesh_lineage_hash_v1(mesh):
80+
raise QualificationError("MECHANICS_MESH_LINEAGE_DRIFT")
81+
if rig.rig_lineage_hash != canonical_rig_lineage_hash_v2(rig):
82+
raise QualificationError("MECHANICS_RIG_LINEAGE_DRIFT")
83+
if skin.skin_lineage_hash != canonical_skin_lineage_hash_v2(skin):
84+
raise QualificationError("MECHANICS_SKIN_LINEAGE_DRIFT")
85+
if rig.mesh_lineage_hash != mesh.mesh_lineage_hash or skin.mesh_lineage_hash != mesh.mesh_lineage_hash:
86+
raise QualificationError("MECHANICS_PARENT_MESH_DRIFT")
87+
if skin.deform_structure_hash != rig.deform_structure_hash:
88+
raise QualificationError("MECHANICS_DEFORM_STRUCTURE_DRIFT")
89+
if rest_position_tolerance < 0.0 or rest_constraint_tolerance < 0.0:
90+
raise QualificationError("MECHANICS_TOLERANCE_INVALID")
91+
92+
_validate_local_frames(rig)
93+
chain_ids = {c.canonical_chain_id for c in rig.chains}
94+
control_ids = {c.canonical_control_id for c in rig.controls}
95+
joint_ids = {j.canonical_joint_id for j in rig.joints}
96+
for constraint in rig.constraints:
97+
if any(cid not in control_ids for cid in constraint.input_canonical_control_ids):
98+
raise QualificationError("MECHANICS_CONSTRAINT_CONTROL_UNKNOWN")
99+
if any(jid not in joint_ids for jid in constraint.output_canonical_joint_ids):
100+
raise QualificationError("MECHANICS_CONSTRAINT_JOINT_UNKNOWN")
101+
if constraint.canonical_chain_id is not None and constraint.canonical_chain_id not in chain_ids:
102+
raise QualificationError("MECHANICS_CONSTRAINT_CHAIN_UNKNOWN")
103+
validate_rig_constraint_operator_v1(
104+
operator_id=constraint.operator_id,
105+
input_control_count=len(constraint.input_canonical_control_ids),
106+
output_joint_count=len(constraint.output_canonical_joint_ids),
107+
has_chain=constraint.canonical_chain_id is not None,
108+
parameters=constraint.parameters,
109+
)
110+
111+
rest_pose = solve_control_pose_v1(rig, ())
112+
deformed = deform_mesh_lbs_v1(mesh, rig, skin, rest_pose)
113+
mesh_by_id = {str(v.canonical_mesh_vertex_id): np.asarray(v.P, dtype=np.float64) for v in mesh.vertices}
114+
max_rest_drift = 0.0
115+
for vid, value in zip(deformed.canonical_mesh_vertex_ids, deformed.positions):
116+
max_rest_drift = max(max_rest_drift, float(np.linalg.norm(np.asarray(value, dtype=np.float64) - mesh_by_id[vid])))
117+
max_constraint_residual = max((float(v) for _, v in rest_pose.constraint_residuals), default=0.0)
118+
if max_rest_drift > float(rest_position_tolerance):
119+
raise QualificationError(f"MECHANICS_REST_POSE_DRIFT:{max_rest_drift:.9g}")
120+
if max_constraint_residual > float(rest_constraint_tolerance):
121+
raise QualificationError(f"MECHANICS_REST_CONSTRAINT_RESIDUAL:{max_constraint_residual:.9g}")
122+
123+
rest_pose_hash = content_sha256(rest_pose.to_dict())
124+
qualification = {
125+
"schema": "RealSaS.MechanicsQualification.v1",
126+
"status": "PASS_MECHANICS_EXECUTABLE",
127+
"frame_coverage": len(rig.local_frames),
128+
"control_count": len(rig.controls),
129+
"chain_count": len(rig.chains),
130+
"constraint_count": len(rig.constraints),
131+
"max_rest_position_drift": max_rest_drift,
132+
"max_rest_constraint_residual": max_constraint_residual,
133+
"rest_position_tolerance": float(rest_position_tolerance),
134+
"rest_constraint_tolerance": float(rest_constraint_tolerance),
135+
"constraint_solver_executed": True,
136+
"rig_program_mutated": False,
137+
"skin_mutated": False,
138+
"learned_inference_performed": False,
139+
}
140+
qualification_hash = content_sha256(qualification)
141+
value = CanonicalMechanicsIRV1(
142+
mesh_lineage_hash=mesh.mesh_lineage_hash,
143+
rig_lineage_hash=rig.rig_lineage_hash,
144+
deform_structure_hash=rig.deform_structure_hash,
145+
control_program_hash=rig.control_program_hash,
146+
skin_lineage_hash=skin.skin_lineage_hash,
147+
constraint_schedule=tuple(c.canonical_constraint_id for c in rig.constraints),
148+
executable_operator_ids=RIG_CONSTRAINT_OPERATOR_IDS_V1,
149+
rest_pose_hash=rest_pose_hash,
150+
qualification_hash=qualification_hash,
151+
mechanics_lineage_hash="",
152+
metadata={
153+
"authority": "COMPILER_CANONICAL_MECHANICS",
154+
"constraint_execution_semantics": "MECHANICS_CONTROL_SOLVER_V1",
155+
"post_bind_frame_observability_owner": "MECHANICS",
156+
"canonical_constraint_solution_rest_pose": True,
157+
"runtime_control_pose_solution_uses_same_solver": True,
158+
"compiler_rig_synthesis_performed": False,
159+
"motion_authority_claimed": False,
160+
"graphics_authority_claimed": False,
161+
},
162+
)
163+
return replace(value, mechanics_lineage_hash=canonical_mechanics_lineage_hash_v1(value))
164+
165+
166+
def canonical_mechanics_from_dict_v1(payload: dict[str, Any]) -> CanonicalMechanicsIRV1:
167+
schema = str(payload.get("schema_version") or payload.get("schema") or "")
168+
if schema != "RealSaS.CanonicalMechanicsIR.v1":
169+
raise QualificationError("MECHANICS_SCHEMA_DRIFT")
170+
value = CanonicalMechanicsIRV1(
171+
mesh_lineage_hash=str(payload["mesh_lineage_hash"]),
172+
rig_lineage_hash=str(payload["rig_lineage_hash"]),
173+
deform_structure_hash=str(payload["deform_structure_hash"]),
174+
control_program_hash=str(payload["control_program_hash"]),
175+
skin_lineage_hash=str(payload["skin_lineage_hash"]),
176+
constraint_schedule=tuple(map(str, payload.get("constraint_schedule") or ())),
177+
executable_operator_ids=tuple(map(str, payload.get("executable_operator_ids") or ())),
178+
rest_pose_hash=str(payload["rest_pose_hash"]),
179+
qualification_hash=str(payload["qualification_hash"]),
180+
mechanics_lineage_hash=str(payload["mechanics_lineage_hash"]),
181+
schema_version=schema,
182+
metadata=dict(payload.get("metadata") or {}),
183+
)
184+
if value.mechanics_lineage_hash != canonical_mechanics_lineage_hash_v1(value):
185+
raise QualificationError("MECHANICS_LINEAGE_HASH_DRIFT")
186+
if value.metadata.get("authority") != "COMPILER_CANONICAL_MECHANICS":
187+
raise QualificationError("MECHANICS_AUTHORITY_DRIFT")
188+
return value
189+
190+
191+
__all__ = [
192+
"CanonicalMechanicsIRV1", "canonical_mechanics_from_dict_v1",
193+
"canonical_mechanics_lineage_hash_v1", "mint_canonical_mechanics_v1",
194+
]

0 commit comments

Comments
 (0)