/** * KinematicChainTrait — DH-parameter FK + damped Jacobian IK (H2). * * Provides forward kinematics (FK) and inverse kinematics (IK) for serial * kinematic chains described by standard Denavit-Hartenberg parameters. * * ## DH Convention (Standard) * * Each row of the DH table defines the transform from frame i-1 to frame i: * * T_{i-1,i} = Rot_z(θ_i) · Trans_z(d_i) · Trans_x(a_i) · Rot_x(α_i) * * Row-major 4×4 matrix form: * [ cos θ, -sin θ cos α, sin θ sin α, a cos θ ] * [ sin θ, cos θ cos α, -cos θ sin α, a sin θ ] * [ 0, sin α, cos α, d ] * [ 0, 0, 0, 1 ] * * where θ = thetaOffset + jointAngle (constant offset + variable q_i). * * ## IK: damped Jacobian (Levenberg-Marquardt) * * Position-only IK. 3×n Jacobian column j: J[:,j] = z_{j-1} × (p_ee - p_{j-1}). * Update: dq = J^T (JJ^T + λ²I)⁻¹ Δp. Converges in ≤ 100 iterations for * well-conditioned chains. * * ## Domain-neutrality * * No domain nouns appear here. The solver applies to robotics, animation, * biomechanics, and any articulated structure. * * ## Trait usage * * onAttach: pre-computes FK from initial config if links/angles are set. * onEvent 'kinematic_chain.solve_fk': FK → result on node.__kinematic_fk. * onEvent 'kinematic_chain.solve_ik': IK → result on node.__kinematic_ik. */ import type { TraitHandler } from './TraitTypes'; /** One row of the standard Denavit-Hartenberg parameter table. */ export interface DHParameter { /** Link length (scene units). */ a: number; /** Link twist α (radians). */ alpha: number; /** Joint offset d along z (scene units). */ d: number; /** Constant joint angle offset (radians). Added to the variable q_i. */ theta: number; } /** Trait configuration — DH table plus current joint angles. */ export interface KinematicChainConfig { /** DH table — one row per joint. */ links: DHParameter[]; /** Current joint angles q (radians). Length must equal `links.length`. */ jointAngles: number[]; } /** Result of forward kinematics. */ export interface FKResult { /** End-effector position in the base frame. */ endEffectorPosition: { x: number; y: number; z: number; }; /** Full 4×4 end-effector transform (row-major, 16 elements). */ endEffectorTransform: number[]; /** Per-joint frame transforms (row-major 4×4), indexed 0..n-1. */ frameTransforms: number[][]; } /** Input to the IK solver. */ export interface IKRequest { /** DH table — one row per joint. */ links: DHParameter[]; /** Target end-effector position in the base frame. */ target: { x: number; y: number; z: number; }; /** Initial joint angles. Defaults to all-zero. */ initialAngles?: number[]; /** Maximum iterations. Default: 100. */ maxIterations?: number; /** Convergence tolerance (scene units). Default: 1e-4. */ tolerance?: number; /** Damping factor λ for LM update. Default: 0.01. */ damping?: number; } /** Result of inverse kinematics. */ export interface IKResult { /** Joint angles that achieve (approximately) the target. */ jointAngles: number[]; /** True when final error is below tolerance. */ converged: boolean; /** Final end-effector position error. */ finalError: number; /** Iterations used. */ iterations: number; } /** * Standard DH homogeneous transform (row-major, 16 elements). * Index [row*4 + col]. */ export declare function dhTransform(a: number, alpha: number, d: number, theta: number): number[]; /** * Forward kinematics — compute end-effector pose from DH table + joint angles. */ export declare function solveFk(links: DHParameter[], jointAngles: number[]): FKResult; /** * Position-only IK using a damped Jacobian (Levenberg-Marquardt). * * Converges in ≤ `maxIterations` steps. Returns `converged: true` when the * end-effector position is within `tolerance` of `target`. */ export declare function solveIk(req: IKRequest): IKResult; export declare const kinematicChainHandler: TraitHandler;