Mini Sumo Robot Yapımı
Güncelleme 14/11/2024
ROBOT = ALGI + KARAR + EYLEM
Robotun ağırlık, yükseklik, en , boy gibi niceliklerinin yanı sıra robotların yarıştıkları dohyo ( Sumo robotların güreştikleri mat siyah renkli çevresi beyaz şeritle kaplanmış dairesel alan ) değişiklik göstermektedir. Toplamda 7 tip sumo robot kategorisi bulunmaktadır.
Mini Sumo
Mini sumo robot yapabilmek için öncelikle kategori kurallarına iyice bilmeniz gerekiyor.
Mini sumo robot 10×10×10 cm’lik üzeri açık bir küpün içine sığmalıdır.Bu da bize mini sumomuzun tabanının 10×10 cm’den küçük olması gerektiğini anlatmaktadır. Ancak yükseklik konusunda herhangi bir kısıtlama belirtilmemiş.
Mini sumo robot 500 gramdan ağır olamaz. Bu nedenle boyutlara ve malzeme seçimine önem verilmelidir.
Mini sumo Robotun amacı pistten çıkmadan rakibi pistin dışına atmaktır. Mini sumo robot bunu yaparken otonom olmalı, piste ve rakibe zarar vermemelidir.
Güncel olarak rakibi dışarıya atmak için itme yöntemi kullanılır. Bu nedenle seçilecek motorların hızlı olmasından ziyade, torklu olması önem arz etmektedir.
Sumo Robot Stratejileri
Ağırlık merkezi tabana yaklaştırılmalıdır. Ağırlık merkezinin tabana yakın olması robotun daha iyi manevra yapmasını sağlayacaktır. Böylece robotun dohyodan düşme ihtimali azalacaktır. Bir diğer avantajı da robotun boyu kısa olacağından rakip robotun robotumuzu fark etmesi zorlaşacaktır.
Karşılaşma başladığında daha geniş bir alan kaplanmalıdır. Sumo robotlar karşılaşmaya başlamadan önce boyut testlerini geçmek zorundadırlar . Bu kural karşılaşma başlayana kadar geçerlidir. Karşılaşma başladıktan sonra robotun boyutları değişebilir.
Kontrast sensörü beyazı algıladığında motor açıyla döndürülebilir. Böylece robotun dohyoda taradığı alan artacak ve rakip robotu daha çabuk algıla yarak dohyo dışına atması kolaylaşacaktır.
Tekerleklerin dohyoya tutunduğu yüzey artırıldığında sürtünmeden en yoğun şekilde yararlanılabilecek ve rakip robot ile karşı karşıya kalındığında dohyo içinde kalabilmek için büyük bir avantaj sağlanmış olunacaktır.
Tekerlek – Motor ikilisi sumo robotların performansı açısından oldukça önemlidir. Bu fikir çerçevesinde motor ve teker seçimi uygun yapılmalıdır. Yüksek devirli motorun yüksek torkla çalışmasını sağlamak için dişli kutusuyla devri düşürülür. Büyük boyutlu tekerlekler kullanıldığında da tork düşer. Yapılan bu çalışma ister istemez güç kaybına yol açar. Yapılan robotta hız önemli değilse; gücü çok yüksek olmayan bir motor kullanmalı ve buna uygun torku düşürmeyecek minimum boyda tekerlekler kullanılmalıdır.
Yapılan robotun rengi de önemlidir. Sumo robotların birçoğunda siyah renk kullanılır. Bunun nedeni IR ışınlarını siyah rengin soğurması yani yansıtmamasıdır.
Sumo Robotun Tasarımı
• Sumo robotun tasarımının en temel noktası robotun şasi şeklinin belirlenmesi ve şaside kullanılacak malzemenin seçilmesi hususudur. Verilin kısıtlara uyacak şekilde istenilen her tasarım kullanılabilir. Fakat bu tasarım yapılırken robotun özellikle ön kısmında ağırlık sınırını mümkün olduğunca az etkileyecek ve aynı zamanda müsabaka esnasında rakip sumo robot ile gerçekleşen çarpışmalar sırasında elektronik aksamın zarar görmesini engellemesi ve aynı zamanda rakip robotu dohyo dışarısına çıkarılmasında olumlu bir etki yaratması durumlarının göz önünde bulundurulması uygun olacaktır.
• Tasarım yapılırken göz önünde bulundurulması gereken bir diğer nokta ise sensörlerin konumları ve kullanılacak sensor miktarı olmalıdır. Temel bir sumo robot yapımında gerekli çizgi ve mesafe sensörü olmak üzere 2 çeşit sensör kullanılması gerekmektedir.
o Bunlardan çizgi sensörünün görevi sumo robotun dışı beyaz bir çemberle çevrili, siyah bir dohyo üzerinde icra edilen müsabaka esnasında, müsabaka alanının dışarısına çıkmamasını sağlamaktır. Sumo robot gerçek zamanlı olarak konum kontrolünü altına yerleştirilmiş çizgi sensörlerinden aldığı veri ile gerçekleştirir ve bu sensör veya sensörlerden gelen veri ile konumunu şekillendirir.
o Bir diğer sensor olan mesafe sensörlerinin görevi ise rakip robotun en kısa sürede tespit ederek buna karşı bir reaksiyon göstermesinin sağlanmasıdır. Sensörler sumo robotun üzerine çevresinde herhangi bir kör nokta bırakmayacak şekilde yerleştirilmelidir. Aynı zamanda sensörler, yükseklik sınırının olmadığı mini sumo robot kategorisinde rakip robotun yüksekliği ne olursa olsun doğru mesafe değerlerini döndürecek bir yüksekliğe yerleştirilmelidir. Yerleştirilen mesafe sensörlerinin yükseklikleri rakip robotun yerden yüksekliğinden daha yukarda olması durumunda sensörlerin hatalı veri döndüreceği unutulmamalıdır.
• Kullanılacak mikrodenetleyicinin ve donanımlara hükmedecek sürücünün seçilmesi de tasarımda göz ardı edilmemesi gereken bir faktördür. Seçim yapılırken boyut kısıtları ve sumo robot üzerinde kullanılacak sensörler gibi ünitelerin hepsine cevap verebilecek kapasitede giriş çıkış ünitesi olmasına dikkat edilmelidir.
Mini Sumo Robotların Özellikleri
Robotlar tamamen otonom olmalıdır.
Sumo robotun ağırlığı 500 gram olmalıdır. Ağırlıkta hata payı, %2 dir.
10 x 10 cm lik kareye sığacak boyutlarda olmalıdır.
Maç başladığında parçalara ayrılmamalıdır.
Hakem işaretinden sonra 5 saniye gecikmeli başlamalıdır.
Robotların içindeki mikrobilgisayarlar herhangi bir tür veya marka olabilir
Sizlere algoritmalar üzerinden nasıl kodlandığını gösteren projeler sunuyorum. Amaç mantığını anlamanız .
Mini Sumo Algoritması Örnek
Mini Sumo Örnek Kod
#include <ZumoShield.h> ZumoMotors motors; int mL = 0; int mC = 0; int mR = 0; int rL = 0; int rR = 0; int a=500; //motor gucu int b=400; //dönüs süresi int c=300; //geri gelme süresi #include <SharpIR.h> SharpIR sensorON (SharpIR::GP2Y0A41SK0F, A2 ); SharpIR sensorSAG (SharpIR::GP2Y0A41SK0F, A3 ); SharpIR sensorSOL (SharpIR::GP2Y0A41SK0F, A4 ); void setup () { pinMode (A0, INPUT); // QTR-1A - Çizgi Sensörü pinMode (A1, INPUT); pinMode (A2, INPUT); // SHARP – IR Mesafe Sensörü pinMode (A3, INPUT); pinMode (A4, INPUT); } void loop () { rL = analogRead(A0); // Zeminin Rengini Anlayacak Olan Sensörler rR = analogRead(A1); int mC = sensorON.getDistance(); // Rakip Robotu Tespit Edecek Olan Sensörler int mR = sensorSAG.getDistance(); int mL = sensorSOL.getDistance(); 54 if (mC < 15) {// Merkezde Bulunanan Sensörün Rakip Robotu Algılama Kontrolü motors.setLeftSpeed(a); motors.setRightSpeed(-a); // Motorlar İleri if (rR <900 || rL <900) { motors.setLeftSpeed(-a); motors.setRightSpeed(a); // Motorlar Geri delay(c); // "0.c" sn Gecikme motors.setLeftSpeed(-a); motors.setRightSpeed(-a); // Köşeden Kaçış delay(b); // "0.b" sn Gecikme } } else if (mR<15) {// Sağ Sensör Kontrol motors.setLeftSpeed(a); motors.setRightSpeed(a); // Sağa Dön } else if(mL<15) {// Sol Sensör Kontrol motors.setLeftSpeed(-a); motors.setRightSpeed(-a); // Sola Dön } // KONUM KONTROLU else if (rL >= 900 && rR >= 900) {// İki Sensörde Siyah Çizgide motors.setLeftSpeed(a); motors.setRightSpeed(-a); // Motorlar İleri } else if (rR <900 && rL >900) {// Sağ Ön Çizgiye Değdi motors.setLeftSpeed(-a); motors.setRightSpeed(a); // Motorlar Geri delay(c); //"0.c" sn Gecikme motors.setLeftSpeed(-a); motors.setRightSpeed(-a); // Köşeden Kaçış 55 delay(b); // "0. b" sn Gecikme } else if (rR >= 900 && rL <900) {// Sol Ön Çizgiye Değdi motors.setLeftSpeed(-a); motors.setRightSpeed(a); // Motorlar Geri delay(c); // "0.c" sn gecikme motors.setLeftSpeed(a); motors.setRightSpeed(a); // Köşeden Kaçış delay(b); // "0. b" sn gecikme } else if (rR <900 && rL <900) {// İkiside Çizgide motors.setLeftSpeed(-a); motors.setRightSpeed(a); // Motorlar Geri delay(c); // "0. c" sn Gecikme motors.setLeftSpeed(-a); motors.setRightSpeed(-a); // Köşeden Kaçış delay(b); // "0. b" sn Gecikme } else {// Her İhtimale Karşı Değil Durumunda Robotun İleri Hareketinin Devamı İçin motors.setLeftSpeed(a); motors.setRightSpeed(-a); // Motorlar İleri } delay (10); //Kodun Verimliliği İçin }
Mini Sumo Örnek Kod
// GENESIS BOARD MINI SUMO ROBOT PROGRAM //FOR 3 OPPONENT SENSOR, 2 EDGE SENSOR // JSUMO 01/2020 /////////////////////////////////////// //MOTOR CONTROL int RPwm = 11; int RDir = 13; int LPwm = 3; int LDir = 12; //LED & BUZZER int Buzzer = 9; int ArduLed = 8; //EDGE & CONTRAST SENSORS int Redge = A0; int Ledge = A1; //TRIMPOTS int SPD = A7; int TRN = A6; //OPPONENT SENSORS int LSens = A4; int RSens = A2; int MSens = A3; int LFSens = A5; int RFSens = 4; // DIPSWITCH & BUTTON int Button = 10; // Can be used as start pin too. int DS1 = 5; int DS2 = 6; int DS3 = 7; //VALUES int Speed =50; int MaxSpeed = 80; // Idle Speed while no sensor giving data. int TurnSpeed = 65; // Left and Right Forward Turning Speed int EdgeTurn = 150; // Turning Time variable when minisumo sees white line int Duration; // Turning Time at minisumo starting. int LastValue = 5; // Last Value Variable for remembering last Opponent sensor sense. void setup() { pinMode(LSens, INPUT); // Left Opponent Sensor Input pinMode(RSens, INPUT); // Right Opponent Sensor Input pinMode(MSens, INPUT); // Middle Opponent Sensor Input pinMode(Buzzer, OUTPUT); // Buzzer Declared as Output pinMode(ArduLed, OUTPUT); // Buzzer Declared as Output pinMode(Button, INPUT); // Buzzer Declared as Output pinMode(RPwm, OUTPUT); // Four PWM Channel Declared as Output pinMode(RDir, OUTPUT); pinMode(LPwm, OUTPUT); pinMode(LDir, OUTPUT); digitalWrite(Buzzer, LOW); // Buzzer Pin Made Low for Silence 🙂 digitalWrite(ArduLed, LOW); // Arduino Mode Led Made Low digitalWrite(DS1, HIGH); // 3 Dipswitch Pin Pullups Made digitalWrite(DS2, HIGH); digitalWrite(DS3, HIGH); digitalWrite(LSens, HIGH); // Opponent Sensor Pullups Made digitalWrite(RSens, HIGH); digitalWrite(LFSens, HIGH); digitalWrite(RFSens, HIGH); digitalWrite(MSens, HIGH); Serial.begin(9600); } //Motor Control Function void Set_Motor (float Lval, float Rval, int timex){ Lval = Lval*2.5; Rval = Rval*2.5; if (Lval >=0) { analogWrite(LPwm, Lval); digitalWrite(LDir, LOW); } else { Lval=abs(Lval); digitalWrite(LDir, HIGH); analogWrite(LPwm, Lval); } if (Rval >=0) { analogWrite(RPwm, Rval); digitalWrite(RDir, HIGH); } else { Rval=abs(Rval); digitalWrite(RDir, LOW); analogWrite(RPwm, Rval); } //If you want to see Speed Values please uncomment bottom line. // Serial.print(Rval); Serial.print(“-“); Serial.println(Lval); delay(timex); } void loop() { digitalWrite(RPwm, LOW); digitalWrite(LPwm, LOW); tone(Buzzer, 18, 100); // Pin, Frequency, Duration ////////////////////////////////////////////// // This function below, used for stopping robot while no button is pushed or Microstart is not triggered. while (digitalRead(Button)==0) { Serial.println(“Button Press Waited”); Set_Motor(0,0,1); /// Sensor Control While Waiting The Button Press /// if ( digitalRead(MSens)==LOW || digitalRead(RSens)==LOW || digitalRead(LSens)== LOW || digitalRead(RFSens)==LOW || digitalRead(LFSens)== LOW || analogRead(Redge)< 100 || analogRead(Ledge)< 100 ) { digitalWrite(ArduLed, HIGH);} else { digitalWrite(ArduLed, LOW); } } /////////////////////////////////////////////// if (digitalRead(Button)==1) { Duration=(analogRead(TRN)/5); // Duration variable based on TRN (A6) trimpot Duration=205-Duration; // Serial.println(“5 Sec Routine Started”); for (int i = 0; i < 5; i++){ digitalWrite(Buzzer, HIGH); digitalWrite(ArduLed, HIGH); delay(100); digitalWrite(Buzzer, LOW); digitalWrite(ArduLed, LOW); delay(900); } if (digitalRead(DS1)==0 && digitalRead(DS2)==1 && digitalRead(DS3)==1){ Serial.print(“LEFT TURN”); Set_Motor(-100,100,Duration); // } else if (digitalRead(DS1)==0 && digitalRead(DS2)==0 && digitalRead(DS3)==0) { Serial.print(“MIDDLE DIRECT”); Set_Motor(80,80,2); } else if (digitalRead(DS1)==1 && digitalRead(DS2)==1 && digitalRead(DS3)==0){ Serial.print(“Sag”); Set_Motor(100,-100,Duration); } else if (digitalRead(DS1)==1 && digitalRead(DS2)==0 && digitalRead(DS3)==0){ Serial.print(“Left Circle”); Set_Motor(100,36,650); } else if (digitalRead(DS1)==0 && digitalRead(DS2)==0 && digitalRead(DS3)==1){ Serial.print(“Right Circle”); Set_Motor(36,100,650); } else if (digitalRead(DS1)==0 && digitalRead(DS2)==1 && digitalRead(DS3)==0){ Serial.print(“Reverse 180”); Set_Motor(-100,100,Duration*2); // One Duration time is for 90 degree, so we multiply by 2. } Serial.print(“OK”); digitalWrite(Buzzer, LOW); EdgeTurn=(analogRead(TRN)/5); // Raw value comes with 0 to 1023, we divide it for 0 t0 205 mS turning time. EdgeTurn=205-EdgeTurn; // } //Main Loop while(1) { /// Edge Sensor Control Routine /// digitalWrite(ArduLed, LOW); if (analogRead(Ledge)<300 && analogRead(Redge)> 300) { digitalWrite(Buzzer, LOW); digitalWrite(ArduLed, HIGH); Set_Motor(-100, -100,55); // Backward for 55 mS. Set_Motor(-100, 100, EdgeTurn); // Left Backward, Right Forward, Turning Time Based on ETRN Trimpot LastValue=5; } else if (analogRead(Ledge)> 300 && analogRead(Redge)< 300) { digitalWrite(Buzzer, LOW); digitalWrite(ArduLed, HIGH); Set_Motor(-100, -100,55); // Backward for 55 mS. Set_Motor(100, -100, EdgeTurn); // Right Backward, Left Forward, Turning Time Based on ETRN Trimpot LastValue=5; } else if (analogRead(Ledge)< 300 && analogRead(Redge)< 300) { digitalWrite(Buzzer, LOW); digitalWrite(ArduLed, HIGH); Set_Motor(-100, -100,55); // Backward for 55 mS. Set_Motor(100, -100, EdgeTurn); // Right Backward, Left Forward, Turning Time Based on ETRN Trimpot LastValue=5; }else /// Opponent Sensor Control Routine /// // Please uncomment below line if yu are using microstart, When microstart gives 0V it will stop motors. //while (digitalRead(Button)==LOW) {Set_Motor(0, 0, 20); digitalWrite(Buzzer, HIGH); LastValue=3;} digitalWrite(Buzzer, LOW); if (digitalRead(MSens)==LOW) {Set_Motor(MaxSpeed, MaxSpeed,1); digitalWrite(Buzzer, HIGH); LastValue=5;} else if (digitalRead(LSens)== LOW) {Set_Motor(-40, TurnSpeed,1); digitalWrite(Buzzer, HIGH); LastValue=7;} else if (digitalRead(RSens)==LOW) {Set_Motor(TurnSpeed, -40,1); digitalWrite(Buzzer, HIGH); LastValue=3;} else if (digitalRead(LFSens)== LOW) {Set_Motor(-40, TurnSpeed,1); digitalWrite(Buzzer, HIGH); LastValue=7;} else if (digitalRead(RFSens)==LOW) {Set_Motor(TurnSpeed, -40,1); digitalWrite(Buzzer, HIGH); LastValue=3;} else { digitalWrite(Buzzer, LOW); Speed=(analogRead(SPD)/10.3); // This raw speed value comes with 0 to 1023 so we divide to 10.3 After that it is 0 to 99 integer. Speed=100-Speed; // This is used for reversing trimpot dial direction at board. if (LastValue==5) { Set_Motor(Speed, Speed,1);} else // Forward, Based on SPD (A7) Trimpot if (LastValue==7) { Set_Motor(-20, Speed,2);} else // Left Turning Based on SPD (A7) Trimpot if (LastValue==3) { Set_Motor(Speed, -20,2);} // Right Turning Based on SPD (A7) Trimpot } } }
Mini Sumo Algoritması Örnek
Mini Sumo Örnek Kod
#define motor_1 2 #define motor_2 3 #define motor_3 4 #define motor_4 5 //////////////////////////////////////////////////////// #define cizgi_sensor_on_1 6 #define cizgi_sensor_on_2 7 #define cizgi_sensor_arka 8 #define engel_1 9 #define engel_2 10 ///////////////////////////////////////////////////////// void motor_ileri(){ digitalWrite(motor_1,LOW); digitalWrite(motor_2,HIGH); digitalWrite(motor_3,HIGH); digitalWrite(motor_4,LOW);} ///////////////////////////////////////////// void motor_geri(){ digitalWrite(motor_1,HIGH); digitalWrite(motor_2,LOW); digitalWrite(motor_3,LOW); digitalWrite(motor_4,HIGH);} ///////////////////////////////////////////// void motor_sag(){ digitalWrite(motor_1,HIGH); digitalWrite(motor_2,LOW); digitalWrite(motor_3,HIGH); digitalWrite(motor_4,LOW);} //////////////////////////////////////////// void motor_sol(){ digitalWrite(motor_1,LOW); digitalWrite(motor_2,HIGH); digitalWrite(motor_3,LOW); digitalWrite(motor_4,HIGH);} ///////////////////////////////////////////// void motor_dur(){ digitalWrite(motor_1,LOW); digitalWrite(motor_2,LOW); digitalWrite(motor_3,LOW); digitalWrite(motor_4,LOW);} /////////////////////////////////////////////// void setup(){ pinMode(motor_1,OUTPUT); pinMode(motor_2,OUTPUT); pinMode(motor_3,OUTPUT); pinMode(motor_4,OUTPUT); pinMode(cizgi_sensor_on_1,INPUT); pinMode(cizgi_sensor_on_2,INPUT); pinMode(cizgi_sensor_arka,INPUT); pinMode(engel_1,INPUT); pinMode(engel_2,INPUT); delay(5000); //start verildikten 5 sn sonra başlayacak } void loop() { if(digitalRead(engel_1)== LOW && digitalRead(engel_2)== LOW){ if(digitalRead(cizgi_sensor_on_1) == LOW){motor_geri();delay(2000);} if(digitalRead(cizgi_sensor_on_2) == LOW){motor_geri();delay(2000);} motor_ileri();} else if(digitalRead(engel_1)== LOW && digitalRead(engel_2)== HIGH) {motor_sol();delay(50);} else if(digitalRead(engel_1)== HIGH && digitalRead(engel_2)== LOW) {motor_sag();delay(50);} else if(digitalRead(cizgi_sensor_on_1) == LOW) {motor_geri();} else if(digitalRead(cizgi_sensor_on_2) == LOW) {motor_geri();} else if(digitalRead(cizgi_sensor_arka) == LOW) {motor_ileri();delay(2000);} else {motor_sag();} delay(50); }