Solvers#
Base#
- class mink_warp.Solver[source]#
Bases:
ABCBatched IK solver operating on a shared
Configuration.Contract:
solve_and_integrate()advances the configuration toward the task targets and returns a representative tangent velocity(nworld, nv).For multi-iteration backends (LM / L-BFGS) the returned
vis the sum of the per-iteration tangent steps divided bydt. Re-integratingvoverdtreproduces the optimized configuration exactly for Euclidean joints (hinge / slide); for free / ball joints it agrees to second order (the true update is a composition of manifold exponentials,vtheir tangent sum). The configuration itself is always left at the exact optimized state. A solver is bound to its configuration’snworld/nvand cannot be reused with a differently sized one.- supports_limits: bool = False#
Whether this backend enforces hard limits. Only
ConstrainedSolversets this True; the cost-only backends (DLS / LM / L-BFGS) cannot honour alimits=argument and callers must not silently assume they do.
- abstractmethod solve_and_integrate(tasks: Sequence[Task], dt: float, *, iterations: int = 1, use_graph: bool = False, **kwargs) array[source]#
Advance
configurationand return the tangent velocity.
Backends#
- class mink_warp.DLSSolver[source]#
Bases:
SolverReusable batched damped-least-squares IK solver.
Solves \((W^T W + \lambda I)\Delta q = -W^T e\) on device and returns \(v = \Delta q / dt\). Optional CUDA graph capture for fixed task sets.
Note: CUDA graphs cannot include host->device copies.
dtis written to a device buffer before capture; integrate is out-of-place (in-place qpos aliasing is not graph-safe).- solve(tasks: Sequence[Task], dt: float, damping: float | None = None) array[source]#
Compute the velocity for one differential step (no integration).
- class mink_warp.LMSolver[source]#
Bases:
SolverBatched Levenberg-Marquardt IK solver.
- Parameters:
lambda0 – initial damping (reset at the start of every call).
lambda_max (lambda_min /) – clamp range for the adaptive damping.
eps – gain-ratio regularizer added to the predicted reduction, so a near-zero prediction at convergence does not amplify float32 noise.
- class mink_warp.LBFGSSolver[source]#
Bases:
SolverBatched limited-memory BFGS IK solver.
- Parameters:
history – number
mof(s, y)pairs retained.line_search – candidate step sizes evaluated in parallel each iteration.
eps – sufficient-decrease floor for the line search.
curvature_eps – relative curvature floor
s.y > curvature_eps * ||y||^2below which a pair is skipped (kept out of the history).
- class mink_warp.ConstrainedSolver[source]#
Bases:
SolverBatched constrained IK via ADMM on the task normal equations.
Per world, solves:
\[\min_{\Delta q}\ \tfrac{1}{2} \Delta q^\top H \Delta q + c^\top \Delta q \quad \text{s.t.}\ \ell \leq \Delta q \leq u,\ G \Delta q \leq h\]where \(H, c\) match
DLSSolver. Box limits are enforced exactly each ADMM iteration; general rows converge withadmm_iters.- Parameters:
configuration – Batched configuration to advance.
limits – Hard limits.
None→ defaultConfigurationLimit;[]→ unconstrained regularized DLS inside the solver.admm_iters – Inner ADMM iterations per solve.
rho_scale – ADMM penalty \(\rho = \mathrm{clamp}(\rho_{\mathrm{scale}} \sqrt{h_{\min} h_{\max}}, \ldots)\).
rho_min – ADMM penalty \(\rho = \mathrm{clamp}(\rho_{\mathrm{scale}} \sqrt{h_{\min} h_{\max}}, \ldots)\).
rho_max – ADMM penalty \(\rho = \mathrm{clamp}(\rho_{\mathrm{scale}} \sqrt{h_{\min} h_{\max}}, \ldots)\).
alpha – Over-relaxation in \([1, 2)\).
damping – Tikhonov \(\lambda\) on \(H\) (matches
solve_ik).sigma – SPD floor for the general-inequality path.
use_inequalities – Force dense \(G \Delta q \leq h\) even for box limits. Auto-enabled for inequality-only limits such as
CollisionAvoidanceLimit.
- supports_limits: bool = True#
Whether this backend enforces hard limits. Only
ConstrainedSolversets this True; the cost-only backends (DLS / LM / L-BFGS) cannot honour alimits=argument and callers must not silently assume they do.
- solve(tasks: Sequence[Task], dt: float, damping: float | None = None) array[source]#
Compute the box-feasible velocity for one differential step.
- solve_and_integrate(tasks: Sequence[Task], dt: float, *, iterations: int = 1, use_graph: bool = False, damping: float | None = None) array[source]#
Solve and integrate
iterationstimes; returns last velocity.Each outer iteration re-linearizes
Hand recomputes the box at the current configuration, so the returned step stays feasible throughout.
Factory#
- mink_warp.make_solver(configuration: Configuration, kind: str = 'dls', **kwargs) Solver[source]#
Construct a solver backend by name.
"dls"/"lm"/"lbfgs"/"constrained"(the last enforces hard joint limits; passlimits=to override the default ConfigurationLimit).
Registry#
mink_warp.solvers.SOLVERS maps solver name strings to backend classes
("dls", "lm", "lbfgs", "constrained").