Inhoudsopgave:
- Stap 1: Hardwarewijzigingen
- Stap 2: Download de VarSpeedServo-bibliotheek
- Stap 3: Voer deze schets uit
- Stap 4: Feiten, problemen en dergelijke…
Video: Arduino Uno gebruiken voor XYZ-positionering van 6 DOF-robotarmen - Ajarnpa
2024 Auteur: John Day | [email protected]. Laatst gewijzigd: 2024-01-30 11:18
Dit project gaat over het implementeren van een korte en relatief eenvoudige Arduino-schets om XYZ inverse kinematische positionering te bieden. Ik had een robotarm met 6 servo's gebouwd, maar als het erop aankwam software te vinden om het uit te voeren, was er niet veel anders dan aangepaste programma's die draaiden op aangepaste servoschilden zoals de SSC-32(U) of andere programma's en apps die waren ingewikkeld om te installeren en te communiceren met de arm. Toen vond ik Oleg Mazurov's meest uitstekende "Robotic Arm Inverse Kinematics on Arduino", waar hij inverse kinematica implementeerde in een eenvoudige Arduino-schets.
Ik heb twee wijzigingen aangebracht om zijn code aan te passen:
1. Ik gebruikte de VarSpeedServo-bibliotheek in plaats van zijn aangepaste servoschildbibliotheek, omdat ik dan de snelheid van de servo's kon regelen en ik het servoschild dat hij gebruikte niet zou hoeven gebruiken. Voor iedereen die overweegt de hier verstrekte code uit te voeren, raad ik u aan deze VarSpeedServo-bibliotheek te gebruiken in plaats van de servo.h-bibliotheek, zodat u de beweging van uw robotarm tijdens de ontwikkeling kunt vertragen of u kunt ontdekken dat de arm u onverwachts naar binnen steekt het gezicht of erger omdat het op volle servosnelheid zal bewegen.
2. Ik gebruik een eenvoudige sensor / servo-schild om de servo's op de Arduino Uno aan te sluiten, maar het vereist geen speciale servo-bibliotheek omdat het alleen de pinnen van de Arduino gebruikt. Het kost maar een paar tientjes, maar het is niet nodig. Het zorgt voor een mooie schone verbinding van de servo's met de Arduino. En ik zal nu nooit meer teruggaan naar het bedraden van servo's naar de Arduino Uno. Als u deze sensor/servo-afscherming gebruikt, moet u een kleine wijziging aanbrengen die ik hieronder zal beschrijven.
De code werkt geweldig en stelt u in staat de arm te bedienen met een enkele functie waarin u de x-, y-, x- en snelheidsparameters doorgeeft. Bijvoorbeeld:
set_arm (0, 240, 100, 0, 20); // parameters zijn (x, y, z, grijperhoek, servosnelheid)
vertraging (3000); // vertraging is vereist om de arm de tijd te geven om naar deze locatie te gaan
Eenvoudiger kan niet. Ik zal de schets hieronder toevoegen.
Oleg's video is hier: Robotarm besturen met Arduino en USB-muis
Oleg's originele programma, beschrijvingen en bronnen: Oleg's Inverse Kinematics voor Arduino Uno
Ik begrijp niet alle wiskunde achter de routine, maar het leuke is dat je de code niet hoeft te gebruiken. Hoop dat je het eens wilt proberen.
Stap 1: Hardwarewijzigingen
1. Het enige dat nodig is, is dat uw servo in de verwachte richtingen draait, waardoor u mogelijk de montage van uw servo's fysiek moet omkeren. Ga naar deze pagina om de verwachte servorichting voor basis-, schouder-, elleboog- en polsservo's te zien:
2. Als je het sensorschild gebruikt dat ik gebruik, moet je er één ding aan doen: buig de pin die de 5v van het schild naar de Arduino Uno verbindt, uit de weg zodat deze geen verbinding maakt met het Uno-bord. U wilt de externe spanning op het schild gebruiken om alleen uw servo's van stroom te voorzien, niet de Arduino Uno of het kan de Uno vernietigen, ik weet dat ik twee Uno-kaarten heb verbrand toen mijn externe spanning 6 volt was in plaats van 5. Dit stelt u in staat om hoger dan 5 V te gebruiken om uw servo's van stroom te voorzien, maar als uw externe spanning hoger is dan 5 volt, sluit dan geen 5 volt-sensoren aan op het schild of ze zullen worden gebakken.
Stap 2: Download de VarSpeedServo-bibliotheek
U moet deze bibliotheek gebruiken die de standaard arduino-servobibliotheek vervangt, omdat u hiermee een servosnelheid in de servo-schrijfinstructie kunt doorgeven. De bibliotheek is hier gevestigd:
VarSpeedServo-bibliotheek
Je kunt gewoon de zip-knop gebruiken, het zip-bestand downloaden en vervolgens installeren met de Arduino IDE. Na installatie ziet het commando in uw programma er als volgt uit: servo.write(100, 20);
De eerste parameter is de hoek en de tweede is de snelheid van de servo van 0 tot 255 (volledige snelheid).
Stap 3: Voer deze schets uit
Hier is het wedstrijdprogramma. U moet een paar parameters wijzigen voor de afmetingen van uw robotarm:
1. BASE_HGT, HUMERUS, ULNA, GRIPPER lengtes in millimeters.
2. Voer uw servo-pinnummers in
3. Voer de servo min en max in de bijlagenverklaringen in.
4. Probeer vervolgens een eenvoudige opdracht set_arm() en vervolgens de functies zero_x(), line() en circle() om te testen. Zorg ervoor dat uw servosnelheid laag is wanneer u deze functies voor het eerst uitvoert om schade aan uw arm en uw eigen arm te voorkomen.
Veel geluk.
#include VarSpeedServo.h
/* Servobesturing voor AL5D-arm */
/* Armafmetingen (mm) */
#define BASE_HGT 90 // basishoogte
#define HUMERUS 100 //schouder-tot-elleboog "bot"
#define ULNA 135 //elleboog-naar-pols "bot"
#define GRIPPER 200 //gripper (incl. heavy duty polsrotatiemechanisme) lengte"
#define ftl(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) //float naar long conversie
/* Servonamen/nummers *
* Basisservo HS-485HB */
#define BAS_SERVO 4
/* Schouderservo HS-5745-MG */
#define SHL_SERVO 5
/* Elleboogservo HS-5745-MG */
#define ELB_SERVO 6
/* Polsservo HS-645MG */
#define WRI_SERVO 7
/* Polsrotatieservo HS-485HB */
#define WRO_SERVO 8
/* Grijperservo HS-422 */
#define GRI_SERVO 9
/* voorcalculaties */
float hum_sq = HUMERUS*HUMERUS;
float uln_sq = ULNA*ULNA;
int servoSnelheid = 10;
//ServoShield-servo's; //ServoShield-object
VarSpeedServo servo1, servo2, servo3, servo4, servo5, servo6;
int loopCounter=0;
int pulseWidth = 6,6;
int microsecondenToDegrees;
ongeldige 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);
vertraging (5500);
//servo's.start(); //Start het servo-schild
servo_park();
vertraging (4000);
Serieel.begin(9600);
Serial.println("Start");
}
lege lus()
{
loopCounter +=1;
//set_arm (-300, 0, 100, 0, 10); //
//vertraging (7000);
//nul_x();
//lijn();
//cirkel();
vertraging (4000);
if (loopCounter > 1) {
servo_park();
//set_arm (0, 0, 0, 0, 10); // parkeren
vertraging (5000);
uitgang(0); }//pauzeer programma - druk op reset om door te gaan
//afsluiten (0);
}
/* armpositioneringsroutine met behulp van inverse kinematica */
/* z is hoogte, y is afstand van het middelpunt van de basis naar buiten, x is van links naar rechts. y, z kan alleen positief zijn */
// ongeldig 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 = radialen(grip_angle_d); // grijphoek in radialen voor gebruik in berekeningen
/* Basishoek en radiale afstand van x, y-coördinaten */
float bas_angle_r = atan2(x, y);
float rdist = sqrt((x * x) + (y * y));
/* rdist is de y-coördinaat voor de arm */
y = rdst;
/* Grip-offsets berekend op basis van griphoek */
float grip_off_z = (sin(grip_angle_r)) * GRIPPER;
float grip_off_y = (cos(grip_angle_r)) * GRIPPER;
/* Polshouding */
float pols_z = (z - grip_off_z) - BASE_HGT;
float pols_y = y - grip_off_y;
/* Afstand schouder tot pols (AKA sw) */
float s_w = (pols_z * pols_z) + (pols_y * pols_y);
float s_w_sqrt = sqrt(s_w);
/* s_w hoek naar de grond */
float a1 = atan2(pols_z, pols_y);
/* s_w hoek naar opperarmbeen */
float a2 = acos(((hum_sq - uln_sq) + s_w) / (2 * HUMERUS * s_w_sqrt));
/* schouderhoek */
float shl_angle_r = a1 + a2;
float shl_angle_d = graden (shl_angle_r);
/* elleboog hoek */
float elb_angle_r = acos((hum_sq + uln_sq - s_w) / (2 * HUMERUS * ULNA));
float elb_angle_d = graden (elb_angle_r);
float elb_angle_dn = -(180.0 - elb_angle_d);
/* polshoek */
float wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;
/* Servopulsen */
float bas_servopulse = 1500,0 - ((graden (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);// bijgewerkt 2018/2/11 door jimrd - ik heb de plus in een min veranderd - ik weet niet zeker hoe deze code eerder voor iemand werkte. Het kan zijn dat de elleboogservo met 0 graden naar beneden is gemonteerd in plaats van omhoog.
/* Stel servo's in */
//servos.setposition (BAS_SERVO, ftl (bas_servopulse));
microsecondenToDegrees = map(ftl(bas_servopulse), 544, 2400, 0, 180);
servo1.write (microsecondenToDegrees, servoSpeed); // gebruik deze functie zodat je de servosnelheid kunt instellen //
//servo's.setposition (SHL_SERVO, ftl (shl_servopulse));
microsecondenToDegrees = map(ftl(shl_servopulse), 544, 2400, 0, 180);
servo2.write (microsecondenToDegrees, servoSpeed);
//servo's.setposition (ELB_SERVO, ftl (elb_servopulse));
microsecondenToDegrees = map(ftl(elb_servopulse), 544, 2400, 0, 180);
servo3.write (microsecondenToDegrees, servoSpeed);
//servos.setposition (WRI_SERVO, ftl (wri_servopulse));
microsecondenToDegrees = map(ftl(wri_servopulse), 544, 2400, 0, 180);
servo4.write (microsecondenToDegrees, servoSpeed);
}
/* verplaats servo's naar parkeerpositie */
ongeldig servo_park()
{
//servo's.setposition (BAS_SERVO, 1500);
servo1.write(90, 10);
//servo's.setposition (SHL_SERVO, 2100);
servo2.write(90, 10);
//servo's.setposition (ELB_SERVO, 2100);
servo3.write(90, 10);
//servo's.setposition (WRI_SERVO, 1800);
servo4.write(90, 10);
//servo's.setposition (WRO_SERVO, 600);
servo5.write(90, 10);
//servo's.setposition (GRI_SERVO, 900);
servo6.write(80, 10);
opbrengst;
}
ongeldig nul_x()
{
voor (dubbele y-as = 250,0; y-as < 400,0; y-as += 1) {
Serial.print(" yaxis=: ");Serial.println(yaxis);
set_arm (0, yaxis, 200,0, 0, 10);
vertraging(10);
}
voor (dubbele y-as = 400,0; y-as > 250,0; y-as -= 1) {
set_arm (0, yaxis, 200,0, 0, 10);
vertraging(10);
}
}
/* beweegt arm in een rechte lijn */
lege regel()
{
voor (dubbele x-as = -100,0; x-as < 100,0; x-as += 0,5) {
set_arm(xas, 250, 120, 0, 10);
vertraging(10);
}
for(float x-as = 100,0; x-as > -100,0; x-as -= 0,5) {
set_arm(xas, 250, 120, 0, 10);
vertraging(10);
}
}
lege cirkel()
{
#define RADIUS 50.0
// zweefhoek = 0;
zweven zaxis, yaxis;
for(zweefhoek = 0,0; hoek < 360,0; hoek += 1,0) {
yaxis = RADIUS * sin(radialen(hoek)) + 300;
zaxis = RADIUS * cos(radialen(hoek)) + 200;
set_arm (0, yaxis, zaxis, 0, 50);
vertraging(10);
}
}
Stap 4: Feiten, problemen en dergelijke…
1. Als ik de cirkel()-subroutine gebruik, beweegt mijn robot meer in een elliptische vorm dan in een cirkel. Ik denk dat dat komt omdat mijn servo's niet zijn gekalibreerd. Ik heb er een getest en 1500 microseconden was niet hetzelfde als 90 graden. Zal hieraan werken om te proberen een oplossing te vinden. Geloof niet dat er iets mis is met het algoritme, maar eerder met mijn instellingen. Update 2018/2/11 - zojuist ontdekt dat dit te wijten is aan een fout in de originele code. Ik zie niet hoe zijn programma werkte Vaste code die dit gebruikt: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (originele code werd toegevoegd)
2. Waar kan ik meer informatie vinden over hoe de set_arm() functie werkt: De website van Oleg Mazurov legt alles uit of biedt links voor meer info:
3. Is er sprake van randvoorwaardencontrole? Nee. Als mijn robotarm een ongeldige xyz-coördinaat passeert, maakt hij een grappige boogbeweging als een kat die zich uitrekt. Ik geloof dat Oleg wel wat checkt in zijn nieuwste programma dat een USB gebruikt om de armbewegingen te programmeren. Bekijk zijn video en link naar zijn laatste code.
4. De code moet worden opgeschoond en de microsecondecode kan worden afgeschaft.
Aanbevolen:
Hoe de GPIO-pinnen en Avrdude van een Raspberry Pi te gebruiken om DIMP 2 of DA PIMP te Bit-bang-programma te gebruiken 2: 9 stappen
Hoe de GPIO-pinnen van een Raspberry Pi en Avrdude te gebruiken voor Bit-bang-programma DIMP 2 of DA PIMP 2: Dit zijn stapsgewijze instructies voor het gebruik van een Raspberry Pi en het gratis open-source commando avrdude to bit-bang -programmeer een DIMP 2 of DA PIMP 2. Ik neem aan dat je bekend bent met je Raspberry Pi en de LINUX-opdrachtregel. Je hoeft niet
Idee voor doe-het-zelf-activiteit voor weerstations voor 12+ jaar: 4 stappen
Idee voor doe-het-zelf-weerstationactiviteit voor 12-plussers: in deze activiteit zullen deelnemers hun weerstation opzetten, de lucht in sturen en de opnames (licht, temperatuur, vochtigheid) in realtime volgen via de Blynk-app. Bovendien leert u hoe u de geregistreerde waarden publiceert
Mac Terminal gebruiken en toetsfuncties gebruiken: 4 stappen
Mac Terminal gebruiken en toetsfuncties gebruiken: We laten u zien hoe u de MAC Terminal opent. We zullen u ook enkele functies binnen de Terminal laten zien, zoals ifconfig, mappen wijzigen, toegang tot bestanden en arp. Met Ifconfig kunt u uw IP-adres en uw MAC-advertentie controleren
Verdubbel de levensduur van de batterij van de DX3-radio van Spektrum voor minder dan $ 20: 11 stappen
Verdubbel de levensduur van de batterij van de DX3-radio van Spektrum voor minder dan $ 20: ik kreeg het idee hiervoor voor het eerst op de draad voor de DX6/7 op RCGRoups.com-forums. Ik rijd met nitro-auto's, dus kocht ik een DX3. Ik heb de radio een tijdje gebruikt en mijn batterijduur was aan de betere kant van de meeste radio's - maar de DX7-bezitters begonnen
Overtuig uzelf om gewoon een 12V-naar-AC-lijnomvormer te gebruiken voor LED-lichtsnoeren in plaats van ze opnieuw te bedraden voor 12V: 3 stappen
Overtuig uzelf om gewoon een 12V-naar-AC-lijnomvormer te gebruiken voor LED-lichtsnoeren in plaats van ze opnieuw te bedraden voor 12V.: Mijn plan was eenvoudig. Ik wilde een door de muur aangedreven LED-lichtsnoer in stukken knippen en vervolgens opnieuw bedraden om 12 volt te laten lopen. Het alternatief was om een omvormer te gebruiken, maar we weten allemaal dat ze vreselijk inefficiënt zijn, toch? Rechts? Of zijn ze?