Pada postingan sebelumnya, kita telah membahas robot
pengikut garis menggunakan sensor cahaya phototransistor. Maka pada pembahasan
kali ini, kita akan membuat robot pengikut garis dengan metode image processing
menggunakan webcam sebagai sensor garisnya. Prinsip robot pengikut garis
menggunakan kamera ini sebenarnya sama dengan robot pengikut garis
konvensional. Kamera akan mendeteksi perubahan garis hitam ketika garis hitam
tersebut berbelok ke arah kiri atau kanan, perubahan posisi hitam yang
terdeteksi itulah yang kemudian akan diproses oleh MATLAB komputer PC/laptop yang
akan mengirimkan karakter tertentu pada robot, dan oleh mikrokontroler karakter
tersebut akan diterjemahkan dalam bentuk kondisi gerak motor berupa maju ke
depan, belok kiri, belok kanan ataupun diam yang akan membuat posisi robot
senantiasa berada di tengah-tengah garis hitam.
Gambar 1. Ilustrasi robot vision line tracking dengan webcam
Berikut adalah metode yang digunakan dalam
pembuatan robot line follower berbasis webcam, metode ini terinspirasi oleh
Perpendu Kumar tahun 2012. Tahapan pertama adalah membuat program MATLAB untuk
mendeteksi perubahan posisi garis berwarna hitam, dari program ini kemudian
kita dapat mengkarakterisasi nilai ketika garis di tengah, belok kanan, atau
belok kiri.
Gambar 2. Tahapan metode pembuatan robot pengikut garis
Dari data perubahan posisi garis hitam, tahapan
selanjutnya adalah kita membuat program kontrol robot berupa karakter tertentu,
ketika garis hitam di tengah-tengah robot maka akan dikirimkan karakter agar
robot berjalan lurus kedepan, ketika garis hitam terdeteksi belok ke arah kiri,
maka akan di kirimkan karakter agar robot belok ke arah kiri, begitupula ketika
garis hitam terdeteksi belok ke arah kanan, maka akan dikirimkan karakter agar
robot belok ke arah kanan. Tahapan selanjutnya adalah pembuatan hardware robot
menggunakan mikrokontroler AT mega(8/16/32/8535) yang nantinya akan dihubungkan
secara serial dengan PORT USB laptop untuk menterjemahkan karakter yang
dikirimkan oleh MATLAB komputer PC/laptop. Berikut adalah tahapan proses
pembuatan robot line follower berbasis webcam menggunakan metode image
processing MATLAB.
Program Kalibrasi
Deteksi Garis Hitam
vid=videoinput('winvideo',1,'YUY2_320x240');
set(vid,'TriggerRepeat',Inf);
vid.returnedcolorspace='rgb';
vid.FrameGrabInterval=2;
start(vid)
while(1)
data
= getsnapshot(vid);
a=im2bw(data);
b=imresize(a,0.2);
c=1-b;
se=strel('disk',2);
d=imerode(c,se);
[stat
num]=bwlabel(d);
r=regionprops(stat);
e=r.Centroid;
cy=e(1:2:end-1)
imshow(data)
end
stop(vid)
Output Program
Kalibrasi
(a) Posisi garis hitam di tengah
(e) Posisi garis hitam belok kiri curam
Gambar 3. Kalibrasi garis hitam robot line tracer image
processing
Dari hasil output program yang di tampilkan pada
gambar 3. Diperoleh data deteksi perubahan posisi garis hitam sebagai berikut:
Tabel 1. Output hasil kalibrasi posisi garis hitam
No
|
Posisi Garis Hitam
|
Nilai Karakteristik Cy
|
1
|
Di Tengah
|
32.74
|
2
|
Belok Kanan
Sedang
|
40.93
|
3
|
Belok Kanan
Curam
|
50.93
|
4
|
Belok Kiri
Sedang
|
23.12
|
5
|
Belok Kiri Curam
|
13.21
|
Program Logika
Arah Belok Robot Line Tracer
Dari data Tabel 1, kita dapat membuat sebuah
logika arah gerak robot pengikut garis agar senantiasa posisi robot berada di
tengah-tengah garis hitam.
Tabel 2. Logika arah gerak robot pengikut garis
No
|
Posisi Garis Hitam
|
Nilai Karakteristik Cy
|
1
|
Belok Kanan
Sedang
|
38 < Cy <
48
|
2
|
Belok Kanan
Curam
|
Cy > 48
|
3
|
Belok Kiri
Sedang
|
17 < Cy <
27
|
4
|
Belok Kiri Curam
|
Cy < 17
|
5
|
Maju ke Depan
|
27 < Cy <
38
|
Berikut adalah program lengkap untuk logika arah
gerak robot line follower berbasis webcam.
%
setting input video
vid=videoinput('winvideo',1,'YUY2_320x240');
set(vid,'TriggerRepeat',Inf);
vid.returnedcolorspace='rgb';
vid.FrameGrabInterval=2;
%memulai
video
start(vid)
while(1)
data =
getsnapshot(vid);
a=im2bw(data);
b=imresize(a,0.2);
c=1-b;
se=strel('disk',2);
d=imerode(c,se);
[stat
num]=bwlabel(d);
r=regionprops(stat);
e=r.Centroid;
cy=e(1:2:end-1)
if cy>48
disp('BELOK KANAN CURAM');
elseif cy>38
&& cy<48
disp('BELOK KANAN SEDANG');
elseif cy<17
disp('BELOK KIRI CURAM');
elseif cy>17
&& cy<27
disp('BELOK KIRI SEDANG');
else
disp('MAJU LURUS KE DEPAN');
end
%
menampilkan citra
imshow(data)
end
%menutup video
stop(vid),delete(vid),clear
vid;
Output
Program Logika Arah Belok Robot Line Tracer
Gambar 4. Output program logika belok robot line tracer
Program Matlab
Robot Line Tracer Berbasis Webcam
%
setting input video
vid=videoinput('winvideo',1,'YUY2_320x240');
set(vid,'TriggerRepeat',Inf);
vid.returnedcolorspace='rgb';
vid.FrameGrabInterval=2;
%memulai
video
start(vid)
%komunikasi
serial mikrokontroler dan komputer PC/laptop
s=serial('com21'); %
com disesuaikan dengan yang tertera pd device manager
fopen(s);
while(1)
data =
getsnapshot(vid);
a=im2bw(data);
b=imresize(a,0.2);
c=1-b;
se=strel('disk',2);
d=imerode(c,se);
[stat
num]=bwlabel(d);
r=regionprops(stat);
e=r.Centroid;
cy=e(1:2:end-1);
if cy>48
fwrite(s,'x');
disp('BELOK KANAN CURAM');
elseif cy>38
&& cy<48
fwrite(s,'X');
disp('BELOK KANAN SEDANG');
elseif cy<17
fwrite(s,'y');
disp('BELOK KIRI CURAM');
elseif cy>17
&& cy<27
fwrite(s,'Y');
disp('BELOK KIRI SEDANG');
else
fwrite(s,'Z')
disp('MAJU LURUS KE DEPAN');
end
%
menampilkan citra
imshow(data)
end
%menutup
komunikasi serial dan menghentikan video
fclose(s);
stop(vid);
DESAIN PROTEUS
ROBOT PENGIKUT GARIS
Gambar 5. Simulasi proteus robot kontrol PC
Untuk membuat sebuah robot yang dapat dikendalikan computer, maka
perlu dibuat komunikasi serial antara robot (mikrokontroler) dengan sistem
computer melalui IC MAX 232 dan PORT DB9. Dalam simulasi proteus, PORT DB9 dibuat
virtualnya dengan nama COMPIM, sedangkan untuk menampilkan monitor computer
digunakan VTERM. Pada Realitanya,
penulis tidak menggunakan IC MAX 232 dan DB9 karena laptop keluaran terbaru
sudah tidak dilengkapi lagi dengan PORT DB9 tetapi menggunakan komunikasi USB,
karena itu dalam penelitian ini, penulis menggunakan DI-USB
to TTL converter kit.
Program Code Vision AVR pada Mikrokontroler AVR Robot
Tabel berikut ini menunjukkan logika pada
mikrokontroler untuk menterjemahkan perintah karakter yang dikirimkan oleh
MATLAB komputer PC/laptop.
Tabel 3. Logika gerak pada mikrokontroler untuk
menterjemahkan
karakter dari MATLAB
Karakter
|
D2
|
D3
|
D6
|
D7
|
Makna
|
x
|
0
|
1
|
1
|
0
|
Belok kanan cepat/curam
|
X
|
0
|
1
|
0
|
0
|
Belok kanan sedang
|
y
|
1
|
0
|
0
|
1
|
Belok kiri cepat/curam
|
Y
|
0
|
0
|
0
|
1
|
Belok kiri sedang
|
Z
|
0
|
1
|
0
|
1
|
Maju ke depan
|
M
|
1
|
0
|
1
|
0
|
Mundur ke belakang
|
o
|
0
|
0
|
0
|
0
|
Diam
|
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP
InfoTech s.r.l.
http://www.hpinfotech.com
Project : Robot dengan Kontrol PC untuk Line Follower berbasis WebCam
Version : I
Date
: 11/12/2012
Author
: Mada Sanjaya WS, Ph.D
Company : Bolabot Techno Robotic School
Comments: "SEMANGAT!!!!"
Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#include <delay.h>
#ifndef RXB8
#define RXB8 1
#endif
#ifndef TXB8
#define TXB8 0
#endif
#ifndef UPE
#define UPE 2
#endif
#ifndef DOR
#define DOR 3
#endif
#ifndef FE
#define FE 4
#endif
#ifndef UDRE
#define UDRE 5
#endif
#ifndef RXC
#define RXC 7
#endif
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];
#if RX_BUFFER_SIZE <= 256
unsigned char
rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int
rx_wr_index,rx_rd_index,rx_counter;
#endif
// This flag is set on USART Receiver
buffer overflow
bit rx_buffer_overflow;
// USART Receiver interrupt service routine
interrupt [USART_RXC] void
usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR |
PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index++]=data;
#if RX_BUFFER_SIZE == 256
//
special case for receiver buffer size=256
if
(++rx_counter == 0)
{
#else
if
(rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if
(++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
#endif
rx_buffer_overflow=1;
}
}
}
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver
buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index++];
#if RX_BUFFER_SIZE != 256
if (rx_rd_index == RX_BUFFER_SIZE)
rx_rd_index=0;
#endif
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif
// USART Transmitter buffer
#define TX_BUFFER_SIZE 8
char tx_buffer[TX_BUFFER_SIZE];
#if TX_BUFFER_SIZE <= 256
unsigned char
tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int
tx_wr_index,tx_rd_index,tx_counter;
#endif
// USART Transmitter interrupt service
routine
interrupt [USART_TXC] void
usart_tx_isr(void)
{
if (tx_counter)
{
--tx_counter;
UDR=tx_buffer[tx_rd_index++];
#if TX_BUFFER_SIZE != 256
if
(tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
#endif
}
}
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART
Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA &
DATA_REGISTER_EMPTY)==0))
{
tx_buffer[tx_wr_index++]=c;
#if TX_BUFFER_SIZE != 256
if
(tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
#endif
++tx_counter;
}
else
UDR=c;
#asm("sei")
}
#pragma used-
#endif
// Standard Input/Output functions
#include <stdio.h>
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In
Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T
State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In
Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T
State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In
Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T
State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=Out Func4=Out
Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=0 State4=0
State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x30;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 7.813 kHz
// Mode: Fast PWM top=0x00FF
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xA1;
TCCR1B=0x0D;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s)
initialization
TIMSK=0x00;
// USART initialization
// Communication Parameters: 8 Data, 1
Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by
Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
// Global enable interrupts
#asm("sei")
printf("WELCOME TO BOLABOT");//menampilkan karakter
di PC
//definisikan output untuk motor dc
//motor kiri
DDRD.2=1;
DDRD.3=1;
//motor kanan
DDRD.6=1;
DDRD.7=1;
//kondisi awal
PORTD.2=0;
PORTD.3=0;
PORTD.6=0;
PORTD.7=0;
//PWM motor dc
OCR1A=200;
OCR1B=200;
while (1)
{
if (getchar()=='X') //belok kanan sedang
{
PORTD.2=0;
PORTD.3=1;
PORTD.6=0;
PORTD.7=0;
printf("\n BELOK KANAN SEDANG");
}
else if (getchar()=='x') //belok kanan curam
{
PORTD.2=0;
PORTD.3=1;
PORTD.6=1;
PORTD.7=0;
printf("\n BELOK KANAN CURAM");
}
else if (getchar()=='Y') //belok kiri sedang
{
PORTD.2=0;
PORTD.3=0;
PORTD.6=0;
PORTD.7=1;
printf("\n BELOK KIRI SEDANG");
}
else if (getchar()=='y') //belok kiri curam
{
PORTD.2=1;
PORTD.3=0;
PORTD.6=0;
PORTD.7=1;
printf("\n BELOK KIRI CURAM");
}
else if (getchar()=='M')
//mundur
{
PORTD.2=1;
PORTD.3=0;
PORTD.6=1;
PORTD.7=0;
printf("\n BERGERAK MUNDUR");
}
else if (getchar()=='Z') //maju
{
PORTD.2=0;
PORTD.3=1;
PORTD.6=0;
PORTD.7=1;
printf("\n BERGERAK MAJU");
}
else
{
PORTD.2=0;
PORTD.3=0;
PORTD.6=0;
PORTD.7=0;
printf("\n ROBOT DIAM");
}
}
}
Simulasi Proteus Output Program:
Gambar 6. Simulasi proteus robot kontrole komputer
Berikut adalah realisasi robot vision line tracking webcam berbasis image processing MATLAB
Gambar 7. Realisasi robot vision line tracking BOLABOT
Demikian penjelasan pembuatan robot line tracking webcam menggunakan image processing MATLAB yang telah dibuat oleh Profesor Bolabot.
Copyright @ 2013 Mada Sanjaya WS, Ph.D (Profesor Bolabot)