Aller au contenu


Photo
- - - - -

Vitesse régulée par un PID

pid vitesse

  • Veuillez vous connecter pour répondre
4 réponses à ce sujet

#1 transistance

transistance

    Membre passionné

  • Membres
  • PipPipPip
  • 409 messages

Posté 06 mars 2015 - 05:33

Je suis en train de réaliser un premier algorithme d'asservissement de vitesse par PID, le but étant de faire rouler droit le robot en question.

 

J'ai commencé par implémenter un PID à 50Hz sur un seul des deux moteurs et ça semblait bien marcher. Du coup j'ai testé ce que ça donne à 100Hz pour voir. Et là j'ai constaté que le moteur allait plus vite... ce qui n'est pas normal si ?

 

Je me suis basé sur cette page. Comme je ne travaille pas sur arduino j'ai adapté le code à mon besoin.

Pour déboguer et régler l'asservissement j'utilise la même méthode. D'ailleurs, bien que visuellement la roue semble tourner plus vite, les valeurs retournées de celles-ci sont similaires.

 

Infos utiles : Je programme en C sur un AVR atmega328p cadencé à 20Mhz. Celui-ci est totalement dédié à l'asservissement des 2 moteurs du robot. Les codeurs sont lu sur interruption.

 

La routine principale qui appel le pid 50 fois par seconde:

while (1) 
	{
	
		pid(consigne);		// consigne = nombre de tr/sec
		_delay_ms(20);		// PID à 50Hz (F=1/t)
	}

La fonctione d'asservissement:

void pid(float ConsigneVit)
{
	float compteurD;
	float mesure_vit_d;

	// affectation des compteurs de PID et reset des compteurs sur interruption
	compteurD = tickD;
	tickD = 0;
		
	mesure_vit_d = (50*compteurD)/tick_trm/reduction;		// vitesse mesurée en tr/s
		
	//calcul des erreurs
  	erreur_d = ConsigneVit - mesure_vit_d;	
	somme_erreur_d += erreur_d;
	delta_erreur_d = erreur_d - erreur_prec_d;
		
	// calcul de la commande
        PWMD += ((kp * erreur_d) + (ki * somme_erreur_d) + (kd * delta_erreur_d));
	
	// Normalisation des commandes PWM de sortie (le moteur ne bouge pas avec un pwm < 240)
	if (PWMD < 240) {PWMD = 240;}
		else if (PWMD > 1023) {PWMD = 1023;}
		
	// mise à jour de l'erreur précédente
		erreur_prec_d = erreur_d;
	
	//EnvoiFloat((PWMD/100));			
	EnvoiFloat(mesure_vit_d);               // envoie la valeur via uart
	EnvoiChaine("\r\n"); 			// retour a la ligne
}

Quelqu'un pourrait m'aider à comprendre ?

 

Merci.


N'oubliez jamais que "Ban Ki-moon n'attrape pas mousse"


#2 transistance

transistance

    Membre passionné

  • Membres
  • PipPipPip
  • 409 messages

Posté 06 mars 2015 - 06:05

Bon bah me revoilà avec la solution à mon propre problème, j'avais oublié d'éditer la fréquence d'échantillonage dans le calcul de mesure de vitesse... :whistle2:

 

Maintenant je vais passer à l'étape suppérieure : asservir l'ensemble des deux moteurs afin que le robot roule droit à la vitesse voulue.


N'oubliez jamais que "Ban Ki-moon n'attrape pas mousse"


#3 transistance

transistance

    Membre passionné

  • Membres
  • PipPipPip
  • 409 messages

Posté 07 mars 2015 - 05:14

Avant d'asservir l'ensemble des deux moteurs je tente de changer l'unité de commande mais ça ne se passe pas bien.

 

Pour l'instant je travail en tr/s mais comme c'est pas très parlant je veux traduire ça en cm/s. En théorie, je me suis dit qu'il suffisait de donner une consigne en cm/s et de modifier le calcul de mesure de vitesse sauf que je me retrouve avec un moteur qui répond de manière très brusque et saccadé. Je n'arrive pas à voir ce qui cloche.

 

L'ancien calcul qui donnait une mesure en tr/s:

mesure_vit_d = (50*compteurD)/tick_trm/reduction;

Le nouveau calcul qui donne une mesure en cm/s:

mesure_vit_d = (50*compteurD)/tick_trm/reduction;
mesure_vit_d = mesure_vit_d * perim_roue;

Evidemment je donne une consigne en cm/s

 

avec:

- 50 = frequence d'échantillonage

- CompteurD = nombre de tick compté

- tick_trm = nombre de tick du codeur

- reduction = le rapport de réduction entre la sortie moteur et la roue

- perim_roue = perimetre de la roue en mm

 

Une idée svp ?

 

EDIT : En faisant la conversion cm/s vers tr/s hors de la routine d'asservissement  pour alimenter la consigne ça fonctionne.

consigne = 12/(perim_roue/10); //12cm/s converti en tr/s

Si quelqu'un peut m'expliquer ce qui m'échappe ça serait sympas.


N'oubliez jamais que "Ban Ki-moon n'attrape pas mousse"


#4 Leon

Leon

    Membre passionné

  • Membres
  • PipPipPipPipPip
  • 1 289 messages
  • Gender:Male

Posté 07 mars 2015 - 07:43

Est-ce que tu as bien pensé à changer les "gains" kP, kI, et kD? Si tu changes d'unité, il faut changer les gains en conséquence.

 

Exemple : si tu as un gain proportionnel kP de 10V/m, cela est équivalent à 0.1V/cm

 

Leon.


BOB4, mon drone hélicoptère autonome d'intérieur http://heli.bot.free.fr/
BOB3, mon robot autonome d'intérieur avec WiFi + Foxboard Linux http://ze.bot.free.fr/
BOB5, robot bipède simulé, puis tentative de réalisation (fail)


#5 transistance

transistance

    Membre passionné

  • Membres
  • PipPipPip
  • 409 messages

Posté 07 mars 2015 - 09:08

Merci Léon c'était bien ça ! :)


N'oubliez jamais que "Ban Ki-moon n'attrape pas mousse"






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

0 members, 0 guests, 0 anonymous users