Dependencies:   BufferedSerial

main.cpp

Committer:
josefg25
Date:
2021-05-10
Revision:
3:892592b2c2ea
Parent:
2:faef6636d456
Child:
4:0fac5e5d08f7

File content as of revision 3:892592b2c2ea:

#include "mbed.h"
#include "BufferedSerial.h"
#include "rplidar.h"
#include "Robot.h"
#include "Communication.h"
#include <math.h>
#include <time.h>

#define M_PI 3.14159265358979323846

Serial pc(SERIAL_TX, SERIAL_RX);
RPLidar lidar;
BufferedSerial se_lidar(PA_9, PA_10);
PwmOut rplidar_motor(D3);

clock_t start, end;

int nW=2;
float wTheta[2] = {0, 0};
float wRad[2] = {3.5, 3.5};
float wWid[2] = {1.5, 1.5};
float wheelsRadius = 3.5;
float wheelsDistance = 14.7;

//Platform Properties
float platRad=18/2;   

//Constante de Tempo
double T = 0;

//Definição do Mapa
float Mapa200[200][200] = {0.5};
float Mapa40[40][40]={0.5};
int log_mapa[40][40]={0};


//Size Map40
int X = ceil(200/5);
int Y = ceil(200/5);

/*
%Parede da esquerda
for(int i = 0; i <= 200; i++){
   Mapa200[i][0] = {1};
   Mapa200[i][1] = {1};
   Mapa200[i][2] = {1};
}

%Parede da direita
for(int i = 0; i <= 200; i++){
   Mapa200[i][199] = {1};
   Mapa200[i][198] = {1};
   Mapa200[i][197] = {1};
}

%Parede de cima
for(int i = 0; i <= 200; i++){
   Mapa200[0][i] = {1};
   Mapa200[1][i] = {1};
   Mapa200[2][i] = {1};
}

%Parede de baixo
for(int i = 0; i <= 200; i++){
   Mapa200[199][i] = {1};
   Mapa200[198][i] = {1};
   Mapa200[197][i] = {1};
}*/

float pose[3][1];
float pose_f[3][1];
float PointDetected[2][1];

//posicao inicial
float xa = 0;
float ya = 150;
float rPos_a={{xa}, {ya}};
float rTheta_a = 0;

//posicao final
float xf = 50;
float yf = 150;
float rTheta_f=0;
float rPos_a={{xf}, {yf}};

//Waypoints
int waypoints = 1;
float Wx[1] = {25};
float Wy[1] = {125};

//Inicialização do robô
Robot Robot;
robot(Robot, rPos, rTheta, nW, wPos, wTheta, wRad, wWid, platRad);

//Calculo pose inicial 
getPose(Robot, pose);

//------------VFF------------
int fcr = 460; //Intensidade da força repulsiva 
int fca = 20;  //Intensidade da força atrativa
int KS = 25; 
int KV = 3; 
int KI = 0.05;
float erro_int = 0;
float erro = 0;

float vRobot=0; 
float wRobot=0;

float w = 0;

float phi = 0;

float dt = 0;
float delta_fx = 0;
float delta_fy = 0;

//Força Repulsiva
float fax = 0;
float fay = 0;

//Força Resultante
float frx = 0;
float fry = 0;
float Fx = 0;
float Fy = 0;

float i_aux = 0;
float j_aux = 0;
float dij = 0;
float F = 0;
float angulo = 0;

float x_prox = 0;
float y_prox = 0;

float delta_theta = 0;

/*// poll for measurements. Returns -1 if no new measurements are available. returns 0 if found one.
        if(lidar.pollSensorData(&data) == 0) {
            pc.printf("%f\t%f\t%d\t%c\n", data.distance, data.angle, data.quality, data.startBit); // Prints one lidar measurement.
        }

        wait(0.01); 
*/

int main(){
    struct RPLidarMeasurement data;
    
    pc.baud(115200);
    init_communication(&pc);

    // Lidar initialization
    rplidar_motor.period(0.0005f);
    rplidar_motor.write(0.5f);
    lidar.begin(se_lidar);
    lidar.setAngle(0,360);
    setSpeeds(50,50);

    pc.printf("Program started.\n");

    lidar.startThreadScan();

    //Scan for 3s the environment 
    while (T < 3){
        start = clock();
        if(lidar.pollSensorData(&data) == 0) {
            //pc.printf("%f\t%f\t%d\t%c\n", data.distance, data.angle, data.quality, data.startBit); // Prints one lidar measurement.
            ComputeLidarPoint(pose, PointDetected, data.distance, data.angle, float theta)
            occupancy_grid_mapping(log_mapa, Mapa40, d, pose[2], xa, ya, theta, X_grelha, Y_grelha);
        }
        end = clock();
        T = ((double) (end - start)) / CLOCKS_PER_SEC;
    }

    while(1) {
        for(int way = 0; way <= waypoints+1; way++){
            pc.printf("Waypoint %d\n", way);

            if (way < waypoints+1){
                //Vai adicionando os waypoints como pontos finais
                Robot_f = robot([{Wx[way]}, {Wy[way]}],rTheta_f,nW,wPos,wTheta,wRad,wWid,platRad);
                getPose(Robot,pose_f);
                df = sqrt((pose_f[1]-pose[1])^2 + (pose_f[2]-pose[2])^2);
            } 
            elseif (way == waypoints+1){
                //Vai adicionar o ponto final proposto pelo o utilizador
                Robot_f = robot([{rPos_f[1]}, {rPos_f[2]}],rTheta_f,nW,wPos,wTheta,wRad,wWid,platRad);
                getPose(Robot,pose_f);
                df = sqrt((pose_f[1]-pose[1])^2 + (pose_f[2]-pose[2])^2);
            }

            while (df > 5){
                start = clock();
                velRobot2velWheels(vRobot, wRobot, wheelsRadius, wheelsDistance, w);
                nextPose(T, w, wRobot, pose, wheelsRadius, wheelsDistance, pose);

                //FAZER CALCULO DO ON DEMAND
        

                //Força Atrativa
                delta_fx=pose_f[0]-pose[0];
                delta_fy=pose_f[1]-pose[1];

                df=sqrt(delta_fx^2 + delta_fy^2);

                fax=fca*(delta_fx)/df;
                fay=fca*(delta_fy)/df;

                //Força Repulsiva
                frx=0; 
                fry=0;

                for(int j = xa-40; j <= xa+40; j++){
                    for(int i = ya-40; i <= ya+40; i++){
                        if((i > 0) && (i <= Y) && (j > 0) && (j <= X)){
                            if(Mapa40[i][j] ~= 0){
                        //Passar para coordenas cartesianas
                                i_aux=(i-1)*5+2.5;
                                j_aux=(j-1)*5+2.5;

                                dij=sqrt(((i_aux-pose[0])^2+(j_aux-pose[1])^2));

                                F=(fcr*Mapa40(i,j)/(dij^2));
                                angulo=atan2(j_aux-pose[1],i_aux-pose[0]);

                                frx=frx+F*cos(angulo);
                                fry=fry+F*sin(angulo);

                            }
                        }
                    }
                }

                //Força Resultante
                Fx=fax-frx;
                Fy=fay-fry;

                //Posição seguinte
                x_prox=pose[0]+Fx;
                y_prox=pose[1]+Fy;

                //Calculo do Erro
                erro=sqrt((x_prox-pose[0])^2 + (y_prox-pose[1])^2) - 2;
                erro_int=erro_int + erro;

                //Calculo Velocidade  
                vRobot=KV*erro+KI*erro_int;    

                if (vRobot > 50){
                    vRobot = 50;
                }

                //Calculo Phi
                phi=atan2(Fy,Fx);
                phi=atan2(sin(phi),cos(phi));

                delta_theta=atan2(sin(phi-pose[2]),cos(phi-pose[2]));

                //Velocidade Angular
                wRobot=KS*delta_theta;

                //Colocar as velocidades no Robot
                setPose(Robot, pose);

                //Calcula o tempo que recorreu
                end = clock();
                T = ((double) (end - start)) / CLOCKS_PER_SEC;
            }
        }
        pc.printf("Chegou ao ponto final!\n");
    }
}