Моделирование амортизатора — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
Строка 7: | Строка 7: | ||
::<math> | ::<math> | ||
m \ddot{y} = -mg - c \Delta y + F_{сж.}^{отб} \dot{y} \\ | m \ddot{y} = -mg - c \Delta y + F_{сж.}^{отб} \dot{y} \\ | ||
− | F_{сж.} = \frac{\pi^{2} * E *\pi * d_{шт.}^{4}}{64 * L^{2}} | + | F_{сж.} = \frac{\pi^{2} * E *\pi * d_{шт.}^{4}}{64 * L^{2}}\\ |
− | F_{отб.} = \frac{d_{пор.}^{2} * \pi * p} {4} | + | F_{отб.} = \frac{d_{пор.}^{2} * \pi * p} {4}\\ |
</math> | </math> | ||
+ | |||
+ | Fсж - сонаправлена с вектором скорости(возникает на ходе сжатия поршня) | ||
+ | Fотб - направлена противоположна вектору скорости(возникает на ходе отбоя поршня) | ||
Левая клавиша мыши по грузу - перетаскивание. | Левая клавиша мыши по грузу - перетаскивание. |
Версия 13:26, 26 мая 2015
Виртуальная лаборатория>Моделирование амортизатораМоделируется работа амортизатора
Уравнения движения системы будут выглядеть так (вектор скорости направлен вверх):
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 = 1;
20 var L = 300;
21 // *** Задание физических параметров ***
22 var E = 2.05e5 * 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>