Arduino İle Kendi Kendine (Otonom) Park Eden Araba Yapımı

15 7.738

Kendi Robotunu Yap projelerimizin bu bölümünde arduino otonom park eden araba projesini yapacağız. Otonom park etme işleminde belirli varsayımlara göre algoritmayı oluşturup sensörleri konumlandırmamız gerekiyor. Varsayımlarımız bu projemizde şu şekilde olacak. Senaryoda yolun sol kısmı duvar ve park alanlarından oluşacak. Videoda da göreceğiniz üzere arabanın sol tarafında 2 tane, arka ve ön kısmında da birer tane olmak üzere toplamda 4 tane sensörle etrafı algılamaktadır. Araba harekete başladığında sol taraftaki sensörler sürekli mesafe ölçerek park alanına uygun genişlik ararlar. Her iki sensör de park için uygun mesafe tespit ederse park işlemi algoritması devreye girer. Bu projede arabanın nasıl park edeceği iki farklı yöntemden oluşuyor.

Projeyi Satın Al

Sistemin Algoritması:

Arabanın sol kenarındaki iki sensörün ölçtüğü değer 15cm den küçük ise duvar olduğunu anlar ve ileri hareket eder.Bunu hafızasına kaydeder. Daha sonra park aramaya başlar.İleri giderken Kenardaki iki sensör sürekli ölçüm yapar ve bu ölçümler sonucu ikisinin de değeri aynı anda 15cm den büyük ise, nasıl park edeceğine karar vermesi gerekiyor.

Park Yöntemi Seçimi Algoritması
  • 1. durum : Eğer ölçülen değer arabanın eninden büyük ve arabanın uzunluğundan küçük ise paralel park sistemini çalıştıracak.
  • 2. durum : Eğer ölçülen değer arabanın uzunluğundan büyük ise robot dik şekilde park edecektir.
Paralel Park Etme Algoritması:

Bu durumda araba park alanını geçerek, kenardaki iki sensör tekrar duvar gördüğünde araba durur. Biraz geri gelir. ve sağa 45 derece döner. Geriye hareket ederken arka sensör ölçüm yaparak park alanına girer ve sola doğru dönemeye başlar. Sola hareketi sırasında kenarlardaki sensörler sürekli ölçüm yapar ve iki sensörün ölçtüğü değer birbirine eşit oluncaya kadar sola dönmeye devam eder. Eşit olduğunda durur. Ön sensör ölçüm yapar ve 10 cm den küçük olana kadar ileri gider. ve 10 cm den küçük ise durur. ve park etme işlemi sona erer.

Dik Park Etme Algoritması

Kenarlardaki sensörler aynı anda arabanın uzunluğundan fazla değer ölçmüş ise araba durur. ve sola 90 derece  dönüş yapar. Park alanına doğru hareket etmeye başlar. Bu esnada ön sensör sürekli ölçüm yapar ve ölçülen değer 10cm den küçük ise araba durur. park işlemi tamamlanmış olur.

Malzemeler:
  • Arduino Mega
  • Adafruit Motor Shield
  • 4 Dc Motorlu Robot Kit
  • 4 Adet HC-SR04 Ultrasonik Sensör
  • LM 393 Kızılötesi Hız Sensörü
  • Lipo Pil ( 7.4V 850 mah yeterlidir)
  • Jumper Kablolar

Mekanik Kısım:

Sistemde bulunan kızılötesi sensör motorun devrini ölçmektedir. Bu sayede park ederken tekerleklerin tur sayısını ölçerek hatasız park etmesini sağlamaktır. Robot kitinizde enkoder disk yoksa ek olarak alıp takabilirsiniz. Burada dikkat edilmesi gereken nokta enkoder disk üzerindeki delik sayısıdır. Bu projedeki enkoder diskin delik sayısı 20 dir. Sizdeki farklı sayıda ise arabanın dönüşlerini tekrar ayarlamanız gerekiyor.

LM393 Hız sensörünü yukarıdaki şekildeki gibi yerleştiriniz. Enkoder disk deliklerinin hızasında olmasına dikkat ediniz. 

Sol kenardaki sensörleri yukarıdaki gibi konumlandırın. Sensörlerin köşelerde olması arabanın uzunluğuna göre park alanı bulmasını sağlamaktadır. Diğer iki sensörün birini öne diğerini de arkaya yerleştiriniz. 

Devre Şeması:

Ultrasonik Sensörlerin Pin Bağlantıları

Ön Sensör => Trig Pin : D34 , Echo Pin : D35

Sol Ön Sensör => Trig Pin : D36 , Echo Pin : D37

Sol Arka Sensör => Trig Pin : D38 , Echo Pin : D39

Arka Sensör => Trig Pin : D40 , Echo Pin : D41

Motor Shield Dc Motor Pin Bağlantıları

Sol Ön Motor => M4

Sağ Ön Motor => M3

Sol Arka Motor => M1

Sağ Arka Motor => M2

LM393 Hız Sensörü Pin Bağlantıları

VCC => 5V : OUT => D21 : GND => GND

 

Yazılım Kısmı:

Ultrasonik Sensör Kütüphanesi : Ultrasonic.zip

Arduino Yazılımı:

// Otonom Park Eden Araba
// Developed by Sezgin GÜL

//motorların tanımları
#include <AFMotor.h>
AF_DCMotor Sol_On_Motor(4);
AF_DCMotor Sag_On_Motor(3);
AF_DCMotor Sol_Arka_Motor(1);
AF_DCMotor Sag_Arka_Motor(2);
#include <Ultrasonic.h>

Ultrasonic ultrasonic_arka(40,41),ultrasonic_sol_arka(38,39),ultrasonic_sol_on(36,37),ultrasonic_on(34,35);
// ultrasomik sensörlerin tanımlamamalrı

#define Sol 0 //sol yön komutu
#define Sag 1 //sağ yön komutu
#define Ileri 2 //ileri yön komutu
#define Geri 3 //geri yön komutu
#define minimum_limit 15 //Arabanın genişliği (cm)
#define minimum_limit1 28 //arabanın uzunluğu (cm)

byte park_durumu = 0;
int sinyalpin = 21;
volatile int val;

int sayac = 0;
int guncel_durum = 0;
int onceki_durum = 0;

void say(int saydir)
{
for (int i = 0 ; i <= saydir; i+1)
{
val = digitalRead(sinyalpin);
if (val == LOW) {

guncel_durum = 0;
}
else {

guncel_durum = 1;
}

if(guncel_durum != onceki_durum)
{
if(guncel_durum == 1)
{
sayac = sayac + 1;
Serial.println(sayac);
i = i+1;
}
else
{
i = i ;
}

onceki_durum = guncel_durum;

}
if (i == saydir)
{

Sol_On_Motor.run(RELEASE);
Sag_On_Motor.run(RELEASE);
Sol_Arka_Motor.run(RELEASE);
Sag_Arka_Motor.run(RELEASE);

}

}

}

void motor_pinSetup()
{

Sol_On_Motor.run(RELEASE);
Sag_On_Motor.run(RELEASE);
Sol_Arka_Motor.run(RELEASE);
Sag_Arka_Motor.run(RELEASE);
}

// Hareket fonksiyonları
void Robot_Hareket(byte motor, byte spd)
{
if (motor == Ileri)
{
Sol_On_Motor.setSpeed(spd);
Sag_On_Motor.setSpeed(spd);
Sol_Arka_Motor.setSpeed(spd);
Sag_Arka_Motor.setSpeed(spd);
Sol_On_Motor.run(FORWARD);
Sag_On_Motor.run(FORWARD);
Sol_Arka_Motor.run(FORWARD);
Sag_Arka_Motor.run(FORWARD);

}
if (motor == Geri)
{
Sol_On_Motor.setSpeed(spd);
Sag_On_Motor.setSpeed(spd);
Sol_Arka_Motor.setSpeed(spd);
Sag_Arka_Motor.setSpeed(spd);
Sol_On_Motor.run(BACKWARD);
Sag_On_Motor.run(BACKWARD);
Sol_Arka_Motor.run(BACKWARD);
Sag_Arka_Motor.run(BACKWARD);

}
if (motor == Sol)
{
Sol_On_Motor.setSpeed(spd);
Sag_On_Motor.setSpeed(spd);
Sol_Arka_Motor.setSpeed(spd);
Sag_Arka_Motor.setSpeed(spd);
Sol_On_Motor.run(BACKWARD);
Sag_On_Motor.run(FORWARD);
Sol_Arka_Motor.run(BACKWARD);
Sag_Arka_Motor.run(FORWARD);

}

if (motor == Sag)
{
Sol_On_Motor.setSpeed(spd);
Sag_On_Motor.setSpeed(spd);
Sol_Arka_Motor.setSpeed(spd);
Sag_Arka_Motor.setSpeed(spd);
Sol_On_Motor.run(FORWARD);
Sag_On_Motor.run(BACKWARD);
Sol_Arka_Motor.run(FORWARD);
Sag_Arka_Motor.run(BACKWARD);

}

}

void Robot_Dur()
{
Sol_On_Motor.run(RELEASE);
Sag_On_Motor.run(RELEASE);
Sol_Arka_Motor.run(RELEASE);
Sag_Arka_Motor.run(RELEASE);
}

// Park yeri araması
bool Park_Yeri_Kontrol()
{

long on_Sensor = ultrasonic_on.Ranging(CM);
long sag_Sensor = ultrasonic_sol_on.Ranging(CM);
long sag_arka_Sensor =ultrasonic_sol_arka.Ranging(CM);

if( (sag_Sensor <= minimum_limit)&&(sag_arka_Sensor <= minimum_limit)&&(park_durumu == 0))
{
Robot_Hareket(Ileri, 100);
park_durumu = 1; Serial.println(park_durumu);
}

if((sag_Sensor > minimum_limit)&&(sag_Sensor < minimum_limit1)&&(sag_arka_Sensor > minimum_limit)&&(sag_arka_Sensor < minimum_limit1)&&(park_durumu == 1))
{
Robot_Hareket(Ileri, 100);
park_durumu = 2;Serial.println(park_durumu);
}

if((sag_Sensor >= minimum_limit1)&&(sag_arka_Sensor >= minimum_limit1)&&(park_durumu == 1))
{
/* Dik Park Etme Kararı */
Robot_Dur() ;
delay(500);
park_durumu = 10;Serial.println(park_durumu);
}

if((sag_Sensor <= minimum_limit)&&(sag_arka_Sensor <= minimum_limit)&&(park_durumu == 2))
{
/* Paralel Park Etme Kararı */
park_durumu = 3; Serial.println(park_durumu);
}

return park_durumu;
}

void Park_bul()
{
Park_Yeri_Kontrol();
if(park_durumu == 3 )
{
Robot_Dur();Serial.println(park_durumu);
delay(400);
park_durumu = 4;
}
if(park_durumu == 4 )
{

Robot_Hareket(Geri,120);
say(18);
Robot_Dur();Serial.println(park_durumu);
delay(500);
Robot_Hareket(Sag,150);
say(9);
Robot_Dur();
delay(500);
park_durumu = 5;
}
if(park_durumu == 5)
{

Robot_Hareket(Geri,120);
long arka_Sensor = ultrasonic_arka.Ranging(CM);Serial.println(arka_Sensor);

if(arka_Sensor>0 && arka_Sensor <= 13)
{
Robot_Dur();
delay(400);
park_durumu = 6;
}
return arka_Sensor;
}

if(park_durumu == 6)
{
Robot_Hareket(Sol,150);
long sag_Sensor = ultrasonic_sol_on.Ranging(CM); Serial.println(sag_Sensor);
long sag_arka_Sensor = ultrasonic_sol_arka.Ranging(CM); Serial.println(sag_arka_Sensor);

if(sag_Sensor == sag_arka_Sensor)
{
Robot_Dur();
park_durumu = 7;
}

return sag_Sensor,sag_arka_Sensor;
}
if(park_durumu == 7)
{
long on_Sensor = ultrasonic_on.Ranging(CM);

if(on_Sensor<=6)
{
Robot_Dur();
park_durumu = 8;
}
else
{
Robot_Hareket(Ileri,100);
}
return on_Sensor;
}
if (park_durumu ==10)
{

Robot_Hareket(Sol,180);
say(14);
Robot_Dur();
delay(500);
park_durumu = 7;

}

}

void setup()
{
Serial.begin(9600);
attachInterrupt(5, say, CHANGE);
pinMode (sinyalpin, INPUT) ;

motor_pinSetup();
}

void loop()
{
Park_bul();
}

Projenin Bütün Yazılımını Buradan İndirebilirsiniz.>> Otonom Park Eden Araba

Kendi Robotunu Yap projelerimizin bu bölümünde otonom park eden araba yapımından bahsettik. Bir sonraki projede görüşmek üzere..

Bunları da beğenebilirsin

Cevap bırakın

E-posta hesabınız yayımlanmayacak.

  1. yusu

    4 ultrasonic hepsinden deger alamıyoruz nasıl sorunu cözecegiz en fazla 2 tane ultrasonicten deger alabiliyoruz.

  2. sinan

    herşeyi yaptık tek sorun 4 ultrasonic aynı anda algılamyor en fazla 2 tane algılıyor

  3. my

    öncelikle tebrik ederim elinize sağlık. Adafruit Motor Shield yerine l293d shild kullanabilirmiyiz ?

  4. yusuf

    2 dc motorlu robot kit için en değerleri nsıl olur?

  5. yusuf

    2 DC motorlu kit,boy kodları nasıl olur?

  6. mustafa özdemir

    Öncelikle böyle bir projeyi paylaştığınız için teşekkürler. fakat kodu yüklemeye çalışınca hata veriyor.

  7. kubilay

    acaba arduino uno kullanabilirmyiz bu projede yoksa mega kullanmak şart mı?

  8. yusuf

    böylesi bir projeyi paylaştığınız için öncelikle teşekkür ederim
    bu kodu alıp derlediğimde hatalar çıkıyor kütüphanelerden başka birşey eklemelimiyim

  9. sinan

    4 dc motorlu robot kit yerine 2 dc motorlu robot kit kullansak işe yarar mı?

    1. Sezgin GÜL

      Kullanabilirsin Sinan. Sol ve sağ taraftaki motorlar ikili olarak aynı hareketi yapıyor. Kodda değişiklik yapmak istemiyorsan bir motor sol diğerini de sağ girişlerden birine takabilirsin. Diğer önemli nokta ise robotun boy ve en değerleridir. Arabanın boyutları farklı ise kodda belirtilen değişkenlere yeni değerleri yazmalısın.

  10. Evren

    Çok güzel , lm393 ve kızılötesi vericilerden 4 tane mi kullandınIz? O kısmın mantığını biraz açıklarsanız çok sevinirim…amaç 4 tekerleğinde aynı hızda gitmesini sağlamak mı? Pwm yerine bu şekilde mi hız ayarlaması yapıyoruz2?

    1. Sezgin GÜL

      sadece bir motora bağlamanız yeterli. Amaç ne kadar hızda gitmesi değil ne kadar mesafe gideceğini belirlemek Örneğin dikey parkta 90 derece dönmesi için tekerleklerin ne kadar tur atması gerektiğini kodda belirtmek. Enkoder delik sayısına göre her delik arası mesafeyi bir adım olarak adlandırabiliriz. Tıpkı step motorlardaki gibi . Kodda da ne kadar adım atacağını belirterek o kadar hareket etmesini sağladım.

  11. ÖZgür

    Tebrik ederim güzel bir çalışma olmuş. elinize sağlık. Paylaşım için de ayrıca teşekkür ederim.

    1. Sezgin GÜL

      teşekkürler. rica ederim.

      1. Cem

        Sezgin yaptım fakat yatay park etmiyor.