{
  "version": "2026-11-09b",
  "_note": "단일 기준 규격. 브라우저(engine.js·mjengine.js·camera.js)와 PC Python 패키지가 모두 이 값을 따른다. 단위 m, 좌표 원점 = 매트 중심, +x = 2팀 골대 쪽, +y = 카메라 A 화면 위쪽, z 위.",
  "mat": { "w": 0.90, "h": 0.60, "color": "#3a7d44" },
  "table_margin": 0.12,
  "play_area": { "x": 0.38, "y": 0.23, "line_w": 0.010, "center_circle_r": 0.08 },
  "goal": { "mouth_half": 0.09, "depth": 0.06, "post_r": 0.005 },
  "walls": { "x": 0.45, "y": 0.30, "height": 0.03, "thickness": 0.01 },
  "ball": { "type": "탁구공", "r": 0.020, "mass": 0.0027 },
  "robot": {
    "_note": "머리 윗면 100x100mm 는 확정(11/9). 걸음·질량 등 나머지는 실측 전 가정값.",
    "footprint": [0.09, 0.07],
    "height": 0.15,
    "mass": 0.20,
    "head_top": [0.10, 0.10],
    "gait": { "forward_m": 0.06, "back_m": 0.04, "turn_rad": 0.35, "step_s": 0.5 },
    "drive": { "v_max": 0.12, "w_max": 0.8, "dt": 0.1 }
  },
  "aruco": {
    "corner_markers": { "dictionary": "DICT_4X4_50", "size": 0.040, "quiet": 0.008,
      "centers": { "0": [-0.415, 0.265], "1": [0.415, 0.265], "2": [0.415, -0.265], "3": [-0.415, -0.265] } },
    "hat_markers": { "dictionary": "DICT_4X4_50", "size": 0.070, "quiet": 0.015, "height": 0.15,
      "ids": { "A": 10, "B": 20, "C": 30, "D": 40 }, "_orientation": "마커 0행이 로봇 앞쪽" },
    "calib_grid": { "dictionary": "DICT_4X4_100", "size": 0.040, "quiet": 0.010,
      "xs": [-0.36, -0.216, -0.072, 0.072, 0.216, 0.36], "ys": [-0.225, -0.075, 0.075, 0.225],
      "id_rule": "50 + 6*행 + 열 (행은 ys 순서, 열은 xs 순서)" }
  },
  "checkerboard": { "inner": [9, 6], "square": 0.025 },
  "cameras": {
    "_recommend": "1080p UVC 웹캠, 수동 노출·초점, 수평 화각 약 70~78° (예: Logitech C920/C922급). 조당 2대.",
    "A": { "pos": [0.0, -0.02, 0.90], "target": [0.0, 0.0, 0.0], "hfov": 74, "k1": -0.18, "k2": 0.04, "role": "천장 내려다보기" },
    "B": { "pos": [-0.70, -0.60, 0.80], "target": [0.0, 0.0, 0.0], "hfov": 74, "k1": -0.12, "k2": 0.02, "role": "측면 비스듬히" },
    "B_group1": { "pos": [0.385, -0.62, 0.20], "target": [0.385, 0.0, 0.03], "hfov": 62, "k1": -0.08, "k2": 0.01, "role": "1조 골라인 수직면" }
  },
  "groups": {
    "1": { "name": "1조 · 라인아웃 VAR", "mode": "var", "robots": { "A": [1, "슈터"], "B": [2, "골키퍼"] }, "extra": "YOLO-Seg 비교용 자동 라벨 데이터 내보내기" },
    "2": { "name": "2조 · 1대1 공격", "mode": "soccer", "robots": { "A": [1, "공격"], "C": [2, "수비"] }, "drive": true },
    "3": { "name": "3조 · 포켓몬 축구", "mode": "soccer", "robots": { "A": [1, "공격"], "B": [1, "골키퍼"], "C": [2, "공격"], "D": [2, "골키퍼"] }, "extra": "공유 자율: 정책이 움직이고 키보드/컨트롤러 입력이 있으면 덮어씀. 실물은 2대(1대1)" },
    "4": { "name": "4조 · 점령전", "mode": "zones", "robots": { "A": [1, "점령"], "B": [1, "점령"], "C": [2, "점령"], "D": [2, "점령"] } }
  },
  "hub_url": "https://robot.basecamp.im",
  "student_os": "Windows"
}
