Robot Following using Camera (Marian Vysluzil)
Contents
[hide]Zadanie
Úlohou bolo zostrojiť robota platformy Acrob, ktorý bude sledovať čiaru pomocou kamery mobilného telefónu z ktorého budú dáta odosielané pomocou technológie bluetooth.
Hardware
Ako základ bol použitý robot Acrob založený na platforme Arduino.
Bluetooth prijímač/vysielač bol použitý JY-MCU v1.02 ktorý , ale pracuje na napätí 3.3V na rozdiel od Acroba ktorý pracuje na 5V. Preto bolo treba upraviť komunikačný signál smerom od robota k bluetooth modulu. Úprava bola spravená odporovým deličom ktorý zmenšil výstupné napätie z robota na 3V ktoré modulu postačovalo. Vstupné napätie z modulu do robota upravované nebolo.
Software
Komunikácia:
Aplikácia pre mobilný telefón bola napísaná v Jave pre operačný systém Android. Pre komunikáciu bola pridaná upravená knižnica Amarino, ktorá slúži pre komunikáciu s Arduinom na robotovi Arcob (knižnicu Amarino si treba nainštalovať aj do mobilného telefónu) a oproti štandardnej verzií obsahuje nový konštruktor, ktorý namiesto HardwareSerial komunikácie použije SoftwareSerial aby bolo možné naraz používať SerialMonitor Arduina a bluetooth modul.
MeetAndroid::MeetAndroid(int rxPin, int txPin, long int baud)
{
customErrorFunc = false;
SoftwareSerial *softSerial = new SoftwareSerial(rxPin, txPin);
softSerial->begin(baud);
stream = softSerial;
init();
}
Riadenie robota:
Na riadenie bol použitý jednoduchý PID kontroler ktorý upravuje rýchlosť motorov. Robot sa snaží držať v strede čiary ktorú nájde pomocou funkcie findTape(), ktorá nájde najvzdialenejšiu čiaru väčšiu ako 10 pixlov v prvej polovici „videnia robota“, čo je vlastne obrázok z kamery, ak takú čiaru nenájde robot pokračuje v ceste rovno.
public int findTape(int[] rgb, int width, int height) {
int tapeStart = -1;
int tapeEnd = -1;
int tmpStart = -1;
int tmpEnd = -1;
int scanline = -1;
for (int x = height/2; x < height; x += 5) {
for (int pix = 0; pix < height; pix++) {
int pixVal = (0xff & (int) rgb[x + pix * width]);
if (pixVal == 0) {
if (tmpStart == -1) {
tmpStart = pix;
} else {
tmpEnd = pix;
if (tmpEnd - tmpStart > minPixels
&& (Math.abs((tmpEnd - tmpStart) / 2 - height
/ 2) < Math.abs((tapeEnd - tapeStart)
/ 2 - height / 2))) {
tapeEnd = tmpEnd;
tapeStart = tmpStart;
scanline = x;
}
}
} else {
tmpStart = -1;
tmpEnd = -1;
}
}
if(tapeStart>-1){
break;
}
}
if (tapeStart > -1 && tapeEnd > -1 && scanline > -1) {
for (int pix = tapeStart; pix <= tapeEnd; pix++) {
rgb[scanline + pix * width] = 0xff000000 | (0 << 16)
| (255 << 8) | 0;
}
} else {
return -1;
}
return (tapeEnd + tapeStart) / 2;
}
Rozlíšenie kamery bolo nastavene na 176x144 pixlov. Keď robot vypočíta výchylku odošle dáta na Arduino (pre každý motor zvlášť), kde sa príjmu a ak sú v rozsahu od 0-30 daný motor ostane stáť , v opačnom prípade sa rozbehnú. Ak robot nedostane dáta do 500ms zastaví. Robot po každej úprave rýchlostí motorov odošle na Android číslo ako kontrolu spojenia.
void set_motor_speed(byte flag, byte numOfValues)
{
int data[numOfValues];
meetAndroid.getIntValues(data);
meetAndroid.send(1);
motor1speed = data[1];
motor2speed = data[0];
lastcmd = millis();
}
Záver
Robot fungoval dobre a dráhu zvládol. Občasný problém v kontrole robota bol odraz svetla na leskom povrchu dráhy ktorú mal robot absolvovať. Riešenie by bolo napríklad aby mobil svietil na dráhu osvetlením pre fotoaparát , čo by znamenalo opätovné nastavenie premennej treshold ktorá určuje ktorá farba je čierna.
Video