Mündəricat:

6 DOF Robotik Qolun XYZ Yerləşdirilməsi üçün Arduino Uno'dan istifadə: 4 addım
6 DOF Robotik Qolun XYZ Yerləşdirilməsi üçün Arduino Uno'dan istifadə: 4 addım

Video: 6 DOF Robotik Qolun XYZ Yerləşdirilməsi üçün Arduino Uno'dan istifadə: 4 addım

Video: 6 DOF Robotik Qolun XYZ Yerləşdirilməsi üçün Arduino Uno'dan istifadə: 4 addım
Video: Как-то в носе прочищая... ► 3 Прохождение Resident Evil Code: Veronica (PS2) 2024, Noyabr
Anonim
Image
Image

Bu layihə, XYZ tərs kinematik mövqeləşdirmə təmin etmək üçün qısa və nisbətən asan bir Arduino eskizini tətbiq etməkdir. 6 servo robot qolu qurmuşdum, amma onu işə salmaq üçün proqram tapmağa gəldikdə, SSC-32 (U) kimi xüsusi servo qalxanlarda işləyən xüsusi proqramlar və ya digər proqram və tətbiqlər istisna olmaqla çox şey yox idi. qolu ilə qurmaq və ünsiyyət qurmaq çətindir. Sonra Oleq Mazurovun ən mükəmməl "Arduino üzərindəki Robotik Qol Tərs Kinematikası" nı tapdım, burada sadə Arduino eskizində tərs kinematik tətbiq etdi.

Kodunu uyğunlaşdırmaq üçün iki dəyişiklik etdim:

1. Xüsusi servo qalxan kitabxanasının yerinə VarSpeedServo kitabxanasını istifadə etdim, çünki o zaman servoların sürətini idarə edə bildim və onun istifadə etdiyi servo qalxanından istifadə etməyəcəyəm. Burada verilən kodu işə salmağı düşünən hər kəs üçün, robo qolunuzun hərəkətini yavaşlatmaq üçün servo.h kitabxanasından deyil, bu VarSpeedServo kitabxanasından istifadə etməyi məsləhət görürəm və ya qolun sizi gözlənilmədən itələyəcəyini görə bilərsiniz. üz və ya daha pis, çünki tam servo sürətlə hərəkət edəcək.

2. Servoları Arduino Uno -ya bağlamaq üçün sadə bir sensor/servo qalxanı istifadə edirəm, ancaq Arduino sancaqlarından istifadə etdiyi üçün xüsusi servo kitabxana tələb etmir. Yalnız bir neçə dollara başa gəlir, lakin tələb olunmur. Arduino ilə servoların gözəl bir təmiz bağlantısı təmin edir. Və indi heç vaxt Arduino Uno -nun sərtləşdirilmiş servolarına qayıtmayacağam. Bu sensor/servo qalxandan istifadə edirsinizsə, aşağıda təsvir edəcəyim kiçik bir dəyişiklik etməlisiniz.

Kod əla işləyir və x, y, x və sürət parametrlərini ötürdüyünüz bir funksiyadan istifadə edərək qolu idarə etməyə imkan verir. Misal üçün:

set_arm (0, 240, 100, 0, 20); // parametrləri (x, y, z, tutma açısı, servo sürəti)

gecikmə (3000); // qolun bu yerə keçməsinə icazə vermək üçün gecikmə tələb olunur

Daha sadə ola bilməzdi. Aşağıdakı eskizi daxil edəcəyəm.

Oleqin videosu burada: Arduino və USB Mouse ilə Robotik Qolun İdarə Edilməsi

Oleqin orijinal proqramı, təsvirləri və mənbələri: Arduino Uno üçün Oleqin Ters Kinematikası

Rutinin arxasındakı bütün riyaziyyatı başa düşmürəm, amma ən gözəl tərəfi odur ki, kodu istifadə etmək lazım deyil. Ümid edirəm sınayacaqsınız.

Addım 1: Avadanlıq dəyişiklikləri

Avadanlıq Dəyişiklikləri
Avadanlıq Dəyişiklikləri

1. Tələb olunan tək şey servolarınızın fiziki olaraq servolarınızın montajını geri çevirməyinizi tələb edə biləcək gözlənilən istiqamətlərə çevrilməsidir. Baza, çiyin, dirsək və bilək servoları üçün gözlənilən servo istiqamətini görmək üçün bu səhifəyə keçin:

2. İstifadə etdiyim sensor qalxanından istifadə edirsinizsə, bunun üçün bir şey etməlisiniz: 5v -ni qalxandan Arduino Uno -ya bağlayan pimi Uno lövhəsinə qoşulmaması üçün yoldan kənarda əymək. Arduino Uno -nu yox, yalnız servolarınızı gücləndirmək üçün qalxandakı xarici gərginliyi istifadə etmək istəyirsiniz və ya Uno -nu məhv edə bilər, bilirəm ki, xarici gərginliyim 5 voltdan çox deyil, 6 volt olduqda iki Uno lövhəsini yandırmışam. servolarınızı gücləndirmək üçün 5v -dən yuxarı güc istifadə edin, ancaq xarici gərginliyiniz 5 voltdan yüksəkdirsə, heç bir 5 voltlu sensoru qalxana qoşmayın, yoxsa qızardılacaq.

Addım 2: VarSpeedServo Kitabxanasını yükləyin

Standart arduino servo kitabxanasını əvəz edən bu kitabxanadan istifadə etməlisiniz, çünki servo yazma ifadəsinə servo sürətini ötürməyə imkan verir. Kitabxana burada yerləşir:

VarSpeedServo Kitabxanası

Yalnız zip düyməsini istifadə edə, zip faylını yükləyə və sonra Arduino IDE ilə quraşdıra bilərsiniz. Proqramınızda əmr quraşdırıldıqdan sonra belə olacaq: servo.write (100, 20);

Birinci parametr bucaq, ikincisi isə servonun 0 -dan 255 -ə qədər sürəti (tam sürət).

Addım 3: Bu eskizi işə salın

Budur rəqabət proqramı. Robot qol ölçüləriniz üçün bir neçə parametr dəyişdirməlisiniz:

1. BASE_HGT, HUMERUS, ULNA, GRIPPER uzunluqları millimetrdə.

2. Servo pin nömrələrinizi daxil edin

3. Qoşma ifadələrinə servo min və max daxil edin.

4. Sonra test üçün sadə bir set_arm () əmrini və sonra sıfır_x (), xətt () və dairə () funksiyalarını sınayın. Qolunuza və öz əlinizə zərər verməmək üçün bu funksiyaları ilk dəfə işlədərkən servo sürətinizin aşağı olduğundan əmin olun.

Uğurlar.

#VarSpeedServo.h daxil edin

/ * AL5D qolu üçün servo idarəetmə */

/ * Kol ölçüləri (mm) */

#define BASE_HGT 90 // baza hündürlüyü

#define HUMERUS 100 // çiyin-dirsək "sümüyü"

#define ULNA 135 // dirsəkdən biləyə "sümük"

#define GRIPPER 200 // tutucu (ağır vəzifəli bilək dönmə mexanizmi daxil olmaqla) uzunluğu"

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

/ * Servo adları/nömrələri *

* Əsas servo HS-485HB */

#BAS_SERVO 4 təyin edin

/ * Çiyin Servo HS-5745-MG */

#SHL_SERVO 5 -i təyin edin

/ * Dirsək Servo HS-5745-MG */

#ELB_SERVO 6 təyin edin

/ * Bilək servosu HS-645MG */

#təyin WRI_SERVO 7

/ * Bilək dönmə servosu HS-485HB */

#müəyyən WRO_SERVO 8

/ * Tutucu servo HS-422 */

#təyin GRI_SERVO 9

/ * əvvəlcədən hesablamalar */

float hum_sq = HUMERUS*HUMERUS;

float uln_sq = ULNA*ULNA;

int servoSPeed = 10;

// ServoShield servoları; // ServoShield obyekti

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

int loopCounter = 0;

int pulseWidth = 6.6;

int microsecondsToDegrees;

boş quraşdırma ()

{

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);

gecikmə (5500);

//servos.start (); // Servo qalxanı işə salın

servo_park ();

gecikmə (4000);

Serial.begin (9600);

Serial.println ("Başlat");

}

boşluq döngəsi ()

{

loopCounter += 1;

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

// gecikmə (7000);

// sıfır_x ();

// xətt ();

// dairə ();

gecikmə (4000);

if (loopCounter> 1) {

servo_park ();

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

gecikmə (5000);

çıxış (0); } // proqramı durdur - davam etmək üçün sıfırla vurun

// çıxmaq (0);

}

/ * tərs kinematikdən istifadə edərək qol yerləşdirmə qaydası */

/* z hündürlükdür, y baza mərkəzindən kənara olan məsafədir, x yan -yana. y, z yalnız müsbət ola bilər */

// void set_arm (uint16_t x, uint16_t y, uint16_t z, uint16_t grip_angle)

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

{

float grip_angle_r = radians (grip_angle_d); // hesablamalarda istifadə üçün radianda tutma bucağı

/ * Əsas açı və x, y koordinatlarından radial məsafə */

float bas_angle_r = atan2 (x, y);

float rdist = sqrt ((x * x) + (y * y));

/ * rdist qol üçün koordinatdır */

y = rdist;

/ * Tutuş açıları nəzərə alınmaqla tutma sapmaları */

float grip_off_z = (günah (grip_angle_r)) * TUTUCU;

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

/ * Bilək mövqeyi */

float wrist_z = (z - grip_off_z) - BASE_HGT;

float bilək_y = y - grip_off_y;

/ * Çiyin bilək məsafəsi (AKA sw) */

float s_w = (bilək_z * bilək_z) + (bilək_y * bilək_y);

float s_w_sqrt = sqrt (s_w);

/ * s_w yerə açı */

float a1 = atan2 (bilək_z, bilək_y);

/ * humerusa s_w bucağı */

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

/ * çiyin açısı */

float shl_angle_r = a1 + a2;

float shl_angle_d = dərəcə (shl_angle_r);

/ * dirsək açısı */

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

üzmək elb_angle_d = dərəcə (elb_angle_r);

üzmək elb_angle_dn = - (180.0 - elb_angle_d);

/ * bilək açısı */

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/ * Servo pulsları */

float bas_servopulse = 1500.0 - ((dərəcə (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 tərəfindən 2018/2/11 tarixində yeniləndi - Mən artını mənfi olaraq dəyişdim - bu kodun əvvəllər hər kəs üçün necə işlədiyindən əmin deyiləm. Dirsək servosu yuxarı deyil, aşağıya baxaraq 0 dərəcə quraşdırılmış ola bilər.

/ * Servo təyin edin */

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

microsecondsToDegrees = xəritə (ftl (bas_servopulse), 544, 2400, 0, 180);

servo1.write (microsecondsToDegrees, servoSpeed); // servo sürətini təyin etmək üçün bu funksiyadan istifadə edin //

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

microsecondsToDegrees = xəritə (ftl (shl_servopulse), 544, 2400, 0, 180);

servo2.write (microsecondsToDegrees, servoSpeed);

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

microsecondsToDegrees = xəritə (ftl (elb_servopulse), 544, 2400, 0, 180);

servo3.write (microsecondsToDegrees, servoSpeed);

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

microsecondsToDegrees = xəritə (ftl (wri_servopulse), 544, 2400, 0, 180);

servo4.write (microsecondsToDegrees, servoSpeed);

}

/ * servoları park vəziyyətinə keçirin */

boş 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);

qayıtmaq;

}

boş sıfır_x ()

{

üçün (cüt yaxis = 250.0; yaxis <400.0; yaxis += 1) {

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

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

gecikmə (10);

}

üçün (cüt yaxis = 400.0; yaxis> 250.0; yaxis -= 1) {

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

gecikmə (10);

}

}

/ * qolunu düz bir xəttdə hərəkət etdirir */

boşluq xətti ()

{

üçün (ikiqat xaxis = -100.0; xaxis <100.0; xaxis += 0.5) {

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

gecikmə (10);

}

üçün (float xaxis = 100.0; xaxis> -100.0; xaxis -= 0.5) {

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

gecikmə (10);

}

}

boşluq dairəsi ()

{

#RADIUS 50.0 təyin edin

// üzmə açısı = 0;

float zaxis, yaxis;

üçün (float açısı = 0,0; bucaq <360,0; bucaq += 1,0) {

yaxis = RADIUS * sin (radian (bucaq)) + 300;

zaxis = RADIUS * cos (radian (bucaq)) + 200;

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

gecikmə (10);

}

}

Addım 4: Faktlar, Məsələlər və bənzəri…

Faktlar, Məsələlər və bənzəri…
Faktlar, Məsələlər və bənzəri…

1. Mən dairəni () alt proqramını işlədərkən robotum bir dairədən daha çox elips şəklində hərəkət edir. Düşünürəm ki, buna səbəb servolarımın kalibrlənməməsidir. Onlardan birini sınadım və 1500 mikrosaniya 90 dərəcə ilə eyni deyildi. Bunun üzərində çalışaraq bir həll tapmağa çalışacağıq. Alqoritmdə səhv bir şey olduğuna inanmayın, əksinə parametrlərimlə. 2018/2/11 yeniləmə - bunun orijinal koddakı səhvdən qaynaqlandığını kəşf etdim. Proqramının necə işlədiyini görmürəm Sabit kod bundan istifadə edir: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (orijinal kod əlavə edildi)

2. Set_arm () funksiyasının necə işlədiyinə dair daha çox məlumatı haradan tapa bilərəm: Oleq Mazurovun veb saytı hər şeyi izah edir və ya daha çox məlumat üçün bağlantılar təqdim edir:

3. Hər hansı bir sərhəd şərtinin yoxlanılması varmı? Xeyr. Robot qolum etibarsız bir xyz koordinatından keçəndə, uzanan bir pişik kimi bu gülməli arıqlama hərəkətini edir. İnanıram ki, Oleq, qol hərəkətlərini proqramlaşdırmaq üçün USB istifadə edən ən son proqramını yoxlayır. Videoya baxın və son koduna keçid edin.

4. Kodu təmizləmək lazımdır və mikrosaniyə kodu yox etmək olar.

Tövsiyə: