Difference between revisions of "Modeling of a shock absorber"

From Department of Theoretical and Applied Mechanics
Jump to: navigation, search
 
(10 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[Virtual laboratory]] > [[Modeling of shock absorber]] <HR>
+
[[ru:Моделирование амортизатора]]
Simulated work of a shock absorber
+
This demonstration stand shows the 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.
  
[[File:Amor.jpg|250px|left| Automobile shock absorber]]
+
[[File:Amor.jpg|350px|left| Automobile shock absorber]]
  
The equations of the system motion look like (the velocity vector is directed upwards):
+
The equations of motion have the form (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}^{ten}  \dot{y}, \\
F_{com} = \frac{\pi^{2} * E *\pi * d_{rod}^{4}}{64 * L^{2}}\\
+
F_{com} = \frac{\pi^{2} * E *\pi * d_{rod}^{4}}{64 * L^{2}},\\
F_{reb} = \frac{d_{pist}^{2} * \pi * p} {4},\\
+
F_{ten} = \frac{d_{pist}^{2} * \pi * p} {4},\\
 
</math>
 
</math>
where '''E''' - modulus of elasticity (Young's modulus) = 2.05*10^11 Pa;
+
where <math>E</math> is the modulus of elasticity (Young's modulus) <math>E= 2.05 \cdot 10^{11}</math> Pa;
  
'''Fcom''' - directed opposite to the velocity vector (appears during the '''com'''pression of piston);
+
<math>F_{com}</math> is the force directed opposite to the velocity vector (acts during the ''com''pression of a piston);
  
'''Freb''' - codirectional with the velocity vector (appears on the piston during the '''reb'''ound).
+
<math>F_{ten}</math> is the force directed along the velocity vector (acts on the piston during the ''ten''sion).
  
Clicking the left mouse button on the load - drag and drop.
+
You can drag and drop the yellow square to load the damper.
  
The graph of changing 'y' coordinate depends on the time.
+
The time dependence of 'y' coordinate is plotted below:
  
 
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Bogdanov/shock_absorbers/index.html |width=1000 |height=750 |border=0 }}
 
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Bogdanov/shock_absorbers/index.html |width=1000 |height=750 |border=0 }}
  
Download [[Медиа:Shock_absorbers.zip|Shock_absorbers.zip]].
+
Download [[Media:Shock_absorbers.zip|Shock_absorbers.zip]].
  
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
'''The program text on JavaScript (developer [[:ru:Богданов Дмитрий|Bogdanov Dmitriy]], the code based on the program by[[Tsvetkov Denis]]):''' <div class="mw-collapsible-content">
 
'''The program text on JavaScript (developer [[:ru:Богданов Дмитрий|Bogdanov Dmitriy]], the code based on the program by[[Tsvetkov Denis]]):''' <div class="mw-collapsible-content">
Файл '''"Spring.js"'''
+
File '''"Spring.js"'''
 
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 
window.addEventListener("load", Main_Spring, true);
 
window.addEventListener("load", Main_Spring, true);
Line 34: Line 34:
  
 
     var canvas = spring_canvas;
 
     var canvas = spring_canvas;
     canvas.onselectstart = function () {return false;};    // запрет выделения canvas
+
     canvas.onselectstart = function () {return false;};    // disabling canvas selection
     var ctx = canvas.getContext("2d");                      // на ctx происходит рисование
+
     var ctx = canvas.getContext("2d");                      // ctx drawing
     var w = canvas.width;                                  // ширина окна в расчетных координатах
+
     var w = canvas.width;                                  // the width of the window in the actual coordinates
     var h = canvas.height;                                  // высота окна в расчетных координатах
+
     var h = canvas.height;                                  // the height of the window in the actual coordinates
  
     var Pi = Math.PI;              // число "пи"
+
     var Pi = Math.PI;              // the 'Pi' number
 
var g = 9.81;
 
var g = 9.81;
     var m0 = 1;                  // масштаб массы
+
     var m0 = 1;                  // the scale of weight
     var T0 = 1;                  // масштаб времени (период колебаний исходной системы)
+
     var T0 = 1;                  // the scale of time (period of oscillation the initial system)
  
     var k0 = 2 * Pi / T0;          // масштаб частоты
+
     var k0 = 2 * Pi / T0;          // the scale of frequency
     var C0 = 1;          // масштаб жесткости
+
     var C0 = 1;          // the scale of stiffness
     var D0 = 0.001;            // диаметра
+
     var D0 = 0.001;            // the diameter
var p0 = 1; // давление
+
var p0 = 1; // the pressure
 
var E0 = 1e-6;
 
var E0 = 1e-6;
 
var L = 300;
 
var L = 300;
     // *** Задание физических параметров ***
+
     // *** Setting the physical parameters ***
var E = 2.05e11 * E0; // модуль упругости
+
var E = 2.05e11 * E0; // the elastic modulus
     var m = 3 * m0;                // масса
+
     var m = 3 * m0;                // the mass
     var C = 15 * C0;                // жесткость
+
     var C = 15 * C0;                // the stiffness
     var Dp = 43.1 * D0;                // диаметр поршня
+
     var Dp = 43.1 * D0;                // the piston diameter
var Dsh = 17.3 * D0; // диаметр штока
+
var Dsh = 17.3 * D0; // the rod diameter
var p = 4 * p0; // давление
+
var p = 4 * p0; // the pressure
 
     slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1);
 
     slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1);
 
     slider_C.value = (C / C0).toFixed(1); number_C.value = (C / C0).toFixed(1);
 
     slider_C.value = (C / C0).toFixed(1); number_C.value = (C / C0).toFixed(1);
Line 64: Line 64:
 
     slider_L.value = (L).toFixed(1); number_L.value = (L).toFixed(1);
 
     slider_L.value = (L).toFixed(1); number_L.value = (L).toFixed(1);
  
     // *** Задание вычислительных параметров ***
+
     // *** Setting the computing parameters***
  
     var fps = 100;               // frames per second - число кадров в секунду (качечтво отображения)
+
     var fps = 100;               // frames per second
     var spf = 50;               // steps per frame   - число шагов интегрирования между кадрами (увеличивает скорость расчета)
+
     var spf = 50;               // steps per frame - the number of integration steps between frames (increases the calculation speed)
     var dt  = 0.05 * T0 / fps;        // шаг интегрирования (качество расчета)
+
     var dt  = 0.05 * T0 / fps;        // the integration step (the quality of calculation)
     var steps = 0;                      // количество шагов интегрирования
+
     var steps = 0;                      // the number of integration steps
  
 
     function setM(new_m) {m = new_m * m0;}
 
     function setM(new_m) {m = new_m * m0;}
Line 91: Line 91:
 
     number_L.oninput = function() {slider_L.value = number_L.value;      setL(number_L.value);};
 
     number_L.oninput = function() {slider_L.value = number_L.value;      setL(number_L.value);};
  
     var count = true;      // проводить ли расчет системы
+
     var count = true;      // calculate the system
     var v = 0; // скорость тела
+
     var v = 0; // the body speed
  
 
     var rw = canvas.width / 10;    var rh = canvas.height;
 
     var rw = canvas.width / 10;    var rh = canvas.height;
 
     var x0 = canvas.width / 2 - 25;    var y0 = rh/2-25;
 
     var x0 = canvas.width / 2 - 25;    var y0 = rh/2-25;
  
     // параметры пружины
+
     // the spring settings
     var coil = 11;        // количество витков
+
     var coil = 11;        // the number of coils
     var startY = h;      // закрепление пружины
+
     var startY = h;      // the spring fixation
  
     // создаем прямоугольник-грузик
+
     // a fancy yellow square
 
     var rect = {
 
     var rect = {
 
         x: x0,  width: 50,
 
         x: x0,  width: 50,
 
         y: y0, height: 50,
 
         y: y0, height: 50,
         fill: "rgba(112, 155, 255, 1)"    // цвет
+
         fill: "rgba(112, 155, 255, 1)"    // yellow
 
     };
 
     };
  
     // захват прямоугольника мышью
+
     // mouse control
     var my_;                                    // буфер позиции мыши (для расчета скорости при отпускании шара)
+
     var my_;                                    // mouse position buffer (to calculate the initial speed of the ball)
     document.onmousedown = function(e) {        // функция при нажатии клавиши мыши
+
     document.onmousedown = function(e) {        // mouse click function
 
         if (Dp <= Dsh)
 
         if (Dp <= Dsh)
 
{  
 
{  
alert("Диаметр поршня должен быть больше диаметра штока");
+
alert("The diameter of the piston must be larger than the diameter of the rod");
 
slider_Dsh.value = (Dp / D0 - 1).toFixed(1);  
 
slider_Dsh.value = (Dp / D0 - 1).toFixed(1);  
 
number_Dsh.value = (Dp / D0 - 1).toFixed(1);
 
number_Dsh.value = (Dp / D0 - 1).toFixed(1);
Line 120: Line 120:
 
}
 
}
 
else {
 
else {
var m = mouseCoords(e);                // получаем расчетные координаты курсора мыши
+
var m = mouseCoords(e);                // getting coordinates of the mouse cursor
 
         var x = rect.x;
 
         var x = rect.x;
 
         var xw = rect.x + rect.width;
 
         var xw = rect.x + rect.width;
Line 126: Line 126:
 
         var yh = rect.y + rect.height;
 
         var yh = rect.y + rect.height;
 
         if (x <= m.x && xw >= m.x  && y <= m.y && yh >= m.y) {
 
         if (x <= m.x && xw >= m.x  && y <= m.y && yh >= m.y) {
             if (e.which == 1) {                        // нажата левая клавиша мыши
+
             if (e.which == 1) {                        // left mouse button is pressed
                 rect.xPlus = rect.x - m.x;              // сдвиг курсора относительно грузика по x
+
                 rect.xPlus = rect.x - m.x;              // cursor displacement with respect to the mass on the X axis
                 rect.yPlus = rect.y - m.y;              // сдвиг курсора относительно грузика по y
+
                 rect.yPlus = rect.y - m.y;              // cursor displacement with respect to the mass on the Y axis
 
                 my_ = m.y;
 
                 my_ = m.y;
 
                 count = false;
 
                 count = false;
                 document.onmousemove = mouseMove;      // пока клавиша нажата - работает функция перемещения
+
                 document.onmousemove = mouseMove;      // while the mouse button is pressed the function works
 
             }
 
             }
 
         }
 
         }
Line 137: Line 137:
 
     };
 
     };
  
     document.onmouseup = function(e) {          // функция при отпускании клавиши мыши
+
     document.onmouseup = function(e) {          // the working function when you release the mouse button
         document.onmousemove = null;              // когда клавиша отпущена - функции перемещения нету
+
         document.onmousemove = null;              // when the key is released displacement function does not work
 
         count = true;
 
         count = true;
 
     };
 
     };
  
     function mouseMove(e) {                    // функция при перемещении мыши, работает только с зажатой ЛКМ
+
     function mouseMove(e) {                    // the function works only while holding LMB
         var m = mouseCoords(e);                // получаем расчетные координаты курсора мыши
+
         var m = mouseCoords(e);                // getting calculated coordinates of the mouse cursor
 
         rect.y = m.y + rect.yPlus;
 
         rect.y = m.y + rect.yPlus;
//        v = 6.0 * (m.x - mx_) / dt / fps;    // сохранение инерции
+
//        v = 6.0 * (m.x - mx_) / dt / fps;    // inertia conservation law
 
         v = 0;
 
         v = 0;
 
         my_ = m.y;
 
         my_ = m.y;
 
     }
 
     }
  
     function mouseCoords(e) {                  // функция возвращает расчетные координаты курсора мыши
+
     function mouseCoords(e) {                  // the function returns the calculated coordinates of the mouse cursor
 
         var m = [];
 
         var m = [];
 
         var rect = canvas.getBoundingClientRect();
 
         var rect = canvas.getBoundingClientRect();
Line 158: Line 158:
 
     }
 
     }
  
     // график
+
     // the graph
     var vGraph = new New_graph(                  // определить график
+
     var vGraph = new New_graph(                  // initialisation of the graph
         "#vGraph",                              // на html-элементе #vGraph
+
         "#vGraph",                              // at html-page #vGraph
         250,                                    // сколько шагов по оси "x" отображается
+
         250,                                    // the number of steps by X axis
         -1, 1, 0.2);                            // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
+
         -1, 1, 0.2);                            // the minimum value of Y axis, the maximum value of Y axis, step along the Y axis
  
 
     function control() {
 
     function control() {
Line 170: Line 170:
 
     }
 
     }
 
     control();
 
     control();
//    setInterval(control, 1000 / fps);                      // Запуск системы
+
//    setInterval(control, 1000 / fps);                      // starting system
 
 
 
 
Line 190: Line 190:
 
             rect.y += v * dt;
 
             rect.y += v * dt;
 
             steps++;
 
             steps++;
             if (steps % 80 == 0) vGraph.graphIter(steps, -(rect.y-y0)/canvas.height*2);  // подать данные на график
+
             if (steps % 80 == 0) vGraph.graphIter(steps, -(rect.y-y0)/canvas.height*2);  // streaming the data on the graph
 
         }
 
         }
  
Line 228: Line 228:
 
}
 
}
 
New_graph.prototype.graphIter = function(x, y){
 
New_graph.prototype.graphIter = function(x, y){
     this.vArray.push([x, y]);                    // добавляем значение в конец массива
+
     this.vArray.push([x, y]);                    // adding a value to the end of the array
     if (this.vArray.length > this.yArrayLen) this.vArray.shift(); // если в массиве больше yArrayLen значений - удаляем первое
+
     if (this.vArray.length > this.yArrayLen) this.vArray.shift(); // if the array has more 'yArrayLen' values, than remove the first one
 
     var htmlElement1 = this.htmlElement;
 
     var htmlElement1 = this.htmlElement;
 
     var vArray1 = this.vArray;
 
     var vArray1 = this.vArray;
Line 243: Line 243:
 
             }
 
             }
 
         };
 
         };
         $.plot(htmlElement1, [vArray1], options);  // рисуем график на элементе "vGraph"
+
         $.plot(htmlElement1, [vArray1], options);  // drawing graph at the element "vGraph"
 
     });
 
     });
 
};
 
};
Line 262: Line 262:
 
             }
 
             }
 
         };
 
         };
         $.plot(htmlElement1, [vArray1], options);  // рисуем график на элементе "vGraph"
+
         $.plot(htmlElement1, [vArray1], options);  // drawing graph at the element "vGraph"
 
     });
 
     });
 
};
 
};
Line 271: Line 271:
 
New.prototype.addSlider = function(htmlSliderElement, htmlValueElement, minVal, maxVal, stepVal, startVal, setFunc){
 
New.prototype.addSlider = function(htmlSliderElement, htmlValueElement, minVal, maxVal, stepVal, startVal, setFunc){
 
     $(function() {
 
     $(function() {
         $( htmlSliderElement ).slider({                              // слайдер на div - элемент "slider_m"
+
         $( htmlSliderElement ).slider({                              // element "slider_m"
 
             value:startVal, min: minVal, max: maxVal, step: stepVal,
 
             value:startVal, min: minVal, max: maxVal, step: stepVal,
             slide: function( event, ui ) {                      // работает во время движения слайдера
+
             slide: function( event, ui ) {                      // it works during movement of the slider
                 $( htmlValueElement ).text( ui.value.toFixed(2) );    // присваивает значение текстовому полю "value_m"
+
                 $( htmlValueElement ).text( ui.value.toFixed(2) );    // it assigns a value to the text field "value_m"
 
                 setFunc(ui.value);
 
                 setFunc(ui.value);
 
             }
 
             }
Line 299: Line 299:
 
};
 
};
 
</syntaxhighlight>
 
</syntaxhighlight>
Файл '''"index.html"'''
+
File '''"index.html"'''
 
<syntaxhighlight lang="html5" line start="1" enclose="div">
 
<syntaxhighlight lang="html5" line start="1" enclose="div">
 
<!DOCTYPE html>
 
<!DOCTYPE html>
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>
+
     dpist = <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>
+
     drod = <input type="number" id="number_Dsh" min="0" max="98" step=0.1 style="width: 40px;" /> mm<br>
 
<input type="range" id="slider_L" min="50" max="500" step=1 style="width: 120px;" />
 
<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;" /> mm<br>
 
     L = <input type="number" id="number_L" min="50" max="500" step=1 style="width: 40px;" /> mm<br>
Line 332: Line 332:
 
<div id = "Fo"> </div>
 
<div id = "Fo"> </div>
 
<div id = "Fs"> </div>
 
<div id = "Fs"> </div>
<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  
+
<div id = "info"> where: m is the mass, C is the coefficient of elasticity <br>dpist is the piston diameter, drod is the rod diameter<br>L is the rod length, p is the pressure in the shock absorber<br>Freb is the force of the tension stroke <br>Fcom is the force of the compression stroke  
 
</td>
 
</td>
 
</tr>
 
</tr>
Line 340: Line 340:
 
</div>
 
</div>
 
</div>
 
</div>
 
[[Category: Virtual_laboratory]]
 
[[Category: Programming]]
 
[[Category: JavaScript]]
 

Latest revision as of 18:19, 18 January 2017

This demonstration stand shows the 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 motion have the form (the velocity vector is directed upwards):

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

where [math]E[/math] is the modulus of elasticity (Young's modulus) [math]E= 2.05 \cdot 10^{11}[/math] Pa;

[math]F_{com}[/math] is the force directed opposite to the velocity vector (acts during the compression of a piston);

[math]F_{ten}[/math] is the force directed along the velocity vector (acts on the piston during the tension).

You can drag and drop the yellow square to load the damper.

The time dependence of 'y' coordinate is plotted below:

Download Shock_absorbers.zip.

The program text on JavaScript (developer Bogdanov Dmitriy, the code based on the program byTsvetkov Denis):

File "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;};     // disabling canvas selection
  6     var ctx = canvas.getContext("2d");                      // ctx drawing 
  7     var w = canvas.width;                                   // the width of the window in the actual coordinates
  8     var h = canvas.height;                                  // the height of the window in the actual coordinates
  9 
 10     var Pi = Math.PI;    	      	    // the 'Pi' number
 11 	var g = 9.81;
 12     var m0 = 1;    		      	        // the scale of weight
 13     var T0 = 1;    		      	        // the scale of time (period of oscillation the initial system)
 14 
 15     var k0 = 2 * Pi / T0;           	// the scale of frequency
 16     var C0 = 1;          	// the scale of stiffness
 17     var D0 = 0.001;  	      	    // the diameter
 18 	var p0 = 1;					// the pressure
 19 	var E0 = 1e-6;
 20 	var L = 300;
 21     // *** Setting the physical parameters ***
 22 	var E = 2.05e11 * E0;				// the elastic modulus
 23     var m = 3 * m0;                 	// the mass
 24     var C = 15 * C0;                 	// the stiffness
 25     var Dp = 43.1 * D0;                 	// the piston diameter
 26 	var Dsh = 17.3 * D0;					// the rod diameter
 27 	var p = 4 * p0;						// the pressure
 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     // *** Setting the computing parameters***
 36 
 37     var fps = 100;		      	        // frames per second
 38     var spf = 50;		      	        // steps per frame - the number of integration steps between frames (increases the calculation speed)
 39     var dt  = 0.05 * T0 / fps;    	    // the integration step (the quality of calculation)
 40     var steps = 0;                      // the number of integration steps
 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;       // calculate the system
 63     var v = 0;				// the body speed
 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     // the spring settings
 69     var coil = 11;        // the number of coils
 70     var startY = h;       // the spring fixation
 71 
 72     // a fancy yellow square
 73     var rect = {
 74         x: x0,  width: 50,
 75         y: y0,	height: 50,
 76         fill: "rgba(112, 155, 255, 1)"    	// yellow
 77     };
 78 
 79     //  mouse control
 80     var my_;                                    // mouse position buffer (to calculate the initial speed of the ball)
 81     document.onmousedown = function(e) {        // mouse click function 
 82         if (Dp <= Dsh)
 83 		{ 
 84 		alert("The diameter of the piston must be larger than the diameter of the rod");
 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);                 // getting coordinates of the mouse cursor
 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) {                         // left mouse button is pressed
 98                 rect.xPlus = rect.x - m.x;              // cursor displacement with respect to the mass on the X axis
 99                 rect.yPlus = rect.y - m.y;              // cursor displacement with respect to the mass on the Y axis
100                 my_ = m.y;
101                 count = false;
102                 document.onmousemove = mouseMove;       // while the mouse button is pressed the function works
103             }
104         }
105 			}
106     };
107 
108     document.onmouseup = function(e) {          // the working function when you release the mouse button
109         document.onmousemove = null;              // when the key is released displacement function does not work
110         count = true;
111     };
112 
113     function mouseMove(e) {                     // the function works only while holding LMB
114         var m = mouseCoords(e);                 // getting calculated coordinates of the mouse cursor
115         rect.y = m.y + rect.yPlus;
116 //        v = 6.0 * (m.x - mx_) / dt / fps;     // inertia conservation law
117         v = 0;
118         my_ = m.y;
119     }
120 
121     function mouseCoords(e) {                   // the function returns the calculated coordinates of the mouse cursor
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     // the graph
130     var vGraph = new New_graph(                  // initialisation of the graph
131         "#vGraph",                              // at html-page #vGraph
132         250,                                    // the number of steps by X axis
133         -1, 1, 0.2);                            // the minimum value of Y axis, the maximum value of Y axis, step along the Y axis
134 
135     function control() {
136         calculate();
137         draw();
138         requestAnimationFrame(control);
139     }
140     control();
141 //    setInterval(control, 1000 / fps);                       // starting system
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);   // streaming the data on the graph
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]);                    // adding a value to the end of the array
200     if (this.vArray.length > this.yArrayLen) this.vArray.shift(); // if the array has more 'yArrayLen' values, than remove the first one
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);  // drawing graph at the element "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);  // drawing graph at the element "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({                               // element "slider_m"
243             value:startVal, min: minVal, max: maxVal, step: stepVal,
244             slide: function( event, ui ) {                      // it works during movement of the slider
245                 $( htmlValueElement ).text( ui.value.toFixed(2) );    // it assigns a value to the text field "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 };

File "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     dpist = <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     drod = <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 is the mass, C is the coefficient of elasticity <br>dpist is the piston diameter, drod is the rod diameter<br>L is the rod length, p is the pressure in the shock absorber<br>Freb is the force of the tension stroke <br>Fcom is the force of the compression stroke 
33 	</td>
34 	</tr>
35 </body>
36 </html>