Laboratory
Dependencies: mbed BufferedSerial LSM6DS33
main.cpp
- Committer:
- abm_mechatronika
- Date:
- 2022-05-19
- Revision:
- 2:aa102819471f
- Parent:
- 1:6e9fe61d7074
File content as of revision 2:aa102819471f:
//Program na NUCLEO F429ZI #include "mbed.h" #include "BufferedSerial.h" #include "LSM6DS33.h" #include "math.h" #include <stdio.h> /*PwmOut rled(LED_RED); PwmOut gled(LED_GREEN); PwmOut bled(LED_BLUE);*/ //deklaracje funkcji void testy_czujnika(); //wolne obroty wybranego przegubu void zadajnik_odbiornik(); //zadawanie położenia odebranego z zadajnika void sekwencja_pokazowa(); //przykładowa ścieżka ruchu urządzenia void stabilizacja_smartfon(); //zadawanie położenia odebranego z aplikacji void predkosc_kat(); //zamiana prędkosci obrotowej na kąt void regulacja(); //funkcja regulacji void regulacja2(); //funkcja regulacji 2 void stream_pc(); //wysyłanie danych na port usb void stream_telefon(); //wysyłanie danych do modułu Bluetooth void odbiornik(); //odbiór danych z zadajnika void odbiornik2(); //odbiór danych z aplikacji mobilnej void stabilizacja_zero(); //stabilizacja położenia dla stałej wartości 0 void odczyt_pozycji_gimbala(); //odczyt danych z czujnika Pololu MinIMU-9 v5 double arc_tan_2(double a, double b); //funkcja zamiany przyśpieszenia na kąt //BUTTON DigitalOut led1(LED1); //żółta DigitalOut led2(LED2); //niebieska DigitalOut led3(LED3); //czerwona InterruptIn button1(USER_BUTTON); //niebiski przycisk volatile bool button1_pressed = false; // Użyte w pętli głównej volatile bool button1_enabled = true; // Eliminacja wpływu drgania styków Timeout button1_timeout; // Drganie styków - zwłoka //TICKER float sampling_time = 0.2; //częstotiwosc zapisu na konsolę PC (terminal) w funkcji przerwania Ticker trigger1; //predkosc_kat Ticker trigger2; //stream na termial //Wyjscia PWM dla trzech silników PwmOut MOTOR_1(PB_3); //ogniwo 1 - od zewnętrznej PwmOut MOTOR_2(PB_4); //ogniwo 2 PwmOut MOTOR_3(PB_5); //ogniwo 3 DigitalOut OBROTY_M1(PE_13); //Kierunek obrotów dla trzech silników(stan 0/1) DigitalOut OBROTY_M2(PE_14); DigitalOut OBROTY_M3(PE_15); //=============REGULACJA====================== int obecna_pozycja=0; float e_x=0, e_x_poprzednie=0; //uchyby położeń kątowych float e_y=0, e_y_poprzednie=0; float e_z=0, e_z_poprzednie=0; int docelowa_pozycja_x=0, docelowa_pozycja_y=0, docelowa_pozycja_z=0; //wartosc zadana double pwm1, pwm2, pwm3; //sygnały sterujace volatile double z_kat,x_kat,y_kat; //wartosc aktualna float Ix=0, Iy=0, Iz=0; //Stałe regulatora PID float Dx=0, Dy=0, Dz=0; float Kp=0.2, Ki=0.05, Kd=0.01; //0.2, 0.05, 0.01 //===============STREAM======================= //Serial pc(USBTX,USBRX); //BLUETOOTH // komunikacja z PC BufferedSerial pc(USBTX,USBRX); //PC Serial device_bt(PD_5, PD_6); //TX, RX aplikacja/modul Bluetooth Serial device_zadajnik(PC_10, PC_11); //TX, RX zadajnik char buffer[24]; //===============BUTTON======================== // Enables button when bouncing is over void button1_enabled_cb(void) { button1_enabled = true; } int tryb = 0; //tryby pracy 1-5 // ISR handling button pressed event void button1_onpressed_cb(void) { if (button1_enabled) { // Disabled while the button is bouncing button1_enabled = false; button1_pressed = true; // To be read by the main loop button1_timeout.attach(callback(button1_enabled_cb), 0.3); // Debounce time 300 ms tryb++; if(tryb>=6){tryb=1;} } } //===================KOMUNIKACJA Z CZUJNIKIEM=================================== volatile double a_x; //deklaracja zmiennych akcelerometru volatile double a_y; volatile double a_z; volatile double g_x; //deklaracja zmiennych żyroskopu volatile double g_y; volatile double g_z; volatile double z_stopnie; //===================KOMUNIKACJA Z ZADAJNIKIEM================================== volatile float X=0; //zmiennne globalne - kąty obrotu zadajnika przesłane przez UART volatile float Y=0; volatile float Z=0; //======================PINY DLA CZUJNIKA======================================= LSM6DS33 gimbal(PB_9, PB_8, LSM6DS33_AG_I2C_ADDR(1)); //akcelerometr i żyroskop //===========PĘTLA GŁÓWNA======================================================= int main() { pc.baud(115200); device_bt.baud(9600); //transmisja danych Bluetooth device_zadajnik.baud(115200); //zadajnik - odbiornik //prędkosci silników(wypełnienie PWM) MOTOR_1.period(0.002f); // 2 milisecond period (500Hz) MOTOR_1.write(1.0f); // wypełnienie (1.0=0%, 0.0=100%) z krokiem 0.01f MOTOR_2.period(0.002f); // 2 ms MOTOR_2.write(1.0f); MOTOR_3.period(0.002f); // 2 ms MOTOR_3.write(1.0f); //LSM6DS33 gimbal(PB_9, PB_8); //akcelerometr i żyroskop wait(0.001); //PRZERWANIA================ button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event -zwolnienie niebieskiego przycisku // Delay for initial pullup to take effect wait(0.001); trigger2.attach(&stream_pc, sampling_time); //wsysyłanie danych w przerwaniu (stream PC) na terminal //trigger1.attach(&predkosc_kat, sampling_time); while(1) { if(button1_pressed) { if(tryb==1) //ODBIORNIK - STREAM TELEFON { led1 = 1; led2 = 0; led3 = 0; //odczyt_pozycji_gimbala(); //testy_czujnika(); //pc.printf(" %.2f\n\r", z_stopnie); //pc.printf(" %.2f\n\r", arc_tan_2(a_y,a_z)); /////// odczyt_pozycji_gimbala(); stream_telefon(); //studenci wybieraja okreslana funkcje //odbiornik(); //stabilizacja_smartfon(); //predkosc_kat(); //stabilizacja_zero(); //!!!! //predkosc_kat(); //odbiornik2(); //zadajnik_odbiornik(); } if(tryb==2) //ZADAJNIK - STABILIZACJA "0" { led1 = 0; led2 = 0; led3 = 1; odczyt_pozycji_gimbala(); stabilizacja_zero(); //!!!! } if(tryb==3) //ZADAJNIK-ODBIORNIK { led1 = 1; led2 = 0; led3 = 1; odczyt_pozycji_gimbala(); odbiornik2(); zadajnik_odbiornik(); } if(tryb==4) { led1 = 1; led2 = 1; led3 = 1; wait(0.02); sekwencja_pokazowa(); } if(tryb==5) //SMARTFON-ODBIORNIK { led1 = 0; led2 = 1; led3 = 0; odczyt_pozycji_gimbala(); odbiornik(); //wartosci zadane polozeniem telefonu stabilizacja_smartfon(); } }//KONIEC WARUNKU BUTTON }//KONIEC PĘTLI WHILE }//KONIEC PĘTLI MAIN //===========_STREAM_======================================================= void stream_pc() { //funkcja streamu //KONSOLA PC //pc.printf(" %.2f ", Y); //pc.printf(" %.2f\n\r", arc_tan_2(a_y,a_z)); //pc.printf(" %.2f\n\r", arc_tan_2(a_y,a_z)); //pc.printf(" %.2f\n\r", z_stopnie); //sprintf((char*)buffer, " %.2f %.2f %.2f\n\r",gimbal.ax, gimbal.ay, gimbal.az); //pc.printf(buffer); //studenci moga wybrav sposrod trzech komend sprintf((char*)buffer, " %.2f %.2f %.2f\n\r",a_x, a_y, a_z); pc.printf(buffer); //sprintf((char*)buffer, " %.2f %.2f %.2f\n\r",gimbal.gx, gimbal.gy, gimbal.gz); //pc.printf(buffer); //sprintf((char*)buffer, " %.2f %.2f %.2f\n\r",g_x, g_y, g_z); //pc.printf(buffer); } void stream_telefon(){ //wysłanie jednej ze wspolrzednych przez Bluetooth //MODUŁ BLUETOOTH float dane = (arc_tan_2(a_y,a_z)+180); //+180 stopni aby przesunąc wykres w aplikacji device_bt.putc(0); sprintf((char*)buffer,"%.2f", dane); device_bt.printf(buffer); wait(0.1); } //===================ODCZYT_POZYCJI========================================= void odczyt_pozycji_gimbala(){ gimbal.begin(); gimbal.readAll(); float *wsk1 = &gimbal.ax; //odczyt z czujnika przyspieszenia float *wsk2 = &gimbal.ay; float *wsk3 = &gimbal.az; float *wsk4 = &gimbal.gx; //odczyt z czujnika prędkosci float *wsk5 = &gimbal.gy; float *wsk6 = &gimbal.gz; a_x= *wsk1; a_y= *wsk2; a_z= *wsk3; g_x= *wsk4; g_y= *wsk5; g_z= *wsk6; wait(0.005); //czas próbkowaia czujnika Pololu } //>>>>>>>>>>>>>>>>>>>_FUNKCJA_ATAN2_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> double arc_tan_2(double a, double b) //a - x lub y, b - z (funkcja oblicza kąty wokół osi x, y) { double stopnie; double val = 180.0/3.14; stopnie = atan2(a,b)*val; return stopnie; } //@@@@@@@@@@@_PRĘDKOŚĆ_NA_KĄT_@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void predkosc_kat(){ double z_rad = g_z; //przypisanie zmiennej z czujnika do zmiennej lokalnej if(z_rad>=-4.5&&z_rad<=-2.0){z_rad=0.0;} //dla wart 0 czujnik wskazuje ~-3,6 double delta_t=0.02; //funkcja wywoływana jest co 2,5 milisekund double delta_kat=(z_rad*delta_t); //różnica kątowa= wart. czujnika * dt z_kat=z_kat+delta_kat; //ostateczny kąt = kąt obecny + d kąta z_stopnie = z_kat*(180/3.14); //zamiana radianów na stopnie } //&&&&&&&&&&&®ULACJA&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& void regulacja(){ Kp=0.2, Ki=0.05, Kd=0.01; docelowa_pozycja_x=X; //pozycja docelowa dla zadajników docelowa_pozycja_y=Y; docelowa_pozycja_z=Z; e_x=docelowa_pozycja_x-arc_tan_2(a_x,a_z); //uchyb regulacji e_y=docelowa_pozycja_y-arc_tan_2(a_y,a_z); e_z=docelowa_pozycja_z-z_stopnie; Ix=Ix+e_x; Iy=Iy+e_y; Iz=Iz+e_z; Dx=e_x - e_x_poprzednie; Dy=e_y - e_y_poprzednie; Dz=e_z - e_z_poprzednie; //pwm1=(Kp*e_x); //P //pwm1=(Kp*e_x)+(Ki*Ix); //PI pwm1=(Kp*e_x)+(Kd*Dx); //PD //pwm1=(Kp*e_x)+(Ki*Ix)+(Kd*Dx); //PID //pwm2=(Kp*e_y); //P //pwm2=(Kp*e_y)+(Ki*Iy); //PI pwm2=(Kp*e_y)+(Kd*Dy); //PD //pwm2=(Kp*e_y)+(Ki*Iy)+(Kd*Dy); //PID //pwm3=(Kp*e_z); //P //pwm3=(Kp*e_z)+(Ki*Iz); //PI pwm3=(Kp*e_z)+(Kd*Dz); //PD //pwm3=(Kp*e_z)+(Ki*Iz)+(Kd*Dz); //PID } void regulacja2(){ Kp=0.1, Ki=0.05, Kd=0.01; docelowa_pozycja_x=X; //pozycja docelowa dla zadajników docelowa_pozycja_y=Y; docelowa_pozycja_z=Z; e_x=docelowa_pozycja_x-arc_tan_2(a_x,a_z); //uchyb regulacji e_y=docelowa_pozycja_y-arc_tan_2(a_y,a_z); e_z=docelowa_pozycja_z-z_stopnie; Ix=Ix+e_x; Iy=Iy+e_y; Iz=Iz+e_z; Dx=e_x - e_x_poprzednie; Dy=e_y - e_y_poprzednie; Dz=e_z - e_z_poprzednie; pwm1=(Kp*e_x); //P //pwm1=(Kp*e_x)+(Ki*Ix); //PI pwm2=(Kp*e_y); //P //pwm2=(Kp*e_y)+(Ki*Iy); //PI pwm3=(Kp*e_z); //P //pwm3=(Kp*e_z)+(Ki*Iz); //PI } //+++++++++++DANE Z ZADAJNIKA+++++++++++++++++++++++++++++++++++++++++++++ void odbiornik() { char str_x[1]; //definicja wektorów char char str_y[1]; char str_z[1]; device_bt.scanf("%s",str_x); //kąty pochylenia urzadzeia mobilnego device_bt.scanf("%s",str_y); device_bt.scanf("%s",str_z); X = atof(str_x); //zamiana na float Y = atof(str_y); Z = atof(str_z)-180; //rozlozenie zakresu kata obrotu symetrycznie wokol zera } void odbiornik2() { char str_x[1]; //definicja wektorów char char str_y[1]; char str_z[1]; device_zadajnik.scanf("%s",str_x); device_zadajnik.scanf("%s",str_y); device_zadajnik.scanf("%s",str_z); X = atof(str_x); Y = atof(str_y); Z = atof(str_z)-180; } //+++++++++++STABILIZACJA_ZERO++++++++++++++++++++++++++++++++++++++++++ void stabilizacja_zero(){ //platforma stabilizuje się do położenia w którym odczyty z akcelerometru wynoszą: ax=0, ay=0; //OŚ X''''''''''''''''''''''''''''' regulacja(); if(a_x<=0.0) { OBROTY_M3=1; MOTOR_3.write(-0.022*(abs(pwm1))+1); } if(a_x>0.0) { OBROTY_M3=0; MOTOR_3.write(-0.022*(abs(pwm1))+1); } //OŚ Y''''''''''''''''''''''''''''''''''''' if(a_y<=0.0) { OBROTY_M1=1; MOTOR_1.write(-0.022*(abs(pwm2))+1); } if(a_y>0.0) { OBROTY_M1=0; MOTOR_1.write(-0.022*(abs(pwm2))+1); } //OŚ Z''''''''''''''''''''''''''''''''''''' /* if(z_stopnie<=0.0) { OBROTY_M2=0; MOTOR_2.write(-0.022*(abs(pwm3))+1); } if(z_stopnie>0.0) { OBROTY_M2=1; MOTOR_2.write(-0.022*(abs(pwm3))+1); } */ } //++++++++++STABILIZACJA_SMARTFON++++++++++++++++++++++++++++++++++++++++++ void stabilizacja_smartfon(){ //predkosc_kat(); regulacja2(); //OŚ X''''''''''''''''''''''''''''' if(arc_tan_2(a_x,a_z)<=X) { OBROTY_M3=1; MOTOR_3.write(-0.022*(abs(pwm1))+1); //y=ax+b } if(arc_tan_2(a_x,a_z)>X) { OBROTY_M3=0; MOTOR_3.write(-0.022*(abs(pwm1))+1); } //OŚ Y''''''''''''''''''''''''''''''''''''' if(arc_tan_2(a_y,a_z)<=Y) { OBROTY_M1=1; MOTOR_1.write(-0.022*(abs(pwm2))+1); } if(arc_tan_2(a_y,a_z)>Y) { OBROTY_M1=0; MOTOR_1.write(-0.022*(abs(pwm2))+1); } //OŚ Z''''''''''''''''''''''''''''''''''''' /* if(z_stopnie<=Z) { OBROTY_M2=1; MOTOR_2.write(0.9); } if(z_stopnie>Z) { OBROTY_M2=0; MOTOR_2.write(0.9); }*/ } //vvvvvvvvvvvvvvvvvvvvvv_ZADAJNIK_ODBIORNIK_vvvvvvvvvvvvvvvvvvvvvvvvv void zadajnik_odbiornik() { regulacja(); //oblicza pwm1 - sygnał sterujacy //OŚ X''''''''''''''''''''''''''''' if(arc_tan_2(a_x,a_z)<=X) //X - wartosc zadana { OBROTY_M3=1; //kierunek obrotu MOTOR_3.write(-0.022*(abs(pwm1))+1); //y=-ax+1 (odejmujemy od wypełnienia z uwagi na odwrotnosc fali PWM: 1 - 0% wypełnienia, 0 - 100% wypełnienia sygnału } if(arc_tan_2(a_x,a_z)>X) { OBROTY_M3=0; MOTOR_3.write(-0.022*(abs(pwm1))+1); } //OŚ Y''''''''''''''''''''''''''''''''''''' if(arc_tan_2(a_y,a_z)<=Y) { OBROTY_M1=1; MOTOR_1.write(-0.022*(abs(pwm2))+1); } if(arc_tan_2(a_y,a_z)>Y) { OBROTY_M1=0; MOTOR_1.write(-0.022*(abs(pwm2))+1); } //OŚ Z''''''''''''''''''''''''''''''''''''' /* if(z_stopnie<=Z) { OBROTY_M2=1; MOTOR_2.write(0.9); } if(z_stopnie>Z) { OBROTY_M2=0; MOTOR_2.write(0.9); }*/ } //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //&&&&&&&&&&&&&&&&&&&&TESTY CZUJNIKA&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& void testy_czujnika(){ // WOLNE OBROTY - 10 % PWM for(double i=1; i>=0.85; i=i-0.01) { MOTOR_1.write(i); MOTOR_2.write(i); //MOTOR_3.write(i); odczyt_pozycji_gimbala(); wait(0.1); } for(double j=50; j>=0; j=j-1) { wait(0.1); odczyt_pozycji_gimbala(); } for(double i=0.85; i<=1; i=i+0.01) { MOTOR_1.write(i); MOTOR_2.write(i); //MOTOR_3.write(i); odczyt_pozycji_gimbala(); wait(0.1); } //SZYBKIE OBROTY - 100% PWM /* for(double i=1; i>=0.01; i=i-0.01) { MOTOR_1.write(i); //MOTOR_2.write(i); //MOTOR_3.write(i); wait(0.1); } for(double j=50; j>=0; j=j-1) { wait(0.1); } for(double i=0.00; i<=1; i=i+0.01) { MOTOR_1.write(i); //MOTOR_2.write(i); //MOTOR_3.write(i); wait(0.1); }*/ } //$$$$$$$$$$$$$SEKWENCJE_POKAZ$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //SEKWENCJA 2 void sekwencja_pokazowa(){ // funkcja sekwencja pokazowa for(double i=1; i>=0.6; i=i-0.01) { MOTOR_1.write(i); MOTOR_2.write(i); MOTOR_3.write(i); wait(0.1); } //WTRĄCENIE 2.1 for(double i=1; i>=0.6; i=i-0.01) { MOTOR_1.write(i); wait(0.1); } for(double i=0.6; i<=1.0; i=i+0.01) { MOTOR_1.write(i); wait(0.1); } OBROTY_M2=1; //zmiana obrotów for(double i=1; i>=0.6; i=i-0.01) { MOTOR_1.write(i); wait(0.1); } for(double i=10.6; i<=1.0; i=i+0.01) { MOTOR_1.write(i); wait(0.1); } //=============== wait(2.0); for(double i=0.6; i<=1.0; i=i+0.01) { MOTOR_1.write(i); MOTOR_2.write(i); MOTOR_3.write(i); wait(0.1); } wait(1.0); //SEKWENCJA 1 for(double i=1; i>=0; i=i-0.01) { MOTOR_1.write(i); MOTOR_2.write(i); MOTOR_3.write(i); wait(0.1); } for(double i=0; i<=1; i=i+0.01) { MOTOR_1.write(i); MOTOR_2.write(i); MOTOR_3.write(i); wait(0.1); } wait(2.0); } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$