TMHP51_Lecture03.pdf

TMHP51 Servomechanisms (HT2012)
Lecture 03
Numerics
Model algorithm
Model refinement
Magnus Sethson
magnus.sethson@liu.se
1
1
Numerics
magnus.sethson@liu.se
2
2
Explicit Euler Method (Forward Euler)
The explicit Euler method is a general method for integrating
functions on a discreet grid. In simulation techniques the grid is
often one-dimensional time.
x[(n + 1) T ] = x[n T ] +
magnus.sethson@liu.se
T ẋ[n T ]
3
3
Implicit Euler Method (Backward Euler)
The implicit Euler method is also a general method for
integrating functions on a discreet grid. The numerical stability
is far better than the implicit, but it often comes with a need of
solving non-linear functions numerically in every time step.
x[(n + 1) T ] = x[n T ] +
magnus.sethson@liu.se
T ẋ[(n + 1) T ]
4
4
Explicit Trapetzoidal Method
The trapetzoidal method is a natural extension to the explicit
Euler method. It has far better frequency performance. It also
shares some characteristics with the transmission line modeling
and is therefore a highly suitable numeric method for hydraulic
systems simulation.
T
x[(n + 1) T ] = x[n T ] +
(ẋ[(n + 1) T ] + ẋ[n T ])
2
magnus.sethson@liu.se
5
5
Model Simulation
f
magnus.sethson@liu.se
t
6
6
Non-linear Model
8
p
A
B
ẋ
F
=
M
ẍ
>
L
p
p
p
L
t
p
>
>
<
q = Ap ẋp + 41 Vet ṗL
>
q
>
>
: q = Cq wxv 1 (Ps pL )
⇢
xv : Input signal
xp : Output signal
FL : External disturbance
xp , ẋp , pL : Internal states
magnus.sethson@liu.se
7
7
Explicit Euler Method
magnus.sethson@liu.se
8
8
Solving using Explicit Euler Method
0
1
0
1
xp [(n + 1) T ]
xp [n T ]
@ vp [(n + 1) T ] A = @ vp [n T ] A +
pL [(n + 1) T ]
pL [n T ]
0
1
0
ẋp
B
@ v̇p A = B
B
@
ṗL
magnus.sethson@liu.se
0
ẋp [n T ]
T @ v̇p [n T ] A
ṗL [n T ]
1
vp
4 e
Vt
⇣
p L Ap Bp v p F L
Mt
Cq wxv
q
1
⇢ (Ps
pL )
1
Ap v p
C
C
C
⌘ A
9
9
Sort equations, find iterative algorithm
q[(n + 1) T ] = Cq wxv [(n + 1) T ]
ṗL [(n + 1)
pL [(n + 1)
ẍp [(n + 1)
ẋp [(n + 1)
xp [(n + 1)
r
1
(Ps
⇢
pL [n T ])
4 e
T] =
(q[(n + 1) T ] Ap ẋp [n T ])
Vt
T ] = pL [n T ] + T ṗL [(n + 1) T ]
1
T] =
(pL [(n + 1) T ]Ap Bp ẋp [n T ]
Mt
T ] = ẋp [n T ] + T ẍp [(n + 1) T ]
T ] = xp [n T ] + T ẋp [(n + 1) T ]
FL [(n + 1) T ])
t
magnus.sethson@liu.se
10
10
From model, to algorithm, to code
Unr
ead
able
void servo_system(unsigned int nsamp) {
/* parameters and variables */
double pL=0; /* load pressure, initially zero, system state */
double Ps=70e5; /* supply pressure, 70 [bar] */
double rho=790; /* oil density, 790 [kg/m^3] */
double xv=0; /* spool displacement, (system input), initially zero*/
double w=8e-3; /* area gradient, [-] */
double Cq=0.67; /* flow coefficient, standard value, 0.67 [-] */
double dT=0; /* numerical integration time step size */
double T=0; /* time [s] */
double q=0; /* flow, [m^3/s] */
double Ap=0.001963495408; /* piston area, [m^2] (value from 50mm piston diameter) */
double vp=0; /* piston velocity, initially zero, system state */
double betae=1.5e9; /* bulk modulus of oil, [N/m^2] */
double Vt=0.001570796327; /* total cylinder volume, [m^3] (value from 50mm piston and 0.8m cylinder length) */
double Bp=5e4; /* system damping, [Ns/m] */
double Mt=500; /* system mass load, [kg] */
double xp=0; /* piston position within cylinder, [m] (main output), system state */
double FL=0; /* external load */
/* iteration variable */
unsigned long int n=0; /* iteration counter */
/* set up time step */
dT=0.2/nsamp;
/* write first line for T=0 */
printf("\"Te%u\",\"XVe%u\",\"PLe%u\",\"VPe%u\",\"XPe%u\"\n",nsamp,nsamp,nsamp,nsamp,nsamp);
printf("%.16f,%.16f,%.16f,%.16f,%.16f\n",T,xv,pL,vp,xp);
/* iterate and write result for nsamp time steps */
for(n=1;n<nsamp;n++) {
if(0.01<=T) xv=0.0001; /* on step T=0.01 the input is set to 0.1mm valve displacement */
if(0.08<=T) xv=0; /* on step T=0.08 the input is reset and valve is closed */
q=Cq*w*xv*sqrt((Ps-pL)/rho);
pL=pL+(q-Ap*vp)*4*betae/Vt*dT;
vp=vp+(pL*Ap-Bp*vp-FL)/Mt*dT;
xp=xp+vp*dT;
T=T+dT; /* increment time */
printf("%.16f,%.16f,%.16f,%.16f,%.16f\n",T,xv,pL,vp,xp);
}
}
magnus.sethson@liu.se
11
11
DEMO: Solving the model in plain C
Unr
ead
able
#include <stdio.h>
#include <math.h>
void servo_system(unsigned int nsamp) {
DEMO
DEMO
DEMO
/* parameters and variables */
double pL=0; /* load pressure, initially zero, system state */
double Ps=70e5; /* supply pressure, 70 [bar] */
double rho=790; /* oil density, 790 [kg/m^3] */
double xv=0; /* spool displacement, (system input), initially zero*/
double w=8e-3; /* area gradient, [-] */
double Cq=0.67; /* flow coefficient, standard value, 0.67 [-] */
double dT=0; /* numerical integration time step size */
double T=0; /* time [s] */
double q=0; /* flow, [m^3/s] */
double Ap=0.001963495408; /* piston area, [m^2] (value from 50mm piston diameter) */
double vp=0; /* piston velocity, initially zero, system state */
double betae=1.5e9; /* bulk modulus of oil, [N/m^2] */
double Vt=0.001570796327; /* total cylinder volume, [m^3] (value from 50mm piston and 0.8m cylinder length) */
double Bp=5e4; /* system damping, [Ns/m] */
double Mt=500; /* system mass load, [kg] */
double xp=0; /* piston position within cylinder, [m] (main output), system state */
double FL=0; /* external load */
/* iteration variable */
unsigned long int n=0; /* iteration counter */
/* set up time step */
dT=0.2/nsamp;
/* write first line for T=0 */
printf("\"Te%u\",\"XVe%u\",\"PLe%u\",\"VPe%u\",\"XPe%u\"\n",nsamp,nsamp,nsamp,nsamp,nsamp);
printf("%.16f,%.16f,%.16f,%.16f,%.16f\n",T,xv,pL,vp,xp);
/* iterate and write result for nsamp time steps */
for(n=1;n<nsamp;n++) {
if(0.01<=T) xv=0.0001; /* on step T=0.01 the input is set to 0.1mm valve displacement */
if(0.08<=T) xv=0; /* on step T=0.08 the input is reset and valve is closed */
q=Cq*w*xv*sqrt((Ps-pL)/rho);
pL=pL+(q-Ap*vp)*4*betae/Vt*dT;
vp=vp+(pL*Ap-Bp*vp-FL)/Mt*dT;
xp=xp+vp*dT;
T=T+dT; /* increment time */
printf("%.16f,%.16f,%.16f,%.16f,%.16f\n",T,xv,pL,vp,xp);
}
}
int main(int argc,char** argv) {
unsigned int nsamp=2000;
if(2==argc) sscanf(argv[1],"%u",&nsamp);
servo_system(nsamp);
return 0;
}
gcc -Wall -pedantic -o servo_explicit_euler servo_explicit_euler.c -lm
./servo_explicit_euler > servo_explicit_euler.csv
magnus.sethson@liu.se
12
12
Results Explicit Euler Method
Simulation Example, Explicit Euler Method
0.10
35
2.0
30
1.8
10
1.6
25
0.08
1.4
20
1.2
10
1.0
Xp [mm]
15
Vp [mm/s]
0.06
PL [bar]
Xv [mm]
5
0.8
0.04
0
5
0
0.02
Variables
Xv vs Time
PL vs Time
0
0
0.02
0.04
0.06
0.08
0.10
0.12
0.14
0.16
0.18
−5
Vp vs Time
Xp vs Time
0.20
0.22
0.6
0.4
−5
0.2
−10
0
Time [s]
magnus.sethson@liu.se
13
13
Results, Step Comparison
Simulation example, Euler's explicit method
2.0
Position Xp [mm]
1.5
1.0
0.5
Timesteps
ΔT=0.0167 (NaN)
ΔT=0.0111 (NaN)
ΔT=0.0091 (NaN)
ΔT=0.0080
ΔT=0.0040
ΔT=0.0020
ΔT=0.0010
ΔT=0.0001
0
−0.5
−1.0
0
magnus.sethson@liu.se
0.02
0.04
0.06
0.08
0.10 0.12
Time [s]
0.14
0.16
0.18
0.20
0.22
14
14
Implicit Euler Method
magnus.sethson@liu.se
15
15
Solving using Implicit Euler Method
0
1
0
1
xp [(n + 1) T ]
xp [n T ]
@ vp [(n + 1) T ] A = @ vp [n T ] A +
pL [(n + 1) T ]
pL [n T ]
0
1
0
ẋp [(n + 1) T ]
B
@ v̇p [(n + 1) T ] A = B
B
@
ṗL [(n + 1) T ]
magnus.sethson@liu.se
0
1
ẋp [(n + 1) T ]
T @ v̇p [(n + 1) T ] A
ṗL [(n + 1) T ]
vp [(n + 1) T ]
4 e
Vt
⇣
pL [(n+1) T ]Ap Bp vp [(n+1) T ] FL [(n+1) T ]
Mt
Cq wxv [(n + 1) T ]
q
1
⇢ (Ps
pL [(n + 1) T ])
Ap vp [(n + 1) T ]
1
C
C
C
⌘ A
16
16
Solving using Implicit Euler Method (cont.)
0
0
B
B
B
@
vp [(n + 1) T ]
4 e
Vt
⇣
ẋp [(n + 1) T ]
@ v̇p [(n + 1) T ] A =
ṗL [(n + 1) T ]
1
pL [(n+1) T ]Ap Bp vp [(n+1) T ] FL [(n+1) T ]
Mt
Cq wxv [(n + 1) T ]
magnus.sethson@liu.se
q
1
⇢ (Ps
pL [(n + 1) T ])
1
Ap vp [(n + 1) T ]
C
C
C
⌘ A
17
17
Newton-Raphson Method
The Newton-Raphson method for solving non-linear equations
numerically is widely adopted in many applications. Even if
originally defined in one dimension it is available in multidimensional versions also. It iterates and moves an initial guess
towards a near-by root-locus.
f (xk )
f 0 (xk )
xk+1 = xk
xk+1 = xk
J
1
f (xk )
One-dimensional
Multi-dimensional
@fi (x1...N )
Jij =
@xj
Hint:
f (xk+1 )
xk+1
f (xk )
⇡ f 0 (xk )
xk
magnus.sethson@liu.se
18
18
The Jacobian
0
B
B
TB
@
4 e
Vt
f (xp [(n + 1) T ], vp [(n + 1) T ], pL [(n + 1) T ]) =
0
1 0
1
xp [(n + 1) T ]
xp [n T ]
@ vp [(n + 1) T ] A @ vp [n T ] A
pL [(n + 1) T ]
pL [n T ]
1
vp [(n + 1) T ]
C
pL [(n+1) T ]Ap Bp vp [(n+1) T ] FL [(n+1) T ]
C
C
Mt
⇣
⌘ A
q
Cq wxv [(n + 1) T ] ⇢1 (Ps pL [(n + 1) T ]) Ap vp [(n + 1) T ]
magnus.sethson@liu.se
19
19
The Jacobian (cont.)
xk+1
J11 = 1
J12 =
xk = J
1
f (xk )
T
The Newton-Raphson method is often
solved like a linear set of equations,
avoiding the full Jacobian inverse.
J13 = 0
J21 = 0 (No spring involved!)
Bp
J22 = 1 +
T
Mt
Ap
J23 =
T
Mt
J31 = 0
4 e Ap
J32 =
T
Vt
4 e ⇢Cq wxv [(n + 1) T ][k]
p
J33 = 1 +
T
Vt 2 Ps pL [(n + 1) T ][k]
magnus.sethson@liu.se
J(xk ) dk+1 = J(xk )[xk+1
xk ] =
f (xk )
20
20
From model, to algorithm, to code
Unr
ead
able
void servo_system(unsigned int nsamp) {
/* parameters and variables */
double pL=0; /* load pressure, initially zero, system state */
double Ps=70e5; /* supply pressure, 70 [bar] */
double rho=790; /* oil density, 790 [kg/m^3] */
double xv=0; /* spool displacement, (system input), initially zero*/
double w=8e-3; /* area gradient, [-] */
double Cq=0.67; /* flow coefficient, standard value, 0.67 [-] */
double dT=0; /* numerical integration time step size */
double T=0; /* time [s] */
double Ap=0.001963495408; /* piston area, [m^2] (value from 50mm piston diameter) */
double vp=0; /* piston velocity, initially zero, system state */
double betae=1.5e9; /* bulk modulus of oil, [N/m^2] */
double Vt=0.001570796327; /* total cylinder volume, [m^3] (value from 50mm piston and 0.8m
cylinder length) */
double Bp=5e4; /* system damping, [Ns/m] */
double Mt=500; /* system mass load, [kg] */
double xp=0; /* piston position within cylinder, [m] (main output), system state */
double FL=0; /* external load */
gsl_vector_set(b,0,(xpk-xp-dT*vpk));
gsl_vector_set(b,1,(vpk-vp-dT*(pLk*Ap-Bp*vpk-FL)/Mt));
gsl_vector_set(b,2,(pLk-pL-dT*4*betae/Vt*(Cq*w*xv*sqrt((Ps-pL)/rho)-Ap*vpk)));
gsl_matrix_set(J,0,0,1.0);
gsl_matrix_set(J,0,1,-dT);
gsl_matrix_set(J,0,2,0.0);
gsl_matrix_set(J,1,0,0.0);
gsl_matrix_set(J,1,1,1+Bp/Mt*dT);
gsl_matrix_set(J,1,2,-Ap/Mt*dT);
gsl_matrix_set(J,2,0,1.0);
gsl_matrix_set(J,2,1,-4*betae*Ap/Vt*dT);
gsl_matrix_set(J,2,2,1.0+2*betae/Vt*rho*Cq*w*xv/sqrt(Ps-pLk)*dT);
gsl_matrix_memcpy(A,J);
gsl_blas_dgemv(CblasNoTrans, 1.0, J, xk, -1.0, b);
gsl_linalg_LU_decomp(J,p,&s);
gsl_linalg_LU_solve(J,p,b,x);
gsl_linalg_LU_refine(A,J,p,b,x,xk);
xpk=gsl_vector_get(x,0);
vpk=gsl_vector_get(x,1);
pLk=gsl_vector_get(x,2);
k++;
} while(k<20 && (abs(gsl_vector_get(x,0)/(xp+EPS))>RAC || abs(gsl_vector_get(x,1)/(vp
+EPS))>RAC || abs(gsl_vector_get(x,2)/(pL+EPS))>RAC));
/* GSL related structures */
gsl_matrix* J=NULL;
gsl_matrix* A=NULL;
gsl_vector* b=NULL;
gsl_vector* x=NULL;
gsl_vector* xk=NULL;
int s=0;
gsl_permutation* p=NULL;
double xpk=0;
double vpk=0;
double pLk=0;
/* iteration variable */
unsigned long int n=0; /* iteration counter */
unsigned long int k=0; /* numerical counter */
/* set up time step */
dT=0.2/nsamp;
xp=xpk;
vp=vpk;
pL=pLk;
/* set up GSL parts */
J=gsl_matrix_alloc(3,3);
A=gsl_matrix_alloc(3,3);
b=gsl_vector_alloc(3);
x=gsl_vector_alloc(3);
xk=gsl_vector_alloc(3);
p=gsl_permutation_alloc(3);
}
/* write first line for T=0 */
printf("\"Ti%u\",\"XVi%u\",\"PLi%u\",\"VPi%u\",\"XPi%u\"\n",nsamp,nsamp,nsamp,nsamp,nsamp);
printf("%.16f,%.16f,%.16f,%.16f,%.16f\n",T,xv,pL,vp,xp);
/* iterate and write result for nsamp time steps */
for(n=1;n<nsamp;n++) {
if(T>=0.01) xv=0.0001; /* on step T=0.01 the input is set to 0.1mm valve displacement */
if(T>=0.08) xv=0; /* on step T=0.08 the input is reset and valve is closed */
}
T=T+dT; /* increment time */
printf("%.16f,%.16f,%.16f,%.16f,%.16f\n",T,xv,pL,vp,xp);
/* clean up GSL */
gsl_permutation_free(p);
gsl_vector_free(xk);
gsl_vector_free(x);
gsl_vector_free(b);
gsl_matrix_free(A);
gsl_matrix_free(J);
/* implicit iteration loop */
k=0;
xpk=xp;
vpk=vp;
pLk=pL;
do {
gsl_vector_set(xk, 0, xpk);
gsl_vector_set(xk, 1, vpk);
gsl_vector_set(xk, 2, pLk);
magnus.sethson@liu.se
21
21
Results Implicit Euler Method
Simulation Example, Implicit Euler Method
0.10
35
2.0
30
1.8
10
1.6
25
0.08
1.4
20
1.2
10
1.0
Xp [mm]
15
Vp [mm/s]
0.06
PL [bar]
Xv [mm]
5
0.8
0.04
0
5
0
0.02
Variables
Xv vs Time
PL vs Time
0
0
0.02
0.04
0.06
0.08
0.10
0.12
0.14
0.16
0.18
−5
Vp vs Time
Xp vs Time
0.20
0.22
0.6
0.4
−5
0.2
−10
0
Time [s]
magnus.sethson@liu.se
22
22
Explicit Trapetzoid Method
magnus.sethson@liu.se
23
23
From model, to algorithm, to code
void servo_system(unsigned int nsamp) {
/* parameters and variables */
double pL=0; /* load pressure, initially zero, system state */
double Ps=70e5; /* supply pressure, 70 [bar] */
double rho=790; /* oil density, 790 [kg/m^3] */
double xv=0; /* spool displacement, (system input), initially zero*/
double w=8e-3; /* area gradient, [-] */
double Cq=0.67; /* flow coefficient, standard value, 0.67 [-] */
double dT=0; /* numerical integration time step size */
double T=0; /* time [s] */
double q=0; /* flow, [m^3/s] */
double Ap=0.001963495408; /* piston area, [m^2] (value from 50mm piston diameter) */
double vp=0; /* piston velocity, initially zero, system state */
double betae=1.5e9; /* bulk modulus of oil, [N/m^2] */
double Vt=0.001570796327; /* total cylinder volume, [m^3] (value from 50mm piston and 0.8m cylinder length) */
double Bp=5e4; /* system damping, [Ns/m] */
double Mt=500; /* system mass load, [kg] */
double xp=0; /* piston position within cylinder, [m] (main output), system state */
double FL=0; /* external load */
Unr
ead
able
/* trapetzoid related storage */
double npL=0;
double nvp=0;
double nxp=0;
double spL=0;
double svp=0;
double sxp=0;
/* iteration variable */
unsigned long int n=0; /* iteration counter */
/* set up time step */
dT=0.2/nsamp;
/* write first line for T=0 */
printf("\"Te%u\",\"XVe%u\",\"PLe%u\",\"VPe%u\",\"XPe%u\"\n",nsamp,nsamp,nsamp,nsamp,nsamp);
printf("%.16f,%.16f,%.16f,%.16f,%.16f\n",T,xv,pL,vp,xp);
/* iterate and write result for nsamp time steps */
for(n=1;n<nsamp;n++) {
if(0.01<=T) xv=0.0001; /* on step T=0.01 the input is set to 0.1mm valve displacement */
if(0.08<=T) xv=0; /* on step T=0.08 the input is reset and valve is closed */
spL=npL;
svp=nvp;
sxp=nxp;
q=Cq*w*xv*sqrt((Ps-pL)/rho);
npL=(q-Ap*vp)*4*betae/Vt;
pL=pL+0.5*(npL+spL)*dT;
nvp=(pL*Ap-Bp*vp-FL)/Mt;
vp=vp+0.5*(nvp+svp)*dT;
nxp=vp;
xp=xp+0.5*(nxp+sxp)*dT;
T=T+dT; /* increment time */
printf("%.16f,%.16f,%.16f,%.16f,%.16f\n",T,xv,pL,vp,xp);
}
}
magnus.sethson@liu.se
24
24
Results Explicit Trapetzoid Method
Simulation Example, Explicit Trapetzoid Method
0.10
35
2.0
30
1.8
10
1.6
25
0.08
1.4
20
1.2
10
1.0
Xp [mm]
15
Vp [mm/s]
0.06
PL [bar]
Xv [mm]
5
0.8
0.04
0
5
0
0.02
Variables
Xv vs Time
PL vs Time
0
0
0.02
0.04
0.06
0.08
0.10
0.12
0.14
0.16
0.18
−5
Vp vs Time
Xp vs Time
0.20
0.22
0.6
0.4
−5
0.2
−10
0
Time [s]
magnus.sethson@liu.se
25
25
Results, Method Comparison
Simulation Example, Method Comparison (ΔT=20μs)
2.0
0.10
1.8
10
1.6
1.80
0.08
1.4
0.091
0.092
1.76
4.8
0.8
0.04
0
4.6
Variables
Xv vs Time
PL,implicit vs Time
PL,trapetz vs Time
PL,explicit vs Time
Xp,implicit vs Time
Xp,trapetz vs Time
Xp,explicit vs Time
4.4
0.02
0.038
0
1.0
Xp [mm]
0.06
0.090
1.2
5
PL [bar]
Xv [mm]
1.78
0
0.02
0.04
0.039
0.06
0.040
4.2
0.08
0.10
0.12
0.14
0.16
0.18
0.20
0.6
0.4
−5
0.2
0.22
0
Time [s]
magnus.sethson@liu.se
26
26
Model Extensions
magnus.sethson@liu.se
27
27
Add Physics!!!
•
•
•
•
•
•
•
•
•
•
•
•
magnus.sethson@liu.se
Internal leakage
External springs
Asymmetric cylinder
End-of-Stroke conditions
Laminar flow
Valve dynamics
Supply system dynamics
Asymmetric valve orifice
Separate meter-in and meter-out
Piston friction
Long lines between cylinder and valve
Wave propagation in lines
28
28
Dynamic Mathematical Model Principles
Orifice
r
2
q = Cq wxv
(Pa
⇢
Pb )
Continuity
qin
qout
dV
V dp
=
+
dt
e dt
Force Balance
p 1 A1
magnus.sethson@liu.se
P2 A 2
FL
BL ẋp = Mt ẍp
29
29
Textual Simulation Computer Languages
C
magnus.sethson@liu.se
Matlab
VHDL-AMS
Haskell
C++
Modelica
Fortran 77
Haskell
Phyton
30
30
DEMO: Simple hydraulic servo system in plain C
/* An example of a simulation program for a very simple hydraulic servo
system */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
DEMO
DEMO
DEMO
#define PI 3.141592653589793
void warning(const char* msg,const char* fn,const int line) {
fprintf(stderr, "WARNING! %s(%d) : %s\n",fn,line,msg);
}
void cavitation(double p,const char* comp,const char* fn,const int line) {
if(p<0.7e5) {
fprintf(stderr, "WARNING! %s(%d) : CAVITATION in %s (p=%.16f)
\n",fn,line,comp,p);
}
}
double orifice(double Cq,double w,double xv,double rho,double p1,double p2) {
double q=0;
if(xv<0) return 0;
if(Cq<0) return 0;
if(w<0) return 0;
if(rho<0) return 0;
if(p1<0) return 0;
if(p2<0) return 0;
cavitation(p1, "orifice p1",__FILE__,__LINE__);
cavitation(p2, "orifice p2",__FILE__,__LINE__);
if((p1-p2)>0) {
q=+Cq*w*xv*sqrt(2/rho*(p1-p2));
} else {
q=-Cq*w*xv*sqrt(2/rho*(p2-p1));
}
return q;
}
double area(double Dp,double Dr) {
double A;
if(Dp<0) warning("Negative diameter in area()",__FILE__,__LINE__);
if(Dr<0) warning("Negative diameter in area()",__FILE__,__LINE__);
A=PI*(Dp*Dp-Dr*Dr)*0.25;
return A;
}
double volume(double Dp,double D,double L) {
double V=0;
if(L<0) warning("Negative length in volume()",__FILE__,__LINE__);
if(L>=0) V=area(Dp,D)*L;
return V;
}
double compression(double q,double V,double dV,double betae) {
double dp=0;
if(V<0) warning("Negative volume in compression()",__FILE__,__LINE__);
if(V>0) dp=(q-dV)*betae/V;
return dp;
}
double piston(double p1,double p2,double Dp,double d1,double d2) {
double Fc=0;
double A1=0;
double A2=0;
magnus.sethson@liu.se
A1=area(Dp,d1);
A2=area(Dp,d2);
Fc=p1*A1-p2*A2;
return Fc;
Unr
ead
able
double dp2=0;
double dV1=0;
double dV2=0;
}
/* trapetzoid numerical integration */
void trapetz(double dx,double state[3],double dT) {
state[2]=state[1];
state[1]=dx;
state[0]+=0.5*(state[1]+state[2])*dT;
}
double value(double state[3]) {
return state[0];
}
void initialize(double state[3],double x0) {
state[0]=x0;
state[1]=0;
state[2]=0;
}
double spring(double k,double L0,double x) {
double Fs=0;
if(k<0) warning("Negative spring coefficient in
spring()",__FILE__,__LINE__);
Fs=k*(x-L0);
return Fs;
}
void servo_system(unsigned int nsamp,double Tmax) {
/* system states */
double p1[3]; /* positive cylinder chamber pressure */
double p2[3]; /* positive cylinder chamber pressure */
double vp[3]; /* piston velocity */
double xp[3]; /* piston position */
/* parmeters and variables */
double Ps=70e5; /* supply pressure, 70 [bar] */
double Pt=1e5; /* tank pressure, 70 [bar] */
double rho=790; /* oil density, 790 [kg/m^3] */
double xv=0; /* spool displacement, (system input), initially zero*/
double w=8e-3; /* area gradient, [-] */
double Cq=0.67; /* flow coefficient, standard value, 0.67 [-] */
double dT=0; /* numerical integration time step size */
double Dp=0.050; /* piston diameter [m] */
double Dr1=0.020; /* rod diameter in chamber 1 [m] */
double Dr2=0.020; /* rod diameter in chamber 2 [m] */
double V01=0.0001; /* dead volume chamber 1 [m^3] */
double V02=0.0001; /* dead volume chamber 2 [m^3] */
double V1=0; /* total volume in chamber 1 */
double V2=0; /* total volume in chamber 2 */
double L=0.8; /* cylinder length */
double Fc=0; /* total applied force on piston */
double FL=0; /* external load force */
double T=0; /* time [s] */
double q1=0; /* flow into chamber 1, [m^3/s] */
double q2=0; /* flow into chamber 2, [m^3/s] */
double betae=1.5e9; /* bulk modulus of oil, [N/m^2] */
double Bp=5e4; /* system damping, [Ns/m] */
double Mt=500; /* system mass load, [kg] */
unsigned long int n=0; /* iteration counter */
/* temporaries */
double dp1=0;
initialize(p1,
initialize(p2,
initialize(vp,
initialize(xp,
Pt);
Pt);
0);
0);
dT=Tmax/nsamp;
printf("\"T\",\"x_v\",\"p_1\",\"p_2\",\"v_p\",\"x_p\",\"q_1\",
\"q_2\"\n");
n=0;
do {
T=n*dT;
if(0.01<=T) xv=0.0001; /* open valve */
if(0.08<=T) xv=0; /* close valve */
if(xv>=0) {
q1=orifice(Cq, w, xv, rho, Ps, value(p1));
q2=orifice(Cq, w, xv, rho, Pt, value(p2));
} else {
q1=orifice(Cq, w, -xv, rho, Pt, value(p1));
q2=orifice(Cq, w, -xv, rho, Ps, value(p2));
}
if(value(xp)<-0.5*L) {
initialize(xp, -0.5*L);
initialize(vp, 0);
}
if(value(xp)>+0.5*L) {
initialize(xp, +0.5*L);
initialize(vp, 0);
}
dV1=+value(vp)*area(Dp, Dr1);
dV2=-value(vp)*area(Dp, Dr2);
V1=volume(Dp, Dr1, 0.5*L+value(xp))+V01;
V2=volume(Dp, Dr2, 0.5*L-value(xp))+V02;
dp1=compression(q1, V1, dV1, betae);
dp2=compression(q2, V2, dV2, betae);
trapetz(dp1, p1, dT);
trapetz(dp2, p2, dT);
Fc=piston(value(p1), value(p2), Dp, Dr1, Dr2)-FL-Bp*value(vp);
trapetz(Fc/Mt, vp, dT);
trapetz(value(vp), xp, dT);
printf("%.12f,%.12f,%.12f,%.12f,%.12f,%.12f,%.12f,%.12f
\n",T,xv,value(p1),value(p2),value(vp),value(xp),q1,q2);
n++;
} while(n<nsamp);
}
int main(int argc, const char * argv[]) {
unsigned int nsamp=2000;
double Tmax=0.2;
if(2<=argc) sscanf(argv[1],"%u",&nsamp);
if(3==argc) sscanf(argv[2],"%lg",&Tmax);
servo_system(nsamp,Tmax);
return 0;
}
31
31
Simulation Programs
HOPSAN NG (FluMeS, LiU)
Dymola (Dassault Systems)
Amesim (LMS Intl.)
Easy5 (MSC Software)
magnus.sethson@liu.se
Flowmaster (Flowmaster Inc.)
Matlab/Simulink (Mathworks Inc)
32
32
magnus.sethson@liu.se
33
33
Examples
https://mechatronic.iei.liu.se/svn/TMHP_simulation/
magnus.sethson@liu.se
34
34
Next Lecture:
08:15, 2012-11-08, P34
Magnus Sethson
magnus.sethson@liu.se
35
35