Taula de continguts:

Utilització d’Arduino Uno per al posicionament XYZ de 6 braços robòtics DOF: 4 passos
Utilització d’Arduino Uno per al posicionament XYZ de 6 braços robòtics DOF: 4 passos

Vídeo: Utilització d’Arduino Uno per al posicionament XYZ de 6 braços robòtics DOF: 4 passos

Vídeo: Utilització d’Arduino Uno per al posicionament XYZ de 6 braços robòtics DOF: 4 passos
Vídeo: Система управления положением двигателя постоянного тока на основе Arduino PID 2024, De novembre
Anonim
Image
Image

Aquest projecte tracta d’implementar un esbós Arduino breu i relativament fàcil per proporcionar un posicionament cinemàtic invers de XYZ. Havia construït un braç robòtic de 6 servidors, però a l’hora de trobar programari per executar-lo, no hi havia gaire, excepte per a programes personalitzats que s’executaven amb servescuts personalitzats com el SSC-32 (U) o altres programes i aplicacions que eren complicat d’instal·lar i comunicar-se amb el braç. Després vaig trobar la més excel·lent "Cinemàtica inversa del braç robòtic a Arduino" d'Oleg Mazurov, on va implementar la cinemàtica inversa en un simple esbós d'Arduino.

Vaig fer dues modificacions per adaptar el seu codi:

1. Vaig fer servir la biblioteca VarSpeedServo en lloc de la seva biblioteca de servescut personalitzat perquè podia controlar la velocitat dels servos i no hauria d’utilitzar el servescut que va utilitzar. Per a qualsevol persona que tingui en compte executar el codi que es proporciona aquí, us recomano que utilitzeu aquesta biblioteca VarSpeedServo, en lloc de la biblioteca servo.h, de manera que pugueu alentir el moviment del braç robotitzat durant el desenvolupament o potser trobareu que el braç us col·loquen inesperadament. la cara o pitjor perquè es mourà a tota la velocitat del servo.

2. Utilitzo un senzill escut de sensor / servo per connectar els servos a l'Arduino Uno, però no requereix cap biblioteca de servidors especials, ja que només fa servir els pins d'Arduino. Només costa uns quants dòlars, però no és obligatori. Proporciona una bona connexió neta dels servos a l'Arduino. I ara no tornaré mai als servos de cablejat de l’Arduino Uno. Si utilitzeu aquest escut del sensor / servo, heu de fer una modificació menor que esbossaré a continuació.

El codi funciona molt bé i us permet operar el braç mitjançant una única funció en la qual passeu els paràmetres x, y, x i velocitat. Per exemple:

set_arm (0, 240, 100, 0, 20); // els paràmetres són (x, y, z, angle de pinça, velocitat de servo)

retard (3000); // es requereix un retard per permetre que el temps d'armament es mogui a aquesta ubicació

No podria ser més senzill. Inclouré l'esbós a continuació.

El vídeo d’Oleg és aquí: Control del braç robòtic amb Arduino i ratolí USB

Programa original, descripcions i recursos d’Oleg: la cinemàtica inversa d’Oleg per a Arduino Uno

No entenc totes les matemàtiques que hi ha darrere de la rutina, però el més agradable és que no cal que utilitzeu el codi. Espero que ho proveu.

Pas 1: modificacions del maquinari

Modificacions de maquinari
Modificacions de maquinari

1. L'únic que es requereix és que el servo giri en les direccions esperades, cosa que pot requerir que invertiu físicament el muntatge dels servos. Aneu a aquesta pàgina per veure la direcció del servo esperada per als servos base, espatlla, colze i canell:

2. Si feu servir el blindatge del sensor que faig servir, heu de fer-hi una cosa: doblegueu el pin que connecta els 5v del blindatge a l'Arduino Uno perquè no es connecti a la placa Uno. Voleu utilitzar la tensió externa de l’escut per alimentar només els servos, no l’Arduino Uno o pot destruir l’Uno, ho sé, ja que vaig cremar dues plaques Uno quan el meu voltatge extern era de 6 volts en lloc de 5. Això us permet per utilitzar més de 5 v per alimentar els vostres servos, però si la vostra tensió externa és superior a 5 volts, no connecteu cap sensor de 5 volts al blindatge o es fregirà.

Pas 2: descarregueu la biblioteca VarSpeedServo

Heu d’utilitzar aquesta biblioteca que substitueix la biblioteca de servidors arduino estàndard perquè us permet passar una velocitat de servo a la sentència servo write. La biblioteca es troba aquí:

Biblioteca VarSpeedServo

Només podeu utilitzar el botó zip, descarregar el fitxer zip i instal·lar-lo amb l'IDE Arduino. Un cop instal·lat, l'ordre al programa tindrà el següent aspecte: servo.write (100, 20);

El primer paràmetre és l’angle i el segon és la velocitat del servo de 0 a 255 (velocitat màxima).

Pas 3: executeu aquest esbós

Aquí teniu el programa competeix. Heu de modificar uns quants paràmetres per a les dimensions robotitzades del braç:

1. BASE_HGT, HUMERUS, ULNA, GRIPPER longituds en mil·límetres.

2. Introduïu els números del vostre servo pin

3. Introduïu el servo min i max a les instruccions adjuntes.

4. A continuació, proveu una senzilla ordre set_arm () i després les funcions zero_x (), line () i circle () per provar-les. Assegureu-vos que la velocitat del servo sigui baixa la primera vegada que executeu aquestes funcions per evitar danyar el braç i el propi braç.

Bona sort.

#include VarSpeedServo.h

/ * Control servo per al braç AL5D * /

/ * Dimensions del braç (mm) * /

#define BASE_HGT 90 // altura de la base

#define HUMERUS 100 // "os" d'espatlla a colze

#define ULNA 135 // "os" de colze a canell

#define GRIPPER 200 // longitud de la pinça (inclòs el mecanisme de gir del canell de pes pesat)"

#define ftl (x) ((x)> = 0? (long) ((x) +0.5):(long) ((x) -0.5)) // conversió flotant a llarga

/ * Noms / números de servidors *

* Servo base HS-485HB * /

#define BAS_SERVO 4

/ * Servo d'espatlla HS-5745-MG * /

#define SHL_SERVO 5

/ * Servidor de colze HS-5745-MG * /

#define ELB_SERVO 6

/ * Servo de canell HS-645MG * /

#define WRI_SERVO 7

/ * Servo giratori de canell HS-485HB * /

#define WRO_SERVO 8

/ * Servo de pinça HS-422 * /

#define GRI_SERVO 9

/ * pre-càlculs * /

flotador hum_sq = HUMERUS * HUMERUS;

float uln_sq = ULNA * ULNA;

int servoSPeed = 10;

// ServoShield servos; // Objecte ServoShield

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

int loopCounter = 0;

int pulseWidth = 6,6;

int microsegonsToDegrees;

configuració nul·la ()

{

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

retard (5500);

//servos.start (); // Inicieu el servescut

servo_park ();

retard (4000);

Serial.begin (9600);

Serial.println ("Inici");

}

bucle buit ()

{

loopCounter + = 1;

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

// demora (7000);

// zero_x ();

// línia ();

//cercle();

retard (4000);

if (loopCounter> 1) {

servo_park ();

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

retard (5000);

sortida (0); } // pausa del programa: premeu Restableix per continuar

// sortir (0);

}

/ * rutina de posicionament del braç mitjançant cinemàtica inversa * /

/ * z és l’alçada, y és la distància del centre de la base cap a fora, x és d’un costat a l’altre. y, z només pot ser positiu * /

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

{

flotador grip_angle_r = radians (grip_angle_d); // angle d’adherència en radians per utilitzar-lo en càlculs

/ * Angle de base i distància radial des de les coordenades x, y * /

float bas_angle_r = atan2 (x, y);

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

/ * rdist és la coordenada y del braç * /

y = rdist;

/ * Desplaçaments d’adherència calculats en funció de l’angle d’adherència * /

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

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

/ * Posició del canell * /

flotador canell_z = (z - grip_off_z) - BASE_HGT;

flotador canell_y = y - grip_off_y;

/ * Distància de l'espatlla al canell (AKA sw) * /

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

float s_w_sqrt = sqrt (s_w);

/ * s_w angle a terra * /

flotador a1 = atan2 (canell_z, canell_y);

/ * angle s_w respecte l'húmer * /

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

/ * angle d'espatlla * /

flotador shl_angle_r = a1 + a2;

flotador shl_angle_d = graus (shl_angle_r);

/ * angle del colze * /

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

flotador elb_angle_d = graus (elb_angle_r);

float elb_angle_dn = - (180.0 - elb_angle_d);

/ * angle del canell * /

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/ * Polsos servo * /

float bas_servopulse = 1500.0 - ((graus (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); // actualitzat el 2018-02-02 per jimrd - He canviat el plus a un menys - no estic segur de com funcionava aquest codi per a ningú abans. Podria ser que el servo colze estigués muntat amb 0 graus cap avall en lloc de cap amunt.

/ * Estableix servos * /

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

microsegons a graus = mapa (ftl (bas_servopulse), 544, 2400, 0, 180);

servo1.write (microsegonsToDegrees, servoSpeed); // utilitzeu aquesta funció perquè pugueu configurar la velocitat del servo //

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

microsegons a graus = mapa (ftl (shl_servopulse), 544, 2400, 0, 180);

servo2.write (microsegonsToDegrees, servoSpeed);

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

microsegons a graus = mapa (ftl (elb_servopulse), 544, 2400, 0, 180);

servo3.write (microsegonsToDegrees, servoSpeed);

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

microsegonsToDegrees = mapa (ftl (wri_servopulse), 544, 2400, 0, 180);

servo4.write (microsegonsToDegrees, servoSpeed);

}

/ * Mou servos a la posició d'aparcament * /

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

tornar;

}

buida zero_x ()

{

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

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

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

retard (10);

}

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

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

retard (10);

}

}

/ * mou el braç en línia recta * /

línia buida ()

{

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

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

retard (10);

}

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

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

retard (10);

}

}

cercle buit ()

{

#defineix RADIUS 50.0

// angle flotant = 0;

zaxis flotant, yaxis;

for (angle flotant = 0,0; angle <360,0; angle + = 1,0) {

yaxis = RADIUS * sin (radians (angle)) + 300;

zaxis = RADIUS * cos (radians (angle)) + 200;

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

retard (10);

}

}

Pas 4: fets, qüestions i similars …

Fets, qüestions i similars …
Fets, qüestions i similars …

1. Quan executo la subrutina circle (), el meu robot es mou més en forma el·líptica que en cercle. Crec que això és perquè els meus servos no estan calibrats. N’he provat un i 1500 microsegons no eren el mateix que 90 graus. Treballarem en això per intentar trobar una solució. No crec que hi hagi cap problema amb l'algorisme, sinó amb la meva configuració. Actualització del 2018-02-02: acabo de descobrir que es deu a un error al codi original. No veig com va funcionar el seu programa Codi fix amb això: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (es va afegir el codi original)

2. On puc trobar més informació sobre com funciona la funció set_arm (): el lloc web d'Oleg Mazurov ho explica tot o proporciona enllaços per obtenir més informació:

3. Hi ha alguna comprovació de les condicions del límit? No. Quan es passa el braç del robot amb una coordenada xyz no vàlida, fa aquest divertit tipus de moviment d'arcs com un gat que s'estira. Crec que Oleg fa una revisió del seu darrer programa que utilitza un USB per programar els moviments dels braços. Vegeu el seu vídeo i enllaceu amb el seu darrer codi.

4. Cal netejar el codi i es pot eliminar el codi de microsegon.

Recomanat: