One convention across both independent courses
The executable baseline is MuJoCo 3.13.0, fixed in pyproject.toml and uv.lock. The Python baseline is 3.12. Links to stable documentation may advance; use the version selector when comparing with these examples. SI units and radians are the default. Use
Equations and fields
: configuration, stored in data.qpos, length model.nq. : generalized velocity, data.qvel, length model.nv. In general . : data.qacc, length nv. : generalized inertia, nv by nv. Reconstruct with mj_fullM(model, data, M) in the tested version. Internal storage is not a dense array to reshape. : data.qfrc_bias, combining Coriolis, centrifugal, and gravitational bias. : an alternative textbook name for the same bias vector in this course. It is not an additional force. A decomposition is possible, but C itself is not unique. : total nonconstraint generalized force. Separate qfrc_actuator, qfrc_passive, and qfrc_applied. Cartesian loads in xfrc_applied also need their generalized-force mapping. : engine constraint contribution, qfrc_constraint. Constraint-space data include efc_J and efc_force, with storage and active rows determined by the model/solver.
The simple force-residual practices deliberately leave xfrc_applied zero. Do not reuse that abbreviated residual for a model with nonzero Cartesian applied loads without including their mapping. ctrl has length nu and is an actuator input, not generally an nv-dimensional torque vector. act stores optional activation state.
Reference: MuJoCo computation.
Quaternions and frames
Use scalar-first (w, x, y, z). Identity is (1, 0, 0, 0). We write Q for one quaternion and q for the whole configuration. Q represents a body-to-world active rotation:
A positive
For a free joint, configuration has [px, py, pz, qw, qx, qy, qz]. Velocity has [vx, vy, vz, wx, wy, wz]: translational velocity in the world frame and angular velocity in the local body frame. Querying other spatial quantities can use different origins or component order. In particular, mj_objectVelocity returns a rotational-then-linear spatial vector in the selected orientation frame.
Tangent operations
Use mj_integratePos for full-configuration updates and mj_differentiatePos for differences. Calling differentiatePos with dt=1 gives a local configuration displacement, not a measured velocity over one second.
dq = np.empty(model.nv)
mujoco.mj_differentiatePos(model, dq, 1.0, q_reference, data.qpos)
error = np.concatenate([dq, data.qvel - v_reference])
For direct actuators without activation, the local dynamics state has 2 nv coordinates. With activation, it has 2 nv + na. mjd_transitionFD uses these tangent dimensions. The teaching examples use Euler; this derivative API does not support RK4 in the referenced version.
Function connections
- Refresh a state without integrating: mj_forward.
- Advance physics: mj_step.
- Dense inertia for small examples: mj_fullM.
- Tool Jacobians: mj_jacSite.
- Requested-acceleration force query: mj_inverse. Set qacc first and interpret passive/constraint contributions.
- Contact-frame wrench: mj_contactForce.
- Object spatial velocity: mj_objectVelocity.
Always refresh derived quantities after editing a state before reading them.
MJX boundary
The optional example selects MJX-JAX explicitly. Functional data updates, jit, and vmap differ from mutable CPU MuJoCo. Synchronize device outputs when timing. MJX-Warp is a different backend with different support; do not assume JAX autodiff guarantees apply to it. Read the MJX feature documentation before extending a model.