Indholdsfortegnelse:
- Trin 1: Hardwaremodifikationer
- Trin 2: Download VarSpeedServo -biblioteket
- Trin 3: Kør denne skitse
- Trin 4: Fakta, spørgsmål og lignende …
Video: Brug af Arduino Uno til XYZ Positionering af 6 DOF robotarm: 4 trin
2024 Forfatter: John Day | [email protected]. Sidst ændret: 2024-01-30 08:29
Dette projekt handler om at implementere en kort og relativt let Arduino -skitse til at give XYZ invers kinematisk positionering. Jeg havde bygget en 6 servo robotarm, men da det kom til at finde software til at køre den, var der ikke meget derude bortset fra brugerdefinerede programmer, der kørte på brugerdefinerede servoskærme som SSC-32 (U) eller andre programmer og apps, der var kompliceret at installere og kommunikere med armen. Derefter fandt jeg Oleg Mazurovs mest fremragende "Robotic Arm Inverse Kinematics on Arduino", hvor han implementerede invers kinematik i en simpel Arduino -skitse.
Jeg lavede to ændringer for at tilpasse hans kode:
1. Jeg brugte VarSpeedServo -biblioteket i stedet for hans brugerdefinerede servoskærmbibliotek, fordi jeg derefter kunne kontrollere servoernes hastighed, og jeg ikke skulle bruge det servoskærm, han brugte. For alle, der overvejer at køre koden her, anbefaler jeg, at du bruger dette VarSpeedServo -bibliotek frem for servo.h -biblioteket, så du kan bremse din robotarmbevægelse under udviklingen, eller du kan opleve, at armen uventet vil stikke dig ind ansigtet eller værre, fordi det vil bevæge sig ved fuld servohastighed.
2. Jeg bruger en simpel sensor/servoskærm til at forbinde servoerne til Arduino Uno, men det kræver ikke noget specielt servobibliotek, da det bare bruger Arduino's pins. Det koster kun et par kroner, men det er ikke påkrævet. Det giver en dejlig ren forbindelse af servoerne til Arduino. Og jeg vil aldrig gå tilbage til hardwiring servoer til Arduino Uno nu. Hvis du bruger denne sensor/servoskærm, skal du foretage en mindre ændring, som jeg vil skitsere nedenfor.
Koden fungerer godt og giver dig mulighed for at betjene armen ved hjælp af en enkelt funktion, hvor du sender parametrene x, y, x og hastighed. For eksempel:
set_arm (0, 240, 100, 0, 20); // parametre er (x, y, z, gribervinkel, servohastighed)
forsinkelse (3000); // forsinkelse er påkrævet for at tillade armtid at flytte til dette sted
Kunne ikke være enklere. Jeg vil inkludere skitsen herunder.
Olegs video er her: Styring af robotarm med Arduino og USB -mus
Olegs originale program, beskrivelser og ressourcer: Oleg's Inverse Kinematics for Arduino Uno
Jeg forstår ikke al matematik bag rutinen, men det gode er, at du ikke behøver at bruge koden. Håber du vil prøve det.
Trin 1: Hardwaremodifikationer
1. Det eneste, der kræves, er, at din servo drejer i de forventede retninger, hvilket kan kræve, at du fysisk vender monteringen af dine servoer tilbage. Gå til denne side for at se den forventede servoretning for baser, skuldre, albuer og håndledsservoer:
2. Hvis du bruger det sensorskjold, som jeg bruger, skal du gøre en ting ved det: bøj stiften, der forbinder 5v fra skjoldet til Arduino Uno, så den ikke kan tilsluttes Uno -kortet. Du vil bruge den eksterne spænding på skjoldet til kun at drive dine servoer, ikke Arduino Uno, eller det kan ødelægge Uno, jeg ved, da jeg brændte to Uno -kort op, da min eksterne spænding var 6 volt i stedet for 5. Dette giver dig mulighed for at bruge højere end 5v til at drive dine servoer, men hvis din eksterne spænding er højere end 5 volt, skal du ikke tilslutte nogen 5 volt sensorer til skjoldet, ellers bliver de stegt.
Trin 2: Download VarSpeedServo -biblioteket
Du skal bruge dette bibliotek, der erstatter det normale arduino servobibliotek, fordi det giver dig mulighed for at videregive en servohastighed til servoskrivningssætningen. Biblioteket ligger her:
VarSpeedServo -bibliotek
Du kan bare bruge zip -knappen, downloade zip -filen og derefter installere den med Arduino IDE. Når den er installeret, ser kommandoen i dit program ud: servo.write (100, 20);
Den første parameter er vinklen, og den anden er servoens hastighed fra 0 til 255 (fuld hastighed).
Trin 3: Kør denne skitse
Her er konkurrenceprogrammet. Du skal ændre et par parametre for dine robotarmdimensioner:
1. BASE_HGT, HUMERUS, ULNA, GRIPPER længder i millimeter.
2. Indtast dine servopindnumre
3. Indtast servo min og max i vedhæftede udsagn.
4. Prøv derefter en simpel kommando set_arm () og derefter funktionerne zero_x (), line () og circle () til test. Sørg for, at din servohastighed er lav første gang du kører disse funktioner for at forhindre skade på din arm og din egen arm.
Held og lykke.
#omfatter VarSpeedServo.h
/ * Servokontrol til AL5D -arm */
/ * Armmål (mm) */
#define BASE_HGT 90 // basishøjde
#define HUMERUS 100 // skulder-til-albue "knogle"
#define ULNA 135 // albue-til-håndled "knogle"
#define GRIPPER 200 // griber (inkl. kraftig håndledsrotationsmekanisme) længde"
#define ftl (x) ((x)> = 0? (long) ((x) +0.5):(long) ((x) -0.5)) // float to long conversion
/ * Servo navne/numre *
* Base servo 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åndledsservo HS-645MG */
#define WRI_SERVO 7
/ * Håndled roter servo HS-485HB */
#define WRO_SERVO 8
/ * Gripper servo HS-422 */
#define GRI_SERVO 9
/ * forberegninger */
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 opsætning ()
{
servo1. vedhæfte (BAS_SERVO, 544, 2400);
servo2.attach (SHL_SERVO, 544, 2400);
servo3. vedhæfte (ELB_SERVO, 544, 2400);
servo4.attach (WRI_SERVO, 544, 2400);
servo5.attach (WRO_SERVO, 544, 2400);
servo6. vedhæfte (GRI_SERVO, 544, 2400);
forsinkelse (5500);
//servos.start (); // Start servoskjoldet
servo_park ();
forsinkelse (4000);
Serial.begin (9600);
Serial.println ("Start");
}
hulrum ()
{
loopCounter += 1;
// sæt_arm (-300, 0, 100, 0, 10); //
// forsinkelse (7000);
// zero_x ();
// linje ();
//cirkel();
forsinkelse (4000);
hvis (loopCounter> 1) {
servo_park ();
// sæt_arm (0, 0, 0, 0, 10); // park
forsinkelse (5000);
exit (0); } // pause program - tryk på nulstil for at fortsætte
// exit (0);
}
/ * armpositioneringsrutine ved hjælp af omvendt kinematik */
/* z er højden, y er afstanden fra basen midt ud, x er side til side. y, z kan kun 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); // grebsvinkel i radianer til brug i beregninger
/ * Grundvinkel og radial afstand 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;
/ * Grebsforskydninger beregnet ud fra grebsvinklen */
float grip_off_z = (sin (grip_angle_r)) * GRIPPER;
float grip_off_y = (cos (grip_angle_r)) * GRIPPER;
/ * Håndledsstilling */
float wrist_z = (z - grip_off_z) - BASE_HGT;
float wrist_y = y - grip_off_y;
/ * Skulder til håndled afstand (AKA sw) */
float s_w = (wrist_z * wrist_z) + (wrist_y * wrist_y);
float s_w_sqrt = sqrt (s_w);
/ * s_w vinkel til jorden */
float a1 = atan2 (wrist_z, wrist_y);
/ * s_w vinkel til humerus */
float 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åndledsvinkel */
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); // opdateret 2018/2/11 af jimrd - jeg ændrede pluset til et minus - ved ikke hvordan denne kode fungerede for nogen før. Kan være, at albueservoen var monteret med 0 grader nedad frem for opad.
/ * Sæt servoer */
//servos.setposition(BAS_SERVO, ftl (bas_servopulse));
microsecondsToDegrees = map (ftl (bas_servopulse), 544, 2400, 0, 180);
servo1.write (microsecondsToDegrees, servoSpeed); // brug denne funktion, så du kan indstille servohastighed //
//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);
}
/ * flyt servoer til parkeringsposition */
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.skriv (90, 10);
//servos.setposition(GRI_SERVO, 900);
servo6.write (80, 10);
Vend tilbage;
}
ugyldig zero_x ()
{
for (dobbelt 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 (dobbelt yaxis = 400,0; yaxis> 250,0; yaxis -= 1) {
set_arm (0, yaxis, 200,0, 0, 10);
forsinkelse (10);
}
}
/ * bevæger armen i en lige linje */
tom linje ()
{
for (dobbelt 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);
}
}
hulrum ()
{
#define RADIUS 50.0
// flydevinkel = 0;
float zaxis, yaxis;
for (flydevinkel = 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);
}
}
Trin 4: Fakta, spørgsmål og lignende …
1. Når jeg kører cirklen () underrutine, bevæger min robot sig mere i en elliptisk form end en cirkel. Jeg tror, det er fordi mine servoer ikke er kalibreret. Jeg testede en af dem, og 1500 mikrosekunder var ikke det samme som 90 grader. Vil arbejde på dette for at forsøge at finde en løsning. Tro ikke, at der er noget galt med algoritmen, men derimod med mine indstillinger. Opdatering 2018/2/11 - opdagede lige, at dette skyldes fejl i den originale kode. Jeg kan ikke se, hvordan hans program fungerede Fixed code using this: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (den originale kode tilføjede)
2. Hvor kan jeg finde mere information om, hvordan funktionen set_arm () fungerer: Oleg Mazurovs websted forklarer alt eller giver links til mere info:
3. Er der nogen grænsetilstandskontrol? Nej. Når min robotarm passeres, får en ugyldig xyz -koordinat denne sjove slags buebevægelse som en kat, der strækker sig. Jeg tror, at Oleg tjekker noget i sit seneste program, der bruger en USB til at programmere armbevægelserne. Se hans video og link til hans seneste kode.
4. Koden skal ryddes op, og mikrosekundskoden kan fjernes.
Anbefalede:
Billig NMEA/AIS Hub - RS232 til Wifi Bridge til brug ombord: 6 trin
Billig NMEA /AIS Hub - RS232 til Wifi Bridge til brug ombord: Opdater 9. januar 2021 - Tilføjet ekstra TCP -forbindelse og genbrug sidste forbindelse, hvis flere klienter opretter Opdatering 13. december 2020 - Tilføjet ingen konfigurationsversion af koden til både med eksisterende routere Introduktion Denne NMEA / AIS RS232 til WiFi -bro er
I2C / IIC LCD -skærm - Brug et SPI LCD til I2C LCD Display Brug SPI til IIC modul med Arduino: 5 trin
I2C / IIC LCD -skærm | Brug en SPI LCD til I2C LCD -skærmen Brug af SPI til IIC -modulet med Arduino: Hej fyre, da en normal SPI LCD 1602 har for mange ledninger at tilslutte, så det er meget svært at grænseflade det med arduino, men der er et modul på markedet, som kan konverter SPI -skærm til IIC -skærm, så du skal kun tilslutte 4 ledninger
Neopixel Ws2812 Rainbow LED Glød Med M5stick-C - Kører Rainbow på Neopixel Ws2812 Brug af M5stack M5stick C Brug af Arduino IDE: 5 trin
Neopixel Ws2812 Rainbow LED Glød Med M5stick-C | Kører Rainbow på Neopixel Ws2812 Brug af M5stack M5stick C Brug af Arduino IDE: Hej fyre i denne instruktion vil vi lære at bruge neopixel ws2812 LED'er eller led strip eller led matrix eller led ring med m5stack m5stick-C udviklingstavle med Arduino IDE, og vi vil lave et regnbuemønster med det
Brug 1 analog indgang til 6 knapper til Arduino: 6 trin
Brug 1 analog indgang til 6 knapper til Arduino: Jeg har ofte spekuleret på, hvordan jeg kunne få flere digitale indgange til min Arduino. Det gik for nylig op for mig, at jeg skulle kunne bruge en af de analoge indgange til at indføre flere digitale input. Jeg lavede en hurtig søgning og fandt ud af, hvor folk var
Orange PI HowTo: Konfigurer den til brug sammen med bilens bagskærm og HDMI til RCA -adapter: 15 trin
Orange PI Sådan gør du det: Brug det med bilens bagskærm og HDMI til RCA -adapter: FOREWORD. Det ser ud til, at hver anden bruger et stort og endnu større tv -apparat eller en skærm med et fjollet Orange PI -kort. Og det ligner lidt overkill, når det er beregnet til integrerede systemer. Her har vi brug for noget lille og noget billigt. Som en