Solver kernel#
The batched HJCD solver: block-cooperative coarse search, then warp-per-candidate Levenberg–Marquardt refinement.
The native host API lives in csrc/kernel/hjcd_kernel.h. Both sampling and solving
serialize access to shared CUDA constants and stop flags. Python releases the GIL while
these operations run. Models and joint limits are cached per CUDA device; callers must
keep the CUDA context alive (calling cudaDeviceReset invalidates those caches).
Result<T> owns its host arrays, releases them on destruction, and supports moves
but not copies. Temporary device allocations are released on normal return and exceptions.
HJCD CUDA runtime failures raise std::runtime_error (Python RuntimeError),
including generated model/limit initialization. HJCD uses GRiD’s checked APIs:
initialization failures report the operation, roll back partial allocations best-effort,
and never reset the CUDA context or terminate the process. This does not promise
recovery after a context-invalidating CUDA error.
A null model argument selects the internally cached model for sampling. The solver selects its own coarse/refine models by precision; its model argument is retained for source compatibility. Position errors are in millimeters and orientation errors in radians.
Defines
-
PI#
Functions
-
template<typename T, typename RT = double>
Result<T> generate_ik_solutions(T *target_pose, const grid::robotModel<T> *d_robotModel, int b_size, int num_solutions = 1, bool collision_free = false, const char *problems_json_text = nullptr, const char *problem_set_name = nullptr, int problem_idx = 0, bool write_stats = false, int collision_mode = -1)# Solve one end-effector target with a GPU batch of candidate configurations.
Compiled instantiations are <double,double>, <double,float>, and <float,double>. T controls I/O; RT controls LM compute precision; coarse search always uses float. Calls serialize shared native state on the calling thread’s current CUDA device. Cached models require that context to remain alive; cudaDeviceReset is unsupported.
- Parameters:
target_pose – Nonnull seven-vector [x,y,z,qw,qx,qy,qz], meters and scalar-first quaternion. Finite nonzero quaternions are normalized without mutating this input.
d_robotModel – Retained for source compatibility; ignored. Precision-specific internally cached generated models are used by the solver.
b_size – Positive candidate count (not a target count), bounded by CUDA indexing.
num_solutions – Positive maximum number of distinct candidates requested.
collision_free – Enable post-solve collision processing; requires a collision build.
problems_json_text – MotionBenchMaker-style JSON, required with collision_free.
problem_set_name – Key under the JSON “problems” object.
problem_idx – Nonnegative index within the selected problem set.
write_stats – Append diagnostics to ik_stats.csv; write failures throw.
collision_mode – 0 = environment-only soft ranking, 1 = hard self/environment filtering, 2 = both; -1 reads HJCD_CC_MODE (defaults to hard). Ignored in open-world solves.
- Throws:
std::invalid_argument – For invalid scalar/pose values.
std::runtime_error – For checked CUDA or output failures. Scene errors also throw. Generated model/limit initialization uses GRiD’s checked APIs and raises on failure.
- Returns:
Owning result. Candidates may be approximate, fewer than requested, or empty. Collision checks describe configurations, never paths.
-
template<typename T>
std::vector<std::array<T, 7>> sample_random_target_poses(const grid::robotModel<T> *d_robotModel, int num_configs, std::uint64_t seed)# Sample reachable world-frame poses from a seeded Halton joint sequence.
T may be float or double. The result uses [x,y,z,qw,qx,qy,qz], meters and scalar-first quaternions. Sampling respects joint limits but does not check collision. Calls share the solver lock and use the calling thread’s current CUDA device.
- Parameters:
d_robotModel – Device model matching the compiled robot and T, or nullptr for the cache.
num_configs – Positive target count bounded by CUDA launch indexing.
seed – Unsigned seed used to shift the Halton sequence.
-
void init_joint_limits_from_grid()#
Lazily initialize generated joint limits on the current device; normally called internally.
-
int grid_num_joints()#
Return the compiled actuated joint count without initializing CUDA.
-
bool grid_has_collision()#
Return whether the compiled header includes collision geometry, without initializing CUDA.
-
template<typename T>
struct Result# - #include <hjcd_kernel.h>
Move-only owner of a native solve’s row-major host buffers.
Read only the first count rows. A returned candidate is not a success certificate: check both error arrays against your tolerances. Collision filtering can yield count == 0. Buffers remain valid until this object is reset, destroyed, or moved from. Do not delete the individual pointers; ownership follows the Result object.
Public Functions
-
Result() = default#
-
inline ~Result()#
-
inline void reset() noexcept#
Release all owned buffers and restore the empty state; safe to call repeatedly.
Public Members
-
int count = 0#
Number of returned candidates, possibly less than requested.
-
Result() = default#
-
namespace grid#