The HJCD-IK algorithm#

HJCD-IK three-phase pipeline — initialization, polishing, collision filter

Fig. 1 The HJCD-IK pipeline: orientation-aware greedy coordinate-descent initialization (PO-CCD), parallel Jacobian-based polishing (PJ-IK), and a parallel collision filter.#

Hybrid Jacobian Coordinate Descent is a three-phase, sampling-based solver that combines cheap per-joint coordinate updates with Jacobian-based refinement and a GPU collision filter:

  1. Coarse search (PO-CCD). From hundreds-to-thousands of random restarts, an orientation-aware greedy coordinate-descent sweep picks the per-joint moves that most reduce position and orientation error. Cheap, fast, and good at escaping poor initializations — it produces a diverse set of coarse seeds.

  2. Levenberg–Marquardt refine (PJ-IK). The best coarse candidates are polished: build the 6×N geometric Jacobian from the world-frame joint transforms (cross-products), form the normal equations (JᵀJ + λ·diag)Δq = Jᵀr, and solve them with a warp Cholesky. A trust region + backtracking line search (with dogleg / single-coordinate fallbacks) adapts λ to sub-millimetre, sub-degree accuracy.

  3. Collision filter. The refined batch is filtered for feasibility (see below).

The end-effector error is computed as a quaternion orientation error plus a Euclidean position error. See arXiv:2510.07514 for the full method and evaluation.

Batched execution & warp-locality#

HJCD-IK launches one CUDA block per IK problem and processes one candidate per warp (warp_id = threadIdx.x >> 5, lane = threadIdx.x & 31). This warp-locality is the core performance contract — a single block sweeps many candidates concurrently:

  • Forward kinematics, the Jacobian build, the reductions, and the normal-equations solve are all warp-scoped, using __shfl_*_sync / __syncwarp rather than block-wide barriers.

  • The SYNC() macro selects __syncwarp() for single-warp blocks and __syncthreads() otherwise.

When refactoring math onto GRiD/GLASS, keep it warp-scoped: use grid::ee_pose_inner_warp and the glass::warp:: primitives — not block-scoped (glass::), cooperative-groups (glass::cgrps::), or vendor (glass::nvidia::) paths, which lose parallelism or add overhead at these tiny, warp-dispatched sizes.

Collision avoidance#

With collision_free=True, the refined candidates are scored against the environment after optimization (never on the hot solver loop) using GRiD’s URDF-driven grid_collision. The robot is approximated by covering spheres baked into grid.cuh at codegen (--collision); obstacles (spheres / cuboids / cylinders) come from the problem set. soft mode (default) adds a penetration cost that biases selection; hard mode filters colliding candidates with grid_collision::config_free (self and environment); both combines them (env HJCD_CC_MODE).

Because collision geometry is generated from the same URDF as the kinematics, adding a robot needs no hand-written collision code — see Custom robot (GRiD codegen workflow). A grid.cuh built without --collision runs open-world (a collision_free=True request is ignored).