Tabla de contenido:
- Paso 1: Modificaciones de hardware
- Paso 2: Descargue la biblioteca VarSpeedServo
- Paso 3: ejecuta este boceto
- Paso 4: Hechos, problemas y similares …
Video: Uso de Arduino Uno para el posicionamiento XYZ de un brazo robótico de 6 DOF: 4 pasos
2024 Autor: John Day | [email protected]. Última modificación: 2024-01-30 08:43
Este proyecto trata de implementar un boceto Arduino corto y relativamente fácil para proporcionar un posicionamiento cinemático inverso XYZ. Había construido un brazo robótico de 6 servos, pero cuando se trataba de encontrar software para ejecutarlo, no había mucho por ahí, excepto los programas personalizados que se ejecutaban en escudos de servo personalizados como el SSC-32 (U) u otros programas y aplicaciones que estaban disponibles. complicado de instalar y comunicar con el brazo. Luego encontré la más excelente "Cinemática inversa del brazo robótico en Arduino" de Oleg Mazurov, donde implementó la cinemática inversa en un simple boceto de Arduino.
Hice dos modificaciones para adaptar su código:
1. Usé la biblioteca VarSpeedServo en lugar de su biblioteca personalizada de servo shield porque entonces podía controlar la velocidad de los servos y no tendría que usar el servo shield que él usaba. Para cualquiera que esté considerando ejecutar el código proporcionado aquí, le recomiendo que use esta biblioteca VarSpeedServo, en lugar de la biblioteca servo.h, para que pueda ralentizar el movimiento de su brazo robótico durante el desarrollo o puede encontrar que el brazo lo empujará inesperadamente la cara o algo peor porque se moverá a la máxima velocidad del servo.
2. Utilizo un protector de sensor / servo simple para conectar los servos al Arduino Uno, pero no requiere una biblioteca de servos especial, ya que solo usa los pines de Arduino. Solo cuesta unos pocos dólares, pero no es obligatorio. Hace una buena conexión limpia de los servos al Arduino. Y nunca volveré a conectar los servos al Arduino Uno ahora. Si usa este protector de sensor / servo, debe hacer una modificación menor que describiré a continuación.
El código funciona muy bien y le permite operar el brazo usando una sola función en la que pasa los parámetros x, y, x y velocidad. Por ejemplo:
set_arm (0, 240, 100, 0, 20); // los parámetros son (x, y, z, ángulo de agarre, velocidad del servo)
retraso (3000); // se requiere un retraso para permitir que el tiempo de armado se mueva a esta ubicación
No podría ser más sencillo. Incluiré el boceto a continuación.
El video de Oleg está aquí: Control del brazo robótico con Arduino y mouse USB
Programa, descripciones y recursos originales de Oleg: Cinemática inversa de Oleg para Arduino Uno
No entiendo todas las matemáticas detrás de la rutina, pero lo bueno es que no tienes que usar el código. Espero que lo pruebes.
Paso 1: Modificaciones de hardware
1. Lo único que se requiere es que su servo gire en las direcciones esperadas, lo que podría requerir que invierta físicamente el montaje de sus servos. Vaya a esta página para ver la dirección de servo esperada para los servos de base, hombro, codo y muñeca:
2. Si usa el protector del sensor que estoy usando, debe hacer una cosa: doble el pin que conecta el 5v del protector al Arduino Uno para que no se conecte a la placa Uno. Desea usar el voltaje externo en el escudo para alimentar solo sus servos, no el Arduino Uno o puede destruir el Uno, sé que quemé dos placas Uno cuando mi voltaje externo era de 6 voltios en lugar de 5. Esto le permite usar más de 5v para alimentar sus servos, pero si su voltaje externo es superior a 5 voltios, no conecte ningún sensor de 5 voltios al escudo o se quemarán.
Paso 2: Descargue la biblioteca VarSpeedServo
Necesita usar esta biblioteca que reemplaza la biblioteca de servos arduino estándar porque le permite pasar una velocidad de servo a la declaración de escritura del servo. La biblioteca se encuentra aquí:
Biblioteca VarSpeedServo
Puede usar el botón zip, descargar el archivo zip y luego instalarlo con el IDE de Arduino. Una vez instalado, el comando en su programa se verá así: servo.write (100, 20);
El primer parámetro es el ángulo y el segundo es la velocidad del servo de 0 a 255 (velocidad máxima).
Paso 3: ejecuta este boceto
Aquí está el programa competir. Necesita modificar algunos parámetros para las dimensiones de su brazo robótico:
1. BASE_HGT, HUMERUS, ULNA, GRIPPER longitudes en milímetros.
2. Ingrese sus números de pin de servo
3. Ingrese el servo mínimo y máximo en las declaraciones adjuntas.
4. Luego intente un simple comando set_arm () y luego las funciones zero_x (), line () y circle () para probar. Asegúrese de que la velocidad de su servo sea baja la primera vez que ejecute estas funciones para evitar dañar su brazo y su propio brazo.
Buena suerte.
#include VarSpeedServo.h
/ * Servocontrol para brazo AL5D * /
/ * Dimensiones del brazo (mm) * /
#define BASE_HGT 90 // altura de la base
#define HUMERUS 100 // "hueso" de hombro a codo
#define ULNA 135 // "hueso" de codo a muñeca
#define GRIPPER 200 // longitud de la pinza (incluido el mecanismo de rotación de muñeca para trabajos pesados)"
#define ftl (x) ((x)> = 0? (long) ((x) +0.5):(long) ((x) -0.5)) // conversión flotante a larga
/ * Nombres / números de servo *
* Base servo HS-485HB * /
#define BAS_SERVO 4
/ * Servo de hombro HS-5745-MG * /
#define SHL_SERVO 5
/ * Servo acodado HS-5745-MG * /
#define ELB_SERVO 6
/ * Servo de muñeca HS-645MG * /
#define WRI_SERVO 7
/ * Servo giratorio de muñeca HS-485HB * /
#define WRO_SERVO 8
/ * Servo de pinza HS-422 * /
#define GRI_SERVO 9
/ * pre-cálculos * /
flotar hum_sq = HUMERUS * HUMERUS;
flotar uln_sq = ULNA * ULNA;
int servoSPeed = 10;
// Servos ServoShield; // Objeto ServoShield
VarSpeedServo servo1, servo2, servo3, servo4, servo5, servo6;
int loopCounter = 0;
int pulseWidth = 6.6;
int microsecondsToDegrees;
configuración vacía ()
{
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);
retraso (5500);
//servos.start (); // Iniciar el servo escudo
servo_park ();
retraso (4000);
Serial.begin (9600);
Serial.println ("Inicio");
}
bucle vacío ()
{
contador de bucles + = 1;
// set_arm (-300, 0, 100, 0, 10); //
// retraso (7000);
// zero_x ();
//línea();
//circulo();
retraso (4000);
if (loopCounter> 1) {
servo_park ();
// set_arm (0, 0, 0, 0, 10); // parque
retraso (5000);
salir (0); } // pausar el programa - presione reiniciar para continuar
// salir (0);
}
/ * Rutina de posicionamiento del brazo utilizando cinemática inversa * /
/ * z es la altura, y es la distancia desde el centro de la base hacia afuera, x es de lado a lado. y, z solo puede ser positivo * /
// 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 = radianes (grip_angle_d); // ángulo de agarre en radianes para usar en cálculos
/ * Ángulo base y distancia radial desde las coordenadas x, y * /
float bas_angle_r = atan2 (x, y);
flotar rdist = sqrt ((x * x) + (y * y));
/ * rdist es la coordenada y para el brazo * /
y = rdist;
/ * Compensaciones de agarre calculadas según el ángulo de agarre * /
flotador grip_off_z = (sin (grip_angle_r)) * PINZA;
flotador grip_off_y = (cos (grip_angle_r)) * PINZA;
/ * Posición de la muñeca * /
flotar muñeca_z = (z - grip_off_z) - BASE_HGT;
flotar muñeca_y = y - grip_off_y;
/ * Distancia de hombro a muñeca (AKA sw) * /
flotar s_w = (muñeca_z * muñeca_z) + (muñeca_y * muñeca_y);
flotar s_w_sqrt = sqrt (s_w);
/ * s_w ángulo al suelo * /
flotar a1 = atan2 (muñeca_z, muñeca_y);
/ * ángulo s_w al húmero * /
flotar a2 = acos (((hum_sq - uln_sq) + s_w) / (2 * HUMERUS * s_w_sqrt));
/ * ángulo del hombro * /
flotador shl_angle_r = a1 + a2;
flotar shl_angle_d = grados (shl_angle_r);
/ * ángulo del codo * /
flotar elb_angle_r = acos ((hum_sq + uln_sq - s_w) / (2 * HUMERUS * ULNA));
flotar elb_angle_d = grados (elb_angle_r);
flotar elb_angle_dn = - (180.0 - elb_angle_d);
/ * ángulo de la muñeca * /
flotar wri_angle_d = (grip_angle_d - elb_angle_dn) - shl_angle_d;
/ * Servo pulsos * /
float bas_servopulse = 1500.0 - ((grados (bas_angle_r)) * pulseWidth);
flotador shl_servopulse = 1500.0 + ((shl_angle_d - 90.0) * ancho de pulso);
float elb_servopulse = 1500.0 - ((elb_angle_d - 90.0) * pulseWidth);
// flotar wri_servopulse = 1500 + (wri_angle_d * pulseWidth);
// flotar wri_servopulse = 1500 + (wri_angle_d * pulseWidth);
float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); // actualizado 2018/2/11 por jimrd - cambié el más a un menos - no estoy seguro de cómo funcionó este código para nadie antes. Podría ser que el servo del codo estuviera montado con 0 grados hacia abajo en lugar de hacia arriba.
/ * Establecer servos * /
//servos.setposition(BAS_SERVO, ftl (bas_servopulse));
microsecondsToDegrees = map (ftl (bas_servopulse), 544, 2400, 0, 180);
servo1.write (microsecondsToDegrees, servoSpeed); // use esta función para que pueda configurar la velocidad del servo //
//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));
microsegundos a grados = mapa (ftl (wri_servopulse), 544, 2400, 0, 180);
servo4.write (microsecondsToDegrees, servoSpeed);
}
/ * mover los servos a la posición de estacionamiento * /
vacío 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);
regreso;
}
vacío zero_x ()
{
para (eje de doble eje = 250,0; eje de eje <400,0; eje de eje + = 1) {
Serial.print ("yaxis =:"); Serial.println (yaxis);
set_arm (0, yaxis, 200.0, 0, 10);
retraso (10);
}
para (eje de doble eje = 400,0; eje de eje> 250,0; eje de eje - = 1) {
set_arm (0, yaxis, 200.0, 0, 10);
retraso (10);
}
}
/ * mueve el brazo en línea recta * /
línea vacía ()
{
para (doble eje x = -100,0; eje x <100,0; eje x + = 0,5) {
set_arm (eje x, 250, 120, 0, 10);
retraso (10);
}
para (eje x flotante = 100.0; eje x> -100.0; eje x - = 0.5) {
set_arm (eje x, 250, 120, 0, 10);
retraso (10);
}
}
círculo vacío ()
{
#define RADIUS 50.0
// ángulo de flotación = 0;
flotar zaxis, yaxis;
para (ángulo de flotación = 0.0; ángulo <360.0; ángulo + = 1.0) {
yaxis = RADIO * sin (radianes (ángulo)) + 300;
zaxis = RADIO * cos (radianes (ángulo)) + 200;
set_arm (0, yaxis, zaxis, 0, 50);
retraso (10);
}
}
Paso 4: Hechos, problemas y similares …
1. Cuando ejecuto la subrutina circle (), mi robot se mueve más en forma elíptica que en círculo. Creo que es porque mis servos no están calibrados. Probé uno de ellos y 1500 microsegundos no era lo mismo que 90 grados. Trabajará en esto para tratar de encontrar una solución. No crea que haya nada malo con el algoritmo, sino con mi configuración. Actualización 2018/2/11: recién descubrí que esto se debe a un error en el código original. No veo cómo funcionó su programa Código fijo usando esto: float wri_servopulse = 1500 - (wri_angle_d * pulseWidth); (se estaba agregando el código original)
2. ¿Dónde puedo encontrar más información sobre cómo funciona la función set_arm ()? El sitio web de Oleg Mazurov explica todo o proporciona enlaces para obtener más información:
3. ¿Existe alguna verificación de la condición de contorno? No. Cuando mi brazo robótico pasa una coordenada xyz no válida, hace este tipo de movimiento curioso como el de un gato estirándose. Creo que Oleg revisa su último programa que usa un USB para programar los movimientos del brazo. Vea su video y enlace a su último código.
4. El código debe limpiarse y el código de microsegundos puede eliminarse.
Recomendado:
Mueva su mano para controlar el brazo robótico OWI Sin ataduras: 10 pasos (con imágenes)
Mueva su mano para controlar el brazo robótico OWI … Sin ataduras: LA IDEA: Hay al menos otros 4 proyectos en Instructables.com (a partir del 13 de mayo de 2015) sobre la modificación o el control del brazo robótico OWI. No es sorprendente, ya que es un kit robótico tan bueno y económico para jugar. Este proyecto es similar en s
El brazo de engranaje robótico podría usarse para impresión 3D: 13 pasos
El brazo de engranaje robótico podría usarse para impresión 3d: el objetivo que quería darle al robot es hacer un modelo y demostrar la fuerza de su sistema de transferencia de fuerza a través de engranajes y con esto también generar contacto. el robot se mueve más armoniosamente. Los
BRAZO ROBÓTICO Xbox 360 [ARDUINO]: BRAZO AXIOMA: 4 pasos
BRAZO ROBÓTICO Xbox 360 [ARDUINO]: BRAZO AXIOM:
Cómo montar un impresionante brazo robótico de madera (Parte 1: Robot para seguimiento de líneas) - Basado en Micro: Bit: 9 pasos
Cómo montar un impresionante brazo robótico de madera (Parte 1: Robot para seguimiento de líneas) - Basado en el Micro: Bit: Este tipo de madera tiene tres formas, es muy diferente e impresionante. Entonces entremos uno por uno
Cómo usar unas pocas piezas de madera para ensamblar en un brazo robótico de madera lindo y poderoso: 10 pasos
Cómo usar unas pocas piezas de madera para ensamblar en un lindo y poderoso brazo robótico de madera: El nombre del brazo robótico es WoodenArm. ¡Se ve muy lindo! Si desea obtener más detalles sobre WoodenArm, consulte www.lewansoul.com. Ahora podemos hacer una introducción sobre WoodenArm, ¡sigamos adelante