kendama_simulate — DRIVE kendama op

• 데이터 종류: table → table

• 호출: import fullseye as fs; fs.ledger.kendama_simulate(kp: 'dict', handle, *, p0, v0, t_end: 'float', dt: 'float' = 0.001, perceive=None, catch_plan=None, g: 'float' = None, v_max: 'float' = 2.0, a_max: 'float' = 20.0, v_rel_max: 'float' = 1.0, plan_from: 'float' = 0.0, stop_on_miss: 'bool' = True, contact=None, contact_tol: 'float' = 0.0005) -> 'dict'(구현을 직접 호출하려면 import kendama; kendama.kendama_simulate(kp: 'dict', handle, *, p0, v0, t_end: 'float', dt: 'float' = 0.001, perceive=None, catch_plan=None, g: 'float' = None, v_max: 'float' = 2.0, a_max: 'float' = 20.0, v_rel_max: 'float' = 1.0, plan_from: 'float' = 0.0, stop_on_miss: 'bool' = True, contact=None, contact_tol: 'float' = 0.0005) -> 'dict', 원장에서 가져오려면 opsdrive.get("kendama_simulate"))

사용법

켄다마의 2단 시뮬레이션: 끈이 팽팽한 동안에는 지점(사라도의 실 구멍 = 손잡이 + kp["tie_offset"])에 매인 공(사영법, ballistics.tether_simulate와 동일: 지점 고정·진공이면 같은 궤적, 끈의 길이 = kp["pendulum_length"]), 느슨해지면 자유 낙하(중력 + 항력, kp["bp"]; rho = 0이면 진공). 매 step kendama_catch_check(큰 접시 = 손잡이 + kp["cup_offset"], 축 kp["cup_axis"])로 받기를 판정하고, 받으면 끝납니다.

handle = 손(사라도의 중심)의 (3,) 고정점 또는 t → (3,) 의 함수(개루프 올려 흔들기). catch_plan 이 있으면, 실이 느슨해진 뒤(그리고 t ≥ plan_from: 올려 흔들기가 끝날 때까지는 개루프를 우선)는 매 step perceive 로 지각한 (p̂, v̂) 를 catch_plan(t, p̂, v̂, cup_state) → {"target": 大皿の縁の中心の目標 (3,), …} 에 넘기고, 손을 속도 ≤ v_max·가속도 ≤ a_max 의 bang-bang 으로 「목표 − cup_offset」 으로 옮긴다(손이 움직이면 지점도 움직이므로, 공이 떨어져 |p − 지점| = L 이 되면 다시 팽팽해진다).

지각 perceive:

• None → 참값 (p, v).

• perceive(t, p, v) → (p̂, v̂)(noisy_perceiver 등)는 계획이 살아 있는 step 에서만 호출한다.

• 속성 observe_all = True 인 지각(kendamaworld.camera_perceiver)은 매 step perceive(t, p, v, scene) 로 호출한다(scene = {"t", "hand", "tie", "cup", "cup_axis", "taut"} = 손의 고유수용감각으로 알 수 있는 양 + 세계를 그리기 위한 taut (공 자세의 그리기 약속: 팽팽한 동안은 실 구멍이 매듭을 향하고, 느슨해지면 마지막 자세 그대로). p 도 세계를 그리기 위해서만 넘긴다). 반환값이 None 이면 계획은 그대로(마지막 목표로 계속 옮기고, 목표가 없으면 손을 멈춘다).

공을 움직이는 것은 중력(+ 항력, rho > 0 일 때)과 실의 장력(≥ 0 의 단측 구속)뿐. 켄은 공을 밀지 않는다: contact(hand, p) → 隙間 [m] (kendamaworld.kendama_clearance 등)를 넘기면, 포구 전에 틈 < −contact_tol 이 된 step 에서 "hit_ken" 으로 끝난다(켄 끝·접시 가장자리·사라도에 공이 닿음 = 실패). 포구는 kp["catch_window"](공이 가장자리에 닿은 높이)로 판정한다.

끝나는 방식 end_reason: "caught"(포구), "hit_ken"(켄다마에 닿음), "missed"(느슨해진 뒤, 아래로 떨어지면서 큰 접시 면보다 2 r_b 이상 아래로 옴. stop_on_miss=False 이면 멈추지 않음: snap 의 게이트에 사용), "timeout"(t_end). 반환값 {"t", "p", "v", "hand", "anchor" (= 支点 = 糸穴), "cup", "cup_v", "taut", "tension", "energy", "snap_times", "snap_loss", "slack_t", "caught", "catch_t", "end_reason", "lateral", "plan_log", "n_estimates", "stage", "min_gap"}(배열은 끝난 step 까지. stage = 각 step 의 제어 단계("lift" 올려 흔들기 / "wait" 느슨해졌지만 계획 전 / 계획의 "stage"(hold / carry / absorb) 또는 "plan"). slack_t = 실이팽팽해진 뒤 처음 느슨해진 시각, 처음부터 느슨하면 0.0, 한 번도 느슨해지지 않으면 None. energy = ½mv² + mgz. n_estimates = 계획에넘긴 지각의 수). 초기 상태가 |p₀ − 지점(0)| > L, t_end < 0, dt ≤ 0, 상한 ≤ 0 이면 ValueError.

빈 입력(kp 이(가) 빈 dict)은 ValueError 를 발생시킨다.

참고(샘플 데이터·문헌)

• 샘플 데이터 카탈로그(DL URL / 라이선스) —— 2-D 는 skimage.data(BSD/public)+ 합성, 3-D 는 실데이터 소스(Stanford/PDS 등)의 DL URL.

• 연산자의 내력·참고문헌 —— 이 연산자 족의 바탕이 된 연구/기법의 출처.

• 알고리즘의 정전(저자·연도)과 용도는 위의 패밀리 사용 가이드에 적혀 있습니다.

실행 가능한 예제(이 연산자를 실제로 호출하는 검증된 샘플)

• poc_kendama — py -3.11 examples/poc_kendama.py

타입이 이어지는 다음 연산자(table 를 입력으로 받는 것)

course_layout · course_occupancy · course_contains · world_build · world_camera · world_move · lidar_scan · rss_longitudinal_same

같은 카테고리(kendama)

kendama_params · elliptic_k_agm · pendulum_period_exact · pendulum_launch_speed · pendulum_rod_simulate · tether_tension_fixed · tether_slack_angle · swing_up_plan


*Provenance: kendama.py — DRIVE 연산자 레지스트리. 이 op 노트는 tools/opdocs.py md 가 자동 생성합니다(직접 편집하지 마세요).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.