Site icon Blog ARC Optimizer

Un guide du débutant pour la programmation de robots avec Python


Regardons les choses en face, les robots sont cool. Ils vont également diriger le monde un jour, et avec un peu de chance, à ce moment-là, ils prendront pitié de leurs pauvres créateurs charnus (aka développeurs de robotique ) et nous aideront à construire une utopie spatiale remplie avec beaucoup. Je plaisante bien sûr, mais seulement une sorte de .

Dans mon ambition d'avoir une petite influence sur la question, j'ai suivi un cours sur le contrôle autonome des robots. théorie l'année dernière, qui a abouti à la construction d'un simulateur robotique basé sur Python qui m'a permis de pratiquer la théorie du contrôle sur un robot simple, mobile et programmable.

Dans cet article, je vais montrer comment utiliser un framework de robot Python pour développer un logiciel de contrôle, décrire le schéma de contrôle que j'ai développé pour mon robot simulé, illustrer comment il interagit avec son environnement et atteindre ses objectifs, et discuter de certains des défis fondamentaux de la programmation robotique que j'ai rencontrés le long du

Afin de suivre ce tutoriel sur la programmation robotique pour les débutants, vous devez avoir une connaissance de base de deux choses:

  • Mathématiques – nous utiliserons quelques fonctions et vecteurs trigonométriques
  • Python – puisque Python fait partie des plus populaire langages de programmation de robot de base – nous utiliserons des bibliothèques et des fonctions de base de Python

Les extraits de code montrés ici ne sont qu'une partie de l'ensemble du simulateur, qui s'appuie sur des classes et des interfaces, donc pour lire le code directement, vous peut avoir besoin d'une certaine expérience en Python et programmation orientée objet .

Enfin, les rubriques facultatives qui vous aideront à mieux suivre ce didacticiel sont de savoir ce qu'est une machine d'état et comment fonctionnent les capteurs de plage et les encodeurs.

Le défi du robot programmable: perception versus réalité, et la fragilité du contrôle

Le défi fondamental de toute robotique est le suivant: Il est impossible de connaître le véritable état de l'environnement. Le logiciel de contrôle du robot ne peut que deviner l'état du monde réel sur la base des mesures retournées par ses capteurs. Il ne peut tenter de changer l'état du monde réel que par la génération de signaux de contrôle.

Le logiciel de contrôle de robot ne peut que deviner état du monde réel sur la base des mesures renvoyées par ses capteurs.

Ainsi, l'une des premières étapes de la conception des commandes est de proposer une abstraction du monde réel, connue sous le nom de modèle avec lequel interpréter nos lectures de capteur et prendre des décisions. Tant que le monde réel se comporte selon les hypothèses du modèle, nous pouvons faire de bonnes suppositions et exercer un contrôle. Cependant, dès que le monde réel s'écartera de ces hypothèses, nous ne serons plus en mesure de faire de bonnes suppositions et le contrôle sera perdu. Souvent, une fois le contrôle perdu, il ne peut jamais être repris. (À moins qu'une force extérieure bienveillante ne le rétablisse.)

C'est l'une des principales raisons pour lesquelles la programmation robotique est si difficile. Nous voyons souvent des vidéos du dernier robot de recherche en laboratoire, réalisant des exploits fantastiques de dextérité, de navigation ou de travail d'équipe, et nous sommes tentés de demander: "Pourquoi n'est-ce pas utilisé dans le monde réel?" Eh bien, la prochaine fois que vous verrez une telle vidéo, regardez à quel point l'environnement de laboratoire est hautement contrôlé. Dans la plupart des cas, ces robots ne sont capables d'exécuter ces tâches impressionnantes que tant que les conditions environnementales restent dans les limites étroites de son modèle interne. Ainsi, une des clés de l'avancement de la robotique est le développement de modèles plus complexes, flexibles et robustes – et cette avancée est soumise aux limites des ressources informatiques disponibles.

Une des clés de l'avancement de la robotique est le développement de modèles plus complexes, flexibles et robustes.

[Side Note: Philosophers and psychologists alike would note that living creatures also suffer from dependence on their own internal perception of what their senses are telling them. Many advances in robotics come from observing living creatures and seeing how they react to unexpected stimuli. Think about it. What is your internal model of the world? It is different from that of an ant, and that of a fish? (Hopefully.) However, like the ant and the fish, it is likely to oversimplify some realities of the world. When your assumptions about the world are not correct, it can put you at risk of losing control of things. Sometimes we call this “danger.” The same way our little robot struggles to survive against the unknown universe, so do we all. This is a powerful insight for roboticists.]

Le simulateur de robot programmable

Le simulateur que j'ai construit est écrit en Python et très intelligemment surnommé Sobot Rimulator . Vous pouvez trouver la v1.0.0 sur GitHub . Il n'a pas beaucoup de cloches et de sifflets mais il est conçu pour faire une chose très bien: fournir une simulation précise d'un robot mobile et donner à un aspirant robotique un cadre simple pour pratiquer la programmation de logiciels de robot. Bien qu'il soit toujours préférable d'avoir un vrai robot avec lequel jouer, un bon simulateur de robot Python est beaucoup plus accessible et est un excellent point de départ.

Dans les robots du monde réel, le logiciel qui génère les signaux de contrôle (le « contrôleur ”) est nécessaire pour fonctionner à une vitesse très élevée et effectuer des calculs complexes. Cela affecte le choix des langages de programmation de robot à utiliser: Habituellement, C ++ est utilisé pour ces types de scénarios, mais dans les applications robotiques plus simples, Python est un très bon compromis entre la vitesse d'exécution et la facilité de développement et de test.

Le logiciel que j'ai écrit simule un robot de recherche réel appelé Khepera mais il peut être adapté à une gamme de robots mobiles de différentes dimensions et capteurs. Depuis que j'ai essayé de programmer le simulateur aussi similaire que possible aux capacités du vrai robot, la logique de contrôle peut être chargée dans un vrai robot Khepera avec un refactoring minimal, et il fonctionnera de la même manière que le robot simulé. Les caractéristiques spécifiques implémentées se réfèrent au Khepera III, mais elles peuvent être facilement adaptées au nouveau Khepera IV.

En d'autres termes, la programmation d'un robot simulé est analogue à la programmation d'un vrai robot. Ceci est essentiel si le simulateur doit être d'une quelconque utilité pour développer et évaluer différentes approches logicielles de contrôle.

Dans ce didacticiel, je décrirai l'architecture logicielle de contrôle de robot fournie avec la v1.0.0 de Sobot Rimulator et fournissant des extraits de la source Python (avec de légères modifications pour plus de clarté). Cependant, je vous encourage à plonger dans la source et à vous amuser. Le simulateur a été bifurqué et utilisé pour contrôler différents robots mobiles, y compris un Roomba2 de iRobot . De même, n'hésitez pas à bifurquer le projet et à l'améliorer.

La logique de contrôle du robot est limitée à ces classes / fichiers Python:

  • models / supervisor.py – cette classe est responsable de l'interaction entre le monde simulé autour du robot et le robot lui-même. Il fait évoluer notre machine à états robotique et déclenche les contrôleurs pour calculer le comportement souhaité.
  • models / supervisor_state_machine.py – cette classe représente les différents états dans lesquels le robot peut se trouver, selon son interprétation des capteurs.
  • Les fichiers du répertoire modèles / contrôleurs – ces classes implémentent différents comportements du robot étant donné un état connu de l'environnement. En particulier, un contrôleur spécifique est sélectionné en fonction de la machine d'état.

L'objectif

Les robots, comme les gens, ont besoin d'un but dans la vie. L'objectif de notre logiciel contrôlant ce robot sera très simple: il tentera de se frayer un chemin vers un objectif prédéterminé. C'est généralement la caractéristique de base que tout robot mobile devrait avoir, des voitures autonomes aux aspirateurs robotiques. Les coordonnées de l'objectif sont programmées dans le logiciel de contrôle avant l'activation du robot mais pourraient être générées à partir d'une application Python supplémentaire qui supervise les mouvements du robot. Par exemple, imaginez qu'il traverse plusieurs points de cheminement.

Cependant, pour compliquer les choses, l'environnement du robot peut être semé d'obstacles. Le robot NE PEUT PAS entrer en collision avec un obstacle sur son chemin vers le but. Par conséquent, si le robot rencontre un obstacle, il devra trouver son chemin afin de pouvoir continuer son chemin vers le but.

Le robot programmable

Chaque robot est livré avec des capacités et des préoccupations de contrôle différentes. Familiarisons-nous avec notre robot programmable simulé.

La première chose à noter est que, dans ce guide, notre robot sera un robot mobile autonome. Cela signifie qu'il se déplacera librement dans l'espace et qu'il le fera sous son propre contrôle. Cela contraste, disons, avec un robot télécommandé (qui n'est pas autonome) ou un bras de robot d'usine (qui n'est pas mobile). Notre robot doit trouver par lui-même comment atteindre ses objectifs et survivre dans son environnement. Cela s'avère être un défi étonnamment difficile pour les programmeurs débutants en robotique.

Entrées de contrôle: capteurs

Il existe de nombreuses façons différentes pour qu'un robot soit équipé pour surveiller son environnement. Il peut s'agir de capteurs de proximité, de capteurs de lumière, de pare-chocs, de caméras, etc. De plus, les robots peuvent communiquer avec des capteurs externes qui leur donnent des informations qu'ils ne peuvent pas observer directement.

Notre robot de référence est équipé de neuf capteurs infrarouges – le nouveau modèle a huit capteurs infrarouges et cinq capteurs de proximité à ultrasons – disposés dans une «jupe ”Dans tous les sens. Il y a plus de capteurs face à l'avant du robot qu'à l'arrière, car il est généralement plus important pour le robot de savoir ce qui se trouve devant lui que ce qui est derrière.

En plus des capteurs de proximité, le robot a un paire de tickers de roue qui suivent le mouvement des roues. Ceux-ci vous permettent de suivre le nombre de rotations effectuées par chaque roue, avec un tour complet vers l'avant d'une roue représentant 2 765 ticks. Les tours dans le sens opposé comptent vers l'arrière, diminuant le nombre de ticks au lieu de l'augmenter. Vous n'avez pas à vous soucier de nombres spécifiques dans ce didacticiel, car le logiciel que nous allons écrire utilise la distance parcourue exprimée en mètres. Plus tard, je vais vous montrer comment le calculer à partir de tiques avec une fonction Python simple.

Sorties de contrôle: mobilité

Certains robots se déplacent sur des jambes. Certains roulent comme une balle. Certains glissent même comme un serpent.

Notre robot est un robot à entraînement différentiel ce qui signifie qu'il roule sur deux roues. Lorsque les deux roues tournent à la même vitesse, le robot se déplace en ligne droite. Lorsque les roues se déplacent à des vitesses différentes, le robot tourne. Ainsi, contrôler le mouvement de ce robot revient à contrôler correctement les vitesses de rotation de chacune de ces deux roues.

API

Dans Sobot Rimulator, la séparation entre «l'ordinateur» du robot et le monde physique (simulé) est incarné par le fichier robot_supervisor_interface.py qui définit l'intégralité de l'API pour interagir avec les "vrais robots" capteurs et moteurs:

  • read_proximity_sensors () renvoie un tableau de neuf valeurs au format natif des capteurs
  • read_wheel_encoders () renvoie un tableau de deux valeurs indiquant le nombre total de ticks depuis le début
  • set_wheel_drive_rates (v_l, v_r) prend deux valeurs (en radians par seconde) et définit la vitesse gauche et droite des roues sur ces deux valeurs

Cette interface utilise en interne un objet robot qui fournit les données des capteurs et la possibilité de déplacer des moteurs ou des roues. Si vous souhaitez créer un robot différent, il vous suffit de fournir une classe de robot Python différente qui peut être utilisée par la même interface, et le reste du code (contrôleurs, superviseur et simulateur) fonctionnera prêt à l'emploi! [19659067] Le simulateur

Comme vous utiliseriez un vrai robot dans le monde réel sans trop prêter attention aux lois de la physique impliquées, vous pouvez ignorer la façon dont le robot est simulé et passer directement à la programmation du logiciel du contrôleur, car ce sera presque la même chose entre le monde réel et une simulation. Mais si vous êtes curieux, je vais le présenter brièvement ici.

Le fichier world.py est une classe Python qui représente le monde simulé, avec des robots et des obstacles à l'intérieur. La fonction de pas à l'intérieur de cette classe s'occupe de l'évolution de notre monde simple en:

  • Application de règles de physique aux mouvements du robot
  • Prise en compte des collisions avec des obstacles
  • Fourniture de nouvelles valeurs pour les capteurs du robot

En fin de compte, il appelle les superviseurs du robot chargés d'exécuter le logiciel du cerveau du robot.

La fonction de pas est exécutée en boucle de sorte que robot.step_motion () déplace le robot en utilisant la vitesse de roue calculée par le superviseur à l'étape de simulation précédente.

La fonction apply_physics () met à jour en interne les valeurs des capteurs de proximité du robot afin que le superviseur puisse estimer l'environnement à l'étape de simulation actuelle. Les mêmes concepts s'appliquent aux codeurs.

Un modèle simple

Premièrement, notre robot aura un modèle très simple. Il fera de nombreuses hypothèses sur le monde. Certains des plus importants sont les suivants:

  • Le terrain est toujours plat et même
  • Les obstacles ne sont jamais ronds
  • Les roues ne glissent jamais
  • Rien ne va jamais pousser le robot
  • Les capteurs ne tombent jamais en panne ou donner de fausses lectures
  • Les roues tournent toujours quand on leur dit de

Bien que la plupart de ces hypothèses soient raisonnables dans un environnement semblable à une maison, des obstacles ronds peuvent être présents. Notre logiciel d'évitement d'obstacles a une implémentation simple et suit la frontière des obstacles afin de les contourner. Nous suggérerons aux lecteurs comment améliorer le cadre de contrôle de notre robot avec une vérification supplémentaire pour éviter les obstacles circulaires.

La boucle de contrôle

Nous allons maintenant entrer dans le cœur de notre logiciel de contrôle et expliquer les comportements que nous voulons pour programmer à l'intérieur du robot. Des comportements supplémentaires peuvent être ajoutés à ce cadre, et vous devriez essayer vos propres idées après avoir fini de lire! La robotique basée sur le comportement un logiciel a été proposé il y a plus de 20 ans et c'est toujours un puissant outil de robotique mobile. À titre d'exemple, en 2007 un ensemble de comportements a été utilisé dans le DARPA Urban Challenge – la première compétition pour les voitures autonomes!

Un robot est un système dynamique. L'état du robot, les lectures de ses capteurs et les effets de ses signaux de contrôle sont en constante évolution. Le contrôle du déroulement des événements implique les trois étapes suivantes:

  1. Appliquer des signaux de contrôle.
  2. Mesurer les résultats.
  3. Générer de nouveaux signaux de contrôle calculés pour nous rapprocher de notre objectif.

Ces étapes sont répétées et jusqu'à ce que nous ayons atteint notre objectif. Plus nous pouvons le faire par seconde, plus nous aurons de contrôle sur le système. Le robot Sobot Rimulator répète ces étapes 20 fois par seconde (20 Hz), mais de nombreux robots doivent le faire des milliers ou des millions de fois par seconde afin d'avoir un contrôle adéquat. Rappelez-vous notre introduction précédente sur les différents langages de programmation de robot pour différents systèmes robotiques et exigences de vitesse.

En général, chaque fois que notre robot prend des mesures avec ses capteurs, il utilise ces mesures pour mettre à jour son estimation interne de l'état du monde – pour par exemple, la distance de son objectif. Il compare cet état à une valeur de référence de ce qu'il veut que l'état soit (pour la distance, il veut qu'il soit nul), et calcule l'erreur entre l'état souhaité et l'état réel. Une fois ces informations connues, la génération de nouveaux signaux de contrôle peut être réduite à un problème de minimisation de l'erreur qui finira par déplacer le robot vers le but.

Une astuce astucieuse: simplifier le modèle

Pour contrôler le robot, nous voulons programme, nous devons envoyer un signal à la roue gauche lui indiquant à quelle vitesse tourner, et un signal séparé à la roue droite indiquant à quelle vitesse tourner. Appelons ces signaux v L et v R . Cependant, penser constamment en termes de v L et v R est très lourd. Au lieu de demander: «À quelle vitesse voulons-nous que la roue gauche tourne, et à quelle vitesse voulons-nous que la roue droite tourne?» il est plus naturel de demander: «À quelle vitesse voulons-nous que le robot avance, et à quelle vitesse voulons-nous qu'il tourne ou change de cap?» Appelons ces paramètres vitesse v et vitesse angulaire (rotationnelle) ω (lire «oméga»). Il s'avère que nous pouvons baser tout notre modèle sur v et ω au lieu de v L et v R et seulement une fois que nous avons déterminé comment nous voulons que notre robot programmé se déplace, transformez mathématiquement ces deux valeurs en v L et v R nous devons réellement contrôler les roues du robot. C'est ce qu'on appelle un modèle de monocycle de contrôle.

[19659004] Voici le code Python qui implémente la transformation finale dans supervisor.py . Notez que si ω est égal à 0, les deux roues tourneront à la même vitesse:

Estimation de l'état: robot, connais-toi toi-même

À l'aide de ses capteurs, le robot doit essayer de estimer l'état de l'environnement ainsi que son propre état. Ces estimations ne seront jamais parfaites, mais elles doivent être assez bonnes car le robot basera toutes ses décisions sur ces estimations. À l'aide de ses seuls capteurs de proximité et de ses roues, il doit essayer de deviner ce qui suit:

  • La direction des obstacles
  • La distance des obstacles
  • La position du robot
  • Le cap du robot

Les deux premières propriétés sont déterminées par les lectures du capteur de proximité et sont assez simples. La fonction API read_proximity_sensors () renvoie un tableau de neuf valeurs, une pour chaque capteur. On sait à l'avance que la septième lecture, par exemple, correspond au capteur qui pointe à 75 degrés à droite du robot.

Ainsi, si cette valeur montre une lecture correspondant à 0,1 mètre de distance, on sait qu'il y a un obstacle à 0,1 mètre, 75 degrés à gauche. S'il n'y a pas d'obstacle, le capteur retournera une lecture de sa portée maximale de 0,2 mètre. Ainsi, si nous lisons 0,2 mètre sur le capteur sept, nous supposerons qu'il n'y a en fait aucun obstacle dans cette direction.

En raison du fonctionnement des capteurs infrarouges (mesure de la réflexion infrarouge), les nombres qu'ils renvoient sont non linéaires transformation de la distance réelle détectée. Ainsi, la fonction Python pour déterminer la distance indiquée doit convertir ces lectures en mètres. Cela se fait dans supervisor.py comme suit:

Encore une fois, nous avons un modèle de capteur spécifique dans ce cadre de robot Python , alors que dans le monde réel, les capteurs sont livrés avec un logiciel d'accompagnement qui devrait fournir des fonctions de conversion similaires de valeurs non linéaires en mètres.

Détermination de la position et du cap du robot (ensemble connu sous le nom de pose [19659106] en programmation robotique) est un peu plus difficile. Notre robot utilise odométrie pour estimer sa pose. C'est là que les tickers de roue entrent en jeu. En mesurant combien chaque roue a tourné depuis la dernière itération de la boucle de contrôle, il est possible d'obtenir une bonne estimation de la façon dont la pose du robot a changé, mais seulement si le changement est faible .

C'est une des raisons pour lesquelles il est important d'itérer la boucle de contrôle très fréquemment dans un robot du monde réel, où les moteurs qui déplacent les roues peuvent ne pas être parfaits. Si nous avons attendu trop longtemps pour mesurer les tics de roue, les deux roues auraient pu faire beaucoup de choses, et il sera impossible d'estimer où nous en sommes arrivés.

Compte tenu de notre simulateur de logiciel actuel, nous pouvons nous permettre d'exécuter le calcul de l'odométrie à 20 Hz — la même fréquence que les contrôleurs. Mais ce pourrait être une bonne idée d'avoir un thread Python séparé fonctionnant plus rapidement pour capturer des mouvements plus petits des tickers.

Ci-dessous est la fonction d'odométrie complète dans supervisor.py qui met à jour l'estimation de la pose du robot. Notez que la pose du robot est composée des coordonnées x et y et du titre thêta qui est mesurée en radians à partir de l'axe X positif. Positif x est à l'est et positif y est au nord. Ainsi, un cap de 0 indique que le robot fait face directement à l'est. Le robot suppose toujours que sa pose initiale est (0, 0), 0 .

Maintenant que notre robot est capable de générer une bonne estimation du monde réel, utilisons ces informations pour atteindre nos objectifs.

Méthodes de programmation du robot Python: comportement de Go-to-Goal

Le but suprême de l'existence de notre petit robot dans ce didacticiel de programmation est d'atteindre l'objectif. point. Alors, comment faire tourner les roues pour y arriver? Commençons par simplifier un peu notre vision du monde et supposons qu’il n’y ait aucun obstacle.

Cela devient alors une tâche simple et peut être facilement programmé en Python. Si nous allons de l'avant tout en faisant face au but, nous y arriverons. Grâce à notre odométrie, nous savons quelles sont nos coordonnées et cap actuels. Nous savons également quelles sont les coordonnées de l'objectif car elles ont été préprogrammées. Par conséquent, en utilisant une petite algèbre linéaire, nous pouvons déterminer le vecteur de notre emplacement au but, comme dans go_to_goal_controller.py :

Notez que nous obtenons le vecteur au but dans le cadre de référence du robot et NON en coordonnées mondiales. Si l'objectif est sur l'axe X dans le cadre de référence du robot, cela signifie qu'il est directement en face du robot. Ainsi, l'angle de ce vecteur par rapport à l'axe X est la différence entre notre cap et le cap sur lequel nous voulons être. En d'autres termes, c'est l'erreur entre notre état actuel et ce que nous voulons que notre état actuel soit. Nous voulons donc ajuster notre taux de virage ω afin que l'angle entre notre cap et l'objectif change vers 0. Nous voulons minimiser l'erreur:

self.kP dans l'extrait ci-dessus du contrôleur L'implémentation Python est un gain de contrôle . C'est un coefficient qui détermine la vitesse à laquelle nous tournons en proportion par rapport à l'éloignement du but auquel nous sommes confrontés. Si l'erreur dans notre rubrique est 0 alors le taux de rotation est également 0 . Dans la vraie fonction Python à l'intérieur du fichier go_to_goal_controller.py vous verrez des gains plus similaires, puisque nous avons utilisé un contrôleur PID au lieu d'un simple coefficient proportionnel.

Maintenant que nous avons notre vitesse angulaire ω comment pouvons-nous déterminer notre vitesse avant v ? Une bonne règle générale est celle que vous connaissez probablement instinctivement: si nous ne faisons pas de virage, nous pouvons avancer à pleine vitesse, puis plus nous tournons vite, plus nous devons ralentir. Cela nous aide généralement à maintenir notre système stable et à agir dans les limites de notre modèle. Ainsi, v est une fonction de ω . Dans go_to_goal_controller.py l'équation est:

Une suggestion pour développer cette formule est de considérer que nous ralentissons généralement à proximité du but afin de l'atteindre à vitesse nulle. Comment cette formule changerait-elle? Il doit inclure en quelque sorte un remplacement de v_max () par quelque chose de proportionnel à la distance. OK, nous avons presque terminé une seule boucle de contrôle. Il ne reste plus qu'à transformer ces deux paramètres du modèle monocycle en vitesses de roue différentielles et à envoyer les signaux aux roues. Voici un exemple de la trajectoire du robot sous le contrôleur go-to-goal, sans obstacles:

Comme nous pouvons le voir, le vecteur à l'objectif est une référence efficace sur laquelle baser nos calculs de contrôle. Il s'agit d'une représentation interne de «où nous voulons aller». Comme nous le verrons, la seule différence majeure entre l'objectif et d'autres comportements est que parfois aller vers l'objectif est une mauvaise idée, nous devons donc calculer un vecteur de référence différent.

Méthodes de programmation du robot Python: éviter les obstacles comportement

Aller vers le but quand il y a un obstacle dans cette direction est un bon exemple. Au lieu de nous engouffrer dans les choses sur notre chemin, essayons de programmer une loi de contrôle qui fait que le robot les évite.

Pour simplifier le scénario, oublions maintenant complètement le point de but et faisons simplement ce qui suit notre objectif: Quand il n'y a aucun obstacle devant nous, avancez. Lorsqu'un obstacle est rencontré, détournez-vous de lui jusqu'à ce qu'il ne soit plus devant nous.

Par conséquent, lorsqu'il n'y a pas d'obstacle devant nous, nous voulons que notre vecteur de référence pointe simplement vers l'avant. Alors ω sera nul et v sera la vitesse maximale. Cependant, dès que nous détectons un obstacle avec nos capteurs de proximité, nous voulons que le vecteur de référence pointe dans la direction la plus éloignée de l'obstacle. Cela entraînera ω à tirer pour nous détourner de l'obstacle, et entraîner v à baisser pour nous assurer que nous ne le faisons pas '

Une bonne façon de générer notre vecteur de référence souhaité est de transformer nos neuf relevés de proximité en vecteurs et de prendre une somme pondérée. Lorsqu'aucun obstacle n'est détecté, les vecteurs seront sommés symétriquement, ce qui donne un vecteur de référence qui pointe tout droit comme vous le souhaitez. Mais si un capteur sur, par exemple, le côté droit détecte un obstacle, il apportera un vecteur plus petit à la somme, et le résultat sera un vecteur de référence qui sera décalé vers la gauche.

Pour un robot général avec un placement différent des capteurs, la même idée peut être appliquée mais peut nécessiter des changements de poids et / ou des soins supplémentaires lorsque les capteurs sont symétriques à l'avant et à l'arrière du robot, car la somme pondérée pourrait devenir nulle.

Voici le code qui le fait dans éviter_obstacles_controller.py :

Utilisation du résultat ao_heading_vector comme référence pour le robot pour essayer de faire correspondre, voici les résultats de l'exécution le logiciel du robot dans la simulation en utilisant uniquement le contrôleur éviter les obstacles, en ignorant l'objectif p oint complètement. Le robot rebondit sans but, mais il n'entre jamais en collision avec un obstacle et parvient même à naviguer dans des espaces très étroits:

Méthodes de programmation du robot Python: automates hybrides (machine à états de comportement)

Jusqu'à présent, nous avons décrit deux comportements – aller au but et éviter les obstacles – isolément. Les deux remplissent admirablement leur fonction, mais pour atteindre l'objectif dans un environnement plein d'obstacles, nous devons les combiner.

La solution que nous développerons réside dans une classe de machines qui a la désignation extrêmement cool de automates hybrides . Un automate hybride est programmé avec plusieurs comportements ou modes différents, ainsi qu'une machine d'état de supervision. La machine d'état de supervision passe d'un mode à un autre à des moments discrets (lorsque les objectifs sont atteints ou que l'environnement change trop soudainement), tandis que chaque comportement utilise des capteurs et des roues pour réagir en continu aux changements de l'environnement. La solution a été appelée hybride car elle évolue à la fois de manière discrète et continue.

Notre framework de robot Python implémente la machine d'état dans le fichier supervisor_state_machine. py .

Équipé de nos deux comportements pratiques, une logique simple se suggère: Quand aucun obstacle n'est détecté, utilisez le comportement aller au but. Lorsqu'un obstacle est détecté, passez au comportement éviter-obstacles jusqu'à ce que l'obstacle ne soit plus détecté.

Cependant, il s'avère que cette logique va générer beaucoup de problèmes. Ce que ce système aura tendance à faire quand il rencontrera un obstacle, c'est de s'en détourner, puis dès qu'il s'en sera éloigné, de faire demi-tour à droite et de s'y heurter à nouveau. Le résultat est une boucle sans fin de commutation rapide qui rend le robot inutile. Dans le pire des cas, le robot peut basculer entre les comportements avec à chaque itération de la boucle de commande – un état appelé Zeno condition .

Il existe plusieurs solutions à ce problème, et les lecteurs qui recherchent des connaissances plus approfondies devraient vérifier, par exemple, l'architecture logicielle DAMN .

nous avons besoin pour notre robot simulé simple est une solution plus facile: Un comportement de plus spécialisé avec la tâche de contourner un obstacle et d'atteindre l'autre côté.

Méthodes de programmation du robot Python: comportement de la paroi de suivi

Voici l'idée: lorsque nous rencontrons un obstacle, prenez les deux relevés de capteur les plus proches de l'obstacle et utilisez-les pour estimer la surface de l'obstacle. Ensuite, définissez simplement notre vecteur de référence pour qu'il soit parallèle à cette surface. Continuez à suivre ce mur jusqu'à ce que A) l'obstacle ne soit plus entre nous et le but, et B) nous sommes plus près du but que nous ne l'étions lorsque nous avons commencé. Nous pourrons alors être certains d'avoir correctement traversé l'obstacle.

Avec nos informations limitées, nous ne pouvons pas dire avec certitude s'il sera plus rapide de contourner l'obstacle à gauche ou à droite. Pour nous décider, nous choisissons la direction qui nous rapprochera immédiatement de l'objectif. Pour comprendre de quelle manière il s'agit, nous devons connaître les vecteurs de référence du comportement aller-but et le comportement éviter-obstacle, ainsi que les deux vecteurs de référence possibles du mur de suivi. Voici une illustration de la façon dont la décision finale est prise (dans ce cas, le robot choisira d'aller à gauche):

La détermination des vecteurs de référence du mur de suivi s'avère être un peu plus compliquée que les vecteurs de référence à éviter ou à atteindre. Jetez un œil au code Python dans follow_wall_controller.py pour voir comment cela se fait.

Conception du contrôle final

La conception du contrôle final utilise le comportement de suivi du mur pendant presque toutes les rencontres avec des obstacles. Cependant, si le robot se trouve dans un endroit restreint, dangereusement proche d'une collision, il passera en mode pur éviter les obstacles jusqu'à ce qu'il soit à une distance plus sûre, puis reviendra au mur de suivi. Une fois les obstacles franchis avec succès, le robot passe à l'objectif. Voici le diagramme d'état final, qui est programmé à l'intérieur du supervisor_state_machine.py :

Voici le robot qui réussit à naviguer dans un environnement surpeuplé en utilisant ce schéma de contrôle:

Un supplément La fonctionnalité de la machine d'état que vous pouvez essayer d'implémenter est un moyen d'éviter les obstacles circulaires en passant au but le plus tôt possible au lieu de suivre la frontière d'obstacles jusqu'à la fin (ce qui n'existe pas pour les objets circulaires!) [19659272] Tweak, tweak, tweak: trial and error

Le schéma de contrôle fourni avec Sobot Rimulator est très finement réglé. Il a fallu plusieurs heures pour peaufiner une petite variable ici, et une autre équation là, pour le faire fonctionner d'une manière dont j'étais satisfait. La programmation en robotique implique souvent beaucoup de vieux essais et erreurs. Les robots sont très complexes et il y a peu de raccourcis pour les amener à se comporter de manière optimale dans un environnement de simulateur de robot… du moins, pas beaucoup de machine learning pur et simple, mais c'est une toute autre boîte de vers.

La robotique implique souvent beaucoup de simples essais et erreurs.

Je vous encourage à jouer avec les variables de contrôle dans Sobot Rimulator et à observer et tenter d'interpréter les résultats. Les modifications apportées aux éléments suivants ont tous des effets profonds sur le comportement du robot simulé:

  • Le gain d'erreur kP dans chaque contrôleur
  • Les gains du capteur utilisés par le contrôleur à éviter les obstacles [19659010] Le calcul de v en fonction de ω dans chaque contrôleur
  • La distance de blocage des obstacles utilisée par la suite – contrôleur mural
  • Les conditions de commutation utilisées par supervisor_state_machine.py
  • À peu près tout le reste

Lorsque les robots programmables échouent

Nous avons fait beaucoup de travail pour arriver à ce point, et ce robot semble assez intelligent. Pourtant, si vous exécutez Sobot Rimulator sur plusieurs cartes aléatoires, il ne vous faudra pas longtemps pour en trouver une que ce robot ne pourra pas gérer. Parfois, il s'enfonce directement dans les virages serrés et entre en collision. Parfois, il oscille simplement d'avant en arrière du mauvais côté d'un obstacle. Parfois, il est légitimement emprisonné sans aucun chemin possible vers le but. Après tous nos tests et ajustements, nous devons parfois arriver à la conclusion que le modèle avec lequel nous travaillons n'est tout simplement pas à la hauteur, et nous devons changer la conception ou ajouter des fonctionnalités.

Dans l'univers du robot mobile , le «cerveau» de notre petit robot est à l'extrémité la plus simple du spectre. De nombreux cas d'échec rencontrés pourraient être surmontés en ajoutant des logiciels plus avancés au mélange. Des robots plus avancés utilisent des techniques telles que cartographie pour se souvenir où cela a été et éviter d'essayer les mêmes choses encore et encore; heuristique pour générer des décisions acceptables quand il n'y a pas de décision parfaite à trouver; et apprentissage automatique pour régler plus parfaitement les différents paramètres de contrôle régissant le comportement du robot.

Un échantillon de ce qui va arriver

Les robots font déjà beaucoup pour nous, et ils le sont déjà ne fera que faire plus à l'avenir. Même si la programmation de base en robotique est un domaine d'étude difficile nécessitant une grande patience, elle est aussi fascinante et extrêmement enrichissante.

Dans ce tutoriel, nous avons appris à développer un logiciel de contrôle réactif pour un robot en utilisant le langage de programmation de haut niveau Python. Mais il existe de nombreux concepts plus avancés qui peuvent être appris et testés rapidement avec un cadre de robot Python similaire à celui que nous avons prototypé ici. J'espère que vous envisagerez de vous impliquer dans le façonnement des choses à venir.

Le Toptal Engineering Blog est une plaque tournante pour des didacticiels de développement approfondis et des annonces de nouvelles technologies créés par des ingénieurs logiciels professionnels du réseau Toptal. Vous pouvez lire la pièce originale écrite par Nick McCrea ici . Suivez le blog de Toptal Design sur Twitter et LinkedIn .

Pssst, hé vous!

Voulez-vous recevoir la newsletter technique quotidienne la plus sassée chaque jour, dans votre boîte de réception, gratuitement? Bien sûr, vous le faites: inscrivez-vous au Big Spam ici .






Source link
Quitter la version mobile