![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
controle pendulo roda reacao
Dependencies: mbed MatrixMath QEI Matrix USBDevice
main.cpp
- Committer:
- gabrielpdn
- Date:
- 2020-03-11
- Revision:
- 0:200d9e41a3cf
File content as of revision 0:200d9e41a3cf:
#include "mbed.h" #include "math.h" #include "USBSerial.h" #include "QEI.h" #include "Matrix.h" #include "MatrixMath.h" #define Ts 0.01 #define en2rad_roda 0.006698491798699 //#define en2rad_pend 0.001591485640116 //#define en2rad_roda 0.014660765717029 #define en2rad_pend 0.001570796326795 #define rad2graus 57.295779513082320 #define pi 3.141592653589793 #define omega_nd 210 USBSerial PC; Ticker tick; QEI enc_roda (PTB17, PTD0, NC, 469); QEI enc_pend (PTA12, PTA13, NC, 1000); //QEI enc_roda (PTC2, PTC1, NC, 341.2); //QEI enc_pend (PTD6, PTD5, NC, 1974); DigitalOut OnBoardLed (D13); int aux = 0; float pac = 0.0; // Variaveis encoders float theta = 0.0, theta_1 = 0.0, dtheta = 0.0; float alpha = 0.0, alpha_1 = 0.0, dalpha = 0.0; float angulo = 0.0; float xc1 = 0.0, xc2 = 0.0, xc3 = 0.0, xc4 = 0.0; float dxc1 = 0.0, dxc2 = 0.0, dxc3 = 0.0, dxc4 = 0.0; // Motor DigitalOut InA(PTD5); DigitalOut InB(PTC1); PwmOut V(PTD6); float th5=0.0; float th5_1=0.0; float dth5=0.0; // Alimentacao encoder motor DigitalOut vcc_enc (PTB0); // Variaveis de medida int N=0; const int tempo = 15/Ts; float th[tempo], dth[tempo], alp[tempo], dalp[tempo], u[tempo]; // variavel controle Matrix Z1(1,3); Matrix Z2(1,3); Matrix Z3(1,3); Matrix Y1(3,3); Matrix Y2(3,3); Matrix Y3(3,3); Matrix Z(1,3); Matrix Y(3,3); Matrix K(1,3); float lim_1 = -0.261799387799149; float lim_2 = 0.261799387799149; float rho1 = 0.0, rho2 = 0.0; float u_pwm = 0.0; // drive motor void drive(float u) { int direction=0; if (u>0)direction=1; if (u<0)direction=2; if(u==0)direction=0; switch(direction) { case 0: V.write(u); InA=0; InB=0; break; case 1: V.write(u); InA=1; InB=0; break; case 2: V.write(-u); InA=0; InB=1; break; default: V.write(0.0); InA=0; InB=0; break; } } // Interrupção void inverte() { aux=1; //N++; } int main () { Z1 << 0.0528635583471 << 55.1775667591881 << -334.6107239814101; Z2 << 2.2178052729892 << 89.4963037908543 << -632.0606939025414; Z3 << 0.0527550080233 << 55.1818544517557 << -334.6407739018230; Y1 << 52.229273 << -293.202697 << -1000.523522 << -351.739401 << 8417.246435 << -49726.191528 << -487.165029 << -53707.951308 << 505666.562609; Y2 << 79.768194 << -492.424621 << -1138.974682 << -454.513497 << 15400.080131 << -103976.618630 << -1476.885923 << -101235.956011 << 992352.224275; Y3 << 52.229040 << -293.201469 << -1000.518230 << -351.740390 << 8417.269581 << -49726.325976 << -487.140469 << -53708.234657 << 505667.351490; // LQR contuinuo float K1 = 6.307583719273756; float K2 = 0.808578597390600; float K3 = 0.091291588353526; vcc_enc = 1; OnBoardLed = 1; V.period(0.0001); wait(5); tick.attach(&inverte,Ts); while (1) { if(aux == 1){ aux = 0; theta=enc_roda.getPulses()*en2rad_roda; dtheta=(theta-theta_1)/Ts; theta_1=theta; angulo=enc_pend.getPulses()*en2rad_pend; alpha = angulo - pi*angulo/abs(angulo); dalpha=(alpha-alpha_1)/Ts; alpha_1=alpha; // Disturbio /*if (N>7/Ts && N<7.2/Ts){ alpha = alpha-7*pi/180; }*/ // Variavel LPV rho1 = (alpha - lim_1)/(lim_2-lim_1); rho2 = 1-rho1; // Controle Y = rho1*rho1*Y1+rho1*rho2*Y2+rho2*rho2*Y3; Z = rho1*rho1*Z1+rho1*rho2*Z2+rho2*rho2*Z3; K = Z*MatrixMath::Inv(Y); u_pwm = K.getNumber(1,1)*alpha + K.getNumber(1,2)*dalpha + K.getNumber(1,3)*dtheta; //u_pwm = K1*alpha + K2*dalpha + K3*dtheta; // Saturação da roda if (u_pwm>1.0) u_pwm=1.0; if (u_pwm<-1.0) u_pwm=-1.0; drive(u_pwm); if (N<tempo) { th[N] = theta; dth[N] = dtheta; alp[N] = alpha; dalp[N] = dalpha; u[N] = u_pwm; } if (N == tempo) { tick.detach(); drive(0.0); for (N=0; N<tempo; N++) PC.printf("%f %f %f %f %f\n\r", alp[N], dalp[N], th[N], dth[N], u[N]); } //PC.printf( "%f \n\r",alpha); //PC.printf( "\n" ); } } }