İçindekiler:

6 DOF Robotik Kolun XYZ Konumlandırılması için Arduino Uno'yu Kullanma: 4 Adım
6 DOF Robotik Kolun XYZ Konumlandırılması için Arduino Uno'yu Kullanma: 4 Adım

Video: 6 DOF Robotik Kolun XYZ Konumlandırılması için Arduino Uno'yu Kullanma: 4 Adım

Video: 6 DOF Robotik Kolun XYZ Konumlandırılması için Arduino Uno'yu Kullanma: 4 Adım
Video: Robotiğin Temelleri-1 2024, Kasım
Anonim
Image
Image

Bu proje, XYZ ters kinematik konumlandırma sağlamak için kısa ve nispeten kolay bir Arduino taslağı uygulamakla ilgilidir. 6 servo robotik bir kol inşa etmiştim ama iş onu çalıştıracak yazılım bulmaya geldiğinde, SSC-32(U) gibi özel servo kalkanlarda çalışan özel programlar veya diğer programlar ve uygulamalar dışında pek bir şey yoktu. kol ile kurmak ve iletişim kurmak için karmaşık. Sonra Oleg Mazurov'un basit bir Arduino çiziminde ters kinematiği uyguladığı en mükemmel "Arduino'da Robotik Kol Ters Kinematiği" buldum.

Kodunu uyarlamak için iki değişiklik yaptım:

1. Özel servo kalkan kitaplığı yerine VarSpeedServo kitaplığını kullandım çünkü daha sonra servoların hızını kontrol edebilirdim ve onun kullandığı servo kalkanını kullanmak zorunda kalmazdım. Burada verilen kodu çalıştırmayı düşünenler için servo.h kitaplığı yerine bu VarSpeedServo kitaplığını kullanmanızı tavsiye ederim, böylece geliştirme sırasında robotik kol hareketinizi yavaşlatabilirsiniz veya kolun beklenmedik bir şekilde sizi dürteceğini görebilirsiniz. yüz veya daha kötü çünkü tam servo hızında hareket edecek.

2. Servoları Arduino Uno'ya bağlamak için basit bir sensör/servo kalkanı kullanıyorum ama sadece Arduino'nun pinlerini kullandığı için özel bir servo kitaplığı gerektirmiyor. Sadece birkaç dolara mal olur, ancak gerekli değildir. Servoların Arduino'ya güzel ve temiz bir şekilde bağlanmasını sağlar. Ve şimdi asla Arduino Uno'ya servo kablolamaya geri dönmeyeceğim. Bu sensör/servo kalkanını kullanırsanız, aşağıda özetleyeceğim küçük bir değişiklik yapmanız gerekir.

Kod harika çalışıyor ve x, y, x ve hız parametrelerini ilettiğiniz tek bir işlevi kullanarak kolu çalıştırmanıza izin veriyor. Örneğin:

set_arm(0, 240, 100, 0, 20); // parametreler (x, y, z, tutucu açısı, servo hızı)

gecikme(3000); // kurma süresinin bu konuma taşınmasına izin vermek için gecikme gerekiyor

Daha basit olamazdı. Krokiyi aşağıya ekleyeceğim.

Oleg'in videosu burada: Arduino ve USB Fare ile Robotik Kolu Kontrol Etme

Oleg'in orijinal programı, açıklamaları ve kaynakları: Arduino Uno için Oleg'in Ters Kinematiği

Rutinin arkasındaki tüm matematiği anlamıyorum ama güzel olan şey, kodu kullanmak zorunda olmamanız. Umarım bir deneyeceksin.

Adım 1: Donanım Değişiklikleri

Donanım Değişiklikleri
Donanım Değişiklikleri

1. Gerekli olan tek şey servonuzun, servolarınızın montajını fiziksel olarak tersine çevirmenizi gerektirebilecek beklenen yönlerde dönmesidir. Taban, omuz, dirsek ve bilek servoları için beklenen servo yönünü görmek için bu sayfaya gidin:

2. Kullandığım sensör kalkanını kullanıyorsanız, ona bir şey yapmanız gerekiyor: 5v'yi kalkandan Arduino Uno'ya bağlayan pimi, Uno kartına bağlanmaması için yoldan çekin. Kalkandaki harici voltajı Arduino Uno'ya değil, yalnızca servolarınıza güç sağlamak için kullanmak istiyorsunuz veya Uno'yu yok edebilir, harici voltajım 5 yerine 6 volt olduğunda iki Uno kartını yaktığımı biliyorum. servolarınıza güç sağlamak için 5v'den daha yüksek kullanmak için ancak harici voltajınız 5 volttan yüksekse, o zaman kalkana 5 voltluk sensörler bağlamayın, aksi takdirde kızarlar.

Adım 2: VarSpeedServo Kitaplığını İndirin

Standart arduino servo kitaplığının yerini alan bu kitaplığı kullanmanız gerekiyor çünkü servo yazma deyimine bir servo hızı geçirmenizi sağlıyor. Kütüphane burada bulunur:

VarSpeedServo Kitaplığı

Sadece zip düğmesini kullanabilir, zip dosyasını indirebilir ve ardından Arduino IDE ile kurabilirsiniz. Komutu programınıza yükledikten sonra şöyle görünecektir: servo.write(100, 20);

İlk parametre açıdır ve ikincisi servonun 0'dan 255'e kadar olan hızıdır (tam hız).

Adım 3: Bu Çizimi Çalıştırın

İşte yarışma programı. Robotik kol ölçüleriniz için birkaç parametreyi değiştirmeniz gerekiyor:

1. BASE_HGT, HUMERUS, ULNA, GRIPPER uzunlukları milimetre cinsinden.

2. Servo pin numaralarınızı girin

3. Ek ifadelere servo min ve max değerlerini girin.

4. Ardından basit bir set_arm() komutunu ve ardından test için zero_x(), line() vecircle() işlevlerini deneyin. Kolunuza ve kendi kolunuza zarar vermemek için bu işlevleri ilk çalıştırdığınızda servo hızınızın düşük olduğundan emin olun.

İyi şanlar.

#include VarSpeedServo.h

/* AL5D kolu için servo kontrol */

/* Kol boyutları(mm) */

#define BASE_HGT 90 //taban yüksekliği

#define HUMERUS 100 //omuzdan dirseğe "kemik"

#define ULNA 135 //dirsekten bileğe "kemik"

#define GRIPPER 200 //tutucu (ağır hizmet tipi bilek döndürme mekanizması dahil) uzunluk"

#define ftl(x) ((x)>=0?(uzun)((x)+0.5):(uzun)((x)-0.5)) //kayan uzun dönüşüm

/* Servo adları/numaraları *

* Temel servo HS-485HB */

#define BAS_SERVO 4

/* Omuz Servo HS-5745-MG */

#define SHL_SERVO 5

/* Dirsek Servo HS-5745-MG */

#define ELB_SERVO 6

/* Bilek servosu HS-645MG */

#define WRI_SERVO 7

/* Bilek döndürme servosu HS-485HB */

#define WRO_SERVO 8

/* Tutucu servo HS-422 */

#define GRI_SERVO 9

/* ön hesaplamalar */

float hum_sq = HUMERUS*HUMERUS;

float uln_sq = ULNA*ULNA;

int servoSpeed = 10;

//ServoShield servoları; //ServoShield nesnesi

VarSpeedServo servo1, servo2, servo3, servo4, servo5, servo6;

int loopCounter=0;

int darbe Genişliği = 6.6;

int mikrosaniyeToDegrees;

geçersiz kurulum()

{

servo1.attach(BAS_SERVO, 544, 2400);

servo2.attach(SHL_SERVO, 544, 2400);

servo3.attach(ELB_SERVO, 544, 2400);

servo4.attach(WRI_SERVO, 544, 2400);

servo5.attach(WRO_SERVO, 544, 2400);

servo6.attach(GRI_SERVO, 544, 2400);

gecikme (5500);

//servos.start(); //Servo kalkanını başlat

servo_park();

gecikme(4000);

Seri.başla(9600);

Serial.println("Başlat");

}

boşluk döngüsü()

{

loopCounter +=1;

//set_arm(-300, 0, 100, 0, 10); //

//gecikme(7000);

//sıfır_x();

//hat();

//Daire();

gecikme(4000);

if (loopCounter > 1) {

servo_park();

//set_arm(0, 0, 0, 0, 10); // park

gecikme (5000);

çıkış (0); }//programı duraklat - devam etmek için sıfırla'ya basın

//çıkış(0);

}

/* ters kinematik kullanan kol konumlandırma rutini */

/* z yükseklik, y taban merkezden dışarı uzaklık, x yan yana. y, z sadece pozitif olabilir */

//void set_arm(uint16_t x, uint16_t y, uint16_t z, uint16_t kavrama_açı)

void set_arm(float x, float y, float z, float grip_angle_d, int servoSpeed)

{

float grip_angle_r = radyan(grip_angle_d); //hesaplamalarda kullanmak için radyan cinsinden kavrama açısı

/* x, y koordinatlarından taban açısı ve radyal uzaklık */

float bas_angle_r = atan2(x,y);

kayan nokta rdist = sqrt((x * x) + (y * y));

/* rdist kol için y koordinatıdır */

y = rdist;

/* Kavrama açısına göre hesaplanan kavrama ofsetleri */

float grip_off_z = (sin(grip_angle_r)) * TUTUCU;

float grip_off_y = (cos(grip_angle_r)) * TUTUCU;

/* Bilek pozisyonu */

float bilek_z = (z - grip_off_z) - BASE_HGT;

float bilek_y = y - grip_off_y;

/* Omuzdan bileğe mesafe (AKA sw) */

float s_w = (wrist_z * bilek_z) + (wrist_y * bilek_y);

kayan nokta s_w_sqrt = sqrt(s_w);

/* s_w yere göre açı */

float a1 = atan2(wrist_z, bileklik_y);

/* s_w humerus açısı */

float a2 = acos(((hum_sq - uln_sq) + s_w) / (2 * HUMERUS * s_w_sqrt));

/* omuz açısı */

float shl_angle_r = a1 + a2;

float shl_angle_d = derece(shl_angle_r);

/* dirsek açısı */

float elb_angle_r = acos((hum_sq + uln_sq - s_w) / (2 * HUMERUS * ULNA));

float elb_angle_d = derece(elb_angle_r);

float elb_angle_dn = -(180.0 - elb_angle_d);

/* bilek açısı */

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/* Servo darbeleri */

float bas_servopulse = 1500.0 - ((derece(bas_angle_r)) * pulseWidth);

float shl_servopulse = 1500.0 + ((shl_angle_d - 90.0) * pulseWidth);

float elb_servopulse = 1500.0 - ((elb_angle_d - 90.0) * pulseWidth);

//float wri_servopulse = 1500 + (wri_angle_d * pulseWidth);

//float wri_servopulse = 1500 + (wri_angle_d * pulseWidth);

float wri_servopulse = 1500 - (wri_angle_d * pulseWidth);// jimrd tarafından 2018/2/11 güncellendi - Artıyı eksi olarak değiştirdim - bu kodun daha önce kimse için nasıl çalıştığından emin değilim. Dirsek servosu yukarı değil 0 derece aşağı bakacak şekilde monte edilmiş olabilir.

/* Servoları ayarla */

//servos.setposition(BAS_SERVO, ftl(bas_servopulse));

microsecondsToDegrees = map(ftl(bas_servopulse), 544, 2400, 0, 180);

servo1.write(microsecondsToDegrees, servoSpeed); // servo hızını ayarlayabilmek için bu işlevi kullanın //

//servos.setposition(SHL_SERVO, ftl(shl_servopulse));

microsecondsToDegrees = map(ftl(shl_servopulse), 544, 2400, 0, 180);

servo2.write(microsecondsToDegrees, servoSpeed);

//servos.setposition(ELB_SERVO, ftl(elb_servopulse));

microsecondsToDegrees = map(ftl(elb_servopulse), 544, 2400, 0, 180);

servo3.write(microsecondsToDegrees, servoSpeed);

//servos.setposition(WRI_SERVO, ftl(wri_servopulse));

microsecondsToDegrees = map(ftl(wri_servopulse), 544, 2400, 0, 180);

servo4.write(microsecondsToDegrees, servoSpeed);

}

/* servoları park pozisyonuna taşı */

geçersiz servo_park()

{

//servos.setposition(BAS_SERVO, 1500);

servo1.write(90, 10);

//servos.setposition(SHL_SERVO, 2100);

servo2.write(90, 10);

//servos.setposition(ELB_SERVO, 2100);

servo3.write(90, 10);

//servos.setposition(WRI_SERVO, 1800);

servo4.write(90, 10);

//servos.setposition(WRO_SERVO, 600);

servo5.write(90, 10);

//servos.setposition(GRI_SERVO, 900);

servo6.write(80, 10);

dönüş;

}

geçersiz sıfır_x()

{

for(çift yaxis = 250.0; yaxis < 400.0; yaxis += 1) {

Serial.print(" yaxis=: ");Serial.println(yaxis);

set_arm(0, yaxis, 200.0, 0, 10);

gecikme(10);

}

for(çift yaxis = 400.0; yaxis > 250.0; yaxis -= 1) {

set_arm(0, yaxis, 200.0, 0, 10);

gecikme(10);

}

}

/* kolu düz bir çizgide hareket ettirir */

boşluk satırı()

{

for(çift x ekseni = -100.0; x ekseni < 100.0; x ekseni += 0,5) {

set_arm(xaxis, 250, 120, 0, 10);

gecikme(10);

}

for(float xaxis = 100.0; xaxis > -100.0; xaxis -= 0.5) {

set_arm(xaxis, 250, 120, 0, 10);

gecikme(10);

}

}

boşluk çemberi()

{

#define RADIUS 50.0

//kayan açı = 0;

float zaxis, yaxis;

for(kayan açı = 0.0; açı < 360.0; açı += 1.0) {

yaxis = YARIÇAP * sin(radyan(açı)) + 300;

zaxis = YARIÇAP * cos(radyan(açı)) + 200;

set_arm(0, yaxis, zaxis, 0, 50);

gecikme(10);

}

}

Adım 4: Gerçekler, Sorunlar ve Benzerleri…

Gerçekler, Sorunlar ve Benzerleri…
Gerçekler, Sorunlar ve Benzerleri…

1. Circle() alt programını çalıştırdığımda robotum daire yerine elips şeklinde hareket ediyor. Sanırım bunun nedeni servolarımın kalibre edilmemiş olması. Bunlardan birini test ettim ve 1500 mikrosaniye 90 derece ile aynı değildi. Bir çözüm bulmaya çalışmak için bunun üzerinde çalışacak. Algoritmada değil, ayarlarımda yanlış bir şey olduğuna inanmayın. 2018/2/11 Güncellemesi - bunun orijinal koddaki hatadan kaynaklandığını yeni keşfettim. Programının nasıl çalıştığını anlamıyorum Bunu kullanarak sabit kod: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (orijinal kod ekleniyor)

2. set_arm() işlevinin nasıl çalıştığı hakkında daha fazla bilgiyi nerede bulabilirim: Oleg Mazurov'un web sitesi her şeyi açıklıyor veya daha fazla bilgi için bağlantılar sağlıyor:

3. Herhangi bir sınır koşulu kontrolü var mı? Hayır. Robot kolum geçersiz bir xyz koordinatından geçirildiğinde, kedi esnemesi gibi bu komik türde kavisli bir hareket yapıyor. Oleg'in kol hareketlerini programlamak için bir USB kullanan en son programında bazı kontroller yaptığına inanıyorum. Videosuna bakın ve en son koduna bağlantı verin.

4. Kodun temizlenmesi gerekir ve mikrosaniye kodu ortadan kaldırılabilir.

Önerilen: