Innholdsfortegnelse:

Bruke Arduino Uno for XYZ Plassering av 6 DOF robotarm: 4 trinn
Bruke Arduino Uno for XYZ Plassering av 6 DOF robotarm: 4 trinn

Video: Bruke Arduino Uno for XYZ Plassering av 6 DOF robotarm: 4 trinn

Video: Bruke Arduino Uno for XYZ Plassering av 6 DOF robotarm: 4 trinn
Video: HOMING Y PUNTO CERO. CNC (Control Numérico Computarizado) 2024, November
Anonim
Image
Image

Dette prosjektet handler om å implementere en kort og relativt enkel Arduino -skisse for å gi XYZ invers kinematisk posisjonering. Jeg hadde bygget en 6 servo robotarm, men når det gjaldt å finne programvare for å kjøre den, var det ikke mye der ute, bortsett fra tilpassede programmer som kjører på tilpassede servoskjold som SSC-32 (U) eller andre programmer og apper som var komplisert å installere og kommunisere med armen. Så fant jeg Oleg Mazurovs mest utmerkede "Robotic Arm Inverse Kinematics on Arduino" hvor han implementerte invers kinematikk i en enkel Arduino -skisse.

Jeg gjorde to modifikasjoner for å tilpasse koden hans:

1. Jeg brukte VarSpeedServo -biblioteket i stedet for det tilpassede servoskjoldbiblioteket fordi jeg da kunne kontrollere hastigheten på servoene, og jeg ville ikke måtte bruke servoskjoldet han brukte. For alle som vurderer å kjøre koden som tilbys her, anbefaler jeg at du bruker dette VarSpeedServo -biblioteket, i stedet for servo.h -biblioteket, slik at du kan bremse din robotarmbevegelse under utviklingen, eller du kan oppleve at armen uventet vil stikke deg inn ansiktet eller verre fordi det vil bevege seg med full servohastighet.

2. Jeg bruker et enkelt sensor-/servoskjold for å koble servoene til Arduino Uno, men det krever ikke noe spesielt servobibliotek da det bare bruker Arduino -pinnene. Det koster bare noen få dollar, men det er ikke nødvendig. Det gir en fin ren tilkobling av servoene til Arduino. Og jeg vil aldri gå tilbake til hardwiring servoer til Arduino Uno nå. Hvis du bruker denne sensoren/servoskjoldet, må du gjøre en liten modifikasjon som jeg vil skissere nedenfor.

Koden fungerer bra og lar deg betjene armen ved å bruke en enkelt funksjon der du passerer parametrene x, y, x og hastighet. For eksempel:

set_arm (0, 240, 100, 0, 20); // parametere er (x, y, z, gripevinkel, servohastighet)

forsinkelse (3000); // forsinkelse er nødvendig for at armtiden skal kunne flyttes til dette stedet

Kunne ikke vært enklere. Jeg vil inkludere skissen nedenfor.

Olegs video er her: Kontroll av robotarm med Arduino og USB -mus

Olegs originale program, beskrivelser og ressurser: Oleg's Inverse Kinematics for Arduino Uno

Jeg forstår ikke all matematikken bak rutinen, men det fine er at du ikke trenger å bruke koden. Håper du vil prøve det.

Trinn 1: Maskinvaremodifikasjoner

Maskinvaremodifikasjoner
Maskinvaremodifikasjoner

1. Det eneste som kreves er at servoen din svinger i forventede retninger, noe som kan kreve at du fysisk reverserer monteringen av servoene dine. Gå til denne siden for å se den forventede servoretningen for baser, skuldre, albuer og håndleddsservoer:

2. Hvis du bruker sensorskjermen som jeg bruker, må du gjøre en ting med den: bøy pinnen som kobler 5v fra skjermen til Arduino Uno ut av veien, slik at den ikke kobles til Uno -kortet. Du vil bruke den eksterne spenningen på skjoldet for å bare drive servoene dine, ikke Arduino Uno eller det kan ødelegge Uno, jeg vet da jeg brente opp to Uno -kort da min eksterne spenning var 6 volt i stedet for 5. Dette lar deg å bruke høyere enn 5v for å drive servoene dine, men hvis den eksterne spenningen er høyere enn 5 volt, må du ikke koble noen 5 volt sensorer til skjoldet, ellers blir de stekt.

Trinn 2: Last ned VarSpeedServo -biblioteket

Du må bruke dette biblioteket som erstatter det vanlige arduino servobiblioteket fordi det lar deg overføre en servohastighet til servoskriverklæringen. Biblioteket ligger her:

VarSpeedServo bibliotek

Du kan bare bruke zip -knappen, laste ned zip -filen og deretter installere den med Arduino IDE. Når installert kommandoen i programmet vil se ut: servo.write (100, 20);

Den første parameteren er vinkelen og den andre er servoens hastighet fra 0 til 255 (full hastighet).

Trinn 3: Kjør denne skissen

Her er konkurranseprogrammet. Du må endre noen få parametere for dine robotarmdimensjoner:

1. BASE_HGT, HUMERUS, ULNA, GRIPPER lengder i millimeter.

2. Skriv inn servo -pin -numrene

3. Angi servo min og maks i vedleggsuttalelsene.

4. Prøv deretter en enkel kommando set_arm () og deretter null_x (), linje () og sirkel () funksjoner for testing. Sørg for at servohastigheten er lav første gang du kjører disse funksjonene for å forhindre skade på armen og din egen arm.

Lykke til.

#inkludere VarSpeedServo.h

/ * Servokontroll for AL5D -arm */

/ * Armmål (mm) */

#define BASE_HGT 90 // base høyde

#define HUMERUS 100 // skulder-til-albue "bein"

#define ULNA 135 // albue-til-håndleddet "bein"

#define GRIPPER 200 // griper (inkl. kraftig håndleddrotasjonsmekanisme) lengde"

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

/ * Servo navn/tall *

* Basisservo HS-485HB */

#define BAS_SERVO 4

/ * Skulder Servo HS-5745-MG */

#define SHL_SERVO 5

/ * Albue Servo HS-5745-MG */

#define ELB_SERVO 6

/ * Håndleddservo HS-645MG */

#define WRI_SERVO 7

/ * Håndleddsservo HS-485HB */

#define WRO_SERVO 8

/ * Gripper servo HS-422 */

#define GRI_SERVO 9

/ * forhåndsberegninger */

float hum_sq = HUMERUS*HUMERUS;

float uln_sq = ULNA*ULNA;

int servoSPeed = 10;

// ServoShield servoer; // ServoShield -objekt

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

int loopCounter = 0;

int pulsbredde = 6,6;

int microsecondsToDegrees;

ugyldig oppsett ()

{

servo1. fest (BAS_SERVO, 544, 2400);

servo2.attach (SHL_SERVO, 544, 2400);

servo3. fest (ELB_SERVO, 544, 2400);

servo4.attach (WRI_SERVO, 544, 2400);

servo5.attach (WRO_SERVO, 544, 2400);

servo6. vedlegg (GRI_SERVO, 544, 2400);

forsinkelse (5500);

//servos.start (); // Start servoskjoldet

servo_park ();

forsinkelse (4000);

Serial.begin (9600);

Serial.println ("Start");

}

hulrom ()

{

loopCounter += 1;

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

// forsinkelse (7000);

// zero_x ();

//linje();

//sirkel();

forsinkelse (4000);

if (loopCounter> 1) {

servo_park ();

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

forsinkelse (5000);

exit (0); } // pause programmet - trykk på reset for å fortsette

// exit (0);

}

/ * armposisjonsrutine ved bruk av invers kinematikk */

/* z er høyden, y er avstanden fra basens senter ut, x er side til side. y, z kan bare være positiv */

// 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 = radianer (grip_angle_d); // gripevinkel i radianer for bruk i beregninger

/ * Grunnvinkel og radial avstand fra x, y koordinater */

float bas_angle_r = atan2 (x, y);

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

/ * rdist er y -koordinat for armen */

y = rdist;

/ * Grepforskyvninger beregnet basert på grepvinkel */

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

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

/ * Håndleddet */

float wrist_z = (z - grip_off_z) - BASE_HGT;

float wrist_y = y - grip_off_y;

/ * Skulder til håndledd avstand (AKA sw) */

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

float s_w_sqrt = sqrt (s_w);

/ * s_w vinkel mot bakken */

float a1 = atan2 (wrist_z, wrist_y);

/ * s_w vinkel mot humerus */

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

/ * skuldervinkel */

float shl_angle_r = a1 + a2;

float shl_angle_d = grader (shl_angle_r);

/ * albue vinkel */

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

float elb_angle_d = grader (elb_angle_r);

float elb_angle_dn = - (180.0 - elb_angle_d);

/ * håndleddsvinkel */

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/ * Servopulser */

float bas_servopulse = 1500.0 - ((grader (bas_angle_r)) * pulsbredde);

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

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

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

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

float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); // oppdatert 2018/2/11 av jimrd - jeg endret pluss til minus - ikke sikker på hvordan denne koden fungerte for noen før. Kan være at albueservoen var montert med 0 grader nedover i stedet for opp.

/ * Sett servoer */

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

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

servo1.write (microsecondsToDegrees, servoSpeed); // bruk denne funksjonen slik at du kan stille inn servohastighet //

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

}

/ * flytt servoer til parkeringsposisjon */

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

komme tilbake;

}

ugyldig zero_x ()

{

for (dobbel yaxis = 250,0; yaxis <400,0; yaxis += 1) {

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

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

forsinkelse (10);

}

for (dobbel yaxis = 400,0; yaxis> 250,0; yaxis -= 1) {

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

forsinkelse (10);

}

}

/ * beveger armen i en rett linje */

tom linje ()

{

for (dobbel xaxis = -100,0; xaxis <100,0; xaxis += 0,5) {

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

forsinkelse (10);

}

for (float xaxis = 100,0; xaxis> -100,0; xaxis -= 0,5) {

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

forsinkelse (10);

}

}

tomrom sirkel ()

{

#define RADIUS 50.0

// flytevinkel = 0;

float zaxis, yaxis;

for (flytevinkel = 0,0; vinkel <360,0; vinkel += 1,0) {

yaxis = RADIUS * sin (radianer (vinkel)) + 300;

zaxis = RADIUS * cos (radianer (vinkel)) + 200;

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

forsinkelse (10);

}

}

Trinn 4: Fakta, problemer og lignende …

Fakta, problemer og lignende …
Fakta, problemer og lignende …

1. Når jeg kjører sirkel () underrutine, beveger roboten min mer i en elliptisk form enn en sirkel. Jeg tror det er fordi servoene mine ikke er kalibrert. Jeg testet en av dem og 1500 mikrosekunder var ikke det samme som 90 grader. Skal jobbe med dette for å prøve å finne en løsning. Tror ikke det er noe galt med algoritmen, men heller med mine innstillinger. Oppdatering 2018/2/11 - oppdaget nettopp at dette skyldes feil i den opprinnelige koden. Jeg kan ikke se hvordan programmet hans fungerte Fast kode ved hjelp av dette: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (den opprinnelige koden ble lagt til)

2. Hvor finner jeg mer informasjon om hvordan set_arm () -funksjonen fungerer: Oleg Mazurovs nettsted forklarer alt eller gir lenker for mer info:

3. Er det noen grensekontrollkontroll? Nei. Når robotarmen min blir passert, utfører en ugyldig xyz -koordinat denne morsomme buen som en katt som strekker seg. Jeg tror Oleg sjekker inn det siste programmet som bruker en USB for å programmere armbevegelsene. Se videoen hans og lenke til hans siste kode.

4. Koden må ryddes opp, og mikrosekundkoden kan fjernes.

Anbefalt: