Concepts

Geometry

robokit.geom runs batched SDF queries against scenes of mixed geometry types. Each query point gets its signed distance (negative inside), the surface normal and the closest surface point. Collision terms, motion planning and grasp optimization build on it.

Overview

text
BoxGeom / SphereGeom / PlaneGeom / CapsuleGeom / MeshGeom / VolumeGeom
    |  scene.add(geom)
    v
WarpScene.query_sdf(points, scene_offsets)
    1. route each point to its scene
    2. launch one Warp kernel per geom, aggregated through the min
    3. return signed distances (+ normals, closest points)

Example usage:

python
geom = BoxGeom(half_extents, scene_offsets, poses=poses)  # store raw inputs (CPU)
scene = WarpScene(num_scenes=1, device=device).add(geom)  # allocate GPU arrays of the geom
geom.update(poses=new_poses)  # in-place copy

update copies in place and never reallocates. A query captured in a CUDA graph keeps working after the scene moves.

Geom Types

GeomElementsSDF
BoxGeomhalf extentsanalytical
SphereGeomradiianalytical
PlaneGeomlocal z=0 halfspaces, posedanalytical
CapsuleGeomradii + half heightsanalytical
MeshGeomtriangle meshesmesh BVH or baked grid
VolumeGeompre-baked SdfVolume gridstrilinear grid sample

Every geom takes scene_offsets, which assign its elements to scenes. poses and scales are optional. Set capacity to add elements later without reallocating.

Query

python
sdf, normals, closest = scene.query_sdf(points, scene_offsets)  # min aggregate over all geoms
sdf = scene.query_sdf(points, scene_offsets, distance_only=True)  # query the whole scene, but skip normals/closest
sdf, _, _ = geom.query_sdf(points, scene_offsets)  # this geom only
  • Batching: one WarpScene holds num_scenes independent scenes. scene_offsets or per-point scene_indices map each query point to its scene.
  • Masking: query_mask skips masked points.
  • Gradients: query_sdf_torch(points, offsets, poses={geom: T}) is differentiable in the points and any pose or scale overrides.

Mesh Level-of-Detail

A baked SDF grid speeds up mesh queries. MeshGeom(enable_sdf=True, sdf_voxel_size=0.01) bakes one per mesh and caches it under ~/.robokit/sdf_cache. Queries then cascade:

text
outside the padded AABB -> AABB distance + padding
inside the grid         -> O(1) grid sample
near the surface        -> exact mesh BVH