Essays.club - Получите бесплатные рефераты, курсовые работы и научные статьи
Поиск

Моделирование «Двойной маятник»

Автор:   •  Август 3, 2023  •  Контрольная работа  •  2,462 Слов (10 Страниц)  •  78 Просмотры

Страница 1 из 10

Министерство науки и высшего образования Российской Федерации

федеральное государственное автономное образовательное учреждение высшего образования

«НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ ИТМО»

Моделирование

по теме «Двойной маятник» 

по дисциплине «Физика»

Авторы: Шашкевич Эльфрида, Флийчук Михаил, Мирошников Егор

Факультет: ФИТиП (2 курс)

Группа: М32101

Преподаватель: Хуснутдинова Наира Рустемовна

[pic 1]

Санкт-Петербург

2022

Моделирование «Двойной маятник»

Цель: создание модели двойного маятника и демонстрация его хаотичного поведения.

В качестве инструмента был использован язык программирования Python.

Описание:

Маятник состоит из двух невесомых стержней и двух материальных точек. Он, как правило, вращается вокруг горизонтальной оси так, что оба подвеса лежат в одной плоскости и составляют с вертикалью некоторые углы. Такой маятник, движущийся в одной плоскости, имеет две степени свободы. Фактически маятник состоит из двух круговых математических маятников одинаковой или разной длины и массы, причем второй маятник подвешен к грузу первого. Если двойной маятник с одинаковыми подвесами и грузами вывести из равновесия произвольным образом и предоставить самому себе, то каждый из грузов будет совершать довольно сложное движение, в котором трудно уловить какую-либо закономерность.

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

Код с комментариями:

  • В данной реализации используется модуль tkinter из библиотеки TK. Даёт возможность показывать холст с графическим рисунком, показывает программу с оконным интерфейсом.
  • Данный код был написан нашей командной работой.

import tkinter as tk
import random
from math import pi, sin, cos

G =
9.81


class DoublePendulum():
   
# конструктор класса отвечает за инициализацию переменных и ползунков
   
def __init__(self, mass_1, mass_2, length_1, length_2, theta_1, theta_2, delta):
       
self.mass_1 = mass_1
       
self.mass_2 = mass_2
       
self.length_1 = length_1
       
self.length_2 = length_2
       
self.theta_1 = theta_1
       
self.theta_2 = theta_2
       
self.delta = delta
       
self.deriv_theta_1 = 0
       
self.deriv_theta_2 = 0

       
self.frame = tk.Frame(root)
       
self.scl_length_1 = tk.Scale(self.frame, from_=15, to=165, length=300, tickinterval=50,
                                   
label="Length of Pendulum 1", orient=tk.HORIZONTAL)
       
self.scl_length_1.set(length_1)
       
self.scl_length_2 = tk.Scale(self.frame, from_=15, to=165, length=300, tickinterval=50,
                                   
label="Length of Pendulum 2", orient=tk.HORIZONTAL)
       
self.scl_length_2.set(length_1)
       
self.scl_mass_1 = tk.Scale(self.frame, from_=15, to=165, length=300, tickinterval=50,
                                 
label="Mass of the first pendulum", orient=tk.HORIZONTAL)
       
self.scl_mass_1.set(mass_1)
       
self.scl_mass_2 = tk.Scale(self.frame, from_=15, to=165, length=300, tickinterval=50,
                                 
label="Mass of the second pendulum", orient=tk.HORIZONTAL)
       
self.scl_mass_2.set(mass_2)

       
self.grid_widgets()

   
def grid_widgets(self):
       
# отображение элементов в окне
       
self.frame.grid(row=0, column=1, rowspan=3)
       
self.scl_length_1.grid(row=0, column=0, padx=10, pady=5)
       
self.scl_length_2.grid(row=1, column=0, padx=10, pady=5)
       
self.scl_mass_1.grid(row=2, column=0, padx=10, pady=5)
       
self.scl_mass_2.grid(row=3, column=0, padx=10, pady=5)

   
def update_pendulum(self, pivot_x, pivot_y):
       
# расчёты по формулам (формулы взяты отсюда https://www.myphysicslab.com/pendulum/double-pendulum-en.html)
       
self.length_1 = self.scl_length_1.get()
       
self.length_2 = self.scl_length_2.get()
       
self.mass_1 = self.scl_mass_1.get()
       
self.mass_2 = self.scl_mass_2.get()

       
# Компоненты для первого маятника
       
comp_1 = -G * (2 * self.mass_1 + self.mass_2) * sin(self.theta_1) - self.mass_2 * G * sin(
           
self.theta_1 - 2 * self.theta_2)
       comp_2 =
2 * sin(self.theta_1 - self.theta_2) * self.mass_2 * (
               
self.deriv_theta_2 ** 2 * self.length_2 + self.deriv_theta_1 ** 2 * self.length_1 * cos(
           
self.theta_1 - self.theta_2))
       comp_3 =
self.length_1 * (
               
2 * self.mass_1 + self.mass_2 - self.mass_2 * cos(2 * self.theta_1 - 2 * self.theta_2))
       sec_deriv_theta_1 = (comp_1 - comp_2) / comp_3

       
# Компоненты для второго маятника
       
comp_1 = 2 * sin(self.theta_1 - self.theta_2)
       comp_2 =
self.deriv_theta_1 ** 2 * self.length_1 * (self.mass_1 + self.mass_2) + G * (
               
self.mass_1 + self.mass_2) * cos(
           
self.theta_1) + self.deriv_theta_2 ** 2 * self.length_2 * self.mass_2 * cos(self.theta_1 - self.theta_2)
       comp_3 =
self.length_2 * (
               
2 * self.mass_1 + self.mass_2 - self.mass_2 * cos(2 * self.theta_1 - 2 * self.theta_2))
       sec_deriv_theta_2 = (comp_1 * comp_2) / comp_3

       
# изменение углов маятников
       
self.deriv_theta_1 += sec_deriv_theta_1 * self.delta
       
self.deriv_theta_2 += sec_deriv_theta_2 * self.delta
       
self.theta_1 += self.deriv_theta_1 * self.delta
       
self.theta_2 += self.deriv_theta_2 * self.delta

       
# изменение координат оснований маятников
       
pend_1_x = pivot_x + self.length_1 * sin(self.theta_1)
       pend_1_y = pivot_y +
self.length_1 * cos(self.theta_1)
       pend_2_x = pend_1_x +
self.length_2 * sin(self.theta_2)
       pend_2_y = pend_1_y +
self.length_2 * cos(self.theta_2)

       
return pend_1_x, pend_1_y, pend_2_x, pend_2_y


class MainApplication(tk.Tk):
   
# класс отвечающий за графическое отображение маятника на экране
   
def __init__(self, master, double_pendulum_params):
       
self.master = master
       
self.frm_upper = tk.Frame(self.master)
       
self.btn_double = tk.Button(self.frm_upper, text="Double Pendulum", state=tk.DISABLED,
                                   
command=lambda: self.switch(0))
       
self.frm_canvas = tk.Frame(self.master)
       
self.canvas = tk.Canvas(self.frm_canvas, height=700, width=700, bg="black")
       
self.frm_lower = tk.Frame(self.master)

       
# инициализация кнопок внизу окна
       
self.chk_trace = tk.Checkbutton(self.frm_lower, text="Trace", command=self.start_trace)
       
self.btn_clear = tk.Button(self.frm_lower, text="Clear Trace", command=self.clear_trace)
       
self.btn_pause = tk.Button(self.frm_lower, text="Pause", width=7, command=self.pause)

       
self.double_pendulum = DoublePendulum(**double_pendulum_params)
       
self.pivot_x = int(self.canvas['width']) / 2  # Расположение осей маятников на экране
       
self.pivot_y = 300
       
self.btn_randomize = self.btn_randomize = tk.Button(self.double_pendulum.frame,
                                                           
text="Randomize (Initial Theta)", command=self.randomize)
       
self.bool_trace = False
       
self.bool_pause = False
       
self.all_traces = []
       
self.curr_trace = []
       
self.grid_pack_widgets()
       
self.draw_double_pendulum()

   
def grid_pack_widgets(self):
       
# инициализация кнопок взаимодействия
       
self.frm_upper.grid(row=0, column=0)
       
self.frm_canvas.grid(row=1, column=0)
       
self.frm_lower.grid(row=2, column=0)
       
self.btn_double.pack(side=tk.LEFT)
       
self.canvas.pack()
       
self.chk_trace.pack(side=tk.LEFT)
       
self.btn_clear.pack(side=tk.LEFT)
       
self.btn_pause.pack(side=tk.LEFT)
       
self.btn_randomize.grid(row=4, column=0, padx=10, pady=5)

   
def draw_double_pendulum(self):
       
# прорисовка траекторий
       
if self.bool_pause:
           tk.after_id =
self.canvas.after(15, self.draw_double_pendulum)
       
else:
           
self.canvas.delete("pendulum")
           
self.canvas.delete("line")
           
self.canvas.delete("trace")
           
self.double_motion()
           tk.after_id =
self.canvas.after(15, self.draw_double_pendulum)

   
def double_motion(self):
       
# инициализация рёбер (их движение)
       
(x, y, x2, y2) = self.double_pendulum.update_pendulum(self.pivot_x, self.pivot_y)
       radius =
10
       
self.canvas.create_oval(x - radius, y - radius, x + radius, y + radius, tag="pendulum", fill="red")
       
self.canvas.create_oval(x2 - radius, y2 - radius, x2 + radius, y2 + radius, tag="pendulum", fill="white")

       
self.canvas.create_line(self.pivot_x, self.pivot_y, x, y, width=3, tag="line", fill="red")
       
self.canvas.create_line(x, y, x2, y2, width=3, tag="line", fill="white")

       
if self.bool_trace:
           
self.curr_trace.append((x2, y2, x2, y2))
       
if self.all_traces:
           
for trace in self.all_traces:
               
self.canvas.create_line(trace, tag="trace", fill="red")
       
if self.curr_trace:
           
self.canvas.create_line(self.curr_trace, tag="trace", fill="red")

   
def start_trace(self):
       
# начало прорисовки
       
if self.curr_trace:
           
self.all_traces.append(self.curr_trace)
       
self.curr_trace = []
       
self.bool_trace = not self.bool_trace

   
def clear_trace(self):
       
# удаление прорисовки
       
self.curr_trace = []
       
self.all_traces = []
       
self.canvas.delete('trace')

   
def pause(self):
       
# пауза
       
if self.bool_pause:
           
self.btn_pause['text'] = "Pause"
           
self.bool_pause = False
       else
:
           
self.btn_pause['text'] = "Resume"
           
self.bool_pause = True

   def
randomize(self):
       
# генерация случайного расположения маятника
       
if self.curr_trace:
           
self.all_traces.append(self.curr_trace)
       
self.curr_trace = []
       
self.double_pendulum.theta_1 = random.uniform(-pi, pi)
       
self.double_pendulum.deriv_theta_1 = 0
       
self.double_pendulum.theta_2 = random.uniform(-pi, pi)
       
self.double_pendulum.deriv_theta_2 = 0

# начальные параметры для запуска по умолчанию
if __name__ == '__main__':
   dub_pend_params = {
       
'length_1': 165,
       
'length_2': 165,
       
'mass_1': 5,
       
'mass_2': 5,
       
'theta_1': pi / 2,
       
'theta_2': 3 * pi / 4,
       
'delta': .1,

   
}

   root = tk.Tk()
   root.title(
"Pendulum Simulation")
   root.resizable(
False, False)
   root.columnconfigure(
1, weight=1)
   app = MainApplication(root
, dub_pend_params)
   root.mainloop()

...

Скачать:   txt (16.5 Kb)   pdf (151 Kb)   docx (353.6 Kb)  
Продолжить читать еще 9 страниц(ы) »
Доступно только на Essays.club