Sadržaj:

Korištenje Arduino Uno za XYZ pozicioniranje 6 DOF robotske ruke: 4 koraka
Korištenje Arduino Uno za XYZ pozicioniranje 6 DOF robotske ruke: 4 koraka

Video: Korištenje Arduino Uno za XYZ pozicioniranje 6 DOF robotske ruke: 4 koraka

Video: Korištenje Arduino Uno za XYZ pozicioniranje 6 DOF robotske ruke: 4 koraka
Video: [Audio Fixed] Robojax Arduino Course: What is Arduino? Lesson 00 2024, Decembar
Anonim
Image
Image

Ovaj projekt govori o implementaciji kratke i relativno jednostavne Arduino skice za pružanje XYZ inverznog kinematičkog pozicioniranja. Izgradio sam 6 servo robotsku ruku, ali što se tiče pronalaženja softvera za njeno pokretanje, nije bilo puno toga osim prilagođenih programa koji se izvode na prilagođenim servo štitovima poput SSC-32 (U) ili drugih programa i aplikacija koji su bili komplikovano instalirati i komunicirati s rukom. Tada sam pronašao najodličniju "Inverznu kinematiku robotske ruke na Arduinu" Olega Mazurova gdje je implementirao inverznu kinematiku u jednostavnu Arduino skicu.

Napravio sam dvije izmjene kako bih prilagodio njegov kod:

1. Koristio sam VarSpeedServo biblioteku umjesto njegove prilagođene biblioteke servo štita jer sam tada mogao kontrolirati brzinu servomotora i ne bih morao koristiti servo štit koji je on koristio. Za sve koji razmišljaju o pokretanju ovdje navedenog koda, preporučujem vam da koristite ovu biblioteku VarSpeedServo, a ne biblioteku servo.h, tako da možete usporiti kretanje robotske ruke tokom razvoja ili ćete otkriti da će vas ruka neočekivano ubosti u lice ili još gore jer će se kretati punom servo brzinom.

2. Koristim jednostavan senzor/servo štit za spajanje servosistema na Arduino Uno, ali ne zahtijeva posebnu servo biblioteku jer koristi samo Arduino pinove. Košta samo nekoliko dolara, ali nije potrebno. Omogućuje lijepu čistu vezu servosistema s Arduinom. I nikad se više neću vratiti na ožičene servo sisteme za Arduino Uno. Ako koristite ovaj senzor/servo štit, morate napraviti jednu manju izmjenu koju ću dolje opisati.

Kod odlično funkcionira i omogućuje vam rukovanje rukom pomoću jedne funkcije u kojoj prosljeđujete parametre x, y, x i brzinu. Na primjer:

set_arm (0, 240, 100, 0, 20); // parametri su (x, y, z, kut hvataljke, servo brzina)

kašnjenje (3000); // potrebno je kašnjenje kako bi se omogućilo vrijeme prelaska na ovu lokaciju

Ne može biti jednostavnije. Skicu ću uključiti u nastavku.

Olegov video zapis je ovdje: Upravljanje robotskom rukom pomoću Arduina i USB miša

Olegov originalni program, opisi i izvori: Olegova inverzna kinematika za Arduino Uno

Ne razumijem svu matematiku koja stoji iza rutine, ali lijepo je to što ne morate koristiti kôd. Nadam se da ćete pokušati.

Korak 1: Promjene hardvera

Modifikacije hardvera
Modifikacije hardvera

1. Jedino što je potrebno je da se vaš servo okreće u očekivanim smjerovima što bi moglo zahtijevati da fizički obrnete montažu servomotora. Idite na ovu stranicu da vidite očekivani servo smjer za baze, ramena, lakat i zglobove:

2. Ako koristite štitnik senzora koji ja koristim, morate mu učiniti jednu stvar: savijte pin koji povezuje 5v od štita sa Arduino Uno s puta tako da se ne poveže s Uno pločom. Želite koristiti vanjski napon na štitu za napajanje samo vaših servo -a, a ne Arduino Uno ili bi mogao uništiti Uno, znam da sam spalio dvije Uno ploče kada je moj vanjski napon bio 6 volti, a ne 5. To vam omogućuje koristiti više od 5v za napajanje servo -a, ali ako je vaš vanjski napon veći od 5 volti, nemojte priključivati nikakve 5 -voltne senzore na štit ili će se spržiti.

Korak 2: Preuzmite biblioteku VarSpeedServo

Morate koristiti ovu biblioteku koja zamjenjuje standardnu arduino servo biblioteku jer vam omogućuje da prenesete brzinu servo u izraz servo zapisa. Biblioteka se nalazi ovdje:

Biblioteka VarSpeedServo

Možete jednostavno koristiti zip dugme, preuzeti zip datoteku, a zatim je instalirati sa Arduino IDE -om. Jednom instalirana naredba u vašem programu izgledat će ovako: servo.write (100, 20);

Prvi parametar je kut, a drugi brzina servo od 0 do 255 (puna brzina).

Korak 3: Pokrenite ovu skicu

Evo takmičarskog programa. Morate izmijeniti nekoliko parametara za dimenzije robotske ruke:

1. BASE_HGT, HUMERUS, ULNA, GRIPPER dužine u milimetrima.

2. Unesite brojeve servo pinova

3. Unesite servo min i max u naredbe za dodavanje.

4. Zatim isprobajte jednostavnu naredbu set_arm (), a zatim funkcije zero_x (), line () i circle () za testiranje. Budite sigurni da je vaša servo brzina mala pri prvom pokretanju ovih funkcija kako biste spriječili oštećenje ruke i vlastite ruke.

Sretno.

#include VarSpeedServo.h

/ * Servo kontrola za AL5D ruku */

/ * Dimenzije ruke (mm) */

#define BASE_HGT 90 // osnovna visina

#define HUMERUS 100 // "kost" od ramena do lakta

#define ULNA 135 // "kost" od lakta do zgloba

#define GRIPPER 200 // hvataljka (uključujući mehanizam za rotiranje zgloba za teške uslove rada) dužina"

#define ftl (x) ((x)> = 0? (long) ((x) +0.5):(long) ((x) -0.5)) // konverzija s float na long

/ * Servo nazivi/brojevi *

* Osnovni servo HS-485HB */

#define BAS_SERVO 4

/ * Servo za ramena HS-5745-MG */

#define SHL_SERVO 5

/ * Servo za koljena HS-5745-MG */

#define ELB_SERVO 6

/ * Servo za zglob HS-645MG */

#define WRI_SERVO 7

/ * Servo za okretanje zgloba HS-485HB */

#define WRO_SERVO 8

/ * Servo hvataljke HS-422 */

#define GRI_SERVO 9

/ * predračuni */

float hum_sq = HUMERUS*HUMERUS;

float uln_sq = ULNA*ULNA;

int servoSPeed = 10;

// ServoShield servo; // Objekt ServoShield

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

int loopCounter = 0;

int pulseWidth = 6,6;

int mikrosekundeToDegrees;

void setup ()

{

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

kašnjenje (5500);

//servos.start (); // Pokretanje servo štita

servo_park ();

kašnjenje (4000);

Serial.begin (9600);

Serial.println ("Start");

}

void loop ()

{

loopCounter += 1;

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

// kašnjenje (7000);

// nula_x ();

// linija ();

// krug ();

kašnjenje (4000);

if (loopCounter> 1) {

servo_park ();

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

kašnjenje (5000);

izlaz (0); } // pauziranje programa - pritisnite reset za nastavak

// izlaz (0);

}

/ * rutina pozicioniranja ruke koja koristi inverznu kinematiku */

/* z je visina, y je udaljenost od središta baze prema van, x je strana na stranu. y, z može biti samo pozitivno */

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

{

plovak grip_angle_r = radijani (grip_angle_d); // kut zahvata u radijanima za upotrebu u proračunima

/ * Osnovni kut i radijalna udaljenost od x, y koordinata */

float bas_angle_r = atan2 (x, y);

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

/ * rdist je y koordinata za ruku */

y = rdist;

/ * Pomak gripa izračunat na osnovu kuta zahvata */

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

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

/ * Položaj zgloba */

float wrist_z = (z - grip_off_z) - BASE_HGT;

float wrist_y = y - grip_off_y;

/ * Rastojanje od ramena do zgloba (AKA sw) */

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

float s_w_sqrt = sqrt (s_w);

/ * s_w kut prema tlu */

float a1 = atan2 (wrist_z, wrist_y);

/ * kut s_w prema humerusu */

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

/ * ugao ramena */

float shl_angle_r = a1 + a2;

float shl_angle_d = stepeni (shl_angle_r);

/ * ugao lakta */

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

float elb_angle_d = stepeni (elb_angle_r);

float elb_angle_dn = - (180.0 - elb_angle_d);

/ * ugao zgloba */

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/ * Servo impulsi */

float bas_servopulse = 1500.0 - ((stepeni (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);

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

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

float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); // ažurirao 2018-11-11 od jimrd - Promijenio sam plus na minus - nisam siguran kako je ovaj kod radio za bilo koga prije. Moguće je da je servo koljena montiran s 0 stupnjeva prema dolje, a ne prema gore.

/ * Podesite servomotore */

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

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

servo1.write (microsecondsToDegrees, servoSpeed); // koristite ovu funkciju kako biste mogli postaviti brzinu serva //

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

}

/ * premjestite servo u položaj za parkiranje */

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

return;

}

void zero_x ()

{

za (dvostruki osi = 250,0; osi <400,0; osi += 1) {

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

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

kašnjenje (10);

}

za (dvostruki osi = 400,0; osi> 250,0; osi -= 1) {

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

kašnjenje (10);

}

}

/ * pomera ruku u pravoj liniji */

linija void ()

{

za (dvostruki osi = -100,0; osi <100,0; osi += 0,5) {

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

kašnjenje (10);

}

za (float xaxis = 100.0; xaxis> -100.0; xxx -= 0.5) {

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

kašnjenje (10);

}

}

praznina krug ()

{

#define RADIUS 50.0

// kut plutanja = 0;

plovak zaxis, yaxis;

for (kut plutanja = 0,0; kut <360,0; kut += 1,0) {

yaxis = RADIUS * sin (radijani (ugao)) + 300;

zaxis = RADIUS * cos (radijani (kut)) + 200;

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

kašnjenje (10);

}

}

Korak 4: Činjenice, problemi i slično…

Činjenice, problemi i slično…
Činjenice, problemi i slično…

1. Kad pokrenem podrutinu circle () moj robot se kreće više u eliptičnom obliku nego u krug. Mislim da je to zato što moji servo motori nisu kalibrirani. Testirao sam jednu od njih i 1500 mikrosekundi nije bilo isto što i 90 stepeni. Radit će na tome kako bi pokušao pronaći rješenje. Ne vjerujte da nešto nije u redu s algoritmom, već s mojim postavkama. Ažuriranje 2018/2/11 - upravo sam otkrio da je to zbog greške u izvornom kodu. Ne vidim kako je njegov program radio. Fiksni kod koristeći ovo: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (dodaje se originalni kod)

2. Gdje mogu pronaći više informacija o tome kako funkcionira funkcija set_arm (): Web stranica Olega Mazurova objašnjava sve ili nudi veze za više informacija:

3. Postoji li provjera graničnih uvjeta? Ne. Kada se mojoj robotskoj ruci doda pogrešna xyz koordinata, ona izvodi ovu smiješnu vrstu lukavog pokreta poput mačke koja se proteže. Vjerujem da Oleg provjerava svoj najnoviji program koji koristi USB za programiranje pokreta ruku. Pogledajte njegov video i povežite se s njegovim posljednjim kodom.

4. Kôd treba očistiti i mikrosekundni kôd se može ukloniti.

Preporučuje se: