Commande servo par centrale inertielle MPU6050

Bonjour à tous,

Pour un projets d’études, je dispose d’un Arduino Uno, d’une centrale inertielle MPU6050, et d’un servomoteur un axe classique.
Je souhaite imposer un mouvement du servo en fonction de la vitesse Vz selon l’axe Z et de l’angle de rotation Gy suivant l’axe Y de la centrale inertielle. Ce mouvement est décrit par l’angle A du servo (compris entre 0 et 179 degrés) :
A=K*(arctan(racine(a*Vz))-Gy)
où K et a sont des constantes définies

Étant novice en programmation, j’ai tenté de programmer cela pour mon Arduino, mais l’effet n’est pas celui souhaité du tout… Il semble que l’Arduino ne différencie pas Gy et Ay, de même que Az et Gz.

Voici mon code :

// ######## Déclaration des bibliothèques ########

#include <Servo.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>
#include <math.h>
// ######## Renommage les composants pour simplifier leur utilisation ########

MPU6050 mpu; //Centrale Inertielle
Servo act; //Actionneur

// ######## Initialisation des variables ########
//Composants
int16_t ax, ay, az;
int16_t gx, gy, gz;
float rot;
float prevrot;
float acc;


//Fonctions

float a;
float ac;
float sqr;
float rotoptrad;
float rotoptdeg;
float comm;
float K;

// ######## Initialisation du programme ########

void setup() 
{
    Wire.begin(); //Initialisation de la transmission
    mpu.initialize(); //Initialisation du
    act.attach(9);

    Serial.begin(9600); //Communication série à 9600 Bauds  
}

// ######## Programme de commande ########

void loop() 
{
    mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);   //récupéation des accélérations linéaires et angulaires
    acc=map(ay,-17000,17000,0,179);   
    rot=map(gy,-17000,17000,0,10); 
    //a(c+vz)
    ac=a*(acc);                                     
    sqr=double   sqrt (double __ac);                
    optrot=double  atan (double __sqr);             //calcul de arctan((a*(c+Vzair))**0.5)
    
    comm=K*(rot-(rotopt*180/3.1415926535));         //calcul de K*(theta-thetaopt)
    act.write(acc);                                //affichage de l'angle de commande
    delay(50);                                     //attente de 200 ms
}

Quelqu’un aurait-il une idée pour m’aider à résoudre mon problème ?

Merci par avance et bonne journée,

JulesRichard

Peux-tu décrire le mouvement souhaité de façon plus simple ? c'est genre un Gimbal ?

Tu utilises des variables non déclarées (a par exemple)
Tu changes des noms de variables (ac devient __ac)
pour convertir une donnée d’un type dans un autre on spécifie le type entre parenthèses.

sqr=double   sqrt (double __ac);

doit s’écrire

sqr=(double)   sqrt ((double) __ac);

cela dit, ce n’est nécessaire que si le type de l’argument ne correspond pas au type de la variable qui reçoit la valeur.

UniseV:
c'est genre un Gimbal ?

un cardan, quoi mais avec un seul axe on dirait.

bonjour,
avec un seul servo tu ne peux piloter qu'un seul axe.

comme indiqué au dessus, tu veux faire quoi, en terme simple.

Êtes-vous certain des valeurs 17 000..

   acc=map(ay,-17000,17000,0,179);   
    rot=map(gy,-17000,17000,0,10);

Quelle est la cohérence, l'homogénéité et la dimension de cette équation :

A=K*(arctan(racine(a*Vz))-Gy)

Pour cela, quelles sont les dimensions des coefficients K et a ?

Par ailleurs, le servo est-il couplé mécaniquement à un des trois axes de la centrale ou bien est-il indépendant ?

Cordialement.

Pierre