Det blev mycket enklare för den att hålla kursen med större hjulavstånd. Den arbetar nu efter en karta som är 18x18 rutor stor, och varje ruta är 34x34cm. En lärdom till nästa projekt är att Sharps IR avståndsmätare har en mycket smal "mätstråle". Ping sensor hade varit bättre.
Den fixar dock biffen och går från sovrum till arbetsrum, och navigerar runt alla hinder på vägen. En LCD display listar position och sysselsättning, eller om roboten har blivit instängd.
WaveFront algoritmen är mycket enkel att arbeta med. Alla andra alternativ som jag har hittat verkar kräva långtgående akademiska kunskaper i ämnet
Kod: Markera allt
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "lcd.h"
void MoveBackward(int);
void MoveForward(int);
void RotateLeft(void);
void RotateRight(void);
void FindLowest(void);
void RoutePath(void);
void GotoNext(void);
void ClearMap(void);
int rx = 16; //robot x position
int ry = 4;
int gx = 2;
int gy = 4; //robot y position
int direction = 1; //robot direction
int lowest; //check for lowest number
int proxim; //starting pos is in vicinity
int x = 1; //Set start, upper left
int y = 1; //corner
int quit = 0; //path found
int distance; //distance
int value;
int test = 800;
int left;
int right;
int upp;
int down;
int light;
int qr;
int test;
char cx[4]; //for LCD rx
char cy[4]; //for LCD ry
int map[18][18] = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, //0 = unoccupied, 1 = wall, 2 = goal, 254 = robot start
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
int main(void)
{
map[rx][ry] = 254; //set startposition
map[gx][gy] = 2; //set goalposition
//TIMERS
TCCR1B |=(1<<CS10); //Start timer at F/CPU
//ADC
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
ADMUX |= ((1 << REFS0)|(1 << REFS1));
ADCSRA |= (1 << ADATE);
ADCSRA |= (1 << ADEN);
ADCSRA |= (1 << ADSC);
//PORTS
DDRD = 255; //Set Port D as Output
DDRC = 0; //Set Port C as Input
PORTC|=_BV(0); //Enable internal PullUpp on PortC, Pin 0
lcd_init(LCD_DISP_ON);
RoutePath();
while(1)
{
FindLowest();
GotoNext();
}
}
void GotoNext(void)
{
lcd_clrscr();
itoa(rx,cx,10);
itoa(ry,cy,10);
lcd_gotoxy(0,0);
lcd_puts("x:");
lcd_gotoxy(0,1);
lcd_puts("y:");
lcd_gotoxy(2,0);
lcd_puts(cx);
lcd_gotoxy(2,1);
lcd_puts(cy);
if(lowest ==1 && direction ==1)
{
MoveForward(3);
if(qr != 1)
rx = rx -1;
qr = 0;
}
else if(lowest == 1 && direction == 2)
{
RotateLeft();
direction = lowest;
MoveForward(3);
if(qr != 1)
rx = rx -1;
qr = 0;
}
else if(lowest == 1 && direction == 3)
{
RotateRight();
RotateRight();
direction = lowest;
MoveForward(3);
if(qr != 1)
rx = rx -1;
qr = 0;
}
else if(lowest == 1 && direction == 4)
{
RotateRight();
direction = lowest;
MoveForward(3);
if(qr != 1)
rx = rx -1;
qr = 0;
}
// if lowest = 2
if(lowest ==2 && direction ==2)
{
MoveForward(3);
if(qr != 1)
ry = ry +1;
qr = 0;
}
else if(lowest == 2 && direction == 3)
{
RotateLeft();
direction = lowest;
MoveForward(3);
if(qr != 1)
ry = ry +1;
qr = 0;
}
else if(lowest == 2 && direction == 4)
{
RotateRight();
RotateRight();
direction = lowest;
MoveForward(3);
if(qr != 1)
ry = ry +1;
qr = 0;
}
else if(lowest == 2 && direction == 1)
{
RotateRight();
direction = lowest;
MoveForward(3);
if(qr != 1)
ry = ry +1;
qr = 0;
}
// if lowest = 3
if(lowest ==3 && direction ==3)
{
MoveForward(3);
if(qr != 1)
rx = rx +1;
qr = 0;
}
else if(lowest == 3 && direction == 4)
{
RotateLeft();
direction = lowest;
MoveForward(3);
if(qr != 1)
rx = rx +1;
qr = 0;
}
else if(lowest == 3 && direction == 2)
{
RotateRight();
direction = lowest;
MoveForward(3);
if(qr != 1)
rx = rx +1;
qr = 0;
}
else if(lowest == 3 && direction == 1)
{
RotateRight();
RotateRight();
direction = lowest;
MoveForward(3);
if(qr != 1)
rx = rx +1;
qr = 0;
}
// if lowest = 4
if(lowest ==4 && direction ==4)
{
MoveForward(3);
if(qr != 1)
ry = ry -1;
qr = 0;
}
else if(lowest == 4 && direction == 1)
{
RotateLeft();
direction = lowest;
MoveForward(3);
if(qr != 1)
ry = ry -1;
qr = 0;
}
else if(lowest == 4 && direction == 2)
{
RotateRight();
RotateRight();
direction = lowest;
MoveForward(3);
if(qr != 1)
ry = ry -1;
qr = 0;
}
else if(lowest == 4 && direction == 3)
{
RotateRight();
direction = lowest;
MoveForward(3);
if(qr != 1)
ry = ry -1;
qr = 0;
}
if(map[rx][ry] == 2)
{
lcd_clrscr();
lcd_puts("goal found");
while(1)
{
}
}
}
void FindLowest(void)
{
lcd_clrscr();
lcd_puts("SEARCH LOWEST");
if(map[rx-1][ry] <=1)
upp = 255;
else upp = map[rx-1][ry];
if(map[rx][ry-1] <=1)
left = 255;
else left = map[rx][ry-1];
if(map[rx+1][ry] <=1)
down = 255;
else down = map[rx+1][ry];
if(map[rx][ry+1] <=1)
right = 255;
else right = map[rx][ry+1];
if(right <= upp && right <= left && right <= down)
lowest = 2;
if(down <= upp && down <= left && down <= right)
lowest = 3;
if(left <= upp && left <= right && left <= down)
lowest = 4;
if(upp <= right && upp <= left && upp <= down)
lowest = 1;
if(upp == right && right == down && down == left && left == upp) //if trapped
{
while(1)
{
lcd_clrscr();
lcd_puts("TRAPPED");
}
}
}
void RoutePath(void)
{
lcd_clrscr();
lcd_puts("TRAPPED!");
x = 1;
y = 1;
while(1) //mapping starts
{
value = 0;
if(map[x][y] == 0) //if square doesnt have number since before
{
if(map[x-1][y] <= 253)
{ //check left if not wall or robot startingpos
if(map[x-1][y] >= 2)
value = map[x-1][y]; //save number on the one on the left
}
if(map[x-1][y] == 254) //check if robot startpos is close
proxim = 1;
if(map[x+1][y] <= 253)
{ //check right if not wall or robot startingpos
if(map[x+1][y] >= 2)
{
if(value >= map[x+1][y])
value = map[x+1][y]; //save number on the one on the left
if(value == 0)
value = map[x+1][y];
}
}
if(map[x+1][y] == 254) //check if robot startpos is close
proxim = 1;
if(map[x][y-1] <= 253)
{ //check above not wall or robot startingpos
if(map[x][y-1] >= 2)
{
if(value >= map[x][y-1])
value = map[x][y-1]; //save number on the one on the left
if(value == 0)
value = map[x][y-1];
}
}
if(map[x][y-1] == 254) //check if robot startpos is close
proxim = 1;
if(map[x][y+1] <= 253)
{ //check below if not wall or robot startingpos
if(map[x][y+1] >= 2)
{
if(value >= map[x][y+1])
value = map[x][y+1]; //save number on the one on the left
if(value == 0)
value = map[x][y+1];
}
}
if(map[x][y+1] == 254) //check if robot startpos is close
proxim = 1;
}
if(value >= 3) //check if map coordinate is set
{
if(proxim == 1)
quit = 1; //and if robot start pos is next
} //path found.
if(value > 0)
{
value++;
map[x][y] = value;
}
proxim = 0;
if(x>=17) //next square below
{
x = 1;
y++;
}
else if(x<=16) //next column to the right
x++;
if(y>=17 && x>=17) //check if hole map has been scaned once, if so, start over
{
x=1;
y=1;
}
if(quit == 1 && y>=16)
goto finish;
}
finish:;
quit = 0;
}
void MoveForward(int sec)
{
distance = ADCL + (ADCH<<8);
if(distance >= 320)
{
lcd_clrscr();
lcd_puts("PATH BLOCKED");
ClearMap();
RoutePath();
qr = 1;
goto end;
}
int gang = 0;
int P = 0;
while((gang/50) <= sec)
{
gang = gang + 1;
PORTD &=~(1<<0);
PORTD &=~(1<<1);
while(P <= 12)
{
while(TCNT1 <= 19000)
{
}
P = P + 1;
TCNT1 = 0;
}
P = 0;
TCNT1 = 0;
PORTD |=(1<<0);
PORTD |=(1<<1);
while(TCNT1 <= 9300)
{
}
PORTD &=~(1<<0);
TCNT1 = 0;
while(TCNT1 <= 1040)
{
}
PORTD &=~(1<<1);
TCNT1 = 0;
}
TCNT1 = 0;
end:;
}
void MoveBackward(int sec)
{
int gang = 0;
int P = 0;
while((gang/20) <= sec)
{
gang = gang + 1;
PORTD &=~(1<<0);
PORTD &=~(1<<1);
while(P <= 12)
{
while(TCNT1 <= 19000)
{
}
P = P + 1;
TCNT1 = 0;
}
P = 0;
TCNT1 = 0;
PORTD |=(1<<0);
PORTD |=(1<<1);
while(TCNT1 <= 9300)
{
}
PORTD &=~(1<<1);
TCNT1 = 0;
while(TCNT1 <= 1050)
{
}
PORTD &=~(1<<0);
TCNT1 = 0;
}
}
void RotateRight(void)
{
int gang = 0;
int P = 0;
while(gang <= 135)
{
gang = gang + 1;
PORTD &=~(1<<0);
PORTD &=~(1<<1);
while(P <= 12)
{
while(TCNT1 <= 19000)
{
}
P = P + 1;
TCNT1 = 0;
}
P = 0;
TCNT1 = 0;
PORTD |=(1<<0);
PORTD |=(1<<1);
while(TCNT1 <= 9300)
{
}
PORTD &=~(1<<0);
TCNT1 = 0;
while(TCNT1 <= 1)
{
}
PORTD &=~(1<<1);
TCNT1 = 0;
}
}
void RotateLeft(void)
{
int gang = 0;
int P = 0;
while(gang <=120)
{
gang = gang + 1;
PORTD &=~(1<<0);
PORTD &=~(1<<1);
while(P <= 12)
{
while(TCNT1 <= 19000)
{
}
P = P + 1;
TCNT1 = 0;
}
P = 0;
TCNT1 = 0;
PORTD |=(1<<0);
PORTD |=(1<<1);
while(TCNT1 <= 10350)
{
}
PORTD &=~(1<<0);
TCNT1 = 0;
while(TCNT1 <= 1)
{
}
PORTD &=~(1<<1);
TCNT1 = 0;
}
}
void ClearMap(void)
{
lcd_clrscr();
lcd_puts("CLEARING MAP");
if(direction == 1)
map[rx-1][ry] = 1;
if(direction == 2)
map[rx][ry+1] = 1;
if(direction == 3)
map[rx+1][ry] = 1;
if(direction == 4)
map[rx][ry-1] = 1;
x = 1;
y = 1;
while(y<=9)
{
if(map[x][y] >=3 && map[x][y] != 254)
map[x][y] = 0;
if(map[x][y] == 3)
map[x][y] = 0;
if(x<17)
x++;
else
{
x=1;
y++;
}
}
}