Conception d'algorithmes critiques: mise en œuvre

  1. Conception
  2. la mise en oeuvre
  3. L'intégration


Quand je commençais ma carrière dans le développement professionnel, je ne comprenais pas pourquoi l'open source était nécessaire. Je ne comprenais pas non plus les projets parallèles, d'ailleurs. Après tout, pourquoi donner gratuitement un travail précieux? Au fil des années, en travaillant sur des projets open source, ainsi qu'en travaillant avec Apex.AI, ROS 2 et Autoware.Auto, j'ai acquis une certaine compréhension de l'open source.



Les ingénieurs adorent créer. Les gens veulent de la reconnaissance et de la gratitude.



Lorsque vous combinez ces facteurs ensemble, vous avez le chemin de l'open source. Si je construis quelque chose pour répondre à mes besoins créatifs, pourquoi ne pas laisser tout le monde apprécier mon travail et y trouver une utilité pratique et une valeur? Après tout, je ne fais pas ça pour l'argent.



En ce qui concerne les projets parallèles, je n'ai réalisé leur charme qu'après avoir commencé à me développer professionnellement et à aborder plus attentivement divers aspects de mon travail. Pour créer un produit fiable que les gens paieront, il est souvent nécessaire de restreindre artificiellement les flux de travail. Analyse de conception. Revue de code. Normes de codage, guides de style, métriques de couverture de test, etc. Ne vous méprenez pas, ce sont toutes de bonnes choses qui sont probablement nécessaires pour développer un produit de qualité. C'est juste que parfois un développeur veut un peu de liberté. Un développeur peut vouloir créer ce qu'il veut, comme il le souhaite et quand il le souhaite. Pas de réunions, d'examens ou d'analyses de rentabilité.



Alors, comment combinez-vous ces aspects lorsqu'il s'agit de développer des algorithmes sûrs ou de haute qualité? Une grande partie de l'attrait du monde open source est la liberté, et les pratiques qui contribuent à garantir le développement d'un code plus fiable limitent cette liberté.



La réponse que j'ai trouvée est de suivre une discipline ouverte et cohérente, et d'utiliser généreusement de nombreux outils sympas qui sont venus du monde open source.



Planification de projets open source



Les ingénieurs ont besoin d'un ensemble de compétences spécifiques pour résoudre ces problèmes. Les ingénieurs doivent être concentrés, ils ont besoin de bonnes compétences en résolution de problèmes. Les ingénieurs doivent également être capables de séparer les préoccupations et posséder les solides compétences de base nécessaires pour acquérir des connaissances sur tout ce qui précède.



Cet ensemble de compétences particulières peut conduire les ingénieurs à être quelque peu dépassés.



Malgré toutes les capacités techniques des ingénieurs, leurs capacités sont finalement limitées. Je dirais que la plupart des développeurs sont incapables de garder à l'esprit l'ensemble du projet tout en écrivant des lignes de code individuelles. De plus, je dirais que la plupart des développeurs ne peuvent pas programmer et garder un projet plus large dans leur tête sans oublier les objectifs commerciaux généraux.



C'est là que la magie noire de la gestion de projet entre en jeu.



Bien que nous, développeurs, ayons des relations quelque peu controversées avec les responsables des ressources humaines, techniques ou de projet, il faut reconnaître que toutes ces personnes font un travail important. Les meilleurs représentants de la profession de management s'assurent que les développeurs ne perdent pas de vue les tâches importantes, et les irritants ennuyeux ne nous empêchent pas de tirer sur des problèmes avec toutes les armes.



Et bien que nous comprenions l'importance des différents managers, les personnes possédant ces compétences ne s'impliquent généralement pas dans un projet open source typique dont le but est de s'amuser.



Alors, que devons-nous faire alors?



Eh bien, nous les développeurs pouvons mettre la main à la pâte et passer un peu de temps à planifier à l'avance.



Je n'entrerai pas dans ces conversations, car dans le post précédent, je suis allé dans le détail sur les étapes de conception et de planification du développement. En fin de compte, compte tenu de la conception et de l'architecture, pour lesquelles, en règle générale, se composent de nombreux composants et forment des dépendances, dans votre propre projet, vous formez vous-même la conception et collectez ses composants séparément.



Pour en revenir à l'aspect planification de projet, j'aime commencer par les composants avec le moins de dépendances (pensez une minute!), puis continuez à travailler, en ajoutant des stubs d'implémentation si nécessaire pour poursuivre le développement. Avec cet ordre de travail, vous pouvez généralement créer de nombreux tickets (avec certaines dépendances correspondant à vos dépendances architecturales - si votre outil de suivi des tâches a une telle fonctionnalité). Ces tickets peuvent contenir des remarques générales qu'il est utile de garder à l'esprit avant de vous lancer dans une tâche plus en détail. Les billets doivent être aussi petits et spécifiques que possible. Regardons les choses en face - notre concentration et notre capacité à tenir le contexte sont limitées. Plus les tâches de développement sont détaillées, plus il est facile - alors pourquoi ne pas essayer de rendre les tâches difficiles aussi simples que possible?



Au fur et à mesure que votre projet évolue, votre travail sera de prendre les tickets par ordre de priorité et de terminer les tâches qui leur sont assignées.



De toute évidence, il s'agit d'une version considérablement simplifiée de la gestion de projet. Une véritable gestion de projet comporte de nombreux autres aspects tels que les ressources, la planification, les analyses de rentabilisation concurrentes, etc. La gestion de projet en open source peut être plus simple et plus libre. Peut-être, dans le monde du développement open source, il existe des cas de gestion de projet à part entière.



Développement ouvert



Après avoir tapé une pile de tickets, formé un plan de travail et compris tous les détails, nous pouvons procéder au développement.



Cependant, bon nombre des facteurs de liberté présents dans l'ouest sauvage du développement ouvert ne devraient pas être dans le développement d'un code sécurisé. Vous pouvez éviter de nombreux pièges en utilisant des outils open source et avec une certaine discipline (et avoir des amis).



Je suis un grand partisan de la discipline comme moyen d'améliorer la qualité du travail (après tout, la discipline est à la 6ème place de ma note sur StrengthsFinder) Avec suffisamment de discipline pour utiliser des outils open source, écouter les autres, agir sur les résultats et s'en tenir aux flux de travail, nous pouvons surmonter de nombreuses failles qui s'insinuent dans les approches cowboy du monde open source.



En bref, l'utilisation des outils et pratiques suivants (qui, avec quelques mises en garde, peuvent être facilement appliqués dans n'importe quel projet) permet d'améliorer la qualité du code:



  1. Tests (ou mieux encore, développement piloté par les tests)
  2. Analyse statique
  3. Intégration continue (CI / CD)
  4. Examen du code


Je vais également donner un certain nombre de principes auxquels j'adhère lorsque j'écris du code directement:



  1. SEC
  2. Utilisation complète de la langue et des bibliothèques
  3. Le code doit être lisible et d'une évidence aveuglante.


Je vais essayer de relier ce texte à l'implémentation réelle de l'algorithme de localisation NDT , qui a été complétée en 10 demandes de fusion par mon bon collègue Yunus . Il est trop occupé par le travail direct, je peux donc accrocher sur moi des médailles imaginaires en écrivant sur son travail.



De plus, pour illustrer certains des processus et des pratiques, je donnerai un exemple de développement d'un algorithme open-source pour le contrôleur MPC . Il a été développé dans un style légèrement plus lâche (cow-boy) dans environ 30+ demandes de fusion , sans compter les modifications supplémentaires et les améliorations apportées après l'achèvement du travail principal.



Essai



Parlons des tests.



J'ai eu une relation longue et difficile (selon mes critères) avec les tests. Quand j'ai obtenu un poste de développeur pour la première fois et que j'ai pris le premier projet, je ne croyais absolument pas que mon code fonctionnait, et j'ai donc été le premier de l'équipe à commencer à écrire au moins des tests unitaires significatifs. Cependant, j'avais absolument raison de dire que mon code ne fonctionnait pas.



Depuis lors, ma relation tumultueuse avec les tests a connu de nombreux rebondissements dignes des films du jour au lendemain. Parfois j'aimais ça. Parfois, je détestais tout. J'ai écrit trop de tests. Trop de copier-coller, trop de tests redondants. Puis les tests sont devenus un travail de routine, une autre partie du développement. J'ai d'abord écrit le code, puis j'ai écrit des tests pour cela, c'était l'ordre des choses.



Maintenant, j'ai une relation normale avec les tests. Cela fait partie intégrante de mon flux de travail, quelle que soit l'application sur laquelle je travaille.



Ce qui a changé pour moi, ce sont les techniques de développement pilotées par les tests que j'ai commencé à utiliser dans mon projet mpc.



J'ai brièvement parlé du développement piloté par les tests dans le texte précédent, mais voici une autre description du processus:



  1. Développer une spécification (cas d'utilisation, exigences, etc.).
  2. Mettre en œuvre l'API / l'architecture
  3. Rédiger des tests basés sur l'API et les spécifications de conception; ils doivent échouer.
  4. Mettre en œuvre la logique; les tests doivent réussir


Il y a une certaine itération dans ce processus (les tests n'échouent pas sur les stubs, l'implémentation échoue les tests, l'API peut être gênante, etc.), mais dans l'ensemble, je pense que cela peut être extrêmement utile.



J'ai beaucoup parlé de la planification avant la mise en œuvre, et le développement piloté par les tests vous offre cette opportunité. Le premier point a été noté. Ensuite, vous pensez à l'architecture et aux API, et vous les mappez à des cas d'utilisation. Cela vous donne une excellente occasion de vous rapprocher du code, tout en pensant au problème plus largement. Le deuxième point a été noté.



Ensuite, nous passons à l'écriture de tests. Il y a plusieurs raisons aux avantages d'écrire des tests avant la mise en œuvre, et je pense qu'elles sont toutes importantes:



  1. Les tests doivent être écrits en tant qu'objets de première priorité, et non en tant que modules complémentaires.
  2. , – .
  3. API , .
  4. , , , , .


Dans l'ensemble, je pense que les avantages du développement piloté par les tests sont énormes, et une fois encore, je recommande vivement à tout le monde de l'essayer au moins.



Revenons à Autoware.Auto. Yunus, sans s'en tenir aux méthodes de développement basées sur les tests, a écrit des tests pour chaque demande de fusion pendant le développement NDT. Dans le même temps, le volume du code de test était égal (et parfois même dépassé) le volume du code d'implémentation, et c'est bien. En comparaison, SQLite , qui est probablement la référence pour les tests (pas seulement selon les normes des projets open source), a 662 fois plus de code de test que de code d'implémentation. Dans Autoware.Auto, nous n'en sommes pas encore tout à fait à ce stade, mais si vous regardez l'historique des demandes de fusion liées à NDT, vous pouvez voir que le volume de code de test a lentement rampé jusqu'à atteindre une couverture de 90% (bien qu'il ait depuis baissé en raison d'autres conceptions et code externe).



Et c'est cool.



De même, mon projet mpc a des tests pour tout, y compris les tests eux-mêmes . De plus, je mène toujours soigneusement des tests de régression pour m'assurer que le bogue est corrigé et ne réapparaît plus.



Je vais bien.



Analyse statique



De nombreux concepts sont curieux dans la mesure où les définitions qu'ils contiennent peuvent être considérablement étirées. Par exemple, les tests vont bien au-delà des tests fonctionnels écrits à la main. En fait, la vérification de style ou la recherche de bogues peuvent également être considérées comme une forme de test (il s'agit essentiellement d'une inspection, mais si vous étirez la définition, cela peut être appelé test).



Ces "tests" sont quelque peu pénibles et laborieux à utiliser. Après tout, validation, validation des tabulations / espaces en alignement? Non merci.



Mais l'un des aspects les plus agréables et les plus précieux de la programmation est la possibilité d'automatiser des processus pénibles et chronophages. Dans le même temps, le code peut obtenir des résultats plus rapidement et plus précisément que n'importe qui. Et si nous pouvions faire de même avec les bogues et les constructions problématiques ou sujettes aux erreurs dans notre code?



Eh bien, nous pouvons - avec des outils d'analyse statique.



J'ai écrit sur l'analyse statique assez longtemps dans un précédent article de blog , je ne vais donc pas approfondir ses avantages et les outils que vous pouvez utiliser.



Dans Autoware.Auto, nous utilisons une version légèrement plus petite de l'ensemble ament_lintde nos amis proches de ROS 2. Ces outils nous font beaucoup de bien, mais le plus important est peut-être que le formatage automatique de notre code pour éliminer les conflits de style - des outils impartiaux nous disent ce qui est bien et ce qui ne va pas. Si vous êtes intéressé, je noterai que le format clang est plus strict que décroissant .



Dans le projet mpc, je suis allé un peu plus loin. Dans celui-ci, j'ai utilisé l'indicateur Weverything du compilateur Clang, en plus de tous les avertissements de clang-tidy et de l' analyseur statique Clang. Étonnamment, le développement commercial nécessitait la désactivation de plusieurs options (en raison d' avertissements redondants et de confusion conceptuelle). Lors de l'interaction avec du code externe, j'ai dû désactiver de nombreuses vérifications - elles entraînaient un bruit inutile.



En fin de compte, je me suis rendu compte que l'utilisation d'une analyse statique approfondie n'interfère pas beaucoup avec le développement normal (dans le cas de l'écriture d'un nouveau code et après avoir passé un certain point sur la courbe d'apprentissage)



Il est difficile de quantifier la valeur de l'analyse statique, surtout si vous l'utilisez depuis le début. Le fait est qu'il est difficile de deviner si l'erreur existait avant l'introduction de l'analyse statique ou non.



Cependant, je pense que l’utilisation des avertissements et de l’analyse statique est l’une de ces choses où, même correctement utilisées, on ne peut pas être sûr qu’elles ont fait quoi que ce soit.. En d'autres termes, vous ne pouvez pas être sûr de la valeur d'un analyseur statique lorsqu'il est allumé, mais diable, vous remarquerez qu'il n'est pas là tout de suite.



CI / CD



Même si j'aime les tests rigoureux et l'analyse de code statique / dynamique, tous les tests et vérifications sont sans valeur s'ils ne sont pas exécutés. CI peut relever ces défis avec un minimum de frais généraux.



Je pense que tout le monde convient que disposer d'une infrastructure CI / CD est une partie essentielle du développement moderne, ainsi que d'utiliser un système de contrôle de version et d'avoir des normes de développement (au moins des guides de style). Cependant, la valeur d'un bon pipeline CI / CD est que ses opérations doivent être reproductibles.



Le pipeline CI / CD doit, au minimum, générer du code et exécuter des tests avant de pousser le code dans votre référentiel. Après tout, personne ne veut être ce gars (ou cette fille, ou cette personne) qui a cassé une assemblée ou une sorte de test et doit tout réparer rapidement et honteusement. Les CI (et donc vos chers ingénieurs DevOps) vous protègent de cette honte.



Mais CI peut faire beaucoup plus pour vous.



Avec un pipeline CI robuste, vous pouvez tester un nombre illimité de combinaisons de systèmes d'exploitation, de compilateurs et d'architectures (avec certaines limitations, compte tenu des tests de combinaison ). Vous pouvez également effectuer des builds, exécuter des tests et d'autres opérations qui peuvent être trop gourmandes en ressources ou lourdes pour qu'un développeur puisse les effectuer manuellement. Vous ne pouvez pas sauter par-dessus votre tête.



Pour revenir à la déclaration d'origine, avoir un pipeline CI / CD (que nous utilisons chez Autoware.Auto ) dans votre projet open-source aidera à piloter le développement ingérable. Le code ne pourra pas entrer dans le projet s'il ne génère pas ou ne passe pas les tests. Si vous adhérez à une discipline de test stricte, vous pouvez toujours être sûr que le code fonctionne.



Dans Autoware.Auto, CI:



  1. Collecte le code
  2. Exécute des tests (style, contrôles linter, tests fonctionnels).
  3. Mesure la couverture des tests
  4. Vérifie que le code est documenté




À son tour, mon CI compilé à la hâte dans le projet mpc:



  1. Collecte le code
  2. Effectue une analyse (analyse statique Clang)
  3. Exécute des tests (mais n'arrête pas CI si les tests échouent).


Un pipeline CI mis en place par un ingénieur DevOps expérimenté (comme notre J.P. Samper ou Hao Peng !) Peut faire beaucoup plus. Alors chérissez vos ingénieurs DevOps. Ils nous facilitent la vie (en tant que développeurs).



Examen du code



Les benchmarks, les analyseurs et l'IC sont excellents. Vous pouvez exécuter des tests, tout analyser et vous assurer que ces tests sont effectués en utilisant CI, n'est-ce pas?



Malheureusement non.



Encore une fois, tous les tests dans le monde sont sans valeur s'ils sont mauvais. Alors, comment vous assurez-vous que vos tests sont bons?



Malheureusement, je n'ai pas de réponses magiques. En fait, je reviens à l'ancienne technique d'ingénierie, l'examen par les pairs. En particulier, à la révision du code.



On pense généralement que deux têtes valent mieux qu'une. En fait, je dirais que ce concept est soutenu non seulement par la littérature, mais aussi par la théorie.



Ensemble de méthodesdans l'apprentissage automatique illustre cette théorie. On pense que l'utilisation d'un ensemble de méthodes est un moyen rapide et facile d'améliorer les performances des modèles statistiques (la méthode de renforcement bien connue en est un exemple ). De même, d'un point de vue purement statistique, la variance est moindre (avec des hypothèses) plus vous avez d'échantillons. En d'autres termes, vous êtes plus susceptible d'être plus proche de la vérité si vous connectez plus d'employés.



Vous pouvez essayer cette technique avec un exemple en direct en faisant un exercice de consolidation d'équipe . Une version moins amusante pourrait impliquer de deviner des statistiques aléatoires individuellement et en groupe.



Mis à part la théorie et la consolidation d'équipe, la révision du code est un outil important et puissant. Sans surprise, la révision du code fait partie intégrante de tout processus de développement professionnel, et même recommandée par la norme ISO 26262.



Tout cela suggère qu'il y a toujours un danger qu'un enfant ait sept nounous. De plus, la révision du code peut parfois causer certaines difficultés.



Cependant, je pense que les révisions de code peuvent être agréables et indolores si le réviseur et les pairs se souviennent de ce qui suit:



  1. Vous n'êtes pas votre code.
  2. Vous parlez à une autre personne.
  3. Sois poli
  4. Tout le monde travaille vers le même objectif; la révision du code ne représente aucune concurrence (même si cela arrive parfois en programmation )


Beaucoup de personnes plus intelligentes et plus gentilles que moi ont écrit sur la façon de faire correctement les révisions de code, et je vous invite à jeter un coup d'œil à leur travail . La dernière chose que je peux dire, c'est que vous devriez faire des révisions de code si vous voulez que votre code soit plus fiable.



SEC



Je suis allé dans le détail sur les processus et les outils qui peuvent être utilisés pour créer un environnement de développement: des contrôles et des outils qui effectuent des contrôles et s'assurent que le code est suffisamment bon.



Ensuite, j'aimerais passer à un bref exposé sur les prouesses de la programmation et partager quelques réflexions sur les processus et l'intention derrière l'écriture de lignes de code individuelles.



Il y a quelques concepts qui m'ont aidé à améliorer considérablement mon code. L'un de ces concepts était la capacité de se souvenir de l'intention, de la sémantique et de la lisibilité, dont je parlerai un peu plus tard. Une autre est la compréhension de la POO et la séparation des préoccupations . La dernière idée importante est DRY ( Don't Repeat Yourself ) ou le principe «Ne vous répétez pas».



DRY est ce qui est enseigné à l'école et, comme pour beaucoup d'autres choses, nous mettons cette pensée sur l'étagère la plus éloignée et n'y attachons pas beaucoup d'importance en dehors des examens (du moins pour moi). Mais, comme c'est le cas pour beaucoup d'autres choses à l'école, on n'apprend rien de tout cela. En fait, c'est une bonne pratique.



Pour faire simple, si vous vous trouvez fréquemment à copier et coller du code, ou à écrire fréquemment du code très similaire, c'est une très bonne indication que le code répétable devrait devenir une fonction ou une partie d'une abstraction.



Mais DRY va plus loin que de vérifier que du code doit être déplacé dans une fonction. Ce concept peut également servir de base à certaines décisions architecturales.



Bien que cette approche croise certains concepts architecturaux (tels que l'aliasing, la connectivité et la séparation des préoccupations), un exemple de la façon dont DRY est appliqué à l'architecture peut être vu dans mon projet mpc. Pendant le développement du contrôleur mpc, j'ai remarqué que je devrais dupliquer du code si j'écrivais un autre contrôleur. Il s'agit d'un code standard pour le suivi de l'état, des publications, des abonnements, des conversions, etc. En d'autres termes, il semblait que c'était une tâche distincte du contrôleur mpc.



C'était une bonne indication que je devais séparer les conceptions générales et les fonctionnalités dans une classe distincte . Le retour sur investissement était double: le contrôleur mpc est concentré à 100% sur le code lié à mpc, et avecle module qui lui est associé n'est qu'un modèle de configuration. En d'autres termes, en raison d'abstractions architecturales, je n'ai pas à tout réécrire lorsque je travaille avec un contrôleur différent.



Le monde est composé de nuances de gris, de sorte que ces décisions de conception doivent être approfondies avec soin et dans le bon état d'esprit. Sinon, vous pouvez aller trop loin et commencer à créer des abstractions là où elles ne sont pas nécessaires. Cependant, si le développeur est conscient des concepts que ces abstractions modélisent, DRY est un outil puissant pour façonner les décisions architecturales. À mon avis, DRY est le concept principal pour garder votre code propre et dense.



Après tout, l'un des principaux avantages du code est sa capacité à effectuer des tâches répétitives, alors pourquoi ne pas déplacer la répétition vers des fonctions et des classes bien conçues?



Utilisation complète de la langue et de la bibliothèque



DRY, à mon avis, est un concept si important et omniprésent que ce point n'est en réalité qu'une continuation de la conversation DRY.



Si votre langue prend en charge quelque chose, vous devez généralement utiliser l'implémentation en ligne, à moins que vous n'ayez de très bonnes raisons de vous désinscrire. Et C ++ a beaucoup de choses intégrées .



La programmation est une compétence et il y a une grande différence dans les niveaux de compétence. Je n'ai eu qu'un aperçu de la hauteur de la montagne de cette compétence et, en général, je trouve que les personnes qui créent des normes sont plus aptes que moi à mettre en œuvre des modèles communs.



Un argument similaire peut être avancé pour la fonctionnalité des bibliothèques (bien que peut-être pas aussi catégoriquement). Quelqu'un d'autre a déjà fait de même, et probablement à un bon niveau, il n'y a donc aucune raison de réinventer la roue.



Néanmoins, comme beaucoup d’autres, ce paragraphe est une recommandation et non une règle rigide et urgente à appliquer. Bien que cela ne vaille pas la peine de réinventer la roue, et si les implémentations standard sont généralement très bonnes, il ne sert à rien d'essayer de presser une pièce carrée dans un trou rond. Pensez avec votre tête.



Code lisible



Le dernier concept qui m'a aidé à améliorer mes compétences en programmation était que la programmation ne consiste pas tant à écrire du code qu'à communiquer. Si ce n'est pas la communication avec d'autres développeurs, alors la communication avec vous-même du futur. Bien sûr, vous devez penser à la mémoire, aux mathématiques et à la complexité du Big O, mais une fois que vous avez terminé, vous devez commencer à penser à l'intention, à la sémantique et à la clarté.



Il existe un livre très célèbre et largement recommandé sur ce sujet, Clean Code , donc je ne peux pas ajouter grand-chose à ce sujet. Voici quelques informations générales auxquelles je me réfère lors de l'écriture de code et des révisions de code:



  1. Essayez de garder vos cours clairs et concentrés:

    • Minimiser les accrocs
    • ()



      • const, noexcept? ? (, )




    • , (, , ).
    • (, )
    • .
  2. -



    • «», , .
    • (, ).
    • ( ) ().
  3. ? ()



    • , ().
    • , , , (, ).


Les directives de base ISO C ++ sont une autre excellente ressource qui résout ce type de problème .



Je répète qu'aucun de ces principes n'est révolutionnaire, nouveau ou unique, mais si l'écriture des principes a de la valeur (ou si quelqu'un dira «aha» en le lisant ), alors je n'ai pas gaspillé les bits et le trafic pour écrire ce post. ...



Regarder en arrière



Ce sont quelques-uns des outils, principes et processus que nous avons utilisés pour développer et implémenter l'algorithme de localisation NDT, ainsi que pour travailler sur le contrôleur MPC. Beaucoup de travail a été fait, c'était amusant, ce n'est pas si intéressant d'en parler.



Dans l'ensemble, nous avons fait un grand usage des outils et des pratiques que j'ai mentionnés, mais nous n'étions pas parfaits.



Ainsi, par exemple, lorsque nous travaillons sur le NDT, nous n'avons pas suivi les idiomes du développement piloté par les tests (bien que nous ayons tout parfaitement testé!). À mon tour, j'ai suivi des techniques de développement pilotées par les tests sur MPC, mais ce projet n'a pas bénéficié du CI plus puissant intégré à Autoware.Auto. De plus, le projet MPC n'était pas public et n'a donc pas bénéficié d'une révision du code.



Les deux projets pourraient bénéficier de l'introduction d'une analyse statique, de tests plus détaillés et de plus de commentaires. Cependant, nous parlons de projets créés par une seule personne, donc je pense que les tests effectués et les commentaires reçus sont suffisants. En ce qui concerne l'analyse statique, des formes meilleures et plus ciblées relèvent généralement des intérêts du développement de produits et s'éloignent de la communauté des développeurs open source (bien que des idées intéressantes puissent apparaître à l'horizon ).



Je n'ai rien à dire sur le développement simultané de deux algorithmes - nous avons travaillé au mieux de nos capacités, en adhérant aux principes que j'ai exposés ci-dessus.



Je pense que nous avons fait un excellent travail de décomposition de gros problèmes en plus petits morceaux (bien que le composant MR dans l'algorithme NDT puisse être plus petit), et avons fait des tests approfondis. Je pense que les résultats préliminaires parlent d'eux-mêmes.



Mouvement vers l'avant



Après la mise en œuvre, il est temps pour l'intégration. Il est nécessaire de se connecter à un système plus grand avec ses propres composants complexes. Ce système prendra votre entrée, la digérera et produira les résultats de votre algorithme. L'intégration est peut-être la partie la plus difficile du développement d'un algorithme, car vous devez suivre la planification globale du système et résoudre les problèmes de bas niveau. Toute erreur dans l'une de vos nombreuses lignes de code peut empêcher l'intégration de votre algorithme.



Je couvrirai cela dans le troisième et dernier article de cette série.



En guise d'aperçu, je dirai qu'au cours du processus de développement, pas une seule grosse erreur n'a été trouvée lors de l'utilisation et de l'intégration du contrôleur mpc. Certes, il y a eu des problèmes d'écriture de scripts , d'assemblage,tests , la validation des données d'entrée a été ignorée , et il y avait également des problèmes d' incompatibilité des paramètres QoS , mais il n'y avait rien de terrible dans le code.



En fait, il était capable de fonctionner (en contournant les incompatibilités de QoS et les options de configuration) presque hors de la boîte .



Il en va de même pour l'algorithme NDT, qui a rencontré un certain nombre de problèmes mineurs tels que l' instabilité de la covariance , une erreur de recherche de chaînes dans le code existant et des cartes mal alignées. Quoi qu'il en soit, il était également capable de fonctionner hors de la boîte .



Pas mal pour les produits conçus pour que tout le monde puisse les voir.



Abonnez-vous aux chaînes:

@TeslaHackers — Tesla-, Tesla

@AutomotiveRu — ,







image



- automotive . 2500 , 650 .



, , . ( 30, ), -, -, - (DSP-) .



, . , , , . , automotive. , , .


:






All Articles