Моделирование подпружиненного маятника на вращающемся диске

Я хочу написать на Python симуляцию, аналогичную описанной в Моделирование маятника, висящего на вращающемся диске.

Но я хочу, чтобы система была подпружинена. Поэтому вместо того, чтобы масса висела на нити, я хочу, чтобы масса висела на вращающейся пружине. Я попытался собрать ОДУ, но расчет занял целую вечность:

import sympy as sp
from IPython.display import display

R = sp.symbols('R')
omega = sp.symbols('omega')
t = sp.symbols('t')
phi = sp.Function('phi')(t)
theta = sp.Function('theta')(t)
s = sp.Function('s')(t)
L = sp.symbols('L')
m = sp.symbols('m')
k = sp.symbols('k')
g = sp.symbols('g')

x = R*sp.cos(omega*t)+(L+s)*(sp.sin(theta)*sp.cos(phi))
y = R*sp.sin(omega*t)+(L+s)*(sp.sin(theta)*sp.sin(phi))
z = -(L+s)*sp.cos(theta)

xs = sp.diff(x,t)
ys = sp.diff(y,t)
zs = sp.diff(z,t)

v = xs**2 + ys**2 + zs**2
Ekin = 0.5*m*v
Epot = g*(L+s)*sp.cos(theta)+0.5*k*s**2

L = Ekin + Epot

#display(L)

ELTheta = sp.diff(sp.diff(L,sp.Derivative(theta,t)), t) + sp.diff(L,theta)
ELPhi = sp.diff(sp.diff(L,sp.Derivative(phi,t)), t) + sp.diff(L,phi)
ELs = sp.diff(sp.diff(L,sp.Derivative(s,t)), t) + sp.diff(L,s)

Eq1 = sp.Eq(ELTheta,0)
Eq2 = sp.Eq(ELPhi,0)
Eq3 = sp.Eq(ELs,0)

LGS = sp.solve((Eq1,Eq2,Eq3),(sp.Derivative(theta,t,2),sp.Derivative(phi,t,2),sp.Derivative(s,t,2)))

thetadd = sp.simplify(LGS[sp.Derivative(theta,t,2)])
phidd = sp.simplify(LGS[sp.Derivative(phi,t,2)])
sdd = sp.simplify(LGS[sp.Derivative(s,t,2)])

Не знаю, правильно ли я выбрал исходное состояние. Есть ли более простой и быстрый способ вычислить эту или другую формулу задачи, которая бы ее упростила?

Я знаю, что ответ уже есть. Но подождите, прежде чем назначать награду. Возможно, я смогу найти время, чтобы показать вам, как использовать SymPy для вычисления уравнений движения для любой системы.

Davide_sd 18.06.2024 09:43

@Davide_sd Хорошо, мне интересно, что ты придумаешь

Mo711 18.06.2024 15:29

пожалуйста, назначьте награду. К сожалению, я не могу найти время, чтобы закодировать эту задачу :( Кстати, вы, кажется, интересуетесь механикой, возможно, вы захотите изучить модуль sympy.physics.mechanics, чтобы сгенерировать уравнения движения. Однако будьте осторожны: это глубокий кролик дыра, для полного понимания которой требуется значительное количество времени.

Davide_sd 19.06.2024 23:52
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
3
235
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как только вы устраните ограничение маятника фиксированной длины, вероятно, будет проще решить эту проблему в декартовых координатах, используя 2-й закон Ньютона (F = ma), а не с помощью уравнений движения Лагранжа.

Рассмотрим пружину естественной длины L и жесткости k, один конец которой прикреплен к точке на краю диска радиуса R, вращающегося с угловой скоростью ω, а другой удерживает шарик массы m.

Точка привязки на диске имеет координаты, зависящие от времени.

У Боба есть координаты

На боб действуют две силы: сила упругости пружины величиной

и его вес

Уравнение движения просто

или

где n — единичный вектор направления троса, а g — ускорение свободного падения.

Обратите внимание, что здесь нет механизма рассеивания энергии, поэтому избегайте резонанса (т. е. собственная круговая частота пружины sqrt(k/m) не должна быть близка к круговой частоте омега точки вращения). .

Чтобы получить стабильную, а не очень «прыгучую» орбиту, см. основной код ниже.

Код:

import math
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from scipy.integrate import solve_ivp
from mpl_toolkits.mplot3d import Axes3D

g = 9.81                                                             # acceleration due to gravity (m/s^2)
gravity = np.array( [ 0.0, 0.0, -g ] )

def plot_animation( t, qx, qy, qz, x, y, z ):
   plotInterval = 1
   fig = plt.figure( figsize=(4,4) )
   ax = fig.add_subplot(111, projection='3d' )
   ax.view_init(30, 45)
   ax.set_xlim( -2.0, 2.0 );   ax.set_ylim( -2.0, 2.0 );   ax.set_aspect('equal')

   ax.plot( qx, qy, qz, 'k' )                                        # tether point
   a = ax.plot( [qx[0],x[0]], [qy[0],y[0]], [qz[0],z[0]], 'g' )      # pendulum string
   b = ax.plot( [x[0]], [y[0]], [z[0]], 'ro' )                       # pendulum bob
   def animate( i ):                                                 # update anything that has changed
      a[0].set_data_3d( [qx[i],x[i]], [qy[i],y[i]], [qz[i],z[i]] )   
      b[0].set_data_3d( [x[i]], [y[i]], [z[i]] )
   ani = animation.FuncAnimation( fig, animate, interval=4, frames=len( t ) )
   plt.show()
#  ani.save( "demo.gif", fps=50 )


def deriv( t, Y, R, omega, L, k, m ):
    x, v = Y[0:3], Y[3:6]                                                      # bob position and velocity (vectors)
    q = np.array( [ R*math.cos(omega*t), R*math.sin(omega*t), 0.0 ] )          # position vector of tether
    spring = q - x                                                             # vector from bob to tether
    length = np.linalg.norm( spring )                                          # stretched length of spring                                             
    unitVector = spring / length                                               # direction of elastic force
    extension = length - L                                                     # extension of spring
    a = ( k / m ) * extension * unitVector + gravity                           # F combines elastic force and gravity
    return np.hstack( ( v, a ) )                                               # return velocity and acceleration


R = 0.5            # radius of disk (m)
omega = 2.0        # angular velocity of disk (rad/s)
L = 1.0            # natural length of spring (m)
k = 20.0           # stiffness of spring (N/m)             # warning: avoid resonance!
m = 2.0            # mass (kg)
Y0 = np.array( [ R, 0.0, -L, 0.0, 0.0, 0.0 ] )                                 # initial position and velocity

period = 2 * np.pi / omega
tmax = 5 * period
solution = solve_ivp( deriv, [0, tmax], Y0, args=(R,omega,L,k,m), rtol=1.0e-6, dense_output=True )

t = np.linspace( 0, tmax, 1000 )
Y = solution.sol( t )

# Position of bob
x = Y[0,:]
y = Y[1,:]
z = Y[2,:]

# Position of tether on disk
qx = R * np.cos( omega * t )
qy = R * np.sin( omega * t )
qz = np.zeros_like( qx )

plot_animation( t, qx, qy, qz, x, y, z )

Можно придать качанию маятника начальное положение и скорость, которые позволят ему перейти на устойчивую орбиту (постоянное движение по кругу, синхронно с тросом на диске). Если вы установите центростремительную силу, равную горизонтальной составляющей силы упругости, а вес, равный вертикальной составляющей силы упругости, то вы сможете одновременно решить пару уравнений для тангенса угла к вертикали и растяжения пружины и тем самым обеспечьте соответствующие начальные условия для Y0. Попробуйте заменить инициализацию Y0 следующими строками. Вероятно, существуют также синхронные решения, в которых боб отстает от точки привязки, но я их не исследовал.

# "Equilibrium motion" - moves in a circle, synchronised with the tether
t, e = 0, 0                  # tan(theta) and extension
w2g = omega ** 2 / g
mgk = m * g / k
for _ in range( 100 ):
     c = 1 / math.sqrt( 1 + t*t );   s = t * c        # cosine and sine
     t = w2g * ( R + (L+e) * s )
     e = mgk / c
     # print( t, e )
x = R + (L+e) * s
z =   - (L+e) * c
Y0 = np.array( [ x, 0.0, z, 0.0, x * omega, 0.0 ] )

Можно ли как-нибудь добавить к этому вязкое демпфирование? Я имею в виду типа F =x' * b

Mo711 18.06.2024 15:48

Если вы хотите, вы можете добавить любой коэффициент демпфирования к силе или ускорению. В данный момент вам не нужен затухающий член, пока вы (а) не достигнете резонансной частоты; и (б) не начинайте с амплитуды, достаточно большой, чтобы в какой-то момент движения вызвать пружину нулевой длины.

lastchance 18.06.2024 15:53

Наверное, я попал в резонансную частоту. Добавление демпфирования к ускорению будет завершено с помощью вязкостного демпфирования: curren_a-(x'*b)/m, это правильно?

Mo711 18.06.2024 16:04

Если вам нужна сила демпфирования, добавьте эту силу, разделенную на массу, к ускорению. Да, вычитание (коэффициент демпфирования) умноженного на скорость/массу из ускорения a было бы правильным для модели линейного демпфирования. Вам придется сказать мне, какие m, k и omega вы использовали, чтобы установить, является ли резонанс проблемой.

lastchance 18.06.2024 16:15

Но разве пружина когда-нибудь ослабевает? Потому что должна быть точка, в которой он стремится к равновесию.

Mo711 19.06.2024 08:53

Пружина не может увлажниться. Идеальный осциллятор с массовой пружиной будет вечно колебаться вокруг точки равновесия, если вы сместите его из этой точки (или придадите ему начальную скорость).

lastchance 19.06.2024 09:15

@Mo711, Mo711, я добавил внизу поста несколько строк, которые позволяют вам придать маятнику начальное положение и скорость, которые позволяют ему двигаться по стабильной орбите (круг, синхронно с тросом на кольце).

lastchance 19.06.2024 17:38

Другие вопросы по теме