Documentation Index
Fetch the complete documentation index at: https://dadd.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Register a callback that runs after mj_step every physics frame. Use this for reading simulation results, computing rewards, or logging.
Signature
useAfterPhysicsStep(
callback: (model: MujocoModel, data: MujocoData) => void
): void
Usage
Reading State
useAfterPhysicsStep((model, data) => {
const pos = data.xpos.subarray(3, 6); // Body 1 position
console.log("Body position:", pos[0], pos[1], pos[2]);
});
Computing Rewards (RL)
useAfterPhysicsStep((model, data) => {
const targetPos = [0.5, 0, 0.3];
const eePos = data.xpos.subarray(eeSiteId * 3, eeSiteId * 3 + 3);
const dist = Math.sqrt(
(eePos[0] - targetPos[0]) ** 2 +
(eePos[1] - targetPos[1]) ** 2 +
(eePos[2] - targetPos[2]) ** 2
);
rewardRef.current = -dist;
});
Logging Sensor Data
useAfterPhysicsStep((model, data) => {
if (data.time % 0.1 < model.opt.timestep) {
logRef.current.push({
time: data.time,
qpos: Array.from(data.qpos),
sensordata: Array.from(data.sensordata),
});
}
});
Execution Order
1. Provider zeros qfrc_applied
2. useBeforePhysicsStep callbacks
3. IK solving (if enabled)
4. mj_step
5. → Your useAfterPhysicsStep callbacks run here ←
Notes
- After-step runs at physics rate, not render rate
- Results are available immediately for rendering in the same frame
- Multiple after-step hooks compose — all run each frame
- Write results to refs (not React state) to avoid re-renders at 60fps