20) 07/10/2017 : Se dégourdir les jambes (MJD 58033)

Aujourd’hui restera mémorable pour les équipes qui travaillent sur la sonde martienne. Cette dernière va commencer l’apprentissage de la marche à pieds. Le bébé va quitter son berceau confortable pour toucher du doigt les réalités quotidiennes et découvrir les difficultés de la marche à pied. Toutefois, comme ce mode de déplacement impose la notion de Mouvement Coordonné, avant d’envisager les premières fonctions motrices nous allons pas à pas (Je ne résiste pas à ce jeu de mots rigolo !) décrire cette procédure incontournable, préalable à de nombreux programmes intégrés dans le calculateur. C’est le démonstrateur P11_Evaluation_des_mouvements.ino qui sera mis à contribution pour tester les premières briques de l’édifice logiciel.

Les tableaux de postures.

Probablement que vos moteurs seront assez proches des SG90 intégrés sur le prototype. Vous pourrez globalement utiliser directement le programme P29 qui écrit les tableaux de valeurs en EEPROM. Compte tenu de la dispersion de caractéristiques, il faut s’attendre à des divergences. Aussi, par utilisation du programme P08 il vous se

ra possible de piloter moteur par moteur au potentiomètre pour affiner les valeurs propres à votre machine. Cette manipulation sera facilitée en notant les valeurs numériques des consignes dans la fiche vierge nommée Consignes pour les postures. Pour que vous puissiez éventuellement avoir un résumé de ce qui est actuellement contenu dans l’EEPROM, est également disponible ma fiche personnelle. Il sera inutile de l’imprimer, la consulter sur le moniteur vidéo de l’ordinateur étant suffisant pour comparer les données et détecter une aberration éventuelle durant vos manipulations. Modifier P29 est facile car chaque posture est bien délimitée par des remarques et facile à identifier par les titres des séparations de blocs de données.

Avant de développer les configurations particulières et les modes de déplacement, notez que globalement les valeurs inscrites en EEPROM devraient globalement convenir. Mise à part la configuration de décollage pour laquelle les Jambes sont vraiment très proches les unes des autres, les autres tableaux contiennent des valeurs probablement suffisamment voisines de celles correspondant à vos motorisations pour rester exploitable. Dans un premier temps vous pouvez certainement utiliser les tableaux en l’état, vous peaufinerez ensuite à votre guise. Toujours pour vous simplifier la vie, si vous ouvrez le dossier <Galerie d’Images> et que vous consultez Image 07.jpg vous allez constater qu’il est facile de se passer d’un berceau. Un simple bocal peut faire l’affaire. Dans ce cas je vous conseille de le remplir de sable par exemple pour l’alourdir et le rendre plus stable. (Ou mieux si vous avez : De la poudre d’or bien tassée !) Il faut savoir que par moment la sonde est animée de mouvements assez brusques. Il vaut mieux que son berceau soit bien stable.
Surtout ne vous précipitez-pas pour rapidement étudier un circuit imprimé. Attendez que je vous propose le mien, car les schémas électroniques vont changer. À ce stade du développement ils ne sont pas du tout stabilisés. L’architecture matérielle n’est qu’ébauchée. On va certainement réaffecter les broches, changer certains choix, ajouter des fonctions. Alors patience …

La posture VEILLE.

Certainement celle qui sera la plus employée en termes de durée car elle permet de ranger la sonde dans le placard quand elle n’est pas utilisée pendant de longues périodes, sans avoir obligatoirement à réaliser un quelconque berceau. Cette posture a pour but de poser le châssis sur le bouclier et de rétracter les Jambes assez haut pour ne pas qu’elles portent sur le sol. On soulage ainsi les éléments mécaniques fragiles, et tout particulièrement la motorisation. (Palier de guidage des arbres, engrenages …) Ce sera la configuration à adopter lorsqu’en exploitation une tempête de sable sera imminente. Dans ces tourmentes du climat martien l’atmosphère est totalement rendue opaque rendant inutilisables les instruments scientifiques. Les vents violents peuvent soumettre l’appareil à des poussées brusques néfastes pour les Jambes. On pose alors JEKERT sur son robuste bouclier et on la fait passer en SOMMEIL pour économiser l’énergie électrique. Quand la météo est meilleure, on

réveille la sonde qui peut reprendre ses activités. La Fig.97 présente la posture VEILLE. Cette configuration est caractérisée par l’orientation horizontale des Fémurs. Les Griffes sont ramenées vers le haut de telle façon que les « chaussettes » dont il est question ci-dessous soient légèrement au dessus du sol quand le bouclier est en contact avec ce dernier. L’intégralité des jambes est alors déchargée de tout effort dû au poids de la sonde, la mécanique étant entièrement délestée.

L’expérience démontre largement que l’adhérence avec une surface non rugueuse, comme le plateau en bois de la table de séjour par exemple, est très insuffisante pour éviter du glissement lors des déplacements. Les Griffes dérapent inexorablement dès que l’on cherche à déplacer la sonde. La Fig.96 propose une solution provisoire qui consiste à munir l’extrémité des Griffes de « chaussettes » en caoutchouc visible en 1. Cette solution n’est pas une panacée absolue mais améliore considérablement le comportement de JEKERT. Ces chaussettes sont constituées de « passe cloison » en caoutchouc modifiés par perçage pour pouvoir y introduire les Griffes. N’étant pas sérieusement liés à la pièce en aluminium ils ont tendance à se déboîter quand le frottement engendre des efforts transversaux. Il est prévu de les coller : affaire à suivre quand on passera à l’intégration définitive.

Changement de stratégie.

Remettre en cause les choix effectués au cours des études qui précèdent un développement en cours fait partie de la règle du jeu. Abordant les prémisses de la motricité, divers phénomènes expliqués dans le chapitre précédent engagent à changer notre fusil d’épaule. En effet, la posture « Stable raisonnable » présentée sur la Fig.88 n’est pas du tout idéale pour plusieurs raisons. En particulier l’amplitude des mouvements des Hanches est notable et rend les Contraintes n°2 et n°3 exagérées avec des pertes d’équilibre engendrées par l’inertie en translation difficiles à palier. Par ailleurs, l’amplitude des glissements au sol est trop importante. (Voir la Fig.95) de ce fait la Contraintes n°4 est pénalisée. Suite à de nombreux essais prospectifs, une solution acceptable a été dégagée. On « abandonne » la posture au bénéfice de la configuration « Stable raisonnable« . Mis à part certains cas particuliers comme JEKERT sur un plan incliné à forte pente par exemple, ce sera cette nouvelle configuration qui sera prise en référence pour tout déplacement élémentaire. Cette configuration présentée en Fig.98 est caractérisée par l’alignement transversal des contacts entre les Griffes et le sol avec la direction transversale des axes de rotation des Hanches.
Par exemple on peut observer sur la Fig.98 que les contacts a et d sont dans le prolongement de la droite allant des arbres moteurs A et D. Pour les Jambes arrières, les contact b et c sont sur la droite qui passe par les axes des arbres moteurs B et C. Observez les Image 09.jpg et Image 10.jpg dans la <Gallerie d’images> pour avoir une idée plus précise de cette posture fondamentale. Fondamentale car elle servira de départ pour une majorité de mouvements de base et terminera ces derniers. Maintenant il reste à concrétiser par logiciel.

Les mouvements coordonnés.

Contemplant la nature qui nous entoure, on constate que tous les animaux ainsi que les humains se déplacent en bougeant leurs membres par des mouvements soigneusement coordonnés qui n’ont rien d’innés. Certains animaux arrivent rapidement à se tenir debout. Un poulain par exemple ne met que quelques minutes à se redresser sur ses pattes. Pour les humains l’apprentissage est bien plus laborieux. JEKERT, bien qu’étant un animal artificiel, devra comme pour le monde des vivants procéder par des « gesticulations » synchronisées. Par exemple, quand on désire effectuer un pas en avant, une multitude d’articulations dans notre corps va être mise en mouvements simultanés, chaque variation de posture élémentaire étant parfaitement synchrone aux autres sans que nous n’y prêtions attention. Les déplacements sur trois ou quatre Jambes seront également des ajustements angulaires coordonnés si l’on veut espérer voir marcher l’insecte robotisé. Pour comprendre le principe des mouvements coordonnés, c’est à dire simultanés, nous allons analyser un changement de posture. Par exemple on va étudier

le passage de la configuration Stable Transversale du mode VEILLE. Sur la Fig.99 ne sont représentées que les configurations de départ et de fin de mouvement de rétraction des Jambe. En S est représentée la configuration Stable transversal et en V la posture du mode VEILLE. Dans le premier cas les chaussettes sont en contact avec le sol martien. Dans le deuxième cas c’est le bouclier de protection qui sera posé dans la poussière ocre. Comme on veut éviter au maximum l’usure des chaussettes en caoutchouc, il faut éliminer les glissements transversaux, soit Tg à gauche ou Td à droite. Pour ne pas que la chaussette ne dérape latéralement, il faut que son mouvement V par rapport au châssis suive la verticale Z’Z. Pour arriver à ce résultat il importe que les rotations Rp du Pied et celle du Tibia Rt soit réalisées simultanément et coordonnées, c’est à dire dans des rapports de vitesses bien précis. Sur des animaux on peut considérer qu’il y a une infinité de postures intermédiaires entre les configurations S et V. Dans notre réalité logicielle on procédera par un nombre fini de huit étapes suffisant pour obtenir une cinématique relativement fluide.

 

Compromission acceptable.

Compte tenu des faiblesses de rigidité mécaniques déjà mentionnées dans les chapitres précédents, il ne servira à rien d’engager des procédures complexes pour coordonner la gestuelle de la petite sonde. Hors, pour assurer un déplacement par rapport au châssis parfaitement vertical, il faudrait que durant tout le mouvement les vitesses angulaires des rotations Rp et Rt soient dans des proportions dont le calcul relève d’une trigonométrie très indigeste. Nous allons nous contenter d’une solution approximative tout à fait convenable qui minimisera l’étendu du code.

La technique utilisée consiste à :
• Utiliser le pilotage manuel pour déterminer les valeurs de consigne correspondant pour chaque articulation concernée aux deux positions extrêmes.
• Diviser la différence de ces valeurs limites par huit pour déterminer la variation moyenne.
• Sur toutes les articulations impliquées, partir de la consigne initiale, et huit fois lui ajouter la variation moyenne pour effectuer une étape élémentaire. Cette séquence est imposée pour chaque étape à tous les moteurs qui participent au déplacement souhaité.

Examinons en détail la procédure void Coordonne() qui se charge d’effectuer ce travail. Elle sera invoquée à chaque étape pour tous les moteurs concernés. En réalité, pour minimiser le code on pilotera systématiquement tous les moteurs, mais dans cette procédure, ceux qui ne sont pas concernés recevront chaque fois leur consigne initiale, donc ils ne bougeront pas.
Configuration_voulue est un tableau contenant les douze consignes pour tous les moteurs.
• Chaque fois que le programme fait appel à la routine qui fait bouger un moteur, le tableau de douze valeurs Configuration_actuelle est mis à jour. Ce tableau contient donc en permanence les positions angulaires de tous les moteurs de la sonde sous formes de « consignes » de type int.
Pour générer un mouvement de base, cette procédure va se voir invoquée huit fois pour chaque moteur soit 8 x 12 = 96 fois. Pour fonctionner, la table Configuration_actuelle est déjà à sa disposition en mémoire RAM. Il faut en revanche amener dans le tableau Configuration_voulue les valeurs de la posture finale qui sont préservées sous forme « d’empreintes » dans la mémoire EEPROM non volatile. Dans ce but, on désigne en  à void Coordonne() l’adresse en EEPROM du début du tableau des empreintes par un passage de paramètre Configuration_desiree.


En (2) le programme affecte au pointeur PTR cette adresse de départ. C’est en (3) qu’il est fait appel à la routine Charge_configuration_voulue() qui recopie dans le tableau Configuration_voulue les valeurs correspondant à la configuration finale souhaitée.


L’instruction (4) va calculer les valeurs moyennes des douze variations angulaires élémentaires logées également dans un tableau désigné par l’identificateur Increment. Notez que les trois tableaux contiennent des entités homogènes toutes de type int.
Pour calculer la valeur d’un incrément la technique immédiate consiste à utiliser la formule :

Toutefois, dans le but d’optimiser la compacité du code généré, l’instruction (4) utilise une astuce logicielle. Généralement, la division d’un nombre entier par un autre nombre entier conduit à une valeur fractionnaire. Hors les consignes envoyées aux moteurs le sont sous forme d’int ce qui obligerait à utiliser une instruction de transposition.  Mathématiquement, diviser par huit revient à diviser trois fois par deux. En binaire, seule base de fonctionnement d’un microcontrôleur, diviser par deux une donnée binaire se fait « naturellement par un décalage logique « à droite« . (Shift.) Le résultat reste entier, car les bits qui correspondraient à la fraction décimale

sont « perdus » durant le décalage. C’est cette technique totalement optimisée qui est utilisée dans l’instruction (4). La boucle for (byte I = 0; I < 12; I++) génère les douze valeurs correspondant à chaque moteur. Noter que si la consigne finale et la consigne initiale sont identiques, on obtiendra un incrément égal à zéro, donc pas de modification sur la consigne qui sera envoyée au multiplexeur. La boucle (5) va générer une séquence de huit étapes aboutissant au déplacement complet. Pour chaque changement de posture élémentaire, en (6) on pilote les douze moteurs. Utilisant les divers paramètres, la procédure Bouge_un_membre() en (7) fait changer un moteur de position angulaire si « Moteurs OFF » n’est pas effectif. Enfin, avec l’instruction (8) on génère entre chaque posture intermédiaire un petit délai de 50mS pour laisser le temps aux moteurs de balayer l’angle « Increment« . Ce ralentissement sera surtout favorable au respect de la Contrainte n°2 relative aux inerties pouvant faire basculer la sonde.

C’est pas juste !

Reste que si cette procédure effectue un travail considérable, le résultat final n’est pas totalement celui attendu. En effet, la division par huit fait perdre un résidu fractionnaire. Du coup, la posture ne sera pas tout à fait celle désirée. Globalement, il sera généralement suffisant d’en rester là.  De toute façon nous savons que les faiblesses mécaniques engendreront des écarts bien plus importants que ce petit résidu « oublié » dans les instructions de décalage. Du reste, pour se rendre compte que l’écart final reste assez dérisoire, effectuons le calcul pour le moteur du Fémur de la Jambe B par exemple. (C’est le moteur n°5 qui est concerné par cette évaluation) On va consulter les valeurs deux configurations extrêmes sur le tableau de la Fiche n°9 :

La consigne finale sera : 414 – (14 x 8) = 414 – 112 = 294.
Il est clair que pour cet exemple, 294 ou 296 ne sera pas « visible ». Si « l’arrondi » est plus défavorable, l’écart peut s’avérer plus important. Aussi, la posture Stable Transversal servant de référence, on terminera les déplacements de base qui y font appel par la subroutine void Confirme_stable_et_libere_efforts() qui effectue coup sur coup deux actions :
• Elle fait passer de la posture finale approximative à la posture exacte,
• Elle libère les efforts parasites dans les articulations des jambes. (Voir ci-dessous.)

Libérer les efforts parasites dans la motorisation.

Trépigner peut s’avérer salutaire. Considérons à nouveau la Fig.95 qui fait apparaître les glissements transversaux. Ces derniers engendrent des frottements. Bien que l’on ait cherché à les minimiser, ils seront malgré tout effectifs. Par ailleurs, quand on va avancer, reculer, tourner etc, il y aura forcément des efforts longitudinaux parasites qui résulteront de frottements au sol un peu différents sur chaque Griffe. Ces phénomènes combinés vont se traduire par des poussées horizontales diverses sur les « chaussettes ». Ces efforts sont parasites, il convient de les annuler.
La technique pour atteindre ce but consiste à soulever puis reposer rapidement chaque Jambe les une après les autres. La procédure void Libere_efforts() effectue cette opération qui pour des raisons d’optimisation de « stabilité » procède en « alterne/interne », c’est à dire qu’elle va animer les quatre Jambes dans l’ordre A, C, B puis D. Notez au passage que pour réactiver la Sonde et la faire passer du mode VEILLE à la posture de base Stable Transversal, il suffit d’effectuer un mouvement coordonné entre les deux configuration, suivi de void Confirme_stable_et_libere_efforts(). Ne faisant appel qu’à deux ou trois subroutines, les mouvements de base vont maintenant se montrer très économes en code binaire généré par le compilateur. Avec ces quelques procédures très optimisées, nous disposons des briques logicielles qui vont nous permettre de construire tout l’édifice.

Un petit pas pour JEKERT, un pas de géant pour le programme.

Wouaffffff, quelle formule géniale je viens de trouver ! Il faut absolument la proposer au prochain spationaute qui foulera pour la toute première fois la poussière du sol martien. Elle va devenir historique cette phrase, je vous l’assure, c’est une évidence …
Bon, redevenons sérieux. Pour rappel, les études préliminaires ont montré qu’il sera avantageux de toujours partir de Stable Transversal pour effectuer un déplacement de base, et toujours terminer ce dernier par cette posture. Cette technique assure une stabilité suffisante lors des mouvements combinés. Elle facilite la programmation car on connaît pour chaque mouvement de base sa configuration initiale. Terminer par Stable Transversal est facile et se résume à un appel de procédure. Enfin, pour simplifier le développement, on libérera les efforts parasites à chaque mouvement de base. On pourrait objecter que ces trépignements systématiques vont ralentir globalement les déplacements. C’est vrai. Mais ils simplifient la programmation, et surtout il optimise le code objet généré. Hors, contrairement à un « animal simulé » qui devrait pouvoir se sauver en cas de danger ou pour attraper une proie, une sonde spatiale par « nature » effectue toujours des déplacements lents. Les ondes radio entre la station de contrôle et Mars vont prendre au minimum 15 minutes. On ne reçoit l’accusé de réception qu’une demi-heure plus tard. Dans ces conditions on analyse en détail  l’environnement avec la caméra de bord, on décide d’un mouvement « raisonnable » et l’on fait bouger « avec prudence » le lointain robot. Dans un tel contexte, la lenteur c’est la routine.

Toujours dans le but permanent d’optimiser le code, on va faire appel à un maximum de procédures de service pour faire bouger JEKERT. Par la suite, un simple appel devient suffisant pour faire bouger l’insecte mécanique dans tous les sens. Le secret d’une programmation efficace quand il s’agit d’un microcontrôleur réside dans cette obsession d’optimisation. C’est grâce à elle que l’on va pouvoir programmer une foule d’actions alors que l’espace mémoire pour le programme est totalement dérisoire si l’on compare avec les téraoctets disponibles sur les P.C.

Explicité en Fig.93 le principe fondamental pour faire avancer la sonde montre que l’on décale les Jambes latéralement par paires. Il aurait été possible d’adopter des mouvements de type alterne/interne qui seraient plus proches de ceux d’un animal. Cette approche a été écartée toujours pour des raisons d’avarice en génération de code objet. La posture de départ étant géométriquement caractérisée par des orientations transversales des Hanches, décaler vers l’avant ou vers l’arrière va faire appel à deux subroutines dédiées. Choisir le coté qui bouge revient à préciser « Bâbord » ou « Tribord », information qui sera passée en paramètre. Du coup on va utiliser la même procédure void Avance_paire(« coté« )  ou void Recule_paire(« coté« ) pour laquelle on fournira en paramètre le coté désiré sous forme d’un booleen. Si ce dernier vaut true les deux Jambes Bâbord bougeront par rapport au châssis. S’il est positionné à false ce sont celles de Tribord qui seront animées. Faire avancer d’un pas ou reculer d’un pas devient quasiment élémentaire :

Il importe de noter que chaque mouvement d’une Hanche est suivi d’un délai de 0,2 seconde pour laisser le temps au servomoteur de balayer l’angle de rotation consigné, les deux procédures Avance_paire() et Recule_paire() étant strictement analogues.

Enfin, toujours dans l’optique de diminuer à outrance les octets consommés par le programme objet, pour avancer ou reculer une Jambe on fait encore appel à une procédure de servitude Avance_Recule_Jambe () pour laquelle on indique en paramètre le sens du mouvement et la Jambe concernée. Tout jeu de mots mis à part, avec ces quelques procédures de service nous avons fait un pas en avant considérable dans le développement logiciel. Avec quelques appels à subroutines qui s’enchaînent, nous sommes en mesure de faire réaliser à JEKERT des déplacements complexes en ne consommant que quelques dizaines d’octets par mouvement. Le moral est au beau fixe, le projet est sur des rails. Faites-vous plaisir. Dans un premier temps, la sonde étant sur son berceau tester le mode VEILLE, et la posture de base Stable Transversal. Puis observez Avancer d’un pas, Reculer d’un pas. Voir ainsi le petit animal mécanique gigoter à un coté un peu magique, presque fascinant. Puis, posture veille imposée, déposez l’animal sur son bouclier et recommencez les manipulations. Il m’a fallu des heures pour mettre au point ces divers mouvements de base, mais quelle satisfaction de voir ainsi se trémousser la petite sonde. La robotique ludique c’est proprement génial !

La suite est ici.

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *