Robot med helvarvs-servon
Re: Robot med helvarvs-servon
Jag håller på att bygga något liknande, även om det ligger i malpåse.
Snygga hjul måste jag säga! Var har du hitta dom? Har mycket svårt att hitta bra hjul till min.
Min konstruktion är i frigolit och aluminiumfolie så ... den är lite efter i hårdhet.
Snygga hjul måste jag säga! Var har du hitta dom? Har mycket svårt att hitta bra hjul till min.
Min konstruktion är i frigolit och aluminiumfolie så ... den är lite efter i hårdhet.
Re: Robot med helvarvs-servon
Hej
Jag är jättenöjd med hjulen, köpte dom på Hobbytronik.
http://www.hobbytronik.se/product_info. ... ucts_id/35
//Alexander
Jag är jättenöjd med hjulen, köpte dom på Hobbytronik.
http://www.hobbytronik.se/product_info. ... ucts_id/35
//Alexander
Re: Robot med helvarvs-servon
Nu har jag finslipat lite på koden och tror att den ska fungera, har simulerat den i AvrStudio ett antal vändor. Kartan är utökat till 10x10.
Jag ska börja skriva lite på programdelen som ska följa själva kartan också, och en lösning till hur roboten ska reagera om det inte finns någon väg alls till målet.
//Alexander
Kod: Markera allt
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,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 proxim;
int x = 1; //Set start, upper left
int y = 1; //corner
while(quit!=1) //mapping starts
{
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
}
else 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)
value = map[x-1][y]; //save number on the one on the left
}
else 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)
value = map[x-1][y]; //save number on the one on the left
}
else 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)
value = map[x][y+1]; //save number on the one on the left
}
else 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.
map[x][y] = value + 1;
proxim = 0;
}
if(y>=8) //next column
{
y = 1;
x++;
}
else if(y<=7) //next row
y++;
if(y==8 && x==8) //check if hole map has been scaned once, if so, start over
{
x=1;
y=1;
}
//Alexander
Re: Robot med helvarvs-servon
Kastar ut en ide som flöt upp, den är alltså inte genomtänkt för fem öre men kan kanske vara något att lura på.
Istället för en karta med data på varenda x,y position i hela världen, så spara en lista på x,y koordianter där det finns något. Dvs du slipper spara en massa nollor i minnet.
Denna lista utökas sedan allt eftersom du hittar saker tills minnet är fullt, då kan du börja slänga det som är längst bort eller äldst eller vad du nu vill göra när kartan är full...
Istället för en karta med data på varenda x,y position i hela världen, så spara en lista på x,y koordianter där det finns något. Dvs du slipper spara en massa nollor i minnet.
Denna lista utökas sedan allt eftersom du hittar saker tills minnet är fullt, då kan du börja slänga det som är längst bort eller äldst eller vad du nu vill göra när kartan är full...
-
- Inlägg: 2436
- Blev medlem: 28 januari 2007, 18:45:40
- Ort: Kungsbacka
Re: Robot med helvarvs-servon
Inte så smart om det finns fler än några få punkter.
Och då måste du kolla på alla punkter för att se om det finns något på den punkten du vill se på om du inte sorterar dem.
Och då måste du kolla på alla punkter för att se om det finns något på den punkten du vill se på om du inte sorterar dem.
Re: Robot med helvarvs-servon
Nja, man kan ha rätt många punkter innan man går back förstås. (halva kartan fullklottrad)
Nackdelen är som du säger att man behöver söka igenom dem när man frågar efter status på en position, fast med tanke på hur lite minne det finns att tillgå så lär en sådan sökning inte bli särskilt tung.
Nackdelen är som du säger att man behöver söka igenom dem när man frågar efter status på en position, fast med tanke på hur lite minne det finns att tillgå så lär en sådan sökning inte bli särskilt tung.
Re: Robot med helvarvs-servon
Nu har jag skrivit klart koden, roboten ska nu också kunna följa kartan som ritas upp. Det fungerar dock inte, och i mina simuleringar i AvrStudio beter sig programet märkligt åt.
Matrisen ser ut så här, men när jag började felsöka så visar en extra rad som jag lade in, att
den påstår att ruta 1:6 är = 1, men den är 0. Programmet fungerar som det ska ända tills denna ruta. Vad kan vara tokigt?
//Alexander
Kod: Markera allt
int map[10][10]= {{1,1,1,1,1,1,1,1,1,1}, {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}};
Kod: Markera allt
if(map[1][6] == 1)
test++;
//Alexander
Re: Robot med helvarvs-servon
Kod: Markera allt
int map[10][10]= {
{1,1,1,1,1,1,1,1,1,1},
{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}};
{1,0,0,0,0,0,1,0,0,1},
_0 1 2 3 4 5 6 7 8 9
position 6 (dvs. sjunde elementet ifrån vänster) är 1.
Det är inte så att du har gjort någon tankevurpa??
Re: Robot med helvarvs-servon
Däremot så är map[6][1] en nolla. Du tänkte kanske fel på x och y?
- JimmyAndersson
- Inlägg: 26571
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: Robot med helvarvs-servon
Eller glömde nollan och började räkna från ett.
Det finns många sätt att räkna fel med sånt här. Jag har nog provat de flesta..
Det finns många sätt att räkna fel med sånt här. Jag har nog provat de flesta..

Re: Robot med helvarvs-servon
Hej
Självklart har jag blandat ihop X och Y
Tackar för hjälpen!
//Alexander
Självklart har jag blandat ihop X och Y

//Alexander
Re: Robot med helvarvs-servon
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.

Här är koden, i fungerande skick.
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.

Här är koden, i fungerande skick.
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;
}
}
Re: Robot med helvarvs-servon
Du skulle ju kunna använda en kompass för att få till 90 graderssvänga utan att driva med tiden! De kostar ju inte särskilt mycket.
Jag har inte riktigt kollat igenom din kod, men jag förstår inte varför den börjar med att gå till rutan med 13 i och inte den bredvid med 12?? Vad betyder 0'orna?
Annars:
. Ser riktigt lovande ut!
Jag har inte riktigt kollat igenom din kod, men jag förstår inte varför den börjar med att gå till rutan med 13 i och inte den bredvid med 12?? Vad betyder 0'orna?

Annars:

Re: Robot med helvarvs-servon
Hej
Roboten går enbart i 90graders vinklar, när den söker av omgivningen efter lägre nummer hittar den inte dom som är på "diagonalen". 0'orna betyder att rutan är tom, inga hinder, och att den inte har blivit tilldelad en siffra.
0 = tom
1 = vägg
2 = mål
255 = start
3-254 = siffror som ska följas i minskande ordning.
Jag har börjat fundera lite på adaptiv mappning, en modell är att ha 2st kartor, ett orginal som sedan kopieras och fylls med siffor, och varje gång ett hinder hittas på vägen, så uppdateras orginalet och en ny kopia görs, med nya siffror. Kommer dock ta dubbelt så mycket utrymme. Kartan kan göras något större, kanske 20x20 om man enbart använder en.
Jag tror tyvärr att man inte kan använda programinnet till någon av dem, eftersom man måste kunna skriva till dem under programets gång.
//Alexander
Roboten går enbart i 90graders vinklar, när den söker av omgivningen efter lägre nummer hittar den inte dom som är på "diagonalen". 0'orna betyder att rutan är tom, inga hinder, och att den inte har blivit tilldelad en siffra.
0 = tom
1 = vägg
2 = mål
255 = start
3-254 = siffror som ska följas i minskande ordning.
Jag har börjat fundera lite på adaptiv mappning, en modell är att ha 2st kartor, ett orginal som sedan kopieras och fylls med siffor, och varje gång ett hinder hittas på vägen, så uppdateras orginalet och en ny kopia görs, med nya siffror. Kommer dock ta dubbelt så mycket utrymme. Kartan kan göras något större, kanske 20x20 om man enbart använder en.
Jag tror tyvärr att man inte kan använda programinnet till någon av dem, eftersom man måste kunna skriva till dem under programets gång.
//Alexander
Re: Robot med helvarvs-servon
Jag började på något liknande en gång (men det har kommit av sig lite). I alla fall så hade jag två moddade servon för hjulen, samt "kugghjul" på utgående axel och läsgafflar så att jag fick lite feedback på hur de snurrade egentligen.
En liten P-regulator sänkte farten aningens på det hjul som kom efter det andra vid rakt fram körning.
osv osv.
En liten P-regulator sänkte farten aningens på det hjul som kom efter det andra vid rakt fram körning.
osv osv.