# Groupe 1 : Melia, Maxime, Raul, Lucas, Mathieu, Arianne, Hind

##  PROJET ROB 3 

#### <span style="text-decoration: underline;">**Informations :** </span>

- ##### **Membres et contact :** 
    
    Raul ABI KHALIL: [raul.abi\_khalil@etu.sorbonne-universite.fr](mailto:raul.abi_khalil@etu.sorbonne-universite.fr)
    
    Hind BENRADJA: [hind.benradja@etu.sorbonne-universite.fr ](mailto:hind.benradja@etu.sorbonne-univesite.fr)
    
    Arianne BONJOUR: charle-henri.bonjour@etu.sorbonne-universite.fr Lucas BRUGNONE: <lucas.brugnone@etu.sorbonne-universite.fr>
    
    Maxime CARLIER: <maxime.carlier@etu.sorbonne-universite.fr>
    
    Melia TAFAT: <melia.tafat@etu.sorbonne-universite.fr>[ ](mailto:melia.tafat@etu.sorbonne-universite.fr)
- Projet effectué du 12 février 2026 au 28mai 2026.
- POLYTECH Sorbonne ROB 3 2025-2026.

#### <span style="text-decoration: underline;">**Contexte et objectifs :**</span>

 Dans le cadre de notre projet de Robotique de troisième année, nous avons du concevoir un robot capable de saisir un objet appelé totem et le déplacer de manière autonome au sein d'une arène de jeu.

 L'enjeu majeur de ce projet est l'intégration de plusieurs domaines de l'ingénierie:

 **Conception Mécanique** : L'architecture du robot repose sur un châssis simple conçu à l'aide de croquis à la main ainsi que de SolidWorks.

  **Électronique**: afin de gérer la distribution d'énergie par une batterie 12V, la communication par bus CAN entre les composants, ainsi que l'utilisation des capteurs à ultrason à l'aide de ARDUINO MEGA.

  **Informatique**: L'intelligence du robot est pilotée par un programme ARDUINO. Ce code, en langage C++,permet de gérer la navigation autonome, la détection du totem et l'exécution des trajectoires. Il assure également le traitement des données capteurs et la commande précise des moteurs KTECH et Dynamixel.

#### <span style="text-decoration: underline;">**Matériel à disposition :**</span>

- une pince 3551
- deux moteurs KTECH MS4015-V3
- un moteur Dynamixel
- deux petites roues et une roue pivotante ( de caddie)
- une carte Arduino MEGA, un shield SEED et un shield Dynamixel
- deux capteurs à distance ultrasons HC-SR04
- une batterie RS PRO 12V 1,2Ah

<span style="color: #222222;"><span style="caret-color: rgb(34, 34, 34); font-size: 23.323999px;">**<u>Répartition des tâches :</u>**</span></span>

 Après s'être familiarisés avec le sujet, on se répartit les taches de la manière suivante :

- Chef de projet: Maxime CARLIER
- Responsable du pôle électronique: Raul ABI KHALIL
- Responsables du pôle informatique: Hind BENRADJA et Melia TAFAT
- Responsable du pôle mécanique: Lucas BRUGNONE
- Responsables du Wiki: Hind BENRADJA et Melia TAFAT

**Diagramme de GANTT du projet:**

[![Capture d’écran 2026-05-28 à 00.58.00.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/capture-decran-2026-05-28-a-00-58-00.png)](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/capture-decran-2026-05-28-a-00-58-00.png)


#### <span style="text-decoration: underline;">**Codes du projets:**</span>  


**[Ktech\_motor.cpp](https://wiki.fablab.sorbonne-universite.fr/BookStack/attachments/1865)**

**[Ktech\_motor.h](https://wiki.fablab.sorbonne-universite.fr/BookStack/attachments/1867)**

**[robot\_ROB3\_complet.ino](https://wiki.fablab.sorbonne-universite.fr/BookStack/attachments/1866)**

<span style="color: #222222;"><span style="caret-color: rgb(34, 34, 34); font-size: 23.323999px;">**<u>Pôle mécanique :</u>**</span></span>

 Différentes solutions ont été envisagées mais on opte, dans un premier temps, pour la solution suivante:

[ ![image.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-03/scaled-1680-/aFtimage.png) ](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-03/aFtimage.png)

  **<span style="text-decoration: underline;">Figure 1:</span>** Modélisation de la première solution

 On modélise un châssis avec des emplacements définis pour chaque composant, et on décide d'adopter pour une structure en escalier afin de fixer la roue pilotante à l'extrémité la plus haute, étant donné le fait qu'elle soit plus volumineuse que les autres roue, et de placer la pince sur une cale située à l'autre extrémité. Le mouvement de celle-ci sera piloté par un système de pont levis qui consiste à lever la cale à l'aide d'une corde qui s'enroulera.

 Cependant, après réflexion, on se rend compte que cette première solution était inutilement complexe et présentait quelques inconvénients, comme le fait que la pince soit trop haute. On décide alors d'opter pour une solution plus simple qui est la suivante :[ ](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-03/u9Uimage.png)

<span style="text-decoration: underline;">**Le châssis** </span>

 Un châssis rectangulaire (figure 2) a été dimensionné de sorte à ce que tous les composants puissent être placés dessus sans encombrer la maquette. La roue libre a été placée à l'arrière du robot et les deux roues motrices à l'avant, afin que le centre de rotation, lorsque le robot tourne sur lui-même, soit le plus proche possible de la pince. Cela permet d'avoir des mouvements plus précis lors des rotations.

 Quatre trous ont été prévus afin de pouvoir fixer les supports de la carte Arduino et ceux de la batterie sur le châssis.

 Une ouverture rectangulaire verticale a également été ajoutée afin de permettre le passage du câblage de la maquette et d’éviter que les fils gênent les différents éléments mécaniques.

 À l’avant du robot, deux fentes horizontales identiques servent à fixer les supports des roues motrices. Une autre fente horizontale, plus fine cette fois, permet la fixation du capteur à ultrasons utilisé pour détecter le mur situé à droite du robot.

 Enfin, huit petits trous ont été prévus afin de fixer le support du moteur contrôlant la pince et ainsi assurer un maintien stable de celle-ci sur le robot.

 [![Capture d’écran 2026-05-28 à 01.19.50.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/capture-decran-2026-05-28-a-01-19-50.png)](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/capture-decran-2026-05-28-a-01-19-50.png)

  **<span style="text-decoration: underline;">Figure 2:</span>** Esquisse du châssis

 Concernant les fixations des roues motrices (figure 3), celles-ci viennent s’encastrer dans le châssis par le dessus grâce aux encoches prévues sur leur partie supérieure. Ces encoches ont été dimensionnées légèrement plus larges que les ouvertures du châssis afin d’obtenir un assemblage serré et d’assurer une bonne tenue de l’ensemble.

 Un trou rectangulaire vertical central a également été prévu afin d’accueillir le support du capteur utilisé pour détecter les obstacles situés à l’avant de la maquette, notamment les murs et le totem. En plus de maintenir le capteur, cette pièce permet aussi de garder un bon écartement entre les deux supports de roues, ce qui limite les déformations du châssis et le rend plus rigide.

 Enfin, quatre trous ont été ajoutés afin de permettre la fixation des moteurs des roues motrices. Ces fixations permettent de maintenir correctement les moteurs et d’assurer un bon alignement du système moteur.

[ ![image.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/641image.png)](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/641image.png)

  **<span style="text-decoration: underline;">Figure 3:</span>** Fixation des roues motrices

<span style="text-decoration: underline;">**La pince** </span>

 Pour pouvoir attraper le totem, la pince qui nous a été fournie va être utilisée. Afin de lui permettre de se lever verticalement et d’atteindre la partie la plus fine du totem, le couple délivré par le moteur sera exploité. À ce moteur est fixée une pièce réalisée en impression 3D (1), qui sera utilisée comme bras de levage. Cette pièce est ensuite reliée à une petite planche, appelée “planche à pivot” (2), capable d’effectuer une rotation verticale afin d’orienter correctement la pince vers la zone fine du totem. Enfin, une encoche dans la planche à pivot est prévue, afin d’y encastrer un support qui permettra par la suite d'y visser solidement la pince grâce à deux trous de fixation.

[ ![image.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/JFjimage.png) ](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/JFjimage.png)

 <span style="text-decoration: underline;">**Figure 4:**</span> Mécanisme de la pince

[ ](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/ULyimage.png)

<span style="text-decoration: underline;">**Les capteurs**</span>

 Les deux capteurs sont disposés de la manière suivante : le premier capteur est placé sur le côté du robot afin de mesurer la distance par rapport au mur et ainsi permettre au robot de se repérer dans son environnement, tandis que le second capteur est situé sous le châssis afin de détecter le totem, mais également les obstacles ou murs présents devant le robot. Afin de maintenir ces capteurs en place, deux supports sont conçus (figure 4). Chacun d'entre eux possède un emplacement adapté aux deux capteurs optiques ainsi que des trous de vissage permettant de les fixer solidement. Concernant le support du capteur situé sous le châssis, deux encoches sont crées afin qu’il puisse s’encastrer entre les deux planches maintenant les moteurs des roues, cela permet d’assurer une fixation plus stable du support sur le robot. Enfin, pour le support du capteur latéral, une seule encoche a été ajoutée à sa base afin qu’il puisse s’encastrer directement dans le châssis.

[ ![image.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/zxgimage.png) ](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/zxgimage.png)[![image.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/7Qjimage.png)](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/7Qjimage.png)

 <span style="text-decoration: underline;">**Figure 5:**</span> Modélisation des supports de capteur

 Finalement, lors du montage sur leurs supports, on constate que les capteurs ne sont pas totalement plats et présentent un relief entre les deux capteurs optiques. Ne disposant pas de vis suffisamment longues et adaptées au diamètre des trous de fixation pour compenser cette surépaisseur, on décide de modifier légèrement les supports en ponçant la zone située entre les deux capteurs optiques afin de laisser passer ce relief (figure 6).

[![image.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/Fslimage.png) ](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/Fslimage.png)[![image.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/OtQimage.png)](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/OtQimage.png)

 <span style="text-decoration: underline;">**Figure 6:**</span> Design final des supports de capteur

<span style="color: #222222;"><span style="caret-color: rgb(34, 34, 34); font-size: 23.323999px;">**<u>Pôle électronique :</u>**</span></span>

 Pour le pôle électronique, le début du projet n'était pas très actif. Lors de la première séance on a juste vérifier que tout le matériel étaient fonctionnel et marchait correctement. En réalisant ces testes, on remarque qu'il manque un fil pour relier le servomoteur dynamixel à l'arduino MEGA.   
  
 Lors de la deuxième séance on décide donc de nous même assemblé ce fil en soudant deux fils qui sont liés à différents embout compatible à l'Arduino d'un coté et au dynamixel de l'autre. Pour cela on utilise, un fer à souder pour faire chauffer de l'éteint entre les câbles que l'on souhaite souder. Une fois que l'éteint c'est faufilé entre les fils qu'on souhaite souder, on laisse refroidir pendant un instant, on aplatit la zone soudé avec une pince à tête plate et on couvre la zone par de la gaine thermo rétractable que l'on vient chauffer avec un pistolet à air chaud.

 Le produit final donnera quelque chose comme cela:

[![DA2EB33F-376D-4B1F-818D-EFA031EF259A.JPG](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/da2eb33f-376d-4b1f-818d-efa031ef259a.JPG)](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/da2eb33f-376d-4b1f-818d-efa031ef259a.JPG)

 <span style="text-decoration: underline;">**Figure 7:**</span> Cable reliant le Shield Dynamixel et le servomoteur Dynamixel

 Plus tard dans le projet, après que la modélisation du châssis soit terminé, on assemble donc tout les câbles et réalisons toutes les connections sur les différent port. (Voir les instructions de câblage un peu plus bas.) Nous avons essayé de câbler le montage d'une manière propre.  
  
**Câblage du Robot:**

<table border="1" class="align-center" id="bkmrk-el%C3%A9ment-pin-capteurs" style="border-collapse: collapse; width: 100%; height: 278.4px;"><colgroup><col style="width: 50%;"></col><col style="width: 50%;"></col></colgroup><tbody><tr style="height: 35.2px;"><td class="align-center" style="height: 35.2px;">**Elément**</td><td style="height: 35.2px;">**Pin**

</td></tr><tr style="height: 35.2px;"><td style="height: 35.2px;">Capteurs US droit (latéral)</td><td style="height: 35.2px;">VCC : 5V, GND : GND, TRIG : PIN 22, ECHO : PIN 23

</td></tr><tr style="height: 35.2px;"><td style="height: 35.2px;">Capteur US avant</td><td style="height: 35.2px;">VCC : 5V, GND : GND , TRIG : PIN 42 , ECHO : PIN 43

</td></tr><tr style="height: 57.6px;"><td style="height: 57.6px;">Servomoteur Dynamixel</td><td style="height: 57.6px;">Brancher d'un côté sur le dynamixel et de l'autre sur le Shield dynamixel (Voir figure ??)

</td></tr><tr style="height: 80px;"><td style="height: 80px;">Moteur Ktech</td><td style="height: 80px;">Fils rouges : 12V de la batterie, Fils noirs : Masse de la batterie, Fils bleus: Sur le bornier du Shield CAN (côté gauche), Fils jaunes : Sur le bornier du Shield CAN (côté droit).

</td></tr><tr style="height: 35.2px;"><td style="height: 35.2px;">Pince</td><td style="height: 35.2px;">Fil Rouge : 5V, Fil Noir : GND, Fil Blanc : PIN 6, Fil Vert : PIN ANALOG A15

</td></tr><tr><td>Cable UART-USB pour recevoir des informations sur le système en temps réel</td><td>Fil Noir : GND , Fil Orange : PIN 7, Fil Jaune : PIN 8, BAUD RATE : 115200 (Dans le terminal Arduino\*)

</td></tr></tbody></table>

 On a aussi décidé de rajouté un interrupteur sur la batterie afin de sécuriser le montage et de faciliter le téléversement des programme lorsque le système est totalement monté. Pour installer cet interrupteur, on a juste branché sur le fil rouge du distributeur au différent bornier connecté sur la batterie l'interrupteur.

**\*: Pour observer les information dans le terminal Arduino, il faut ouvrir un moniteur serial sur un nouveau programme Arduino, le connecté au port du câble USB-UART et réglé la vitesse de transmission à 115200 bauds.**

<span style="color: #222222;"><span style="caret-color: rgb(34, 34, 34); font-size: 23.323999px;">**<u>Pôle informatique :</u>**</span></span>

 On réalise tout d'abord un organigramme afin de structurer la logique de l'algorithme avant de passer à la programmation.

[ ![image.png](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/scaled-1680-/Y3iimage.png)](https://wiki.fablab.sorbonne-universite.fr/BookStack/uploads/images/gallery/2026-05/Y3iimage.png)

 <span style="text-decoration: underline;">**Figure 8:**</span> Organigramme du fonctionnement du robot

 Pour réaliser la boucle correspondante, on code dans un premier temps les fonctions suivantes :

<span style="text-decoration: underline;">**Initialisation**</span>

**verifierEtatInitial()** Séquence de vérification au démarrage : lève le bras, ouvre la pince, puis lit la position analogique de la pince (pin A15) pour confirmer que les actionneurs répondent correctement.

**setup()** Fonction Arduino standard exécutée une seule fois au démarrage. initialise le port série, les capteurs ultrason, le servomoteur de la pince, le bus CAN, le servomoteur Dynamixel en mode position, et les moteurs KTech. Effectue un reset des encodeurs en fin d'initialisation.

<span style="text-decoration: underline;">**Conversion**</span>

**deg\_to\_m(float deg)**: Convertit un angle en degrés (rotation d'un moteur) en distance linéaire en mètres, en utilisant le rayon de la roue.

<span style="text-decoration: underline;">**Cinématique**</span>

**MotorSpeed(float v\_translation, float v\_rotation):** Calcule et envoie les commandes de vitesse aux deux moteurs KTech via le bus CAN. Prend en entré une vitesse de translation (m/s) et une vitesse de rotation (rad/s), et applique le modèle cinématique d'un robot pour convertir ces consignes en RPM pour chaque roue.

**stopMotors()**: Envoie une commande de vitesse nulle aux deux moteurs pour arrêter immédiatement le robot.

<span style="text-decoration: underline;">**Capteurs Ultrasons**</span>

**fonction lire\_distance (int pinTrig, int pinEcho)** : qui reçoit en entrée les numéros des broches du capteur. Elle sert à mesurer la distance séparant le robot d’un obstacle en calculant le temps de vol d'une onde sonore. Le code commande d'abord au capteur d'émettre un son (via la broche *Trigger*), puis met le programme brièvement en pause pour mesurer le temps de propagation de l'écho reçu (via la broche *Echo*). Enfin, elle réalise un calcul mathématique simple pour convertir cette durée en centimètres (en utilisant la vitesse du son) et envoie le résultat final sous forme de nombre décimal au programme principal, permettant au robot de décider s'il doit s'arrêter ou continuer sa route.

**distanceValide(float d) :** Vérifie qu'une mesure de distance est dans une plage physiquement cohérente (entre 2 et 900cm). Retourne 'True' si la valeur est dans l'intervalle, 'False' sinon.

<span style="text-decoration: underline;">**Actionneurs**</span>

**controlePince(bool ouvrir)** : qui, comme son nom l'indique, <span data-path-to-node="1,1"><span class="citation-352">sert à ouvrir ou fermer la pince du robot afin d'attraper et relâcher le totem</span></span><span data-path-to-node="1,7">. </span><span data-path-to-node="1,9"><span class="citation-350">La fonction reçoit en entrée un choix logique (*true* </span><span class="citation-350">pour ouvrir, *false* </span><span class="citation-350">pour fermer): si la condition est vraie, elle envoie un signal électrique spécifique (PWM de 500) sur la broche de la pince pour l'ouvrir au maximum </span></span><span data-path-to-node="1,12"><span class="citation-349">; si elle est fausse, elle envoie un signal différent (PWM de 950) pour la fermer</span></span><span data-path-to-node="1,14">. </span><span data-path-to-node="1,16"><span class="citation-348">Enfin, on </span><span class="citation-348">intègre une courte pause (*delay*</span><span class="citation-348">), qui laisse le temps mécanique au servomoteur de finaliser son mouvement afin d'éviter de perturber les autres commandes électriques du robot</span></span><span data-path-to-node="1,18">.</span>

**baisserBras():** Envoie au servomoteur Dynamixel la consigne de postion basse (DXL\_POS\_BAS) pour abaisser le bras du robot. On attend 1500ms pour la fin du mouvement.

**leverBras():** Envoie au servomoteur Dynamixel la consigne de position haute (DXL\_POS\_HAUT) pour lever le bras. Attend 1500ms pour la fin du mouvement.

<span style="text-decoration: underline;">**Odométrie**</span>

**reset\_encodeurs():** Lit l'état actuel des deux moteurs et sauvegarde leurs positions angulaires comme référence zéro. Toutes les mesures de déplacement ultérieures seront calculées relativement à ce point de départ.

**lire\_d0\_d1(float &amp;d0, float &amp;d1) :** Lit les positions courantes des deux moteurs et calcule les distances parcourues en mètres par chaque roue depuis le dernier reset, en tenant compte du sens de rotation.

**mesurer\_distance\_parcourue():** Retourne la distance linéaire moyenne parcourue par le robot (moyenne des deux roues) depuis le dernier reset des encodeurs, en mètres. Affiche également les valeurs individuelles sur le port série.

<span style="text-decoration: underline;">**Suivi de Mur**</span>

**avancerSuiviMur():** Fait avancer le robot en corrigeant sa trajectoire pour maintenir une distance par rapport au mur droit (DIST\_MUR\_CIBLE), à l'aide d'un correcteur proportionnel (gain KP\_MUR). La vitesse d'avance est réduite si l'erreur latérale est trop grande. Doit être appelée en boucle.

<span style="text-decoration: underline;">**Déplacements par odométrie**</span>

**avancerDistancePrecise(float distCible\_m)** Fait avancer le robot en ligne droite sur une distance précise en mètres, mesurée par odométrie. S'arrête dès que la distance cible est atteinte.

**reculerDistancePrecise(float distCible\_m)** Fait reculer le robot sur une distance précise en mètres, mesurée par odométrie. S'arrêete dès que la distance cible est atteinte.

**avancerDistanceSuiviMur(float distCible\_m)** Fait avancer le robot sur une distance précise en mètre tout en maintenant me suivi du mur droit.

<span style="text-decoration: underline;">**Rotations par odométrie**</span>

**tournerDroite90()** Effectueune rotation de 90° vers la droite sur place, en contrôlant l'angle par odométrie. Pour compenser le glissement des roues on a rajouté un coefficient empirique de 0.83.

**tournerGauche90()** Effectueune rotation de 90° vers la gauche sur place, en contrôlant l'angle par odométrie. Pour compenser le glissement des roues on a rajouté un coefficient empirique de 0.83.

 Ainsi, on réussit à obtenir un robot fonctionnel, conforme aux attentes, comme en témoigne cette vidéo : [vidéo robot fonctionnel](https://drive.google.com/file/d/1M_Iu5rXr3HK9zu05pScoAy84JGMlHxM9/view?usp=share_link)