fit_spin_aero — DRIVE ball op

• Datenarten: signal × points × table → table

• Aufruf: import fullseye as fs; fs.ledger.fit_spin_aero(t, p, bp: 'dict', *, omega0=None, fit_cl: 'bool' = False, omega_max: 'float' = 1000.0, iters: 'int' = 25, dt: 'float' = 0.001) -> 'dict' (die Implementierung direkt: import ballistics; ballistics.fit_spin_aero(t, p, bp: 'dict', *, omega0=None, fit_cl: 'bool' = False, omega_max: 'float' = 1000.0, iters: 'int' = 25, dt: 'float' = 0.001) -> 'dict'; aus dem Register: opsdrive.get("fit_spin_aero"))

• GPU: nein (nur CPU-Referenzimplementierung)

Verwendung

Liest Luftwiderstand und Spin gemeinsam(fit_spin mit freiem C_d): passt die Bewegungsgleichungen mit Luftwiderstand + Magnus an eine Trajektorie (t_i, p_i) (ein Intervall ohne Abpraller) mit den 10 Parametern (p₀, v₀, ω, C_d) per Levenberg–Marquardt an (fit_cl=True gibt auch den Auftriebs-Skalenfaktor κ frei, also 11 Parameter).

Das C_d des Modells ist konstant (keine Re-Abhängigkeit wird angepasst); der Auftrieb folgt der empirischen Spinverhältnis-Formel C_L = κ·S/(1 + 2S) (S = rω/|v|), der Skalenfaktor κ ist standardmäßig 1. ★Ein bp mit numerischem (konstantem) C_L wird abgelehnt (ValueError): Die Magnus-Kraft eines konstanten C_L hat einen von ω unabhängigen Betrag, die |ω|-Spalte verschwindet, und der Betrag des Spins ist nicht ablesbar (gemessen: fit_spin mit konstantem C_L bewegt |ω| bei einer Trajektorie mit wahren 150 rad/s nur bis 10.3 rad/s).

Was nicht lesbar ist, steht im Rückgabewert: Der Luftwiderstand wirkt entlang −v, Magnus entlang ω × v (senkrecht zu v), die Kraftrichtungen trennen sich also orthogonal, aber (a) bei kurzem Flug, in dem die Geschwindigkeit kaum sinkt, ist C_d mit v₀ verflochten, (b) ω und der Auftriebs-Skalenfaktor κ lassen sich nicht trennen, wenn das Spinverhältnis S im Flug wenig variiert (wo S klein ist, gilt C_L ≈ κS, die Kraft liegt also nahe am Produkt κ·ω, und bei einem langsamen Ball mit S = 0.49–0.56, wo sich S nur um 14 % bewegt, sieht man C_L(S) praktisch an einem einzigen Punkt), und (c) die zu v parallele Komponente von ω erzeugt keine Kraft. Das zeigt sich in cond (Konditionszahl der skalierten Jacobi-Matrix), corr (Korrelationsmatrix der Schätzer, in der Reihenfolge von param_names), cov_unit (Kovarianz der Schätzer pro 1 m Positionsrauschen = linearisierte Cramér-Rao-Schranke; bei Rauschen σ [m] mit σ² multiplizieren), corr_cd_omega (Korrelation von C_d mit dem Betrag von ω⊥), corr_cd_v0 (Korrelation von C_d mit dem Betrag der Anfangsgeschwindigkeit), omega_axial_std_unit (Standardabweichung der zu v parallelen Komponente von ω, pro 1 m Rauschen) und omega_perp_std_unit (Standardabweichung jeder der zwei senkrechten Komponenten von ω). Wann es lesbar ist: In der Linearisierung desselben Modells beträgt die ω⊥-Standardabweichung mit fit_cl=True (Rauschen 1.5 mm) bei v₀ = 6 m/s 628 rad/s (419 %), bei 15 m/s 76 (50 %) und bei 25 m/s mit ω = 300 rad/s 35 (12 %): Die Entartung ist ein Befund für Bedingungen, unter denen S sich kaum bewegt, nicht „prinzipiell aus der Trajektorie nicht lesbar“; schnelle Bälle und stark abbremsende Flüge sind lesbar. Fällt der Rang der Jacobi-Matrix ab (z. B. im Vakuum), ist cond None statt inf und rank_deficient True. corr_cd_omega ist None, wenn ω⊥ = 0 (keine Richtung; NaN wird nie zurückgegeben). Rückgabewert {"p0", "v0", "omega", "omega_perp", "cd", "cl_scale", "rms", "cond", "rank_deficient", "corr", "param_names", "cov_unit", "corr_cd_omega", "corr_cd_v0", "omega_axial_std_unit", "omega_perp_std_unit", "iters", "t0", "at_bound"}. Eine mit demselben Modell erzeugte Trajektorie wird auf 1e-6 zurückgewonnen (Gate). ★Ist die Welt ein anderes Modell (C_d hängt von Re ab, C_L hat eine Senke), werden die konstant angepassten C_d, ω und C_L zu effektiven Werten über das Intervall und sind verzerrt (die Verzerrung wird im PoC gemessen). Die Verzerrung ist nicht auf eine Senke beschränkt: Verfehlt das angepasste C_L-Modell den Beiwert der Welt, wird ω mitgezogen, mit dem 1.5- bis 2.7-fachen des Beiwertfehlers (in einer Welt ohne Senke verfehlt die κ = 1-Anpassung ω bei den Beiwertfaktoren 0.6 / 0.8 / 1.2 um 58 / 34 / +53 %). Ob die Anpassung danebenliegt, zeigt rms. omega_max ist wie bei fit_spin (obere Schranke des Spinbetrags). Die Konvergenz ist langsam, wenn omega0 weit von der Wahrheit entfernt ist, die Trajektorie kurz ist oder fit_cl=True gilt; im flachen Tal erreichen manche Stichproben iters nicht (ist das zurückgegebene iters gleich dem Argument, wurde abgebrochen).

Grenzen: Variiert das Spinverhältnis S im Flug wenig, sind mit fit_cl=True die Spalten von |ω| und κ nahezu parallel (cond groß, corr ≈ ±1; ein langsamer Ball mit S = 0.49–0.56 ergibt eine ω⊥-Standardabweichung von 419 % von ω, ein schneller mit v₀ = 25 m/s 12 %) — dann ω aus dem Muster des Balls lesen (balltrack.spin_from_markers) und den Auftriebsfaktor stattdessen aus der Trajektorie bestimmen (fit_aero bei bekanntem ω). Ein bp mit konstantem C_L und weniger als 12 Stichproben lösen ValueError aus; bei Rangverlust der Jacobi-Matrix ist cond None (nie inf) und corr_cd_omega None, wenn ω⊥ = 0.

Referenzen (Beispieldaten, Literatur)

• Katalog der Beispieldaten (Download-URLs / Lizenzen) — 2-D nutzt skimage.data (BSD/Public Domain) plus synthetische Bilder, 3-D nennt Download-URLs echter Datenquellen (Stanford, PDS, …).

• Herkunft und Literatur der Operatoren — die Quellen der Forschung/Verfahren, auf denen diese Operatorfamilie beruht.

• Der kanonische Algorithmus (Autor, Jahr) und seine Anwendungen stehen im Familienleitfaden oben.

Ausführbare Beispiele (verifizierte Samples, die diesen Operator wirklich aufrufen)

• poc_cd_spin_joint — py -3.11 examples/poc_cd_spin_joint.py

Typkompatible Folge-Operatoren (nehmen table als Eingabe)

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

Gleiche Kategorie (ball)

ball_params · impact_params · flight_vacuum · flight_ode · flight_simulate · flight_state_at · magnus_lift_coefficient · drag_coefficient_sphere


*Provenance: ballistics.py — DRIVE Operator-Registry. Diese Notiz wird von tools/opdocs.py md erzeugt (nicht von Hand bearbeiten).*

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