Ball in Cup¶
A planar ball-and-cup task: a ball hangs from a tether attached to a movable cup. The agent actuates the cup in 2D and must catch the ball inside.
BallInCup¶

| Property | Value |
|---|---|
| Canonical ID | mjx/ball_in_cup-v0 |
| Action space | Box(-1.0, 1.0, (2,), float32) |
| Observation space | Box(-inf, inf, (8,), float32) |
| Episode length | 1000 |
| Config | {"ctrl_dt": 0.02, "sim_dt": 0.002, "naconmax": 10_000, "njmax": 25} |
Description¶
The cup moves freely in the 2D plane while the ball swings on its tether. The task succeeds the moment the ball is brought inside the cup's catch region. The tether dynamics make this a coordination problem — yanking the cup directly toward the ball usually misses on the first pass and overshoots on the second.
Rewards¶
Uses a sparse reward that fires only when the ball sits inside the cup's catch region in both x and z:
| Python | |
|---|---|
1 2 3 | |
The product over the two axes acts as a logical AND. The reward is binary:
1.0when the ball is inside the catch region in both x and z.0.0if either axis is outside.
Starting state¶
1 | |
(qpos and qvel concatenated — cup at the origin, ball hanging at rest.)
Termination¶
Episode ends when step >= max_steps (default 1000). No early termination.
Usage¶
| Python | |
|---|---|
1 2 | |
Reference¶
Upstream: mujoco_playground/_src/dm_control_suite/ball_in_cup.py.