[ARDUINO] Asservissement grâce au PID

Le problème exposé dans ce sujet a été résolu.

Si alpha vaut 50°, je ne vois pas comment l’angle plat peut valoir alpha + 90°… C’est de la géométrie élémentaire. Et j’ai encore l’impression que tu as encore changé la définition de alpha.

Ensuite, cela ne t’aide pas à calculer le couple de quelque manière que ce soit. C’est un problème secondaire.

Bref, je ne comprends pas où tu veux aller, et je ne peux pas t’aider dans ces conditions.

Tu as mal compris mon changement de couleur sur le schéma :) le alpha+90 comprend l’angle alpha donc cela ne correspond pas à l’angle plat.

C’est vrai que cela est inutile pour le couplé. .. Je vais donc regarder plus précisément la méthode du bras de levier :)

C’est vrai que je m’embrouille un peu parfois désolé…

Re @Aabu ! :)

Je reviens vers toi, non pas pour la formule de l’angle car je n’ai pas eu trop le temps de m’y pencher puisque nous n’avons pas eu beaucoup d’heures de projets depuis mon dernier message et nous étions confrontés à un autre petit problème, qui est en cours de résolution ; mais pour une petite question Simulink. Pour le moment, j’ai cela dans ma simulation :

Image utilisateur
Image utilisateur

Pour simuler le PID il faut faire le calcul de l’erreur avec l’angle modifié (que l’on connait (bloc Angle après perturbation) la première fois mais toutes les autres fois il faudra ne pas prendre en compte cet angle mais celui renvoyé par le bloc "Calcul de l’angle" (grâce à la formule que je trouverai, enfin un jour :)) et je me demande comment faire cela… Saurais-tu comment faire ?

Merci d’avance !

Salut,

Une solution consiste à mettre ta perturbation comme valeur initiale de l’angle dans ton système. Tu dois avoir un intégrateur quelque part (qui intègre la vitesse de rotation pour donner l’angle), tu peux mettre la perturbation ici (au passage d’ailleurs, tu peux aussi choisir une vitesse initiale).

Après, il y a d’autres solutions un peu plus élaborées, où tu peux choisir quand et à quelle valeur tu réinitialise, mais mieux vaut savoir faire l’autre d’abord.

Merci de ta réponse !

Cependant, je n’ai pas trop compris ce que tu me proposais de faire : pour l’instant, la position initiale de mon système = 180° = consigne, pour avoir l’erreur je dois donc soustraire la consigne à l’angle, qui correspond à quelque-chose de connu la première fois (angle suite à la perturbation) mais que l’on doit calculer pour la suite.

Il y a bien un bloc intégrateur mais je n’ai pas trop compris quoi faire avec, pourquoi s’embêter à intégrer une vitesse pour au final re-avoir un angle que l’on connait ? En sachant que par la suite il y auras toujours le problème de ne pas prendre en compte cette valeur après la première boucle.

PS : Si tu as le temps, je pense que je verrais beaucoup mieux avec un mini schéma :)

+0 -0

pour l’instant, la position initiale de mon système = 180° = consigne, pour avoir l’erreur je dois donc soustraire la consigne à l’angle, qui correspond à quelque-chose de connu la première fois (angle suite à la perturbation) mais que l’on doit calculer pour la suite.

Tu choisis que ta position initiale soit égale à la consigne, ça pourrait être différent (ou même ça devrait). Ensuite, l’erreur est toujours par définition la différence entre la consigne et l’angle mesuré, il n’y a rien à toucher. En fait, l’angle suite à la perturbation est, dans un sens, une position initiale : tu dis à un instant t0, mon angle vaut theta0 (angle de perturbation).

Et ça revient à forcer un intégrateur à une valeur donnée pour un unique pas de temps et le laisser reprendre ça vie. Cela peut être fait comme condition initiale (dans les paramètres de l’intégrateur) ou alors pendant la simulation (plus compliqué, il faut regarder dans les options de l’intégrateur, je te déconseille dans un premier temps).

J’ai l’impression que tu essaies de faire les calculs à la place de Simulink en disant « je connais telle valeur, donc je connais telle autre, donc je peux calculer telle autre, mais du coup après je dois ignorer celle-ci etc. ». Ce n’est pas comme ça qu’il faut procéder. Simulink te permet d’une part de décrire la boucle de rétroaction (c’est-à-dire : tu prends les valeurs de l’étape d’avant et tu fais tel calcul avec point) ; toi, d’autre part, tu lui dis d’où il commence (en donnant la position initiale dans les paramètres) et tu peux éventuellement créer des accidents de parcours (plus compliqué, et c’est ce que je te déconseille dans un premier temps).

Il y a bien un bloc intégrateur mais je n’ai pas trop compris quoi faire avec

Si tu parles de l’intégrateur du PID, ce n’est pas celui-là dont je parle.

pourquoi s’embêter à intégrer une vitesse pour au final re-avoir un angle que l’on connait ?

Parce que la physique marche comme ça. Le principe fondamental de la dynamique te dis que si tu connais le couple (que tu peux déduire des forces de poussée) alors tu peux en déduire l’accélération angulaire, puis la vitesse et donc l’angle par intégration.

de manière générale, la solution d’une équation différentielle s’obtient par intégration. C’est assez intuitif en fait : pour avoir ce qu’il y a sous la dérivée, on intègre. Il y a donc une constante d’intégration, comme dans toutes les intégrations, et il se trouve que c’est la valeur initiale de la solution. C’est sous cette forme qu’on utilise les équations de la dynamique dans Simulink.

En sachant que par la suite il y auras toujours le problème de ne pas prendre en compte cette valeur après la première boucle.

L’angle à l’étape d’après est calculé avec l’étape d’avant, qui est elle-même calculée avec l’étape d’avant, etc. en partant de la position et vitesse initiales. En gros, Simulink calcule une suite récurrente un peu compliquée, rien de plus ! Et tu peux naturellement lui donner le terme initial.

PS : Si tu as le temps, je pense que je verrais beaucoup mieux avec un mini schéma

Si ce que je dis au-dessus ne t’aide pas, peut-être, mais je ne peux pas non plus faire tout. Au bout d’un moment, ça revient presque à faire le travail à ta place. :D

Merci de ta réponse !

Finalement, nous avons pu énormément avancer aujourd’hui et nous avons finalement trouvé une autre solution que la tienne :) :

  • La formule : -0,29Pg + 0,29Pd = J * accélération_angulaire -> Pour le moment, nous avons pris J = 1

  • Voici notre modèle (le PID n’est pas encore réglé) :

Matlab
Matlab
Poussées
Poussées
Angle
Angle
  • Cela nous fait de jolies courbes comme celle-ci :
Image utilisateur
Image utilisateur
  • Cependant, comme tu l’as peut-être remarqué, nous ne transformons pas encore l’accélération en angle car si nous faisons comme cela :
Image utilisateur
Image utilisateur
  • Nous avons cette erreur… :
Image utilisateur
Image utilisateur

Et je ne sais pas trop ce que j’ai fait de mal…

+0 -0

Salut,

Je pense que tu as quelque chose qui part à l’infini (ce qui est généralement signe d’une équation fausse). Vérifie en regardant bien tous tes signaux, c’est comme ça qu’on débugue dans Simulink. Tu as aussi des problèmes de signe.

J’ai une petite idée d’où ça peut venir, mais je préfère que tu trouves toi-même, ce sera plus formateur.

nous avons finalement trouvé une autre solution que la tienne

Ce n’est pas équivalent. Votre solution revient à mentir au contrôleur, pas à perturber le système.

En faite, je ne suis pas sûr que mon équation soit fausse, je ne sais pas trop pourquoi mais je me suis aperçu quand lançant le modèle, le Display des poussée prenaient des valeurs énormes (x10^5) pendant un très court moment au début de la simulation… Pour les problèmes de signes, je pense savoir d’où viens le problème mais du coup je ne sais pas si ce que je vais dire est bon : 0,29Pg - 0,29Pd = J * a ?

Pour la "solution" :

Notre solution est-elle cependant correcte ? C’est vrai que cela n’est pas très élégant du coup mais c’est un projet dans un cadre scolaire, donc le but principal est d’avoir quelque chose de fonctionnelle et de compréhensible, donc si cela fonctionne mais que ça peut être très moche pour des connaisseurs, je ne pense pas que cela dérangera trop.

Dans tout les cas, ma faible connaissance dans ce côté de la simulation (les intégrations etc…), j’avoue ne pas encore avoir compris ce que tu m’expliquais : le début oui : je devrais prendre une position initiale différente de la consigne, et cette position, à t = 0, correspondrait à l’angle après la perturbation. Cependant, j’ai moins compris ce passage avec l’intégrateur, notamment je ne vois pas trop comment le "bloquer" pendant un certain temps :

Et ça revient à forcer un intégrateur à une valeur donnée pour un unique pas de temps et le laisser reprendre ça vie. Cela peut être fait comme condition initiale (dans les paramètres de l’intégrateur) ou alors pendant la simulation (plus compliqué, il faut regarder dans les options de l’intégrateur, je te déconseille dans un premier temps).

Merci encore pour ton aide en tout cas ! :)

+0 -0

Il y a d’autres problèmes avec tes équations. J’ai l’impression que le calcul des poussées est suspicieux. Tu devrais regarder tout tes signaux pour bien voir ce qu’il se passe.

Sinon pour l’intégrateur, tu as un paramètre dans Simulink qui s’appelle condition initiale… Sinon, tu sais ce que c’est une dérivée, une primitive et une intégrale ? Tu sais résoudre des équations différentielles formellement ? Tu as eu des cours de mathématique là-dessus ?

Hum, la formule que j’ai utilisé avec les poussées est la même que pour Arduino, et elle avait l’air de bien marcher (notre drone ne marche pas encore car nous avons été confronté à un problème avec les vibrations du drone sur la mesure mais le drone cherche bien à se rapprocher de la position initiale et les moteurs ont le bon comportement. Je regarderais pour les signaux un peu plus tard :)

Je regarderai également pour ce paramètre. Étant en terminale S, j’ai bien vu les dérivées, je viens de finir les primitives et intégrales mais les équations différentielles ont été supprimé du programme, je n’en ai donc entendu parler que de nom et car nous en avons rapidement parlé pour introduire la fonction exponentielle avec exp' = exp et exp0 = 1

Hum, la formule que j’ai utilisé avec les poussées est la même que pour Arduino,

T’en es sûr ? Tu as vérifié ce que tu as écrit dans Simulink ?

Pour rappel, ton code en page 4 :

poussee_g = (1/2) * commande + poussee_moyenne ;
poussee_d = poussee_moyenne - (1/2) * commande ; 

les équations différentielles ont été supprimé du programme, je n’en ai donc entendu parler que de nom et car nous en avons rapidement parlé pour introduire la fonction exponentielle avec exp' = exp et exp0 = 1

Jupiter41

Ah dommage, ça t’aurais aidé. Tu peux voir exp(0) = 1 comme une condition initiale. Il y a d’autres fonction que exp qui vérifient f' = f, mais en fixant un point de départ, il n’y en a plus qu’une.

Ah oui mince, voilà ce que cela fait maintenant (ça n’a pas changé grand chose) :

Poussées
Poussées
Graphique
Graphique

(la 1ère oscillation un peu coupée va de 100 à environ 260)

Toutefois, j’ai pu revoir ce dont je t’ai parlé : quand je lance la simulation cela affiche pendant un très court instant des valeurs très grandes ou très petite (+- x10^4 environ) apparaissent dans le Display des poussées avant de disparaître et d’être tout de suite remplacé par les valeurs finales qui ne bougent plus puisque le drone est stabilisé.

+0 -0

Ah oui mince, voilà ce que cela fait maintenant (ça n’a pas changé grand chose) :

Poussées
Poussées

Il y a encore une erreur…

Toutefois, j’ai pu revoir ce dont je t’ai parlé : quand je lance la simulation cela affiche pendant un très court instant des valeurs très grandes ou très petite (+- x10^4 environ) apparaissent dans le Display des poussées avant de disparaître et d’être tout de suite remplacé par les valeurs finales qui ne bougent plus puisque le drone est stabilisé.

Jupiter41

Ce n’est pas forcément anormalà ce stade. Le réglage du PID peut faire ça dans la simulation, mais garde en tête que ce n’est pas raisonnable physiquement.

Ah oui ? je sens que cela doit-être un truc bête mais je ne vois pas d’erreur @Aabu

Ce n’est pas forcément anormalà ce stade. Le réglage du PID peut faire ça dans la simulation, mais garde en tête que ce n’est pas raisonnable physiquement.

Aabu

C’est bien ce que je me disais mais étant donné que tu me disais que l’erreur avec l’intégrateur pouvait être dû au fait que les poussées tendaient vers l’infini, je me disais que c’était peut-être à cause de ça…

+0 -0

Ah oui ? je sens que cela doit-être un truc bête mais je ne vois pas d’erreur @Aabu

Une technique pour vérifier que deux choses qui devraient être équivalentes le sont sont de regarder qu’on a bien la même chose en sortie pour la même chose en entrée. Essaie de faire faire les calculs avec les mêmes entrées pour ton code et ton Simulink et vérifie que c’est bien pareil.

Ah oui c’est vrai, bonne technique @Aabu ! :p

Comme ça normalement c’est bon (même si cela me paraît bizarre maintenant : le drone est stabilisé à 180° (et reste à 180°) alors que les poussées des 2moteurs sont différentes…) :

Image utilisateur
Image utilisateur

Cependant, cela ne marche toujours pas avec les blocs intégrateur, peut-être est-ce un problème de réglage ? Voici ce que l’on peut mettre à l’intérieur :

Image utilisateur
Image utilisateur
+0 -0

Cependant, cela ne marche toujours pas avec les blocs intégrateur, peut-être est-ce un problème de réglage ?

Qu’est-ce que ça fait ? Qu’est-ce que ça devrait faire ? Est-ce que tu as regardé tout tes signaux ? Que dit le contrôleur ? Sur combien de temps tu as regardé ? Tu as essayé de changer les réglages du PID ? D’ailleurs, il est réglé comment ?

Avec une courbe ou autre, ce serait plus facile de t’aider. Mais ça ne vient probablement pas des intégrateurs (en tout cas pas ceux qui calculent l’angle).

Est-ce normal qu’avec la modification de la formule, le drone est stabilisé à 180° (et reste à 180°) alors que les poussées des 2moteurs sont différentes ?

L’angle et la consigne :

Image utilisateur
Image utilisateur
Image utilisateur
Image utilisateur

Et bien ça devrait convertir l’accélération en angle afin de faire de l’asservissement d’angle et non d’accélération :) alors que cela fait toujours la même erreur que je t’avais envoyé.

Le temps est réglé sur l’infinie mais je l’arrête avant "la fin" :p Non, je n’ai pas encore vraiment touché aux réglages du PID, les voici :

Image utilisateur
Image utilisateur

Salut,

Est-ce normal qu’avec la modification de la formule, le drone est stabilisé à 180° (et reste à 180°) alors que les poussées des 2moteurs sont différentes ?

Et toi qu’est-ce que tu en penses ? Je suis sûr que tu peux répondre à cette question avec assurance.


Autrement, ça se complique. Tu vas devoir vraiment regarder tous tes signaux en détail (et je dis bien tous tes signaux, jusqu’à présent, tu n’as jamais tout regardé).

À ce stade, ça devient assez dur d’aider à distance, mais j’ai quelques conseils pour t’aider à voir ce qu’il se passe.

  • Regarde en changeant la consigne dans le temps (par exemple un échelon) et en enlevant totalement la perturbation.
  • Essaie une autre méthode pour gérer ta perturbation (comme celle dont j’ai parlé par exemple).
  • Regarde voir pour faire le PID à la main (ce qui t’aidera à comprendre comment l’utiliser…) et regarde comment se comportent les différentes composantes (P, I et D).
  • Essaie d’enlever D aussi dans un premier temps, ce n’est pas essentiel pour débuguer.
  • Et surtout, essaie de réfléchir posément et calmement et d’utiliser ton sens physique.
Ce sujet est verrouillé.