Et bien, non ! Rien ne va plus !
Je pensais que cela fonctionnait parce que le UNO était alimenté par l'USB.
Si j'enlève l'USB et le cavalier, le UNO n'est plus alimenté.
Posté 09 décembre 2020 - 12:49
Et bien, non ! Rien ne va plus !
Je pensais que cela fonctionnait parce que le UNO était alimenté par l'USB.
Si j'enlève l'USB et le cavalier, le UNO n'est plus alimenté.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 09 décembre 2020 - 02:58
En définitive, il faut alimenter spécifiquement le UNO si le cavalier est enlevé.
Je vais piquer la tension sur un connecteur servo et la souder sur le point de soudure du Vin.
Malheureusement, ce Shield ne redistribue pas les connecteurs du UNO en mode gigogne.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 09 décembre 2020 - 03:34
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 17 décembre 2020 - 07:40
J'ai donc testé les modifications de Sandro. Dans un premier temps, directement sur mon Quad qui n'a pas du tout apprécié et un servo a rendu l'âme.
J'ai donc monté un banc de test spécifique avec 2 servos MG90S. Ce banc de test comporte une seule patte, la patte avant droite (FR).
Le servo de gauche est le FRLS, et celui de droite est le FRRS.
Le 4 barres dessine inlassablement une ligne verticale sur l'axe Y, avec x=0 et y=-50 à y=50.
Cela fonctionne bien, mais bizarrement ! Par exemple, si je commentarise la ligne 107, cela ne fonctionne plus.
Quelques questions:
1 - pourquoi à la ligne 36, la position initiale est à 1700 ?
2 - pourquoi à la ligne 38 et 39, les min et max sont à 1000 et 2000, au lieu de 500 et 2500 ?
3- à partir de la 70 à 80, j'essaye de positionner les servos dans leur position initiale que j'ai défini à 50° et 180°-50°, mais cela ne fonctionne pas.
Voici le code et le banc de test.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 17 décembre 2020 - 10:52
Bonsoir,
tout d'abord, je suis désolé si la destruction du servo vient de mon code. Est-ce que tu as une idée de ce qui peut l'avoir cassé? Appui contre butée? Surchauffe? Tu alimentes tes servos avec quelle tension vs quelle tension nominale?
Pour répondre à tes questions :
1) la valeur de 1700 est une valeur "au hasard". Il me semble que j'avais initialement mis 1500 ("le milieu"), puis changé à 1700 pour faire bouger un peu les servos. Tu peux sans problème changer cette valeur pour 1500, ou une valeur de ton choix pour chaque servo. Tu peux aussi appeller set_position_degrees depuis le setup pour fixer la position initiale (qui sera exécutée au premier appel de envoyer_pulse)
2) J'avais en tête que les impulsions des servos allaient de 1000 à 2000µs. Mais je me trompe ou que tes servos exploitent une gamme plus large, libre a toi de modifier (j'ai volontairement mis un tableau de constantes pour chaque servo dans le but de facilement pouvoir configurer : dans le cas contraire, j'aurais juste pu utiliser une valeur fixe en dur dans le code)
3) c'est normal : mon code, contrairement à la librarie servo.h n'utilise pas interruptions : chaque appel à envoyer_pulse génère une seule et unique impulsion. Il faut donc appeller la fonction envoyer_pulse toutes les PERIODE_US microssecondes (ie toutes mes 20 000µs si on veut respecter la convention standard des servos de modélisme, ou on peut tenter une période moindre si on veut essayer d'augmenter la fréquence d'asservissement).
Donc pour que ça marche, il faut impérativement une boucle semblable au while (nb : le calcul de la nouvelle position est facultatif : par défaut on garde la dernière position demandée).
Je vois également que tu as tenté de faire quelques modifications sur la structure du code, qui, j'en ai bien peur, ne le rendent probablement inopérant. Le fait que j'ai eut la "mauvaise" idée d'avoir deux variables locales avec le même nom dans mon code (start_time), a probablement du t'induire en erreur (en pratique, il s'agit de deux variables locales de portée ("visibilité") totalement disjointe, et qui n'ont aucune relation entre elles.
Sans compter que mon code est très "spécialisé", et est prévu pour fonctionner d'une manière très précise (et ne fonctionnera plus si certains détails changent). En somme, mon code n'a rien d'une libraire conçue pour être utilisée facilement au gré de l'utilisateur : il s'agit au contraire d'un canevas qui "force" l'utilisateur à l'utiliser d'une manière très précise.
Voici donc une version un peu clarifiée, spécifiant explicitement ce que l'utilisateur peut faire ou ne pas faire :
Je te suggère d'essayer d'insérer ton code dans le canevas ci-dessous (qui explique mieux quoi faire ou ne pas faire).
STP : ne modifie rien en dehors de là où c'est explicitement indiqué : tu risque fortement de rendre le programme non fonctionnel (sauf si tu sais exactement ce que tu fais).
Si tu as besoin d'aide, c'est avec plaisir.
PS : dans le canevas, j'ai remplacé le pin 0 par le pin A0 pour le bouton, car utiliser les pins 0 et 1 est souvent une mauvaise idée vu qu'ils servent pur la communication en USB avec l'ordianteur
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
Posté 18 décembre 2020 - 08:54
Merci Sandro. Pas de souci pour le servo, j'en ai d'autres.
1 - Ok.
2 - Désolé, j'ai dit n'importe quoi ! Oui, 1000 à 2000us, c'est bon !
3 - La position initiale, c'est celle qui met le Quad debout, prêt à partir au moment où j'appuie sur le bouton Start.
Non, non, je n'ai pas touché à la structure de ton code. J'ai un peu customisé, pour gagner des lignes, et j'ai mis tes fonctions à la fin, plutôt qu'au début.
Je ne me rappelle pas avoir touché à la variable start_time.
Ce qui m'inquiète le plus, c'est la ligne 107. C'est le Serial.print, première ligne de la fonction InverseKinematics(), si je la mets en commentaire, plus rien ne fonctionne.
Pour le pin 0, vieux débat ! En pratique, cela n'a jamais eu aucune incidence.
Peu importe, je vais revoir tout ça.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 18 décembre 2020 - 10:16
Bonjour,
pourtant, si tu regardes le code que j'avais posté pour la V2 (https://www.robot-ma...e-7#entry111960), j'ai bien 2 variables locales appelées start_time, et non une unique variable globale. Et la valeur de start_time est mise à micros en chaque début de boucle.
Mais après réflexion, je crois que ce point ne pose pas de problème significatif.
Le vrai problème vient je crois du fait d'avoir remplacé
//attendre la fin de la période while(micros()-start_time<PERIODE_US) { //ne rien faire }
par
//attendre la fin de la période while(duration < PERIODE_US) {}
En effet, ta variante est une boucle infinie, car rien ne vient mettre à jour duration.
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
Posté 18 décembre 2020 - 01:42
Oui, tu as raison !
Mais pourquoi ai-je fait cette modif ? C'est incroyable !
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 18 décembre 2020 - 01:53
Probablement car je calculais moi même "duration" dans le loop, avec la même formule, mais juste pour l'afficher.
Je suppose que tu as donc voulu supprimer le doublon en réutilisant duration (ce qui aurait été justifié si la formule ne changeait pas de valeur "toute seule")
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
Posté 19 décembre 2020 - 07:19
Tout va bien ! J'ai réussi à faire fonctionner le programme de Sandro.
Après l'avoir testé, je n'ai pas résisté à l'envie de le mettre à ma sauce. Je préfère un code concis, je n'aime pas dérouler des centaines de lignes.
Les principales modifications sont :
- j'ai gardé le setup() et le loop() au début, et j'ai déplacé les fonctions vers le bas.
- j'ai réécrit l'initialisation des servos à ma sauce. Cela fonctionne très bien.
- dans le loop(), la variable c était incrémentée en première ligne, je l'ai déplacée à la fin, car on manquait la première valeur du tableau.
- le plus important est sans aucun doute la modification des valeurs des tableaux duree_pulse_us_min[10] et duree_pulse_us_max[10] que j'ai passé de 1000 et 2000 à 500 et 2500. Avec les anciennes valeurs, les angles des servos étaient incorrectes.
Dans cette page, https://www.arduino....s/servo/attach/ , on parle de valeurs de pulse allant de 544 à 2400. J'avais cela en tête, même si mes valeurs ne sont pas tout à fait identiques.
Voilà le résultat du mouvement du chapeau chinois. Ne vous méprenez pas, c'est pas mal pour un assemblage de pièces qui est très imprécis dans ce montage. Plus bas, j'ai mis l'image en référence.
Voici mon code.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 20 décembre 2020 - 08:51
J'ai testé sur mon Quad.
Malheureusement, c'est très lent. Au moins, 10 fois plus lent, pas un petit peu.
Et je ne sais pas comment régler la vitesse.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 20 décembre 2020 - 11:48
Le problème est simple : sur une période, tu as 66 points. Une commande prends PERIODE_US=20 000µs= 1/50 s. Du coup, pour faire un "pas" (une période), il te faut 66*(1/50)=1.32 secondes. C'est sur, qu'à se rythme là, tu ne vas pas bien vite.
Que se passait-il sans ton ancien code : tu envoyais les commandes à intervalles beaucoup plus rapprochés (inférieurs à 20ms). Mais la librairie servo n'envoyait quand même qu'un pulse toutes les 20ms pour chaque moteur : il y a donc des points qui sont ignorés, sans que tu maîtrise lesquels (d'ailleurs, ce n'est même pas forcément le même qui est ignoré pour tous les servos).
Pour résumer, le nouveau code fait ce que tu lui dis, et passe par tous les points (un tous les 20ms), alors que l'ancien s'autorisait à en sauter un bon nombre sans que tu maîtrise lesquels.
Donc pour retrouver le comportement de l'ancien code, il suffit de ne garder que un point sur 10 (si tu dis que tu vas 10 fois moins vite) : c'est ce que faisait déjà l'ancien code, sauf que tu n'avais aucune maîtrise sur quel point tu laisse tomber.
Un autre piste pour aller plus vite (et augmenter la précision de la trajectoire), c'est de commander les moteurs plus rapidement : pour ça, il suffit de réduire la valeur de PERIODE_US. Pour celà, il faut que tu respectes 2 contraintes:
- les servos doivent fonctionner avec PERIODE_US aussi faible (ceux que j'ai testé, je peux réduire autant que je veux, d'autres semblerait-il ne peuvent pas descendre trop pas)
- il faut qu'il reste possible de respecter une période de PERIODE_US. Si on appelle T_pulse_max la durée du plus long pulse possible (2.5ms dans ton dernier code), T_processing le temps d'exécution de calculer_nouvelle_position et T_marge une petite marge de sécurité (je pense que 0.5ms devrait suffire), alors il faut que T_pulse_max+T_processing+T_marge <= PERIODE_US
Ce que je te suggèrerais, c'est de combiner les deux :
1) tu cherches la plus petite valeur possible pour PERIODE_US. Cette valeur ne bougera plus ensuite dans tes tests
2) tu adaptes la distance entre les points pour adapter la vitesse
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
Posté 20 décembre 2020 - 02:32
Mouuuuuuais !
Je ne suis pas convaincu. Pour PERIODE_US, j'y avais bien pensé, d'autant que c'était documenté dans les commentaires. J'attendais ta confirmation.
Pour le reste, cela voudrait dire qu'il suffirait de faire moins de pas dans un mouvement pour aller plus vite. Ce n'est pas le cas !
C'est, évidemment, ce que je pensais intuitivement, mais les tests montrent le contraire.
De plus, d'expérience, je fais bien la différence entre un mouvement avec un pas long et celui avec un pas court.
Que le servo n'arrive pas au bout de sa consigne, d'accord, mais qu'il la saute, non, je ne pense pas.
Je vais faire encore quelques tests, après je passe à autre chose. . .
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 20 décembre 2020 - 02:41
Je comprends ce que Sandro explique.
La carte Arduino envoie une consigne toutes les 20ms (c'est ce que fait la bibliothèque Servo par défaut). Ton code tente d'en envoyer plus de 50 consignes par seconde en appelant la fonction Servo, sans respecter le temps de pause de 20ms. Certaines consignes sont perdues car elles ne sortent même pas de la carte Arduino. En fait, le servo ne saute rien du tout, en fait, il ne reçoit qu'une partie des commande que tu cherches à envoyer. Courage !
Le code de Sandro résout ce problème. Tu peux en envoyer toutes les 2.5ms avec la bonne configuration.
Patrick.
Posté 20 décembre 2020 - 03:34
Pour le reste, cela voudrait dire qu'il suffirait de faire moins de pas dans un mouvement pour aller plus vite. Ce n'est pas le cas !C'est, évidemment, ce que je pensais intuitivement, mais les tests montrent le contraire.
Ce n'était probablement pas le cas sur ton ancien code car tu envoyais les pas "trop vite", l'arduino n'ayant même pas le temps de tous les transmettre aux servos.
Avec mon nouveau code, le timming est régulier : SI la vitesse des servos est inférieure à leur vitesse max ALORS le temps de parcours est égal à NBR_PAS*PERIODE_US. Donc pour accélérer ta trajectoire, tu peux "tout simplement" réduire le nombre de pas sur la trajectoire. Attention : si les servos n'arrivent plus à suivre la vitesse demandée, alors ce raisonnement n'est plus valable (et on peut même avoir l'effet inverse, en n'allant plus au bout des enjambées)
Que le servo n'arrive pas au bout de sa consigne, d'accord, mais qu'il la saute, non, je ne pense pas.
Comme l'explique Patrick, le problème est que l'arduino (avec la librairie servo) n’envoie une consigne (ie un pulse) au servo que toutes les 20ms. Si pendant cette durée tu as changé 4 fois la valeur de la consigne, alors seul la dernière valeur sera effectivement transmise au servo.
Le code de Sandro résout ce problème. Tu peux en envoyer toutes les 2.5ms avec la bonne configuration.
Pas tout à fait : il faut ajouter le temps de calculer les nouvelles consignes. Du coup, je dirais plutôt une consigne toutes les 5ms, à moins de pré-calculer la longueur des pulses par servo, plutôt que de les calculer en cours d'exécution à partir des trajectoires en x et y. Si on pré-calcule tout, je pense qu'il doit être possible d'envoyer des données toutes les 3ms
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
Posté 20 décembre 2020 - 07:30
Je comprends parfaitement ce que vous dites, mais il n'en reste pas moins qu'au final, avec des pas de 5mm, je vais plus vite qu'avec des pas de 10mm, pour une amplitude équivalente.
C'est donc en contradiction avec ce que vous dites, à moins que je me sois trompé dans mes tests. C'est parfaitement possible.
Je vais donc tester cela avec mon programme tel qu'il est, pour éventuellement vous en convaincre, puis je testerai avec le programme de Sandro.
Bon, là, avec les fêtes, c'est un peu compliqué, mais je vais faire de mon mieux.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 20 décembre 2020 - 07:45
Avec ton programme, c'est difficile de prédire comment ça vas se comporter, vu qu'il agit de manière "imprévisible". Du coup, il est possible qu'avec des pas plus petits il soit plus rapide.
Si tu te bases sur mon code, alors, tant que les moteurs suivront, je suis convaincu que plus les pas sont longs, plus le robot ira vite (nb : j'insiste : tant que les moteurs suivent : si les moteurs ne tiennent plus la vitesse de déplacement, alors je ne sais pas comment ça vas se comporter, mais il est possible que la situation empire)
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
Posté 20 décembre 2020 - 09:15
Ok, je vais commencer avec ton programme.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 21 décembre 2020 - 09:41
Bravo Sandro !
J'ai baissé la variable PERIODE_US de 20000us à 8000us pour avoir une vitesse acceptable avec un pas de 5mm. Pas génial, environ 250cm en 5 secondes.
Puis, je suis passé au pas de 10mm. Là, tu as égalé mon record à 510cm en 5 secondes, du premier coup.
Evidemment, l'inconvénient, c'est qu'avec un pas de 10mm, ça sautille beaucoup plus qu'avec un pas de 5mm. Les mouvements sont plus violents.
Du coup, les tests sont plus difficiles à faire, et je cours après la bête pour la remettre dans le droit chemin. Malheureusement, il pleut, et je ne peux pas utiliser le rail en extérieur.
Voici les images Excel des 2 pas et du mouvement que j'ai utilisé.
J'ai mis les tableaux duree_pulse_us_min[10] et duree_pulse_us_max[10] respectivement à 544 et 2400 comme indiqué dans cette page https://www.arduino....s/servo/attach/
Voici le code.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
Posté 21 décembre 2020 - 10:25
Bonjour,
le fait que ça sautille plus, ça peut venir du fait que le pas est 10mm, mais aussi simplement du fait que ça ailles plus vite (petit test si tu veux vérifier : garde le pas à 10mm, mais mets PERIODE_US à 16000 µs : tu devrais aller à la même vitesse qu'avec le pas de 5mm à 8000µs, et tu pourra voir si ça sautille plus avec le pas de 10mm qu'avec celui de 5mm à vitesse égale).
Sinon, tu peux aussi tenter de réduire PERIODE_US à 4000 µs (si ton calcul est assez rapide pour tenir la en 1500µs) et reprendre un pas de 5mm. Ou réduire à 0.66*8000 µs, et prendre un pas de 6.66mm
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
0 members, 1 guests, 0 anonymous users