usePolicy works with synchronous browser models, remote HTTP
policies, and receding-horizon policies that return chunks of future actions.
The hook only schedules policy inference and applies the returned actions. It
does not run IK, blend actions, or synthesize task logic. If a policy is trained
for a scene, the scene, observation vector, camera streams, units, and action
order must match that policy.
Signature
Usage
Config
Return Value
How It Works
- The hook registers a
useBeforePhysicsStepcallback - Each physics step, it checks if enough time has elapsed since the last inference (based on
frequency) - If a queued action exists, it applies that action with
onAction - If inference is needed, it calls
onObservationto build the observation vector - Then it calls
inferif provided; otherwise it uses the observation as the action - If
inferreturns a chunk, the first action is applied immediately when possible and the rest are queued - If
inferreturns a promise, future actions are queued when the promise resolves
queueStrategy: "replace" so fresh chunks
supersede stale queued actions. Use prefetchThreshold to request the next
chunk before the queue is empty.
infer receives queuedActions, the number of future actions still buffered
when the request starts. Remote policy adapters can pass this to the server so
it can tune horizon length, skip work, or report queue telemetry.
For long open-loop chunks, use queueStrategy: "append" so prefetching does not
discard the tail of the current plan. When pausing a remote policy or changing
policy inputs, call reset() or set clearQueueOnStop: true; pending async
responses are ignored after a reset so stale server results cannot resume later.
Example: Remote Chunked Policy
useRemotePolicy is a convenience wrapper around usePolicy: it posts JSON to
endpoint, accepts responses shaped like { action: number[] } or
{ actions: number[][] }, and exposes request metadata such as
remoteStatus, requestCount, responseCount, lastHttpStatus, and
lastRequestMs. It aborts the active HTTP request on stop() and reset() by
default; call policy.abort() to cancel explicitly, or set abortOnStop: false
to let a request finish in the background. Use parseResponse when a server
returns a custom schema.
For browser-to-Python inference, an HTTP endpoint that returns chunks is usually
enough. WebSockets or SSE are useful when the policy server needs a continuous
bidirectional stream, but they add lifecycle complexity that chunked HTTP avoids.
Example: Visual Policy Captures
PairusePolicy with usePolicyCameraFramesFromMountedStreams when the policy
expects images and your camera streams should resolve from the loaded MuJoCo
model:
capturePolicyCameraFramesFromMountedStreams(api, options) instead when
the capture happens outside React.
Example: TensorFlow.js Policy
Notes
- Disable IK or any other controller that writes the same controls while a policy is running.
- The policy runs inside
useBeforePhysicsStep, so it executes at physics rate but only does inference atfrequencyHz onObservationandonActionrun in the physics callback; keep them fast.- Remote inference belongs in
infer, which may return a promise. - Match policy units explicitly. For example, do not send degrees to a policy trained on radians.
- Use
applyPolicyActionToControlsfor the common case of writing an action vector todata.ctrl; it clamps tomodel.actuator_ctrlrangeand skips non-finite entries by default.