sra-romi
Dependencies: BufferedSerial Matrix
control.cpp
- Committer:
- joaopsousa99
- Date:
- 2021-05-11
- Revision:
- 4:1defb279922a
File content as of revision 4:1defb279922a:
#include <cstdint> #include <cstdio> #include <cstdlib> #include <math.h> #include "Communication.h" #include "control.h" #include "mbed.h" #include "Robot.h" #include "Matrix.h" const float TIMESTEP = 0.05; const float CELL_SIZE = 5; const int MAP_SIZE = 100; const int GRID_SIZE = int(MAP_SIZE/CELL_SIZE); const int WINDOW_SIZE = int(45/CELL_SIZE); const float PI = 3.1415926; Matrix create_occupation_grid(){ Matrix occupationGrid = Matrix(GRID_SIZE,GRID_SIZE); for(int i = 1; i <= 20; i++) for(int j = 1;j <= 20; j++) if (i > 8 && i < 12 && j > 8 && j < 12) occupationGrid.add(i,j,1); return occupationGrid; } /*int occupationGrid[GRID_SIZE][GRID_SIZE] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};*/ /*int occupationGrid[GRID_SIZE][GRID_SIZE] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};*/ void moveToPoint(float xObj, float yObj){ float kv = 0.2; float kw = 10; float d = sqrt((xObj - poseX)*(xObj - poseX) + (yObj - poseY)*(yObj - poseY)); float angleError = atan2(yObj - poseY, xObj - poseX); //printf("ANGLE ERROR: %.1f ", angleError*180/PI); angleError = atan2(sin(angleError - poseTheta), cos(angleError - poseTheta)); // equivalente a wrapToPi() float wheelSpeeds[2]; robotVel2wheelVel(kv*d, kw*angleError, wheelSpeeds); wheelSpeeds[0] = mapSpeeds(wheelSpeeds[0]); wheelSpeeds[1] = mapSpeeds(wheelSpeeds[1]); //printf("wheel speeds: [%.0f, %.0f]\t", wheelSpeeds[0], wheelSpeeds[1]); setSpeeds(wheelSpeeds[0], wheelSpeeds[1]); } float vff(Matrix occupationGrid, int *xactive, int *yactive, int lenx, int leny, float *objCellCenter, Serial pc){ //printf("i vff; "); float Fcr = 35; float Fca = 1.5; // não se sabe quantas células estão ocupadas então aloca-se espaço para todas para mais // à frente guardar apenas as ocupadas e apagar estes arrays //int *auxRows, *auxCols; //auxRows = (int *)calloc(lenx*leny, sizeof(int)); //auxCols = (int *)calloc(lenx*leny, sizeof(int)); //int occupiedCounter = 0; //int auxCounter = 0; // pesquisa a grelha de ocupação e guarda os índices da janela ativa que correspondem a // células ocupadas float Frx = 0; float Fry = 0; float xCell, yCell; float value; for(int i = 0; i < lenx; i++){ for(int j = 0; j < leny; j++){ // necessario somar 1 porque os indices na matriz comecam em 1 value = occupationGrid(xactive[i]+1,yactive[j]+1); //printf("occupationGrid(%d, %d): %.0f", xactive[i]+1, yactive[j]+1, value); if(value == 1){ //auxRows[auxCounter] = xactive[i]; //auxCols[auxCounter] = yactive[j]; //occupiedCounter++; xCell = xactive[i]*CELL_SIZE + CELL_SIZE/2; yCell = yactive[i]*CELL_SIZE + CELL_SIZE/2; Frx += Fcr*(xCell - poseX)/pow(sqrt(pow(xCell - poseX, 2) + pow(yCell - poseY, 2)), 3); Fry += Fcr*(yCell - poseY)/pow(sqrt(pow(xCell - poseX, 2) + pow(yCell - poseY, 2)), 3); } else{ continue; //auxRows[auxCounter] = -1; //auxCols[auxCounter] = -1; } //auxCounter++; } } //pc.printf("Fr = [%.1f, %.1f] ", Frx, Fry); float Fax = Fca*(objCellCenter[0] - poseX)/(sqrt(pow(objCellCenter[0] - poseX, 2) + pow(objCellCenter[1] - poseY, 2))); float Fay = Fca*(objCellCenter[1] - poseY)/(sqrt(pow(objCellCenter[0] - poseX, 2) + pow(objCellCenter[1] - poseY, 2))); //pc.printf("Fa = [%.1f, %.1f] ", Fax, Fay); /*if(occupiedCounter == 0){ float F[2] = {Fax, Fay}; printf("f vff; "); return atan2(F[1], F[0]); }*/ /*int *xOccupied, *yOccupied; xOccupied = (int *)calloc(occupiedCounter, sizeof(int)); yOccupied = (int *)calloc(occupiedCounter, sizeof(int)); occupiedCounter = 0; for(int i = 0; i < lenx*leny; i++){ if(auxRows[i] != -1){ xOccupied[occupiedCounter] = auxRows[i]; yOccupied[occupiedCounter] = auxCols[i]; occupiedCounter++; } } for (int i = 0; i < occupiedCounter; i++) { xCell = xOccupied[i]*CELL_SIZE + CELL_SIZE/2; yCell = yOccupied[i]*CELL_SIZE + CELL_SIZE/2; Frx += Fcr*(xCell - poseX)/pow(sqrt(pow(xCell - poseX, 2) + pow(yCell - poseY, 2)), 3); Fry += Fcr*(yCell - poseY)/pow(sqrt(pow(xCell - poseX, 2) + pow(yCell - poseY, 2)), 3); } free(auxCols); free(auxRows); free(xOccupied); free(yOccupied);*/ float F[2] = {Fax - Frx, Fay - Fry}; //printf("f vff; "); return atan2(F[1], F[0]); } void followPath(float &objAheadX, float &objAheadY, float &intError, float *objCellCenter, Matrix occupationGrid, Serial pc){ //printf("i followPath; "); float kv = 0.3; float ki = 0.2; float kw = 10; int vObj = 7; // temos de fazer experiências para afinar isto float vffAngle = poseTheta; int dObj = 3; float xmax = floor(static_cast<float>(poseX/CELL_SIZE)) + floor(static_cast<float>(WINDOW_SIZE/2)); float xmin = floor(static_cast<float>(poseX/CELL_SIZE)) - floor(static_cast<float>(WINDOW_SIZE/2)); float ymax = floor(static_cast<float>(poseY/CELL_SIZE)) + floor(static_cast<float>(WINDOW_SIZE/2)); float ymin = floor(static_cast<float>(poseY/CELL_SIZE)) - floor(static_cast<float>(WINDOW_SIZE/2)); if(xmin < 0) xmin = 0; if(xmax >= GRID_SIZE) xmax = GRID_SIZE - 1; if(ymin < 0) ymin = 0; if(ymax >= GRID_SIZE) ymax = GRID_SIZE - 1; int lenx = xmax - xmin + 1; int leny = ymax - ymin + 1; // pre alocacao de espaco int *xactive, *yactive; xactive = (int *)calloc(lenx, sizeof(int)); yactive = (int *)calloc(leny, sizeof(int)); // linspace do matlab for(int j = 0; j < lenx; j++) xactive[j] = xmin + j; for(int i = 0; i < leny; i++) yactive[i] = ymin + i; // repmat do matlab //int *xactive = repeat_matrix2(x, lenx, leny); //int *yactive = repeat_matrix(y, leny, lenx); //int activeSize = lenx*leny; vffAngle = vff(occupationGrid, xactive, yactive, lenx, leny, objCellCenter, pc); objAheadX = objAheadX + TIMESTEP * vObj * cos(vffAngle); objAheadY = objAheadY + TIMESTEP * vObj * sin(vffAngle); float distError = sqrt(pow(objAheadY - poseY, 2) + pow(objAheadX - poseX, 2)) - dObj; intError = intError + distError * TIMESTEP; float v = kv * distError + ki * intError; float phiObj = atan2(objAheadY - poseY, objAheadX - poseX); float w = kw*atan2(sin(phiObj - poseTheta), cos(phiObj - poseTheta)); float *wheelSpeeds; wheelSpeeds = (float *)calloc(2, sizeof(float)); robotVel2wheelVel(v, w, wheelSpeeds); wheelSpeeds[0] = mapSpeeds(wheelSpeeds[0]); wheelSpeeds[1] = mapSpeeds(wheelSpeeds[1]); setSpeeds((int)wheelSpeeds[0], (int)wheelSpeeds[1]); free(wheelSpeeds); free(xactive); free(yactive); //printf("f followPath; "); }