¿Cómo se calculan los movimientos delta?

8

En una impresora cartesiana, los movimientos son realmente simples. Si suponemos que la impresora tiene 100 pasos / mm en cada eje, entonces un movimiento de 10 mm en un eje es solo 1000 pasos en ese eje.

Los movimientos que no están alineados con un eje también son simples. Pasar de x, y = 0,0 a 10,10 sería 1000 pasos en x e y.

En deltas, incluso para movimientos simples, más de un motor tiene que moverse. Y solo calcular la cantidad de pasos en cada eje necesarios para llegar al destino probablemente da un movimiento curvo.

Entonces, ¿cuál es el algoritmo para calcular los pasos para un movimiento dado para una impresora delta?

Lars Pötter
fuente
Esta parece ser únicamente una pregunta teórica que podría ser más apropiada para un sitio que se ocupa de la programación y / o las matemáticas, ya que el funcionamiento interno del firmware es irrelevante para el uso de una impresora 3D. Por otro lado, la pregunta es específica para la impresión 3D y podría ser relevante para alguien que intente modificar o modificar el firmware de su impresora.
Tom van der Zanden

Respuestas:

7

Existen dos pasos especiales principales para la técnica utilizada por la mayoría de los controladores de impresora 3D de código abierto:

  1. Divida cada segmento de gcode lineal en muchos subsegmentos muy pequeños ("Segmentación")
  2. Use alguna trigonometría básica o el teorema de Pitágoras para vincular la posición del extrusor a la altura del carro para cada una de las tres torres ("Cinemática inversa") para encontrar la posición objetivo para cada segmento pequeño

La cinemática inversa es sorprendentemente simple. Se construye un triángulo virtual de 90 grados a partir de dos longitudes conocidas para resolver la tercera longitud desconocida:

  • La longitud fija del brazo delta es la hipotenusa del triángulo.
  • La distancia horizontal entre las juntas de la columna y las juntas del efector final se calcula a partir de las coordenadas XY de la boquilla y la posición fija de la columna, para determinar la longitud del lado inferior del triángulo
  • La longitud del lado superior del triángulo se calcula a partir de los dos anteriores a través del teorema de Pitágoras.
  • La longitud del lado superior se agrega a la altura Z de la boquilla para obtener la altura del carro necesaria

Creo que la mejor referencia de código abierto aquí es el documento de Rostock Kinematics de Steve Grave, rev3 disponible para descargar aquí: https://groups.google.com/d/msg/deltabot/V6ATBdT43eU/jEORG_l3dTEJ Algunas fotos relevantes: ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Estos cálculos de cinemática inversa se realizan para cada carro para obtener una posición objetivo de "espacio de carro", y esto se realiza para cada subsegmento de ruta.

Los resultados de estos pasos se pueden volver a insertar en las técnicas de interpolación de ruta lineal estándar para la impresora, en las que dispara los pasos en las proporciones necesarias y a las velocidades necesarias para producir el movimiento en línea recta deseado y el perfil de aceleración / velocidad. (Cómo se hace ESO es una pregunta diferente).

El efecto neto es que la impresora se moverá a través de una serie de pequeños movimientos de carro "lineales" (lineal que significa velocidad constante * con respecto al tiempo) que se aproximan colectivamente a los movimientos curvos (posición cuadrática con respecto al tiempo) necesarios para producir un movimiento efector final en línea recta.

* (La velocidad constante antes de la desaceleración de la aceleración se aplica para obedecer las restricciones dinámicas, de todos modos. De nuevo, ese es el tema de una pregunta diferente).

La segmentación es muy similar al proceso de usar un polígono para aproximar un círculo. Si las facetas son lo suficientemente pequeñas, el polígono es una buena aproximación. Las tasas de segmentación más altas producen menos errores de seguimiento de ruta. La principal diferencia conceptual entre dibujar arcos circulares y rutas de movimiento Delta es que el llamado "arco facetado" con segmentación Delta se construye en coordenadas altura-tiempo en lugar de las coordenadas X-vs-Y que usarías para dibujar un círculo en la pantalla de una computadora.

Este sistema se utiliza en gran parte porque el soporte para impresoras de estilo Delta se atornilló originalmente en planificadores de movimiento basados ​​en GRBL que se escribieron exclusivamente para rutas de movimiento en línea recta en impresoras cartesianas. Fue una modificación relativamente mínima a la base de código existente en comparación con la implementación de la interpolación de ruta cuadrática completa.

Las técnicas han evolucionado a lo largo de los años. Y a menudo se utilizan enfoques alternativos: por ejemplo, la bifurcación dc42 de RepRapFirmware realiza el seguimiento exacto de la ruta sin segmentación, recalculando el tiempo adecuado para el siguiente paso después de cada paso . Esto es funcionalmente equivalente a aproximar un círculo con un recuento de facetas de polígono tan alto que cada píxel en la pantalla tiene su propia faceta . Por lo tanto, es exactamente tan preciso como lo permite la resolución de posicionamiento de los motores. La desventaja es que esta técnica libre de segmentación es bastante intensiva en el procesador, por lo que solo funciona en controladores relativamente rápidos, no en el antiguo Atmega AVR de 8 bits que alimenta a la mayoría de las impresoras de consumo / afición existentes en la actualidad.

Otras técnicas son posibles. La literatura académica de control de robótica paralela es un mundo completamente diferente de técnicas matemáticas y complejidad para producir algoritmos de control generalizados que funcionan para una amplia gama de mecanismos de robot. La versión que utilizamos en impresoras 3D de código abierto es bastante simple y específica de la aplicación en comparación.

Ryan Carlyle
fuente
2

Estoy describiendo cómo se hace esto en el firmware de Marlin.

El primer paso es dividir un movimiento lineal de (x, y, z) a (x ', y', z ') en muchos segmentos discretos. Para este fin, se calcula la cantidad de tiempo que tomaría el movimiento a una velocidad dada, y el valor delta_segments_per_second se usa para calcular el número de segmentos utilizados.

Esto se hace en la función prepare_move_delta en el archivo Marlin_main.cpp. Los puntos finales de cada uno de estos segmentos se pasan a la función Calculate_delta :

void calculate_delta(float cartesian[3]) {
    //reverse kinematics.
    // Perform reversed kinematics, and place results in delta[3]
    // The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014

    float SCARA_pos[2];
    static float SCARA_C2, SCARA_S2, SCARA_K1, SCARA_K2, SCARA_theta, SCARA_psi;

    SCARA_pos[X_AXIS] = cartesian[X_AXIS] * axis_scaling[X_AXIS] - SCARA_offset_x;  //Translate SCARA to standard X Y
    SCARA_pos[Y_AXIS] = cartesian[Y_AXIS] * axis_scaling[Y_AXIS] - SCARA_offset_y;  // With scaling factor.

    #if (Linkage_1 == Linkage_2)
      SCARA_C2 = ((sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS])) / (2 * (float)L1_2)) - 1;
    #else
      SCARA_C2 = (sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS]) - (float)L1_2 - (float)L2_2) / 45000;
    #endif

    SCARA_S2 = sqrt(1 - sq(SCARA_C2));

    SCARA_K1 = Linkage_1 + Linkage_2 * SCARA_C2;
    SCARA_K2 = Linkage_2 * SCARA_S2;

    SCARA_theta = (atan2(SCARA_pos[X_AXIS], SCARA_pos[Y_AXIS]) - atan2(SCARA_K1, SCARA_K2)) * -1;
    SCARA_psi = atan2(SCARA_S2, SCARA_C2);

    delta[X_AXIS] = SCARA_theta * SCARA_RAD2DEG;  // Multiply by 180/Pi  -  theta is support arm angle
    delta[Y_AXIS] = (SCARA_theta + SCARA_psi) * SCARA_RAD2DEG;  //       -  equal to sub arm angle (inverted motor)
    delta[Z_AXIS] = cartesian[Z_AXIS];
}

Esta función se encarga de la geometría delta y los cálculos necesarios para convertir las coordenadas (x, y, z) de los puntos finales del segmento en las posiciones correspondientes para los carros. Las coordenadas traducidas se pasan luego a plan_buffer_line , que calcula los pasos necesarios para cada motor paso a paso y realmente hace que estos pasos sucedan.

La cinemática exacta utilizada en esta función se explica con mucho más detalle en el github Marlin .

Es importante tener en cuenta que plan_buffer_line mueve los carros linealmente, y el cabezal de impresión describe un arco y no una línea recta. Un movimiento en línea recta se aproxima por muchos arcos pequeños.

Tom van der Zanden
fuente
El código es difícil de leer. ¿Qué es SCARA? ¿Podría describir los pasos que implementa el código?
Lars Pötter