Modeling of a shock absorber

From Department of Theoretical and Applied Mechanics
Revision as of 02:33, 25 May 2016 by 95.161.239.57 (talk)

Jump to: navigation, search
Virtual_laboratory>Modeling of shock absorber

Simulated work of a shock absorber

A shock absorber (in reality, a shock "damper") is a mechanical or hydraulic device designed to absorb and damp shock impulses. It does this by converting the kinetic energy of the shock into another form of energy (typically heat) which is then dissipated.

Automobile shock absorber

The equations of the system motion look like (the velocity vector is directed upwards):

[math] m \ddot{y} = -mg - c \Delta y - F_{com}^{reb} \dot{y} \\ F_{com} = \frac{\pi^{2} * E *\pi * d_{rod}^{4}}{64 * L^{2}}\\ F_{reb} = \frac{d_{pist}^{2} * \pi * p} {4}\\ [/math]

, where E - modulus of elasticity (Young's modulus) = 2.05*10^11 Pa;

Fcom - directed opposite to the velocity vector (appears during the compression of piston);

Freb - codirectional with the velocity vector (appears on the piston during the rebound).

Clicking the left mouse button on the load - drag and drop.

The graph of changing 'y' coordinate depends on the time.

Download Shock_absorbers.zip.

The program text on JavaScript (developer Богданов Дмитрий, the code based on the program byЦветков Денис):

Файл "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;" /> kg<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 N/m<br>
21     <input type="range" id="slider_Dp" min="0" max="100" step=0.1 style="width: 120px;" />
22     hgfjhk = <input type="number" id="number_Dp" min="0" max="100" step=0.1 style="width: 40px;" /> mm<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;" /> mm<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;" /> mm<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;" /> MPa<br><br></td>
29 	<td>
30 	<div id = "Fo"> </div>
31 	<div id = "Fs"> </div>
32 	<div id = "info"> where:m - mass, C - coefficient of elasticity <br>dpist - piston diameter, drod - rod diameter<br>L - rod length, p -  pressure in the shock absorber<br>Freb - force of rebound stroke<br>Fcom - force of the compression stroke 
33 	</td>
34 	</tr>
35 </body>
36 </html>