Çizgi izleyen ve Engel Aşan Robot

Selamlar, Arduino ya başlayalı 2-3 ay oldu ve çizgi izleyen bir robot yaptık, şimdi engel aşması için de kod yazmak istiyorum. http://imageshack.us/photo/my-images/201/33234655.jpg/ http://imageshack.us/photo/my-images/209/80899003.jpg/ Robotoun önünde bir servo motor var ve servo motora da 10 cm den az mesafelerde 0V veren bir dijital IR sensör bağlı. Şuan yaptığım şey sadece robot engel gördüğü zaman duruyor. Çizgi izleyen robotoumun kodu bu, engeli aşması için ekstra yazacağım kodu bu kodun neresine yazmalıyım nasıl bir yol izlemeliyim. Yapmak istediğim de servo hep 90 derecede duracak, robot engelle karşılaşınca duracak , servo motor 60 derecelik açılarla sağa ve sola bakacak, ve hangi taraf boşsa oradan bir yarım kare çizip yola devam edecek. #include Servo.h #include PololuQTRSensors.h #include AFMotor.h AF_DCMotor motor1(1, MOTOR12_8KHZ ); // PIN 11 - create motor #1 pwm AF_DCMotor motor2(2, MOTOR12_8KHZ ); // PIN 3 - create motor #2 pwm // Change the values below to suit your robot’s motors, weight, wheel type, etc. #define KP .2 #define KD 5 #define M1_DEFAULT_SPEED 55 #define M2_DEFAULT_SPEED 55 #define M1_MAX_SPEED 70 #define M2_MAX_SPEED 70 #define MIDDLE_SENSOR 3 #define NUM_SENSORS 5 // number of sensors used #define TIMEOUT 2500 // waits for 2500 us for sensor outputs to go low PololuQTRSensorsRC qtrrc((unsigned char) { 7, 6, 5, 4, 3} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN); unsigned int sensorValues[NUM_SENSORS]; void setup() { delay(1); manual_calibration(); } int lastError = 0; int last_proportional = 0; int integral = 0; int sensorValue = analogRead(A5); int pos = 0; void loop() { int sensors[5]; int position = qtrrc.readLine(sensors); int error = position - 2000; int motorSpeed = KP * error + KD * (error - lastError); lastError = error; int leftMotorSpeed = M1_DEFAULT_SPEED + motorSpeed; int rightMotorSpeed = M2_DEFAULT_SPEED - motorSpeed; // set motor speeds using the two motor speed variables above set_motors(leftMotorSpeed, rightMotorSpeed); } void set_motors(int motor1speed, int motor2speed) { if (motor1speed > M1_MAX_SPEED ) motor1speed = M1_MAX_SPEED; // limit top speed if (motor2speed > M2_MAX_SPEED ) motor2speed = M2_MAX_SPEED; // limit top speed if (motor1speed < 0) motor1speed = 0; // keep motor above 0 if (motor2speed < 0) motor2speed = 0; // keep motor speed above 0 motor1.setSpeed(motor1speed); // set motor speed motor2.setSpeed(motor2speed); // set motor speed motor1.run(FORWARD); motor2.run(FORWARD); if (sensorValue= analogRead(A5) < 500) // I added here to stop the robot when distance sensor see an obstacle { set_motors(0, 0); } } void manual_calibration() { int i; for (i = 0; i < 50; i++) // the calibration will take a few seconds { qtrrc.calibrate(QTR_EMITTERS_ON); delay(20); } if (DEBUG) { // if true, generate sensor dats via serial output Serial.begin(9600); for (int i = 0; i < NUM_SENSORS; i++) { Serial.print(qtrrc.calibratedMinimumOn[i]); Serial.print(’ ‘); } Serial.println(); for (int i = 0; i < NUM_SENSORS; i++) { Serial.print(qtrrc.calibratedMaximumOn[i]); Serial.print(’ '); } Serial.println(); Serial.println(); } }

Proje komplike değil. Anlatımın çok karmaşık. Kimsenin başka birinin problemini bedava çözmek için böyle uzun bir metni okuyup, ne demek istediğini anlayıp çözüm önerecek vakti yok. Detaylara girmeden problemi anlatırsan detaylar için üstteki yazıya bakabiliriz. Kodu da indirmeden görebileceğimiz bir yere koyarsan daha kolay olur.

Kısalatarak yukarıya tekrar yazdım. Teşekkürler.

if (sensorValue= analogRead(A5) < 500) // I added here to stop the robot when distance sensor see an obstacle{set_motors(0, 0);}} burada set_motors(0, 0); 'nin sonuna servoları 60 derece swipe edecek konu ekleyeceksin. swipe(motorları sağa sola çevirmek-süpürme hareketi) ederken if (sensorValue= analogRead(A5) > 500) diyip bunun altına robotun o yöne hareketini sağlayacaksın. Hangi mesafedeki engeli algılayıp algılamayacağını da o 500 değeriyle oynayarak bulacaksın. Burada problem servolar swipe ederken hangi pozisyondayken engelsiz noktayı gördüğü ve robotu süren motorları o noktoya sürmek olacaktır. Swipe kodunun içinde for döngüsü var. for’daki “i” 179’a veya 0’a kadar saydırılır. for’un içine sensörden gelen veriyi hangi i’de yakalamışsa onu robotu süren değere atayarak çözebilirsin. swipe for’unun içine if(sensördeğeri=boşlukdeğeri) {fordan çık motoları sür} yaparak kolayca çözebilirsin.

if (sensorValue= analogRead(A5) < 500) { myservo.attach(10); set_motors(0, 0); for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees { // in steps of 1 degree myservo.write(pos); // tell servo to go to position in variable ‘pos’ delay(15); // waits 15ms for the servo to reach the position } for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees { myservo.write(pos); // tell servo to go to position in variable ‘pos’ delay(15); // waits 15ms for the servo to reach the position } Selamlar, geri dönüşünüz için teşekkürler. dedikleriniz doğrultusunda boyle bir kısım ekledim set motors(0,0) dan sonra, motor engel görünce duruyor, servo 0->180, 180->0 taramasını yapıyor ama önündeki engeli çektiğim zaman hiç durmadan servo taramaya devam ediyor takılıyor yani orada.

Selamlar yukarıda yazdığım sorunu kodu aşağıdaki gibi değiştirerek çözdüm (if case ini void loop un içine yazarak), bu kod ile engel görünce servo motor 90->150, 150->30, 30->89 tarıyor ve engel yoksa önünde taramadan sonra yola devam ediyor. Şöyle bir sıkıntı var şuan, robotun önünde engel var 90 dan 150 ye taradı ve 130 dan sonrabirşey görmedi diyelim , geri döndü 30 a kadar taradı 30 a kadar engel gördü 30 dan 90 a zaten bir engel var,bu durumda servo tekrar dönmeye başlıyor (yani tarmanın sonunda engel görmezse yola devam ediyor ama taramanın sonunda engel görürse tekrar tarıyor). Oysaki bu hareketi 1 defaya mahsus yapıp hangi açıda engel yok onu tanımlamam lazım. Bunun için nasıl bir yol izlemeliyim. void loop() { unsigned int sensors[5]; int position = qtrrc.readLine(sensors); int error = position - 2000; myservo.attach(10); int pos = 90; int motorSpeed = KP * error + KD * (error - lastError); lastError = error; int leftMotorSpeed = M1_DEFAULT_SPEED + motorSpeed; int rightMotorSpeed = M2_DEFAULT_SPEED - motorSpeed; if (sensorValue= analogRead(A5) < 500) { myservo.attach(10); set_motors(0, 0); int pos = 90 ; for(pos = 90; pos < 150; pos += 1) { myservo.write(pos); delay(15); } for(pos = 150; pos>=30; pos-=1) { myservo.write(pos); delay(15); } for(pos = 30; pos<=89; pos+=1) { myservo.write(pos); delay(15); } } void set_motors(int motor1speed, int motor2speed) { if (motor1speed > M1_MAX_SPEED ) motor1speed = M1_MAX_SPEED; // limit top speed if (motor2speed > M2_MAX_SPEED ) motor2speed = M2_MAX_SPEED; // limit top speed if (motor1speed < 0) motor1speed = 0; // keep motor above 0 if (motor2speed < 0) motor2speed = 0; // keep motor speed above 0 motor1.setSpeed(motor1speed); // set motor speed motor2.setSpeed(motor2speed); // set motor speed motor1.run(FORWARD); motor2.run(FORWARD); }

Kodun ilgili kısmını bu şekilde değiştirerek, sensörü dönderdikçe engellerden olan uzaklığı kontrol etmeniz lazım. Onları bir şekilde kaydedip tarama bittikten sonra motorları ona göre hareket ettirmelisiniz. if (analogRead(A5) < 500) { int bosluk=90; int uzunluk=1; myservo.attach(10); set_motors(0, 0); for(pos = 91; pos < 150; pos += 1) { myservo.write(pos); delay(15); if (analogRead(A5) > 500) { // En geniş boşluğun nerede ve ne kadar olduğunu burada ölçmek lazım } } for(pos = 150; pos > 30; pos -= 1) { myservo.write(pos); delay(15); } for(pos = 30; pos < 91; pos += 1) { myservo.write(pos); delay(15); if (analogRead(A5) > 500) { // En geniş boşluğun nerede ve ne kadar olduğunu burada ölçmek lazım } } } Açılarla da biraz oynama yaptım ve sensörü okuma işini her açı için bir kez yaptım. Yani 150’den 30’a geri dönerken okuma yapmasına gerek yok. Ama bu kod sadece nerede engel var nerede yok onu anlamaya yarar. Bunun hemen içine -o belirttiğim boşluklara-, en geniş boşluğun nerede olduğunu gösteren kodu eklemeniz lazım. Bu kodun tamamının altına da aracı o yöne çevirip motorlara tam güç vermeniz lazım. En geniş boşluğu bulup o yönde düz ilerletmek en mantıklısı çünkü: 91 ile 140 arasında engel var ama 141 serbest gözüküyorsa 141 e düz devam etmek veya oraya gitmek için yarım kare çizmek engeli aşmak için yetmeye bilir çünkü belki 142’de de engel var? Umarım anlatabilmişimdir ve yardımcı olabilmişimdir.