Turinys:

„Arduino Uno“naudojimas 6 DOF robotų rankos XYZ pozicionavimui: 4 žingsniai
„Arduino Uno“naudojimas 6 DOF robotų rankos XYZ pozicionavimui: 4 žingsniai

Video: „Arduino Uno“naudojimas 6 DOF robotų rankos XYZ pozicionavimui: 4 žingsniai

Video: „Arduino Uno“naudojimas 6 DOF robotų rankos XYZ pozicionavimui: 4 žingsniai
Video: How to Build Your Own Robotic Arm with Arduino Braccio #arduino #electronics #electrician #robot #ai 2024, Lapkritis
Anonim
Image
Image

Šis projektas yra apie trumpo ir palyginti lengvo „Arduino“eskizo įgyvendinimą, kad būtų galima nustatyti XYZ atvirkštinę kinematinę padėtį. Aš sukūriau 6 servo robotų ranką, bet kai reikėjo rasti programinę įrangą, kad ją paleisti, ten nebuvo daug, išskyrus pasirinktines programas, veikiančias pagal pasirinktinius servo skydus, tokius kaip SSC-32 (U), arba kitas programas ir programas, kurios buvo sudėtinga įdiegti ir bendrauti su ranka. Tada radau geriausią Olego Mazurovo „Robotų rankos atvirkštinę kinematiką„ Arduino ““, kur jis įgyvendino atvirkštinę kinematiką paprastu „Arduino“eskizu.

Aš padariau du pakeitimus, kad pritaikyčiau jo kodą:

1. Aš naudoju „VarSpeedServo“biblioteką vietoj jo pasirinktinio servo skydo bibliotekos, nes tada galėjau valdyti servo greitį ir man nereikėjo naudoti jo naudojamo servo skydo. Tiems, kurie svarsto, ar paleisti čia pateiktą kodą, rekomenduoju naudoti šią „VarSpeedServo“biblioteką, o ne servo.h biblioteką, kad kūrimo metu galėtumėte sulėtinti robotų rankų judėjimą arba galite pastebėti, kad ranka netikėtai jus įstums. veidas arba dar blogiau, nes jis judės visu servo greičiu.

2. Aš naudoju paprastą jutiklį/servo skydą, kad prijungčiau servus prie „Arduino Uno“, tačiau tam nereikia jokios specialios servo bibliotekos, nes ji naudoja tik „Arduino“kaiščius. Tai kainuoja tik keletą dolerių, bet tai nėra būtina. Tai užtikrina puikų švarų servo prijungimą prie „Arduino“. Ir dabar niekada negrįšiu prie laidinių „Arduino Uno“servo. Jei naudojate šį jutiklį/servo skydą, turite atlikti vieną nedidelį pakeitimą, kurį aprašysiu toliau.

Kodas puikiai veikia ir leidžia valdyti ranką naudojant vieną funkciją, kurioje perduodami x, y, x ir greičio parametrai. Pavyzdžiui:

„set_arm“(0, 240, 100, 0, 20); // parametrai yra (x, y, z, griebtuvo kampas, servo greitis)

vėlavimas (3000); // reikia atidėti, kad įjungimo laikas galėtų pereiti į šią vietą

Negali būti paprasčiau. Žemiau pridėsiu eskizą.

Olego vaizdo įrašas yra čia: Robotų rankos valdymas naudojant „Arduino“ir USB pelę

Originali Olego programa, aprašymai ir ištekliai: Olego atvirkštinė kinematika, skirta „Arduino Uno“

Aš nesuprantu visos įprastos matematikos, bet malonu tai, kad jums nereikia naudoti kodo. Tikiuosi, kad pabandysite.

1 žingsnis: Aparatūros modifikacijos

Techninės įrangos modifikacijos
Techninės įrangos modifikacijos

1. Vienintelis dalykas, kurio reikia, yra tai, kad jūsų servo sistema pasuktų numatytomis kryptimis, dėl kurių gali tekti fiziškai pakeisti savo servo montavimą. Eikite į šį puslapį, norėdami pamatyti numatomą pagrindo, peties, alkūnės ir riešo servo servo kryptį:

2. Jei naudojate mano naudojamą jutiklio skydą, turite padaryti vieną dalyką: sulenkite kaištį, jungiantį 5v nuo skydo prie „Arduino Uno“, kad jis neprisijungtų prie „Uno“plokštės. Norite naudoti išorinę skydo įtampą, kad maitintumėte tik savo servus, o ne „Arduino Uno“, nes tai gali sunaikinti „Uno“, aš žinau, kad sudeginau dvi „Uno“plokštes, kai išorinė įtampa buvo 6 voltai, o ne 5. Tai leidžia jums Norėdami naudoti didesnę nei 5 V įtampą savo servams, bet jei jūsų išorinė įtampa yra didesnė nei 5 voltai, neprijunkite jokių 5 voltų jutiklių prie skydo, kitaip jie bus kepti.

2 veiksmas: atsisiųskite „VarSpeedServo“biblioteką

Turite naudoti šią biblioteką, kuri pakeičia standartinę arduino servo biblioteką, nes ji leidžia perduoti servo greitį į servo rašymo pareiškimą. Biblioteka yra čia:

„VarSpeedServo“biblioteka

Galite tiesiog naudoti „zip“mygtuką, atsisiųsti ZIP failą ir įdiegti jį naudodami „Arduino IDE“. Įdiegus komandą jūsų programoje atrodys taip: servo.write (100, 20);

Pirmasis parametras yra kampas, o antrasis - servo greitis nuo 0 iki 255 (visu greičiu).

3 žingsnis: paleiskite šį eskizą

Čia yra varžybų programa. Turite pakeisti keletą savo robotų rankos parametrų:

1. BASE_HGT, HUMERUS, ULNA, GRIPPER ilgiai milimetrais.

2. Įveskite savo servo kaiščio numerius

3. Pridėti teiginius įveskite servo min ir max.

4. Tada išbandykite paprastą komandą set_arm (), o tada nulio_x (), line () ir apskritimo () funkcijas. Pirmą kartą paleisdami šias funkcijas įsitikinkite, kad jūsų servo greitis yra mažas, kad nepažeistumėte rankos ir rankos.

Sėkmės.

#include VarSpeedServo.h

/ * Servo valdymas AL5D rankai */

/ * Rankos matmenys (mm) */

#define BASE_HGT 90 // pagrindo aukštis

#define HUMERUS 100 // „nuo peties iki alkūnės“kaulas

#define ULNA 135 // „alkūnės iki riešo“kaulas

#define GRIPPER 200 // griebtuvas (įskaitant sunkų riešo sukimo mechanizmą) ilgis"

#define ftl (x) ((x)> = 0? (ilgas) ((x) +0,5):(ilgas) ((x) -0,5)) // float to long conversion

/ * Servo pavadinimai/numeriai *

* Pagrindinė servo sistema HS-485HB */

#define BAS_SERVO 4

/ * Pečių servo HS-5745-MG */

#define SHL_SERVO 5

/ * Alkūnės servo HS-5745-MG */

#define ELB_SERVO 6

/ * Riešo servo HS-645MG */

#define WRI_SERVO 7

/ * Riešo pasukimo servo HS-485HB */

#define WRO_SERVO 8

/ * Gripper servo HS-422 */

#define GRI_SERVO 9

/ * išankstiniai skaičiavimai */

plūdė hum_sq = HUMERUS*HUMERUS;

plūdė uln_sq = ULNA*ULNA;

int servoSPeed = 10;

// ServoShield servos; // ServoShield objektas

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

int loopCounter = 0;

int pulseWidth = 6,6;

int mikrosekundėsToDegrees;

negaliojanti sąranka ()

{

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

vėlavimas (5500);

//servos.start (); // Paleiskite servo skydą

servo_park ();

vėlavimas (4000);

Serial.begin (9600);

Serial.println („Pradėti“);

}

tuštumos kilpa ()

{

loopCounter += 1;

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

// uždelsimas (7000);

// nulis_x ();

// line ();

// apskritimas ();

vėlavimas (4000);

if (loopCounter> 1) {

servo_park ();

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

vėlavimas (5000);

išėjimas (0); } // pristabdyti programą - norėdami tęsti, paspauskite „Reset“

// išeiti (0);

}

/ * rankos padėties nustatymo tvarka, naudojant atvirkštinę kinematiką */

/* z yra aukštis, y yra atstumas nuo pagrindo centro, x yra iš vienos pusės į kitą. y, z gali būti tik teigiamas */

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

{

plūdė grip_angle_r = radianai (grip_angle_d); // sukibimo kampas radianais, naudojamas skaičiavimams

/ * Bazinis kampas ir radialinis atstumas nuo x, y koordinačių */

plūdė bas_angle_r = atan2 (x, y);

plūdė rdist = sqrt ((x * x) + (y * y));

/ * rdist yra y rankos koordinatė */

y = rdist;

/ * Rankenos poslinkiai apskaičiuoti pagal sukibimo kampą */

plūdė grip_off_z = (sin (grip_angle_r)) * GRIPPER;

plūdė grip_off_y = (cos (grip_angle_r)) * GRIPPER;

/ * Riešo padėtis */

plūdė riešo_z = (z - grip_off_z) - BASE_HGT;

plūdė riešo_y = y - grip_off_y;

/ * Atstumas nuo peties iki riešo (AKA sw) */

plūdė s_w = (riešo_ž * riešo_z) + (riešo_y * riešo_y);

plūdė s_w_sqrt = sqrt (s_w);

/ * s_w kampas į žemę */

plūdė a1 = atan2 (riešas_z, riešas_y);

/ * s_w kampas iki žastikaulio */

plūdė a2 = acos ((((hum_sq - uln_sq) + s_w) / (2 * HUMERUS * s_w_sqrt));

/ * pečių kampas */

plūdė shl_angle_r = a1 + a2;

plūdė shl_angle_d = laipsniai (shl_angle_r);

/ * alkūnės kampas */

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

plūdė elb_angle_d = laipsniai (elb_angle_r);

plūdė elb_angle_dn = - (180,0 - elb_angle_d);

/ * riešo kampas */

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/ * Servo impulsai */

plūdė bas_servopulse = 1500,0 - ((laipsniai (bas_angle_r)) * pulseWidth);

plūdė shl_servopulse = 1500.0 + ((shl_angle_d - 90.0) * pulseWidth);

plūdė 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); // atnaujinta 2018/2/11 pagal jimrd - pakeičiau pliusą į minusą - nesu tikras, kaip šis kodas anksčiau veikė. Gali būti, kad alkūninis servo buvo sumontuotas 0 laipsnių kampu žemyn, o ne aukštyn.

/ * Nustatyti servus */

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

mikrosekundėsToDegrees = žemėlapis (ftl (bas_servopulse), 544, 2400, 0, 180);

servo1.write (mikrosekundėsToDegrees, servoSpeed); // naudokite šią funkciją, kad galėtumėte nustatyti servo greitį //

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

mikrosekundėsToDegrees = žemėlapis (ftl (shl_servopulse), 544, 2400, 0, 180);

servo2.write (mikrosekundėsToDegrees, servoSpeed);

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

mikrosekundėsToDegrees = žemėlapis (ftl (elb_servopulse), 544, 2400, 0, 180);

servo3.write (mikrosekundėsToDegrees, servoSpeed);

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

mikrosekundėsToDegrees = žemėlapis (ftl (wri_servopulse), 544, 2400, 0, 180);

servo4.write (mikrosekundėsToDegrees, servoSpeed);

}

/ * perkelkite servo į stovėjimo padėtį */

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

grįžti;

}

void zero_x ()

{

už (dviguba ašis = 250,0; ašis <400,0; ašis += 1) {

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

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

vėlavimas (10);

}

(dviguba ašis = 400,0; ašis> 250,0; ašis -= 1) {

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

vėlavimas (10);

}

}

/ * judina ranką tiesia linija */

tuščia eilutė ()

{

(dviguba ašis = -100,0; ašis <100,0; ašis += 0,5) {

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

vėlavimas (10);

}

už (plūdė xaxis = 100.0; xaxis> -100.0; xaxis -= 0.5) {

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

vėlavimas (10);

}

}

tuščias ratas ()

{

#define RADIUS 50.0

// plūdės kampas = 0;

plūdė zaxis, yaxis;

už (plūdės kampas = 0,0; kampas <360,0; kampas += 1,0) {

yaxis = RADIUS * sin (radianai (kampas)) + 300;

zaxis = RADIUS * cos (radianai (kampas)) + 200;

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

vėlavimas (10);

}

}

4 žingsnis: faktai, problemos ir panašiai …

Faktai, problemos ir panašiai…
Faktai, problemos ir panašiai…

1. Kai paleidžiu apskritimo () paprogramę, mano robotas juda daugiau elipsės formos nei apskritimo. Manau, kad taip yra todėl, kad mano servos nėra sukalibruotos. Aš išbandžiau vieną iš jų ir 1500 mikrosekundžių nebuvo tas pats kaip 90 laipsnių. Dirbs tai ir bandys rasti sprendimą. Netikėkite, kad kažkas negerai su algoritmu, o su mano nustatymais. Atnaujinimas 2018/2/11 - ką tik sužinojau, kad tai įvyko dėl klaidos pradiniame kode. Nematau, kaip jo programa veikė Fiksuotas kodas naudojant šį: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (pridėtas originalus kodas)

2. Kur galiu rasti daugiau informacijos apie tai, kaip veikia funkcija set_arm (): Olego Mazurovo svetainėje viskas paaiškinta arba pateikiamos nuorodos, kad gautumėte daugiau informacijos:

3. Ar yra koks nors ribinių sąlygų tikrinimas? Ne. Kai mano roboto ranka perduodama netinkama xyz koordinatė, ji atlieka tokį juokingą lankstymo judesį kaip katė. Manau, kad Olegas tikrina savo naujausią programą, kuri naudoja USB jungtį rankos judesiams programuoti. Peržiūrėkite jo vaizdo įrašą ir nuorodą į naujausią jo kodą.

4. Reikia išvalyti kodą ir panaikinti mikrosekundinį kodą.

Rekomenduojamas: