Редактирование: Колебания с двумя степенями свободы
Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 2: | Строка 2: | ||
Маятник с двумя степенями свободы | Маятник с двумя степенями свободы | ||
− | Тяжелая материальная точка массы <math>m</math> подвешена на невесомой пружине жесткости <math> | + | Тяжелая материальная точка массы <math>m</math> подвешена на невесомой пружине жесткости <math>с</math> и длины <math>l_0</math> в ненапряженном состоянии. |
− | + | Уравнения движения системы будут выглядеть так: | |
::<math> | ::<math> | ||
\ddot{x} + \frac{g}{L} x = 0 \\ | \ddot{x} + \frac{g}{L} x = 0 \\ | ||
Строка 13: | Строка 13: | ||
− | + | Колебания выглядят так: | |
− | Скачать [[Медиа: | + | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Pogodina/Koleb2mayatnik/new1.html |width=1000 |height=750 |border=0 }} |
+ | |||
+ | Скачать [[Медиа:Shock_absorbers.zip|Shock_absorbers.zip]]. | ||
<div class="mw-collapsible mw-collapsed" style="width:100%" > | <div class="mw-collapsible mw-collapsed" style="width:100%" > | ||
− | '''Текст программы на языке JavaScript (разработчик [[ | + | '''Текст программы на языке JavaScript (разработчик [[Богданов Дмитрий]], код основан на программе [[Цветков Денис]]):''' <div class="mw-collapsible-content"> |
− | Файл '''" | + | Файл '''"Spring.js"''' |
<syntaxhighlight lang="javascript" line start="1" enclose="div"> | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
− | + | window.addEventListener("load", Main_Spring, true); | |
− | + | function Main_Spring() { | |
− | // | + | |
− | + | var canvas = spring_canvas; | |
− | var | + | canvas.onselectstart = function () {return false;}; // запрет выделения canvas |
− | + | var ctx = canvas.getContext("2d"); // на ctx происходит рисование | |
− | + | var w = canvas.width; // ширина окна в расчетных координатах | |
− | + | var h = canvas.height; // высота окна в расчетных координатах | |
− | var | + | |
− | + | var Pi = Math.PI; // число "пи" | |
− | + | var g = 9.81; | |
− | + | var m0 = 1; // масштаб массы | |
− | + | var T0 = 1; // масштаб времени (период колебаний исходной системы) | |
− | var | + | |
− | + | var k0 = 2 * Pi / T0; // масштаб частоты | |
− | + | var C0 = 1; // масштаб жесткости | |
+ | var D0 = 0.001; // диаметра | ||
+ | var p0 = 1; // давление | ||
+ | var E0 = 1e-6; | ||
+ | var L = 300; | ||
// *** Задание физических параметров *** | // *** Задание физических параметров *** | ||
− | + | var E = 2.05e11 * E0; // модуль упругости | |
− | + | var m = 3 * m0; // масса | |
− | var | + | var C = 15 * C0; // жесткость |
− | + | var Dp = 43.1 * D0; // диаметр поршня | |
− | var | + | var Dsh = 17.3 * D0; // диаметр штока |
− | var | + | var p = 4 * p0; // давление |
− | var | + | slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1); |
− | var | + | slider_C.value = (C / C0).toFixed(1); number_C.value = (C / C0).toFixed(1); |
+ | slider_Dp.value = (Dp / D0).toFixed(1); number_Dp.value = (Dp / D0).toFixed(1); | ||
+ | slider_Dsh.value = (Dsh / D0).toFixed(1); number_Dsh.value = (Dsh / D0).toFixed(1); | ||
+ | slider_p.value = (p / p0).toFixed(1); number_p.value = (p / p0).toFixed(1); | ||
+ | slider_L.value = (L).toFixed(1); number_L.value = (L).toFixed(1); | ||
+ | |||
+ | // *** Задание вычислительных параметров *** | ||
+ | |||
+ | var fps = 100; // frames per second - число кадров в секунду (качечтво отображения) | ||
+ | var spf = 50; // steps per frame - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета) | ||
+ | var dt = 0.05 * T0 / fps; // шаг интегрирования (качество расчета) | ||
+ | var steps = 0; // количество шагов интегрирования | ||
+ | |||
+ | function setM(new_m) {m = new_m * m0;} | ||
+ | function setC(new_C) {C = new_C * C0;} | ||
+ | function setDp(new_Dp) {Dp = new_Dp * D0;} | ||
+ | function setP(new_p) {p = new_p * p0;} | ||
+ | function setDsh(new_Dsh) {Dsh = new_Dsh * D0;} | ||
+ | function setL(new_L) {L = new_L;} | ||
+ | |||
+ | slider_m.oninput = function() {number_m.value = slider_m.value; setM(slider_m.value);}; | ||
+ | number_m.oninput = function() {slider_m.value = number_m.value; setM(number_m.value);}; | ||
+ | slider_C.oninput = function() {number_C.value = slider_C.value; setC(slider_C.value);}; | ||
+ | number_C.oninput = function() {slider_C.value = number_C.value; setC(number_C.value);}; | ||
+ | slider_p.oninput = function() {number_p.value = slider_p.value; setP(slider_p.value);}; | ||
+ | number_p.oninput = function() {slider_p.value = number_p.value; setP(number_p.value);}; | ||
+ | slider_Dp.oninput = function() {number_Dp.value = slider_Dp.value; setDp(slider_Dp.value);}; | ||
+ | number_Dp.oninput = function() {slider_Dp.value = number_Dp.value; setDp(number_Dp.value);}; | ||
+ | slider_Dsh.oninput = function() {number_Dsh.value = slider_Dsh.value; setDsh(slider_Dsh.value);}; | ||
+ | number_Dsh.oninput = function() {slider_Dsh.value = number_Dsh.value; setDsh(number_Dsh.value);}; | ||
+ | slider_L.oninput = function() {number_L.value = slider_L.value; setL(slider_L.value);}; | ||
+ | number_L.oninput = function() {slider_L.value = number_L.value; setL(number_L.value);}; | ||
+ | |||
+ | var count = true; // проводить ли расчет системы | ||
+ | var v = 0; // скорость тела | ||
+ | var rw = canvas.width / 10; var rh = canvas.height; | ||
+ | var x0 = canvas.width / 2 - 25; var y0 = rh/2-25; | ||
+ | |||
+ | // параметры пружины | ||
+ | var coil = 11; // количество витков | ||
+ | var startY = h; // закрепление пружины | ||
+ | |||
+ | // создаем прямоугольник-грузик | ||
+ | var rect = { | ||
+ | x: x0, width: 50, | ||
+ | y: y0, height: 50, | ||
+ | fill: "rgba(112, 155, 255, 1)" // цвет | ||
+ | }; | ||
+ | |||
+ | // захват прямоугольника мышью | ||
+ | var my_; // буфер позиции мыши (для расчета скорости при отпускании шара) | ||
+ | document.onmousedown = function(e) { // функция при нажатии клавиши мыши | ||
+ | if (Dp <= Dsh) | ||
+ | { | ||
+ | alert("Диаметр поршня должен быть больше диаметра штока"); | ||
+ | slider_Dsh.value = (Dp / D0 - 1).toFixed(1); | ||
+ | number_Dsh.value = (Dp / D0 - 1).toFixed(1); | ||
+ | setDsh(slider_Dsh.value); | ||
+ | setDsh(number_Dsh.value); | ||
+ | } | ||
+ | else { | ||
+ | var m = mouseCoords(e); // получаем расчетные координаты курсора мыши | ||
+ | var x = rect.x; | ||
+ | var xw = rect.x + rect.width; | ||
+ | var y = rect.y; | ||
+ | var yh = rect.y + rect.height; | ||
+ | if (x <= m.x && xw >= m.x && y <= m.y && yh >= m.y) { | ||
+ | if (e.which == 1) { // нажата левая клавиша мыши | ||
+ | rect.xPlus = rect.x - m.x; // сдвиг курсора относительно грузика по x | ||
+ | rect.yPlus = rect.y - m.y; // сдвиг курсора относительно грузика по y | ||
+ | my_ = m.y; | ||
+ | count = false; | ||
+ | document.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | document.onmouseup = function(e) { // функция при отпускании клавиши мыши | ||
+ | document.onmousemove = null; // когда клавиша отпущена - функции перемещения нету | ||
+ | count = true; | ||
+ | }; | ||
+ | |||
+ | function mouseMove(e) { // функция при перемещении мыши, работает только с зажатой ЛКМ | ||
+ | var m = mouseCoords(e); // получаем расчетные координаты курсора мыши | ||
+ | rect.y = m.y + rect.yPlus; | ||
+ | // v = 6.0 * (m.x - mx_) / dt / fps; // сохранение инерции | ||
+ | v = 0; | ||
+ | my_ = m.y; | ||
+ | } | ||
− | + | function mouseCoords(e) { // функция возвращает расчетные координаты курсора мыши | |
− | + | var m = []; | |
− | + | var rect = canvas.getBoundingClientRect(); | |
− | + | m.x = (e.clientX - rect.left); | |
− | + | m.y = (e.clientY - rect.top); | |
− | + | return m; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | // | + | // график |
− | + | var vGraph = new New_graph( // определить график | |
− | var | + | "#vGraph", // на html-элементе #vGraph |
− | + | 250, // сколько шагов по оси "x" отображается | |
− | + | -1, 1, 0.2); // мин. значение оси Y, макс. значение оси Y, шаг по оси Y | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | function control() { | |
− | + | calculate(); | |
− | |||
− | |||
draw(); | draw(); | ||
+ | requestAnimationFrame(control); | ||
} | } | ||
+ | control(); | ||
+ | // setInterval(control, 1000 / fps); // Запуск системы | ||
+ | |||
− | + | function calculate() { | |
− | + | if (!count) return; | |
− | + | for (var s=1; s<=spf; s++) { | |
− | + | var Fo = Math.pow(Dp/D0, 2) * Pi * p / 4; | |
− | + | var Fs = Math.pow(Pi, 3) * E * Math.pow(Dsh/D0, 4) / (64 * L * L * 100); | |
− | + | document.getElementById('Fo').innerHTML = '<b>F отб. =</b>'+Fo.toFixed(2)+' H'; | |
+ | document.getElementById('Fs').innerHTML = '<b>F сж. =</b>'+Fs.toFixed(2)+' H'; | ||
+ | var f; | ||
+ | if (v >= 0){ | ||
+ | f = -C * (rect.y - y0) - Fs * D0 * v; | ||
+ | }; | ||
+ | if (v < 0){ | ||
+ | f = -C * (rect.y - y0) - Fo * D0 * v; | ||
+ | }; | ||
+ | v += f / m * dt; | ||
+ | rect.y += v * dt; | ||
+ | steps++; | ||
+ | if (steps % 80 == 0) vGraph.graphIter(steps, -(rect.y-y0)/canvas.height*2); // подать данные на график | ||
} | } | ||
+ | |||
} | } | ||
− | + | function draw() { | |
− | + | ctx.clearRect(0, 0, w, h); | |
− | + | ctx.fillStyle = "#4B4747"; | |
− | + | ctx.fillRect(rect.x-22 , 480, 100, 20 ); | |
− | + | ctx.fillRect(rect.x + 18, rect.y + 40, 14, 900 ) | |
− | + | ctx.strokeStyle = "#000"; | |
− | + | ctx.beginPath(); | |
− | + | for (var i = 0; i <= coil; i++ ) { | |
− | + | var x; | |
− | + | var y; | |
+ | if (i != coil + 1) { | ||
+ | y = startY + ((rect.y - startY))/coil*i; | ||
+ | x = canvas.width/2 + ((i%2==0)?-1:1)*15 + (rect.x - x0)/coil*i; | ||
+ | } else { | ||
+ | y = startY + ((rect.y - startY))/coil*(i+1); | ||
+ | x = canvas.width/2 + ((i%2==0)?1:-1)*15 + (rect.x - x0)/coil*(i+1); | ||
+ | } | ||
+ | if (i==0) x = x0+25; | ||
+ | ctx.lineTo(x, y+5); | ||
} | } | ||
− | + | ctx.stroke(); | |
− | this. | + | ctx.fillStyle = "#FFFC06"; |
− | { | + | ctx.fillRect(rect.x, rect.y, rect.width, rect.height); |
+ | } | ||
+ | } | ||
+ | function New_graph(htmlElement, yArrayLen, minY, maxY, stepY){ | ||
+ | this.htmlElement = htmlElement; | ||
+ | this.yArrayLen = yArrayLen; | ||
+ | this.minY = minY; | ||
+ | this.maxY = maxY; | ||
+ | this.stepY = stepY; | ||
+ | this.vArray = []; | ||
+ | } | ||
+ | New_graph.prototype.graphIter = function(x, y){ | ||
+ | this.vArray.push([x, y]); // добавляем значение в конец массива | ||
+ | if (this.vArray.length > this.yArrayLen) this.vArray.shift(); // если в массиве больше yArrayLen значений - удаляем первое | ||
+ | var htmlElement1 = this.htmlElement; | ||
+ | var vArray1 = this.vArray; | ||
+ | var minY1 = this.minY; | ||
+ | var maxY1 = this.maxY; | ||
+ | var stepY1 = this.stepY; | ||
+ | $(function() { | ||
+ | var options = { | ||
+ | yaxis: { | ||
+ | min: minY1, | ||
+ | max: maxY1, | ||
+ | tickSize: stepY1 | ||
+ | } | ||
+ | }; | ||
+ | $.plot(htmlElement1, [vArray1], options); // рисуем график на элементе "vGraph" | ||
+ | }); | ||
+ | }; | ||
− | + | New_graph.prototype.graph = function(data){ | |
− | + | this.vArray = data; | |
− | + | var htmlElement1 = this.htmlElement; | |
− | + | var vArray1 = this.vArray; | |
− | + | var minY1 = this.minY; | |
− | + | var maxY1 = this.maxY; | |
− | + | var stepY1 = this.stepY; | |
− | + | $(function() { | |
− | + | var options = { | |
− | + | yaxis: { | |
− | { | + | min: minY1, |
− | + | max: maxY1, | |
− | + | tickSize: stepY1 | |
− | + | } | |
− | + | }; | |
− | + | $.plot(htmlElement1, [vArray1], options); // рисуем график на элементе "vGraph" | |
− | + | }); | |
− | + | }; | |
− | + | ||
+ | |||
+ | |||
+ | function New(){} | ||
+ | New.prototype.addSlider = function(htmlSliderElement, htmlValueElement, minVal, maxVal, stepVal, startVal, setFunc){ | ||
+ | $(function() { | ||
+ | $( htmlSliderElement ).slider({ // слайдер на div - элемент "slider_m" | ||
+ | value:startVal, min: minVal, max: maxVal, step: stepVal, | ||
+ | slide: function( event, ui ) { // работает во время движения слайдера | ||
+ | $( htmlValueElement ).text( ui.value.toFixed(2) ); // присваивает значение текстовому полю "value_m" | ||
+ | setFunc(ui.value); | ||
+ | } | ||
+ | }); | ||
+ | }); | ||
+ | }; | ||
+ | New.prototype.addInputSlider = function(htmlSliderElement, htmlValueElement, minVal, maxVal, stepVal, startVal, setFunc, pressFunc){ | ||
+ | window[pressFunc] = function(event){ | ||
+ | var regExpPattern = /[0-9]+[.]?[0-9]+/; | ||
+ | var inputVal = document.getElementById(htmlValueElement.substr(1)).value; | ||
+ | if (regExpPattern.test(inputVal.toString()) && inputVal != 0){setFunc(inputVal);} | ||
+ | }; | ||
− | + | $(function() { | |
− | + | $( htmlSliderElement ).slider({ | |
− | + | value:startVal, min: minVal, max: maxVal, step: stepVal, | |
− | + | slide: function( event, ui ) { | |
− | + | $( htmlValueElement ).val( ui.value.toFixed(2) ); | |
− | + | setFunc(ui.value); | |
− | + | } | |
− | + | }); | |
− | + | $( htmlValueElement ).val($( htmlSliderElement ).slider( "value" ).toFixed(2) ); | |
− | + | }); | |
− | + | }; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Файл '''" | + | Файл '''"index.html"''' |
<syntaxhighlight lang="html5" line start="1" enclose="div"> | <syntaxhighlight lang="html5" line start="1" enclose="div"> | ||
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html> | <html> | ||
<head> | <head> | ||
− | <meta charset="UTF-8"/> | + | <meta charset="UTF-8" /> |
− | <title> | + | <title>Амортизатор</title> |
− | <script src=" | + | <script src="Spring.js"></script> |
+ | <script src="jquery.min.js"></script> | ||
+ | <script src="jquery.flot.js"></script> | ||
</head> | </head> | ||
<body> | <body> | ||
− | <canvas id=" | + | <table> |
− | + | <tr> | |
− | + | <td><canvas id="spring_canvas" width="300" height="500" style="border:1px solid #000000;"></canvas></td> | |
− | + | <td><div id="vGraph" style="width:600px; height:300px; clear:both;"></div></td> | |
− | + | </tr> | |
− | + | <tr> | |
− | + | <td><input type="range" id="slider_m" min="0.1" max="10" step=0.1 style="width: 120px;" /> | |
− | + | M = <input type="number" id="number_m" min="0.1" max="10" step=0.1 style="width: 40px;" /><br> | |
− | + | <input type="range" id="slider_C" min="0" max="50" step=0.1 style="width: 120px;" /> | |
− | + | C = <input type="number" id="number_C" min="0" max="50" step=0.1 style="width: 40px;" /> *10^5 H/м<br> | |
− | + | <input type="range" id="slider_Dp" min="0" max="100" step=0.1 style="width: 120px;" /> | |
− | + | dпор. = <input type="number" id="number_Dp" min="0" max="100" step=0.1 style="width: 40px;" /> мм<br> | |
− | + | <input type="range" id="slider_Dsh" min="0" max="100" step=0.1 style="width: 120px;" /> | |
− | + | dшт. = <input type="number" id="number_Dsh" min="0" max="98" step=0.1 style="width: 40px;" /> мм<br> | |
− | + | <input type="range" id="slider_L" min="50" max="500" step=1 style="width: 120px;" /> | |
− | + | L = <input type="number" id="number_L" min="50" max="500" step=1 style="width: 40px;" /> мм<br> | |
− | + | <input type="range" id="slider_p" min="0" max="10" step=0.1 style="width: 120px;" /> | |
− | + | p = <input type="number" id="number_p" min="0" max="10" step=0.1 style="width: 40px;" /> МПа<br><br></td> | |
− | + | <td> | |
− | + | <div id = "Fo"> </div> | |
− | + | <div id = "Fs"> </div> | |
− | + | <div id = "info"> где:M - масса, C - коэффициент упругости <br>dпор - диаметр поршня, dшт - диаметр штока<br>L - длина штока, p - давление в амортизаторе<br>F отб - сила на ходе отбоя<br>F сж - сила на ходе сжатия | |
− | + | </td> | |
− | + | </tr> | |
− | < | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | < | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</body> | </body> | ||
</html> | </html> |