Independent 2D top-down re-implementation of the same social-force proxemics controller as the 3D version (the underlying model already lives in a flat plane, so this recomputes it directly rather than re-skinning a 3D scene). The robot is a differential-drive vehicle steered by the sum of an attractive pull toward the desk it is visiting and a repulsive push away from every other seated student's personal-space bubble (Hall's proxemics zones, 1966):
F = k_a·(goal − p)/|goal − p| + Σ k_r·max(0, (R − d_i)/R)·(p − s_i)/d_i
d_i = distance to student i, R = 1.8 × personal-space radius
heading error e = atan2(F) − θ, ω = clamp(k_p·e, ±2.5 rad/s)
v = v_max · max(0, cos e) · min(1, dist_to_goal / 0.4 m)
- Personal-space radius — boundary of each bystander's zone (intimate <0.45 m, personal 0.45–1.2 m). Only the desk being visited right now is exempt.
- kr — repulsion gain; raise it and the path swings wider around occupied desks.
- Max approach speed — caps linear velocity; the robot always slows as it turns (v ∝ cos of heading error) and as it nears the goal.
- ka — attraction gain toward the current desk; low values let repulsion dominate and can stall the robot near a crowded row.
- Steering gain kp — how aggressively the heading tracks the force direction; too high and the path oscillates, too low and turns lag behind.
Drag any desk to relocate a student live and watch the force field bend around the new layout; drag empty floor to pan, scroll to zoom — same as orbiting the 3D scene. The strip chart below tracks nearest-bystander and goal distance over time so you can see the controller react.