// Detection Functions
void scan(int a, int b, int c, int d){
for(int i=0 ; i< IR_NB_READINGS; i++){
irReadings0[i] = analogRead(a);
irReadings1[i] = analogRead(b);
irReadings2[i] = analogRead(c);
irReadings3[i] = analogRead(d);}
valuesOptimisation();
}
void valuesOptimisation(){
ir_dist[0]=read_gp2d12_range(test_valeurs(irReadings0, IR_NB_READINGS));
//Serial.println("");
ir_dist[1]=read_gp2d12_range(test_valeurs(irReadings1, IR_NB_READINGS));
//Serial.println("");
ir_dist[2]=read_gp2d12_range(test_valeurs(irReadings2, IR_NB_READINGS));
//Serial.println("");
ir_dist[3]=read_gp2d12_range(test_valeurs(irReadings3, IR_NB_READINGS));}
//Serial.println("");
boolean nothingInFront(){
if ((ir_dist[0] < 75) || (ir_dist[1] < 75) || (ir_dist[2] < 75) || (ir_dist[3] < 75)){
return false;}
else {
return true;}}
boolean obstacle(){
if ((ir_dist[0] < DISTANCE_LIMIT) || (ir_dist[1] < DISTANCE_LIMIT) || (ir_dist[2] < DISTANCE_LIMIT) || (ir_dist[3] < DISTANCE_LIMIT)){
return true;}
else {
return false;}
}
void obstacleAvoidanceModule(){
if ((ir_dist[0] < DISTANCE_LIMIT) && ((ir_dist[1] > DISTANCE_LIMIT) && (ir_dist[2] > DISTANCE_LIMIT) && (ir_dist[3] > DISTANCE_LIMIT))){
go_forward((int)(TURN_SPEED+1.2*ir_dist[0]),(int)(0.75*FORWARD_SPEED));}
else if (((ir_dist[0] > DISTANCE_LIMIT) && (ir_dist[1] > DISTANCE_LIMIT) && (ir_dist[2] > DISTANCE_LIMIT)) && (ir_dist[3] < DISTANCE_LIMIT)){
go_forward((int)(0.75*FORWARD_SPEED),(int)((TURN_SPEED+1.2*ir_dist[3])));}
else if (((ir_dist[0] < DISTANCE_LIMIT) && (ir_dist[3] < DISTANCE_LIMIT)) && ((ir_dist[1] > DISTANCE_LIMIT) && (ir_dist[2] > DISTANCE_LIMIT))){
go_forward(FORWARD_SPEED,FORWARD_SPEED);}
else if ((ir_dist[0] < DISTANCE_LIMIT)||(ir_dist[1] < DISTANCE_LIMIT)){
turn_left(1.6*TURN_SPEED,FORWARD_SPEED);}
else if ((ir_dist[3] < DISTANCE_LIMIT)||(ir_dist[2] < DISTANCE_LIMIT)){
turn_right(FORWARD_SPEED,1.6*TURN_SPEED);}
if ((ir_dist[1] < DISTANCE_LIMIT) && (ir_dist[2] < DISTANCE_LIMIT)){
if((ir_dist[0] < DISTANCE_LIMIT)&&(ir_dist[3] > DISTANCE_LIMIT)){
go_backwards((int)(0.75*FORWARD_SPEED),(int)((TURN_SPEED+1.2/3*(ir_dist[0]+ir_dist[1]+ir_dist[2]))));}
else if ((ir_dist[3] < DISTANCE_LIMIT)&&(ir_dist[0] > DISTANCE_LIMIT)){
go_backwards((TURN_SPEED+(int)(1.2/3*(ir_dist[1]+ir_dist[2]+ir_dist[3]))),(int)(0.75*FORWARD_SPEED));}
if ((ir_dist[3] < DISTANCE_LIMIT)&&(ir_dist[0] < DISTANCE_LIMIT)){
if(ir_dist[0] < ir_dist[3]){
go_backwards(TOPSPEED,0);}
else{
go_backwards(0,TOPSPEED);}}
}
}
// Motor Functions
void set_speed(int left, int right){ // set speed
speeds[0]=left;
speeds[1]=right;
analogWrite(speedPinA, speeds[0]);
analogWrite(speedPinB, speeds[1]);}
void set_direction (byte j){ // set direction ==>> 0 = right ; 1 = left ; 2 = go backward ; 3 = forward <<==
switch(j){
case 0:
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
break;
case 1:
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
break;
case 2:
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
break;
case 3:
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
break;}}
void go_forward(int left, int right){
set_speed(left, right);
set_direction(3);}
void go_backwards(int left, int right){
set_speed(left, right);
set_direction(2);}
void turn_right(int left, int right){
set_speed(left,right);
set_direction(1);}
void turn_left(int left, int right){
set_speed(left,right);
set_direction(0);}
void accelerate(int init, int fin){
for (i=init; i<=fin; i+=1){
go_forward(i,i);}}
void slowToStop(){
for (i=TOPSPEED; i>=0 ; i-=5) {
go_forward(i,i);}}
void stoppe(){
set_speed(0,0);}
// Distance Conversion
float read_gp2d12_range(float ir_value){
if (ir_value < 3){
return -1; }// invalid value
return (6787.0 /(ir_value - 3.0)) - 4.0;}
// Test Values
float test_valeurs(int *tab, int sizeTab){
// Local Variables
int i,j;
int copy[sizeTab];
float var[sizeTab];
float mean=0;
float varmean=0;
int nb_best = sizeTab*3/5;
int newCopy[nb_best];
float newmean=0;
// Copy tab, Calculate mean
for (i=0; i<sizeTab;i++){
copy[i]=tab[i];
mean+=tab[i];}
mean/=sizeTab;
// Calculate variances and meand of variances : Var = (value - mean)²
for(i=0 ; i<sizeTab ; i++){
var[i]=pow((tab[i] - mean), 2);
varmean+=var[i];}
varmean/=sizeTab;
// Selection and Copy best values according to the variance criterion then calculate new mean
for (i=0; i<nb_best; i++){
int it=-1;
int max=0;
for (j=0; j<sizeTab; j++){
if (copy[j]>max && var[j]<= varmean){
max=copy[j];
it=j;}
}
newCopy[i]=copy[it];
if((newCopy[i]>600)||(newCopy[i]<3)){
newCopy[i]=mean;}
newmean+=newCopy[i];
copy[it]=0;
}
newmean/=nb_best;
return newmean;
}
// Beacon Functions
void readTransceiver(int a, int b, int c, int d){
north = analogRead(a);
east = analogRead(b);
south = analogRead(c);
west = analogRead(d);}
boolean foundBeacon(){
if((west > DETECTION_CONST) && (east > DETECTION_CONST ) && (south > DETECTION_CONST ) && (north > DETECTION_CONST)){
return false; }
else{
return true; }}
void getDirAndSetMode(){
getDirection();
setModeOfDirections();}
void getDirection(){
if(minValue > west){
//minValue = west;
dir = 4;}
else if(minValue > south){
//minValue = south;
dir = 3;}
else if(minValue > east){
//minValue = east;
dir = 2;}
else if(minValue > north){
//minValue = north;
dir = 1;}
addDirectionToReadings();}
//print_beacon_direction();
void addDirectionToReadings(){
directionReadings[index] = dir;
index = (index + 1);
if (index == NUM_READINGS) // if we're at the end of the array...
index = 0;}
void setModeOfDirections(){
int directionCounts[4] = {0,0,0,0}; //{North(1), East(2), South(3), West(4)}
for (int i = 0; i < NUM_READINGS; i++){
//Serial.print(directionReadings[i]);
//Serial.print("|");
directionCounts[directionReadings[i]-1]++;}
//Determine mode of directions from count array
//Serial.println("");
int maxi=0;
int it=-1;
for(int i = 0; i < 4; i++){
//Serial.print(directionCounts[i]);
//Serial.print("|");
if(maxi < directionCounts[i]){
maxi = directionCounts[i]; //set count
it = i+1;}} // set direction}
modeOfDirections = it;
//Serial.println("");
//Serial.print("Direction Mode: ");
//Serial.println(modeOfDirections);
}
void moveTowardBeacon(){
//g_lcd.clear();
getDirAndSetMode();
if( modeOfDirections == 4 || modeOfDirections==3){ // West
turn_left(BEACON_SPEED, TURN_SPEED);}
else if( modeOfDirections == 2 ){ // East
turn_right(TURN_SPEED,BEACON_SPEED);}
//delay (100);
else if( modeOfDirections == 1 ){ //North
if (accelerateOn==true){
go_forward(TOPSPEED,TOPSPEED);}
else{
go_forward(FORWARD_SPEED,FORWARD_SPEED);}}
}