Implementierung eines Kugelpendels

Ich versuche, ein Kugelpendel zu implementieren. Der Lagrangian (den ich noch nicht ganz verstanden habe) basiert auf l , θ und φ von dieser Seite ergeben die Gleichungen:

θ ¨ = φ ˙ 2 Sünde θ cos θ G l Sünde θ φ ¨ = 2 θ ˙ φ ˙ Kinderbett θ

Ich behandle θ ¨ wie die Beschleunigung und von θ ˙ als Geschwindigkeit von θ . Ist das richtig? Nun wird jeder Schritt der Bewegung wie folgt implementiert (Python):

theta_f = pow(phi_v, 2) * sin(theta) * cos(theta) - G / L * sin(theta)
phi_f = - 2 * theta_v * phi_v / tan(theta)

theta_v += theta_f / timesteps
phi_v += phi_f / timesteps

theta += theta_v
phi += phi_v

Dies funktioniert solange phi_v( ϕ ˙ ) ist 0 oder nahe 0.

Pendel

Wenn ϕ ˙ Initial > 0 , die Bewegung ist fehlerhaft.

unregelmäßige Pendelbewegung

Meine Anfangswerte sind

theta = 0.8
phi = 0.5
timesteps = 60
L ~ 2
G = 2.0
theta_v = 0.0
phi_v = 0.1

Nach einigen Iterationen erzeugt der Code ein math range erroras phi_vgets too large. Ich habe diese Frage gefunden , die den mathematischen Rundungsfehler erklären könnte.

Ich verwende 60 Samples pro Sekunde, weil es eine Echtzeit-Interaktion geben wird. Annäherungswerte werden völlig in Ordnung sein, aber ich kann nicht glauben, dass der aktuelle Zustand einfach ein Annäherungsfehler ist.

Wie kann ich meinen Code korrigieren, um das Kugelpendel zu simulieren?

Du redest von Beschleunigungen, nicht von Kräften. Es sollte keine Masse mehr im Spiel sein.
Haben Sie viel größere Werte der anfänglichen Winkelgeschwindigkeit ausprobiert? Es könnte sein, dass der Ball in diesen Bildern fast, aber nicht ganz, die Mitte trifft.
In Ihrem Code, z ϕ ¨ , warum gibt es eine 4 anstelle einer 2 , und warum gibt es a Sünde θ Begriff?
Ok aber warum die Sünde θ Begriff? Ich würde das Gefühl haben, dass dies einen großen Unterschied machen würde, wenn Sie durch ihn dividieren. Wenn θ = 0 Sie hätten eine unendliche Beschleunigung.
Warum ist ϕ ˙ + = ϕ ¨ ? Gehst du davon aus Δ T = 1 ??
@KyleKanos Ich wollte als nächstes danach fragen. Das Problem könnten auch zu große Zeitschritte sein. Dies ist kein sehr guter Weg, um die Gleichungen zu "integrieren".
@AaronStevens Ich bin ziemlich zuversichtlich, dass dies das eigentliche Problem ist
Sie verwenden die diskrete „Integrationsmethode“, wie Sie die Schrittweite steuern?, versuchen Sie, die RK4-Integrationsmethode zu implementieren.
Es könnte mehrere Probleme geben. Ich werde den Code nicht auseinandernehmen, sondern einige Ratschläge geben. Wenn Sie keinen guten ODE-Löser verwenden und Ihre Schrittgröße regulieren, wird dies die Dinge stark vermasseln. Implizite Löser sind normalerweise universell stabil, aber schwieriger zu codieren. Ich bin mir nicht sicher, ob die Winkelvariable ein Problem darstellt, aber in der Einstellungsdynamik verwendet man Viertelangaben anstelle von Winkeln, um fehlerhafte Ergebnisse zu vermeiden. Es gibt spezielle Winkel, in denen das System nicht umgekehrt werden kann und die Richtung des nächsten Schritts mehrdeutig wird. Sie lösen gewissermaßen nach der Lage Ihres Pendels auf.
@Aaron Ich habe die Gleichung korrigiert und die Werte am Ende der Frage eingefügt. Die Bewegung im 2. Bild sieht jedoch sehr seltsam aus. Wäre es immer noch wahrscheinlich, dass dies aufgrund zu großer Zeitschritte geschieht? Hier scheint es grundlegende Fehler zu geben, die meiner Meinung nach von RK gelöst werden.
@ggcg Da ich überhaupt keinen ODE-Löser verwende, würden die Berechnungen in Quaternions/DirectionVectors die aktuellen Probleme beseitigen. Ich habe die Berechnungen von dieser Seite kopiert, weil ich davon ausgegangen bin, dass selbst meine Zeitschritte diese gigantischen Fehler nicht verursachen würden.
@Leander, Sie müssen einen ODE-Solver verwenden, ob Sie es wissen oder nicht. Wenn Sie nur ein acc dt zur Geschwindigkeit und dann v dt zum Winkel hinzufügen, dann machen Sie einen Euler-Schritt, der bekanntermaßen sehr schlecht ist. Für ODE zweiter Ordnung machen wir typischerweise einen neuen Freiheitsgrad p = dx/dt und lösen bei jedem Schritt nach x und p auf.
@Leander, teilst du durch den Zeitschritt, um die Geschwindigkeit zu erhalten?
Ja, ich scheine all diese falschen Dinge zu tun. Mir ist jetzt klar, wie ich letzteres beheben kann und warum es nicht funktioniert. Zuerst habe ich diese Zeile komplett entfernt und nur die "Länge" der Zeichenfolge geändert.
@ggcg * ... mache einen neuen Freiheitsgrad p = dx/dt und löse bei jedem Schritt nach x und p auf. * Könnten Sie das bitte weiter ausführen? Mit Link, Antwort oder Suchbegriffen?
@Leander, siehe meine Antwort. Es mag schwer zu lesen sein, aber die Gleichungen sind explizit ausgeschrieben. Sie können in Numerical Recipes nachschlagen, einem klassischen Text, der in vielen Computercodesprachen (FORTRAN, C, C++, Java usw.) geschrieben wurde. Sie können die Mathematik von jedem dieser Elemente abrufen und an Python anpassen.
Wäre Computational Science ein besseres Zuhause für diese Frage?
Numerische Lösungen des ivp für das Kugelpendel sind jetzt im C++-Programm unter vixra.org/abs/1909.0201 . Dort gibt es zwei Ansätze: die Lösungen in Form von elliptischen Integralen erster und dritter Art zu schreiben und (als a check), um die gekoppelten Differentialgleichungen für die beiden Winkel mit einem Prädiktorcode bis zur vierten Ordnung der Ableitungen zu lösen.

Antworten (2)

Das Problem scheint zu sein, dass Sie die Schrittgröße beim Integrieren nicht rechtzeitig berücksichtigen. Dies sollte offensichtlich sein, wenn Sie Dinge wie tun

phi_v += phi_f

im Code. 1 Die Beschleunigung kann nicht einfach zur Geschwindigkeit addiert werden (die Einheiten stimmen nicht überein!). Die erwartete Beziehung ist,

A ϕ = D v ϕ D T Δ v ϕ Δ T v ϕ v ϕ ' + A ϕ Δ T
Wo v ϕ ' ist der vorherige Wert ist die Geschwindigkeit.

Was Sie tun sollten, ist die Verwendung der 4 Gleichungen (2 Positionen, 2 Geschwindigkeiten),

v = D X D T  Und  A = 1 M D F D T ,
Wo v = [ ϕ ˙ , θ ˙ ] T und ähnlich für X , und lösen Sie diese über einen Leap-Frog-Integrator wie Velocity Verlet . Da Sie jedoch eine geschwindigkeitsabhängige Beschleunigung haben (dh A = F ( X , v ) ), müssen Sie eine modifizierte Version des Integrators verwenden (worüber ich in dieser anderen Antwort von mir spreche ),

(1) A 1 ( T ) = berechnen aus  X ( T )  Und  v ( T ) (2) X ( T + Δ T ) = X ( T ) + v ( T ) Δ T + 1 2 A 1 ( T ) Δ T 2 (3) v ( T + Δ T ) = v ( T ) + A 1 ( T ) Δ T (4) A 2 ( T + Δ T ) = berechnen aus  X ( T + Δ T ) v ( T + Δ T ) (5) v ( T + Δ T ) = v ( T + Δ T ) + 1 2 ( A 2 ( T + Δ T ) A 1 ( T ) ) Δ T
die Sie dann einfach durchlaufen, bis Sie zufrieden sind (z. B. T T Ende ). Bereitgestellt Δ T klein genug ist, sollte dies einen stabileren Löser liefern als die Geschwindigkeits-Verlet-Integration allein.



1. OP hat den timestepsTerm zu den Gleichungen in Version 6 hinzugefügt ; Diese Antwort wurde vor dieser Bearbeitung gepostet.

Es sieht für mich so aus, als ob Sie versuchen, ein System gewöhnlicher Differentialgleichungen zu lösen, indem Sie die Lösung für kleine Schritte schätzen. Hab ich recht? Wenn ja, dann gibt es einiges zu beachten.

Erstens benötigen Sie eine gute Schätzung für den Ableitungsoperator, um den zukünftigen Zustand unter den Anfangsbedingungen zu approximieren. Diese Art von Problem wird als Anfangswertproblem (ivp) bezeichnet.

Da die Gleichung sowohl Zeitableitungen erster als auch zweiter Ordnung beinhaltet, besteht ein gemeinsamer Schritt darin, Impulsvariablen zu definieren und ein größeres System zu propagieren. Dies hilft, Fehler zu vermeiden, wenn die Gesamtzeit zunimmt. Ich habe dieses Problem bei Raytracing-Codes gesehen, und was ich vorschlage, ist so häufig, dass die meisten Leute niemals eine Gleichung zweiter Ordnung propagieren. Die Idee ist:

p_theta = d(theta)/dt

p_phi = d(phi)/dt

dann ist deine gleichung

d(p_theta)/dt = (p_phi)^2*cos(theta)*sin(theta) - g/l*sin(theta)

d(p_phi)/dt = -2*p_theta*p_phi*cot(theta)

plus die beiden Gleichungen, die die p definieren.

Ein einfacher Euler-Schritt würde implementiert als

p_theta(t0+dt) = p_theta(t0) + (d(p_theta)/dt)(t0)*dt
p_phi(t0+dt) = p_phi(t0) + (d(p_phi)/dt)(t0)*dt

plus die Gleichungen für Theta und Phi in den Definitionen von p.

Dies ist die typische Konfiguration. Nun, der Euler-Schritt ist sehr schlecht und wird niemals empfohlen. Sie sollten besser eine Methode höherer Ordnung wie RK4 oder RK5 (4) usw. mit Schrittgrößensteuerung implementieren.

Abgesehen davon ist die Verwendung von Winkeln manchmal ein Problem, da dies dazu führen kann, dass Sie bei einem Schritt den nächsten Wert nicht eindeutig bestimmen können, da das System singulär ist. In Luft- und Raumfahrtsimulationen verwenden sie Viertelionen, um dies zu beheben. Einzelheiten zur Mathematik oder Zipfel-Modellierung und -Simulation der Dynamik von Luft- und Raumfahrtfahrzeugen finden Sie in Goldstein Classical Mechanics. Ich denke, Sie brauchen diese Maschinerie jetzt nicht. Sie müssen die Gleichungen richtig schreiben und einen einfachen Schrittalgorithmus ausprobieren, bevor Sie zu anspruchsvoll werden. Ich würde denken, dass Python ein ODE-Solver-Paket hat, sodass Sie kein eigenes schreiben müssen, sondern nur richtig einrichten und aufrufen. Ich hoffe das hilft.

Ich habe hochgestimmt. Ihre Antwort war sehr hilfreich. Ich werde mir einfach viel Zeit nehmen, um die Informationen zu verarbeiten und mich in die neuen Konzepte einzulesen, die mir völlig unbekannt waren. Nochmals vielen Dank für Ihre Hilfe!