Πίνακας περιεχομένων:

Χρήση του Arduino Uno για τοποθέτηση XYZ του ρομποτικού βραχίονα 6 DOF: 4 βήματα
Χρήση του Arduino Uno για τοποθέτηση XYZ του ρομποτικού βραχίονα 6 DOF: 4 βήματα

Βίντεο: Χρήση του Arduino Uno για τοποθέτηση XYZ του ρομποτικού βραχίονα 6 DOF: 4 βήματα

Βίντεο: Χρήση του Arduino Uno για τοποθέτηση XYZ του ρομποτικού βραχίονα 6 DOF: 4 βήματα
Βίντεο: Palletizer & Conveyor machine design part 2 (simulations using Factory IO & tia portal) 2024, Ιούλιος
Anonim
Image
Image

Αυτό το έργο αφορά την εφαρμογή ενός σύντομου και σχετικά εύκολου σχεδίου Arduino για την παροχή αντίστροφης κινηματικής τοποθέτησης XYZ. Είχα κατασκευάσει έναν 6-σερβο ρομποτικό βραχίονα, αλλά όταν ήρθε η εύρεση λογισμικού για την εκτέλεσή του, δεν υπήρχαν πολλά εκτός από τα προσαρμοσμένα προγράμματα που λειτουργούσαν σε προσαρμοσμένες σερβο-ασπίδες όπως το SSC-32 (U) ή άλλα προγράμματα και εφαρμογές που ήταν περίπλοκη εγκατάσταση και επικοινωνία με το βραχίονα. Στη συνέχεια βρήκα το πιο εξαιρετικό "Robotic Arm Inverse Kinematics on Arduino" του Όλεγκ Μαζούροφ όπου εφάρμοσε την αντίστροφη κινηματική σε ένα απλό σκίτσο Arduino.

Έκανα δύο τροποποιήσεις για να προσαρμόσω τον κώδικά του:

1. Χρησιμοποίησα τη βιβλιοθήκη VarSpeedServo στη θέση της προσαρμοσμένης βιβλιοθήκης του servo shield γιατί στη συνέχεια μπορούσα να ελέγξω την ταχύτητα των servos και δεν θα χρειαστεί να χρησιμοποιήσω την servo shield που χρησιμοποίησε. Για οποιονδήποτε σκέφτεται να εκτελέσει τον κωδικό που παρέχεται εδώ, συνιστώ να χρησιμοποιήσετε αυτήν τη βιβλιοθήκη VarSpeedServo και όχι τη βιβλιοθήκη servo.h, ώστε να επιβραδύνετε την ρομποτική κίνηση του βραχίονα σας κατά τη διάρκεια της ανάπτυξης ή μπορεί να διαπιστώσετε ότι ο βραχίονας θα σας βάλει απροσδόκητα το πρόσωπο ή ακόμα χειρότερα γιατί θα κινείται με πλήρη σερβο ταχύτητα.

2. Χρησιμοποιώ έναν απλό αισθητήρα/servo shield για να συνδέσω τα servos στο Arduino Uno αλλά δεν απαιτεί ειδική βιβλιοθήκη servo καθώς χρησιμοποιεί μόνο τις καρφίτσες του Arduino. Κοστίζει μόνο μερικά δολάρια, αλλά δεν απαιτείται. Κάνει μια ωραία καθαρή σύνδεση των servos με το Arduino. Και δεν θα επιστρέψω ποτέ σε σκληρά καλώδια servos στο Arduino Uno τώρα. Εάν χρησιμοποιείτε αυτόν τον αισθητήρα/σερβοπροστασία πρέπει να κάνετε μια μικρή τροποποίηση που θα περιγράψω παρακάτω.

Ο κώδικας λειτουργεί τέλεια και σας επιτρέπει να χειρίζεστε τον βραχίονα χρησιμοποιώντας μία μόνο συνάρτηση στην οποία περνάτε τις παραμέτρους x, y, x και ταχύτητας. Για παράδειγμα:

set_arm (0, 240, 100, 0, 20); // οι παράμετροι είναι (x, y, z, gripper angle, servo speed)

καθυστέρηση (3000)? // απαιτείται καθυστέρηση για να επιτρέψει τη μετακίνηση του χρόνου βραχίονα σε αυτήν τη θέση

Δεν θα μπορούσε να είναι πιο απλό. Θα συμπεριλάβω το σκίτσο παρακάτω.

Το βίντεο του Oleg είναι εδώ: Controlling Robotic Arm με Arduino και USB Mouse

Το αρχικό πρόγραμμα, οι περιγραφές και οι πόροι του Oleg: Overse's Inverse Kinematics για το Arduino Uno

Δεν καταλαβαίνω όλα τα μαθηματικά πίσω από τη ρουτίνα, αλλά το ωραίο είναι ότι δεν χρειάζεται να χρησιμοποιήσετε τον κώδικα. Ελπίζω να το δοκιμάσετε.

Βήμα 1: Τροποποιήσεις υλικού

Τροποποιήσεις υλικού
Τροποποιήσεις υλικού

1. Το μόνο που απαιτείται είναι ότι το σερβο σας γυρίζει στις αναμενόμενες κατευθύνσεις που θα μπορούσαν να απαιτήσουν από εσάς να αντιστρέψετε τη συναρμολόγηση των σερβομηχανών σας. Μεταβείτε σε αυτήν τη σελίδα για να δείτε την αναμενόμενη κατεύθυνση σερβο για σερβιτόρους βάσης, ώμου, αγκώνα και καρπού:

2. Εάν χρησιμοποιείτε την ασπίδα αισθητήρα που χρησιμοποιώ, πρέπει να κάνετε ένα πράγμα σε αυτήν: λυγίστε τον πείρο που συνδέει το 5v από την ασπίδα στο Arduino Uno έξω από τον δρόμο, έτσι ώστε να μην συνδέεται με την πλακέτα Uno. Θέλετε να χρησιμοποιήσετε την εξωτερική τάση στην ασπίδα για να τροφοδοτήσετε μόνο τα servos σας, όχι το Arduino Uno ή μπορεί να καταστρέψει το Uno, ξέρω καθώς έκαψα δύο πλακέτες Uno όταν η εξωτερική μου τάση ήταν 6 βολτ αντί για 5. Αυτό σας επιτρέπει να χρησιμοποιείτε υψηλότερα από 5v για να τροφοδοτείτε τα servos σας, αλλά εάν η εξωτερική σας τάση είναι υψηλότερη από 5 volts, τότε μην συνδέετε αισθητήρες 5 volt στην ασπίδα ή θα τηγανιστούν.

Βήμα 2: Κατεβάστε τη Βιβλιοθήκη VarSpeedServo

Πρέπει να χρησιμοποιήσετε αυτήν τη βιβλιοθήκη που αντικαθιστά την τυπική arduino servo βιβλιοθήκη, επειδή σας επιτρέπει να περάσετε μια ταχύτητα σερβο στη δήλωση servo εγγραφής. Η βιβλιοθήκη βρίσκεται εδώ:

Βιβλιοθήκη VarSpeedServo

Μπορείτε απλά να χρησιμοποιήσετε το κουμπί zip, να κατεβάσετε το αρχείο zip και στη συνέχεια να το εγκαταστήσετε με το Arduino IDE. Μόλις εγκατασταθεί η εντολή στο πρόγραμμά σας θα μοιάζει με: servo.write (100, 20);

Η πρώτη παράμετρος είναι η γωνία και η δεύτερη η ταχύτητα του σερβο από 0 έως 255 (πλήρης ταχύτητα).

Βήμα 3: Εκτελέστε αυτό το σκίτσο

Εδώ είναι το πρόγραμμα του διαγωνισμού. Πρέπει να τροποποιήσετε μερικές παραμέτρους για τις ρομποτικές διαστάσεις του βραχίονα σας:

1. BASE_HGT, HUMERUS, ULNA, GRIPPER μήκη σε χιλιοστά.

2. Εισαγάγετε τους αριθμούς των σερβο -καρφιτσών σας

3. Εισάγετε το σερβο min και max στις προτάσεις επισύναψης.

4. Στη συνέχεια, δοκιμάστε μια απλή εντολή set_arm () και στη συνέχεια τις δοκιμές μηδενικού_χ (), γραμμής () και κύκλου (). Βεβαιωθείτε ότι η ταχύτητα σερβο είναι χαμηλή την πρώτη φορά που εκτελείτε αυτές τις λειτουργίες για να αποφύγετε ζημιά στο χέρι και το δικό σας χέρι.

Καλή τύχη.

#include VarSpeedServo.h

/ * Έλεγχος σερβο για βραχίονα AL5D */

/ * Διαστάσεις βραχίονα (mm) */

#define BASE_HGT 90 // ύψος βάσης

#define HUMERUS 100 // «κόκκαλο» ώμου προς αγκώνα

#define ULNA 135 // αγκώνα-στον καρπό "κόκκαλο"

#define GRIPPER 200 // gripper (συμπεριλαμβανομένου του μηχανισμού περιστροφής καρπού βαρέως τύπου) μήκος"

#define ftl (x) ((x)> = 0? (long) ((x) +0.5):(long) ((x) -0.5)) // μεταφορά σε μεγάλη μετατροπή

/ * Servo ονόματα/αριθμοί *

* Base servo HS-485HB */

#define BAS_SERVO 4

/ * Shoulder Servo HS-5745-MG */

#define SHL_SERVO 5

/ * Elbow Servo HS-5745-MG */

#define ELB_SERVO 6

/ * Καρπό σερβο HS-645MG */

#define WRI_SERVO 7

/ * Σερβο σετ περιστρεφόμενου καρπού HS-485HB */

#define WRO_SERVO 8

/ * Gripper servo HS-422 */

#define GRI_SERVO 9

/ * προ-υπολογισμοί */

float hum_sq = HUMERUS*HUMERUS;

float uln_sq = ULNA*ULNA;

int servoSPeed = 10;

// ServoShield servos; // αντικείμενο ServoShield

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

int loopCounter = 0;

int pulseWidth = 6,6;

int microsecondsToDegrees;

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

καθυστέρηση (5500)?

//servos.start (); // Ξεκινήστε την σερβοπροστασία

servo_park ();

καθυστέρηση (4000)?

Serial.begin (9600);

Serial.println ("Έναρξη");

}

κενός βρόχος ()

{

loopCounter += 1;

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

// καθυστέρηση (7000);

// zero_x ();

//γραμμή();

//κύκλος();

καθυστέρηση (4000)?

if (loopCounter> 1) {

servo_park ();

// set_arm (0, 0, 0, 0, 10); // πάρκο

καθυστέρηση (5000)?

έξοδος (0)? } // παύση προγράμματος - πατήστε επαναφορά για να συνεχίσετε

// έξοδος (0);

}

/ * ρουτίνα τοποθέτησης βραχίονα χρησιμοποιώντας αντίστροφη κινηματική */

/* z είναι ύψος, y είναι απόσταση από το κέντρο βάσης προς τα έξω, το x είναι από πλευρά σε πλευρά. y, z μπορεί να είναι μόνο θετικό */

// 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 = ακτίνια (grip_angle_d); // γωνία πρόσφυσης σε ακτίνια για χρήση σε υπολογισμούς

/ * Γωνία βάσης και ακτινική απόσταση από τις συντεταγμένες x, y */

float bas_angle_r = atan2 (x, y);

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

/ * rdist είναι y συντεταγμένη για το χέρι */

y = rdist;

/ * Οι αντισταθμίσεις πρόσφυσης υπολογίζονται με βάση τη γωνία πρόσφυσης */

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

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

/ * Θέση καρπού */

float wrist_z = (z - grip_off_z) - BASE_HGT;

float wrist_y = y - grip_off_y;

/ * Απόσταση ώμου έως καρπού (AKA sw) */

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

float s_w_sqrt = sqrt (s_w);

/ * s_w γωνία στη γείωση */

float a1 = atan2 (wrist_z, wrist_y);

/ * γωνία s_w προς βραχιόνιο βραχίονα */

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

/ * γωνία ώμου */

float shl_angle_r = a1 + a2;

float shl_angle_d = μοίρες (shl_angle_r);

/ * γωνία αγκώνα */

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

float elb_angle_d = μοίρες (elb_angle_r)?

float elb_angle_dn = - (180.0 - elb_angle_d);

/ * γωνία καρπού */

float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;

/ * Σερβο παλμοί */

float bas_servopulse = 1500,0 - ((μοίρες (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); // ενημέρωση 2018/2/11 από τον jimrd - άλλαξα το συν σε μείον - δεν είμαι σίγουρος πώς λειτουργούσε αυτός ο κώδικας για κανέναν πριν. Μπορεί το σερβο αγκώνα να έχει τοποθετηθεί με 0 μοίρες προς τα κάτω και όχι προς τα πάνω.

/ * Σετ σερβιτόρων */

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

microsecondsToDegrees = χάρτης (ftl (bas_servopulse), 544, 2400, 0, 180);

servo1.write (microsecondsToDegrees, servoSpeed); // χρησιμοποιήστε αυτήν τη λειτουργία, ώστε να μπορείτε να ρυθμίσετε την ταχύτητα σερβίς //

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

microsecondsToDegrees = χάρτης (ftl (shl_servopulse), 544, 2400, 0, 180);

servo2.write (microsecondsToDegrees, servoSpeed);

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

microsecondsToDegrees = χάρτης (ftl (elb_servopulse), 544, 2400, 0, 180);

servo3.write (microsecondsToDegrees, servoSpeed);

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

microsecondsToDegrees = χάρτης (ftl (wri_servopulse), 544, 2400, 0, 180);

servo4.write (microsecondsToDegrees, servoSpeed);

}

/ * μετακίνηση servos στη θέση στάθμευσης */

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

ΕΠΙΣΤΡΟΦΗ;

}

κενό μηδέν_x ()

{

για (διπλό yaxis = 250.0; yaxis <400.0; yaxis += 1) {

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

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

καθυστέρηση (10)?

}

για (διπλό yaxis = 400.0; yaxis> 250.0; yaxis -= 1) {

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

καθυστέρηση (10)?

}

}

/ * κινεί το χέρι σε ευθεία γραμμή */

κενή γραμμή ()

{

για (διπλό xaxis = -100,0; xaxis <100,0; xaxis += 0,5) {

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

καθυστέρηση (10)?

}

για (float xaxis = 100.0; xaxis> -100.0; xaxis -= 0.5) {

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

καθυστέρηση (10)?

}

}

κενός κύκλος ()

{

#define RADIUS 50.0

// float angle = 0;

float zaxis, yaxis?

για (γωνία πλωτήρα = 0,0; γωνία <360,0; γωνία += 1,0) {

yaxis = RADIUS * sin (ακτίνια (γωνία)) + 300;

zaxis = RADIUS * cos (ακτίνια (γωνία)) + 200;

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

καθυστέρηση (10)?

}

}

Βήμα 4: Γεγονότα, ζητήματα και τα παρόμοια…

Γεγονότα, ζητήματα και άλλα παρόμοια…
Γεγονότα, ζητήματα και άλλα παρόμοια…

1. Όταν τρέχω την υπορουτίνα του κύκλου (), το ρομπότ μου κινείται περισσότερο σε ελλειπτικό σχήμα παρά σε κύκλο. Νομίζω ότι αυτό συμβαίνει επειδή τα servos μου δεν έχουν βαθμονομηθεί. Δοκίμασα ένα από αυτά και 1500 μικροδευτερόλεπτα δεν ήταν το ίδιο με 90 μοίρες. Θα δουλέψει σε αυτό για να προσπαθήσει και να βρει μια λύση. Μην πιστεύετε ότι υπάρχει κάτι λάθος στον αλγόριθμο αλλά μάλλον στις ρυθμίσεις μου. Ενημέρωση 2018/2/11 - μόλις ανακάλυψα ότι αυτό οφείλεται σε σφάλμα στον αρχικό κώδικα. Δεν βλέπω πώς λειτούργησε το πρόγραμμά του Σταθερός κώδικας χρησιμοποιώντας αυτό: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (προστέθηκε ο αρχικός κώδικας)

2. Πού μπορώ να βρω περισσότερες πληροφορίες σχετικά με τον τρόπο λειτουργίας της λειτουργίας set_arm (): Ο ιστότοπος του Oleg Mazurov εξηγεί τα πάντα ή παρέχει συνδέσμους για περισσότερες πληροφορίες:

3. Υπάρχει έλεγχος οριακής κατάστασης; Όχι. Όταν ο βραχίονας του ρομπότ μου περάσει από έναν άκυρο συντεταγμένο xyz, κάνει αυτό το αστείο είδος αψιδωτής κίνησης σαν μια γάτα που τεντώνεται. Πιστεύω ότι ο Όλεγκ κάνει κάποιους ελέγχους στο τελευταίο του πρόγραμμα που χρησιμοποιεί USB για τον προγραμματισμό των κινήσεων των χεριών. Δείτε το βίντεό του και συνδέστε τον τελευταίο του κώδικα.

4. Ο κωδικός πρέπει να καθαριστεί και ο κωδικός μικροδευτερολέπτου μπορεί να καταργηθεί.

Συνιστάται: