Bonjour,
Je galère un peu avec les modulos 360°
Quelqu’un a t'il vu ou réalisé un programme (genre en C) qui commande un robot pour qu'il effectue une rotation de N degrés sur place (deux moteurs tournant en sens opposés)
Données:
- On a une boussole donnant un azimut compris entre 0 et 359.9°
- On entre une consigne N = Angle de rotation demandé (c'est une rotation relative à la position de départ)
=> Par ex: N = +90: Le robot tourne à droite dans le sens horaire de 90°: il fait donc un quart de tour
=> Par ex: N = -180: Le robot tourne à gauche dans le sens antihoraire de 180°: il fait donc un demi-tour
Dans ma fonction (non bloquante ou boucle itérative peu importe...) je voudrais juste connaitre en temps réel l'écart angulaire pour gréer mes moteurs (PWM réglé par un PID..)
Si l'écart (°départ <=> °arrivé) est positif, je tourne dans un sens
Si l'écart (°départ <=> °arrivé) devient négatif, je dois tourner dans l'autre sens car j'ai dépassé le nouveau cap souhaité
Si l'écart (°départ <=> °arrivé) est proche de +/-0 => Fin
J'ai bricolé un code qui marche uniquement dans un sens de rotation (horaire c-a-d angle augmentant) et qui "dérape" si l'écart devient négatif (fait plusieurs tours jusqu’à ce que l'on tombe sur zéro en écart!)
Vous pouvez tester le code ici : https://www.onlinegdb.com/online_c_compilerCode:#include <stdio.h> int bouger(const int _argument); // Fonction non bloquante qui renvoie 0 lorsque je suis arrivé à destination sinon renvoie 1 int main() { while (bouger(100)); // Boucle jusqu’à l'arrivée à destination (100° sur la droite) return 0; } int bouger(const int _argument) // Cette fonction est un prototype qui ne marche qu'avec _argument > 0 { static int consigne_cap = 0; // Consigne cap à suivre lors des déplacements static unsigned long compteur_deplc = 0; static int init = 1; int Angle_ecart = 0; // calcul de l'écart entre la trajectoire souhaitée et la réelle ou écart en degré par rapport au cap voulu lors des rotations static int boussole = 300; // Simule la boussole => Ici on démarre à l’azimut 300° boussole +=11; // Simule la boussole => Simule le déplacement et donc le changement des valeurs de cap lut par la boussole boussole = boussole %360; // 0° < boussole < 360° if (init) // Exécuté au 1er appel de la fonction (mémorise l'azimut actuel, et RAZ des valeurs de calculs) { init = 0; consigne_cap = boussole + _argument; if (consigne_cap > 360) consigne_cap-= 360; } Angle_ecart = consigne_cap - boussole ; // calcul de l'écart entre l'orientation initiale et la finale if (Angle_ecart < 0) Angle_ecart+= 360; // Evite les bugs lorsque boussole + consigne_cap > 360 printf("\n\nCap: %d D: %d consigne_cap: %d", boussole , Angle_ecart, consigne_cap); // Affiche le déroulement du programme if (Angle_ecart < 1) {printf("\n\nFINI "); return 0;} // STOP car fin du mouvement else return (1); // On a pas fini... }
...et on vois que l'on fait plusieurs tours avant d'y arriver (et évidemment je de gère pas les angles négatifs pour tourner à gauche)
Merci d'avance, cela me permettra de tondre ma pelouse sans faire trop de ronds
Matthieu
-----