Hlimi Omar
/
biniou
TRR2018 omar
Fork of biniou by
stateMachines.cpp
- Committer:
- GaspardD
- Date:
- 2018-09-12
- Revision:
- 18:38504337d2fc
- Parent:
- 17:8c465656eea4
- Child:
- 19:771bf61be276
File content as of revision 18:38504337d2fc:
#include "stateMachines.h" #ifdef DEBUG Serial pc(USBTX, USBRX); // tx, rx #endif uint16_t distMurG90[NB_ECHANTILLONS_IR];//buffer tournant ir coté gauche pour moyenne uint16_t distMurD90[NB_ECHANTILLONS_IR];//buffer tournant ir coté droit pour moyenne uint16_t distMurG45[NB_ECHANTILLONS_IR];//buffer tournant ir avant gauche 45deg pour moyenne uint16_t distMurD45[NB_ECHANTILLONS_IR];//buffer tournant ir avant droit 45deg pour moyenne #ifdef DLVV uint16_t distMurG10[NB_ECHANTILLONS_IR];//buffer tournant ir avant gauche 10deg pour moyenne uint16_t distMurD10[NB_ECHANTILLONS_IR];//buffer tournant ir coté droit 10deg pour moyenne uint16_t distMurFront[NB_ECHANTILLONS_IR];//buffer tournant ir front #endif uint16_t distMurG90Moy; uint16_t distMurD90Moy; uint16_t distMurG45Moy; uint16_t distMurD45Moy; #ifdef DLVV uint16_t distMurG10Moy; uint16_t distMurD10Moy; uint16_t distMurFrontMoy #endif int dist_obstacle_lidar[NB_ECHANTILLONS_LIDAR];//buffer tournant int index_fifo_ir = 0;//pour géreer le buffer tournant int index_fifo_lidar = 0; //sections s_Section p_section1; //PWM Controls PwmOut PwmMotor(PB_6); // PWM4 ch1 TIM4 PwmOut PwmDirection(PB_5); // PWM3 ch2 TIM3 int pulseDirection = DIRECTION_PULSE_MIDDLE; int pulseSpeed = INITAL_PULSE_SPEED; //Capteurs direction AnalogIn anaG90(PC_1);//capteur ir coté gauche AnalogIn anaD90(PA_1);//capteur ir coté droit AnalogIn anaG45(PC_0);//capteur ir avant gauche 45 deg AnalogIn anaD45(PC_2);//capteur ir avant droit 45deg #ifdef DLVV AnalogIn anaDlvvG(PB_0);//capteur ir avant droit 10 deg AnalogIn anaDlvvD(PC_3);//capteur ir coté droit 10 deg AnalogIn anaDlvvFront(PA_4);//capteur ir avant #endif int differenceGD45,differenceGD90; //Capteur vitesse InterruptIn it_tachymeter(PA_11); //LIDAR Serial serialLidar(PC_10,PC_11); // tx, rx int distLidar;// LiDAR actually measured distance value int strengthLidar;// LiDAR signal strength int check;// check numerical value storage int i; int uart[9];// store data measured by LiDAR const int HEADER=0x59;// data package frame header //SPEED int maxSpeed_cmps = 0; int tachySpeed_cmps = 0; int tachyStepsRegister = 0; int tachySectionDist_cm = 0; //Etats MUR_ST st_murs; SECTION_ST st_currentSection; MAX_SPEED_ST st_maxSpeed; THROTTLE_ST st_thro; #ifdef DLVV OBSTACLE_ST st_obstacle; #endif s_Section* p_sectionCourante = NULL; //time monitoring Timer timeSinceStart;// temps.start()/stop()/sec: read()/ms: read_ms()/µs: read_us() Timer timerSinceGetTachy; void getTachySpeed() { //tachySteps = VALEUR_DU_PIN; //poour gérer les vitesses lentes if(tachyStepsRegister == 0 && timerSinceGetTachy.read_us() < 500000) { return;//on attend encore un peu l'aquisition de la vitesse } tachySectionDist_cm += tachyStepsRegister; tachySpeed_cmps = (tachyStepsRegister * 1000000)/timerSinceGetTachy.read_us(); #if DEBUG > 2 pc.printf("IT: distance parcourue %d , vitesse:%d \r\n",tachySectionDist_cm,tachySpeed_cmps); #endif tachyStepsRegister=0; timerSinceGetTachy.reset(); timerSinceGetTachy.start(); return; } uint16_t getDistMoy(uint16_t* tab,int size) { int sumMoy = 0; for(int k=0; k<size;k++) { sumMoy+=tab[k]; } return sumMoy/size; } void it4cm() { tachyStepsRegister+=4; #ifdef DEBUG pc.printf("IT tachy\r\n"); #endif } void it_serial() { if(serialLidar.getc()==HEADER) { // determine data package frame header 0x59 uart[0]=HEADER; if(serialLidar.getc()==HEADER) { //determine data package frame header 0x59 uart[1]=HEADER; for(i=2; i<9; i++) { // store data to array uart[i]=serialLidar.getc(); } check=uart[0]+uart[1]+uart[2]+uart[3]+uart[4]+uart[5]+uart[6]+uart[7]; if(uart[8]==(check&0xff)) { // check the received data as per protocols distLidar=uart[2]+uart[3]*256;// calculate distance value strengthLidar=uart[4]+uart[5]*256;// calculate signal strength value } } } } //########## INIT STATES MACHINES ########## void mursInit(void) { #ifdef DEBUG pc.baud(115200); pc.printf("Init Murs\r\n"); #endif timeSinceStart.start(); st_murs=EQUILIBRAGE_REPULSIF; PwmDirection.period_us(SPEED_PERIOD); PwmDirection.pulsewidth_us(DIRECTION_PULSE_MIDDLE);// milieu return; } #ifdef DLVV void obstacleInit(void) { #ifdef DEBUG pc.printf("Init Obstacle\r\n"); #endif st_speedLimit=FRONT_CLEAR; return; } #endif void sectionInit(void) { #ifdef DEBUG pc.printf("Init Section\r\n"); #endif st_currentSection=ARRET; p_sectionCourante=&p_section1; it_tachymeter.fall(&it4cm); timerSinceGetTachy.start(); getTachySpeed();//to reset tachySectionDist_cm = 0; tachyStepsRegister = 0; //section de test p_section1.nextSection = NULL; p_section1.targetSpeed_cmps = 10; p_section1.slowSpeed_cmps = 5; p_section1.brakingCoefficient = 30; // application de la formule p_section1.us_accel = 1;//+1 microsec each loop p_section1.us_decel = 1; p_section1.lidarWarningDist_cm = 300; p_section1.lng_section_cm = 1500;//1500cm p_section1.coef_p = 35; p_section1.coef_i = 0; p_section1.coef_d = 0; return; } void maxSpeedInit(void) { #ifdef DEBUG pc.printf("Init Max Speed\r\n"); #endif st_maxSpeed=SPEED_MAX; maxSpeed_cmps= p_sectionCourante->targetSpeed_cmps; serialLidar.baud(115200); serialLidar.attach(&it_serial); return; } void throttleInit(void) { #ifdef DEBUG pc.printf("Init Throttle\r\n"); #endif st_thro = UNDER_SPEED; PwmMotor.period_us(SPEED_PERIOD); //20 ms is default PwmMotor.pulsewidth_us(1000); wait(3); PwmMotor.pulsewidth_us(2000); wait(1); PwmMotor.pulsewidth_us(1500); wait(1); pulseSpeed = INITAL_PULSE_SPEED; #ifdef DEBUG pc.printf("temps init: %d micros\r\n",timeSinceStart.read_us()); pc.printf("\r\nStates INIT: state Murs: %d, state Section %d, state MaxSpeed %d, state Throttle %d\r\n",st_murs,st_currentSection,st_maxSpeed,st_thro); timeSinceStart.reset(); timeSinceStart.start(); #endif return; } //########## UPDATE STATES ########## void mursUpdate(void) { #if (DEBUG > 3) pc.printf("\r\nUpdate MURS\r\n"); #endif MUR_ST st_tmpMurs; //lectures distMurG90[index_fifo_ir]=anaG90.read_u16(); distMurD90[index_fifo_ir]=anaD90.read_u16(); distMurG45[index_fifo_ir]=anaG45.read_u16(); distMurD45[index_fifo_ir]=anaD45.read_u16(); index_fifo_ir = (index_fifo_ir+1)%NB_ECHANTILLONS_IR; distMurG45Moy = getDistMoy(distMurG45,NB_ECHANTILLONS_IR); distMurD45Moy = getDistMoy(distMurD45,NB_ECHANTILLONS_IR); #if DEBUG > 1 pc.printf("dist45G:%d dist45D:%d Deadzone: %d\r\n",distMurG45Moy,distMurD45Moy,IR_DEADZONE_U16_22cm); #endif switch (st_murs) { case EQUILIBRAGE_REPULSIF: distMurG90Moy = getDistMoy(distMurG90,NB_ECHANTILLONS_IR); distMurD90Moy = getDistMoy(distMurD90,NB_ECHANTILLONS_IR); if( distMurG90Moy <= IR_DEADZONE_U16_22cm) { st_tmpMurs = ATTRACTIF_D; }else if(distMurD90Moy <= IR_DEADZONE_U16_22cm) { st_tmpMurs = ATTRACTIF_G; }else { st_tmpMurs = EQUILIBRAGE_REPULSIF; } break; case ATTRACTIF_D: distMurD90Moy= getDistMoy(distMurD90,NB_ECHANTILLONS_IR); if( distMurD90Moy >= IR_FAR_U16_105cm) { st_tmpMurs = ATTRACTIF_D; }else { st_tmpMurs = EQUILIBRAGE_REPULSIF; } break; case ATTRACTIF_G: distMurG90Moy= getDistMoy(distMurG90,NB_ECHANTILLONS_IR); if(distMurG90Moy >= IR_FAR_U16_105cm) { st_tmpMurs = ATTRACTIF_G; }else { st_tmpMurs = EQUILIBRAGE_REPULSIF; } break; default: return; } st_murs = st_tmpMurs; return; } #ifdef DLVV void obstacleUpdate(void) { return; } #endif void sectionUpdate(void) { #if (DEBUG > 3) pc.printf("\r\nUpdate Section\r\n"); #endif SECTION_ST st_tmpSection; switch (st_currentSection) { case RUNNING_SECTION: if(tachySectionDist_cm > p_sectionCourante->lng_section_cm)//on pourrait rajouter un test lidar { st_tmpSection = LOADING_SECTION; } else { return; } break; case LOADING_SECTION: if(p_sectionCourante != NULL) //la section a ete chargee dans sectionOutput { st_tmpSection = RUNNING_SECTION; }else { st_tmpSection=ARRET; } break; case ARRET: if(p_sectionCourante != NULL) { st_tmpSection = RUNNING_SECTION; } else { return; } break; default: break; } st_currentSection = st_tmpSection; return; } void maxSpeedUpdate(void) { #if (DEBUG > 3) pc.printf("\r\nUpdate MaxSpeed\r\n"); #endif MAX_SPEED_ST st_tmpMaxSpeed; i=0; if( strengthLidar > (LIDAR_STRENGTH_THRESOLD + LIDAR_STRENGH_DELTA) ) { if(distLidar > 30 && distLidar < p_sectionCourante->lidarWarningDist_cm) { st_tmpMaxSpeed = SPEED_VARIABLE; }else { st_tmpMaxSpeed = SPEED_LIMITED; } }else if(strengthLidar < (LIDAR_STRENGTH_THRESOLD - LIDAR_STRENGH_DELTA)) { st_tmpMaxSpeed = SPEED_MAX; } else{ return;//pour ne pas changer sans arret d'etats lorsque strengthLidar est à la limite du seuil } st_maxSpeed = st_tmpMaxSpeed; return; } void throttleUpdate(void) { #if (DEBUG > 3) pc.printf("\r\nUpdate Throttle\r\n"); #endif THROTTLE_ST st_tmpThro; getTachySpeed(); switch (st_thro) { case UNDER_SPEED: if(st_currentSection == ARRET) { st_tmpThro = BRAKING; } else if( tachySpeed_cmps >= maxSpeed_cmps ) { st_tmpThro = AT_SPEED; }else { return; } break; case OVER_SPEED: if(st_currentSection == ARRET) { st_tmpThro = BRAKING; } else if( tachySpeed_cmps <= maxSpeed_cmps) { st_tmpThro = AT_SPEED; }else { return; } break; case AT_SPEED: if(st_currentSection == ARRET) { st_tmpThro = BRAKING; } else if(tachySpeed_cmps > (maxSpeed_cmps + SPEED_DELTA_CMPS) ) { st_tmpThro = OVER_SPEED; } else if( tachySpeed_cmps < (maxSpeed_cmps - SPEED_DELTA_CMPS) ) { st_tmpThro = UNDER_SPEED; } else { return; } break; case BRAKING: if(st_currentSection == RUNNING_SECTION){ if( tachySpeed_cmps < maxSpeed_cmps ) { st_tmpThro = UNDER_SPEED; }else if( tachySpeed_cmps > maxSpeed_cmps ) { st_tmpThro = OVER_SPEED; }else { st_tmpThro = AT_SPEED; } } else { return; } default: break; } st_thro = st_tmpThro; return; } //########## OUTPUT STATES ########## //updating output parameters void mursOutput(void) { #if (DEBUG > 3) pc.printf("\r\n Output MURS\r\n"); #endif switch (st_murs) { case EQUILIBRAGE_REPULSIF://TO DO TODO case ATTRACTIF_G: case ATTRACTIF_D: differenceGD90 = distMurD90Moy - distMurG90Moy; differenceGD45 = distMurD45Moy - distMurG45Moy; pulseDirection = ( ((differenceGD90*2+differenceGD45*4)/8) / p_sectionCourante->coef_p) + 1500; if(pulseDirection > DIRECTION_PULSE_MAX)//POUR TOURNER A GAUCHE { #if DEBUG > 1 pc.printf("!!! OVER PWM Direction pulse: %d\r\n",pulseDirection); #endif pulseDirection = DIRECTION_PULSE_MAX; } else if(pulseDirection < DIRECTION_PULSE_MIN )//POUR TOURNER A DROITE { #if DEBUG > 1 pc.printf("!!! UNDER PWM Direction pulse: %d\r\n",pulseDirection); #endif pulseDirection = DIRECTION_PULSE_MIN ; } default: break; } #if DEBUG > 1 pc.printf("PWM Direction pulse: %d\r\n",pulseDirection); #endif PwmDirection.pulsewidth_us(pulseDirection); return; } #ifdef DLVV void obstacleOutput(void) { return; } #endif void sectionOutput(void) { #if (DEBUG > 3) pc.printf("\r\n Output Section\r\n"); #endif switch (st_currentSection) { case RUNNING_SECTION: break; case LOADING_SECTION: p_sectionCourante=p_sectionCourante->nextSection; tachySectionDist_cm = 0; break; case ARRET: //on est à l'arret break; default: break; } return; } void maxSpeedOutput(void) { #if (DEBUG > 3) pc.printf("\r\n Output MAX SPEED\r\n"); #endif switch(st_maxSpeed) { case SPEED_LIMITED: maxSpeed_cmps = p_sectionCourante->slowSpeed_cmps; break; case SPEED_VARIABLE: maxSpeed_cmps = p_sectionCourante->targetSpeed_cmps * (distLidar/(distLidar+p_sectionCourante->brakingCoefficient)); break; default: maxSpeed_cmps = p_sectionCourante->targetSpeed_cmps; break; } return; } void throttleOutput(void) { #if (DEBUG > 3) pc.printf("\r\n Output TROTTLE\r\n"); #endif switch (st_thro) { case UNDER_SPEED: if ( (pulseSpeed + p_sectionCourante->us_accel) < MAX_PULSE_WIDTH_FOR_TACHY) { pulseSpeed += p_sectionCourante->us_accel; } break; case OVER_SPEED: if ( (pulseSpeed - p_sectionCourante->us_decel) > INITAL_PULSE_SPEED) { pulseSpeed -= p_sectionCourante->us_decel; } break; case AT_SPEED: break; case BRAKING: #if DEBUG > 2 pc.printf("BRAKINGGGGGGGGGGGGGGGGGG !!! \r\n"); #endif pulseSpeed = BRAKING_PWM; break; default: break; } PwmMotor.pulsewidth_us(pulseSpeed); #if DEBUG > 1 pc.printf("PWM Thro pulse: %d\r\n",pulseSpeed); #endif #if DEBUG > 0 pc.printf("\r\nodo:%d dist = %d \tstrength = %d \tC45D: %d C45G: %d C90D: %d C90G: %d looptime: %d micros",tachySectionDist_cm,distLidar,strengthLidar,distMurD45Moy,distMurG45Moy,distMurD90Moy,distMurG90Moy,timeSinceStart.read_us());// output signal strength value pc.printf("\r\nstate Murs: %d, state Section %d, state MaxSpeed %d, state Throttle %d\r\n",st_murs,st_currentSection,st_maxSpeed,st_thro); //wait(2); timeSinceStart.reset(); timeSinceStart.start(); #endif return; }