Generated by scripts/analyze_human_pushing.py from kp_file0.parquet; every number and figure below is that script's output. Reproduce with:
.venv/bin/python scripts/analyze_human_pushing.py /tmp/kp_file0.parquet
pusht_keypoints, file 0: 206 episodes, 25650 frames at 10 Hz. Columns used: observation.state (agent centre), observation.environment_state (8 block keypoints), next.reward, next.success.galilai-group/lewm-pusht) is the DINO-WM Push-T set, which is these same demonstrations replayed with action noise (DINO-WM App. A.1, LeWM App. E). Velocity, acceleration and jerk must therefore be measured on the clean demonstrations, as done here; the noised replays would corrupt them.(-60,0) (60,0) (60,30) (-60,30), stem (-15,30) (15,30) (15,120) (-15,120)); max fit residual over the file: 3.8e-05 px.next.reward[t] equals clip(coverage[t+1] / 0.95, 0, 1) with coverage computed by pusht_sim.envs.geometry.coverage from the recovered pose; max deviation over the analysed episodes 2.2e-07. "Final coverage" below is 0.95 x next.reward of the last frame, i.e. the coverage of the terminal state.next.success is never True in this file: no demonstration reaches 0.95 coverage before it ends (max terminal coverage 0.901).gap = dist(agent centre, T outline) - 15 (negative when the centre is inside the outline). Contact iff gap <= 1.0 px. The gap histogram over all 25650 frames has a spike in (-1, 0.5] px (Chipmunk's collision slop) and a flat tail beyond, so the threshold is not sensitive between 0.5 and 1.5 px.bar_top y=0, bar_end_R/L x=+-60, bar_bottom_R/L y=30 beside the stem, stem_R/L x=+-15, stem_tip y=120); the outward normal is the unit vector from that point to the agent centre (at corners this is the corner-to-centre direction).v[t] = (p[t+1]-p[t])/DT, a[t] = (v[t+1]-v[t])/DT, j[t] = (a[t+1]-a[t])/DT; the report uses |a| and |j|. Block CoG velocity and rotation rate omega likewise from the recovered pose. Units px/s, px/s^2, px/s^3, rad/s (deg/s in tables).v_n = -v . n_out (speed into the block) and v_t = |v . tangent| at the nearest outline point; dgap = (gap[t+1]-gap[t])/DT.TOUCH: first frame of a contact bout (contact[t] and not contact[t-1]).PUSH: in contact, not TOUCH, speed >= 10 px/s and v_n >= v_t (moving into the block, within 45 deg of the inward normal).HOLD: in contact, not TOUCH, speed < 10 px/s (pausing while touching; kept separate so PUSH/SLIDE speeds are not diluted).RETREAT (release step): in contact, not TOUCH, speed >= 10 px/s and -v_n >= v_t (moving away from the block faster than along it: this is the step that breaks contact).SLIDE: in contact, not TOUCH, speed >= 10 px/s and v_t > |v_n| (moving along the outline).APPROACH: no contact, speed >= 10 px/s and closing speed -dgap >= sqrt(speed^2 - dgap^2), i.e. heading within 45 deg of the nearest outline point. The step that makes contact (contact[t+1]) is always APPROACH: contact resolution shortens its normal component, so its heading is not meaningful.RETREAT: no contact, speed >= 10 px/s and dgap >= sqrt(speed^2 - dgap^2), i.e. heading within 45 deg of straight away from the outline.REPLAN/IDLE: no contact and either speed < 10 px/s (idle) or heading 45..135 deg off the outline direction (orbiting the block at roughly constant range to reach another edge). The same 45-deg normal-vs-tangential split is used in and out of contact.phi_g, 0 deg = +x bar end, 90 = stem tip, -90 = bar top).|angle error (rad)| x 60 px > position error, i.e. the angle error moves the bar ends farther than the CoG is off; position-dominant otherwise.l = (q - CoG) x (-n_out) at the contact point q: the perpendicular offset of an inward-normal push from the CoG, px; sign = sign of the torque it produces. |l| <= 15 px (one pusher radius) counts as a push through the CoG. A velocity-based variant uses the agent's velocity direction instead of the normal.bearing_block: angle of the agent about the CoG in the block frame (same convention as phi_g). bearing_goal: signed angle between the goal->block axis and the CoG->agent vector; 0 = the agent is directly behind the block as seen from the goal (the pushing position), +-180 = between block and goal.206 of 206 episodes contain at least one contact frame; all analysis below uses the first 50 qualifying episodes by episode_index (0..49); the remaining 156 qualifying episodes are used only as an external hold-out for the contact-selection rule (section 6). No stratification by success is possible because next.success is never true.
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| episode length (frames) | 50 | 125 | 126 | 83 | 159 |
| final coverage | 50 | 0.849 | 0.854 | 0.821 | 0.874 |
| max coverage seen in episode | 50 | 0.850 | 0.855 | 0.821 | 0.875 |
| initial position error (px) | 50 | 118.6 | 122.4 | 49.5 | 175.4 |
| initial | angle error | (deg) | 50 | 89.2 | 88.6 |
| contact bouts per episode | 50 | 3.1 | 3.0 | 2.0 | 5.0 |
| contact frames per episode | 50 | 62.4 | 60.0 | 40.0 | 90.3 |

Per episode:
| episode | frames | success | final coverage | bouts | role sequence (run-length compressed) |
|---|---|---|---|---|---|
| 0 | 161 | no | 0.830 | 3 | R-I-A-T-P-S-P-S-I-R-I-A-T-P-H-P-H-P-H-S-I-A-T-P |
| 1 | 118 | no | 0.855 | 2 | I-A-T-P-S-P-S-P-S-P-H-S-I-R-I-A-T-H |
| 2 | 141 | no | 0.860 | 2 | R-I-A-T-P-S-P-S-P-S-P-S-P-S-H-S-I-A-T-P-S-R-I-A-I |
| 3 | 159 | no | 0.874 | 3 | R-I-A-T-P-S-I-R-I-A-T-P-S-R-I-A-T-P-S-P-S-P |
| 4 | 159 | no | 0.864 | 4 | I-R-I-A-T-P-H-P-H-R-I-A-T-P-R-I-A-I-A-T-P-H-S-I-A-T-P |
| 5 | 157 | no | 0.853 | 2 | I-A-T-P-S-P-R-I-A-I-A-T-S-P-H-R-I-A-I |
| 6 | 69 | no | 0.845 | 2 | I-A-T-P-S-R-I-A-T |
| 7 | 169 | no | 0.854 | 6 | R-I-A-T-P-S-I-A-T-I-A-T-P-S-H-S-I-A-T-P-S-R-I-A-T-P-S-R-I-A-T-P |
| 8 | 80 | no | 0.831 | 3 | I-A-I-A-T-P-H-R-I-A-T-P-S-P-S-I-R-I-A-T |
| 9 | 134 | no | 0.866 | 3 | I-A-I-A-I-A-T-P-S-P-S-I-A-T-P-H-S-R-I-A-I-A-T-P |
| 10 | 188 | no | 0.873 | 4 | I-A-I-A-T-P-S-P-H-S-I-A-T-P-H-S-P-S-I-R-I-A-T-P-H-R-I-A-T-P |
| 11 | 149 | no | 0.863 | 2 | A-I-R-I-A-I-A-I-A-T-P-S-P-S-P-S-P-S-P-S-P-S-P-H-S-I-A-T-P |
| 12 | 140 | no | 0.855 | 5 | I-R-I-A-T-P-S-I-A-T-P-S-I-A-T-P-S-R-I-A-T-S-P-H-R-I-A-T-H |
| 13 | 125 | no | 0.864 | 3 | I-R-I-A-T-P-R-I-A-T-P-S-P-S-R-I-A-T-P |
| 14 | 107 | no | 0.834 | 3 | A-I-R-I-A-I-A-T-P-S-P-H-S-I-A-T-P-S-I-A-T |
| 15 | 153 | no | 0.797 | 6 | A-I-A-T-P-S-I-A-T-P-S-R-I-A-T-P-R-I-A-T-P-S-R-I-A-T-P-H-P-S-I-R-I-A-I-A-T |
| 16 | 126 | no | 0.841 | 3 | I-A-T-P-S-I-R-I-A-T-P-H-R-I-A-T-P-S-P-S-P |
| 17 | 102 | no | 0.827 | 2 | I-A-T-S-P-S-P-S-P-R-I-A-T-P-S-P-S-H-P |
| 18 | 86 | no | 0.860 | 2 | I-A-I-A-T-P-S-P-S-I-A-T-P-H-P-S-P |
| 19 | 75 | no | 0.836 | 1 | A-I-A-T-P-S-P-S-P |
| 20 | 142 | no | 0.867 | 3 | I-R-I-A-T-P-S-P-S-P-H-P-S-I-R-I-A-I-A-T-P-R-I-A-T |
| 21 | 115 | no | 0.875 | 2 | I-A-T-P-H-P-R-I-A-T-P |
| 22 | 109 | no | 0.875 | 4 | R-I-A-T-P-S-I-A-T-P-S-I-A-T-P-S-R-I-A-T-P |
| 23 | 110 | no | 0.843 | 3 | I-A-T-P-S-R-I-A-T-P-H-S-R-I-A-T-P |
| 24 | 98 | no | 0.835 | 3 | I-A-I-A-T-P-S-R-I-A-T-P-H-P-S-I-A-T-P |
| 25 | 133 | no | 0.870 | 2 | A-R-I-A-T-P-S-P-S-P-S-I-A-T-P |
| 26 | 158 | no | 0.845 | 5 | I-A-I-A-T-P-S-P-S-R-I-A-T-S-P-S-A-T-P-S-R-I-A-T-P-H-R-I-A-T |
| 27 | 112 | no | 0.820 | 3 | I-A-I-A-I-A-T-P-H-P-S-I-A-I-A-T-P-H-P-S-I-R-I-A-T-P |
| 28 | 107 | no | 0.847 | 2 | I-A-T-P-H-P-R-I-A-T-P |
| 29 | 115 | no | 0.821 | 2 | I-A-I-A-T-S-P-S-P-S-P-S-R-I-A-T-P |
| 30 | 84 | no | 0.842 | 2 | I-A-T-P-S-P-R-I-A-T-P |
| 31 | 95 | no | 0.892 | 3 | I-R-I-A-T-P-S-I-A-T-S-P-S-P-S-P-S-P-H-S-I-A-T-P |
| 32 | 148 | no | 0.901 | 4 | A-I-A-I-A-T-P-S-P-S-R-I-A-T-P-H-S-I-A-T-P-S-I-A-T-H |
| 33 | 120 | no | 0.866 | 3 | A-R-A-I-A-T-P-H-R-I-A-T-P-S-I-A-T-P |
| 34 | 142 | no | 0.855 | 4 | I-A-I-A-T-P-S-P-S-P-S-R-I-A-T-P-S-I-R-I-A-I-A-T-P-S-R-I-A-T |
| 35 | 143 | no | 0.852 | 2 | R-I-A-I-A-T-S-P-S-P-S-P-S-R-I-A-T-P |
| 36 | 142 | no | 0.861 | 3 | A-I-A-T-P-S-P-H-S-I-R-I-A-I-A-I-A-T-P-R-I-A-T-P-H |
| 37 | 121 | no | 0.831 | 3 | I-A-I-A-T-P-S-P-S-I-A-T-P-S-R-I-A-T-P |
| 38 | 186 | no | 0.859 | 7 | I-R-I-A-I-A-I-A-T-P-S-I-A-T-P-S-I-A-T-P-S-P-S-R-I-A-T-P-H-P-H-R-I-A-T-P-S-I-A-T-P-R-I-A-T-P |
| 39 | 99 | no | 0.838 | 2 | R-I-A-I-A-T-P-S-P-S-P-S-P-S-P-S-P-S-R-I-A-T-P |
| 40 | 139 | no | 0.870 | 3 | I-A-I-A-T-P-S-P-S-P-S-P-S-P-S-R-I-A-T-P-S-P-H-R-I-A-T-S-P |
| 41 | 73 | no | 0.835 | 2 | R-A-T-P-H-P-H-P-R-I-A-T-P |
| 42 | 136 | no | 0.782 | 4 | I-A-I-A-T-P-H-R-I-A-T-P-S-P-S-R-I-A-T-P-S-I-A-T |
| 43 | 118 | no | 0.888 | 6 | T-P-S-I-R-I-A-T-S-I-A-T-P-R-I-A-T-I-A-T-P-S-P-S-P-S-P-S-P-S-I-A-I-A-T-P |
| 44 | 127 | no | 0.866 | 3 | I-A-T-P-S-R-I-A-I-A-T-P-S-H-S-P-H-S-I-A-T-P |
| 45 | 152 | no | 0.790 | 4 | I-A-T-P-S-I-R-I-A-T-P-H-S-I-A-I-A-T-P-H-P-R-I-A-T-H |
| 46 | 83 | no | 0.862 | 2 | I-R-I-A-T-P-S-P-S-P-S-P-S-P-S-P-S-P-S-I-A-T-P |
| 47 | 109 | no | 0.855 | 2 | I-A-I-A-I-A-T-P-S-P-R-I-A-T-P-S-P-S-P |
| 48 | 138 | no | 0.838 | 3 | I-R-I-A-I-A-T-S-P-S-I-A-T-S-P-S-P-R-S-I-A-T-P |
| 49 | 83 | no | 0.796 | 2 | I-A-I-A-T-P-S-R-I-A-T-P |
Per-frame labels are in figures/human_pushing/frame_labels.csv. Frame shares and run lengths (a run = maximal sequence of one role):
| role | frames | share | runs | mean run (frames) | median | p10 | p90 |
|---|---|---|---|---|---|---|---|
| APPROACH | 829 | 13.3% | 202 | 4.1 | 4 | 1 | 8 |
| TOUCH | 154 | 2.5% | 154 | 1.0 | 1 | 1 | 1 |
| PUSH | 2404 | 38.6% | 232 | 10.4 | 7 | 2 | 25 |
| SLIDE | 416 | 6.7% | 169 | 2.5 | 2 | 1 | 5 |
| RETREAT | 170 | 2.7% | 88 | 1.9 | 2 | 1 | 3 |
| REPLAN/IDLE | 2156 | 34.6% | 216 | 10.0 | 8 | 2 | 19 |
| HOLD | 106 | 1.7% | 49 | 2.2 | 1 | 1 | 4 |
Transitions between consecutive runs (row = from, column = to, row-normalised %):
| from \ to | APPROACH | TOUCH | PUSH | SLIDE | RETREAT | REPLAN/IDLE | HOLD |
|---|---|---|---|---|---|---|---|
| APPROACH (n=202) | 0 | 76 | 0 | 0 | 1 | 23 | 0 |
| TOUCH (n=146) | 0 | 0 | 88 | 8 | 0 | 1 | 3 |
| PUSH (n=197) | 0 | 0 | 0 | 71 | 8 | 0 | 21 |
| SLIDE (n=169) | 1 | 0 | 51 | 0 | 17 | 29 | 2 |
| RETREAT (n=88) | 2 | 0 | 0 | 1 | 0 | 97 | 0 |
| REPLAN/IDLE (n=214) | 89 | 0 | 0 | 0 | 11 | 0 | 0 |
| HOLD (n=44) | 0 | 0 | 36 | 39 | 25 | 0 | 0 |
Most frequent run trigrams (A=APPROACH, T=TOUCH, P=PUSH, S=SLIDE, R=RETREAT, I=REPLAN/IDLE, H=HOLD):
| trigram | count |
|---|---|
| I-A-T | 151 |
| A-T-P | 128 |
| R-I-A | 85 |
| P-S-P | 75 |
| T-P-S | 69 |
| S-P-S | 65 |
| A-I-A | 43 |
| I-A-I | 40 |
| S-I-A | 36 |
| P-S-I | 34 |
| S-R-I | 28 |
| P-S-R | 26 |
Within a bout, the first frame after TOUCH is PUSH in 90% of bouts longer than one frame, SLIDE in 8%. A bout contains PUSH in 90% of cases and SLIDE in 60%. 48 of the 154 bouts run to the end of the episode; for the 106 bouts that end in a release, the release step is SLIDE 61%, RETREAT 37%, TOUCH 2% (heading of the release step median 124 deg off the inward normal), and the first frame after release is REPLAN/IDLE 58%, RETREAT 41%, APPROACH 1%. The block is already at rest when contact is broken: block speed on the release step median 0.4 px/s, p90 2.2, below 5 px/s in 97% of releases; one frame later it is 0.0 px/s (median), so the block does not coast after release.


distance agent-outline minus radius (px)
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| APPROACH | 829 | 38.1 | 20.0 | 3.7 | 110.7 |
| TOUCH | 154 | -0.2 | -0.1 | -0.5 | 0.6 |
| PUSH | 2404 | -0.2 | -0.1 | -0.3 | -0.0 |
| SLIDE | 416 | -0.1 | -0.1 | -0.2 | 0.0 |
| RETREAT | 170 | 31.2 | 10.4 | -0.0 | 87.1 |
| REPLAN/IDLE | 2156 | 46.8 | 36.8 | 10.5 | 92.8 |
| HOLD | 106 | -0.0 | -0.0 | -0.1 | -0.0 |

heading relative to the block (deg; 0 = straight into the nearest outline point / inward normal, 90 = along it, 180 = straight away)
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| APPROACH | 829 | 26.2 | 24.5 | 4.1 | 44.7 |
| TOUCH | 144 | 20.8 | 15.6 | 3.3 | 51.3 |
| PUSH | 2369 | 18.3 | 16.1 | 2.9 | 36.7 |
| SLIDE | 416 | 70.7 | 63.6 | 47.3 | 103.2 |
| RETREAT | 170 | 150.7 | 147.7 | 137.1 | 168.7 |
| REPLAN/IDLE | 2135 | 84.7 | 82.9 | 55.8 | 116.7 |
| HOLD | 0 | - | - | - | - |

bearing of agent about the CoG, block frame (deg; 0=+x bar end, 90=stem tip, -90=bar top)
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| APPROACH | 829 | 9.6 | 29.5 | -155.3 | 146.7 |
| TOUCH | 154 | 3.8 | 17.0 | -153.9 | 113.9 |
| PUSH | 2404 | -21.8 | -16.3 | -179.4 | 115.1 |
| SLIDE | 416 | -25.8 | -17.0 | -179.7 | 114.4 |
| RETREAT | 170 | 19.9 | 43.3 | -140.3 | 150.5 |
| REPLAN/IDLE | 2156 | -1.3 | -2.7 | -151.8 | 150.8 |
| HOLD | 106 | -20.6 | -0.1 | -180.0 | 119.2 |

bearing of agent off the goal->block axis (deg; 0=behind block, opposite the goal)
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| APPROACH | 829 | 10.0 | 3.6 | -59.9 | 114.2 |
| TOUCH | 154 | 0.2 | -0.1 | -55.6 | 47.1 |
| PUSH | 2404 | 7.3 | 4.2 | -72.0 | 89.3 |
| SLIDE | 416 | 5.3 | 8.0 | -84.8 | 94.0 |
| RETREAT | 170 | 30.9 | 52.6 | -117.6 | 158.5 |
| REPLAN/IDLE | 2156 | 7.9 | 10.8 | -114.6 | 122.9 |
| HOLD | 106 | 44.1 | 68.7 | -91.8 | 155.4 |

agent speed (px/s)
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| APPROACH | 829 | 83.7 | 69.3 | 32.1 | 151.0 |
| TOUCH | 146 | 59.5 | 57.3 | 25.6 | 90.4 |
| PUSH | 2369 | 52.9 | 47.9 | 19.9 | 89.4 |
| SLIDE | 416 | 58.2 | 49.6 | 18.4 | 106.0 |
| RETREAT | 170 | 126.8 | 105.7 | 32.2 | 250.4 |
| REPLAN/IDLE | 2154 | 128.7 | 121.6 | 54.6 | 208.5 |
| HOLD | 101 | 6.4 | 6.5 | 2.9 | 9.1 |

agent |acceleration| (px/s^2)
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| APPROACH | 819 | 194 | 147 | 50 | 362 |
| TOUCH | 142 | 120 | 104 | 40 | 207 |
| PUSH | 2334 | 121 | 88 | 29 | 230 |
| SLIDE | 416 | 280 | 145 | 43 | 730 |
| RETREAT | 170 | 706 | 567 | 224 | 1244 |
| REPLAN/IDLE | 2154 | 360 | 305 | 105 | 682 |
| HOLD | 100 | 216 | 47 | 15 | 764 |

agent |jerk| (px/s^3)
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| APPROACH | 806 | 1592 | 1097 | 331 | 3105 |
| TOUCH | 141 | 1055 | 828 | 268 | 1896 |
| PUSH | 2302 | 1311 | 798 | 252 | 2625 |
| SLIDE | 415 | 2801 | 1316 | 313 | 7583 |
| RETREAT | 170 | 6032 | 4054 | 1727 | 12127 |
| REPLAN/IDLE | 2153 | 2444 | 1778 | 533 | 5131 |
| HOLD | 98 | 2481 | 708 | 144 | 6606 |

Block motion per role (block CoG speed px/s, |rotation rate| deg/s):
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| APPROACH block speed | 829 | 2.0 | 0.0 | 0.0 | 4.8 |
| TOUCH block speed | 146 | 37.6 | 34.4 | 12.9 | 67.1 |
| PUSH block speed | 2369 | 35.8 | 32.4 | 13.7 | 60.6 |
| SLIDE block speed | 416 | 17.2 | 12.0 | 0.1 | 43.9 |
| RETREAT block speed | 170 | 0.2 | 0.0 | 0.0 | 0.6 |
| REPLAN/IDLE block speed | 2154 | 0.0 | 0.0 | 0.0 | 0.0 |
| HOLD block speed | 101 | 4.2 | 4.0 | 1.2 | 7.6 |
| APPROACH | omega | 829 | 1.0 | 0.0 | |
| TOUCH | omega | 146 | 17.7 | 11.9 | |
| PUSH | omega | 2369 | 18.1 | 15.4 | |
| SLIDE | omega | 416 | 7.6 | 4.5 | |
| RETREAT | omega | 170 | 0.1 | 0.0 | |
| REPLAN/IDLE | omega | 2154 | 0.0 | 0.0 | |
| HOLD | omega | 101 | 1.8 | 1.7 |
154 touches in the 50 episodes, 149 deliberate (first bout or >= 5 non-contact frames before) and 5 re-contacts. Statistics below are over deliberate touches; the approach velocity at touch is the last free-flight step before the contact step, (p[t-1]-p[t-2])/DT (the contact step itself is shortened along the normal by contact resolution and would bias the incidence towards glancing), and the incidence angle is measured between it and the inward normal at the contact point (0 = head-on, 90 = glancing).
| edge | touches | share |
|---|---|---|
| bar_top | 39 | 26.2% |
| bar_end_R | 7 | 4.7% |
| bar_bottom_R | 4 | 2.7% |
| stem_R | 25 | 16.8% |
| stem_tip | 33 | 22.1% |
| stem_L | 20 | 13.4% |
| bar_bottom_L | 9 | 6.0% |
| bar_end_L | 12 | 8.1% |
| stem_side (L+R) | 45 | 30.2% |
| bar_top (L+R) | 39 | 26.2% |
| stem_tip (L+R) | 33 | 22.1% |
| bar_end (L+R) | 19 | 12.8% |
| bar_bottom (L+R) | 13 | 8.7% |
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| incidence angle (deg) | 149 | 23.6 | 17.1 | 2.0 | 51.3 |
| approach speed at touch (px/s) | 149 | 68.0 | 67.0 | 29.2 | 105.9 |
| APPROACH run length before touch (frames) | 149 | 4 | 4 | 1 | 8 |
| standoff before re-approach: max gap between bouts (px) | 99 | 42.0 | 38.8 | 16.7 | 70.1 |
| bearing change around block, last contact -> next touch (deg) | 99 | -25.5 | -28.4 | -130.6 | 104.3 |
| bearing change | (deg) | 99 | 81.8 | 88.6 | |
| non-contact frames before touch (bouts after the first) | 99 | 17 | 16 | 9 | 25 |
| agent bearing off goal->block axis | at touch (deg, all bouts) | 154 | 31.9 | 24.4 | |
| agent bearing off goal->block axis | at release (deg, released bouts) | 106 | 85.4 | 85.5 |
Head-on share (incidence <= 30 deg): 72%; glancing share (incidence >= 60 deg): 7%. The edge touched is the one nearest the agent at the previous release (or at the episode start) in 9% of deliberate touches (11% by edge type): the pusher usually travels to a different edge rather than touching the nearest one. Perimeter distance travelled around the outline from the previous release point to the next touch point: median 98 px, p10 25, p90 182 (perimeter 480 px). Gap at the start of the final APPROACH run: median 23 px, p10 3, p90 54.


Over PUSH frames with a defined rotation rate (n = 2369): Pearson correlation between the inward-normal lever arm and the block rotation rate r = 0.869 (velocity-direction lever arm: r = 0.854); least-squares slope 0.562 deg/s per px of lever arm; the sign of the lever arm matches the sign of the rotation in 100% of PUSH frames where the block rotates faster than 2 deg/s.
| PUSH frames by dominant error | n | median |lever| (px) | through CoG (|l| <= 15 px) | corrective torque sign | median block speed (px/s) | median |omega| (deg/s) | |---|---|---|---|---|---|---| | position-dominant | 1883 | 25.2 | 40.4 | 78.5 | 31.4 | 11.5 | | angle-dominant | 486 | 42.5 | 11.5 | 99.4 | 35.5 | 26.1 | | all PUSH | 2369 | 30.1 | 34.4 | 82.8 | 32.4 | 15.4 |
| |angle error| bin (deg) | PUSH frames | median |lever| (px) | lever sign corrective | rotation sign corrective | median |omega| (deg/s) | |---|---|---|---|---|---| | 0-5 | 652 | 5.7 | 56.7 | 57.5 | 3.9 | | 5-10 | 286 | 11.8 | 79.4 | 80.4 | 6.4 | | 10-20 | 275 | 33.9 | 92.0 | 93.8 | 15.2 | | 20-30 | 191 | 37.8 | 92.7 | 92.7 | 19.4 | | 30-45 | 197 | 42.5 | 99.0 | 99.5 | 29.0 | | 45-60 | 197 | 42.7 | 92.9 | 93.4 | 25.4 | | 60-90 | 266 | 43.3 | 96.2 | 96.2 | 28.6 | | 90-180 | 305 | 36.5 | 98.7 | 98.4 | 27.5 |
Per bout (all bouts, n = 154):
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| block CoG displacement per bout (px) | 154 | 57.4 | 44.0 | 4.4 | 125.1 |
| displacement toward goal per bout (px) | 154 | 49.0 | 35.0 | 0.0 | 115.5 |
| efficiency = toward-goal / total displacement | 154 | 0.72 | 0.95 | 0.00 | 1.00 |
| block rotation per bout (deg) | 154 | -0.0 | 0.0 | -62.8 | 60.1 |
| rotation | per bout (deg) | 154 | 30.3 | 9.4 | |
| position error reduced per bout (px) | 154 | 35.7 | 19.9 | -1.0 | 102.1 |
| angle error | reduced per bout (deg) | 154 | 27.7 | 5.5 | |
| bout length (frames) | 154 | 20 | 17 | 3 | 40 |
| block speed on the release step (px/s, released bouts) | 106 | 1.0 | 0.4 | 0.0 | 2.2 |
| agent speed on the release step (px/s) | 106 | 90.7 | 75.9 | 30.0 | 183.3 |
What a bout achieves and when it is released (106 released bouts; the 48 bouts that run to the end of the episode are listed separately). Push alignment is the angle between the inward normal at the contact point (the push direction) and the CoG->goal direction.
| n | mean | median | p10 | p90 | |
|---|---|---|---|---|---|
| push alignment at touch (deg, all bouts) | 154 | 39.1 | 26.5 | 2.5 | 87.2 |
| push alignment at release (deg) | 106 | 92.1 | 88.8 | 47.6 | 152.0 |
| push alignment at episode end (deg, final bouts) | 48 | 22.2 | 13.9 | 2.8 | 53.2 |
| position error at touch (px) | 106 | 92.1 | 95.6 | 21.7 | 159.9 |
| position error at release (px) | 106 | 56.4 | 48.3 | 9.4 | 115.9 |
| angle error | at touch (deg) | 106 | 57.9 | 53.3 | |
| angle error | at release (deg) | 106 | 18.7 | 5.3 | |
| position error at episode end (px, final bouts) | 48 | 6.4 | 6.2 | 4.8 | 8.2 |
| angle error | at episode end (deg, final bouts) | 48 | 2.2 | 1.8 |
Release happens with the push alignment above 45 deg in 91% of released bouts (above 60 deg in 83%), versus 34% of touches made with alignment above 45 deg. By release the bout has reduced the position error by more than 5 px in 71% of cases and the |angle error| by more than 5 deg in 70% (both 50%, neither 9%); the angle error changes sign during 24% of released bouts (overshoot).


Edge type chosen at deliberate touches, split by dominant error:
| dominant error | touches | bar_top | bar_end | bar_bottom | stem_side | stem_tip |
|---|---|---|---|---|---|---|
| position-dominant | 120 | 28% | 13% | 7% | 28% | 24% |
| angle-dominant | 29 | 21% | 10% | 17% | 38% | 14% |
Decision table fitted on all 149 deliberate touches of the 50 episodes. Events are mirrored across the stem axis so the goal is on the +x side (angle error and edge L/R flip with it); rows = direction to goal in the block frame, columns = angle error; cell = majority edge and its share:
| goal direction phi_g (deg) \ angle error (deg) | < -15 | |ang| <= 15 | > 15 | |---|---|---|---| | -90..-45 (bar-top side) | stem_L 4/7 | stem_tip 25/31 | stem_R 6/15 | | -45..0 | stem_L 5/7 | stem_L 9/15 | bar_bottom_L 4/12 | | 0..45 | bar_top 6/9 | stem_L 4/9 | stem_tip 1/2 | | 45..90 (stem-tip side) | bar_top 5/8 | bar_top 20/25 | bar_top 5/9 |
Contact-point model: every candidate point q on the perimeter (every 5 px) gets a score w1 * (-n_out . g) + w2 * (l/60) * angle_err + w3 * (-|l|/60) where g is the unit direction to the goal in the block frame, l the lever arm of an inward push at q and angle_err in radians; the chosen point is a softmax draw (conditional logit) and the prediction is the argmax. goal-normal is the unfitted rule w = (1, 0, ~0): push where the inward normal points at the goal, as close to the CoG line as possible.
Fitted weights on all deliberate touches: w = (1.79, 2.97, 1.92).
| rule | edge accuracy % (5-fold CV by episode, 50 eps) | edge accuracy % (external hold-out, 156 eps, 540 touches) | edge-type accuracy % (CV) | median perimeter error px (CV) |
|---|---|---|---|---|
| majority edge | 26.8 | 23.3 | - | - |
| goal-normal (unfitted) | 57.1 | 48.7 | 58.3 | 32.5 |
| decision table (fitted) | 54.5 | 56.3 | - | - |
| contact-point logit (fitted) | 56.4 | 50.7 | 56.4 | 24.5 |
External hold-out for the logit: edge-type accuracy 51.1%, median perimeter error 45.0 px, p90 170.5 px. Chance level for 8 edges is 12.5%.

Each statement is read off the tables above (medians unless stated; p10-p90 in brackets). Speeds are agent-centre speeds at 10 Hz.
Figures: figures/human_pushing/. Per-touch table: figures/human_pushing/touch_events.csv.
The environment is a deterministic function of the action stream, so the split can be measured. Re-simulating the PD law (k_p=100, k_v=20, dt=0.01, 10 substeps) in free space from each recorded start, driven only by the recorded actions, reproduces the recorded agent path to 0.00 px (median and p90) on 3065 no-contact frames and on 3120 in-contact frames: the pusher is kinematic, the block never acts on it, and the whole agent trajectory is PD(mouse). The mouse stream is the only human quantity; everything else is a filter or a rigid-body response.
Physics, fixed by the reference (would change on any other engine):
Human, portable across engines (the decisions):
| decision | evidence |
|---|---|
| speed by phase: slow in contact, fast when free | mouse speed medians 45 (push) / 41 (touch) / 51 (slide) vs 114 (orbit) / 184 (retreat) px/s; agent follows the mouse exactly (cos = 1.00 in every role) |
| orbit rather than retreat | 72% of free motion tangential, retreat 2.7% of frames, standoff 37 px |
| head-on incidence | 17 deg to the inward normal, 72% within 30 deg |
| edge selection by goal geometry | goal-normal rule 57% CV / 49% hold-out vs 9% nearest-edge |
| lever offset chosen by angle error | 5.7 px at < 5 deg, 42.5 px at 30-45 deg, corrective sign 99% |
| release on geometry, not distance | push alignment 26 deg at touch, 89 deg at release |
| bout pacing | 3 bouts of ~17 frames, 16 frames between |
Consequences for the controller. Section 7's speeds are agent speeds; on a kinematic pusher the controller should emit target-stream speeds (the mouse numbers above) or it double-filters, and on a dynamic pusher the mapping differs again. The rotation gain is reference-only: close the loop on measured angle error instead of feeding forward 0.56 deg/s per px. The edge, lever, orbit, incidence and release rules are the transferable content of this analysis.