Documente Academic
Documente Profesional
Documente Cultură
1
Capitolul 1: Introducere ................................................................................................................................4
2.3. Exemplificare................................................................................................................................20
4.4. Interfata.............................................................................................................................................36
3
Capitolul 1: Introducere
n ă ecuaţiile de miş un
mai general şi include frecă
aplicaţii inginereş Ecuaţ n
liniară simplă se propune
obţine setul de ecuaţii n
4
d
5
,
6
un
7
un
1.
8
2.
3.
9
.
10
Capitolul 2: Modelul matematic, modelare neliniara
± ( )
mi
μi
11
Figura 1 Pendul invers multi-link
(1)
− + = = 1, … , ( + 1) , = [ , 0,0, … ,0]
(2)
=( 1 … )
=1
12
∑ =1 ∑ ̇
1
2 =1
≠
1
2
(3)
1 2
= +
2
=1
−1
∗ ) + sin
2
+ sin( ( )
=−
−1
) + cos
2
′2
1
+ cos( ( ) +
=−
2
(4)
−1
"= ( )+
#( cos cos
( )
=1 =−
(5)
$= %( − −1 ) + % ′2
1 2
1
2 2
=1
13
(6)
= − + + , ( = 1, … , ( + 1))
=[ − ( ) ,− ( 1) 1 1
,…,− ( ) ]
(7)
−1
⎧
= ! + "# $ ′′
+ " # " &' [cos( ') '
′′
− sin( ') ']
⎪
2
⎪
+
'= −
⎪
=1 =1
⎪ " # * [cos( ) ′′
− sin( ) 2
]
⎨
=1
⎪
⎪
=0
⎪
⎪
=0
⎩ =+
(8)
−1
!+"# $ ′′
+ " , " &' [cos( ') '
′′
− sin( ' ) ' ]- #
2
=1 =1 '= −
+ " # * [cos( ) ′′
− sin( ) 2
]++ = − ( )
=1
14
(9)
−1
= + + cos( ) + cos
( − )
= +1 =−
2
+ +
= +1
−1
+ cos
( − ) + cos
( − )
= +1 = − = +1
(10)
= ′′
+ + cos( ) ′′
− + sin( ) ′
= +1 = +1
2 ′′
+ +
= +1
−1
+ cos( − ) ′′
− sin( − )( − )
=−
+ cos − ′′
− sin − ( − )
= +1
−1
+ [cos − ′′
− sin − ( − ) ]
= +1 = −
(11)
−1
=− + sin( ) ′
+ sin
( − )
= +1 =−
−1
+ sin
( − ) + ( −
sin )
= +1 = − = +1
15
(12)
=− + sin( )
= +1
(13)
=( + +1 )
′
− −1
′
+1 + ′
−1
(14)
+1 = + cos( ) ′′
+ 2
+ ′′
= +1 = +1
−1
+ [cos( − ) ′′
− sin( − ) ′′
]
=−
+ [cos − ′′
− sin − ′′
]
= +1
−1
+ [cos − ′′
− sin − 2
]
= +1 = −
− + sin( ) + ( + +1 )
′
− −1
′
+1 + ′
−1
= +1
(i = 1, ..., n)
(15)
( ) ′′
+ ( , ′) ′
+ ( )= ( , )
16
(16)
⎧
⎪
+ , =1
( )=
⎨
=1
⎪ −1 −1 −1 −1 , 1 ≤
⎩
2
+ + < +1
=
(17)
−2
⎧ ≤
⎪
⎪
cos
( ) + cos
( ) , = 1, 1 < +1
= −1 = − −1 = −1
⎪ −2
⎪ ≤
⎪
( ) +
cos cos
( ) , = 1, 1 < +1
= −1 = − −1 = −1
( )= −2
⎨
⎪⎛ [cos( − −1 )] −1 −1 +" #cos$ − −1 %&' −1 ⎞
⎪⎜ = − −1 ⎟ , , -./
⎪⎜ −1 ⎟
=
⎪⎜ ⎟
⎪ +" " ( ( − −1 %]' ' −1
⎩⎝ ⎠
[cos$
= (= −
(18)
34 , = 1
0 ( , ′)
=2
3 −1 + 3 ,1 < ≤ +1
(19)
0 ( , ′)
≤
⎧ −2
0, = 1, 1 < +1
⎪
⎪ − −1 ) −1 − −1 ) −1
⎪
sin( sin
(
= −1 = −1 = − −1
⎪ −2
⎨⎛
− − −1 ) −1 −1 −1 −" − −1 % −1 ' −1 ⎞
=
⎪⎜ ⎟ , , -./
sin( sin$
= − −1
⎪⎜ −1 ⎟
=
⎪⎜ ⎟
⎪ −" " ( sin
( ( − −1 ) −1 ' ' −1
⎩⎝ = (= − ⎠
17
(20)
⎧
0, =1
( )=
⎨− −1 −1 −1 −1 ) ,
⎩
+ sin(
=
(21)
− ( )
( , )=
− ( −1 )
, =1
−1 −1
,
(22)
(1) ( ) ′′
= −!( , ′) ′
− ( )+ ( , ) " =( 1 … )$
( (
(3) & ' %′ = & ' % + )−0 * + )0*
−!
0 0
0 0
Sau
(23)
(
%′ = & '% + + ,++ ,
− ! −
0 0
−1 −1 −1
0
0
Sau
(24)
% ′ ( ) = (%( ), ( ))
%0
%( )
18
(25)
=( 1 1 … −1 )
Stiind ca:
(26)
− , = 1, … , − 1
−1
= +1
= + , = 2, … ,
=1
γ + θ1 (i = 2, … , n)
−1
=1 k
( )
(27)
= −1, ≤ ≤ 2 + 2,
1, = ,
= + 1,2 < + 1, + 3 <
0,
( 1 2 1 2) ( 1 1 1 1)
1 0 00 0 0
⎛ ⎞
−1 10 0
0 1 00 0 0
= ⎜
⎜0 0⎟⎟
0 0
0 01 0
⎝0 0 00 −1 1⎠
0 0 00 1 0
19
2.3. Exemplificare
,
(28)
( + + 2) ̈+( + 2 1 ) cos( 1 ) 1
̈ + cos( 2 ) 2̈ +
−( 2 1 ) sin( 1 ) 1 − 2 2 sin( 2 ) 2 − ( )μ
1 1 1 2 2
2 2
1 1 + =
( + 2 1) ̈+ + 2
+ 2 ̈ + cos( − 2) 2
̈ +( + 2) 1 −
− 2) 2 − ( 2 1 ) sin 1 =− ( 1 )μ
1 1 1 1 1 2 1 1 2 2 1 1 1 2 2
2
+ 2 2 1 sin( 1 1 1 +
̈ + ̈ −
1 1
cos( 2 ) ̈ + cos( − 2) 1 + 2
sin( − 2) 1
2
−
− sin( 2 ) = −
2 2 2 2 1 1 2 2 2 2 2 2 1 1 2 1
+ 2 2 2 2 ( 2 )μ 2 2
1− 2) 1 − 3)
cos 3 cos 2 4 cos 3
( )=
1 2 1
− 2) 21 cos( 2 − 3)
9 cos 1 10 11 cos( 12 cos(
1 − 3) − 3)
18 cos 2 19 cos( 1 20
28 cos 3 29 cos( 30 cos( 2 31
G(q, ̇ )
sin( 1 ) sin( 2 ) sin( 3 ) 3
14 sin( 1 − 2 ) 16 sin( 1 − 3 ) 3
=⎛ ⎞
5 6 2 7 2 8
sin( 1 − 2 ) 1 + 25 sin( 2 − 3 ) 3 +
0 13 2 + 15
⎝0 33 sin( 1 − 3 ) 1 − 3) 2 ⎠
0 22 23 24 26
35 sin( 2 + 36 31
1)
0
( )=
27 sin( 2 )
17 sin(
34 sin( 3 )
20
Tabel 2. Constantele sistemului
1 1 2 + 3 19 ( 2 2 + 3 2) 1
2 1 1 + ( 2 + 3) 1 20 2 + 2 2
2
+ 3 2
2
3 2 2 + 3 2 21 3 3 2
4 3 3 22 − 1( 2 2 + 3 2)
5 23 − 2
6 − 1 1 −( 2 + 3) 1 24 2 + 3
7 −( 2 2 + 3 2) 25 3 3 2
8 − 3 3 26 − 3
9 1 1 + ( 2 + 3) 1 27 − ( 2 2 + 3 2)
2 2
10 1 + 1 1 +( 2 + 3) 1 28 3 3
11 ( 2 2 + 3 2) 1 29 3 3 1
12 3 3 1 30 3 3 2
2
13 1 + 2 31 3 + 3 3
14 ( 2 2 + 3 2) 1 32 3
15 − 2 33 − 3 3 1
16 3 3 1 34 − 3 3
17 − ( 1 1 + 2 + 3 1) 35 − 3 3 1
18 2 2 + 3 2 36 − 3
−
⎛− ⎞
( )μ
( , )=⎜ ⎟
−
( 1 )μ 1 1
−
( 2 )μ 2
⎝ ⎠
2
( 3 )μ 3 3
21
2.4. Tipuri de frecari
un
̇ =0
̇ ≠0
=
+
− <μ
≥μ
=
μ
=μ ( ̇ ),
= −" ̇
μ ,μ ,"
=( + #) .
22
0,08328
0,04287
0,3156
23
Capitolul 3: Controlul sistemului (strategii de comanda)
24
3.2. Aspecte preliminare
2
25
Figura 2. Sistem pendul invers si carut
,θe
26
2
2
=
F=M ̈ +b ̇ +N
2
1
2
= − −
2
=
2
1
2
= ( cos + sin )
2
= =
2
= 2
2
= = −
2
= ( 2
+ )
27
= − sin
= − cos
2 2 2 2
2
= 2
+ sin − cos 2
= cos
= − sin
2 2 2
2
= − cos − sin 2
2 2 2 2
N = m 2
= 2
+ sin − cos 2
2 2 2
P = m 2
= − cos − sin 2
28
Figura 4. Diagrama bloc controler fyzzy
un
– Fc.
29
numerice. Variabilele lingvistice sunt definite in limbaj normal (cum ar fi “mic” sau “mare”) si
μ ∶ → [0,1]
0 μ ( 0
30
Figura 5. Comfigurare de baza CLF
31
3
32
Tabel 3 Exemplu reguli control fuzzy
33
Capitolul 4: Aplicatie
̈+ 12 Ө
̈ =
̈+ ̈
22 Ө =
11
21
̈+ 12 Ө1
̈ + ̈ =
13 Ө2
̈+ ̈
22 Ө1 +
̈
23 Ө2 =
11
̈+ 32 Ө1 +
̈ 33 Ө2 =
̈
21
31
34
̈ Ӫ
−
⎧ ̈=
22 −
22 12
⎨Ӫ = 11 −
11 21 12
⎩ 22 −
21
11 21 12
̈
Ө1 ̈
11 12 13
Ө2̈
21 22 23 =
31 32 33
−1
̈
Ө1 ̈ −1
Ө2̈
=
′
= ̇
⎧ ′̇ = ̈
⎪
⎪Ө1 ′ = Ө1̇
̇′ = Ө1̈
⎨Ө1
⎪Ө2
⎪
′
= Ө2̇
⎩Ө2̇ ′ = Ө2̈
35
Tabelul Butcher
0
1/5 1/5
3/10 3/40 9/40
4/5 44/45 56/ 15 32/9
25360/
8/9 19372/6561 64448/6561 212/729
2187
1 9017/3168 355/33 46732/5247 49/176 5103/18656
1 35/384 0 500/113 125/192 2187/6784 11/84
35/384 0 500/113 125/192 2187/6784 11/84
5179/57600 0 7571/16695 393/640 92097/ 339200 187/2100 1/40
K1 = f(stare initiala, F)
K7 = f(stare initiala + DormandPrince6(k1, k2, k3, k4, k5, k6) * delta, F);
Stare finala = stare initiala + DormandPrince7(k1, k2, k3, k4, k5, k6, k7) * delta;
Unde Ki sunt stari intermediare, f functie incrementara folosita de algoritmul de evolutie, delta
timpul trecut de la pasul anterior si F forta aplicata de controlerul fuzzy.
4.4. Interfata
In interfata aplicatiei se pot observa schimbarile din sistemul pendulului invers. Utilizatorului i se
da posiblitatea de a interactiona cu procesul in timp real, modificand parametrii in care functioneaza
sistemul. Parametrii configurabili sunt: masa si coeficientii de frecare ai caruciorului, masele si
coeficientii de frecare ale pendulelor, starea initiala a sistemului, precum si perturbari in sistem
actionand cu un anumit impuls asupra pendulelor. De asemenea exista posibilitatea de a schimba din
36
sistem dublu in sistem simplu si invers, sau de a reporni sistemul din starea initiala si utilizatorului poate
observa evolutia sistemului fara reglare sau cu reglare.
37
Capitolul 5: Concluzii
un
d
,
.
38
Anexa A: Codul aplicatiei
constuint DEFAULT_THETA_FUZZY_STATE_GRADE = 3;
constuint DEFAULT_D_THETA_FUZZY_STATE_GRADE = 2;
constuint DEFAULT_X_FUZZY_STATE_GRADE = 2;
constuint DEFAULT_D_X_FUZZY_STATE_GRADE = 3;
constuint DEFAULT_FORCE_PENDULUM_FUZZY_STATE_GRADE = 4;
constuint DEFAULT_FORCE_CART_FUZZY_STATE_GRADE = 4;
constdouble DEFAULT_THETA_MAX_RANGE = 0.02;
constdouble DEFAULT_D_THETA_MAX_RANGE = 0.4;
constdouble DEFAULT_X_MAX_RANGE = 2.0;
constdouble DEFAULT_D_X_MAX_RANGE = 0.03;
constdouble DEFAULT_FORCE_PENDULUM_MAX_RANGE = 150.0;
constdouble DEFAULT_FORCE_CART_MAX_RANGE = 80.0;
staticuint theta_fuzzy_state_grade;
staticuint d_theta_fuzzy_state_grade;
staticuint x_fuzzy_state_grade;
staticuint d_x_fuzzy_state_grade;
staticuint force_pendulum_fuzzy_state_grade;
staticuint force_cart_fuzzy_state_grade;
staticdouble theta_max_range;
staticdouble d_theta_max_range;
staticdouble x_max_range;
staticdouble d_x_max_range;
staticdouble force_pendulum_max_range;
staticdouble force_cart_max_range;
staticFuzzyController instance = null;
public FuzzyController()
{
theta_fuzzy_state_grade = DEFAULT_THETA_FUZZY_STATE_GRADE;
d_theta_fuzzy_state_grade = DEFAULT_D_THETA_FUZZY_STATE_GRADE;
x_fuzzy_state_grade = DEFAULT_X_FUZZY_STATE_GRADE;
d_x_fuzzy_state_grade = DEFAULT_D_X_FUZZY_STATE_GRADE;
force_pendulum_fuzzy_state_grade =
DEFAULT_FORCE_PENDULUM_FUZZY_STATE_GRADE;
force_cart_fuzzy_state_grade =
39
DEFAULT_FORCE_CART_FUZZY_STATE_GRADE;
theta_max_range = DEFAULT_THETA_MAX_RANGE;
d_theta_max_range = DEFAULT_D_THETA_MAX_RANGE;
x_max_range = DEFAULT_X_MAX_RANGE;
d_x_max_range = DEFAULT_D_X_MAX_RANGE;
force_pendulum_max_range = DEFAULT_FORCE_PENDULUM_MAX_RANGE;
force_cart_max_range = DEFAULT_FORCE_CART_MAX_RANGE;
double fuzzy_state = value * (double)grade / max_range;
int result;
if (fuzzy_state > 0)
{
if (fuzzy_state > (double)grade 0.5)
{
return (int)grade;
}
result = 0;
while (fuzzy_state > 0.5)
{
result++;
fuzzy_state = 1.0;
}
return result;
}
else
{
if (fuzzy_state < (double)grade + 0.5)
{
return (int)grade;
}
result = 0;
while (fuzzy_state < 0.5)
{
result;
fuzzy_state += 1.0;
}
return result;
}
}
privatestaticint GetXFuzzyState(double x)
{
return GetFuzzyState(x, x_fuzzy_state_grade,
x_max_range);
}
if (DEBUG_FUZZY_CONTROLLER)
{
debug_fuzzy_states[0] = theta_fuzzy_state;
debug_fuzzy_states[1] = d_theta_fuzzy_state;
debug_fuzzy_states[4] = force_pendulum_fuzzy_state;
}
return force_pendulum_max_range *
(double)force_pendulum_fuzzy_state /
(double)force_pendulum_fuzzy_state_grade;
}
if (DEBUG_FUZZY_CONTROLLER)
{
debug_fuzzy_states[2] = x_fuzzy_state;
debug_fuzzy_states[3] = d_x_fuzzy_state;
debug_fuzzy_states[5] = force_cart_fuzzy_state;
}
return force_cart_max_range *
(double)force_cart_fuzzy_state /
(double)force_cart_fuzzy_state_grade;
}
if (DEBUG_FUZZY_CONTROLLER)
{
debug_input_values[0] = s.theta;
debug_input_values[1] = s.d_theta;
debug_input_values[2] = s.x;
debug_input_values[3] = s.d_x;
}
double force_pendulum = GetForcePendulum(s.theta, s.d_theta);
double force_cart = GetForceCart(s.x, s.d_x);
if (DEBUG_FUZZY_CONTROLLER)
{
bool same = true;
for (int i = 0; i < 6; i++)
{
if (saved_debug_fuzzy_states[i] != debug_fuzzy_states[i])
{
same = false;
break;
}
}
if (same)
{
debug_same_result_count++;
Console.Out.Write(".");
Console.Out.Write("Input: Theta = ");
Console.Out.Write(debug_input_values[0]);
Console.Out.Write(", DTheta = ");
Console.Out.Write(debug_input_values[1]);
Console.Out.Write(", X = ");
Console.Out.Write(debug_input_values[2]);
Console.Out.Write(", DX = ");
Console.Out.Write(debug_input_values[3]);
Console.Out.Write(", NEXT_DT = ");
Console.Out.Write(dt);
42
Console.Out.WriteLine();
}
else
{
Console.Out.Write(debug_same_result_count);
Console.Out.WriteLine();
Console.Out.WriteLine();
Console.Out.Write("Force = ");
Console.Out.Write(force_pendulum force_cart);
Console.Out.WriteLine();
43
constdouble DEFAULT_PENDULUM_MASS = 0.1;
constdouble DEFAULT_PENDULUM_LENGTH = 2.0;
constdouble DEFAULT_PENDULUM_DISTANCE_TO_CENTER = 0.5;
constdouble DEFAULT_PENDULUM_INERTIA_MOMENTUM =
DEFAULT_PENDULUM_MASS * DEFAULT_PENDULUM_LENGTH * DEFAULT_PENDULUM_LENGTH
/ 3.0;
constdouble DEFAULT_PENDULUM_VISCOUS_FRICTION = 0.0;
constdouble G = 9.8;
// Let's note:
// Constants:
// M = cart mass
// m = pendulum mass
// l = distance from pendulum base to center of gravity
// I = pendulum moment of inertia
// cc = cart viscous friction
// cp = pendulum viscous friction
// u = cart Coulomb friction
// G = gravity
//
// Variables:
// pA = pendulum angular position
// pDA = pendulum angular velocity (derived position)
// pDDA = pendulum angular acceleration (derived velocity)
// cX = cart position
// cDX = cart velocity (derived position)
// cDDX = cart acceleration (derived velocity)
// cos = cos(pA)
// sin = sin(pA)
//
// The next differential equations must be solved:
// (M+m) * cDDX + (m * l * cos) * pDDA =
// cc * cDX + (m * l * sin) * pDA * pDA (sgn(cDX) * u * (M + m) * G))
// + F;
// (m * l * cos) * cDDX + (I + m * l * l) * pDDA =
// cp * pDA + G * m * l * sin;
//
// By noting:
// A = M+m
// B = (m * l * cos)
// C = cc * cDX + (m * l * sin) * pDA * pDA (sgn(cDX) * u * (M + m) * G))
// D = (m * l * cos)
// E = I + m * l * l
// H = cp * pDA + G * m * l * sin
// The next system is obtained:
// A * cDDX + B * pDDA = C + F
// D * cDDX + E * pDDA = H
// So cDDX and pDDA can be computed as:
// cDDX = ((C + F) * E H * B) / (A * E D * B)
// pDDA = ((C + F) * D H * A) / (B * D E * A)
// These results are used when computing system evolution
staticdouble cart_mass;
staticdouble pendulum_mass;
//static double length; // unused for single inverted pendulum
staticdouble l;
staticdouble inertia;
staticdouble cc;
44
staticdouble uc;
staticdouble cp;
staticdouble total_mass;
staticdouble m_l;
staticdouble i_and_m_l_l;
staticdouble u_total_mass_G;
staticdouble m_l_G;
staticInvertedPendulum instance = null;
private InvertedPendulum()
{
cart_mass = DEFAULT_CART_MASS;
pendulum_mass = DEFAULT_PENDULUM_MASS;
l = DEFAULT_PENDULUM_DISTANCE_TO_CENTER;
inertia = DEFAULT_PENDULUM_INERTIA_MOMENTUM;
cc = DEFAULT_CART_VISCOUS_FRICTION;
uc = DEFAULT_CART_COULOMB_FRICTION;
cp = DEFAULT_PENDULUM_VISCOUS_FRICTION;
ComputeConstants();
}
privatestaticvoid ComputeConstants()
{
total_mass = cart_mass + pendulum_mass;
m_l = pendulum_mass * l;
i_and_m_l_l = inertia + m_l * l;
u_total_mass_G = uc * total_mass * G;
m_l_G = m_l * G;
}
privatestaticvoid check()
{
if (instance == null)
{
instance = newInvertedPendulum();
}
}
// A = M+m
// B = (m * l * cos)
// C = cc * cDX + (m * l * sin) * pDA * pDA (sgn(cDX) * u * (M + m) * G))
// D = (m * l * cos)
// E = I + m * l * l
// H = cp * pDA + G * m * l * sin
double a = total_mass;
double b = m_l * cos;
double c =
45
cc * s.d_x + m_l * sin * s.d_theta * s.d_theta sgn * u_total_mass_G;
double d = b;
double e = i_and_m_l_l;
double h = cp * s.d_theta + m_l_G * sin;
// cDDX = ((C + F) * E H * B) / (A * E D * B)
// pDDA = ((C + F) * D H * A) / (B * D E * A)
double c_and_f = c + f;
double ae_minus_bd = a * e b * d;
result.x = s.d_x;
result.d_x = (c_and_f * e h * b) / ae_minus_bd;
result.theta = s.d_theta;
result.d_theta = (h * a c_and_f * d) / ae_minus_bd;
return result;
}
return s + dt * DormandPrince.DP7(temp);
}
publicstaticdouble GetPendulumLength()
{
return DEFAULT_PENDULUM_LENGTH;
}
}
46
constdouble DEFAULT_PENDULUM_MASS_2 = 0.1;
constdouble DEFAULT_PENDULUM_LENGTH_2 = 2.0;
constdouble DEFAULT_PENDULUM_DISTANCE_TO_CENTER_2 = 0.5;
constdouble DEFAULT_PENDULUM_INERTIA_MOMENTUM_2 =
DEFAULT_PENDULUM_MASS_2 * DEFAULT_PENDULUM_LENGTH_2 *
DEFAULT_PENDULUM_LENGTH_2 /
3.0;
constdouble DEFAULT_PENDULUM_VISCOUS_FRICTION_2 = 0.0;
constdouble G = 9.8;
staticdouble cart_mass;
staticdouble cart_vf;
staticdouble cart_cf;
staticdouble m1;
staticdouble L1;
staticdouble l1;
staticdouble I1;
staticdouble vf1;
staticdouble m2;
staticdouble L2;
staticdouble l2;
staticdouble I2;
staticdouble vf2;
private DoubleInvertedPendulum()
{
cart_mass = DEFAULT_CART_MASS;
cart_vf = DEFAULT_CART_VISCOUS_FRICTION;
cart_cf = DEFAULT_CART_COULOMB_FRICTION;
m1 = DEFAULT_PENDULUM_MASS_1;
L1 = DEFAULT_PENDULUM_LENGTH_1;
l1 = DEFAULT_PENDULUM_DISTANCE_TO_CENTER_1;
I1 = DEFAULT_PENDULUM_INERTIA_MOMENTUM_1;
vf1 = DEFAULT_PENDULUM_VISCOUS_FRICTION_1;
m2 = DEFAULT_PENDULUM_MASS_2;
L2 = DEFAULT_PENDULUM_LENGTH_2;
l2 = DEFAULT_PENDULUM_DISTANCE_TO_CENTER_2;
I2 = DEFAULT_PENDULUM_INERTIA_MOMENTUM_2;
vf2 = DEFAULT_PENDULUM_VISCOUS_FRICTION_2;
ComputeConstants();
}
staticdouble Mt;
staticdouble mt;
staticdouble I1t;
47
staticdouble I2t;
staticdouble m2l2;
staticdouble ml2L1;
privatestaticvoid ComputeConstants()
{
Mt = cart_mass + m1 + m2;
mt = m1 * l1 + m2 * L1;
I1t = I1 + m1 * l1 * l1 + m2 * L1 * L1;
I2t = I2 + m2 * l2 * l2;
m2l2 = m2 * l2;
ml2L1 = m2 * l2 * L1;
}
Matrix3x3 coefficients =
newMatrix3x3(Mt, mt * cos, m2l2 * cos2,
mt, I1t, ml2L1 * cos_diff,
m2l2, ml2L1 * cos_diff, I2t);
result.x = s.d_x;
result.d_x = 0;
result.theta = s.d_theta;
result.d_theta = 0;
result.theta2 = s.d_theta2;
result.d_theta2 = 0;
coefficients.Invert();
coefficients.RightMultiplyWithVector(
cart_vf * s.d_x + mt * sin * s.d_theta * s.d_theta +
m2l2 * sin2 * s.d_theta2 * s.d_theta2 sign * cart_cf * Mt * G,
(vf1 + vf2) * s.d_theta + vf2 * s.d_theta2
ml2L1 * sin_diff * s.d_theta2 * s.d_theta2 + G * mt * sin,
ml2L1 * sin_diff * s.d_theta * s.d_theta +
vf2 * (s.d_theta s.d_theta2) + G * m2l2 * sin2,
ref result.d_x, ref result.d_theta, ref result.d_theta2);
return result;
}
return s + dt * DormandPrince.DP7(temp);
}
publicstaticdouble GetFirstPendulumLength()
{
return L1;
}
publicstaticdouble GetSecondPendulumLength()
{
return L2;
}
}
publicdouble theta2;
publicdouble d_theta2;
publicstaticSystemStatusoperator+(SystemStatus x, SystemStatus y)
{
SystemStatus result = newSystemStatus ();
return result;
}
return result;
49
}
result.x = x.x * a;
result.theta = x.theta * a;
result.theta2 = x.theta2 * a;
result.d_x = x.d_x * a;
result.d_theta = x.d_theta * a;
result.d_theta2 = x.d_theta2 * a;
return result;
}
publicstaticSystemStatus DP1(SystemStatus[] k)
{
return DP[0] * k[0];
}
publicstaticSystemStatus DP2(SystemStatus[] k)
{
return DP[1] * k[0] + DP[2] * k[1];
}
publicstaticSystemStatus DP3(SystemStatus[] k)
50
{
return DP[3] * k[0] + DP[4] * k[1] + DP[5] * k[2];
}
publicstaticSystemStatus DP4(SystemStatus[] k)
{
return DP[6] * k[0] + DP[7] * k[1] + DP[8] * k[2] + DP[9] * k[3];
}
publicstaticSystemStatus DP5(SystemStatus[] k)
{
return DP[10] * k[0] + DP[11] * k[1] + DP[12] * k[2] + DP[13] * k[3] +
DP[14] * k[4];
}
publicstaticSystemStatus DP6(SystemStatus[] k)
{
return DP[15] * k[0] + DP[16] * k[1] + DP[17] * k[2] + DP[18] * k[3] +
DP[19] * k[4] + DP[20] * k[5];
}
publicstaticSystemStatus DP7(SystemStatus[] k)
{
return DP[21] * k[0] + DP[22] * k[1] + DP[23] * k[2] + DP[24] * k[3] +
DP[25] * k[4] + DP[26] * k[5] + DP[27] * k[6];
}
}
privatestaticEngine instance = null;
staticbool use_double;
long lastFrameTime;
constlong FRAME_RATE = 60;
constlong FRAME_LENGTH = 1000 / FRAME_RATE;
publicconstdouble WORLD_HEIGHT = 8.0;
publicconstdouble WORLD_WIDTH = 32.0;
public Engine()
{
if (instance != null)
{
return;
}
instance = this;
use_double = true;
systemStatus = newSystemStatus ();
systemStatus.x = 0.0;
51
systemStatus.d_x = 0.0;
systemStatus.theta = 0.4;
systemStatus.d_theta = 0.0;
systemStatus.theta2 = 0.0;
systemStatus.d_theta2 = 0.0;
// start thread
Thread thread = newThread(newThreadStart(run));
thread.Start();
}
publicvoid run()
{
// start a stopwatch to count time
Stopwatch stopwatch = Stopwatch.StartNew();
stopwatch.Start();
if (use_double)
{
systemStatus =
DoubleInvertedPendulum.Evolution(systemStatus,
FuzzyController.GetForce(systemStatus,
elapsedTime),
elapsedTime);
}
else
{
systemStatus =
InvertedPendulum.Evolution(systemStatus,
FuzzyController.GetForce(systemStatus,
elapsedTime),
elapsedTime);
}
Main.Draw();
}
}
publicstaticSystemStatus GetSystemStatus()
{
return systemStatus;
52
}
53
Anexa B: Interfata aplicatiei
54
Bibliografie
K. Tanaka and M. Sugeno , “Stability analysis and design of fuzzy Control systems”,
156, 1992.
55
C.W. Tao, et al., “Fuzzy
–cart system”, Fuzzy Sets and Systems (2008),ScienceDirect
L. A. Zadeh, “Outline of a new approach of the analysis of complex system and decision
processes,” IEEE Trans. Syst 44, 1963.
, ,
56