bunex-industries

Le Delta Robot

Un robot articulé de type "parallèle", motorisé par des servos, commandé en cinématique inverse par une application Cocoa.

Le Delta robot est une alternative intéressante au positionnement X,Y,Z classique.

La tête "effectrice" reste toujours parallèle à la base du robot. Cependant pour un mouvement de translation simple, les moteurs devront réaliser des mouvements plus compliqués.

On veut donner un triplet de coordonnées x,y,z à un algorithme pour qu'il nous donne des valeurs d'angles pour les moteurs.

On trouve sur le net divers documents relatifs à cette question du pilotage des moteurs (ici et ici par exemple). Ces documents proposent par chance du code en C pour accomplir ces opérations.

Tel quel, ces exemples de code n'ont pas fonctionné. En voici une adaptation pour Cocoa/Obj-C.

Quelques constantes dimensionnelles :

// robot geometry
#define f       120.0       // fixed triangle edge
#define e       70.0        // effector triangle edge
#define rf      62.0       // length of arm
#define re      135.0       // length of parallelogramm

// precalculated trigonometric constants
#define sqrt3   sqrt(3.0)
#define pi      3.141592653
#define sin120  sqrt3/2.0
#define cos120  -0.5
#define tan60   sqrt3
#define sin30   0.5
#define tan30   1/sqrt3

Les fonctions de cinématique inverse :

int delta_calcAngleYZ(double x0, double y0, double z0, double *ptheta)
{
    double y1 = -0.5 * tan30 * f;                                       
    y0 -= 0.5 * tan30    * e;                                           
    double a = (x0*x0 + y0*y0 + z0*z0 + rf*rf - re*re - y1*y1)/(2*z0);
    double b = (y1-y0)/z0;
    double d = -(a+b*y1)*(a+b*y1)+rf*(b*b*rf+rf);
    if (d < 0) return -1;                                               
    double yj = (y1 - a*b - sqrt(d))/(b*b + 1);
    double zj = a + b*yj;
    *ptheta = 180.0*atan(-zj/(y1 - yj))/pi + ((yj>y1)?180.0:0.0);
    return 0;
}

int delta_calcInverse(double x0, double y0, double z0, double *ptheta1, double *ptheta2, double *ptheta3)
{
    int status = delta_calcAngleYZ(x0, y0, z0, ptheta1);
    if (status == 0) status = delta_calcAngleYZ(x0*cos120 + y0*sin120, y0*cos120-x0*sin120, z0, ptheta2); 
    if (status == 0) status = delta_calcAngleYZ(x0*cos120 - y0*sin120, y0*cos120+x0*sin120, z0, ptheta3);
    return status;
}

Enfin, voici l'appel de la fonction. Les pointeurs vers angles sont donnés en arguments et modifiés dans la fonction. Elle renvoie un status (OK, Point hors gamme).

double theta1 = 0;
double theta2 = 0;
double theta3 = 0;
int res = delta_calcInverse(x, y, z, &theta1, &theta2, &theta3);

Ces angles sont ensuite envoyés à l'Arduino par le port USB sous la forme de 4 octets (3 octets codent 3 angles entre 0 et 180° + 1 octet pour piloter une pince).