Sisällysluettelo:

Arduino Unon käyttäminen kuuden DOF -robotin XYZ -paikannukseen: 4 vaihetta
Arduino Unon käyttäminen kuuden DOF -robotin XYZ -paikannukseen: 4 vaihetta

Video: Arduino Unon käyttäminen kuuden DOF -robotin XYZ -paikannukseen: 4 vaihetta

Video: Arduino Unon käyttäminen kuuden DOF -robotin XYZ -paikannukseen: 4 vaihetta
Video: How to use MPU-9250 Gyroscope, Accelerometer, Magnetometer for Arduino 2024, Joulukuu
Anonim
Image
Image

Tässä projektissa toteutetaan lyhyt ja suhteellisen helppo Arduino -luonnos XYZ -käänteisen kinemaattisen paikannuksen aikaansaamiseksi. Olin rakentanut kuuden servo-robottivarren, mutta kun tuli ohjelmistoa sen käyttämiseen, siellä ei ollut paljon muuta kuin mukautetut ohjelmat, jotka toimivat mukautetuilla servokilvillä, kuten SSC-32 (U) tai muut ohjelmat ja sovellukset, jotka olivat hankala asentaa ja kommunikoida käsivarren kanssa. Sitten löysin Oleg Mazurovin erinomaisimman "Robot Arm Inverse Kinematics on Arduino", jossa hän toteutti käänteisen kinematiikan yksinkertaisessa Arduino -luonnoksessa.

Tein kaksi muutosta hänen koodinsa mukauttamiseksi:

1. Käytin VarSpeedServo -kirjastoa hänen mukautetun servokilpikirjastonsa sijasta, koska pystyin sitten hallitsemaan servojen nopeutta, eikä minun tarvinnut käyttää hänen käyttämäänsä servosuojaa. Kaikille, jotka harkitsevat tässä annetun koodin käyttämistä, suosittelen käyttämään tätä VarSpeedServo -kirjastoa servo.h -kirjaston sijasta, jotta voit hidastaa käsivartesi liikettä kehityksen aikana tai saatat huomata, että varsi työntää sinut odottamatta kasvot tai pahempaa, koska se liikkuu täydellä servonopeudella.

2. Käytän yksinkertaista anturia/servosuojaa servojen liittämiseen Arduino Unoon, mutta se ei vaadi erityistä servokirjastoa, koska se käyttää vain Arduinon nastoja. Se maksaa vain muutaman dollarin, mutta sitä ei vaadita. Se tekee servoista mukavan puhtaan yhteyden Arduinoon. Ja en koskaan palaa takaisin johdotettuihin servoihin Arduino Unoon. Jos käytät tätä anturia/servosuojaa, sinun on tehtävä pieni muutos, jonka esittelen alla.

Koodi toimii hyvin ja voit käyttää käsivartta käyttämällä yhtä toimintoa, jossa välität x-, y-, x- ja nopeusparametrit. Esimerkiksi:

set_arm (0, 240, 100, 0, 20); // parametrit ovat (x, y, z, tartuntakulma, servonopeus)

viive (3000); // Viive vaaditaan, jotta käsivarsi voi siirtyä tähän paikkaan

Ei voisi olla yksinkertaisempaa. Lisään alla olevan luonnoksen.

Olegin video on täällä: Robottivarren hallinta Arduinolla ja USB -hiirellä

Olegin alkuperäinen ohjelma, kuvaukset ja resurssit: Olegin käänteinen kinematiikka Arduino Unolle

En ymmärrä kaikkea rutiinin takana olevaa matematiikkaa, mutta mukavaa on, että sinun ei tarvitse käyttää koodia. Toivottavasti annat kokeilla.

Vaihe 1: Laitteiston muutokset

Laitteiston muutokset
Laitteiston muutokset

1. Ainoa asia, jota vaaditaan, on, että servosi kääntyy odotettuihin suuntiin, mikä voi vaatia sinua kääntämään fyysisesti servosi asennuksen. Siirry tälle sivulle nähdäksesi pohjan, olkapään, kyynärpään ja ranteen servojen odotettu servosuunta:

2. Jos käytät käyttämääni anturisuojaa, sinun on tehtävä sille yksi asia: taivuta 5V: n suojan ja Arduino Unon yhdistävä tappi pois tieltä niin, ettei se liity Uno -korttiin. Haluat käyttää kilven ulkoista jännitettä vain servojesi virtalähteeksi, ei Arduino Unoa, tai se voi tuhota Unon. Tiedän, että poltin kaksi Uno -levyä, kun ulkoinen jännite oli 6 volttia eikä 5. käyttääksesi korkeampaa kuin 5 V: n virransyöttöä servoillesi, mutta jos ulkoinen jännite on yli 5 volttia, älä kytke mitään 5 voltin antureita suojaan tai ne paistetaan.

Vaihe 2: Lataa VarSpeedServo -kirjasto

Sinun on käytettävä tätä kirjastoa, joka korvaa tavallisen arduino -servokirjaston, koska sen avulla voit siirtää servonopeuden servokirjoituslausekkeeseen. Kirjasto sijaitsee täällä:

VarSpeedServo -kirjasto

Voit käyttää zip -painiketta, ladata zip -tiedoston ja asentaa sen sitten Arduino IDE: n kanssa. Asennuksen jälkeen komento ohjelmassasi näyttää tältä: servo.write (100, 20);

Ensimmäinen parametri on kulma ja toinen servon nopeus 0 - 255 (täysi nopeus).

Vaihe 3: Suorita tämä luonnos

Tässä kilpailuohjelma. Sinun on muutettava muutamia parametreja robottivarren mitoillesi:

1. BASE_HGT, HUMERUS, ULNA, GIPPER -pituudet millimetreinä.

2. Syötä servonapinumerot

3. Syötä servo min ja max liitetiedoissa.

4. Kokeile sitten yksinkertaista set_arm () -komentoa ja sitten nolla_x () -, line () - ja ympyrä () - toimintoja testausta varten. Varmista, että servonopeutesi on alhainen, kun käytät näitä toimintoja ensimmäisen kerran, jotta et vahingoita käsiäsi ja omaa käsivartta.

Onnea.

#include VarSpeedServo.h

/ * Servo -ohjaus AL5D -varteen */

/ * Varren mitat (mm) */

#define BASE_HGT 90 // peruskorkeus

#define HUMERUS 100 // olkapäästä kyynärpäähän oleva "luu"

#define ULNA 135 // kyynärpäästä ranteeseen "luu"

#define GRIPPER 200 // tarttuja (sis. raskaan ranteen kiertomekanismin) pituus"

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

/ * Servonimet/numerot *

* Perusservo HS-485HB */

#define BAS_SERVO 4

/ * Olkapää Servo HS-5745-MG */

#define SHL_SERVO 5

/ * Kyynärpääservo HS-5745-MG */

#define ELB_SERVO 6

/ * Ranneservo HS-645MG */

#define WRI_SERVO 7

/ * Ranteessa pyörivä servo HS-485HB */

#define WRO_SERVO 8

/ * Tartuntaservo HS-422 */

#define GRI_SERVO 9

/ * esilaskelmat */

float hum_sq = HUMERUS*HUMERUS;

float uln_sq = ULNA*ULNA;

int servoSPeed = 10;

// ServoShield -servot; // ServoShield -objekti

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

int loopCounter = 0;

int pulseWidth = 6,6;

int mikrosekuntiaToDegrees;

mitätön asennus ()

{

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

viive (5500);

//servos.start (); // Käynnistä servosuoja

servo_park ();

viive (4000);

Sarja.alku (9600);

Serial.println ("Käynnistä");

}

tyhjä silmukka ()

{

loopCounter += 1;

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

// viive (7000);

// nolla_x ();

//linja();

//ympyrä();

viive (4000);

if (loopCounter> 1) {

servo_park ();

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

viive (5000);

poistuminen (0); } // keskeytä ohjelma - jatka painamalla reset

// exit (0);

}

/ * käsivarren paikannusrutiini käyttäen käänteistä kinematiikkaa */

/* z on korkeus, y on etäisyys tukikohdan keskeltä ulos, x on sivulta toiselle. y, z voi olla vain positiivinen */

// 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 = radiaanit (grip_angle_d); // otekulma radiaaneina käytettäväksi laskelmissa

/ * Peruskulma ja säteittäinen etäisyys x, y -koordinaateista */

float bas_angle_r = atan2 (x, y);

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

/ * rdist on y -koordinaatti käsivarrelle */

y = rdist;

/ * Kahvan siirtymät lasketaan otekulman perusteella */

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

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

/ * Ranneasento */

kelluva ranne_z = (z - grip_off_z) - BASE_HGT;

float wrist_y = y - grip_off_y;

/ * Etäisyys olkapäästä ranteeseen (AKA sw) */

float s_w = (ranne_z * ranne_z) + (ranne_y * ranne_y);

kellua s_w_sqrt = sqrt (s_w);

/ * s_w kulma maahan */

kellua a1 = atan2 (ranne_z, ranne_y);

/ * s_w kulma olkaluuhun */

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

/ * olkapää kulma */

kellua shl_angle_r = a1 + a2;

float shl_angle_d = astetta (shl_angle_r);

/ * kyynärpää kulma */

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

float elb_angle_d = astetta (elb_angle_r);

float elb_angle_dn = - (180,0 - elb_angle_d);

/ * rannekulma */

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/ * Servopulssit */

float bas_servopulse = 1500,0 - ((astetta (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); // päivitetty 2018/2/11 by jimrd - muutin plussan miinukseksi - en ole varma miten tämä koodi toimi kenellekään ennen. Voi olla, että kyynärpääservo oli asennettu 0 astetta alaspäin eikä ylöspäin.

/ * Aseta servot */

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

mikrosekuntiaToDegrees = kartta (ftl (bas_servopulse), 544, 2400, 0, 180);

servo1.write (mikrosekuntiaToDegrees, servoSpeed); // käytä tätä toimintoa, jotta voit asettaa servonopeuden //

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

mikrosekuntiaToDegrees = kartta (ftl (shl_servopulse), 544, 2400, 0, 180);

servo2.write (mikrosekuntiaToDegrees, servoSpeed);

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

mikrosekuntiaToDegrees = kartta (ftl (elb_servopulse), 544, 2400, 0, 180);

servo3.write (mikrosekuntiaToDegrees, servoSpeed);

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

mikrosekuntiaToDegrees = kartta (ftl (wri_servopulse), 544, 2400, 0, 180);

servo4.write (mikrosekuntiaToDegrees, servoSpeed);

}

/ * siirrä servot pysäköintiasentoon */

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

palata;

}

void zero_x ()

{

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

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

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

viive (10);

}

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

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

viive (10);

}

}

/ * liikuttaa käsivartta suorassa linjassa */

tyhjä rivi ()

{

(kaksinkertainen akseli = -100,0; akseli <100,0; akseli += 0,5) {

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

viive (10);

}

for (float xaxis = 100.0; xaxis> -100.0; xaxis -= 0.5) {

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

viive (10);

}

}

tyhjä ympyrä ()

{

#define RADIUS 50.0

// kellukulma = 0;

float zaxis, yaxis;

for (kellukulma = 0,0; kulma <360,0; kulma += 1,0) {

yaxis = RADIUS * sin (radiaanit (kulma)) + 300;

zaxis = RADIUS * cos (radiaanit (kulma)) + 200;

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

viive (10);

}

}

Vaihe 4: Faktoja, ongelmia ja vastaavia…

Faktoja, kysymyksiä ja vastaavia…
Faktoja, kysymyksiä ja vastaavia…

1. Kun suoritan ympyrä () -aliohjelman, robotti liikkuu enemmän elliptisenä kuin ympyränä. Mielestäni tämä johtuu siitä, että servojani ei ole kalibroitu. Testasin yhden niistä ja 1500 mikrosekuntia ei ollut sama kuin 90 astetta. Tätä yritetään löytää ja löytää ratkaisu. Älä usko, että algoritmissa on jotain vikaa, vaan pikemminkin asetuksissani. Päivitys 2018/2/11 - huomasin juuri, että tämä johtuu virheestä alkuperäisessä koodissa. En näe miten hänen ohjelmansa toimi Kiinteä koodi käyttämällä tätä: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (alkuperäinen koodi lisätty)

2. Mistä löydän lisätietoja set_arm () -toiminnon toiminnasta: Oleg Mazurovin verkkosivusto selittää kaiken tai tarjoaa linkkejä lisätietoja varten:

3. Onko reunaehtojen tarkistusta? Ei. Kun robotin käsivarteni ohitetaan virheellisellä xyz -koordinaatilla, se tekee tämän hauskan kaarevan liikkeen kuin kissa venyttelee. Uskon, että Oleg tarkistaa jonkin verran uusimmassa ohjelmassaan, joka käyttää USB: tä käsivarsien liikkeiden ohjelmointiin. Katso hänen videonsa ja linkki hänen uusimpaan koodiinsa.

4. Koodi on puhdistettava ja mikrosekunnin koodi voidaan poistaa.

Suositeltava: