diff --git a/content/2021-05-10-git-flow/images/git_rebase.svg b/content/2021-05-10-git-flow/images/git_rebase.svg deleted file mode 100644 index d3e6a02..0000000 --- a/content/2021-05-10-git-flow/images/git_rebase.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
Matser
Matser
new_feature
new_fe...
Matser
Matser
new_feature
new_fe...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/content/2021-05-10-git-flow/index.md b/content/2021-05-10-git-flow/index.md deleted file mode 100644 index 0e99006..0000000 --- a/content/2021-05-10-git-flow/index.md +++ /dev/null @@ -1,260 +0,0 @@ -+++ -title = "Git Workflow" -description = "Git est un outil de versionnage très utile, voici comment je m'en sers." -date = 2021-05-10 - -[taxonomies] -tags = ["git", "workflow"] -+++ - -Git est un outil de versionnage très utile, voici comment je m'en sers. - - - -> À noter que ce guide est destiné aux personnes qui ont déjà utilisé git auparavant, -> il ne s'agit pas ici d'un tutoriel pour débutants (bien que je sois ici assez -> exhaustif dans mes explications). - -[TL;DR](#tldr) - -## Les fondations - -Vous êtes bien installé devant votre écran, les doigts ne demandent qu'à -furieusement taper les touches de votre clavier, mais avant le top départ, il faut -préparer le terrain ! Voici quelques commandes **primordiales** (pour ne pas dire -**obligatoires**) à réaliser avant de se lancer dans un projet. - -Premièrement, je n'aime pas la manière qu'a git de faire des commits de fusion -lors d'un pull qui se passe mal (divergence entre votre version locale et distante -par exemple, aka. vous avez committé et quelqu'un d'autre aussi en même temps). -Nous allons donc demander à git de ne pull que lorsque l'historique est linéaire -(fast-forward), et sinon de faire automatiquement un rebase : - -```bash -git config pull.rebase true -``` - -En cas de divergence, un simple `git rebase origin/branche_concernée` vous sortira -d'affaire ! - -Ensuite, il nous arrive de vouloir avoir une vue plus graphique de notre historique -git. Voici un alias, à placer dans votre `~/.gitconfig`, qui vous permet d'afficher -un graphique de vos branches et vos commits de manière plus visuelle que le `git log` -de base de git (honteusement volés [ici](https://stackoverflow.com/a/9074343)) : - -```conf -[alias] - lg1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all - lg2 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all - lg = !"git lg1" -``` - -Si vous n'avez pas besoin d'autant de décorations, ou que vous ne pouvez pas définir -d'alias, cette commande fait quelque chose d'assez similaire : - -```bash -git log --all --decorate --oneline --graph -``` - -Pour avoir des messages de commits unifiés et cohérents avec de jolis alias : - -```conf -fix = "!f() { git commit -sm \"fix: $1\"; }; f" -feat = "!f() { git commit -sm \"feat: $1\"; }; f" -misc = "!f() { git commit -sm \"misc: $1\"; }; f" -wip = "!f() { git commit -sm \"wip: $1\"; }; f" -``` - -## Des branches, des branches, et encore des branches - -Quand on travaille à plusieurs sur git, il devient presque obligatoire d'avoir -des branches pour éviter de se sentir "à l'étroit" dans son `repo`. Pour pouvoir -collaborer et avancer sur un projet en groupe sans se marcher sur les pieds les -uns des autres, les branches deviennent l'outil indispensable de git. - -J'utilise les branches de la manière suivante : - -- les branches ont une durée de vie **très courte** -- une fois que la branche a rempli son rôle et qu'elle a été fusionnée, elle doit être supprimée -- une branche par fonctionnalité ou par résolution de problème - - les noms des branches sont libres *tant qu'ils sont clairs* - - c'est mieux d'avoir comme nom la fonctionnalité développée ou son rôle - - lorsqu'une branche sert à développer une résolution de bug ou un `fix`, il est mieux de l'inclure dans le nom - - lorsque vous travaillez à plusieurs sur la même fonctionnalité, il est conseillé de - faire une branche par personne en partant de la branche princpale de cette fonctionnalité - -Évidemment, une branche fait exception : `master` (ou `main`, peu importe), -qui est une version "propre", "stable", et qui doit présenter le projet dans un état -fonctionnel, tel qu'il serait montré à un client ou à un responsable. - -Il est possible d'avoir une seconde branche sur les projets plus importants, qui se -nomme alors `develop` et qui est la version en développement actif d'un projet, -mais qui ne peut pas être fusionnée sur la branche princpale pour des raisons de -stabilité par exemple, ou qui n'est pas prête pour la mise en production. - -Pour créer une branche fille à partir de la branche sur laquelle vous êtes : - -```bash -git checkout -b nom_de_la_nouvelle_branche -``` - -Et pour basculer de branche en branche : - -```bash -git checkout nom_de_la_branche -``` - -Si vous ne savez pas sur quelle branche vous vous trouvez, vous pouvez faire : - -```bash -git branch -``` - -## Rebaser, c'est la clef - -> Cette partie peut être ignorée si vous ne pouvez pas réaliser de `push force` -> (ou équivalent). En effet, un `rebase` modifie fondamentalement l'historique de -> votre git. Si vous n'êtes pas sûr de vous, n'en faites pas. Je ne suis pas -> responsable si vous perdez des données. - -Votre fonctionnalité est développée et testée, vous voulez la fusionner avec votre -branche parente ? Vous voulez récupérer ce qui est sur votre branche parente et -que vous aimeriez récupérer sur la votre ? Il est temps de rebase ! - -Lorsque l'on crée une branche, celle-ci a un `commit` de "départ", depuis lequel -elle se *base* pour faire du versionnage en parallèle des autres branches. Parfois -il est nécessaire de récupérer du travail qui a été mis sur la branche mère dans -notre branche de travail, par exemple la résolution d'un bogue handicapant. - -Un `rebase` va faire changer votre commit de départ et l'échanger avec un autre. -Prenons le schéma suivant : - -![Schéma d'un rebase](images/git_rebase.svg) - -Nous avons ici la branche `new_feature` qui part d'un commit de master. Disons -que vous êtes en train de développer une fonctionnalité importante, et qu'un bug -vous ralentit dans l'exécution de vos tests, mais qu'il a été réglé après la création -de votre branche, et qu'il est disponible sur `master`. Pour le récupérer sur votre -branche, vous n'avez qu'à `rebase` votre branche sur la dernière version de `master`. -La commande pour faire ceci serait alors : - -```bash -git rebase nom_de_branche_parente -``` - -Il est important de noter que vous risquez d'avoir des conflits au cours de cette -opération. En cas de conflit, vous pouvez les régler, puis faire `git add fichier_en_conflit` -et enfin `git rebase --continue`. Cela aura pour effet de **réécrire** l'historique -git de votre branche, d'où l'importance de faire un push en force, puisque votre -version locale et la/les version(s) distante(s) n'auront plus rien à voir. - -### Quel rapport avec ce git flow - -Comme dit plus haut, les branches ont une existence précise et bien définie dans -le temps. Une branche n'a pas a être fusionnée dans sa branche parente tant que -son contenu n'est pas complet, ou au moins utilisable. Cela ne fait pas vraiment -de sens de "polluer" une branche parente dans le seul but d'en récupérer le nouveau -contenu. Les opérations de rebase sont donc ici fréquentes. - -## Fusion non préparée = fusion refusée - -Votre fonctionnalité ou correctif est terminé(e), votre branche est prête à être -fusionnée ? En vérité, pas tout à fait. Il faut maintenant préparer la fusion ! - -Afin de faciliter au maximum la fusion de votre branche, il va falloir faire un -dernier rebase. Le but de ce rebase est ici de vérifier que le rôle de la branche -et du contenu qu'elle propose sont toujours fonctionnels et qu'aucun bogue n'a été -intruduit par les nouveautés disponibles sur la branche parente. Cela va aussi -vous permettre de gérer les conflits avec la branche mère au sein même de la votre. -Une fusion n'introduira donc pas de bogue, et vous restez pleinement responsable -de votre branche. - -Enfin, vous n'êtes pas responsables de la fusion, un collègue ou responsable va -d'abord vérifier votre code et le contenu que vous apportez et approuver (ou rejeter) -la fusion que vous demandez. Grâce aux opérations de rebasage successifs que vous -avez fait durant la durée de vie de votre branche, la fusion se fera sans encombre. - -À noter que si vous avez des outils tels que les [Merge Requests](https://docs.gitlab.com/ee/user/project/merge_requests/getting_started.html) -chez GitLab, ou [Pull Requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) -chez GitHub, n'hésitez surtout pas à les utiliser ! Ces outils permettront de garder -un suivi des fusions, et d'expliquer son but à un responsable qui ne les a pas -forcément toutes en tête. - -Pour fusionner une branche dans celle sur laquelle vous vous trouvez : - -```bash -git merge nom_de_la_branche_à_fusionner_dans_celle_sur_laquelle_vous_êtes -``` - -## Au revoir vieille branche - -> Les opérations décrites ici peuvent entraîner une perte de code. Je ne suis pas -> responsable si vous supprimez une branche avant qu'elle n'ait été fusionnée. -> Ne supprimez une branche que si vous êtes sûr qu'elle n'a plus d'utilité. - -Votre branche est désormais fusionnée ? C'est la fin pour elle, il est désormais -temps de lui dire au revoir ! - -Commençons d'abord par la supprimer sur le repo distant : - -```bash -git push -d origin nom_de_branche -``` - -Ici, le serveur distant s'appelle `origin`, comme c'est le cas la plupart du temps. - -Vos collègues peuvent synchroniser leurs branches et faire disparaître leurs -références locales à des branches fantômes distantes avec la commande `git fetch -p` (le -`-p` étant ici pour "prune"). - -Enfin, il est temps de supprimer votre copie locale de cette branche : - -```bash -git branch -d nom_de_branche -``` - -À noter que le `-d` ne supprimera votre branche que si elle a été fusionnée. Il est -possible de forcer la suppression d'une branche locale non fusionnée avec l'option -`-D` qui équivaut à un `git --delete --force` sur la branche. - -"Don't cry because it's over, smile because it happened." - *Dr. Seuss* - -## TL;DR {#tldr} - -On commence par demander à git de ne pull que s'il n'y a pas de divergence avec -la version distante de notre branche, et sinon, de rebase notre branche automatiquement : - -```bash -git config pull.rebase true -``` - -Ensuite on utilise une branche par fonctionnalité et par correctif. Une branche a -un rôle précis et une durée de vie très courte. Lorsque plusieurs développeurs -travaillent sur la même branche, ils ne doivent pas exclure la possibilité de créer -des branches personnelles. - -`master` est en tous temps propre et présentable. Une branche intermédiaire peut -être utilisée pour éviter de polluer inutilement la branche principale. Elle pourra -s'appeler `develop` par exemple. - -Les rebase sont fréquents et servent à récupérer sur une branche fille du nouveau -contenu de sa branche mère. - -La fusion se déroule sans accroc, un rebase doit être fait avant pour gérer les -conflits sur la branches fille. - -Une fois la branche fusionnée, elle doit être supprimée. - -## Informations supplémentaires - -### Vocabulaire - -- `repo` : raccourci de `repository`, qui est l'environnement de travail de git, - c'est là dedans que l'on créé ses branches, et que l'on versionne son travail. - -### Pour aller plus loin - -- Le fonctionnement des objets, commits et arbres sur git (en profondeur) : [vidéo](https://youtu.be/MyvyqdQ3OjI). -- Le fonctionnement des branches sur git (en profondeur) : [vidéo](https://youtu.be/mhZQRBp8dXE). -- Comment git stocke son arborescence de fichiers : [article](https://book.git-scm.com/book/en/v2/Git-Internals-Git-Objects). -- Les commandes associées à `git branch` : [documentation](https://git-scm.com/docs/git-branch). diff --git a/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/index.md b/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/index.md deleted file mode 100644 index 0398801..0000000 --- a/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/index.md +++ /dev/null @@ -1,286 +0,0 @@ -+++ -title = "Robot timide – le robot qui fuit la lumière" -description = "Création d'un robot timide pour un projet scolaire." -date = 2022-05-19 - -[taxonomies] -tags = ["maker", "fablab", "robotique"] -+++ - -Création d'un robot timide pour un projet scolaire. - -> Article cloné depuis [Eirlab](https://www.eirlab.net/2022/05/19/robot-timide-le-robot-qui-fuit-la-lumiere/) - -Dans le cadre de l’option Makers proposée en deuxième année à l’ENSEIRB-MATMECA, -en filière Informatique, un robot timide a vu le jour au sein d’Eirlab. -Cet article est un guide pour expliquer comment reproduire notre travail, dans -le plus pur esprit Maker. - - - -![Une vue de 3/4 face du robot finalisé](images/robot_timide_header.jpg) - -## Concept de base - -Nous voulions mettre en oeuvre un robot qui détecterait en temps réel la -luminosité autour de lui et ce dans le but de se déplacer vers l’endroit le -plus sombre de la pièce dans lequel il se trouve, et de s’y cacher. Un autre -mode est aussi disponible, permettant non pas d’aller vers l’endroit le plus -sombre, mais à l’inverse de fuir l’endroit le plus lumineux, pour avoir deux -manières de voir le problème. - -![Une vue de face du robot timide dans sa forme finale.](images/robot_timide_enseirb.jpg) - -## Du matériel - -Avant de pouvoir travailler sur une partie logicielle du projet, il faut -évidemment avoir une base physique pour accueillir et exécuter ce code. - -À noter que ce projet n’a nécessité aucune dépense et a été réalisé entièrement -avec du matériel déjà disponible au sein du Fablab. - -### Liste du matériel - -Pour pouvoir reproduire ce projet, il vous faudra avoir en votre possession les -éléments suivants : - -- 1x Arduino Uno (ou clone équivalent) – c’est la tête pensante de ce projet -- 1x Arduino Motor Shield – pour contrôler les deux moteurs du robot -- 2x moteurs à courant continu, ici des FT DC 130D – pour se mouvoir dans l’espace -- 3x capteurs de distance à ultrasons HC-SR04 – pour éviter de rencontrer des murs trop souvent -- 4x photo résistances – une par côté, pour pouvoir détecter la luminosité autour de lui -- 4x résistances de 2kΩ – pour le circuit des photo résistances, permettant d’avoir une amplitude optimale -- 1x pile 9 Volts – pour alimenter tout le système -- 1x boîtier pour pile 9 Volts [OPTIONNEL] – pour éviter de perdre l’unique source d’alimentation du robot - -### Base du châssis - -Le châssis est une plaque en bois, ici du contreplaqué de 5 millimètres -d’épaisseur, qui a été usinée à l’aide de la découpeuse laser du Fablab. Elle -mesure 17×15,5 centimètres, et dispose de deux bords biseautés pour avoir une -vue frontale des obstacles que le robot pourrait rencontrer. Ici, ces biseaux -ont des angles de 20 degrés, sur 4,5 centimètres. La plaque de base est ensuite -percée pour accueillir les différents modules du robot. Les éléments les plus -légers ou risquant moins de se détacher sont fixés par un simple système de -mâchoire, prenant en étau la plaque de bois dans une forme de U. - -![La forme de U pour prendre la plaque de base en mâchoire et tenir un capteur par pression.](images/u_shape.jpg) - -### Alimentation - -Pour l’alimentation du robot, on vient envoyer 9 Volts d’une source quelconque, -d’une pile ou d’une alimentation stabilisée par exemple, dans l’entrée `VIN` -de l’Arduino, qui sera après régulée en interne pour donner les différents -rails d’alimentation. Cette entrée d’alimentation est connectée en interne au -port DC “barrel jack” de l’Arduino, donc avant les régulateurs de courant, -et prend donc des tensions entre 5 et 9 Volts. - -Dans ce projet, nous utilisons une pile 9 Volts rechargeable dans un boîtier -vissé au châssis. - -![Une vue de la pile 9 Volts que nous utilisons, rechargeable en micro USB.](images/pile9v.jpg) - -### Moteurs - -Les moteurs ici sont vissés au châssis, car juste pris en mâchoire ils ne -tiennent pas et se détachent à la moindre accélération. - -Ils sont directement alimentés et pilotés via la carte Arduino Motor Shield, -qui permet de sélectionner leur vitesse sur une échelle de `0` à `255`, -d’actionner les freins et de leur donner un sens de rotation, et ce très -simplement dans le code. - -Des roues ont été imprimées en 3D pour aller sur les embouts des moteurs, et un -joint torique sert de pneu pour améliorer l’adhérence du robot et éviter les -démarrage en “burn”. - -### PCB - -Au début de ce projet, nous avons utilisé une carte de prototypage électronique, -aussi appelé breadboard. Dans un second temps et pour éviter toute déconnexion -de câbles liée à une potentielle accélération violente, nous avons fait un PCB, -soudé manuellement sur une carte de prototypage prévu à cet effet. - -![Une vue du dessus de notre PCB fait main.](images/pcb_irl.jpg) - -Au niveau électronique, le PCB est routé de la manière suivante : - -![Le routage du PCB sur une carte de protypage de type Breadboard.](images/pcb_fritzing.png) - -Les différents composants viennent se connecter sur le PCB au moyen de -différentes broches femelles, pour que ce dernier puisse être détaché et modifié -sans devoir dessouder le moindre composant. - -## Et du logiciel - -D’un point de vue logiciel, notre projet est assez simple. En pseudo-algorithme, -on peut tout simplement le résumer à “on regarde parmi les 4 photo résistances -et on tourne ou avance vers celle ayant la valeur la plus sombre” dans le cas -où `followDark` est à `true`. Si au contraire cette valeur est à `false`, alors -il ira dans la direction opposée à la photorésistance ayant la plus haute valeur. - -Une mesure des distances en face des trois capteurs à ultrasons permet d’arrêter -le robot (presque) avant collision frontale, et le robot ne se déplacera pas -tant que l’objet en face est toujours présent, et donc en théorie tant qu’il a -trouvé l’endroit le plus sombre. - -```cpp -#define echo1Pin 5 -#define trig1Pin 4 -#define echo2Pin 7 -#define trig2Pin 6 -#define echo3Pin 10 -#define trig3Pin 2 -#define rotMot1Pin 12 -#define brakeMot1Pin 9 -#define vitMot1Pin 3 -#define rotMot2Pin 13 -#define brakeMot2Pin 8 -#define vitMot2Pin 11 -#define photoRes1Pin A2 -#define photoRes2Pin A3 -#define photoRes3Pin A4 -#define photoRes4Pin A5 - -#define followDark false - -long duration; -int distance; - -void setup() { - Serial.begin(9600); - pinMode(rotMot1Pin, OUTPUT); - pinMode(brakeMot1Pin, OUTPUT); - pinMode(vitMot1Pin, OUTPUT); - - pinMode(rotMot2Pin, OUTPUT); - pinMode(brakeMot2Pin, OUTPUT); - pinMode(vitMot2Pin, OUTPUT); - - pinMode(photoRes1Pin, INPUT); - pinMode(photoRes2Pin, INPUT); - pinMode(photoRes3Pin, INPUT); - pinMode(photoRes4Pin, INPUT); - - pinMode(trig1Pin, OUTPUT); - pinMode(echo1Pin, INPUT); - pinMode(trig2Pin, OUTPUT); - pinMode(echo2Pin, INPUT); - pinMode(trig3Pin, OUTPUT); - pinMode(echo3Pin, INPUT); - - delay(3000); -} - -void loop(){ - byte echoPins[3] = {echo1Pin,echo2Pin,echo3Pin}; - byte trigPins[3] = {trig1Pin,trig2Pin,trig3Pin}; - long int durations[3] = {}; - long int distances[3] = {}; - - for(int i = 0; i < 3; i++){ - digitalWrite(trigPins[i], LOW); - delayMicroseconds(2); - - digitalWrite(trigPins[i], HIGH); - delayMicroseconds(10); - digitalWrite(trigPins[i], LOW); - durations[i] = pulseIn(echoPins[i], HIGH); - distances[i] = durations[i] * 0.034 / 2; - } - - int photoRes[4] = {}; - Serial.print("Capteur infra : 1["); - photoRes[0] = analogRead(photoRes1Pin); - Serial.print(photoRes[0]); - Serial.print("] 2["); - photoRes[1] = analogRead(photoRes2Pin); - Serial.print(photoRes[1]); - Serial.print("] 3["); - photoRes[2] = analogRead(photoRes3Pin); - Serial.print(photoRes[2]); - Serial.print("] 4["); - photoRes[3] = analogRead(photoRes4Pin); - Serial.print(photoRes[3]); - - for(int i = 0; i < 3; i++){ - Serial.print("] - distance(cm) : "); - Serial.print(distances[i]); - } - - Serial.println(); - - bool b = false; - for(int i = 0; i < 3; i++){ - if (distances[i] < 30) { - b= true; - } - } - - int photoResRef = photoRes[0]; - bool photoStop = true; - int photoResMinPos = 0; - - if (followDark){ - int photoResMin = 1024; - for (int i = 0; i < 4; i++){ - if (photoResMin > photoRes[i]){ - photoResMin = photoRes[i]; - photoResMinPos = i; - } - if (abs(photoResRef - photoRes[i]) > 20){ - photoStop = false; - } - } - } else{ - int photoResMax = 0; - for (int i = 0; i < 4; i++){ - if (photoResMax < photoRes[i]){ - photoResMax = photoRes[i]; - photoResMinPos = (i + 2)%4; - } - if (abs(photoResRef - photoRes[i]) > 20){ - photoStop = false; - } - } - } - Serial.println(photoResMinPos); - - if (b || photoStop){ - digitalWrite(brakeMot1Pin, HIGH); - digitalWrite(brakeMot2Pin, HIGH); - } else { - digitalWrite(brakeMot1Pin, LOW); - digitalWrite(brakeMot2Pin, LOW); - } - - if (photoResMinPos == 0){ - digitalWrite(rotMot1Pin, LOW); - digitalWrite(rotMot2Pin, LOW); - } - if (photoResMinPos == 1){ - digitalWrite(rotMot1Pin, LOW); - digitalWrite(rotMot2Pin, LOW); - } - if (photoResMinPos == 2){ - digitalWrite(rotMot1Pin, HIGH); - digitalWrite(rotMot2Pin, HIGH); - } - if (photoResMinPos == 3){ - digitalWrite(rotMot1Pin, HIGH); - digitalWrite(rotMot2Pin, LOW); - } - analogWrite(vitMot1Pin, 150); - analogWrite(vitMot2Pin, 150); -} -``` - -## Remerciements - -Merci au Fablab de l’ENSEIRB-MATMECA, Eirlab, pour nous avoir permis de -travailler sur ce projet et d’avoir contribué matériellement au projet. - -Merci aussi aux différents Fabmanagers qui nous ont aidés tout au long du projet -en répondant à nos questions plus ou moins posées sous l’emprise de la fatigue. - -À la mémoire de Kaitlin Rooke. diff --git a/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/pcb_fritzing.png b/content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/pcb_fritzing.png similarity index 100% rename from content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/pcb_fritzing.png rename to content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/pcb_fritzing.png diff --git a/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/pcb_irl.jpg b/content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/pcb_irl.jpg similarity index 100% rename from content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/pcb_irl.jpg rename to content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/pcb_irl.jpg diff --git a/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/pile9v.jpg b/content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/pile9v.jpg similarity index 100% rename from content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/pile9v.jpg rename to content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/pile9v.jpg diff --git a/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/robot_timide_enseirb.jpg b/content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/robot_timide_enseirb.jpg similarity index 100% rename from content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/robot_timide_enseirb.jpg rename to content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/robot_timide_enseirb.jpg diff --git a/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/robot_timide_header.jpg b/content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/robot_timide_header.jpg similarity index 100% rename from content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/robot_timide_header.jpg rename to content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/robot_timide_header.jpg diff --git a/content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/u_shape.jpg b/content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/u_shape.jpg similarity index 100% rename from content/2022-05-19-robot-timide-robot-qui-fuit-la-lumiere/images/u_shape.jpg rename to content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/images/u_shape.jpg diff --git a/content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/index.md b/content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/index.md new file mode 100644 index 0000000..56c244b --- /dev/null +++ b/content/2022-05-19-shy-bot-the-bot-which-is-scared-of-the-light/index.md @@ -0,0 +1,294 @@ ++++ +title = "Shy bot – the robot which is scared of the light" +description = "Creating a shy robot for a school project." +date = 2022-05-19 + +[taxonomies] +tags = ["maker", "fablab", "robotics"] ++++ + +Creating a shy robot for a university project. + +> This is a translated article of mine, original can be found on +[Eirlab](https://www.eirlab.net/2022/05/19/robot-timide-le-robot-qui-fuit-la-lumiere/) + +As part of my computer science engeneering curriculum, I enrolled in an option called +"Makers" during my fourth year. From this course within +[ENSEIRB-MATMECA's makerlab](https://www.eirlab.net) +is born a shy robot, one that hates light and loves the shadows. + +This article is all about explaining how it works and how you could reproduce our work, in the +most "maker" spirit. + + + +![A 3/4th view of said robot](images/robot_timide_header.jpg) + +## Base concept + +We wanted to create a robot which would be able to detect, in real time, +the brightness of its surroundings, and would then use it to go in the +darkest place of the room it would be in, in order to hide (it's a shy one, remember?). + +Instead of going to the darkest place it can detect, there's also another mode +available, where instead of moving towards the darkest place, it tries to +flee the brightest direction. Although looking similar, these two ways of thinking +yield to different results. + +![A view of the robot in its final form.](images/robot_timide_enseirb.jpg) + +## Some hardware + +Before working on the software part of this project, we needed to have some hardware +to run our code on. + +It should be noted that all of the components required for this project were +supplied by the fablab. We tried to only use parts that were already available, +without the need to spend a single euro for this project. + +### Shopping list + +In order to recreate this project, you would need these components: + +- 1x Arduino Uno (or an equivalent clone) – it's the brains of this whole project +- 1x Arduino Motor Shield – to control the motors that will move the robot +- 2x DC motors (here FT DC 130D) – to actually move the robot +- 3x ultrasonic distance sensors HC-SR04 – to avoid hitting walls too often +- 4x photoresistors – one per side, to be able to detect brightness around it +- 4x 2kΩ resistors – for the photocell circuit, to have a better detection amplitude +- 1x 9V battery – because it needs power to do anything +- 1x box for 9V batteries [optional] – so the battery is safely mounted + +### Chassis + +The chassis for this robot is a piece of plywood, 5mm thick to be precise. It +has been machined using a laser cutter, availabe in the fablab. This plank +is about 17 by 15.5 centimeters, and has two beveled corners, which are useful +so the robot can see in front of it. The bevels have a 20 degrees angle, going on +4.5cm. + +The base plate is then pierced to accomodate for the different components that +will need to be mounted on the said plate. The lighter components will be pressure +mounted, using a u-shape that will fit around the plate's side. + +![The u-shape to pressure-mount the component on the plate.](images/u_shape.jpg) + +### Power + +For powering the robot, we want to send 9 volts, from a battery or a power supply, +in the power input `VIN` of our Arduino board. This tension will then be regulated +on the PCB to create the different power rails that would be needed. This input is +connected internally to the barrel jack of the Arduino, which can take power ranging +from 5 to 9 volts. + +In this project, we are using a 9V battery which is placed in a case that is bolted +on the base plate. + +![A picture of the rechargeable 9 volts battery that we are using.](images/pile9v.jpg) + +### Motors + +The motors are bolted to the chassis in this project, because when they were +mounted just using pressure, they would run away each time the robot made a +rough acceleration. + +These motors are directly powered and controlled using the Arduino Motor Shield, +which lets us select a speed ranging from `0` to `255` using a coding API. +This API also lets us engage brakes or set the direction in which the wheels +are turning. + +The wheels for this project have been 3D printed and pressure-fit on the motors +themselves, and an O-ring seal is then used to add some grip. + +### PCB + +In the beginning of this project, we used a breadboard for electronics prototyping. +We had a lot of disconnect issues, so as soon as the hardware part could be frozen, +we migrated the breadboard electronics to a hand-made PCB using a prototyping board. +This made the robot way more resilient to a sharp acceleration curve. + +![A top-view of our hand-made PCB.](images/pcb_irl.jpg) + +On an electronic level, the PCB is routed such as: + +![The PCB routing on a prototyping breadboard.](images/pcb_fritzing.png) + +The different components are interfaced with the PCB using a kind of connector that +lets us connect and disconnect things as we iterated on the sensors without having to +use a soldering iron. + +## And finally some software + +From a software point-of-view, the project is quite simple. + +On a high-level, the algorithm could be summed up as follows: check all four photocells, +and move, using rotation and translation, towards the one that has the darkest value, if +`followDark` is set to `true`. If this value is set to `false`, then the robot will move +itself in the opposite direction to this brighest value. + +A distance mesurement is made using the three ultrasonic distance sensor, so the robot is +able to stop before hitting a wall (hopefully). These sensors act as "kill switches" that +forbid the robot from ever moving while these sensors are detecting an obstacle. + +The code is as follow: + +```cpp +#define echo1Pin 5 +#define trig1Pin 4 +#define echo2Pin 7 +#define trig2Pin 6 +#define echo3Pin 10 +#define trig3Pin 2 +#define rotMot1Pin 12 +#define brakeMot1Pin 9 +#define vitMot1Pin 3 +#define rotMot2Pin 13 +#define brakeMot2Pin 8 +#define vitMot2Pin 11 +#define photoRes1Pin A2 +#define photoRes2Pin A3 +#define photoRes3Pin A4 +#define photoRes4Pin A5 + +#define followDark false + +long duration; +int distance; + +void setup() { + Serial.begin(9600); + pinMode(rotMot1Pin, OUTPUT); + pinMode(brakeMot1Pin, OUTPUT); + pinMode(vitMot1Pin, OUTPUT); + + pinMode(rotMot2Pin, OUTPUT); + pinMode(brakeMot2Pin, OUTPUT); + pinMode(vitMot2Pin, OUTPUT); + + pinMode(photoRes1Pin, INPUT); + pinMode(photoRes2Pin, INPUT); + pinMode(photoRes3Pin, INPUT); + pinMode(photoRes4Pin, INPUT); + + pinMode(trig1Pin, OUTPUT); + pinMode(echo1Pin, INPUT); + pinMode(trig2Pin, OUTPUT); + pinMode(echo2Pin, INPUT); + pinMode(trig3Pin, OUTPUT); + pinMode(echo3Pin, INPUT); + + delay(3000); +} + +void loop(){ + byte echoPins[3] = {echo1Pin,echo2Pin,echo3Pin}; + byte trigPins[3] = {trig1Pin,trig2Pin,trig3Pin}; + long int durations[3] = {}; + long int distances[3] = {}; + + for(int i = 0; i < 3; i++){ + digitalWrite(trigPins[i], LOW); + delayMicroseconds(2); + + digitalWrite(trigPins[i], HIGH); + delayMicroseconds(10); + digitalWrite(trigPins[i], LOW); + durations[i] = pulseIn(echoPins[i], HIGH); + distances[i] = durations[i] * 0.034 / 2; + } + + int photoRes[4] = {}; + Serial.print("Capteur infra : 1["); + photoRes[0] = analogRead(photoRes1Pin); + Serial.print(photoRes[0]); + Serial.print("] 2["); + photoRes[1] = analogRead(photoRes2Pin); + Serial.print(photoRes[1]); + Serial.print("] 3["); + photoRes[2] = analogRead(photoRes3Pin); + Serial.print(photoRes[2]); + Serial.print("] 4["); + photoRes[3] = analogRead(photoRes4Pin); + Serial.print(photoRes[3]); + + for(int i = 0; i < 3; i++){ + Serial.print("] - distance(cm) : "); + Serial.print(distances[i]); + } + + Serial.println(); + + bool b = false; + for(int i = 0; i < 3; i++){ + if (distances[i] < 30) { + b= true; + } + } + + int photoResRef = photoRes[0]; + bool photoStop = true; + int photoResMinPos = 0; + + if (followDark){ + int photoResMin = 1024; + for (int i = 0; i < 4; i++){ + if (photoResMin > photoRes[i]){ + photoResMin = photoRes[i]; + photoResMinPos = i; + } + if (abs(photoResRef - photoRes[i]) > 20){ + photoStop = false; + } + } + } else{ + int photoResMax = 0; + for (int i = 0; i < 4; i++){ + if (photoResMax < photoRes[i]){ + photoResMax = photoRes[i]; + photoResMinPos = (i + 2)%4; + } + if (abs(photoResRef - photoRes[i]) > 20){ + photoStop = false; + } + } + } + Serial.println(photoResMinPos); + + if (b || photoStop){ + digitalWrite(brakeMot1Pin, HIGH); + digitalWrite(brakeMot2Pin, HIGH); + } else { + digitalWrite(brakeMot1Pin, LOW); + digitalWrite(brakeMot2Pin, LOW); + } + + if (photoResMinPos == 0){ + digitalWrite(rotMot1Pin, LOW); + digitalWrite(rotMot2Pin, LOW); + } + if (photoResMinPos == 1){ + digitalWrite(rotMot1Pin, LOW); + digitalWrite(rotMot2Pin, LOW); + } + if (photoResMinPos == 2){ + digitalWrite(rotMot1Pin, HIGH); + digitalWrite(rotMot2Pin, HIGH); + } + if (photoResMinPos == 3){ + digitalWrite(rotMot1Pin, HIGH); + digitalWrite(rotMot2Pin, LOW); + } + analogWrite(vitMot1Pin, 150); + analogWrite(vitMot2Pin, 150); +} +``` + +## Thanks + +We wanted to say thank you to the ENSEIRB-MATMECA, to our fablab, EIRLAB, for +trusting us, helping us and providing the hardware we used throughout this project. + +Thank you also to the fab-managers who helped us and answered all of our questions, +more or less asked under fatigue. + +In memory of Kaitlin Rooke. diff --git a/content/pages/archive.md b/content/pages/archive.md index 0da1e0b..228a7b7 100644 --- a/content/pages/archive.md +++ b/content/pages/archive.md @@ -1,5 +1,5 @@ +++ -title = "Articles archivés" +title = "Archived articles" path = "archive" +++ diff --git a/templates/404.html b/templates/404.html index 50a5bc5..9bec8e4 100644 --- a/templates/404.html +++ b/templates/404.html @@ -2,7 +2,7 @@ {% block content %}
-

{% block heading %}Perdu ?{% endblock heading %}

-

{% block message %}Cette page n'existe pas.{% endblock message %}

+

{% block heading %}Lost?{% endblock heading %}

+

{% block message %}Looks like you're trying something that doesn't exist (anymore?).{% endblock message %}

{% endblock content %} diff --git a/templates/index.html b/templates/index.html index ffc3806..c7f2426 100644 --- a/templates/index.html +++ b/templates/index.html @@ -24,14 +24,14 @@   - Posts plus récents + More recent posts {% endif -%} {%- if paginator.next %} - Posts plus anciens  + Older posts  diff --git a/templates/macros/post.html b/templates/macros/post.html deleted file mode 100644 index f886c71..0000000 --- a/templates/macros/post.html +++ /dev/null @@ -1,108 +0,0 @@ -{% macro content(page, summary, show_only_description) %} - {%- if show_only_description %} -
- {{ page.description | safe }} -
- {% elif summary and page.summary %} -
- {{ page.summary | safe }} -
-
- - - En savoir plus  - ↩︎ - -
- {% else %} - {#- full content -#} -
- {{ page.content | safe }} -
- {%- endif %} -{% endmacro content %} - - -{% macro date(page) %} - - {%- if page.date %} - {{ page.date | date(format="%d-%m-%Y") }} - {% endif -%} - -{% endmacro post_date %} - - -{% macro earlier_later(page) %} - {%- if config.extra.enable_post_view_navigation and page.lower or page.higher %} - - {% endif -%} -{% endmacro earlier_later %} - - -{% macro header(page) %} -

{{ page.title }}

-
- {{ post_macros::date(page=page) }} -
- - {{ post_macros::tags(page=page) }} -{% endmacro header %} - - -{% macro list_posts(pages) %} - -{% endmacro list_posts %} - - -{% macro tags(page, short=false) %} - {%- if page.taxonomies and page.taxonomies.tags %} - - {%- if short %} - :: - {%- set sep = "," -%} - {% else %} - :: tags:  - {%- set sep = " " -%} - {% endif -%} - {%- for tag in page.taxonomies.tags | sort | unique(case_sensitive=false) %} - #{{ tag }} - {%- if not loop.last %}{{ sep | safe }}{% endif -%} - {% endfor -%} - - {% endif -%} -{% endmacro tags %} diff --git a/templates/tags/list.html b/templates/tags/list.html deleted file mode 100644 index 4590e71..0000000 --- a/templates/tags/list.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends "terminimal/templates/tags/list.html" %} - -{% block content %} -
-

Liste des tags

- - -
-{% endblock content %} diff --git a/templates/tags/single.html b/templates/tags/single.html deleted file mode 100644 index d903c36..0000000 --- a/templates/tags/single.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends "terminimal/templates/tags/single.html" %} - - -{% block content %} -
-

- tag: #{{ term.name }} - ({{ term.pages | length }} post{{ term.pages | length | pluralize }}) -

- - - Voir tous les tags - - - {{ post_macros::list_posts(pages=term.pages) }} -
-{% endblock content %}