Nu är grundkoden klar. Roboten kan nu själv räkna ur rutten från sin startposition till mål, utan att gå på några väggar. Koden tar upp 36% av programminnet i min Atmega16, och variablerna(med karta) 22% av eprom(?).
Nästa steg blir att rätta till styrningen, så att en 90graders sväng, verkligen blir 90grader också. Likaså ska kartan anpassas till min lägenhet. Efter det blir det att lägga till en adaptiv funktion som uppdaterar kartan när hinder upptäcks med IR-avståndsmätaren.
Jag har skrivit ner kartan, som programet har ritat upp den. Det är kul att se hur roboten gör när man ändrar i kartan, har ritat upp kartan med eltejp på golvet. Tyvärr så är mina moddade servon inte alls exakta, efter 7-8svängar så är den helt ur kurs, får titta på möjligheten med stegmotorer istället, och större hjulbredd.
Kod: Markera allt
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
void MoveBackward(int);
void MoveForward(int);
void RotateLeft(void);
void RotateRight(void);
void FindLowest(void);
void RoutePath(void);
void GotoNext(void);
int rx = 6; //robot x position
int ry = 4; //robot y position
int direction = 3; //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;
int left;
int right;
int upp;
int down;
int light;
int map[10][10] = {{1,1,1,1,1,1,1,1,1,1}, //0 = unoccupied, 1 = wall, 2 = goal, 255 = robot start
{1,0,0,0,0,0,1,0,0,1},
{1,0,2,0,0,0,1,0,0,1},
{1,0,0,0,0,0,0,0,0,1},
{1,0,0,1,1,1,1,0,0,1},
{1,0,0,1,0,0,0,0,0,1},
{1,0,0,1,255,0,0,0,0,1},
{1,0,0,1,0,0,0,0,0,1},
{1,0,0,1,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1}};
int main(void)
{
//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
RoutePath();
while(1)
{
FindLowest();
GotoNext();
}
}
void GotoNext(void)
{
if(lowest ==1 && direction ==1)
{
MoveForward(1);
rx = rx -1;
}
else if(lowest == 1 && direction == 2)
{
RotateLeft();
MoveForward(1);
direction = lowest;
rx = rx -1;
}
else if(lowest == 1 && direction == 3)
{
RotateRight();
RotateRight();
MoveForward(2);
direction = lowest;
rx = rx -1;
}
else if(lowest == 1 && direction == 4)
{
RotateRight();
MoveForward(1);
direction = lowest;
rx = rx -1;
}
// if lowest = 2
if(lowest ==2 && direction ==2)
{
MoveForward(1);
ry = ry +1;
}
else if(lowest == 2 && direction == 3)
{
RotateLeft();
MoveForward(1);
direction = lowest;
ry = ry +1;
}
else if(lowest == 2 && direction == 4)
{
RotateRight();
RotateRight();
MoveForward(1);
direction = lowest;
ry = ry +1;
}
else if(lowest == 2 && direction == 1)
{
RotateRight();
MoveForward(1);
direction = lowest;
ry = ry +1;
}
// if lowest = 3
if(lowest ==3 && direction ==3)
{
MoveForward(1);
rx = rx +1;
}
else if(lowest == 3 && direction == 4)
{
RotateLeft();
MoveForward(1);
direction = lowest;
rx = rx +1;
}
else if(lowest == 3 && direction == 2)
{
RotateRight();
MoveForward(1);
direction = lowest;
rx = rx +1;
}
else if(lowest == 3 && direction == 1)
{
RotateRight();
RotateRight();
MoveForward(1);
direction = lowest;
rx = rx +1;
}
// if lowest = 4
if(lowest ==4 && direction ==4)
{
MoveForward(1);
ry = ry -1;
}
else if(lowest == 4 && direction == 1)
{
RotateLeft();
MoveForward(1);
direction = lowest;
ry = ry -1;;
}
else if(lowest == 4 && direction == 2)
{
RotateRight();
RotateRight();
MoveForward(1);
direction = lowest;
ry = ry -1;
}
else if(lowest == 4 && direction == 3)
{
RotateRight();
MoveForward(1);
direction = lowest;
ry = ry -1;
}
if(map[rx][ry] == 2)
{
while(1)
{
}
}
}
void FindLowest(void)
{
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;
}
void RoutePath(void)
{
while(quit!=1) //mapping starts
{
value = 0;
if(map[x][y] == 0)
test++;
if(map[x][y] == 1)
test++;
if(map[x][y] == 0) //if square doesnt have number since before
{
if(map[x-1][y] <= 254)
{ //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] == 255) //check if robot startpos is close
proxim = 1;
if(map[x+1][y] <= 254)
{ //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] == 255) //check if robot startpos is close
proxim = 1;
if(map[x][y-1] <= 254)
{ //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] == 255) //check if robot startpos is close
proxim = 1;
if(map[x][y+1] <= 254)
{ //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-1][y] == 255) //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>=8) //next square below
{
x = 1;
y++;
}
else if(x<=7) //next column to the right
x++;
if(y==8 && x==8) //check if hole map has been scaned once, if so, start over
{
x=1;
y=1;
}
}
}
void MoveForward(int sec)
{
int distance;
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;
PORTD |=(1<<7);
while(light <= 1000)
{
while(TCNT1 <=6000)
{
}
TCNT1 = 0;
light ++;
}
PORTD &=~(1<<7);
light = 0;
}
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 <= 65)
{
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 <= 65)
{
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;
}
}