상태: 초안 (2026-10-18), 실측. 공 물리 1단계(A–E) 완료. 이 모델 위에서 돌린 고전 제어 기준선은 5편에, 강화학습은 이후 편에 적습니다. 측정은 2026-10-18 에 홈랩 쿠버네티스의 임시 파드 하나에서 했습니다. 노드는 미니 PC 한 대(Intel Core Ultra 9 185H)이고, 파드 상한은 CPU 3코어·메모리 3 GiB, GPU 없음, 오프스크린 렌더링 끔(
MUJOCO_GL=disable)입니다. 이미지는python:3.12에 pip 로 mujoco 3.16.0, numpy 2.5.4, scipy 1.18.1 을 더했습니다(설치 11.6 s). 파드 메모리 최고치는 725 MB 였습니다. MuJoCo 는 같은 입력에 같은 결과를 내므로 표의 값은 한 번 돌린 값이고, 흩어짐은 접촉 위상(A4, 50가지)과 공 표본(D, 500개)으로 따로 냈습니다. 원자료는 작업 디렉터리tt-robot/out/(표와 그림)과tt-robot/logs/(실행 로그)에 있습니다.
목차
- 1. 직관: 2.7 g 짜리 공은 설정에 민감하다
- 2. 모델: DeepMind 공개 MJCF 의 값 그대로
- 3. 30 cm 낙하: 공이 너무 잘 튄다
- 4. 공기: 마그누스 힘이 문헌보다 4.2배 세다
- 5. 비스듬한 바운드: 탁자가 미끄럽다
- 6. 공개 초기 상태 500개: 무엇이 가장 크게 흔드나
- 7. 라켓: 공이 판을 뚫고 지나간다
- 8. 계산은 싸다
- 9. 한계
- 10. 다음 편으로
- 참고
1. 직관: 2.7 g 짜리 공은 설정에 민감하다
탁구공은 지름 40 mm, 무게 2.7 g 입니다. 7 m/s 로 날아가는 공에 걸리는 공기 힘은 무게와 비슷한 크기이고, 회전이 크면 무게보다 커집니다. 탁자에 닿는 시간은 1 ms 남짓입니다. 그래서 시뮬레이터의 시간 간격, 접촉의 단단함, 유체 계수 같은 설정 몇 개가 공의 길을 크게 바꿉니다.
로봇에게 탁구를 가르치려면 먼저 「시뮬레이터 안의 공이 진짜 공처럼 나는가」를 알아야 합니다. 이 글은 진짜 공의 궤적이 아직 없는 상태에서 할 수 있는 일, 곧 공개된 설정을 그대로 넣고, 문헌의 값과 나란히 놓고, 어느 설정이 결과를 가장 크게 흔드는지 재는 일을 합니다.
2. 모델: DeepMind 공개 MJCF 의 값 그대로
DeepMind 는 ICRA 2025 탁구 논문과 함께 공의 초기 상태 15,792개(랠리 13,088개, 서브 2,704개)와 MuJoCo 노트북을 공개했습니다. 노트북의 값을 그대로 옮겼습니다.
| 항목 | 값 |
|---|---|
| 시간 간격, 적분기 | 1 ms, implicitfast |
| 공 | 질량 2.7 g, 반지름 0.02 m, 얇은 껍질 구 |
| 유체 계수(fluidcoef) | 0.235 0.25 0.0 1.0 1.0 |
| 공과 탁자 접촉 | solref -1000000 -17(강성 1e6, 감쇠 17), friction 0.1 |
| 좌표 | 원점은 탁자 윗면 가운데, x 폭 1.525 m, y 길이 2.74 m, z 위. 로봇 쪽은 y < 0 |
유체 힘은 MuJoCo 가 qfrc_fluid 에 따로 담아 줍니다. 중력을 끄고 속도와 회전만 준 뒤 이 값을 읽으면 항력과 마그누스 힘을 직접 잴 수 있습니다.
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")
(TT Lab 실험 코드 exp_b_magnus.py 에서 발췌. Sim 은 MJCF 를 만들고 mj_forward 까지 부르는 작은 감싸개입니다.)
3. 30 cm 낙하: 공이 너무 잘 튄다
ITTF 규정은 30 cm 에서 떨어뜨린 공이 약 23 cm 튀어야 한다고 정합니다. 공기저항을 무시하면 반발 계수 e ≈ √(23/30) = 0.876 입니다.
| 모델 | 입사 속도 | 반발 속도 | e | 꼭대기 | 규정 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 | 발산 |
| TT3D 의 e 0.85(같은 입사 속도·같은 저항으로 계산) | 0.850 | 20.2 cm | −2.8 cm | ||
| Sony AI 2026 의 e 식(같은 방법으로 계산) | 0.932 | 24.2 cm | +1.2 cm |
(그림의 움직임은 표의 반발 속도로, 실측과 같은 공기저항 C_D 0.471 을 넣어 다시 그렸습니다. 다시 그린 꼭대기는 26.4 cm 와 195.9 cm 로 표와 맞습니다.)
- DeepMind 값의 탁자는 규정보다 탄력적입니다. dt 를 0.25–1 ms 로 바꿔도 e 는 0.968–0.978 입니다.
- dt 2 ms 에서는 수치가 터집니다. 접촉 강성 1e6 은 고유 진동수 ω₀ = √k = 1,000 rad/s 에 해당하고, ω₀·dt 가 2 가 되면 접촉 적분이 에너지를 만들어 냅니다. 7절의 라켓 접촉 측정에서도 ω₀·dt ≤ 1 근처가 안정 경계로 나왔습니다.
- 감쇠 하나로 맞출 수 있습니다. 강성 1e6 을 두고 감쇠 b 만 이분법으로 바꾸면 b = 83.8 에서 e = 0.876(규정), b = 38.5 에서 0.946(+8%), b = 128.1 에서 0.806(−8%)이 됩니다. DeepMind 기본값 0.978 의 +8% 는 1 을 넘으므로 감쇠로는 만들 수 없습니다.
- 접촉 위상에 따른 흩어짐. 같은 낙하라도 접촉이 시간 간격 사이 어디에서 시작하는지에 따라 e 가 달라집니다. 위상 50가지로 재면 표준편차가 dt 0.25 ms 에서 0.005, 0.5 ms 에서 0.012, 1 ms 에서 0.005–0.008 이었고, dt 1 ms 에서는 최대 1.002 로 1 을 넘는 경우도 있었습니다. 강화학습에는 이 흩어짐이 작은 관측 잡음처럼 들어갑니다.
충돌 속도를 1–8 m/s 로 바꿔 보면 차이가 더 분명합니다. MuJoCo 의 e 는 0.96–0.99 로 거의 평평한데, Sony AI 2026 의 식(e = 0.98 − 0.02·입사 속도)은 속도가 빠를수록 e 가 내려갑니다.
4. 공기: 마그누스 힘이 문헌보다 4.2배 세다
| 출처 | C_D | 마그누스 계수 k_M (N·s²/rad/m) | MuJoCo 대비 |
|---|---|---|---|
| MuJoCo, DeepMind 값(실측) | 0.471 | 2.053e-5 | 1.00 |
| TT3D 2025 | 0.494 | 4.860e-6 | 0.237 |
| Tebbe 외 2020(C_D 0.4, C_M 0.6, 힘의 꼴은 추정) | 0.400 | 9.236e-6 | 0.450 |
| Sony AI 2026 | 저속 0.55, 17.5 m/s 에서 0.37–0.51 | 회전비의 함수(이 글에서는 수치를 쓰지 않음) |
- 실효 C_D 는 2–30 m/s 에서 0.470–0.474 로 거의 일정했습니다. fluidcoef 의 첫째 값 0.235 가 C_D/2 에 해당합니다.
- 마그누스 힘은 속도와 회전에 정비례하는 상수 k_M = 2.053e-5 로 나왔습니다. 양력계수로 바꾸면 C_L = 1.33·S 이고, TT3D 는 0.316·S 입니다.
- 7 m/s 로 날아가는 공에 300 rad/s 백스핀을 주면 MuJoCo 의 마그누스 힘은 약 43 mN 으로 무게 26 mN 보다 큽니다. 공이 위로 떠오릅니다. 실제 공에서는 이런 일이 없다고 보지만, 우리 손으로 확인하지는 않았습니다(추정).
- 회전비 0.5 근처에서 양력이 갑자기 바뀌는 현상(lift crisis)을 보고한 연구가 있는데, 계수가 상수인 모델은 MuJoCo 든 문헌 식이든 이것을 그리지 못합니다.
같은 타구(로봇 쪽 끝선 뒤 y = −1.6 m, 높이 0.2 m 에서 속도 (0, 7, 1.6) m/s)에 회전만 바꿔 넣으면 차이가 착지점으로 드러납니다.
| 회전 | MuJoCo 착지 y | TT3D 식 착지 y | 비고 |
|---|---|---|---|
| 탑스핀 300 rad/s | −0.315 m(친 쪽 코트) | 0.355 m | TT3D 는 네트 높이보다 1.2 cm 낮게 지나 네트로 판정 |
| 무회전 | 0.812 m | 0.789 m | 두 모델이 2.3 cm 안에서 같음 |
| 백스핀 150 rad/s | 3.684 m(밖), 꼭대기 51.3 cm | 1.093 m | |
| 백스핀 300 rad/s | 5.378 m(밖), 꼭대기 139.6 cm | 1.482 m(밖) |
무회전 공은 두 모델이 거의 같고, 회전이 들어가면 MuJoCo 쪽이 크게 휩니다. 문제는 공개 데이터의 회전 값이 바로 이 MJCF 와 함께 쓰이도록 만들어졌을 수 있다는 점입니다(추정). 그렇다면 회전 값과 마그누스 계수는 짝으로만 써야 하고, 한쪽만 문헌 값으로 바꾸면 안 됩니다. 6절의 민감도가 그 근거입니다.
5. 비스듬한 바운드: 탁자가 미끄럽다
탁자 바로 위에서 수평 속도 3, 6, 9 m/s, 수직 속도 2, 4 m/s, 회전 −300, 0, +300 rad/s 를 조합해 바운드 직전과 직후의 상태를 비교했습니다.
- DeepMind 값의 실효 마찰 계수는 약 0.10 입니다. 설정한 friction 0.1 과 같고, 문헌의 0.25–0.3 보다 작습니다. 예를 들어 수평 6 m/s, 수직 4 m/s, 무회전으로 들어온 공은 바운드 뒤 수평 5.19 m/s 로 나갔습니다. TT3D 식은 3.78 m/s, Sony 식은 4.10 m/s 입니다.
- 바운드 뒤에도 접촉점이 계속 미끄러졌습니다. 문헌 식은 같은 입력에서 구름으로 끝나는 경우가 많습니다.
- e 를 규정 값에, 마찰을 0.3 에 맞춘 MuJoCo 도 미끄럼 구간에서는 μ 0.30 이 그대로 나왔지만, 구름 구간에서는 실효 μ 가 0.07–0.17 로 남았습니다. 마찰 방향의 접촉 설정(solreffriction)이 감쇠만 있어 미끄럼을 끝까지 멈추지 못하기 때문으로 봅니다(추정).
- 수직 2 m/s 에 백스핀을 준 몇 경우에는 e 가 1.08–1.16 으로 1 을 넘었습니다. 마찰과 수직 방향 접촉이 엮여 생긴 것으로 봅니다(추정). 다음 보정 때 함께 맞춰야 할 항목입니다.
6. 공개 초기 상태 500개: 무엇이 가장 크게 흔드나
랠리 13,088개 가운데 로봇 쪽으로 오는 공 11,999개에서 500개를 무작위로(seed 0) 뽑아 DeepMind 값의 MuJoCo(dt 1 ms)로 날렸습니다. 공개 데이터에는 궤적이 없고 초기 상태만 있습니다. 그래서 아래는 실제 공과의 비교가 아니라 「같은 초기 상태에서 시뮬레이터가 내놓는 값」과 그 민감도입니다.
| 지표 | 5% / 50% / 95% |
|---|---|
| 초기 속력 | 3.80 / 5.49 / 7.89 m/s |
| 초기 회전 | 12.21 / 57.55 / 101.60 rad/s |
| 로봇 쪽 탁자 착지 | 100.0%(네트 접촉 0.6%) |
| 첫 바운드까지 | 0.30 / 0.42 / 0.60 s |
| 바운드 직후 속력 | 3.82 / 4.50 / 5.61 m/s |
| 타격면(y = −1.6 m) 도달 | 0.51 / 0.71 / 1.06 s |
| 타격면 높이 | 0.01 / 0.31 / 0.47 m |
같은 500개를 설정만 바꿔 다시 날리고, 짝지어 타격면에서의 위치 차이를 보았습니다. 라켓 판의 반폭이 약 7.5 cm 이므로, 차이가 수 cm 를 넘으면 정책이 헛칩니다.
| 바꾼 것 | 타격면 위치 차이 중앙값 / 95% | 로봇 쪽 착지율 변화 |
|---|---|---|
| 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 |
| 탁자 μ 0.25 / 0.3 | 0.6 / 5.1 cm, 0.7 / 6.0 cm | 0 |
| 탁자 e 를 규정 값 0.876 으로 | 6.9 / 15.2 cm | 0 |
| 규정 e 에서 ±8% | 4.7 / 10.1 cm, 4.6 / 9.8 cm | 0 |
| 마그누스 ×0.5 | 12.4 / 37.6 cm | −11.0 %p |
| 마그누스 ×0.24(TT3D 세기) | 17.7 / 57.3 cm | −23.0 %p |
| 마그누스 0 | 23.2 / 78.9 cm | −32.2 %p |
| 문헌 값 조합(C_D 0.49, 마그누스 ×0.24, 규정 e, μ 0.3) | 17.4 / 57.3 cm | −21.2 %p |
- 가장 큰 것은 마그누스입니다. 문헌 세기로 낮추면 탁자에 떨어지는 공이 500개 중 385개(77%)로 줄어듭니다. 데이터의 회전 값과 계수가 묶여 있다는 신호입니다.
- 탁자 반발 ±8% 는 공의 5% 를 약 10 cm(95% 지점 9.8–10.1 cm) 비켜 가게 합니다. 라켓 반폭보다 큽니다. DeepMind 의 RSS 2023 논문이 보고한 「탁자 반발이 8% 어긋나면 보상이 크게 떨어진다」는 관찰(조사 문서 기준)과 같은 방향입니다.
- 시간 간격은 1 ms 로 충분합니다(공만 볼 때). 0.5 ms 와 0.25 ms 로 줄여도 타격면 차이 중앙값이 1 cm 안이었습니다. 라켓이 들어오면 이야기가 달라지는데, 이것은 7절에서 봅니다.
7. 라켓: 공이 판을 뚫고 지나간다
라켓 판(15×16 cm, 두께 6 mm·14 mm)을 고정해 두고 공을 정면으로 쏘았습니다. 접촉이 시간 간격 사이 어디에서 시작하는지(위상)를 30–50가지로 흔들어, 되튀는지 뚫고 지나가는지 셌습니다.
- DeepMind 의 탁자 강성(1e6)을 라켓에 그대로 쓰면 빠른 공이 판을 뚫습니다. 6 mm 판은 25 m/s 부터, 14 mm 판은 30 m/s 부터 50번 모두 관통했고, dt 를 0.25 ms 로 줄여도 같았습니다. 공이 판에 파고드는 깊이(선형 근사로 속도/√k, 40 m/s 면 40 mm)가 「공 반지름 + 판 두께의 절반」을 넘으면 공 중심이 판 가운데를 지나 법선이 뒤집히기 때문입니다. 「한 스텝에 너무 멀리 가서 접촉을 놓친다」는 처음 가설은 dt 2 ms 에서만 맞았습니다.
- MuJoCo 기본 접촉(solref 0.02 1)은 공에 너무 무릅니다. 10 m/s 에서도 모든 조건이 관통했습니다.
- 강성을 올리면 이번에는 큰 dt 에서 수치가 튑니다. 아래 격자에서 √k·dt 가 1 을 넘는 칸은 e > 1.05 로 튀는 경우가 생겼고, 1 이하인 칸은 강성 4e6 이상에서 관통도 불안정도 없었습니다.
결정. 물리 시간 간격은 0.5 ms, 라켓 접촉은 solref (−4e6, −34)(감쇠비는 DeepMind 값과 같게)입니다. 14 mm 판, 40 m/s 에서 관통 0/30, 불안정 0/30 이었습니다. 이 설정에서 잰 라켓의 반발 계수는 4 m/s 에서 0.931, 8 m/s 에서 0.893 으로, Sony AI 2026 식(0.80, 0.72)보다 큽니다. 실제 러버가 파고드는 깊이와 접촉 시간에 맞춘 값은 아닙니다(미확인). 탁자는 DeepMind 강성 그대로 두었습니다. 탁자에 닿는 수직 속도는 8 m/s 를 넘지 않는다고 보았고(추정), 8 m/s 까지는 3절에서 안정이었습니다.
8. 계산은 싸다
공과 탁자만 있는 모델은 1코어로 초당 23만–36만 스텝을 돌았습니다. 같은 측정을 두 번 했는데 노드의 다른 부하에 따라 이만큼 달랐습니다(나중 측정: dt 0.25–1 ms 에서 229,806–239,229 스텝/s). dt 0.5 ms 면 실시간의 120–180배입니다. 스레드 3개로 공 512개를 한꺼번에 굴리면 초당 58만–122만 스텝이었습니다. 갠트리 2축과 손목 2축 로봇을 넣은 모델은 dt 0.5 ms 에서 1스레드 초당 152,611 스텝(실시간 76배)이었습니다. 이 단계에는 GPU 가 필요 없습니다. 실험 시간도 짧았습니다. 낙하 묶음(A)은 11.3 s, 공기역학 묶음(B)은 3.6 s, 바운드(C)는 0.5 s, 500개 민감도(D)는 28.7 s 였습니다.
9. 한계
- 진짜 공의 궤적과 비교하지 않았습니다. 비교 대상은 문헌의 값이고, 문헌 값도 우리가 다시 재지 않았습니다. 다음 단계는 우리 카메라로 찍은 궤적으로 계수를 맞추는 것입니다. 지금의 30 fps 점수판 카메라로는 바운드 순간과 회전이 거의 보이지 않아, 고속 카메라가 필요합니다.
- 공개 회전 값이 어떤 모델로 추정됐는지는 확인하지 못했습니다(미확인). 「이 MJCF 와 짝」이라는 해석은 추정입니다.
- Tebbe 식의 힘의 꼴과 Sony 식의 마그누스 계수(회전비 함수)는 이 글에서 수치로 쓰지 않았거나 추정으로 두었습니다.
- 그림의 낙하 움직임은 실측 반발 속도로 다시 그린 것입니다. 회전별 착지 그림은 표의 착지 위치만 찍었고, MuJoCo 궤적 자체는 그리지 않았습니다.
10. 다음 편으로
이 공 모델 위에 로봇을 올려 「보고, 예측하고, 휘두르는」 고전 제어 기준선을 돌린 결과는 5편에 있습니다. 강화학습은 그 기준선을 넘는지로 평가합니다. 로봇의 몸을 어떻게 만들지는 바로 다음 3편에서 봅니다.
티티 한마디. 같은 공인데 시뮬레이터 설정 한 줄 바꿨다고 26 cm 튀던 공이 2 m 가까이 솟았어요. 탁구공이 가볍다고 우습게 보면 안 돼요. 계수는 데이터와 짝으로 다뤄 주세요!
참고
모든 링크는 2026-10-18 에 열람해 열리는 것을 확인했습니다.
- DeepMind, Achieving Human Level Competitive Robot Table Tennis(ICRA 2025): https://arxiv.org/abs/2408.03906
- 공개 데이터와 MuJoCo 노트북: https://github.com/google-deepmind/competitive_robot_table_tennis(초기 공 상태, © 2025 Google LLC, CC BY 4.0. 이 글은 데이터를 다시 배포하지 않고, 500개를 뽑아 시뮬레이터로 날린 결과만 실었습니다.)
- DeepMind, Robotic Table Tennis: A Case Study into a High Speed Learning System(RSS 2023): https://arxiv.org/abs/2309.03315
- Sony AI, Physics Models for Sim-to-Real Transfer in Professional-Level Robot Table Tennis(2026): https://arxiv.org/abs/2606.28805
- TT3D: Table Tennis 3D Reconstruction(2025): https://arxiv.org/abs/2504.10035
- MuJoCo 유체 모델 문서: https://mujoco.readthedocs.io/en/stable/computation/fluid.html, MuJoCo 저장소: https://github.com/google-deepmind/mujoco
- Tebbe 외(2020)의 계수와 회전비 0.5 근처의 lift crisis 보고(Miyazaki, 2017)는 조사 단계에서 원문을 확인한 값이며, 이번에 링크를 다시 확인하지는 않았습니다.
- 인용 코드는 TT Lab 실험 코드입니다.