Robot med helvarvs-servon

Berätta om dina pågående projekt.
Användarvisningsbild
netrunner
Inlägg: 5510
Blev medlem: 4 februari 2005, 12:26:05
Ort: 127.0.0.1

Re: Robot med helvarvs-servon

Inlägg av netrunner »

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.
Anonym2
Inlägg: 456
Blev medlem: 17 november 2007, 21:20:16

Re: Robot med helvarvs-servon

Inlägg av Anonym2 »

Hej

Jag är jättenöjd med hjulen, köpte dom på Hobbytronik.

http://www.hobbytronik.se/product_info. ... ucts_id/35


//Alexander
Anonym2
Inlägg: 456
Blev medlem: 17 november 2007, 21:20:16

Re: Robot med helvarvs-servon

Inlägg av Anonym2 »

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.

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;
				}


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
Gimbal
Inlägg: 8653
Blev medlem: 20 april 2005, 15:43:53

Re: Robot med helvarvs-servon

Inlägg av Gimbal »

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...
victor_passe
Inlägg: 2436
Blev medlem: 28 januari 2007, 18:45:40
Ort: Kungsbacka

Re: Robot med helvarvs-servon

Inlägg av victor_passe »

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.
Gimbal
Inlägg: 8653
Blev medlem: 20 april 2005, 15:43:53

Re: Robot med helvarvs-servon

Inlägg av Gimbal »

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.
Anonym2
Inlägg: 456
Blev medlem: 17 november 2007, 21:20:16

Re: Robot med helvarvs-servon

Inlägg av Anonym2 »

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.

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}};
Matrisen ser ut så här, men när jag började felsöka så visar en extra rad som jag lade in, att

Kod: Markera allt

if(map[1][6] == 1)
	test++;	
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
Användarvisningsbild
Stinrew
Inlägg: 954
Blev medlem: 20 augusti 2006, 03:14:41
Ort: Motala
Kontakt:

Re: Robot med helvarvs-servon

Inlägg av Stinrew »

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}};
Jag håller med programmet. Jag får också [1,6] till 1. Rad 1 (dvs. andra raden uppifrån) är denna:
{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??
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Re: Robot med helvarvs-servon

Inlägg av squiz3r »

Däremot så är map[6][1] en nolla. Du tänkte kanske fel på x och y?
Användarvisningsbild
JimmyAndersson
Inlägg: 26571
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Re: Robot med helvarvs-servon

Inlägg av JimmyAndersson »

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.. :D
Anonym2
Inlägg: 456
Blev medlem: 17 november 2007, 21:20:16

Re: Robot med helvarvs-servon

Inlägg av Anonym2 »

Hej

Självklart har jag blandat ihop X och Y :) Tackar för hjälpen!


//Alexander
Anonym2
Inlägg: 456
Blev medlem: 17 november 2007, 21:20:16

Re: Robot med helvarvs-servon

Inlägg av Anonym2 »

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.

Bild

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;
		}
}
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Re: Robot med helvarvs-servon

Inlägg av squiz3r »

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: :tumupp:. Ser riktigt lovande ut!
Anonym2
Inlägg: 456
Blev medlem: 17 november 2007, 21:20:16

Re: Robot med helvarvs-servon

Inlägg av Anonym2 »

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
Gimbal
Inlägg: 8653
Blev medlem: 20 april 2005, 15:43:53

Re: Robot med helvarvs-servon

Inlägg av Gimbal »

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.
Skriv svar