Моделирование амортизатора

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Виртуальная лаборатория>Моделирование амортизатора

Моделируется работа амортизатора

Амортизатор — устройство для гашения колебаний (демпфирования) и поглощения толчков и ударов подвижных элементов (подвески, колёс), а также корпуса самого транспортного средства, посредством превращения механической энергии движения (колебаний) в тепловую.

Amor.jpg

Уравнения движения системы будут выглядеть так (вектор скорости направлен вверх):

[math] m \ddot{y} = -mg - c \Delta y + F_{сж.}^{отб} \dot{y} \\ F_{сж.} = \frac{\pi^{2} * E *\pi * d_{шт.}^{4}}{64 * L^{2}}\\ F_{отб.} = \frac{d_{пор.}^{2} * \pi * p} {4}\\ [/math]

, где E - модуль Юнга = 2.05*10^11 Па

Fсж - направлена противоположно вектору скорости (возникает на ходе сжатия поршня)

Fотб - сонаправлена с вектором скорости (возникает на ходе отбоя поршня)


Левая клавиша мыши по грузу - перетаскивание.

Скачать Shock_absorbers.zip.

Текст программы на языке JavaScript (разработчик Богданов Дмитрий, код основан на программе Цветков Денис):

Файл "Spring.js"

  1 window.addEventListener("load", Main_Spring, true);
  2 function Main_Spring() {
  3 
  4     var canvas = spring_canvas;
  5     canvas.onselectstart = function () {return false;};     // запрет выделения canvas
  6     var ctx = canvas.getContext("2d");                      // на ctx происходит рисование
  7     var w = canvas.width;                                   // ширина окна в расчетных координатах
  8     var h = canvas.height;                                  // высота окна в расчетных координатах
  9 
 10     var Pi = Math.PI;    	      	    // число "пи"
 11 	var g = 9.81;
 12     var m0 = 1;    		      	        // масштаб массы
 13     var T0 = 1;    		      	        // масштаб времени (период колебаний исходной системы)
 14 
 15     var k0 = 2 * Pi / T0;           	// масштаб частоты
 16     var C0 = 1;          	// масштаб жесткости
 17     var D0 = 0.001;  	      	    // диаметра
 18 	var p0 = 1;					// давление
 19 	var E0 = 1e-6;
 20 	var L = 300;
 21     // *** Задание физических параметров ***
 22 	var E = 2.05e11 * E0;						// модуль упругости
 23     var m = 3 * m0;                 	// масса
 24     var C = 15 * C0;                 	// жесткость
 25     var Dp = 43.1 * D0;                 	// диаметр поршня
 26 	var Dsh = 17.3 * D0;					// диаметр штока
 27 	var p = 4 * p0;						// давление
 28     slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1);
 29     slider_C.value = (C / C0).toFixed(1); number_C.value = (C / C0).toFixed(1);
 30     slider_Dp.value = (Dp / D0).toFixed(1); number_Dp.value = (Dp / D0).toFixed(1);
 31 	slider_Dsh.value = (Dsh / D0).toFixed(1); number_Dsh.value = (Dsh / D0).toFixed(1);
 32     slider_p.value = (p / p0).toFixed(1); number_p.value = (p / p0).toFixed(1);
 33     slider_L.value = (L).toFixed(1); number_L.value = (L).toFixed(1);
 34 
 35     // *** Задание вычислительных параметров ***
 36 
 37     var fps = 100;		      	        // frames per second - число кадров в секунду (качечтво отображения)
 38     var spf = 50;		      	        // steps per frame   - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета)
 39     var dt  = 0.05 * T0 / fps;    	    // шаг интегрирования (качество расчета)
 40     var steps = 0;                      // количество шагов интегрирования
 41 
 42     function setM(new_m) {m = new_m * m0;}
 43     function setC(new_C) {C = new_C * C0;}
 44     function setDp(new_Dp) {Dp = new_Dp * D0;}
 45 	function setP(new_p) {p = new_p * p0;}
 46     function setDsh(new_Dsh) {Dsh = new_Dsh * D0;}
 47 	function setL(new_L) {L = new_L;}
 48 
 49     slider_m.oninput = function() {number_m.value = slider_m.value;       setM(slider_m.value);};
 50     number_m.oninput = function() {slider_m.value = number_m.value;       setM(number_m.value);};
 51     slider_C.oninput = function() {number_C.value = slider_C.value;       setC(slider_C.value);};
 52     number_C.oninput = function() {slider_C.value = number_C.value;       setC(number_C.value);};
 53     slider_p.oninput = function() {number_p.value = slider_p.value;       setP(slider_p.value);};
 54     number_p.oninput = function() {slider_p.value = number_p.value;       setP(number_p.value);};
 55 	slider_Dp.oninput = function() {number_Dp.value = slider_Dp.value;       setDp(slider_Dp.value);};
 56     number_Dp.oninput = function() {slider_Dp.value = number_Dp.value;       setDp(number_Dp.value);};
 57     slider_Dsh.oninput = function() {number_Dsh.value = slider_Dsh.value;       setDsh(slider_Dsh.value);};
 58     number_Dsh.oninput = function() {slider_Dsh.value = number_Dsh.value;       setDsh(number_Dsh.value);};
 59 	slider_L.oninput = function() {number_L.value = slider_L.value;       setL(slider_L.value);};
 60     number_L.oninput = function() {slider_L.value = number_L.value;       setL(number_L.value);};
 61 
 62     var count = true;       // проводить ли расчет системы
 63     var v = 0;				// скорость тела
 64 
 65     var rw = canvas.width / 10;    	var rh = canvas.height;
 66     var x0 = canvas.width / 2 - 25;     	var y0 = rh/2-25;
 67 
 68     // параметры пружины
 69     var coil = 11;        // количество витков
 70     var startY = h;       // закрепление пружины
 71 
 72     // создаем прямоугольник-грузик
 73     var rect = {
 74         x: x0,  width: 50,
 75         y: y0,	height: 50,
 76         fill: "rgba(112, 155, 255, 1)"    	// цвет
 77     };
 78 
 79     // захват прямоугольника мышью
 80     var my_;                                    // буфер позиции мыши (для расчета скорости при отпускании шара)
 81     document.onmousedown = function(e) {        // функция при нажатии клавиши мыши
 82         if (Dp <= Dsh)
 83 		{ 
 84 		alert("Диаметр поршня должен быть больше диаметра штока");
 85 		slider_Dsh.value = (Dp / D0 - 1).toFixed(1); 
 86 		number_Dsh.value = (Dp / D0 - 1).toFixed(1);
 87 		setDsh(slider_Dsh.value);
 88 		setDsh(number_Dsh.value);
 89 		}
 90 			else {
 91 		var m = mouseCoords(e);                 // получаем расчетные координаты курсора мыши
 92         var x = rect.x;
 93         var xw = rect.x + rect.width;
 94         var y = rect.y;
 95         var yh = rect.y + rect.height;
 96         if (x <= m.x && xw >= m.x   && y <= m.y && yh >= m.y) {
 97             if (e.which == 1) {                         // нажата левая клавиша мыши
 98                 rect.xPlus = rect.x - m.x;              // сдвиг курсора относительно грузика по x
 99                 rect.yPlus = rect.y - m.y;              // сдвиг курсора относительно грузика по y
100                 my_ = m.y;
101                 count = false;
102                 document.onmousemove = mouseMove;       // пока клавиша нажата - работает функция перемещения
103             }
104         }
105 			}
106     };
107 
108     document.onmouseup = function(e) {          // функция при отпускании клавиши мыши
109         document.onmousemove = null;              // когда клавиша отпущена - функции перемещения нету
110         count = true;
111     };
112 
113     function mouseMove(e) {                     // функция при перемещении мыши, работает только с зажатой ЛКМ
114         var m = mouseCoords(e);                 // получаем расчетные координаты курсора мыши
115         rect.y = m.y + rect.yPlus;
116 //        v = 6.0 * (m.x - mx_) / dt / fps;     // сохранение инерции
117         v = 0;
118         my_ = m.y;
119     }
120 
121     function mouseCoords(e) {                   // функция возвращает расчетные координаты курсора мыши
122         var m = [];
123         var rect = canvas.getBoundingClientRect();
124         m.x = (e.clientX - rect.left);
125         m.y = (e.clientY - rect.top);
126         return m;
127     }
128 
129     // график
130     var vGraph = new New_graph(                  // определить график
131         "#vGraph",                              // на html-элементе #vGraph
132         250,                                    // сколько шагов по оси "x" отображается
133         -1, 1, 0.2);                            // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
134 
135     function control() {
136         calculate();
137         draw();
138         requestAnimationFrame(control);
139     }
140     control();
141 //    setInterval(control, 1000 / fps);                       // Запуск системы
142 	
143 	
144     function calculate() {
145         if (!count) return;
146         for (var s=1; s<=spf; s++) {
147 			var Fo = Math.pow(Dp/D0, 2) * Pi * p / 4;
148 			var Fs = Math.pow(Pi, 3) * E * Math.pow(Dsh/D0, 4) / (64 * L * L * 100); 
149 			document.getElementById('Fo').innerHTML = '<b>F отб. =</b>'+Fo.toFixed(2)+' H';
150             document.getElementById('Fs').innerHTML = '<b>F сж. =</b>'+Fs.toFixed(2)+' H';
151 			var f;
152 			if (v >= 0){
153 			f = -C * (rect.y - y0) - Fs * D0 * v;
154 			};
155 			if (v < 0){
156 			f = -C * (rect.y - y0) - Fo * D0 * v;	
157 			};
158             v += f / m * dt;
159             rect.y += v * dt;
160             steps++;
161             if (steps % 80 == 0) vGraph.graphIter(steps, -(rect.y-y0)/canvas.height*2);   // подать данные на график
162         }
163 
164     }
165     function draw() {
166        ctx.clearRect(0, 0, w, h);
167 	   ctx.fillStyle = "#4B4747";
168 		ctx.fillRect(rect.x-22 , 480, 100, 20 );
169 		ctx.fillRect(rect.x + 18, rect.y + 40, 14, 900 )
170         ctx.strokeStyle = "#000";
171         ctx.beginPath();
172         for (var i = 0; i <= coil; i++ ) {
173             var x;
174             var y;
175             if (i != coil + 1) {
176                 y = startY + ((rect.y - startY))/coil*i;
177                 x = canvas.width/2 + ((i%2==0)?-1:1)*15 + (rect.x - x0)/coil*i;
178             } else {
179                 y = startY + ((rect.y - startY))/coil*(i+1);
180                 x = canvas.width/2 + ((i%2==0)?1:-1)*15 +  (rect.x - x0)/coil*(i+1);
181             }
182 			if (i==0) x = x0+25;
183             ctx.lineTo(x, y+5);
184         }
185         ctx.stroke();
186         ctx.fillStyle = "#FFFC06";
187         ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
188     }
189 }
190 function New_graph(htmlElement, yArrayLen, minY, maxY, stepY){
191     this.htmlElement = htmlElement;
192     this.yArrayLen = yArrayLen;
193     this.minY = minY;
194     this.maxY = maxY;
195     this.stepY = stepY;
196     this.vArray = [];
197 }
198 New_graph.prototype.graphIter = function(x, y){
199     this.vArray.push([x, y]);                    // добавляем значение в конец массива
200     if (this.vArray.length > this.yArrayLen) this.vArray.shift(); // если в массиве больше yArrayLen значений - удаляем первое
201     var htmlElement1 = this.htmlElement;
202     var vArray1 = this.vArray;
203     var minY1 = this.minY;
204     var maxY1 = this.maxY;
205     var stepY1 = this.stepY;
206     $(function() {
207         var options = {
208             yaxis: {
209                 min: minY1,
210                 max: maxY1,
211                 tickSize: stepY1
212             }
213         };
214         $.plot(htmlElement1, [vArray1], options);  // рисуем график на элементе "vGraph"
215     });
216 };
217 
218 New_graph.prototype.graph = function(data){
219     this.vArray = data;
220     var htmlElement1 = this.htmlElement;
221     var vArray1 = this.vArray;
222     var minY1 = this.minY;
223     var maxY1 = this.maxY;
224     var stepY1 = this.stepY;
225     $(function() {
226         var options = {
227             yaxis: {
228                 min: minY1,
229                 max: maxY1,
230                 tickSize: stepY1
231             }
232         };
233         $.plot(htmlElement1, [vArray1], options);  // рисуем график на элементе "vGraph"
234     });
235 };
236 
237 
238 
239 function New(){}
240 New.prototype.addSlider = function(htmlSliderElement, htmlValueElement, minVal, maxVal, stepVal, startVal, setFunc){
241     $(function() {
242         $( htmlSliderElement ).slider({                               // слайдер на div - элемент "slider_m"
243             value:startVal, min: minVal, max: maxVal, step: stepVal,
244             slide: function( event, ui ) {                      // работает во время движения слайдера
245                 $( htmlValueElement ).text( ui.value.toFixed(2) );    // присваивает значение текстовому полю "value_m"
246                 setFunc(ui.value);
247             }
248         });
249     });
250 };
251 New.prototype.addInputSlider = function(htmlSliderElement, htmlValueElement, minVal, maxVal, stepVal, startVal, setFunc, pressFunc){
252     window[pressFunc] = function(event){
253         var regExpPattern = /[0-9]+[.]?[0-9]+/;
254         var inputVal = document.getElementById(htmlValueElement.substr(1)).value;
255         if (regExpPattern.test(inputVal.toString()) && inputVal != 0){setFunc(inputVal);}
256     };
257 
258     $(function() {
259         $( htmlSliderElement ).slider({
260             value:startVal, min: minVal, max: maxVal, step: stepVal,
261             slide: function( event, ui ) {
262                 $( htmlValueElement ).val( ui.value.toFixed(2) );
263                 setFunc(ui.value);
264             }
265         });
266         $( htmlValueElement ).val($( htmlSliderElement ).slider( "value" ).toFixed(2) );
267     });
268 };

Файл "index.html"

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8" />
 5     <title>Амортизатор</title>
 6     <script src="Spring.js"></script>
 7     <script src="jquery.min.js"></script>
 8     <script src="jquery.flot.js"></script>
 9 </head>
10 <body>
11 <table>
12 <tr>
13     <td><canvas id="spring_canvas" width="300" height="500" style="border:1px solid #000000;"></canvas></td>
14     <td><div id="vGraph" style="width:600px; height:300px; clear:both;"></div></td>	
15 </tr>
16 <tr>    
17 	<td><input type="range" id="slider_m" min="0.1" max="10" step=0.1 style="width: 120px;" />
18     M = <input type="number" id="number_m" min="0.1" max="10" step=0.1 style="width: 40px;" /><br>
19     <input type="range" id="slider_C" min="0" max="50" step=0.1 style="width: 120px;" /> 
20     C = <input type="number" id="number_C" min="0" max="50" step=0.1 style="width: 40px;" /> *10^5 H/м<br>
21     <input type="range" id="slider_Dp" min="0" max="100" step=0.1 style="width: 120px;" />
22     dпор. = <input type="number" id="number_Dp" min="0" max="100" step=0.1 style="width: 40px;" /> мм<br>
23 	<input type="range" id="slider_Dsh" min="0" max="100" step=0.1 style="width: 120px;" />
24     dшт. = <input type="number" id="number_Dsh" min="0" max="98" step=0.1 style="width: 40px;" /> мм<br>
25 	<input type="range" id="slider_L" min="50" max="500" step=1 style="width: 120px;" />
26     L = <input type="number" id="number_L" min="50" max="500" step=1 style="width: 40px;" /> мм<br>
27 	<input type="range" id="slider_p" min="0" max="10" step=0.1 style="width: 120px;" />
28     p = <input type="number" id="number_p" min="0" max="10" step=0.1 style="width: 40px;" /> МПа<br><br></td>
29 	<td>
30 	<div id = "Fo"> </div>
31 	<div id = "Fs"> </div>
32 	<div id = "info"> где:M - масса, C - коэффициент упругости <br>dпор - диаметр поршня, dшт - диаметр штока<br>L - длина штока, p - давление в амортизаторе<br>F отб - сила на ходе отбоя<br>F сж - сила на ходе сжатия 
33 	</td>
34 	</tr>
35 </body>
36 </html>