Kazalo:

Uporaba Arduino Uno za XYZ pozicioniranje 6 DOF robotske roke: 4 koraki
Uporaba Arduino Uno za XYZ pozicioniranje 6 DOF robotske roke: 4 koraki

Video: Uporaba Arduino Uno za XYZ pozicioniranje 6 DOF robotske roke: 4 koraki

Video: Uporaba Arduino Uno za XYZ pozicioniranje 6 DOF robotske roke: 4 koraki
Video: Управление голым реле и управление им с помощью Arduino для нагрузки переменного / постоянного тока 2024, November
Anonim
Image
Image

Ta projekt je namenjen izvajanju kratke in razmeroma enostavne skice Arduino, ki zagotavlja inverzno kinematično pozicioniranje XYZ. Zgradil sem robotsko roko s šestimi servomotori, a ko sem prišel do iskanja programske opreme za njeno izvajanje, ni bilo veliko, razen programov po meri, ki se izvajajo na servo ščitih po meri, kot je SSC-32 (U), ali drugih programov in aplikacij, ki so bile zapleteno za namestitev in komunikacijo z roko. Potem sem našel najodličnejšo "Inverzno kinematiko robotske roke na Arduinu" Olega Mazurova, kjer je izvedel obratno kinematiko v preprosti skici Arduino.

Za prilagoditev njegove kode sem naredil dve spremembi:

1. Namesto knjižnice servo ščitov po meri sem uporabil knjižnico VarSpeedServo, ker sem potem lahko nadzoroval hitrost servomotorjev in mi ni bilo treba uporabljati servo ščita, ki ga je uporabljal. Za vsakogar, ki razmišlja o izvajanju tukaj navedene kode, priporočam, da namesto knjižnice servo.h uporabite to knjižnico VarSpeedServo, da boste lahko med razvojem upočasnili gibanje robotske roke ali pa boste ugotovili, da vas bo roka nepričakovano udarila obraz ali še huje, ker se bo premikal s polno hitrostjo servo.

2. Za priključitev servomotorjev na Arduino Uno uporabljam preprost senzor/servo ščit, vendar ne potrebuje posebne servo knjižnice, saj uporablja samo zatiče Arduino. Stane le nekaj dolarjev, ni pa nujno. Omogoča lepo čisto povezavo servomotorjev z Arduinom. In nikoli se ne bom vrnil na ožičene servomotorje na Arduino Uno. Če uporabljate ta senzor/servo ščit, morate narediti eno manjšo spremembo, ki jo bom opisal spodaj.

Koda deluje odlično in vam omogoča upravljanje roke z eno samo funkcijo, v kateri posredujete parametre x, y, x in hitrost. Na primer:

set_arm (0, 240, 100, 0, 20); // parametri so (x, y, z, kot prijemala, hitrost servo)

zamuda (3000); // zamuda je potrebna, da se čas roke premakne na to lokacijo

Ne bi moglo biti enostavnejše. Skico bom vključil spodaj.

Olegov videoposnetek je tukaj: Upravljanje robotske roke z Arduinom in USB miško

Olegov izvirni program, opisi in viri: Olegova inverzna kinematika za Arduino Uno

Ne razumem vse matematike za rutino, a lepo je, da vam kode ni treba uporabljati. Upam, da boste poskusili.

Korak: Spremembe strojne opreme

Spremembe strojne opreme
Spremembe strojne opreme

1. Edino, kar je potrebno, je, da se vaš servo zavije v pričakovanih smereh, zaradi česar morate fizično obrniti montažo servomotorjev. Pojdite na to stran, če si želite ogledati pričakovano smer servomotorja za podnožje, ramena, komolce in zapestje:

2. Če uporabljate ščit senzorja, ki ga uporabljam, morate narediti eno stvar: upognite zatič, ki povezuje 5v od ščita z Arduino Uno, tako da se ne poveže s ploščo Uno. Če želite uporabiti zunanjo napetost na ščitu, da napajate samo svoje servomotorje, ne Arduino Uno ali pa lahko uniči Uno, vem, saj sem zažgal dve plošči Uno, ko je bila moja zunanja napetost 6 voltov in ne 5. To vam omogoča za napajanje servomotorjev več kot 5V, če pa je vaša zunanja napetost višja od 5 voltov, ne priključite nobenih 5 -voltnih senzorjev na ščit, sicer bodo ocvrti.

Korak: Prenesite knjižnico VarSpeedServo

Uporabiti morate to knjižnico, ki nadomešča standardno servo knjižnico arduino, ker vam omogoča, da posredujete hitrost servo v stavek pisanja servo. Knjižnica se nahaja tukaj:

Knjižnica VarSpeedServo

Lahko preprosto uporabite gumb zip, prenesete datoteko zip in jo nato namestite z Arduino IDE. Ko je ukaz v vašem programu nameščen, bo izgledal tako: servo.write (100, 20);

Prvi parameter je kot, drugi pa hitrost servo od 0 do 255 (polna hitrost).

3. korak: Zaženite to skico

Tukaj je tekmovalni program. Za dimenzije robotske roke morate spremeniti nekaj parametrov:

1. BASE_HGT, HUMERUS, ULNA, GRIPPER dolžine v milimetrih.

2. Vnesite številke servo zatičev

3. Vnesite izjave min in max v priložene stavke.

4. Nato preizkusite preprost ukaz set_arm () in nato funkcije zero_x (), line () in krog () za testiranje. Ko prvič zaženete te funkcije, se prepričajte, da je vaša hitrost servo nizka, da preprečite poškodbe roke in svoje roke.

Vso srečo.

#include VarSpeedServo.h

/ * Servo krmiljenje za roko AL5D */

/ * Mere roke (mm) */

#define BASE_HGT 90 // osnovna višina

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

#define ULNA 135 // "kost" od komolca do zapestja

#define GRIPPER 200 // prijemalka (vključno z mehanizmom za vrtenje zapestja za težke obremenitve) dolžina"

#define ftl (x) ((x)> = 0? (long) ((x) +0,5):(long) ((x) -0,5)) // pretvorba iz lebdečega v dolgi

/ * Servo imena/številke *

* Osnovni servo HS-485HB */

#define BAS_SERVO 4

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

#define SHL_SERVO 5

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

#define ELB_SERVO 6

/ * Zapestni servo HS-645MG */

#define WRI_SERVO 7

/ * Servo zavrtite zapestje HS-485HB */

#define WRO_SERVO 8

/ * Servo prijemala HS-422 */

#define GRI_SERVO 9

/ * predračuni */

float hum_sq = HUMERUS*HUMERUS;

float uln_sq = ULNA*ULNA;

int servoSPeed = 10;

// ServoShield servomotorji; // Objekt ServoShield

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

int loopCounter = 0;

int pulseWidth = 6,6;

int mikrosekundeToDegrees;

void setup ()

{

servo1.priključek (BAS_SERVO, 544, 2400);

servo2.priključek (SHL_SERVO, 544, 2400);

servo3.priključek (ELB_SERVO, 544, 2400);

servo4.priključek (WRI_SERVO, 544, 2400);

servo5.priključek (WRO_SERVO, 544, 2400);

servo6.priključek (GRI_SERVO, 544, 2400);

zamuda (5500);

//servos.start (); // Zaženite servo zaščito

servo_park ();

zamuda (4000);

Serial.begin (9600);

Serial.println ("Start");

}

void loop ()

{

loopCounter += 1;

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

// zakasnitev (7000);

// nič_x ();

// vrstica ();

//krog();

zamuda (4000);

if (loopCounter> 1) {

servo_park ();

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

zamuda (5000);

izhod (0); } // začasno ustavi program - za nadaljevanje pritisnite ponastavitev

// izhod (0);

}

/ * rutinsko pozicioniranje roke z obratno kinematiko */

/* z je višina, y je razdalja od središča baze navzven, x je stran na stran. y, z je lahko 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)

{

float grip_angle_r = radiani (grip_angle_d); // kot oprijema v radianih za uporabo pri izračunih

/ * Osnovni kot in radialna razdalja od x, y koordinat */

float bas_angle_r = atan2 (x, y);

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

/ * rdist je y koordinata za roko */

y = rdist;

/ * Odmiki oprijema, izračunani na podlagi kota oprijema */

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

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

/ * Položaj zapestja */

float wrist_z = (z - grip_off_z) - BASE_HGT;

float wrist_y = y - grip_off_y;

/ * Razdalja med zapestjem in ramo (AKA sw) */

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

float s_w_sqrt = sqrt (s_w);

/ * s_w kot do tal */

float a1 = atan2 (wrist_z, wrist_y);

/ * kot s_w proti humerusu */

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

/ * kot ramena */

float shl_angle_r = a1 + a2;

float shl_angle_d = stopinje (shl_angle_r);

/ * kot komolca */

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

float elb_angle_d = stopinje (elb_angle_r);

plavajoči elb_angle_dn = - (180,0 - elb_angle_d);

/ * kot zapestja */

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/ * Servo impulzi */

float bas_servopulse = 1500,0 - ((stopinje (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);

// plavajoči wri_servopulse = 1500 + (wri_angle_d * pulseWidth);

// plavajoči wri_servopulse = 1500 + (wri_angle_d * pulseWidth);

float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); // posodobil Jimr - 2018/2/11 - spremenil sem plus v minus - nisem prepričan, kako je ta koda za koga prej delovala. Morda je bil servo komolec nameščen z 0 stopinjami navzdol in ne navzgor.

/ * Nastavite servomotorje */

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

mikrosekundeToDegrees = zemljevid (ftl (bas_servopulse), 544, 2400, 0, 180);

servo1.write (mikrosekunde do stopinj, servo hitrost); // uporabite to funkcijo, da nastavite hitrost servo //

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

mikrosekundeToDegrees = zemljevid (ftl (shl_servopulse), 544, 2400, 0, 180);

servo2.write (mikrosekunde do stopinj, servo hitrost);

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

mikrosekundeToDegrees = zemljevid (ftl (elb_servopulse), 544, 2400, 0, 180);

servo3.write (mikrosekunde do stopinj, servo hitrost);

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

mikrosekundeToDegrees = zemljevid (ftl (wri_servopulse), 544, 2400, 0, 180);

servo4.write (mikrosekunde do stopinj, servo hitrost);

}

/ * premaknite servomotorje v parkirni položaj */

void servo_park ()

{

//servos.postavitev(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.postavitev(WRI_SERVO, 1800);

servo4.write (90, 10);

//servos.setposition(WRO_SERVO, 600);

servo5.write (90, 10);

//servos.postavitev(GRI_SERVO, 900);

servo6.write (80, 10);

vrnitev;

}

void zero_x ()

{

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

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

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

zamuda (10);

}

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

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

zamuda (10);

}

}

/ * premika roko po ravni črti */

void line ()

{

za (dvojna os = -100,0; os <100,0; os += 0,5) {

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

zamuda (10);

}

za (plavajoča osi = 100,0; osi> -100,0; osi -= 0,5) {

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

zamuda (10);

}

}

prazen krog ()

{

#define RADIUS 50.0

// plavajoči kot = 0;

plovec zaxis, yaxis;

za (plavajoči kot = 0,0; kot <360,0; kot += 1,0) {

osi = RADIUS * sin (radiani (kot)) + 300;

zaxis = RADIUS * cos (radiani (kot)) + 200;

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

zamuda (10);

}

}

4. korak: dejstva, težave in podobno …

Dejstva, težave in podobno …
Dejstva, težave in podobno …

1. Ko zaženem podprogram krog (), se moj robot premika bolj v eliptični obliki kot v krogu. Mislim, da je to zato, ker moji servomotorji niso umerjeni. Enega izmed njih sem preizkusil in 1500 mikrosekund ni bilo enako kot 90 stopinj. Prizadeval si bom, da bi poskušal najti rešitev. Ne verjemite, da je kaj narobe z algoritmom, ampak z mojimi nastavitvami. Posodobitev 2018/2/11 - pravkar sem odkril, da je to posledica napake v prvotni kodi. Ne vidim, kako je njegov program deloval. Popravljena koda s tem: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (dodala se je prvotna koda)

2. Kje lahko najdem več informacij o delovanju funkcije set_arm (): Spletno mesto Olega Mazurova razlaga vse ali ponuja povezave za več informacij:

3. Ali obstaja preverjanje mejnih pogojev? Ne. Ko moji robotski roki podajo neveljavno koordinato xyz, naredi to smešno gibanje, kot je mačka, ki se razteza. Menim, da Oleg preverja svoj najnovejši program, ki uporablja USB za programiranje gibov rok. Oglejte si njegov videoposnetek in povezavo do njegove najnovejše kode.

4. Kodo je treba očistiti in mikrosekundno kodo odpraviti.

Priporočena: