![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
TRR2018 omar
Fork of biniou by
stateMachines.cpp
- Committer:
- GaspardD
- Date:
- 2018-09-16
- Revision:
- 24:698fefbbee00
- Parent:
- 23:04d393220daa
- Child:
- 25:3d03756a7fa5
File content as of revision 24:698fefbbee00:
#include "stateMachines.h" #if DEBUG >0 Serial pc(USBTX, USBRX); // tx, rx #endif #if DEBUG >= -1 InterruptIn my_button(USER_BUTTON); #ifdef DUMP_SAMPLIG_PERIOD Timer timerLog; #endif #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 index_fifo_ir = 0;//pour géreer le buffer tournant int index_fifo_lidar = 0; //sections s_Section p_section1; s_Section p_section2; //PWM Controls PwmOut PwmMotor(PB_6); // PWM4 ch1 TIM4 PwmOut PwmDirection(PB_5); // PWM3 ch2 TIM3 int pulseDirection_us = DIRECTION_PULSE_MIDDLE; int pulseSpeed_us = INITAL_PULSE_SPEED_US; //Capteurs direction AnalogIn anaG90(CAPT_90_GAUCHE);//capteur ir coté gauche AnalogIn anaD90(CAPT_90_DROITE);//capteur ir coté droit AnalogIn anaG45(CAPT_45_GAUCHE);//capteur ir avant gauche 45 deg AnalogIn anaD45(CAPT_45_DROITE);//capteur ir avant droit 45deg #ifdef DLVV AnalogIn anaDlvvG(CAPT_10_GAUCHE);//capteur ir avant droit 10 deg AnalogIn anaDlvvD(CAPT_10_DROITE);//capteur ir coté droit 10 deg AnalogIn anaDlvvFront(CAPT_DEVANT);//capteur ir avant #endif int differenceGD45,differenceGD90,prevDiffGD90,prevDiffGD45,derive45,derive90; int lastDifferences90[NB_INTEGRAL_SAMPLES] = {0};//for integral correction int lastDifferenceIndex = 0; int integralSum; //Capteur vitesse InterruptIn it_tachymeter(PA_11); //LIDAR Serial serialLidar(PC_10,PC_11); // tx, rx int distLidar;// LiDAR actually measured distance value int distLidarPrev; int strengthLidar;// LiDAR signal strength int strengthLidarPrev; 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; Timer brakingTimer; int brakingDurationNeeded_us = 0; //Etats MUR_ST st_murs; MUR_ST st_tmpMurs; SECTION_ST st_currentSection; SECTION_ST st_tmpSection; MAX_SPEED_ST st_maxSpeed; MAX_SPEED_ST st_tmpMaxSpeed; THROTTLE_ST st_thro; THROTTLE_ST st_tmpThro; #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; // +++++++++++++++++++++++++++++++++++++++++++ SAMPLING +++++++++++++++++++++++++++++++++++++++++++ #ifdef SAMPLING s_Sample history[TAILLE_SAMPLES]; int indexSample = 0; void initSamples(void) { for(int m=0; m<TAILLE_SAMPLES; m++) { history[m].states.murs_dlvv = '0'; history[m].states.section = '0'; history[m].states.maxSpeed = '0'; history[m].states.throttle = '0'; history[m].time = 0; history[m].diffgd45 = 0; history[m].diffgd90 = 0; history[m].pwm_thro_us = 0; history[m].pwm_dir_us = 0; history[m].distLidar = 0; history[m].strLidar = 0; } #if DEBUG > 0 pc.printf("[INIT SAMPLE DONE]\r\n"); #endif return; } void sampleLog(void) { #ifdef DUMP_SAMPLIG_PERIOD if(timerLog.read_us() > DUMP_SAMPLIG_PERIOD) { timerLog.reset(); timerLog.start(); #endif if(indexSample < TAILLE_SAMPLES) { #ifdef DLVV history[indexSample].states.murs_dlvv = (char)st_obstacle; #else history[indexSample].states.murs_dlvv = (char)st_murs; #endif history[indexSample].states.section = (char)st_currentSection; history[indexSample].states.maxSpeed = (char)st_maxSpeed; history[indexSample].states.throttle = (char)st_thro; history[indexSample].time = timeSinceStart.read_us() ; history[indexSample].diffgd45 = differenceGD45; history[indexSample].diffgd90 = differenceGD90; history[indexSample].pwm_thro_us = pulseSpeed_us; history[indexSample].pwm_dir_us = pulseDirection_us; history[indexSample].dist = tachySectionDist_cm, history[indexSample].distLidar = distLidar; history[indexSample].strLidar = strengthLidar; indexSample++; #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; #ifdef DUMP_SAMPLIG_PERIOD } #endif } void transmitData(void) { #if DEBUG > 0 pc.printf("[START TO TRANSMIT]\r\n"); #endif serialLidar.printf("time,diffgd 45,diffgd 90,pwm_thro_us,pwm_dir_us,dist,murs/dlvv,section,maxSpeed,throttle\r\n"); for(int p=0; p<indexSample; p++) { serialLidar.printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", history[p].time, history[p].diffgd45, history[p].diffgd90, history[p].pwm_thro_us, history[p].pwm_dir_us, history[p].dist, history[p].states.murs_dlvv, history[p].states.section, history[p].states.maxSpeed, history[p].states.throttle); } return; } #endif // +++++++++++++++++++++++++++++++++++++++++++ FUNCTION UTILS +++++++++++++++++++++++++++++++++++++++++++ #if DEBUG >= -1 void pressed(void) { #if DEBUG > 0 pc.printf("[BTN PRESSED]\r\n"); #endif //p_sectionCourante = &p_section1; transmitData(); } #endif 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+=TACHY_CM; #if DEBUG > 0 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 distLidarPrev = distLidar; distLidar=uart[2]+uart[3]*256;// calculate distance value strengthLidarPrev = strengthLidar; strengthLidar=uart[4]+uart[5]*256;// calculate signal strength value } } } } // +++++++++++++++++++++++++++++++++++++++++++ STATES MACHINES +++++++++++++++++++++++++++++++++++++++++++ //########## INIT STATES MACHINES ########## void mursInit(void) { #if DEBUG >= -1 my_button.fall(&pressed); initSamples(); #endif #if DEBUG > 0 pc.baud(115200); pc.printf("Init Murs\r\n"); #endif timeSinceStart.start(); st_murs=EQUILIBRAGE_REPULSIF; PwmDirection.period_us(SPEED_PERIOD_US); PwmDirection.pulsewidth_us(DIRECTION_PULSE_MIDDLE);// milieu prevDiffGD45 = 0; prevDiffGD90 = 0; return; } #ifdef DLVV void obstacleInit(void) { #if DEBUG > 0 pc.printf("Init Obstacle\r\n"); #endif st_speedLimit=FRONT_CLEAR; return; } #endif void sectionInit(void) { #if DEBUG > 0 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 1 p_section1.nextSection =NULL;// &p_section2; p_section1.targetSpeed_cmps = 400; p_section1.slowSpeed_cmps = 328; p_section1.brakingCoefficient = 61; // application de la formule p_section1.coef_p_speed = 1; p_section1.lidarWarningDist_cm = 120; p_section1.lng_section_cm = 30000;//30m p_section1.coef_p = 50;//35; p_section1.coef_i = 10000;//35*NB_INTEGRAL_SAMPLES; p_section1.coef_d = 10000;//35; //section de test p_section2.nextSection = NULL; p_section2.targetSpeed_cmps = 328; p_section2.slowSpeed_cmps = 328; p_section2.brakingCoefficient = 0; // application de la formule p_section2.coef_p_speed = 1; p_section2.lidarWarningDist_cm = 300; p_section2.lng_section_cm = 200;//2m p_section2.coef_p = 50; p_section2.coef_i = 10000;//35*NB_INTEGRAL_SAMPLES; p_section2.coef_d = 10000;//35; return; } void maxSpeedInit(void) { #if DEBUG > 0 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) { #if DEBUG > 0 pc.printf("Init Throttle\r\n"); #endif st_thro = REGULATION_SPEED; PwmMotor.period_us(DIERCTION_PERIOD_MS); //20 ms is default PwmMotor.pulsewidth_us(1000);//MIN wait(3); PwmMotor.pulsewidth_us(2000);//MAX wait(1); PwmMotor.pulsewidth_us(1500);//ZEROING wait(1); pulseSpeed_us = INITAL_PULSE_SPEED_US; #if DEBUG > 0 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 #ifdef DUMP_SAMPLIG_PERIOD timerLog.start(); #endif return; } //########## UPDATE STATES ########## void mursUpdate(void) { #if (DEBUG > 3) pc.printf("\r\nUpdate MURS\r\n"); #endif //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); distMurG90Moy = getDistMoy(distMurG90,NB_ECHANTILLONS_IR); distMurD90Moy = getDistMoy(distMurD90,NB_ECHANTILLONS_IR); return; } #ifdef DLVV void obstacleUpdate(void) { return; } #endif void sectionUpdate(void) { #if (DEBUG > 3) pc.printf("\r\nUpdate Section\r\n"); #endif 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 i=0; if( strengthLidar > LIDAR_STRENGTH_THRESOLD ) { if( distLidar > p_sectionCourante->lidarWarningDist_cm ) { st_tmpMaxSpeed = SPEED_MAX; } else if( strengthLidar > LIDAR_STRENGTH_THRESOLD && strengthLidarPrev > LIDAR_STRENGTH_THRESOLD && distLidar < p_sectionCourante->lidarWarningDist_cm && distLidarPrev-distLidar > 0) { st_tmpMaxSpeed = BLOCKED; } else{ st_tmpMaxSpeed = SPEED_WARNING; } } else { st_tmpMaxSpeed = SPEED_MAX; } st_maxSpeed = st_tmpMaxSpeed; return; } void throttleUpdate(void) { #if (DEBUG > 3) pc.printf("\r\nUpdate Throttle\r\n"); #endif getTachySpeed(); switch (st_thro) { case REGULATION_SPEED: if( st_currentSection == ARRET || st_maxSpeed == BLOCKED ) { st_tmpThro = BRAKING; } else if(tachySpeed_cmps > (maxSpeed_cmps + SPEED_DELTA_CMPS)) { st_tmpThro = BRAKING; brakingDurationNeeded_us = (1000000)* MASSE_BINIOU_KG *((tachySpeed_cmps-maxSpeed_cmps)*(tachySpeed_cmps+maxSpeed_cmps)) / (PUISSANCE_FREINAGE_W *2) ; brakingTimer.reset(); brakingTimer.start(); } else { return; } break; case BRAKING: if(breakingTimer.read_us < brakingDurationNeeded_us || BLOCKED)//put a timer here { st_tmpThro = BRAKING; }else if(st_currentSection == ARRET) { st_tmpThro = STOPPED; } else{ brakingDurationNeeded_us = 0; st_tmpThro = REGULATION_SPEED; } break; case STOPPED: if(st_currentSection == RUNNING_SECTION) { st_tmpThro = REGULATION_SPEED; } else { st_tmpThro = STOPPED; } break; default: break; } st_thro = st_tmpThro; return; } //########## OUTPUT STATES ########## //updating output parameters void mursOutput(void) { prevDiffGD90 = differenceGD90; prevDiffGD45 = differenceGD45; #if (DEBUG > 3) pc.printf("\r\n Output MURS\r\n"); #endif differenceGD90 = distMurD90Moy - distMurG90Moy; differenceGD45 = distMurD45Moy - distMurG45Moy; //deriv correction derive45 = differenceGD45 - prevDiffGD45; derive90 = differenceGD90 - prevDiffGD90; //integral correction lastDifferences90[lastDifferenceIndex] = differenceGD90; integralSum=0; for(int f=0; f<NB_INTEGRAL_SAMPLES; f++) { integralSum+=lastDifferences90[f]; } lastDifferenceIndex = (lastDifferenceIndex + 1)%NB_INTEGRAL_SAMPLES; //application des coefficients pulseDirection_us = ( ((differenceGD90*2+differenceGD45*4)/8) / p_sectionCourante->coef_p) + ( derive45 / p_sectionCourante->coef_d) + (integralSum / p_sectionCourante->coef_i) + DIRECTION_PULSE_MIDDLE; //gestioon du dépassement if(pulseDirection_us > DIRECTION_PULSE_MAX) { //POUR TOURNER A GAUCHE #if DEBUG > 1 pc.printf("!!! OVER PWM Direction pulse: %d\r\n",pulseDirection_us); #endif pulseDirection_us = DIRECTION_PULSE_MAX; } else if(pulseDirection_us < DIRECTION_PULSE_MIN ) { //POUR TOURNER A DROITE #if DEBUG > 1 pc.printf("!!! UNDER PWM Direction pulse: %d\r\n",pulseDirection_us); #endif pulseDirection_us = DIRECTION_PULSE_MIN ; } #if DEBUG > 1 pc.printf("PWM Direction pulse: %d\r\n",pulseDirection_us); #endif PwmDirection.pulsewidth_us(pulseDirection_us); 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 BLOCKED: maxSpeed_cmps = 0; break; case SPEED_WARNING: maxSpeed_cmps = p_sectionCourante->slowSpeed_cmps; 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 REGULATION_SPEED: pulseSpeed_us = maxSpeed_cmps * 279 / 2048 + 1558 ; break; case BRAKING: #if DEBUG > 2 pc.printf("BRAKINGGGGGGGGGGGGGGGGGG !!! \r\n"); #endif pulseSpeed_us = BRAKING_PULSE_US; break; case STOPPED: #if DEBUG > 2 pc.printf("STOPPED\r\n"); #endif pulseSpeed_us = ZERO_PULSE_SPEED_US; break; default: break; } PwmMotor.pulsewidth_us(pulseSpeed_us); #if DEBUG > 1 pc.printf("PWM Thro pulse: %d micros\r\n",pulseSpeed_us); #endif return; }