Difference between revisions of "Modeling of a shock absorber"

From Department of Theoretical and Applied Mechanics
Jump to: navigation, search
m
m
Line 34: Line 34:
  
 
     var canvas = spring_canvas;
 
     var canvas = spring_canvas;
     canvas.onselectstart = function () {return false;};    // the prohibition of canvas selection
+
     canvas.onselectstart = function () {return false;};    // disabling canvas selection
     var ctx = canvas.getContext("2d");                      // the drawing takes place on ctx
+
     var ctx = canvas.getContext("2d");                      // ctx drawing  
     var w = canvas.width;                                  // the width of the window in the calculated coordinates
+
     var w = canvas.width;                                  // the width of the window in the actual coordinates
     var h = canvas.height;                                  // the height of the window in the calculated coordinates
+
     var h = canvas.height;                                  // the height of the window in the actual coordinates
  
 
     var Pi = Math.PI;              // the 'Pi' number
 
     var Pi = Math.PI;              // the 'Pi' number
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 parameters of computing ***
+
     // *** Setting the computing parameters***
  
     var fps = 100;               // frames per second (the display quality)
+
     var fps = 100;               // frames per second
     var spf = 50;               // steps per frame   - the number of integration steps between frames (increase the calculation speed)
+
     var spf = 50;               // steps per frame - the number of integration steps between frames (increases the calculation speed)
 
     var dt  = 0.05 * T0 / fps;        // the integration step (the quality of calculation)
 
     var dt  = 0.05 * T0 / fps;        // the integration step (the quality of calculation)
 
     var steps = 0;                      // the number of integration steps
 
     var steps = 0;                      // the number of integration steps
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;      // the verification of the system calculation
+
     var count = true;      // calculate the system
 
     var v = 0; // the body speed
 
     var v = 0; // the body speed
  
Line 101: Line 101:
 
     var startY = h;      // the spring fixation
 
     var startY = h;      // the spring fixation
  
     // the creation of a rectangle-sinker
+
     // 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)"    // colour
+
         fill: "rgba(112, 155, 255, 1)"    // yellow
 
     };
 
     };
  
     // the capture a rectangle by the mouse
+
     // mouse control
     var my_;                                    // the buffer of mouse position (to calculate the speed of the ball releasing)
+
     var my_;                                    // mouse position buffer (to calculate the initial speed of the ball)
     document.onmousedown = function(e) {        // the function of mouse click
+
     document.onmousedown = function(e) {        // mouse click function
 
         if (Dp <= Dsh)
 
         if (Dp <= Dsh)
 
{  
 
{  
Line 120: Line 120:
 
}
 
}
 
else {
 
else {
var m = mouseCoords(e);                // getting calculated coordinates of the mouse cursor
+
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 127: Line 127:
 
         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) {                        // left mouse button is pressed
 
             if (e.which == 1) {                        // left mouse button is pressed
                 rect.xPlus = rect.x - m.x;              // cursor displacement with respect to the sinker on the X axis
+
                 rect.xPlus = rect.x - m.x;              // cursor displacement with respect to the mass on the X axis
                 rect.yPlus = rect.y - m.y;              // cursor displacement with respect to the sinker on the Y axis
+
                 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;      // while the mouse button is pressed the function of movement works
+
                 document.onmousemove = mouseMove;      // while the mouse button is pressed the function works
 
             }
 
             }
 
         }
 
         }
Line 145: Line 145:
 
         var m = mouseCoords(e);                // getting calculated coordinates of the mouse cursor
 
         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;    // inertia conservation
+
//        v = 6.0 * (m.x - mx_) / dt / fps;    // inertia conservation law
 
         v = 0;
 
         v = 0;
 
         my_ = m.y;
 
         my_ = m.y;
Line 159: Line 159:
  
 
     // the graph
 
     // the graph
     var vGraph = new New_graph(                  // the determination of the graph
+
     var vGraph = new New_graph(                  // initialisation of the graph
 
         "#vGraph",                              // at html-page #vGraph
 
         "#vGraph",                              // at html-page #vGraph
 
         250,                                    // the number of steps by X axis
 
         250,                                    // the number of steps by X axis
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);  // submitting the data on graph
+
             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]);                    // adding value to the end of the array
+
     this.vArray.push([x, y]);                    // adding a value to the end of the array
     if (this.vArray.length > this.yArrayLen) this.vArray.shift(); // if the array has more 'yArrayLen' values, we remove the first one
+
     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 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({                              // slider on div - element "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 ) {                      // it works during movement of the slider
 
             slide: function( event, ui ) {                      // it works during movement of the slider
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>

Revision as of 18:56, 26 May 2016

Virtual laboratory > Modeling of 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.

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>