Implementación de un péndulo esférico

Estoy tratando de implementar un péndulo esférico. El Lagrangiano (que aún no he entendido completamente) basado en yo , θ y φ tomados de esta página dan como resultado las ecuaciones:

θ ¨ = φ ˙ 2 pecado θ porque θ gramo yo pecado θ φ ¨ = 2 θ ˙ φ ˙ cuna θ

estoy tratando θ ¨ como la aceleración y de θ ˙ como la velocidad de θ . ¿Es esto correcto? Ahora, cada paso del movimiento se implementa de la siguiente manera (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

Esto funciona siempre que phi_v( ϕ ˙ ) es 0 o cercano a 0.

péndulo

Si ϕ ˙ inicial > 0 , el movimiento es erróneo.

movimiento de péndulo errático

Mis valores iniciales son

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

Después de algunas iteraciones, el código produce un math range erroras phi_vque se vuelve demasiado grande. Encontré esta pregunta que podría explicar el error de redondeo matemático.

Estoy usando 60 muestras por segundo, porque habrá interacción en tiempo real. Los valores aproximados estarán totalmente bien, pero no puedo creer que el estado actual sea simplemente un error de aproximación.

¿Cómo puedo corregir mi código para simular el péndulo esférico?

Estás hablando de aceleraciones, no de fuerzas. Ya no debería haber una masa involucrada.
¿Has probado valores mucho más grandes de velocidad angular inicial? Podría ser que la pelota esté casi, pero no del todo, golpeando el centro en estas imágenes.
En su código, por ϕ ¨ , ¿por qué hay un 4 en lugar de un 2 , y por qué hay un pecado θ ¿término?
bien, pero ¿por qué el pecado θ ¿término? Siento que eso marcaría una gran diferencia si lo divides. Cuando θ = 0 tendrías una aceleración infinita.
Por que es ϕ ˙ + = ϕ ¨ ? estas asumiendo Δ t = 1 ??
@KyleKanos Iba a preguntar sobre esto a continuación. El problema también podría ser pasos demasiado grandes en el tiempo. Esta no es una muy buena manera de "integrar" las ecuaciones.
@AaronStevens Me siento razonablemente seguro de que este es el verdadero problema
Utiliza un "método de integración" discreto, ¿cómo controla el tamaño del paso? Intente implementar el método de integración RK4.
Podría haber varios problemas. No voy a separar el código, pero ofrezco algunos consejos. Si no está utilizando un buen solucionador de ODE y regulando el tamaño de su paso, esto arruinará las cosas. Los solucionadores implícitos suelen ser universalmente estables, pero son más difíciles de codificar. No estoy seguro de si la variable del ángulo es un problema, pero en la dinámica de la actitud uno usa cuartos en lugar de ángulos para evitar resultados erróneos. Hay ángulos especiales donde el sistema no se puede invertir y la dirección del siguiente paso se vuelve ambigua. En cierto sentido, está resolviendo la actitud de su péndulo.
@Aaron He corregido la ecuación y he incluido los valores al final de la pregunta. Sin embargo, el movimiento en la segunda imagen se ve muy extraño. ¿Seguiría siendo probable que esto suceda debido a intervalos de tiempo demasiado grandes? Parece que hay errores fundamentales aquí que puedo pensar en resolver RK.
@ggcg Entonces, dado que no estoy usando ningún solucionador ODE, hacer los cálculos en Quaternions/DirectionVectors eliminaría los problemas actuales. Copié los cálculos de esa página, porque asumí que incluso mis pasos de tiempo no causarían estos errores gigantescos.
@Leander, debe estar usando un solucionador ODE, ya sea que lo sepa o no. Si todo lo que está haciendo es agregar un acc dt a la velocidad y luego v dt al ángulo, entonces está haciendo un paso de Euler, que se sabe que es muy pobre. Para la EDO de segundo orden, típicamente creamos un nuevo grado de libertad p = dx/dt y resolvemos para x y p en cada paso.
@Leander, ¿estás dividiendo por el paso de tiempo para obtener la velocidad?
Sí, parece que estoy haciendo todas estas cosas mal. Ahora me doy cuenta de cómo solucionar este último y por qué no funciona. Al principio, eliminé esa línea por completo y simplemente cambié la "longitud" de la cadena.
@ggcg *... cree un nuevo grado de libertad p = dx/dt y resuelva x y p en cada paso. * ¿Podría ampliar eso, por favor? ¿Con un enlace, respuesta o palabras clave de búsqueda?
@Leander, mira mi respuesta. Puede ser difícil de leer, pero las ecuaciones están explícitamente escritas. Puedes buscar en Recetas Numéricas, un texto clásico escrito en muchos lenguajes de código informático (FORTRAN, C, C++, Java, etc). Puede obtener las matemáticas de cualquiera de estos y adaptarlas a Python.
¿ Sería la ciencia computacional un mejor hogar para esta pregunta?
Las soluciones numéricas del ivp para el péndulo esférico ahora se encuentran en el programa C++ en vixra.org/abs/1909.0201 . Hay dos enfoques allí: escribir las soluciones en términos de integrales elípticas de primer y tercer tipo, y (como check) para resolver las ecuaciones diferenciales acopladas para los dos ángulos con un código predictor hasta el cuarto orden de las derivadas.

Respuestas (2)

El problema parece ser que no está teniendo en cuenta el tamaño del paso a tiempo al integrar. Esto debería ser obvio cuando estás haciendo cosas como

phi_v += phi_f

en el código. 1 La aceleración no se puede simplemente sumar a la velocidad (¡las unidades no coinciden!). La relación esperada es,

a ϕ = d v ϕ d t Δ v ϕ Δ t v ϕ v ϕ + a ϕ Δ t
dónde v ϕ es el valor anterior es la velocidad.

Lo que deberías estar haciendo es usar las 4 ecuaciones (2 posiciones, 2 velocidades),

v = d X d t  y  a = 1 metro d F d t ,
dónde v = [ ϕ ˙ , θ ˙ ] T y de manera similar para X , y resuélvalos a través de un integrador de salto de rana, como la velocidad Verlet . Sin embargo, dado que tiene una aceleración dependiente de la velocidad (es decir, a = F ( X , v ) ), necesita usar una versión modificada del integrador (del que hablo en esta otra respuesta mía ),

(1) a 1 ( t ) = calcular desde  X ( t )  y  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 ) = calcular desde  X ( t + Δ t ) v ( t + Δ t ) (5) v ( t + Δ t ) = v ( t + Δ t ) + 1 2 ( a 2 ( t + Δ t ) a 1 ( t ) ) Δ t
que luego simplemente recorre hasta que esté satisfecho (por ejemplo, t t fin ). Proporcionó Δ t es lo suficientemente pequeño, esto debería proporcionar un solucionador más estable que la integración de Verlet de velocidad sola.



1. OP agregó el timestepstérmino a las ecuaciones en la versión 6 ; esta respuesta se publicó antes de esa edición.

Me parece que estás tratando de resolver un sistema de ecuaciones diferenciales ordinarias estimando la solución en pequeños pasos. ¿Estoy en lo correcto? Si es así, hay una serie de cosas a considerar.

Primero, debe tener una buena estimación del operador derivado para aproximar el estado futuro dadas las condiciones iniciales. Este tipo de problema se llama problema de valor inicial (ivp).

Dado que la ecuación involucra derivadas temporales de primer y segundo orden, un paso común es definir las variables de impulso y propagar un sistema más grande. Esto ayudará a evitar errores a medida que aumenta el tiempo total. He visto ese problema en los códigos de trazado de rayos y lo que sugiero es tan común que la mayoría de las personas nunca propagan una ecuación de segundo orden. La idea es:

p_theta = d(theta)/dt

p_phi = d(phi)/dt

entonces tu ecuacion es

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)

más las dos ecuaciones que definen las p.

Un simple paso de Euler se implementaría como,

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

más las ecuaciones para theta y phi en las definiciones de p.

Esta es la configuración típica. Ahora, el paso de Euler es muy pobre y nunca recomendado. Sería mejor implementar un método de orden superior como RK4 o RK5 (4), etc., con control de tamaño de paso.

Aparte de eso, el uso de ángulos a veces es un problema, ya que lleva a la posibilidad de que en algún paso no pueda determinar de manera única el siguiente valor debido a que el sistema es singular. En las simulaciones aeroespaciales usan cuarterones para arreglar esto. Puede consultar Goldstein Classical Mechanics para obtener detalles sobre las matemáticas o Zipfel Modeling and Simulation of Aerospace Vehicle Dynamics. Creo que no necesitas esta maquinaria en este momento. Debe escribir las ecuaciones correctamente y probar un algoritmo de paso simple antes de volverse demasiado sofisticado. Creo que Python tiene un paquete de resolución de ODE, por lo que no necesita escribir el suyo propio, solo configure correctamente y llame. Espero que eso ayude.

Voté a favor. Tu respuesta fue muy útil. Me tomaré mucho tiempo para procesar la información y leer los nuevos conceptos, con los que no estaba familiarizado. ¡Gracias de nuevo por tu ayuda!