Bonjour,
Je programme en C Arduino pour asservir les vitesses d'un moteur Dynamixel AX-18A. Pour cela, on dispose de registres d'écriture de la vitesse cible (consigne) et de registres de lecture de la vitesse courante (mesure).
Lorsque j'indique des consignes de vitesses au moteur, celui-ci ne bouge pas.
Lorsque j'indique des consignes de postions et de vitesses au moteur, celui-ci bouge mais ne respecte pas vraiment les consignes de vitesse (fichier joint vitessesKO ; erreur quadratique moyenne : 1.1624). Pourtant, la fréquence des mesures n'est pas très élevée, puisqu'il y a une mesure tous les dt=50 ms.
Par contre, lorsque je fais des "fausses" mesures de vitesses, c'est-à-dire lorsque je dérive les positions mesurées, l'erreur quadratique moyenne est beaucoup plus faible : 0.0028786 (fichier joint vitessesOK).
Est-ce que quelqu'un saurait imposer des vitesses sur un moteur Dynamixel ?
Merci d'avance ; et je vous joins le code C qui tente d'imposer des positions et des vitesses (code dont le résultat est représenté sur le fichier joint vitessesKO) :
#include <Commander.h> #include <ax12.h> //Pour les commandes vers Dynamixel #include <BioloidController.h> #include <stdio.h> #include <string.h> #include <stdlib.h> int i=0; int positionMesuree; int vitesseMesuree; double positionMesureeRad; double vitesseMesureeRad; int tempsDepart, tempsCourant; double positionSim[46]={0,0.00044979,0.0017992,0.0040481,0.0071966,0.011245,0.016192,0.02204,0.028787,0.036433,0.044979,0.054425,0.06477,0.076014,0.088159,0.1012,0.11515,0.12999,0.14573,0.16237,0.17992,0.19836,0.2177,0.23786,0.25756,0.27637,0.29428,0.31128,0.32739,0.3426,0.35691,0.37031,0.38282,0.39443,0.40514,0.41495,0.42386,0.43187,0.43898,0.44519,0.45051,0.45492,0.45843,0.46105,0.46276,0.46357}; double vitesseSim[46]={0,0.089958,0.17992,0.26987,0.35983,0.44979,0.53975,0.62971,0.71966,0.80962,0.89958,0.98954,1.0795,1.1695,1.2594,1.3494,1.4393,1.5293,1.6192,1.7092,1.7992,1.8891,1.9791,2.0155,1.9256,1.8356,1.7456,1.6557,1.5657,1.4758,1.3858,1.2959,1.2059,1.1159,1.026,0.93602,0.84606,0.7561,0.66615,0.57619,0.48623,0.39627,0.30631,0.21636,0.1264,0.03644}; double positionDynamixDeci; //Nombre decimal entre 0 et 1023 //De 0 a 1023 : sens trigo //De 1024 a 2047 : sens anti-trigo double vitesseDynamixDeci; int vitesseDynamixEntier; int idMoteur=1; int attente=24; //Fonction pour convertir radians de la sim avec 0 de Dynamixel, en position Dynamixel int radVersDynamix(double positionSim) { double positionDynamixDeci; int positionDynamixEntier; positionDynamixDeci = positionSim * 195.378; //Depasse 1024 ? positionDynamixEntier = (int) positionDynamixDeci; return positionDynamixEntier; } //Fonction pour convertir position mesuree Dynamixel en radians double dynamixVersRad(int positionMesureeDynamix) { double positionMesureeRad; double positionMesureeDynamixDeci = (double) positionMesureeDynamix; positionMesureeRad = positionMesureeDynamixDeci * 5.118 * 0.001; return positionMesureeRad; } //Fonction pour convertir vitesses angulaires de la sim en vitesse Dynamixel int vitesseRadVersDynamix(double vitesseSim) { double vitesseDynamixDeci; int vitesseDynamixEntier; vitesseDynamixDeci = vitesseSim * 195.378; if(vitesseSim>=0) { vitesseDynamixEntier = (int) vitesseDynamixDeci; } else { vitesseDynamixEntier = 1024 + (int) vitesseDynamixDeci; } } //Fonction pour convertir vitesse mesuree Dynamixel en rad/s double vitesseDynamixVersRad(int vitesseMesureeDynamix) { double vitesseMesureeRad; //Gestion du sens de deplacement if(vitesseMesureeDynamix>1023) { vitesseMesureeDynamix = 1024 - vitesseMesureeDynamix; } double vitesseMesureeDynamixDeci = (double) vitesseMesureeDynamix; vitesseMesureeRad = vitesseMesureeDynamixDeci * 5.118 * 0.001; return vitesseMesureeRad; } //------------------------------------------------------------------------------ void setup() { Serial.begin(115200); tempsDepart=millis(); SetPosition(idMoteur,0); delay(2000); } void loop() { //Mesure des positions positionMesuree = ax12GetRegister(idMoteur, AX_PRESENT_POSITION_L, 2); positionMesureeRad = dynamixVersRad(positionMesuree); //Vitesse cible ax12SetRegister2(idMoteur, AX_GOAL_SPEED_L, vitesseRadVersDynamix(vitesseSim[i])); delay(attente); if(i==0) { delay(2000); } //Mesure des vitesses vitesseMesuree = ax12GetRegister(idMoteur, AX_PRESENT_SPEED_L, 2); vitesseMesureeRad = vitesseDynamixVersRad(vitesseMesuree); //Horodatage tempsCourant=millis()-tempsDepart; //Affichage clair Serial.print("Iteration #"); Serial.print(i); Serial.print(" : "); Serial.print("Au temps t="); Serial.print(tempsCourant); Serial.print(" Mesure position en rad="); Serial.print(positionMesureeRad); Serial.print(" / Consigne de vitesse en rad/s="); Serial.print(vitesseSim[i]); Serial.print(" / Mesure vitesse en rad/s="); Serial.println(vitesseMesureeRad); //Affichage pour Matlab /* Serial.print(tempsCourant); Serial.print(","); Serial.print(positionSim[i]); Serial.print(","); Serial.print(positionMesureeRad); Serial.print(","); Serial.print(vitesseSim[i]); Serial.print(","); Serial.print(vitesseMesureeRad); Serial.println(";"); */ i++; }