> ## Documentation Index
> Fetch the complete documentation index at: https://dadd.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Policy Primitives

> Composable hooks for real policy rollouts

These primitives help policy apps avoid raw MuJoCo array plumbing while keeping
controllers explicit and composable.

## Control Ownership

Use `defineControls()` with `useControls()` when a controller, policy, replay,
or teleop path writes actuator controls by name. The hook cooperatively claims
the declared actuators, uses a generated owner by default, and refuses to write
when another writer has already claimed the same actuators.

```tsx theme={null}
import {
  ModelActuators,
  defineControls,
  useBeforePhysicsStep,
  useControls,
} from "mujoco-react";

const arm = defineControls({
  shoulder: ModelActuators.so101.shoulder_pan,
  lift: ModelActuators.so101.shoulder_lift,
  elbow: ModelActuators.so101.elbow_flex,
});

function PolicyControls({ action }: { action: number[] }) {
  const controls = useControls(arm);

  useBeforePhysicsStep(() => {
    controls.write(action);
  });

  return null;
}
```

For sparse updates, use aliases:

```tsx theme={null}
controls.set("elbow", 1.2);
controls.patch({ shoulder: 0.1, lift: -0.4 });
controls.read().elbow;
```

For lower-level actuator-name controls, use `controlGroup()` with
`useControlGroup()`:

```tsx theme={null}
const gripper = controlGroup([ModelActuators.so101.gripper]);
const controls = useControlGroup(gripper, { label: "debug-gripper" });

controls.set(ModelActuators.so101.gripper, -0.17453);
```

Use `useControlWriter` directly only when you need selector-based ownership for
sites, bodies, joints, regular expressions, or predicates.

For real policy evaluation, make policy, IK, keyboard teleop, replay, and debug
state mutation mutually exclusive. Use `force: true` only for deliberate
low-level overrides.

## Named Poses

Use pose hooks for HUDs, diagnostics, and verifier logic:

```tsx theme={null}
const cube = useBodyPose("cube");
const gripper = useSitePose("gripper");
const contactGeom = useGeomPose("left_finger_pad");

cube.position.current.toArray();
gripper.quaternion.current.toArray();
contactGeom.found.current;
```

The hooks update refs after physics steps and do not trigger React re-renders.

## Contact History

`useContactHistory` records a bounded contact log with body and geom names:

```tsx theme={null}
const history = useContactHistory({
  bodyNames: ["cube", "gripper"],
  maxLength: 1000,
});

const graspContacts = history.countPair("cube", "gripper");
history.clear();
```

This is useful for browser verifiers that need evidence of physical contact,
not just visual movement.

## Named Observations

Named observation builders make policy vector order and units visible:

```tsx theme={null}
const observation = useNamedObservation({
  fields: [
    qposField("shoulder_pan", 0, "radians"),
    qposField("shoulder_lift", 1, "radians"),
    bodyPositionField("cube", "meters"),
    sitePositionField("gripper", "meters"),
  ],
  missing: "throw",
});

const { values, layout } = observation.read();
```

`layout` records each field name, vector start, size, and units. Use it in
telemetry and tests so model/input mismatches are visible.
