The HJCD-IK algorithm#
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:
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.
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.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/__syncwarprather 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).