Difference between revisions of "Моделирование амортизатора"
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
[[Virtual_laboratory]]>[[Modeling of shock absorber]] <HR> | [[Virtual_laboratory]]>[[Modeling of shock absorber]] <HR> | ||
− | Simulated 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. | 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. | ||
Line 6: | Line 6: | ||
[[File:Amor.jpg|400px|center| Automobile shock absorber]] | [[File:Amor.jpg|400px|center| Automobile shock absorber]] | ||
− | The equations | + | The equations of the system motion look like (the velocity vector is directed upwards): |
::<math> | ::<math> | ||
m \ddot{y} = -mg - c \Delta y - F_{com}^{reb} \dot{y} \\ | m \ddot{y} = -mg - c \Delta y - F_{com}^{reb} \dot{y} \\ | ||
Line 16: | Line 16: | ||
'''Fcom''' - directed opposite to the velocity vector (appears during the '''com'''pression of piston); | '''Fcom''' - directed opposite to the velocity vector (appears during the '''com'''pression of piston); | ||
− | '''Freb''' - codirectional with | + | '''Freb''' - codirectional with the velocity vector (appears on the piston during the '''reb'''ound). |
Clicking the left mouse button on the load - drag and drop. | Clicking the left mouse button on the load - drag and drop. | ||
Line 322: | Line 322: | ||
C = <input type="number" id="number_C" min="0" max="50" step=0.1 style="width: 40px;" /> *10^5 N/m<br> | C = <input type="number" id="number_C" min="0" max="50" step=0.1 style="width: 40px;" /> *10^5 N/m<br> | ||
<input type="range" id="slider_Dp" min="0" max="100" step=0.1 style="width: 120px;" /> | <input type="range" id="slider_Dp" min="0" max="100" step=0.1 style="width: 120px;" /> | ||
− | + | hgfjhk = <input type="number" id="number_Dp" min="0" max="100" step=0.1 style="width: 40px;" /> mm<br> | |
<input type="range" id="slider_Dsh" min="0" max="100" step=0.1 style="width: 120px;" /> | <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;" /> mm<br> | dшт. = <input type="number" id="number_Dsh" min="0" max="98" step=0.1 style="width: 40px;" /> mm<br> |
Latest revision as of 17:16, 24 May 2016
Virtual_laboratory>Modeling of shock absorberSimulated 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.
The equations of the system motion look like (the velocity vector is directed upwards):
, 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.
Скачать Shock_absorbers.zip.
Файл "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>