Aller au contenu


Photo
- - - - -

BurnBot - Self Balancing Robot

balancing equilibre pas à pas

154 réponses à ce sujet

#81 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 05 février 2018 - 09:20

Super intéressante comme vidéo, merci :)



#82 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 05 février 2018 - 01:04

Bonjour,

 

J'ai écris un code qui me paraît plutôt bon. Je sais que le tunning des coefficients est compliqué mais la j'ai l'impression qu'aucunes combinaison ne va marcher, le robot réagis bizarrement...

 

Je vous joins le code, dites moi ce que vous en pensez, est ce que je suis sur la bonne voix et qu'il ne me reste plus qu'à paramétré les coeff ou alors mon code n'est pas du tout bon ?


#include <Servo.h> // librairie pour servomoteur 
#include<Wire.h>  // librairie pour le gyroscope
#include <PID_v1.h> // librairie pour le PID

///////////////////////////INITIALISATION GYROSCOPE///////////////////////////
///////////////////////////INITIALISATION GYROSCOPE///////////////////////////

const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

///////////////////////////INITIALISATION SERVOMOTEUR///////////////////////////
///////////////////////////INITIALISATION SERVOMOTEUR///////////////////////////

double LServoSpeed = 1520; //Normalement compris entre 1000 et 2000 avec milieu à 1500 (valeurs à qualibrer)
double RServoSpeed = 1550; //same

const int broche_servoL=5; // Constante pour la broche 1
const int broche_servoR=6; // Constante pour la broche 2

Servo LServo;  // crée un objet servo pour contrôler le servomoteur Droit
Servo RServo;  // crée un objet servo pour contrôler le servomoteur Gauche

///////////////////////////INITIALISATION PID///////////////////////////
///////////////////////////INITIALISATION PID///////////////////////////

double Setpoint, Input, Output; //Variales du PID

double Kp=120, Ki=100, Kd=50; //Coefficients du PID

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); //Définition du PID

void setup()
{
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);                     // PWR_MGMT_1 register
  Wire.write(0);                        // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  
  Serial.begin(9600);                   // initialise connexion série matérielle à 9600 bauds
  
  LServo.attach(broche_servoL);         // attache l'objet servo à la broche de commande du servomoteur
  RServo.attach(broche_servoR);         // attache l'objet servo à la broche de commande du servomoteur
  
  pinMode (broche_servoL,OUTPUT);       // Broche broche_servo configurée en sortie
  pinMode (broche_servoR,OUTPUT);       // Broche broche_servo configurée en sortie

  LServo.writeMicroseconds(LServoSpeed); // On met la vitesse des servos à 0
  RServo.writeMicroseconds(RServoSpeed);

  Setpoint = 837.2; // lorsque le robot est à la verticale la consigne est à 100
  
  myPID.SetMode(AUTOMATIC); //Initialisation du PID en mode automatique
  myPID.SetOutputLimits(1000, 2000);
  myPID.SetTunings(Kp, Ki, Kd);
  myPID.SetSampleTime(65);
}

void loop()
{
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  
  //AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
  //AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  //Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  //GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  //GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  //GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  Input = AcZ ;
  myPID.Compute();

  LServoSpeed = Output; //La vitesse du servo gauche prend la valeur de l'output
  LServo.writeMicroseconds(LServoSpeed); //On écris la vitesse du servos gauche

  RServoSpeed = map(LServoSpeed, 1000, 2000, 2000, 1000); //Inversement de la vitesse des deux moteurs
  
  RServo.writeMicroseconds(RServoSpeed); //On écris la vitesse du servos droit

  Serial.println(Input);
  
}



#83 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 05 février 2018 - 08:03

Je viens de passer la journée à essayer de régler ces paramètres je sèche compètement... C'est à croire que ça ne va pas marcher :/ J'avoue que j'aurais besoin d'un peu d'aide...



#84 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 05 février 2018 - 08:12

Une vidéo ? 

Est ce que tu as déjà la base de la bonne tentative de comportement : Si tu penche d'un coté les roues tournent dans le bon sens pour compenser et inversement quand tu penches le robot dans l'autre sens ? 

Ensuite as tu essayé uniquement avec un correcteur proportionnel pour commencer ? 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#85 Path

Path

    Made By Humans

  • Modérateur
  • PipPipPipPipPip
  • 2 504 messages
  • Gender:Male
  • Location:Paris

Posté 05 février 2018 - 08:39

C'est une vrai galère ces 3 paramètres. Je confirme. Je me souviens d'une règle empirique pour les régler. D'abord le P, avec un comportement oscillant. ensuite le D et le I. Je me suis arraché les cheveux avec ça.



#86 Oracid

Oracid

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 6 769 messages
  • Gender:Male

Posté 05 février 2018 - 09:06

C'est une vrai galère ces 3 paramètres. Je confirme.

Pareil, pour moi.

#87 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 05 février 2018 - 09:53

Oui jai le bon comportement mais jai limpression que les paramètres ne changent quasiment rien... jessaRais de faire une vidéo

#88 Darkbhaal

Darkbhaal

    Nouveau membre

  • Membres
  • 5 messages
  • Gender:Male
  • Location:Versailles

Posté 05 février 2018 - 11:59

Bonsoir,

 

Lorsque je regarde ton programme il me semble que tu ne te bases que sur les données brut de l'accélération en Z pour te servir de mesure d'angle hors cette mesure est précise dans le temps mais très très bruité. Il faudrait au moins que tu passes par un filtre complémentaire en intégrant le gyroscope de ton MPU6050.

Je vois que tu print Input, as tu analysé ces variations?

 

Concernant Setpoint es tu sur que 837.2 qui est ta consigne corresponde au point d’équilibre de ton robot?

 

As tu calibrer ton MPU6050 car rien n'apparait dans ton programme.

 

Pour ma part j'utilise 2 PID sans la librairie mais cela doit être pareil, un PID consigne vitesse moteur et un PID Setpoint les 2 étant lier.

Pour ma part URSA n'a commencé qu'a  balancé qu'une fois le PID setpoint mis en place car il suffit de bouger un cable pour changer le point d’équilibre du robot.

float resultatPID = PID (AngleActuel,AngleObjectif,Kp,Kd,Ki,tempo);

angleObj = -speedPI(tempo, vitesse_moyenne, vitesse_voulu, Kps, Kis, Kds); // vitesse moyenne est égale au résultatPID si je ne fait pas de rotation
AngleObjectif = 0.02 * angleObj + 0.98 * AngleObjectif;
AngleObjectif = constrain (AngleObjectif,-MAX_ANGLE, MAX_ANGLE);


float PID (float AngleActuel, float Angle_desire, float Kp, float Kd, float Ki, float tempo) // tempo et le temps entre chaque mesure d'angle(loop)
{
  float erreurActuel;
  float output;
  erreurActuel = Angle_desire - AngleActuel;
  proportionnel = erreurActuel * Kp *0.1;
  ITerm += (Ki*(tempo*0.001)*erreurActuel);  //tempo *0.001 pour le mettre en secondes
  ITerm = constrain (ITerm, (-VIT_MAX/2),(VIT_MAX/2));
  derive = Kd  * (AngleActuel - input_Ant) / (tempo);
  input_Ant = AngleActuel;
  output = constrain ((proportionnel + ITerm - derive),-VIT_MAX,VIT_MAX);
  
  return(output); 
}

float speedPI(float DT, float input, float setPoint,  float Kp, float Ki, float Kd) // sert pour le calcul de l'angle objectif deplacement angleObj = -speedPI(tempo, vitesse_moyenne, vitesse_voulu, Kps, Kis, Kds);
{
  float error;
  float output;
  error = setPoint-input;
  PID_errorSomme += constrain(error,-ITERM_MAX_ERROR,ITERM_MAX_ERROR); 
  PID_errorSomme = constrain(PID_errorSomme,-ITERM_MAX,ITERM_MAX); 
  float prop = Kp * error * 0.001;
  float integ = Ki * PID_errorSomme * (DT * 0.001)*0.0001;
  float deriv = Kd * (error - errorAnt) / DT;
  output = prop + integ + deriv;
  errorAnt = error;
  
  return(output);
}

Je te conseille également de modifier ton programme pour pouvoir changer en fonctionnement tes facteur KP KI et KD car reuploader le programme à chaque changement va te décourager. Et même avec cela je n'ai toujours pas trouver les bons coefficients.

Comme l'a dit mike commence par régler le P en tenant le robot, il te permettra de vérifier si il répond bien en cas lorsque tu le lâches puis I et en dernier le D, n’hésite pas à utiliser des coefficients multiplicateurs pour bien les diminuer au départ .

 

En tout cas bon courage pour la suite



#89 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 06 février 2018 - 08:46

Merci beaucoup pour ton message ca ma beaucoup aidé ! Tu mas permis didentifier certains points qui font que ça ne marche pas.

Premièrement, mes moteurs ne sont pas top (servos bas de gamme) jai du mal à trouver leur vitesse limites. En plus il ya du glissement entre mes roues et le sol ! Du coup le servos espère un comportement quil nontient pas.

Ensuite, et tu marques un point, il ya beaucoup de bruit sur mes données en imput. Mon prochain travail va etre de lisser mes données dentrées et de carrement avoir un angle en degrés, stable.

Une fois avoir réglé tout ça mon PID devrait être plus efficace.

Surtout que le robot tiens très bien en equilibre lorsque je laide un petit peu avec le câble dalimentation. Jimagine que je compense tous les défauts...

Je vais faire un essais plis simple encore dasservi Pid (un peut comme la video doracid) avec un moteur pas à pas, histoire de mettre tout ca en application

#90 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 07 février 2018 - 06:33

Bonjour à tous,

 

J'ai avancé sur l'acquisition des valeurs de mon MPU. :)

 

Alors premièrement j'ai cherché les offsets pour mettre les 0 plus ou moins quand mon robot est à plat (avec le code suivant) :

    mpu.setXGyroOffset(51);  
    mpu.setYGyroOffset(45);
    mpu.setZGyroOffset(-15);
    mpu.setZAccelOffset(1716);

Ensuite j'ai transformé les données pour avoir des résultats en degrés puis j'ai fais un essais statique (robot à plat) pour voir ce que ça donnait :

 

Capture.PNG

 

On voit sur le premier graphique qu'il y'a un cour temps de stabilisation des valeurs (mais l'écart n'est pas tellement préjudiciable, surtout qu'il se calibre vite, quelques secondes). Cependant on remarque de gros bruits vers la fin (alors que le capteur est complètement statique).

 

J'ai réalisé une acquisition plus longue (deuxième graphique) et on voit que ces bruits sont ponctuels, très intenses mais surtout trop souvent présent. Je me demande vraiment à quoi c'est du, une perte de signal dans un câble ? une soudure male faite ? mon portable qui perturberait le signal ?.

 

Enfin bref, j'ai passé plusieurs heures à écrire un filtre convenable pour supprimer ces bruits. En gros, si la différence entre la dernière valeur et la nouvelle est plus grande que 4° alors on ne l'a prend pas en compte.

 

J'en arrive au résultat suivant : une belle courbe sans bruit où l'on distingue bien les différentes positions angulaires données au robot

 

Cap1ture.PNG

 

Voila, je pense avoir réglé mon premier problème au niveau de l'acquisition des données. Elles sont maintenant viables et représentatives de ce qu'il se passe réellement.

 

Si vous avez des remarques faites le moi savoir ça m'intéresse beaucoup !!!



#91 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 08 février 2018 - 06:18

Bonjour,

 

J'avance petit à petit. pour tester mes nouvelles valeurs du gyroscope avec un PID de façon moins complexe qu'avec le robot j'ai fait un petit banc d'essai copié de la vidéo d'Oracid.

 

IMG_50941.JPG

 

Je suis plutôt satisfait car, bien que je ne me soit pas trop cassé la tête à régler les coefficient du PID j'ai un comportement plus qu'acceptable, ma tige reste tout le temps à la verticale.

 

Il faudrait que j'obtienne un comportement plus réactif (en envoyant la vitesse max plus rapidement mais j'ai peur des oscillations, quoi qu'un mpp n'a surement pas d'inertie), car elle met un peu de temps à atteindre la position quand je change l'angle mais l'idée est là et est peut être déjà suffisante pour faire balancer un robot. :D

 

Encore beaucoup de travail mais je trouve ça passionnant, petite vidéo pour illustrer tout ça :

 

 


Modifié par Path, 08 février 2018 - 08:03 .
Insertion de la video


#92 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 08 février 2018 - 10:30

Ok je pense savoir pourquoi ça ne va pas vite, parce que j'ai fais tourner mon système à 3000 step/seconde et ça envoie !! Alors pourquoi lors de mes essais en PID le système évolue à deux à l'heure ? Pourtant ma consigne de vitesse atteint bien les 3000 steps pendant l'essai pourtant il est claire que le moteur n’atteint jamais réellement cette vitesse.

 

La réponse selon moi est que mon prorgamme est lent et que mon "stepper.runspeed()" n'est pas appelé assez souvent (du moins assez pour le faire tourner vite).

 

Du coup je dois trouver une façon pour faire en sorte que mon "stepper.runSpeed()" soit appellé le plus fréquemment possible, vous avez déjà rencontré le problème ? je me penche dessus demain mais je sais pas encore tellement comment m'y prendre. :)



#93 Darkbhaal

Darkbhaal

    Nouveau membre

  • Membres
  • 5 messages
  • Gender:Male
  • Location:Versailles

Posté 08 février 2018 - 11:36

Bonsoir, pour pouvoir t'aider il faudrait un bout de code.

Cela peut venir de ton calcul d'angle qui n'est pas assez rapide après je ne connais pas Accelstepper mais peut etre stepper.setAcceleration n'est pas assez élevé.

En tout cas c'est super tu es sur la bonne voie.:)

Concernant le MPU j'ai du utiliser un câble blindé car j'avais des interférences provenant de mes moteurs qui faisait planté l'I2C si cela peu t'aider.

Après tu peux vérifier le temps de ton Loop avec un truc comme ça tu devrait normalement avoir quelque chose entre 3 et 20ms ne surtout pas utiliser de delay.

//Calcul temps du LOOP toutes les variable sont de type float

    tempoActuel = micros();

    tempoPasse = (tempoActuel - tempoAnterieur); //Temps passé depuis la dernière boucle de programme en Microsecondes
    
    tempo = tempoPasse / 1000; //Temps passé depuis la dernière boucle de programme en Millisecondes

    Serial.print(" Tempo : ");Serial.println(tempo);
    
    tempoAnterieur = tempoActuel;


#94 Path

Path

    Made By Humans

  • Modérateur
  • PipPipPipPipPip
  • 2 504 messages
  • Gender:Male
  • Location:Paris

Posté 08 février 2018 - 11:51

C'est AccelStepper que tu utilise ? Il y a peut-être l'accélération par défaut qui fait que le moteur n'a pas le temps d'atteindre la valeur commandée. Peut-être.

Il y a max speed aussi.

 

mystepper.setMaxSpeed(stepsPerSecond);
Sets the maximum speed. The default is very slow, so this must be configured. When controlled by setting position, the stepper will accelerate to move at this maximum speed, and decelerate as it reaches the destination.

 

mystepper.setAcceleration(stepsPerSecondSquared);
Sets the acceleration to be used, in steps per second per second.

 

 

https://www.pjrc.com...celStepper.html

 

Je sais plus si max speed entre en jeu avec les méthodes non bloquantes comme runSpeed(). (en fait)



#95 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 09 février 2018 - 02:26

Je pense aussi que c'est l'accélération qui est mal réglée ! =)


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#96 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 09 février 2018 - 10:57

Bonjour à tous,

 

Merci pour vos réponses :) (y)

 

J'ai tenté de set l'accélération mais ça n'a rien changé. Ensuite j'ai call mon stepper.runSpeed() le plus de fois possible (à l'intérieur de toutes mes boucles, surtout que j'ai des boucles tant que) et miracle mon motteur s'est mis à tourné à la bonne vitesse :) Voici une petite vidéo qui en témoigne (désolé je n'arrive pas à les incruster moi même) :

 

 

J'ai un peu joué avec les coefficients mais je ne vais pas me prendre la tête ici à bien les régler. Cependant, lorsque je joue avec le P et le I j'ai des comportements normaux (avec de l'overshooting ou pas, etc...) Mais dès que je passe le D de 0 et quelque chose d'autre le système se met à faire n'importe quoi. Mais vraiment, d'un coup il se met à faire 3 tous sur lui même, quand on est pas prêt ça fait peur ^^

 

Enfin bref, voici un graphique qui montre en bleu la position angulaire de mon système et en orange la vitesse du moteur lorsque je joue avec. Autant vous dire que je suis plutôt satisfait du résultat :)

 

Capture.PNG



#97 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 969 messages
  • Gender:Male
  • Location:Anglet

Posté 09 février 2018 - 11:56

quelque chose pour le D c'est quoi ? 0,001 ? 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#98 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 09 février 2018 - 01:48

Non j'incrémente par pas de 1 (ça suffit largement avec les deux autres coefficients), ça serait trop élevé pour le D ?



#99 Oracid

Oracid

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 6 769 messages
  • Gender:Male

Posté 09 février 2018 - 03:01

Je ne sais pas si cela va t'aider. Ce gars a fait 6 vidéos sur le sujet, et il donne pas mal d'informations.
'https://www.youtube....?v=rJ3IljrzSXk'
'https://www.youtube....?v=EwrQEsFmL4E'

#100 Budet

Budet

    Membre passionné

  • Membres
  • PipPipPip
  • 366 messages
  • Gender:Male
  • Location:69

Posté 09 février 2018 - 03:47

Merci Oracid, tes vidéos sont vraiment intéressantes !

 

Je me réattaque à l'electronique de mon robot, et c'est surement la partie que j'aime le moins. Actuellement je souhaite tout cabler comme ceci :

 

CablageBurnbot.PNG

 

C'est la que j'aurais vraiment besoin de vos remarques ! C'est la zone entourée en rouge qui me fait le plus peur !! Est ce que je peux vraiment procéder comme ça ? J'ai coupé une alime sur laquelle j'ai soudé deux fils (oui c'est super dangereux, j'essaye d'être le plus prudent possible). je peux les brancher sur une breadboard et ensuite alimenter chacun des drivers ? Y'a il quelque chose d'autre à rajouter parce que ça me parait pas safe du tout.

 

Surtout pour plus tard quand une batterie remplacera mon alim, dois-je la protéger avec une diode ou autre ? Ou alors comme ça c'est bon ?

 

Et sinon comment vous faites pour avoir une électronique plus pro et plus robuste ? Parce que des petits fils "clipsés" sur une breadboard qui peuvent se déconnecter au moindre choc et dans lesquels il peut y avoir des interférence je suis pas fan. En plus ce n'est pas compact.

 

J'aimerais utiliser des bobines de fils plus souple (gagner en longueur de cable) et tout souder ensemble pour que plus rien ne bouge. Vous avez des suggestions ?





Répondre à ce sujet



  



0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users