Simulación de péndulo doble

PythonPythonBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

El péndulo doble es un problema clásico en física y matemáticas. Involucra dos péndulos unidos entre sí, y el movimiento del segundo péndulo está afectado por el movimiento del primero. En este laboratorio, usaremos Python y Matplotlib para simular el movimiento de un péndulo doble.

Consejos sobre la VM

Una vez que se haya iniciado la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.

A veces, es posible que tenga que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.

Si tiene problemas durante el aprendizaje, no dude en preguntar a Labby. Deje comentarios después de la sesión y lo resolveremos rápidamente para usted.

Importar las bibliotecas necesarias

Comenzaremos importando las bibliotecas necesarias para nuestra simulación.

from collections import deque
import matplotlib.pyplot as plt
import numpy as np
from numpy import cos, sin
import matplotlib.animation as animation

Establecer parámetros

A continuación, definiremos los parámetros para nuestra simulación. Estos parámetros incluyen la aceleración debida a la gravedad, la longitud y la masa de cada péndulo, y el intervalo de tiempo para la simulación.

G = 9.8  ## aceleración debida a la gravedad, en m/s^2
L1 = 1.0  ## longitud del péndulo 1 en m
L2 = 1.0  ## longitud del péndulo 2 en m
L = L1 + L2  ## longitud máxima del péndulo combinado
M1 = 1.0  ## masa del péndulo 1 en kg
M2 = 1.0  ## masa del péndulo 2 en kg
t_stop = 2.5  ## cuántos segundos simular
history_len = 500  ## cuántos puntos de trayectoria mostrar

Definir la función de derivadas

Definiremos una función que calcula las derivadas del sistema en cualquier momento dado. Esta función toma el estado actual del sistema (los ángulos y velocidades angulares de cada péndulo) y devuelve las derivadas de esos valores.

def derivs(t, state):
    dydx = np.zeros_like(state)

    dydx[0] = state[1]

    delta = state[2] - state[0]
    den1 = (M1+M2) * L1 - M2 * L1 * cos(delta) * cos(delta)
    dydx[1] = ((M2 * L1 * state[1] * state[1] * sin(delta) * cos(delta)
                + M2 * G * sin(state[2]) * cos(delta)
                + M2 * L2 * state[3] * state[3] * sin(delta)
                - (M1+M2) * G * sin(state[0]))
               / den1)

    dydx[2] = state[3]

    den2 = (L2/L1) * den1
    dydx[3] = ((- M2 * L2 * state[3] * state[3] * sin(delta) * cos(delta)
                + (M1+M2) * G * sin(state[0]) * cos(delta)
                - (M1+M2) * L1 * state[1] * state[1] * sin(delta)
                - (M1+M2) * G * sin(state[2]))
               / den2)

    return dydx

Establecer las condiciones iniciales e integrar la EDO

Ahora estableceremos las condiciones iniciales para nuestra simulación. Estableceremos los ángulos y velocidades angulares iniciales de cada péndulo, así como el intervalo de tiempo para la simulación. Luego, integrabaremos la EDO usando el método de Euler para obtener la posición y la velocidad de cada péndulo en cada paso de tiempo.

## create a time array from 0..t_stop sampled at 0.02 second steps
dt = 0.01
t = np.arange(0, t_stop, dt)

## th1 and th2 are the initial angles (degrees)
## w10 and w20 are the initial angular velocities (degrees per second)
th1 = 120.0
w1 = 0.0
th2 = -10.0
w2 = 0.0

## initial state
state = np.radians([th1, w1, th2, w2])

## integrate the ODE using Euler's method
y = np.empty((len(t), 4))
y[0] = state
for i in range(1, len(t)):
    y[i] = y[i - 1] + derivs(t[i - 1], y[i - 1]) * dt

Calcular la posición de cada péndulo

Ahora usaremos la posición y la velocidad de cada péndulo en cada paso de tiempo para calcular las coordenadas x e y de cada péndulo.

x1 = L1*sin(y[:, 0])
y1 = -L1*cos(y[:, 0])

x2 = L2*sin(y[:, 2]) + x1
y2 = -L2*cos(y[:, 2]) + y1

Configurar la gráfica

Ahora configuraremos la gráfica para nuestra simulación. Crearemos una figura con límites x e y iguales a la longitud máxima del péndulo, estableceremos la relación de aspecto para que sea igual y agregaremos una cuadrícula.

fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(autoscale_on=False, xlim=(-L, L), ylim=(-L, 1.))
ax.set_aspect('equal')
ax.grid()

Definir la función de animación

Definiremos una función que animará el movimiento del péndulo doble. Esta función tomará el paso de tiempo actual y lo usará para actualizar la posición de cada péndulo. También actualizará la trayectoria del segundo péndulo.

line, = ax.plot([], [], 'o-', lw=2)
trace, = ax.plot([], [], '.-', lw=1, ms=2)
time_template = 'time = %.1fs'
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
history_x, history_y = deque(maxlen=history_len), deque(maxlen=history_len)

def animate(i):
    thisx = [0, x1[i], x2[i]]
    thisy = [0, y1[i], y2[i]]

    if i == 0:
        history_x.clear()
        history_y.clear()

    history_x.appendleft(thisx[2])
    history_y.appendleft(thisy[2])

    line.set_data(thisx, thisy)
    trace.set_data(history_x, history_y)
    time_text.set_text(time_template % (i*dt))
    return line, trace, time_text

Crear la animación

Ahora crearemos la animación usando la función FuncAnimation de Matplotlib.

ani = animation.FuncAnimation(
    fig, animate, len(y), interval=dt*1000, blit=True)
plt.show()

Resumen

En este laboratorio, usamos Python y Matplotlib para simular el movimiento de un péndulo doble. Configuramos los parámetros de nuestra simulación, definimos una función para calcular las derivadas del sistema, integramos la EDO usando el método de Euler, calculamos la posición de cada péndulo en cada paso de tiempo y creamos una animación del movimiento del péndulo doble.