TT Lab
Blog

한국어 English 日本語 中文

Get started
Blog

Blog

Measuring Table Tennis Physics in MuJoCo: Restitution, Drag, and Spin Depend on a Single Simulator Setting Line

Status: Draft (2026-10-18), Measured. Ball physics stage 1 (A–E) completed. The classical control baseline run on this model is described in Part 5and reinforcement learning will be covered in a later part. Measurements were taken on 2026-10-18 in a temporary pod on a home lab Kubernetes cluster. The node is a mini PC (Intel Core Ultra 9 185H), and the pod limits are 3 CPU cores, 3 GiB of memory, no GPU, and offscreen rendering disabled (MUJOCO_GL=disable). Mujoco 3.16.0, numpy 2.5.4, and scipy 1.18.1 were added via pip to python:3.12 (installation took 11.6 s). The peak pod memory was 725 MB. Since MuJoCo produces identical results for identical inputs, the values in the table are from a single run, and dispersion was measured separately for the contact phase (A4, 50 variations) and ball samples (D, 500 units). Raw data is located in the working directory tt-robot/out/(tables and figures) and tt-robot/logs/(execution logs).

Table of Contents

1. Intuition: A 2.7 g Ball is Sensitive to Settings

A table tennis ball is 40 mm in diameter and weighs 2.7 g. The aerodynamic force on a ball flying at 7 m/s is comparable to its weight, and with high spin, it exceeds the weight. The contact time on the table is around 1 ms. Therefore, a few settings like the simulator's time step, contact stiffness, and fluid coefficients significantly alter the ball's trajectory.

To teach a robot table tennis, we must first know whether "the ball inside the simulator flies like a real ball." This post does what can be done while real ball trajectories are not yet available: namely, plugging in the public settings as-is, placing them side-by-side with literature values, and measuring which settings disturb the results the most.

2. Model: Values from DeepMind's Public MJCF As-Is

Alongside their ICRA 2025 table tennis paper, DeepMind released 15,792 initial ball states (13,088 rallies, 2,704 serves) and a MuJoCo notebook. We transferred the notebook's values as-is.

Item Value
Time step, integrator 1 ms, implicitfast
Ball Mass 2.7 g, radius 0.02 m, thin-shell sphere
Fluid coefficients (fluidcoef) 0.235 0.25 0.0 1.0 1.0
Ball-table contact solref -1000000 -17(stiffness 1e6, damping 17), friction 0.1
Coordinates Origin at the center of the table top, x width 1.525 m, y length 2.74 m, z up. Robot side is y < 0

Fluid forces are provided separately by MuJoCo in qfrc_fluid . Disabling gravity and applying only velocity and spin allows reading this value to directly measure drag and Magnus forces.

s = Sim(base.with_(gravity=False))
for v in [2, 5, 10, 15, 20, 25, 30]:
    s.reset([0, 0, 1], [0, v, 0], [0, 0, 0])
    fd = -s.d.qfrc_fluid[1]                    # 진행 방향 반대 힘 = 항력
    cd = fd / (Q * v * v)                      # Q = ½ρA
    for S in [0.0, 0.1, 0.2, 0.4, 0.6, 1.0]:   # 회전비 S = rω / v
        w = S * v / BALL_R
        s.reset([0, 0, 1], [0, v, 0], [-w, 0, 0])   # 탑스핀
        fm = -s.d.qfrc_fluid[2]                # 아래로 누르는 힘 = 마그누스
        km = fm / (w * v) if w > 0 else float("nan")

(Excerpted from TT Lab experiment code exp_b_magnus.py . Sim is a small wrapper that builds the MJCF and invokes mj_forward .)

3. 30 cm Drop: The Ball Bounces Too Well

ITTF regulations specify that a ball dropped from 30 cm should bounce to about 23 cm. Ignoring air resistance, the coefficient of restitution is e ≈ √(23/30) = 0.876.

30 cm 에서 떨어뜨린 공, 같은 탁자 값 시뮬레이션 시간 간격(dt)만 1 ms 와 2 ms 로 다릅니다. 5배 느리게. ▶ 누르면 재생 탁자면 놓은 높이 30 cm ITTF 규정 약 23 cm dt 1 ms, e 0.978 꼭대기 26.4 cm dt 2 ms, e 3.004 ↑ 꼭대기 1.96 m (화면 밖) 높이는 A1 실측(반발 속도·꼭대기)과 같은 공기저항으로 다시 그린 움직임입니다. dt 2 ms 는 접촉 강성에 비해 간격이 커서 에너지가 생겨 3배로 튕깁니다.
Figure: Ball restitution dropped from 30 cm, time steps 1 ms and 2 ms
Model Impact velocity Rebound velocity e Peak height Compared to regulation 23 cm
MuJoCo, dt 0.25 ms −2.375 m/s 2.299 m/s 0.968 26.0 cm +3.0 cm
MuJoCo, dt 0.5 ms −2.373 m/s 2.308 m/s 0.973 26.2 cm +3.2 cm
MuJoCo, dt 1 ms −2.368 m/s 2.317 m/s 0.978 26.4 cm +3.4 cm
MuJoCo, dt 2 ms −2.368 m/s 7.114 m/s 3.004 196.4 cm Diverged
TT3D e 0.85 (calculated with same impact velocity and resistance) 0.850 20.2 cm −2.8 cm
Sony AI 2026 e formula (calculated using the same method) 0.932 24.2 cm +1.2 cm

(The motion in the figure uses the rebound velocity from the table, redrawn with the same air resistance C_D 0.471 as measured. The redrawn peaks are 26.4 cm and 195.9 cm, matching the table.)

Changing the collision velocity to 1–8 m/s makes the difference clearer. MuJoCo's e is nearly flat at 0.96–0.99, whereas Sony AI 2026's formula (e = 0.98 − 0.02·impact velocity) decreases e as velocity increases.

충돌 속도별 탁자 반발 계수 e 0.80 0.85 0.90 0.95 1.00 0 2 4 6 8 입사 속도 |v_z| (m/s) MuJoCo dt 1 ms MuJoCo dt 0.5 ms Sony 2026 식 ITTF 30 cm→23 cm 는 e ≈ 0.876 입니다. ITTF 0.876
Figure: Table restitution coefficient by collision velocity, MuJoCo vs. Sony 2026 formula

4. Air: The Magnus Force is 4.2x Stronger than Literature

Source C_D Magnus coefficient k_M (N·s²/rad/m) Compared to MuJoCo
MuJoCo, DeepMind value (measured) 0.471 2.053e-5 1.00
TT3D 2025 0.494 4.860e-6 0.237
Tebbe et al. 2020 (C_D 0.4, C_M 0.6, force form estimated) 0.400 9.236e-6 0.450
Sony AI 2026 Low speed 0.55, 0.37–0.51 at 17.5 m/s Function of spin ratio (values not used in this post)

Changing only the spin for the same shot (velocity (0, 7, 1.6) m/s at y = −1.6 m behind the robot-side baseline, height 0.2 m) reveals the difference in landing points.

같은 타구, 회전만 바꿨을 때 첫 착지 위치 로봇 쪽 끝선 뒤에서 7 m/s 로 친 공. 가로축은 탁자 길이 방향 y(m). 네트 상대 코트 친 쪽 -1 0 1 2 3 4 5 탑스핀 300 탑스핀 150 무회전 백스핀 150 백스핀 300 속이 빈 표시는 네트에 걸린 공입니다(문헌 식은 네트 높이 아래로 지나가면 걸림으로 판정). MuJoCo(DeepMind 값) TT3D 식 Tebbe 식(힘의 꼴 추정)
Figure: First landing position by model when only spin is changed for the same shot
Spin MuJoCo landing y TT3D formula landing y Note
Topspin 300 rad/s −0.315 m (striker's court) 0.355 m TT3D passes 1.2 cm below net height, judged as a net hit
No spin 0.812 m 0.789 m Both models agree within 2.3 cm
Backspin 150 rad/s 3.684 m (out), peak 51.3 cm 1.093 m
Backspin 300 rad/s 5.378 m (out), peak 139.6 cm 1.482 m (out)

No-spin balls are nearly identical between the two models, but introducing spin causes MuJoCo to drift significantly. The issue is that the spin values in the public data may have been designed to be used specifically with this MJCF (estimated). If so, the spin values and Magnus coefficient must be used only as a pair, and changing only one to a literature value is not allowed. The sensitivity in Section 6 is the basis for this.

5. Oblique Bounce: The Table is Slippery

Combining horizontal velocities of 3, 6, 9 m/s, vertical velocities of 2, 4 m/s, and spins of −300, 0, +300 rad/s directly above the table, we compared the states immediately before and after the bounce.

6. 500 Public Initial States: What Shakes Things Up the Most

Out of 13,088 rallies, 500 balls heading toward the robot side were randomly sampled (seed 0) and flown using DeepMind's MuJoCo values (dt 1 ms). The public data does not contain trajectories, only initial states. Therefore, what follows is not a comparison against real balls, but rather "the values produced by the simulator from the same initial state" and their sensitivity.

Metric 5% / 50% / 95%
Initial velocity 3.80 / 5.49 / 7.89 m/s
Initial spin 12.21 / 57.55 / 101.60 rad/s
Table landing on the robot side 100.0% (net contact 0.6%)
Until first bound 0.30 / 0.42 / 0.60 s
Velocity immediately after bound 3.82 / 4.50 / 5.61 m/s
Reached strike plane (y = −1.6 m) 0.51 / 0.71 / 1.06 s
Strike plane height 0.01 / 0.31 / 0.47 m

We re-launched the same 500 configurations with changed settings and paired them to observe the positional difference at the strike plane. Since the half-width of the racket face is about 7.5 cm, if the difference exceeds a few cm, the policy misses.

계수를 바꾸면 타격면에서 공이 얼마나 비켜 가나 공개 초기 상태 500개를 짝지어 비교. 막대 진한 부분 중앙값, 옅은 부분 95%. 라켓 반폭 7.5 cm dt 0.5 ms 1 / 3.8 C_D 0.40 2.5 / 12.5 C_D 0.55 2.7 / 13.2 탁자 μ 0.3 0.7 / 6 e ITTF ×1.08 4.7 / 10.1 탁자 e = ITTF 6.9 / 15.2 마그누스 ×0.5 12.4 / 37.6 마그누스 ×0.24 17.7 / 57.3 마그누스 0 23.2 / 78.9 문헌 값 조합 17.4 / 57.3 0 20 40 60 80 타격면(y = −1.6 m) 위치 차이 (cm) 기준: DeepMind 공개 MJCF 값, dt 1 ms. 「e ITTF ×1.08」 만 ITTF e 를 기준으로 비교.
Figure: Median and 95th percentile of strike plane position differences when changing coefficients
Changed parameter Strike plane position difference median / 95% Robot-side landing rate change
dt 0.5 ms / 0.25 ms 1.0 / 3.8 cm, 0.7 / 3.2 cm 0
C_D 0.40 / 0.55 2.5 / 12.5 cm, 2.7 / 13.2 cm −1.4 / 0 %p
Table μ 0.25 / 0.3 0.6 / 5.1 cm, 0.7 / 6.0 cm 0
Table e to standard value 0.876 6.9 / 15.2 cm 0
Standard e ±8% 4.7 / 10.1 cm, 4.6 / 9.8 cm 0
Magnus ×0.5 12.4 / 37.6 cm −11.0 %p
Magnus ×0.24 (TT3D intensity) 17.7 / 57.3 cm −23.0 %p
Magnus 0 23.2 / 78.9 cm −32.2 %p
Literature value combination (C_D 0.49, Magnus ×0.24, standard e, μ 0.3) 17.4 / 57.3 cm −21.2 %p

7. Racket: The Ball Passes Through the Face

We fixed the racket face (15×16 cm, thickness 6 mm·14 mm) and shot balls directly at it. We varied the contact start timing (phase) across 30–50 variations to count bounces versus penetrations.

라켓 접촉 강성과 시간 간격: 뚫리거나 튀거나 판 두께 14 mm, 공 속도 20·30·40 m/s 각 30회(접촉 위상을 흔듦). 칸마다 관통·불안정 횟수/90. 0.1 ms 0.25 ms 0.5 ms 1 ms 2 ms 1e6(DeepMind) 관통 60 관통 60 관통 60 관통 60 59/8 4e6(채택) 안정 안정 안정 11/51 56/26 1.6e+07 안정 안정 튐 60 13/74 43/47 6.4e+07 안정 튐 60 튐 81 11/74 39/51 2.56e+08 튐 41 튐 86 튐 89 13/77 41/49 √k·dt = 1 경계(왼쪽이 √k·dt ≤ 1) 「관통 a」 a 회 판을 뚫음, 「튐 b」 e > 1.05 로 튄 횟수, 「a/b」 둘 다. 굵은 테두리가 채택한 조합. 강성 k 의 단위는 1/s². 위의 dt 는 MuJoCo 의 timestep.
Figure: Racket contact stiffness and time step grid: Number of penetrations and instabilities

Decision. The physics time step is 0.5 ms, and racket contact is solref (−4e6, −34) (with damping ratio matching DeepMind's value). For the 14 mm face at 40 m/s, penetration was 0/30 and instability was 0/30. The restitution coefficient of the racket measured under this setup is 0.931 at 4 m/s and 0.893 at 8 m/s, which is larger than the Sony AI 2026 formula (0.80, 0.72). It is not tailored to the actual rubber's penetration depth and contact time (unverified). The table kept DeepMind's stiffness as is. We assumed the vertical velocity hitting the table does not exceed 8 m/s (estimated), and up to 8 m/s was stable in Section 3.

8. Computation is Cheap

The model with only the ball and table ran at 230k–360k steps per second on a single core. Two identical measurements yielded these differences due to varying node loads (later measurement: 229,806–239,229 steps/s at dt 0.25–1 ms). With dt 0.5 ms, this is 120–180x real-time. Running 512 balls simultaneously across 3 threads yielded 580k–1.22M steps per second. The model including a 2-axis gantry and 2-axis wrist robot ran at 152,611 steps per second on 1 thread at dt 0.5 ms (76x real-time). This stage does not require a GPU. Experiment times were also short: drop bundle (A) took 11.3 s, aerodynamics bundle (B) 3.6 s, bounce (C) 0.5 s, and 500-sample sensitivity (D) 28.7 s.

9. Limitations

10. Moving to the Next Part

The results of running classical control baselines—"seeing, predicting, and swinging"—by placing the robot on top of this ball model are in Part 5. Reinforcement learning is evaluated based on whether it surpasses those baselines. How to build the robot's body will be covered right next in Part 3.

TT's Word. It's the same ball, but changing a single line of simulator settings made a ball that bounced 26 cm soar nearly 2 m. Don't underestimate table tennis balls just because they're light. Please treat coefficients as a pair with the data!

References

All links were verified to be accessible on 2026-10-18.

Sign in to like

Comments

No comments yet.

Sign in to leave a comment