Arduino ile Sumo Robot Yapımı
Merhabalar,
Bu projemizde arduino ile Sumo Robot yapmayı amaçladık. Peki Sumo Robot Nedir? Sumo Robotları; uluslararası yarışmaları düzenlenen, halka şeklindeki bir ring içerisinde dışarı çıkmadan rakibini dışarıya çıkmak için zorlayan dövüşçü ve otonom robotlar olarak tanımlayabiliriz. Yarışmaların belli standartları ve kuralları mevcut tabii ki. Detaylı bilgi için linkten faydalanabilirsiniz.
Bu projeyi tercih etmemin sebebi nette gördüğüm bir videoydu. Basit hareket etseler de iki robot arasındaki mücadele oldukça doğaçlama ve eğlenceli geldi.
Metodoloji
Sumo robotlar öncelikle siyah zemin üzerine beyaz çizgi ile sınırı belirlenmiş DOHYO adı verilen yaklaşık 1.5m'lik daire şeklinde bir ring üzerinde mücadele ediyor. İlk amacımız robotumuzun zemindeki çizgiyi algılaması ve dışarı çıkmamak üzerine hareket etmesi olacaktır. Bunun için aslında basitçe çizgi izleyen robotumuzdaki mantığı kullanacağız. Kendi ringimizi evde kolay oluşturulması için siyah zemin üzerine beyaz çizgi değil, normal zemin üzerine siyah çizgi olarak belirleyebiliriz. Ne demiştik her zaman basitten zora doğru gitmekte fayda var.
Çizgiyi algılama işlemini bu projede çizgi izleyen robottan farklı olarak TCRT5000 sensörlerini kullanarak yaptım. Yine aynı şekilde ne kadar çok sensör o kadar hassas kontrol demek ancak o kadar hesaplama karmaşıklığı ve işlemci gücü de demek aynı zamanda. Basit olması açısından ön tarafta 1 adet ve arkada 1 adet olmak üzere min 2 sensör ile bu işlemi gerçekleştirebiliriz. İlk denemede önde 2 arkada 1 adet kullanmıştım ancak rakibi de yapmaya karar verince her ikisine de 2şer tane olacak şekilde planlama yapmam gerekti (elimdeki sensör miktarı nedeni ile). Aslında hayat da böyle. Kaynaklar sonsuz değil o yüzden bazen idealin dışında kısıtlı kaynak ile projeleri gerçekleştirmeye çalışmak da ayrı bir tecrübe ve keyif bence hem de ileride geliştirilmeye açık oluyorlar.
Sahada kalma işini hallettikten sonra yapmamız gereken şey rakibi algılamak ve sonrasında saldırı taktiğini uygulamak. Yarışmalara katılan robotlarda çok değişik stratejiler mevcut ve sadece hayal gücünüzle sınırlı. Yine basitten başlamak gerekirse ilk yaptığımız robot ön kısımda ve sağda olacak şekilde 2 adet HCSR-04 Ultrasound sensör kullanıyordu (elimdeki sensör miktarı nedeni ile :) ). Ancak daha verimli olması açısından Sağda, Solda ve Önde olacak şekilde min 3 adet rakip algılama sensörü kullanmakta fayda var.
Gelelim hangi sensörlerin kullanılabileceğine. Aslında genel olarak bu iş için daha hızlı tepkime sürelerine sahip olan, nispeten daha uzaktan ve daha hızlı cisim algılayan dijital kızılötesi veya lazer sensörler kullanılıyor. Kaliteli sensörlerin de fiyatı oldukça yüksek tabii ki. Minimum maliyet için HCSR-04 ultrasound kullanılabilir. Tepkime süresi uzun olacak ve kod daha yavaş çalışacaktır. Bence maliyet etkinlik açısından hem dijital IR sensör olup hem de başarılı olan ürün MZ-80 olarak bilinen endüstriyel tip 80cme kadar algılama yapabilen mesafe sensörleridir. Dijital oldukları için çok hızlı çıkış veriyorlar ve arkalarındaki pot sayesinde mesafe ayarı kolayca yapılabiliyor.
Robotumuz Sağ-Sol ve Önden yaptığı arama sonucunda belirlenen mesafe içerisinde bir cisim (rakip) algılarsa ona doğru yönlenecek. Cisim sağda ise 90 derece sağa, solda ise sola dönecek ve orta sensörün görüş alanına girdiğinde rakibe doğru atak yapacak. Herhangi bir nesne görmediğinde ise yine sizin tercihinize göre olduğu yerde düzenli olarak dönerek aramaya devam edebilir veya saha içinde çizgi görene kadar gidip oradan da sola veya sağa dönerek devam edebilir. Ben 2.seçeneği tercih ettim. Şimdi yapım aşamalarına geçelim.
Gerekli Malzemeler
3 adet cisim algılama sensörü (HCSR-04 veya MZ-80 veya daha pahalı SHARP vb sensörler)
2 adet çizgi algılama sensörü (TCRT5000 hem ucuz hem de işlevsel)
4 adet redüksiyonlu DC motor
1 adet motor sürücü kartı L298
1 adet Arduino Uno/Nano/Mega
Kablo vs.
Lipo pil (9v pil de olur ama çok çabuk biter)
1 adet switch
Robot araba şasesi (Her zamanki gibi görsel olarak çok şık olmasa da şaseyi kendim yapıyorum)
Robotun Yapılışı
Sumo robot şasesi için yine buradan çizgi izleyen çalışmamızdaki benzer uygulamayı yapabilirsiniz. Ancak dikkat edilmesi gereken nokta rakip robota temas etme durumlarında sizi zor duruma düşürmemesi için rakibe minimum yüzey göstermeniz ve zarar görebilecek tüm elektronikleri ve aksamı çarpışmalardan koruyacak şekilde konumlandırmanız olacaktır. Ayrıca her sumo robotun önünde bıçak olarak adlandırılan ve rakibi ittirmede ve yerden kaldırmada kullanılan eğimli metal levhalar mevcut. İnternetten hazır olarak satın alabilir veya kendiniz elinizdeki bir malzemeden de yapabilirsiniz.
Yine değinmekte fayda duyduğum konulardan biri de Sumo robotlardaki motor ve tekerlek seçimi. Genel olarak amaç pist dışına çıkmamak ve aynızamanda rakibi ittirerek çıkarmak olduğu için maksimum sürtünme ve tutunma sağlayacak özel tekerlekler ve oldukça güçlü motorlar kullanılıyor. Eğer ciddi bir güreşçi yapmak istiyorsanız bu tarz ürünler ve daha sağlam metal-karbon gövdeler tercih etmeniz ve aynı zamanda yarışma kuralları içerisindeki ağırlık limitlerine uymanız gerekir. Bizimkiler kategori dışı.
İlk yaptığım prototipte genişliği 16cm ve derinliği 13cm olan bir dikdörtgen dakota levha kullandım. Ön ve ark tekerleri mümkün olduğunca birbirine yakın konumlandırdım. Genel görünüş ve elektroniklerin yerleşimi şekildeki gibi. Sürekli aynı sarı plastik tekerleri kullanmak istemediğim için elimdeki atıl model uçak tekerleklerinden kullandım ancak sanırım görsel olarak pek şık olmadılar :)
Tekerleklerin mümkün olduğunca yakın olması için motorları dik konumlandırabilirsiniz böylece araç daha küçük inşa edilebilir. Ayrıca dörtçeker olması da şart gibi. İlk versiyonda başta 2 çeker yapmıştım ancak karşılaşmalarda rakibini ittiremiyor ve kayıyordu.
Devre Şeması
Aslında temel olarak her iki cihaz da aynı yapıya sahip. Sadece birinde 3 adet HCSR-04 diğerinde ise MZ-80 mevcut.
Arduino Kodu
Versiyon 2 MZ-80 Robotu için;
//SUMOBOT v2 MZ-80 Nisan 2020
//Mucit Pilot
//mucitpilot.blogspot.com
//Youtube: Mucit Pilot
//////////////////////////////////////////////////////
//değişkenleri tanımlıyorum
#define IRon 11 //çizgi sensörleri
#define IRarka 12
#define MotorR1 6 //motor çıkışları
#define MotorR2 7
#define MotorRE 5
#define MotorL1 8
#define MotorL2 9
#define MotorLE 10
#define sensorsag 2 // MZ-80 sensörler
#define sensororta 3
#define sensorsol 4
///gerekli bazı değişkenleri tanımlayalım
int distance_on;
int distance_sag;
int distance_sol;
int IR_on;
int IR_arka;
int deger;
//setup kodu bir defa çalışacak
void setup() {
//pin tanımlamalarını yapalım
// 2 adet çizgi tespit sensörü
pinMode(IRon, INPUT);
pinMode(IRarka, INPUT);
pinMode(sensorsag, INPUT); // önde, solda ve sağda olmak üzere 3 adet cisim sensörü
pinMode(sensororta, INPUT);
pinMode(sensorsol, INPUT);
pinMode(MotorR1, OUTPUT); //motor çıkış pinleri
pinMode(MotorR2, OUTPUT);
pinMode(MotorL1, OUTPUT);
pinMode(MotorL2, OUTPUT);
Serial.begin(9600);
}
//ana gövde devamlı çalışıyor
void loop() {
IR_on = digitalRead(IRon); //çizgi sensörlerinden veri okuyoruz
IR_arka = digitalRead(IRarka);
while (IR_on == 0 && IR_arka == 0) { //rakip tespit etmeyi bu while içinde yapıcam. eğer çizgi sensörlerden herhangi birinde çizgi sinyali almışsa
//zaten öncelik kendini kurtarmak olacak ve bu while içine hiç girmeyecek
Serial.println("çizgiye basmıyorum ringin içindeyim cisim aramaya başla");
distance_on=digitalRead(sensororta); //ön sensörden ölçüm alıyoruz
distance_sag=digitalRead(sensorsag); //sag sensörden ölçüm alıyoruz
distance_sol=digitalRead(sensorsol); //sol sensörden ölçüm alıyoruz
//MZ-80 sensörler cisim görünce 0 çıkışı veriyor !!!!!!!!!!
while (distance_on == 0) { //ön sensörde cisim algılamışsa
//önce çizgiye basıp basmadığını kontrol edelim. Basıyorsa hiçbirşey yapmayıp döngüden çıkacak
IR_on = digitalRead(IRon);
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
//eğer çizgiye basmıyorsa önde algılama olduğu için rakibe saldıracak
saldir();
Serial.println("hedefe git");
distance_on=digitalRead(sensororta);//while da sonsuz dönmesin diye tekrar ön sensörde algılama olup olmadığını kontrol
//ediyoruz
} //while
while ((distance_sag == 0 && distance_on ==1 )){ // sadece sağdan bilgi alıyor sağa dönecek
IR_on = digitalRead(IRon); //çizgi kontrolü
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break; //çizgi varsa çık
}
yerindesag(); //çizgi yok sağa dönecek
delay(200); //bu değeri aracınızın 90 derece dönmesini sağlayacak şekilde deneme yanılma ile bulun
Serial.println("sağa dön");
distance_on=digitalRead(sensororta); //ön sensörden ölçüm alıyoruz ki whileda kalmasın
distance_sag=digitalRead(sensorsag); //sag sensörden ölçüm alıyoruz
distance_sol=digitalRead(sensorsol); //sol sensörden ölçüm alıyoruz
}
while ((distance_sol == 0 && distance_on ==1 )){ // sadece soldan bilgi alıyor sola dönecek sağ kısmının aynısı
IR_on = digitalRead(IRon);
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
yerindesol();
delay(200);
Serial.println("sola dön");
distance_on=digitalRead(sensororta); //ön sensörden ölçüm alıyoruz
distance_sag=digitalRead(sensorsag); //sag sensörden ölçüm alıyoruz
distance_sol=digitalRead(sensorsol); //sol sensörden ölçüm alıyoruz
}
while ((distance_sag ==1)&&(distance_on == 1) && (distance_sol == 1)){ //hiçbir sensörde cisim yok ne yapalım?
IR_on = digitalRead(IRon); //çizgileri kontrol et
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break; //çizgiye basıyorsan çık
}
ileri(); // cisim görmediğinde yapılacak şey size kalmış biz düz ileri gitmesini istedik.
//yerinde dönme de yaptırılabilir.
Serial.println("cisim bulunamadı ileri git");
distance_on=digitalRead(sensororta); //ön sensörden ölçüm alıyoruz ki while da kalmasın
distance_sag=digitalRead(sensorsag); //sag sensörden ölçüm alıyoruz
distance_sol=digitalRead(sensorsol); //sol sensörden ölçüm alıyoruz
}
IR_on = digitalRead(IRon); //çizgi kontrolü yapalım ki ilk while da sonsuz dönmesin
IR_arka = digitalRead(IRarka);
}//ilk while çıkış
if (IR_on== 1){ //ön çizgi sensörü çizgi algılıyorsa geri gidecek
Serial.println(" ön çizgi tespit edildi geri gidiyorum");
geri();
delay(400); // delay değerleri yine ringinizin boyutuna ve aracınızın hızına göre deneme ile ayarlanabilir.
yerindesag();
delay(300); //// delay değerleri yine ringinizin boyutuna ve aracınızın hızına göre deneme ile ayarlanabilir.
}
else if (IR_arka == 1){
// else if (IR_arka == 1 && (IR_sol ==0 && IR_sag==0)){ //sadece arka sensör gördü o zaman ileri gitmeli
Serial.println("arka çizgi tespit edildi ileri gidiyorum");
ileri();
delay(400);//// delay değerleri yine ringinizin boyutuna ve aracınızın hızına göre deneme ile ayarlanabilir.
}
} //loop sonu
void saldir() { // Robotun saldırma hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 220); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 220); // Sol motorun hızı
}
void ileri() { // Robotun ileri yönde hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 130); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 130); // Sol motorun hızı
}
void yerindesag() { // Robotun sağa dönme hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
analogWrite(MotorRE, 180); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 180); // Sol motorun hızı
}
void yerindesol() { // Robotun sola dönme hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 180); // Sağ motorun hızı
digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
analogWrite(MotorLE, 180); // Sol motorun hızı
}
void dur() { // Robotun durma hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH);
digitalWrite(MotorR2, LOW);
digitalWrite(MotorRE, LOW);
digitalWrite(MotorL1, HIGH);
digitalWrite(MotorL2, LOW);
digitalWrite(MotorLE, LOW);
}
void geri() { // Robotun geri hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
analogWrite(MotorRE, 130); // Sağ motorun hızı
digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
analogWrite(MotorLE, 130); // Sol motorun hızı
}
//Bitti
Versiyon 1 HCSR-04 Kodu
Bu kodda Kolay ve hızlı çalıştığı için newping kütüphanesi kullandım.
Bu linkten indirebilirsiniz.
//SUMOBOT v1 HCSR-04 ile
//Nisan 2020
//Mucit Pilot
//mucitpilot.blogspot.com
//youtube: Mucit Pilot
////////////////////////////
//değişkenleri tanımlıyorum
#define IRon 2 //çizgi sensörleri
#define IRarka 4
#define MotorR1 6 //motorlar
#define MotorR2 7
#define MotorRE 5
#define MotorL1 8
#define MotorL2 9
#define MotorLE 10
#define Echoorta 11 //orta sensör için echo ve trig pinleri
#define Trigorta 12
#define Echosag A0 //sağ sensör için echo ve trig pinleri
#define Trigsag A1
#define Echosol 3 //sol sensör için echo ve trig pinleri
#define Trigsol 13
#include <NewPing.h> //newping kütüphanesi pratik kullanım için
//https://github.com/eduherminio/NewPing adresinden indirebilirsiniz
NewPing sonar_on(12,11,80); // NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); şeklinde kullanılıyor
NewPing sonar_sag(15,14,80); // 3 adet sensör nesnesi tanımlıyoruz
NewPing sonar_sol(13,3,80);
//gerekli bazı değişkenler
int distance_on;
int distance_sag;
int distance_sol;
int IR_on;
int IR_arka;
int deger;
//setup kodu bir defa çalışacak
void setup() {
pinMode(IRon, INPUT); // 2 adet çizgi tespit sensörü
pinMode(IRarka, INPUT);
pinMode(Echoorta, INPUT); // önde, solda ve sağda olmak üzere 3 adet ultrasound sensör
pinMode(Echosag, INPUT);
pinMode(Echosol, INPUT);
pinMode(Trigorta, OUTPUT);
pinMode(Trigsag, OUTPUT);
pinMode(Trigsol, OUTPUT);
pinMode(MotorR1, OUTPUT); //motor çıkış pinleri
pinMode(MotorR2, OUTPUT);
pinMode(MotorL1, OUTPUT);
pinMode(MotorL2, OUTPUT);
Serial.begin(9600);
}
//ana gövde devamlı çalışıyor
void loop() {
IR_on = digitalRead(IRon); //çizgi sensörlerini okuyoruz
IR_arka = digitalRead(IRarka);
while (IR_on == 0 && IR_arka == 0) { //rakip tespit etmeyi bu while içinde yapıcam. eğer IR sensörlerden birinde çizgi sinyali almışsa
//zaten öncelik kendini kurtarmak olacak
// ve bu while içine girmeyecek
//Serial.println("çizgiye basmıyorum ringin içindeyim cisim aramaya başla");
distance_on=sonar_on.ping_cm(); //ultrasound sensörlerden ölçüm alıyoruz
distance_sag=sonar_sag.ping_cm();
distance_sol=sonar_sol.ping_cm();
while (distance_on < 40 && distance_on !=0) { //ön sensör cisim gördükçe çalışacak
//ben mesafeyi 40cm olarak belirledim 0-39cm arası görmesini istedim.
IR_on = digitalRead(IRon); //çizgi kontrolü yapalım
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){ //çizgiye basıyorsa çıkalım
break;
}
saldir(); //çizgi yok ve önde cisim algıladı saldır :)
delay(100);//hedefe git
distance_on=sonar_on.ping_cm(); //whilede sonsuz dönmesin diye tekrar ölçelim
}
while ((distance_sag < 40 && distance_sag !=0) && (distance_on > 40 || distance_on == 0) && (distance_sol > 40 || distance_sol == 0)){
// sadece sağdan bilgi alıyor sağa dönecek
IR_on = digitalRead(IRon); // çizgi kontrolü
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
geri();
delay(200); //delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
yerindesag();
delay(400); //delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
distance_on=sonar_on.ping_cm(); // while da kalmasın diye sensörlerden ölçüm alıyoruz
distance_sag=sonar_sag.ping_cm();
distance_sol=sonar_sol.ping_cm();
}
while ((distance_sol < 40 && distance_sol !=0)&&(distance_on > 40 || distance_on == 0) && (distance_sag > 40 || distance_sag == 0)){
// sadece soldan bilgi alıyor sola dönecek. Sağ kısmı ile aynı mantık
IR_on = digitalRead(IRon);
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
geri();
delay(200);
yerindesol();
delay(400);
//Serial.println("sola dön");
distance_on=sonar_on.ping_cm(); //whiledan çıkış için
distance_sag=sonar_sag.ping_cm();
distance_sol=sonar_sol.ping_cm();
}
while ((distance_sag > 40 || distance_sag ==0)&&(distance_on > 40 || distance_on == 0) && (distance_sol > 40 || distance_sol == 0)){
//hiçbir sensör görmedi düz git
IR_on = digitalRead(IRon);
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
ileri();
delay(100);
distance_on=sonar_on.ping_cm(); //whiledan çıkış için
distance_sag=sonar_sag.ping_cm();
distance_sol=sonar_sol.ping_cm();
}
IR_on = digitalRead(IRon); //ilk whiledan çıkış için çizgi kontrolü
IR_arka = digitalRead(IRarka);
}//ilk while çıkış
if (IR_on==1 && IR_arka==0){ //ön çizgi sensörü çizgi algılıyorsa geri gidecek
// Serial.println("sadece herhangi bir ön çizgi tespit edildi geri gidiyorum");
geri();
delay(600); //delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
yerindesag();
delay(400); //delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
}
else if (IR_arka == 1 && IR_on==0){ //arka çizgi sensörü çizgi algılıyorsa ileri gidecek
//Serial.println("sadece arka çizgi tespit edildi ileri gidiyorum");
ileri();
delay(600);//delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
}
} //loop sonu
void saldir() { // Robotun saldırma hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 250); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 250); // Sol motorun hızı 0
}
void ileri() { // Robotun ileri yönde hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 180); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 180); // Sol motorun hızı
}
void yerindesag() { // Robotun sağa dönme hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
analogWrite(MotorRE, 200); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 200); // Sol motorun hızı
}
void yerindesol() { // Robotun sola dönme hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 200); // Sağ motorun hızı
digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
analogWrite(MotorLE, 200); // Sol motorun hızı
}
void dur() { // Robotun durma hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH);
digitalWrite(MotorR2, LOW);
digitalWrite(MotorRE, LOW);
digitalWrite(MotorL1, HIGH);
digitalWrite(MotorL2, LOW);
digitalWrite(MotorLE, LOW);
}
void geri() { // Robotun geri hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
analogWrite(MotorRE, 150); // Sağ motorun hızı 150
digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
analogWrite(MotorLE, 150); // Sol motorun hızı 150
}
//bitti
Test Platformu (Dövüş Ringi)
Aslında tüm robotlar için test platformu veya çalışma alanı tasarımı oldukça önemli. Robotunuzun özellikleri ve sensör kabiliyetine uygun olmayan bir ortamda robot düzgün çalışamaz. Ayrıca sahanın özelliklerine göre de robotun mekanik aksamı, sensör ayarı ve kodu kalibre edilmelidir. Ben ilk başta bir depron köpük levha üzerine 2cm genişlikte elektrik bandı ile resimdeki sahayı yapmıştım ama alan çok dar olunca robotun çalışması etkileniyor. Çok hızlı olursa kod çizgiyi algılayana kadar dışarı çıkmış olabiliyor. Bu durumda ya robotun hareket hızı düşürülmeli ya da çizgi kalınlaştırılarak daha kolay algılaması sağlanmalı. En güzeli ise robotun ebatına uygun genişlikte bir alan yapmak.
Bu projemizde arduino ile Sumo Robot yapmayı amaçladık. Peki Sumo Robot Nedir? Sumo Robotları; uluslararası yarışmaları düzenlenen, halka şeklindeki bir ring içerisinde dışarı çıkmadan rakibini dışarıya çıkmak için zorlayan dövüşçü ve otonom robotlar olarak tanımlayabiliriz. Yarışmaların belli standartları ve kuralları mevcut tabii ki. Detaylı bilgi için linkten faydalanabilirsiniz.
Bu projeyi tercih etmemin sebebi nette gördüğüm bir videoydu. Basit hareket etseler de iki robot arasındaki mücadele oldukça doğaçlama ve eğlenceli geldi.
Metodoloji
Sumo robotlar öncelikle siyah zemin üzerine beyaz çizgi ile sınırı belirlenmiş DOHYO adı verilen yaklaşık 1.5m'lik daire şeklinde bir ring üzerinde mücadele ediyor. İlk amacımız robotumuzun zemindeki çizgiyi algılaması ve dışarı çıkmamak üzerine hareket etmesi olacaktır. Bunun için aslında basitçe çizgi izleyen robotumuzdaki mantığı kullanacağız. Kendi ringimizi evde kolay oluşturulması için siyah zemin üzerine beyaz çizgi değil, normal zemin üzerine siyah çizgi olarak belirleyebiliriz. Ne demiştik her zaman basitten zora doğru gitmekte fayda var.
Çizgiyi algılama işlemini bu projede çizgi izleyen robottan farklı olarak TCRT5000 sensörlerini kullanarak yaptım. Yine aynı şekilde ne kadar çok sensör o kadar hassas kontrol demek ancak o kadar hesaplama karmaşıklığı ve işlemci gücü de demek aynı zamanda. Basit olması açısından ön tarafta 1 adet ve arkada 1 adet olmak üzere min 2 sensör ile bu işlemi gerçekleştirebiliriz. İlk denemede önde 2 arkada 1 adet kullanmıştım ancak rakibi de yapmaya karar verince her ikisine de 2şer tane olacak şekilde planlama yapmam gerekti (elimdeki sensör miktarı nedeni ile). Aslında hayat da böyle. Kaynaklar sonsuz değil o yüzden bazen idealin dışında kısıtlı kaynak ile projeleri gerçekleştirmeye çalışmak da ayrı bir tecrübe ve keyif bence hem de ileride geliştirilmeye açık oluyorlar.
Sahada kalma işini hallettikten sonra yapmamız gereken şey rakibi algılamak ve sonrasında saldırı taktiğini uygulamak. Yarışmalara katılan robotlarda çok değişik stratejiler mevcut ve sadece hayal gücünüzle sınırlı. Yine basitten başlamak gerekirse ilk yaptığımız robot ön kısımda ve sağda olacak şekilde 2 adet HCSR-04 Ultrasound sensör kullanıyordu (elimdeki sensör miktarı nedeni ile :) ). Ancak daha verimli olması açısından Sağda, Solda ve Önde olacak şekilde min 3 adet rakip algılama sensörü kullanmakta fayda var.
Gelelim hangi sensörlerin kullanılabileceğine. Aslında genel olarak bu iş için daha hızlı tepkime sürelerine sahip olan, nispeten daha uzaktan ve daha hızlı cisim algılayan dijital kızılötesi veya lazer sensörler kullanılıyor. Kaliteli sensörlerin de fiyatı oldukça yüksek tabii ki. Minimum maliyet için HCSR-04 ultrasound kullanılabilir. Tepkime süresi uzun olacak ve kod daha yavaş çalışacaktır. Bence maliyet etkinlik açısından hem dijital IR sensör olup hem de başarılı olan ürün MZ-80 olarak bilinen endüstriyel tip 80cme kadar algılama yapabilen mesafe sensörleridir. Dijital oldukları için çok hızlı çıkış veriyorlar ve arkalarındaki pot sayesinde mesafe ayarı kolayca yapılabiliyor.
Robotumuz Sağ-Sol ve Önden yaptığı arama sonucunda belirlenen mesafe içerisinde bir cisim (rakip) algılarsa ona doğru yönlenecek. Cisim sağda ise 90 derece sağa, solda ise sola dönecek ve orta sensörün görüş alanına girdiğinde rakibe doğru atak yapacak. Herhangi bir nesne görmediğinde ise yine sizin tercihinize göre olduğu yerde düzenli olarak dönerek aramaya devam edebilir veya saha içinde çizgi görene kadar gidip oradan da sola veya sağa dönerek devam edebilir. Ben 2.seçeneği tercih ettim. Şimdi yapım aşamalarına geçelim.
Gerekli Malzemeler
3 adet cisim algılama sensörü (HCSR-04 veya MZ-80 veya daha pahalı SHARP vb sensörler)
2 adet çizgi algılama sensörü (TCRT5000 hem ucuz hem de işlevsel)
4 adet redüksiyonlu DC motor
1 adet motor sürücü kartı L298
1 adet Arduino Uno/Nano/Mega
Kablo vs.
Lipo pil (9v pil de olur ama çok çabuk biter)
1 adet switch
Robot araba şasesi (Her zamanki gibi görsel olarak çok şık olmasa da şaseyi kendim yapıyorum)
Robotun Yapılışı
Sumo robot şasesi için yine buradan çizgi izleyen çalışmamızdaki benzer uygulamayı yapabilirsiniz. Ancak dikkat edilmesi gereken nokta rakip robota temas etme durumlarında sizi zor duruma düşürmemesi için rakibe minimum yüzey göstermeniz ve zarar görebilecek tüm elektronikleri ve aksamı çarpışmalardan koruyacak şekilde konumlandırmanız olacaktır. Ayrıca her sumo robotun önünde bıçak olarak adlandırılan ve rakibi ittirmede ve yerden kaldırmada kullanılan eğimli metal levhalar mevcut. İnternetten hazır olarak satın alabilir veya kendiniz elinizdeki bir malzemeden de yapabilirsiniz.
Yine değinmekte fayda duyduğum konulardan biri de Sumo robotlardaki motor ve tekerlek seçimi. Genel olarak amaç pist dışına çıkmamak ve aynızamanda rakibi ittirerek çıkarmak olduğu için maksimum sürtünme ve tutunma sağlayacak özel tekerlekler ve oldukça güçlü motorlar kullanılıyor. Eğer ciddi bir güreşçi yapmak istiyorsanız bu tarz ürünler ve daha sağlam metal-karbon gövdeler tercih etmeniz ve aynı zamanda yarışma kuralları içerisindeki ağırlık limitlerine uymanız gerekir. Bizimkiler kategori dışı.
İlk yaptığım prototipte genişliği 16cm ve derinliği 13cm olan bir dikdörtgen dakota levha kullandım. Ön ve ark tekerleri mümkün olduğunca birbirine yakın konumlandırdım. Genel görünüş ve elektroniklerin yerleşimi şekildeki gibi. Sürekli aynı sarı plastik tekerleri kullanmak istemediğim için elimdeki atıl model uçak tekerleklerinden kullandım ancak sanırım görsel olarak pek şık olmadılar :)
Biraz çıkartma ile imajı düzeltmeye çalıştık :)
İkinci versiyonda ise yukarıda bahsettiğim gibi MZ-80 kızılötesi sensörlerini 3 yönde yerleştirdim. Araç için genişliği 11, derinliği 15cm bir dakota levha kullandım. MZ-80 sensörleri kolayca monte etmek için hazır satılan bağlantı ekipmanlarından alabilir veya kendiniz sıcak silikon vb. yapıştırıcılar ile sabitleyebilirsiniz. Önünde başka engeller veya aracın parçaları olmamasına özen gösterin. Yaklaşık 15 derecelik bir açı içerisinde algılama yapıyorlar.
Çizgi sensörlerini yine kabiliyetine göre yere uzaklığını ayarlayacak şekilde yerleştiriyoruz. Sonra testler esnasında kalibre edebilirsiniz. TCRT5000de ayar vidası ters tarafta kalacağından sabitlemeden önce ayarlayıp sonra kalıcı olarak sabitleyebilirsiniz. TCRT 5000 1cm civarında oldukça yeterli çalışıyor.
Tekerleklerin mümkün olduğunca yakın olması için motorları dik konumlandırabilirsiniz böylece araç daha küçük inşa edilebilir. Ayrıca dörtçeker olması da şart gibi. İlk versiyonda başta 2 çeker yapmıştım ancak karşılaşmalarda rakibini ittiremiyor ve kayıyordu.
Devre Şeması
Aslında temel olarak her iki cihaz da aynı yapıya sahip. Sadece birinde 3 adet HCSR-04 diğerinde ise MZ-80 mevcut.
Versiyon 2 MZ-80 Robotu için;
//SUMOBOT v2 MZ-80 Nisan 2020
//Mucit Pilot
//mucitpilot.blogspot.com
//Youtube: Mucit Pilot
//////////////////////////////////////////////////////
//değişkenleri tanımlıyorum
#define IRon 11 //çizgi sensörleri
#define IRarka 12
#define MotorR1 6 //motor çıkışları
#define MotorR2 7
#define MotorRE 5
#define MotorL1 8
#define MotorL2 9
#define MotorLE 10
#define sensorsag 2 // MZ-80 sensörler
#define sensororta 3
#define sensorsol 4
///gerekli bazı değişkenleri tanımlayalım
int distance_on;
int distance_sag;
int distance_sol;
int IR_on;
int IR_arka;
int deger;
//setup kodu bir defa çalışacak
void setup() {
//pin tanımlamalarını yapalım
// 2 adet çizgi tespit sensörü
pinMode(IRon, INPUT);
pinMode(IRarka, INPUT);
pinMode(sensorsag, INPUT); // önde, solda ve sağda olmak üzere 3 adet cisim sensörü
pinMode(sensororta, INPUT);
pinMode(sensorsol, INPUT);
pinMode(MotorR1, OUTPUT); //motor çıkış pinleri
pinMode(MotorR2, OUTPUT);
pinMode(MotorL1, OUTPUT);
pinMode(MotorL2, OUTPUT);
Serial.begin(9600);
}
//ana gövde devamlı çalışıyor
void loop() {
IR_on = digitalRead(IRon); //çizgi sensörlerinden veri okuyoruz
IR_arka = digitalRead(IRarka);
while (IR_on == 0 && IR_arka == 0) { //rakip tespit etmeyi bu while içinde yapıcam. eğer çizgi sensörlerden herhangi birinde çizgi sinyali almışsa
//zaten öncelik kendini kurtarmak olacak ve bu while içine hiç girmeyecek
Serial.println("çizgiye basmıyorum ringin içindeyim cisim aramaya başla");
distance_on=digitalRead(sensororta); //ön sensörden ölçüm alıyoruz
distance_sag=digitalRead(sensorsag); //sag sensörden ölçüm alıyoruz
distance_sol=digitalRead(sensorsol); //sol sensörden ölçüm alıyoruz
//MZ-80 sensörler cisim görünce 0 çıkışı veriyor !!!!!!!!!!
while (distance_on == 0) { //ön sensörde cisim algılamışsa
//önce çizgiye basıp basmadığını kontrol edelim. Basıyorsa hiçbirşey yapmayıp döngüden çıkacak
IR_on = digitalRead(IRon);
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
//eğer çizgiye basmıyorsa önde algılama olduğu için rakibe saldıracak
saldir();
Serial.println("hedefe git");
distance_on=digitalRead(sensororta);//while da sonsuz dönmesin diye tekrar ön sensörde algılama olup olmadığını kontrol
//ediyoruz
} //while
while ((distance_sag == 0 && distance_on ==1 )){ // sadece sağdan bilgi alıyor sağa dönecek
IR_on = digitalRead(IRon); //çizgi kontrolü
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break; //çizgi varsa çık
}
yerindesag(); //çizgi yok sağa dönecek
delay(200); //bu değeri aracınızın 90 derece dönmesini sağlayacak şekilde deneme yanılma ile bulun
Serial.println("sağa dön");
distance_on=digitalRead(sensororta); //ön sensörden ölçüm alıyoruz ki whileda kalmasın
distance_sag=digitalRead(sensorsag); //sag sensörden ölçüm alıyoruz
distance_sol=digitalRead(sensorsol); //sol sensörden ölçüm alıyoruz
}
while ((distance_sol == 0 && distance_on ==1 )){ // sadece soldan bilgi alıyor sola dönecek sağ kısmının aynısı
IR_on = digitalRead(IRon);
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
yerindesol();
delay(200);
Serial.println("sola dön");
distance_on=digitalRead(sensororta); //ön sensörden ölçüm alıyoruz
distance_sag=digitalRead(sensorsag); //sag sensörden ölçüm alıyoruz
distance_sol=digitalRead(sensorsol); //sol sensörden ölçüm alıyoruz
}
while ((distance_sag ==1)&&(distance_on == 1) && (distance_sol == 1)){ //hiçbir sensörde cisim yok ne yapalım?
IR_on = digitalRead(IRon); //çizgileri kontrol et
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break; //çizgiye basıyorsan çık
}
ileri(); // cisim görmediğinde yapılacak şey size kalmış biz düz ileri gitmesini istedik.
//yerinde dönme de yaptırılabilir.
Serial.println("cisim bulunamadı ileri git");
distance_on=digitalRead(sensororta); //ön sensörden ölçüm alıyoruz ki while da kalmasın
distance_sag=digitalRead(sensorsag); //sag sensörden ölçüm alıyoruz
distance_sol=digitalRead(sensorsol); //sol sensörden ölçüm alıyoruz
}
IR_on = digitalRead(IRon); //çizgi kontrolü yapalım ki ilk while da sonsuz dönmesin
IR_arka = digitalRead(IRarka);
}//ilk while çıkış
if (IR_on== 1){ //ön çizgi sensörü çizgi algılıyorsa geri gidecek
Serial.println(" ön çizgi tespit edildi geri gidiyorum");
geri();
delay(400); // delay değerleri yine ringinizin boyutuna ve aracınızın hızına göre deneme ile ayarlanabilir.
yerindesag();
delay(300); //// delay değerleri yine ringinizin boyutuna ve aracınızın hızına göre deneme ile ayarlanabilir.
}
else if (IR_arka == 1){
// else if (IR_arka == 1 && (IR_sol ==0 && IR_sag==0)){ //sadece arka sensör gördü o zaman ileri gitmeli
Serial.println("arka çizgi tespit edildi ileri gidiyorum");
ileri();
delay(400);//// delay değerleri yine ringinizin boyutuna ve aracınızın hızına göre deneme ile ayarlanabilir.
}
} //loop sonu
void saldir() { // Robotun saldırma hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 220); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 220); // Sol motorun hızı
}
void ileri() { // Robotun ileri yönde hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 130); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 130); // Sol motorun hızı
}
void yerindesag() { // Robotun sağa dönme hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
analogWrite(MotorRE, 180); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 180); // Sol motorun hızı
}
void yerindesol() { // Robotun sola dönme hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 180); // Sağ motorun hızı
digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
analogWrite(MotorLE, 180); // Sol motorun hızı
}
void dur() { // Robotun durma hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH);
digitalWrite(MotorR2, LOW);
digitalWrite(MotorRE, LOW);
digitalWrite(MotorL1, HIGH);
digitalWrite(MotorL2, LOW);
digitalWrite(MotorLE, LOW);
}
void geri() { // Robotun geri hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
analogWrite(MotorRE, 130); // Sağ motorun hızı
digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
analogWrite(MotorLE, 130); // Sol motorun hızı
}
//Bitti
Versiyon 1 HCSR-04 Kodu
Bu kodda Kolay ve hızlı çalıştığı için newping kütüphanesi kullandım.
Bu linkten indirebilirsiniz.
//SUMOBOT v1 HCSR-04 ile
//Nisan 2020
//Mucit Pilot
//mucitpilot.blogspot.com
//youtube: Mucit Pilot
////////////////////////////
//değişkenleri tanımlıyorum
#define IRon 2 //çizgi sensörleri
#define IRarka 4
#define MotorR1 6 //motorlar
#define MotorR2 7
#define MotorRE 5
#define MotorL1 8
#define MotorL2 9
#define MotorLE 10
#define Echoorta 11 //orta sensör için echo ve trig pinleri
#define Trigorta 12
#define Echosag A0 //sağ sensör için echo ve trig pinleri
#define Trigsag A1
#define Echosol 3 //sol sensör için echo ve trig pinleri
#define Trigsol 13
#include <NewPing.h> //newping kütüphanesi pratik kullanım için
//https://github.com/eduherminio/NewPing adresinden indirebilirsiniz
NewPing sonar_on(12,11,80); // NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); şeklinde kullanılıyor
NewPing sonar_sag(15,14,80); // 3 adet sensör nesnesi tanımlıyoruz
NewPing sonar_sol(13,3,80);
//gerekli bazı değişkenler
int distance_on;
int distance_sag;
int distance_sol;
int IR_on;
int IR_arka;
int deger;
//setup kodu bir defa çalışacak
void setup() {
pinMode(IRon, INPUT); // 2 adet çizgi tespit sensörü
pinMode(IRarka, INPUT);
pinMode(Echoorta, INPUT); // önde, solda ve sağda olmak üzere 3 adet ultrasound sensör
pinMode(Echosag, INPUT);
pinMode(Echosol, INPUT);
pinMode(Trigorta, OUTPUT);
pinMode(Trigsag, OUTPUT);
pinMode(Trigsol, OUTPUT);
pinMode(MotorR1, OUTPUT); //motor çıkış pinleri
pinMode(MotorR2, OUTPUT);
pinMode(MotorL1, OUTPUT);
pinMode(MotorL2, OUTPUT);
Serial.begin(9600);
}
//ana gövde devamlı çalışıyor
void loop() {
IR_on = digitalRead(IRon); //çizgi sensörlerini okuyoruz
IR_arka = digitalRead(IRarka);
while (IR_on == 0 && IR_arka == 0) { //rakip tespit etmeyi bu while içinde yapıcam. eğer IR sensörlerden birinde çizgi sinyali almışsa
//zaten öncelik kendini kurtarmak olacak
// ve bu while içine girmeyecek
//Serial.println("çizgiye basmıyorum ringin içindeyim cisim aramaya başla");
distance_on=sonar_on.ping_cm(); //ultrasound sensörlerden ölçüm alıyoruz
distance_sag=sonar_sag.ping_cm();
distance_sol=sonar_sol.ping_cm();
while (distance_on < 40 && distance_on !=0) { //ön sensör cisim gördükçe çalışacak
//ben mesafeyi 40cm olarak belirledim 0-39cm arası görmesini istedim.
IR_on = digitalRead(IRon); //çizgi kontrolü yapalım
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){ //çizgiye basıyorsa çıkalım
break;
}
saldir(); //çizgi yok ve önde cisim algıladı saldır :)
delay(100);//hedefe git
distance_on=sonar_on.ping_cm(); //whilede sonsuz dönmesin diye tekrar ölçelim
}
while ((distance_sag < 40 && distance_sag !=0) && (distance_on > 40 || distance_on == 0) && (distance_sol > 40 || distance_sol == 0)){
// sadece sağdan bilgi alıyor sağa dönecek
IR_on = digitalRead(IRon); // çizgi kontrolü
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
geri();
delay(200); //delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
yerindesag();
delay(400); //delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
distance_on=sonar_on.ping_cm(); // while da kalmasın diye sensörlerden ölçüm alıyoruz
distance_sag=sonar_sag.ping_cm();
distance_sol=sonar_sol.ping_cm();
}
while ((distance_sol < 40 && distance_sol !=0)&&(distance_on > 40 || distance_on == 0) && (distance_sag > 40 || distance_sag == 0)){
// sadece soldan bilgi alıyor sola dönecek. Sağ kısmı ile aynı mantık
IR_on = digitalRead(IRon);
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
geri();
delay(200);
yerindesol();
delay(400);
//Serial.println("sola dön");
distance_on=sonar_on.ping_cm(); //whiledan çıkış için
distance_sag=sonar_sag.ping_cm();
distance_sol=sonar_sol.ping_cm();
}
while ((distance_sag > 40 || distance_sag ==0)&&(distance_on > 40 || distance_on == 0) && (distance_sol > 40 || distance_sol == 0)){
//hiçbir sensör görmedi düz git
IR_on = digitalRead(IRon);
IR_arka = digitalRead(IRarka);
if (IR_on == 1 || IR_arka == 1){
break;
}
ileri();
delay(100);
distance_on=sonar_on.ping_cm(); //whiledan çıkış için
distance_sag=sonar_sag.ping_cm();
distance_sol=sonar_sol.ping_cm();
}
IR_on = digitalRead(IRon); //ilk whiledan çıkış için çizgi kontrolü
IR_arka = digitalRead(IRarka);
}//ilk while çıkış
if (IR_on==1 && IR_arka==0){ //ön çizgi sensörü çizgi algılıyorsa geri gidecek
// Serial.println("sadece herhangi bir ön çizgi tespit edildi geri gidiyorum");
geri();
delay(600); //delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
yerindesag();
delay(400); //delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
}
else if (IR_arka == 1 && IR_on==0){ //arka çizgi sensörü çizgi algılıyorsa ileri gidecek
//Serial.println("sadece arka çizgi tespit edildi ileri gidiyorum");
ileri();
delay(600);//delay değerlerini ringinizin ebatı ve aracın hızına göre deneme ile ayarlayın
}
} //loop sonu
void saldir() { // Robotun saldırma hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 250); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 250); // Sol motorun hızı 0
}
void ileri() { // Robotun ileri yönde hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 180); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 180); // Sol motorun hızı
}
void yerindesag() { // Robotun sağa dönme hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
analogWrite(MotorRE, 200); // Sağ motorun hızı
digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
analogWrite(MotorLE, 200); // Sol motorun hızı
}
void yerindesol() { // Robotun sola dönme hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
analogWrite(MotorRE, 200); // Sağ motorun hızı
digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
analogWrite(MotorLE, 200); // Sol motorun hızı
}
void dur() { // Robotun durma hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, HIGH);
digitalWrite(MotorR2, LOW);
digitalWrite(MotorRE, LOW);
digitalWrite(MotorL1, HIGH);
digitalWrite(MotorL2, LOW);
digitalWrite(MotorLE, LOW);
}
void geri() { // Robotun geri hareketi için fonksiyon tanımlıyoruz.
digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
analogWrite(MotorRE, 150); // Sağ motorun hızı 150
digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
analogWrite(MotorLE, 150); // Sol motorun hızı 150
}
//bitti
Test Platformu (Dövüş Ringi)
Aslında tüm robotlar için test platformu veya çalışma alanı tasarımı oldukça önemli. Robotunuzun özellikleri ve sensör kabiliyetine uygun olmayan bir ortamda robot düzgün çalışamaz. Ayrıca sahanın özelliklerine göre de robotun mekanik aksamı, sensör ayarı ve kodu kalibre edilmelidir. Ben ilk başta bir depron köpük levha üzerine 2cm genişlikte elektrik bandı ile resimdeki sahayı yapmıştım ama alan çok dar olunca robotun çalışması etkileniyor. Çok hızlı olursa kod çizgiyi algılayana kadar dışarı çıkmış olabiliyor. Bu durumda ya robotun hareket hızı düşürülmeli ya da çizgi kalınlaştırılarak daha kolay algılaması sağlanmalı. En güzeli ise robotun ebatına uygun genişlikte bir alan yapmak.
Sonrasında iki robotun da dövüşebileceği dairesel (elle olduğu kadar :) ) bir alanı parke üzerine 3cm genişlikte elektrik bandı ile yaparak ringi hazırladım. Sanırım çapı 60-70cm civarında oldu. Daha küçük bir alan için daha küçük robotlar yapmanız gerekecektir.
Kalebodur üzerinde yaptığım denemelerde bazen derz çizgilerini algıladığı için hatalı hareketler oldu. Ancak parkede kontrast sorunu pek yaşamadım. Yaşarsanız TCRT5000in kalibre vidası ile hassasiyeti test edip ayarlayabilirsiniz.
Test Videoları
İlk yaptığım ultrasound sensör modelinde sadece sağda ve önde ses sensörü vardı ve ayrıca sadece 2 motoru ile arkadan itişli bir modeldi. İlk test videsou:
İkinci versiyon MZ-80 robotun test videosu:
İki modelin karşılaşması:
Yukarıdaki roundlarda ilk model belirttiğim gibi 2 cisim sensörü ve sadece arkadan itiş ile oldukça dezavantajlı olduğu için genelde kaybetti. Bu hafta onu da 3 sensörlü ve 4 çeker hale getirdim. Zaman olursa yeni roundları çekebilirim.
Umarım sizler de rekabetçi sumo robotlar yaparsınız.
Teşekkürler...
Bu yorum yazar tarafından silindi.
YanıtlaSilmerhaba hayirli isler robutlariniz. yaptim
SilHCSR-04 . ultra ve cizgi calisti
mz80 sensorler. sumo robot calismadi. tcrt.5000 sensör birtane calisiyor.
sebeb. ne olur. mz80. sensörler. calismadi? hayirli isler. dilerim. size
hersey. icin tesekurler
merhaba bu iki robotunuu yaptim calisti elin koluna saglik hayirli isler
Sil