Intelligente robot bouwen; wie kan me helpen???

Hoi iedereen,

Na veel lezen en zoeken heb ik me toch maar geregistreerd om zelf een paar vragen te stellen over ene project waar ik mee bezig ben.

Ik ben een robot aan het maken, aangedreven door een PIC18f4550. Hieraan heb ik twee dir/step chips aangesloten om de 2 unipolaire stappenmotoren aan te sturen (luie oplossing om niet steeds de polen om te gooien). De angle per step is 1,8 graden.
De input en output staat verder nog niet helemaal vast; afgezien van de standaard bumper "sensoren" om botsingen te detecteren.

De robot zal bij houden waar hij is door de omwentelingen (stappen) van de motoren (ik weet dat dit niet de ideale oplossing is, maar zoiets als GPS is ietsje boven het budjet ;) ), geholpen door een absolute plaatsbepaling d.m.v. een nader te bepalen methode (dacht zelf aan kruis op de grond).

Nu mijn vragen, waar jullie me misschien bij kunnen helpen:

"Ik wil dat de robot onthoudt waar hij een botsing gemaakt heeft en dit dus vervolgens niet meer doet. Hij houdt zelf al relatieve x && y waardes bij. Deze zou ik op het moment van botsen dus naar een matrix willen schrijven, maar hier heb ik geen ervaring mee. Ik programmeer nu in C++ voor de eerste keer en weet wel hoe ik een matrix moet maken, namelijk bv. int a[4][6]; Maar ik wil de waardes eigenlijk variabel hebben, zoiets als int a[X][Y]; maar dit werkt niet. Als iemand een oplossing zou weten zou hij/zij me enorm uit de brand helpen. Misschien weet diegene ook hoe ik een method moet schrijven welke deze coordinaten checked en de robot verteld dara niet naartoe te gaan, dat zou helemaal geweldig zijn."

Een andere functie van de robot is dat als de spanning van de batterij onder een bepaalde waarde komt, hij in de richting van punt 0,0 draait (zijn laadstation) en de afstand tot dat punt begint af te leggen. De berekeningen zelf zijn allemaal geen probleem, hele simpele pythagoras/tangent berekeningen worden gebruikt. Wel heb ik een vraag over het volgende:

"Hoe lees ik de waarde van de batterijen af en hoe sluit ik dit precies aan. Ik weet dat het met de ad-convertor commando's moet, mara weet niet precies hoe. Ik heb nu het volgende:

void main(void)
{
TRISB = 0b00000000; // Port B0-B7 = output
TRISD = 0b11111111; // Port D0-D7 = input

ADCON0 = 0x01; // Channel 0, not started, ADC ON
ADCON1 = 0x07; // Portconfig: AN0 analog, other i/o digital, Vref- = Vss, Vref+ = Vdd
ADCON2 = 0b00111010; // Result left justified, aq time = 20 Tad, conversion clock = Fosc/32

while(1) {
Delay10mS(5); //Delay for 50mS (voor de AD conversion)

ADCON0bits.GO = 1; // Start conversion
while(ADCON0bits.GO == 1); // Wait for completion
resultLDR = ADRESH; // Read result, 8 MSBs
LATB = resultLDR; // Write 8 MSBs of result to port D
}

}

Ik hoop dat de code een beetje overzichtelijk overgekomen is; ik heb er de nutteloze regels voor deze vraag uitgehaald. Ik heb deze code van de site van m'n universiteit afgehaald, maar snap eerlijk gezegd niet goed wat het doet. Hopelijk iemand aanwezig die het wel weet en het me kan uitleggen :)

Paar korte vraagjes nog:
"Weet iemand hoe ik de robot kan belonen/straffen? So called reinforcement learning...? Ik wete nog niet of ik het nodig zal hebben, maar ik vind het wel een heel interressant onderwerp dus alles wat ik kan leren is meegenomen!"

"Iemand ervaring met zonnepaneeltje i.p.v. een batterij? Ik denk dan aan een leuke toepassing met LDR-tjes ofzo, maar ben bang voor de beperkte spanning en stroom die die dingen leveren, ook de kosten zullen misschien al meteen een dik kruis door dit idee zetten :), ik wete het in ieder geval niet."

Ondertussen is het een heel verhaal geworden en ben benieuwd hoe de layout wordt na het posten (best irri dit kleine schermpje); alvast bedankt voor diegene die me kunnen helpen!

Op 11 maart 2007 17:59:33 schreef XQlusive:

"Ik wil dat de robot onthoudt waar hij een botsing gemaakt heeft en dit dus vervolgens niet meer doet.

ben benieuwd hoe de layout wordt na het posten (best irri dit kleine schermpje)

Ik ben helemaal niet thuis in het wereldje van C++, maar ik stel me de vraag bij dat onthouden van een obstakel.
Als je object nu een vluchtig object is (lees: verplaatsbaar), dan zal de robot de volgende keer uitwijken voor iets dat er niet meer is ?

en btw, je kan je post eens eens bekijken door op de knop "Preview" te klikken voordat je op de knop "posten" klikt :)

Je zou eventueel een IR sensor plus IR led kunnen gebruiken als input.

Ja klopt, heb ik ook aan gedacht, maar wilde de robot iets laten leren en het leren van botsingen leek mij de logischte (lees makkelijkste) optie. Dat hij die ene stoel blijft ontwijken nadat die er niet meer staat neem ik dan maar voor lief (hij rijdt toch op een grote werkvloer dus ruimte zat).
Bedenk me nu terwijl ik dit typ dat ik het programma ook een voorwaarde kan laten stellen aan de blokkade: als dit al vaker is voorgekomen, dan ... voeg toe aan blacklist. ofzoiets :) Zal het morgen eens gana bekijken op school.

Wat betreft de IR sensor/IR led die je noemde... Hoe werkt dat precies???
A. Allebei op de robot en gebruiken als "afstandsensor"; dus bij weerkaatsing is er iets in de buurt.
Of B. Als "baken" om zich opnieuw te eiken in z'n virtuele grid?

In geval van A, hoe zou je het dan oplossen als er een voorwerp (bv. stoelpoot/kast) net naast/boven de sensor zit? Of denk je dat dit wel mee zal vallen?
In geval van B, hoe werkt dit dan? Sensor op robot en led op 'n bepaalde plek in de ruimte ofzo?
Weet je misschien ook hoe duur die dingen zijn toevallig? Blijf een "arme student" he ;)

Iin ieder geval al bedankt voor je hulp, stel het zeer op prijs!

Op 11 maart 2007 22:32:02 schreef XQlusive:

Bedenk me nu terwijl ik dit typ dat ik het programma ook een voorwaarde kan laten stellen aan de blokkade: als dit al vaker is voorgekomen, dan ... voeg toe aan blacklist. ofzoiets :) Zal het morgen eens gana bekijken op school.

Voila :)

Zo een IR led / ontvanger monteer je dus op je robot zoals jouw optie A en is zeer goedkoop.
Ik geloof dat de detectie hoek zeer groot is en dat je met 2 zenders (leds)/ ontvangers over voldoende vooraan'zicht' beschikt. (dit hangt natuurlijk af van de groote van je speelgoed:))

Niemand verder nog suggesties hoe ik m'n problemen op zou kunnen lossen?

Voor het programmeren van de detectie routine, kan je eens kijken bij game programming web-sites. Hierin specifiek collision detections en path finding. Dit is niet precies wat je zoekt, maar zal je wel een stuk op weg moeten helpen met de theorie.

Ik zal het eens nakijken, in ieder geval bedankt voor je meedenken!

Voor path-finding: A* (uitspreken: a star). Goede link is:
http://theory.stanford.edu/~amitp/GameProgramming/

Maar houdt er rekening mee dat je VEEL geheugen nodig hebt en dat heeft een PIC uberhaupt niet. Geen optie dus. Een veel simpeler control-algoritme is nodig.

Goede keuze om stappenmotoren te gebruiken. Geeft je iig iets van een idee waar je bent. Maar je moet wielrotaties nog wel omzetten in een positie en dat is ook niet triviaal, want daar komt de nodige wiskunde (goniometrie/lineaire algebra) bij kijken en daar zijn die 8-bit controllers niet bepaald goed in ivm afrondingsfouten die ook nog eens cummalitief doorwerken.

Probeer wel de slip vd wielen minimaal te houden (langzaam optrekken / afremmen) en probeer de omwenteling vs afgelegde afstand te calibreren. Laat het ding een keer recht vooruit bewegen over een lijn en kijk wat de afwijking is. Vermenig vervolgens het aantal pulsen van de linker of rechter motor met een bepaalde factor (ergens rond de 1 beginnen uiteraard) en kijk of het beter of slechter wordt.

Trouwens: waarom heeft iedereen het over C++ als ze C bedoelen. Er is een significant verschil. C kent geen objecten (classes) en is stiekum een redelijk vies taaltje. C++ met templates is daarentegen erg krachtig en erg geschikt om erg grote applicaties mee te bouwen.

Arrays hebben ALTIJD een vaste grootte die je opgeeft bij het aanmaken. Wat jij wilt is dynamische geheugenallocatie.
Hiervoor maak je eerst een pointer aan (dus int *pLijstje). Vervolgens maak je in de initializatie van je controller pLijstje = NULL.

Als je pLijstje wilt gebruiken kun je met 'malloc' geheugen alloceren via 'malloc([aantal gewenste variabelen] * sizeof(int))'. Vervolgens kun je de data benaderen als een normale (1D) array (dus pv pLijstje[2] = 33). Houdt er wel rekening mee dat als je dat doet ZONDER dat je malloc hebt aangeroepen of een index opgeeft die buiten je bereik valt, dit gegarandeerd vervelende lastig op te sporen problemen geeft (corrupted data en vastlopers).

Daarnaast vraak ik me ten zeerste af of dat met dit soort kleine microcontroller uberhaupt mogelijk is. Om dynamisch geheugen toe te wijzen heb je nl een heap nodig en dat neemt ook weer (kostbare) ruimte in beslag.

Mijn advies: gebruik GEEN dynamische geheugen-allocatie voor microcontrollers. Dit is een gegarandeerde bron van nare lastig op te sporen bugs.

http://theory.stanford.edu/~amitp/GameProgramming/

Interessant A* gelijk aan m'n favorieten toegevoegd, als ik tijd over heb...

Die pagina is idd briljant. ;)

Dexter die link van je is inderdaad super! Veel informatie en misschien dan wel iets te hoog gegrepen voor dit moment (ivm de geheigenopslag cap van de pic), maar buitengewoon interressant.

Het is trouwens inderdaad C waarin ik programmeer, ben Java gewend dus haal hier en daar nog wel eens termen door elkaar =)

De tip van simpel beginnen en de afwijking meten en aanpassen is ook zeker handig; dit is m'n eerste robot en ik heb nog wel eens de neiging om alles in 1 kere te willen doen en vergeet dan toch wel belangrijke dingen.

En eigenwijs als ik ben ga ik toch proberen te werken met de plaatsbepaling. Ik had het eigenlijk al opgegeven, maar jouw uitleg over pointer en malloc geeft precies aan wat ik in m'n hoofd had.

Je hebt me in ieder geval weer veel leesvoer gegeven ;-) bedankt daarvoor...