Skip to main content

Projet ROB3 : Fares, Ilyes, Albéric

Projet ROB3 : 

Ilyes Elotreuch, Fares Charni, Albéric Fasquelle

Informations

Polytech Sorbonne - Spécialité Robotique - Projet de 3eme année 

Contact des membres de l'équipe :
Albéric Fasquelle alberic.fasquelle@etu.sorbonne-universite.fr
Ilyes Elotreuch ilyes.elotreuch@etu.sorbonne-universite.fr
Fares Charni fares.charni@etu.sorbonne-universite.fr

Introduction

Dans le cadre de ce projet de robotique nous avons à réaliser un robot écrivain. Celui-ci dispose de plusieurs fonctions et mode qui participe à la complexité de ce projet. 

En premier lieu nous avons le mode manuel qui pilotera le robot à l'aide d'un joystick afin de dessiner ce que l'on souhaite. De plus notre robot dispose de quatre fonctions supplémentaires qui dessinerons de manière automatique une cercle et une ligne.

Le présent document détaille les exigences du projet, les différentes étapes de sa réalisation, ainsi que les ressources et les échéances qui nous guideront tout au long de ce processus.

Cahier des charges 

Dans ce cahier des charges, nous sommes chargés de concevoir un robot capable de réaliser des dessins sur une surface plane. Nous devons lui permettre d'accomplir différentes tâches, telles que tracer des lignes et des cercles de longueurs et de rayons spécifiques dans un temps défini. De plus, il doit être en mesure de reproduire un dessin particulier dans un carré donné, tout en étant contrôlé par un joystick pour son mouvement. Nous pouvons envisager d'ajouter une fonctionnalité supplémentaire pour ajuster la vitesse du robot selon les besoins. Les contraintes incluent l'utilisation exclusive des équipements du FABLAB de Sorbonne Université, le choix des composants prédéfinis, la fabrication des pièces avec des machines spécifiques, et la programmation en C via l'IDE Arduino. Notre objectif sera également de minimiser la quantité de matériau utilisé pour ce projet.

1. Conception préliminaire 

Dans cette section, nous présentons trois solutions potentielles pour la conception et la réalisation du robot écrivain, en tenant compte des exigences du cahier des charges et des contraintes spécifiées. Chaque solution est accompagnée de schémas, ainsi qu'une explication pour faciliter la compréhension. Nous avons retenu une proposition parmi les trois proposé ci dessous en fonction du cahier des charges et de nos préférences personnelles. 

Solution 1 :


La première solution utilise pour les mouvements dans le plan horizontal de la feuille un mécanisme en boucle fermée à 4 barres, 5 liaisons pivots, dont deux sont motorisées. Voir une explication de son fonctionnement sur ce site . Pour les mouvements verticaux, on produit une translation verticale de la base qui soulève l'ensemble du robot.

Nous nous sommes inspiré du robot Cozmo WeDraw pour la création de cette solution. Voir ici (minute 2:25 de la vidéo)

Solution 2 : 

Notre deuxième solution est un bras robotique classique utilisant les servomoteurs en série afin de déplacer le bras selon les axes X et Y. Le troisième servo est utilisé ici pour soulever l'effecteur. Cette solution possède certains avantage comme une configuration cinématique assez simple. Cependant, elle présente des risques de stabilité structurelle, surtout lors de mouvements rapides. De plus, la précision du robot peut être compromise aux extrémités au niveau de l'effecteur, en raison des effets de la gravité et de la flexion des composants(notamment des servomoteurs).

Solution 3 : 

Notre 3eme solution s'appuie sur un principe de guidage linéaire, à la manière des imprimantes 3D en retirant la composante Z. Un dispositif de guidage supporte le crayon et se déplace le long de rails des guidages pour réaliser les dessins sur la plaque support. Cette solution utilise deux rails de guidage ainsi que des courroies pour déplacer l'effecteur selon l'axe X et Y. Pour soulever le stylo nous ajoutons un servomoteur au niveau du stylo. Cette solution ne sera pas retenu en raison des contraintes matériels. 

Choix de la solution 

L’idée 3 à été écarté des possibilités en raison des composants disponibles.

Solution  Avantages Inconvénients

Idée 1

-Facilité de conception 

-Esthétique

-Précision : pas de contraintes mécanique trop importante sur l'axe des servomoteurs

 

-Possibilité d'une écriture du code plus complexe en raison de la forme.
Idée 2

-Mise en place simple

-Architecture simple

-Pas de contrainte potentielle sur les composants

-Possiblement difficile à réaliser car la contrainte mécanique sur l'axe d'un des servomoteur.

-Pas spécialement beau

 

Idée 3

- modèle cinématique facile à réaliser

-Guidage difficile à réaliser au niveau des courroies

-Composant non disponibles: courroie, rails de guidage 

-possibilité de perte de précision lors des déplacements à causes des roulements

Nous avons décidé après l'étude des différentes solution de sélectionner la première proposition. D'une part puisque nous trouvions le design  agréable et original. Et d'autre part pour certaines raisons pratiques cités ci-dessus. 

Ensemble des tâches à réaliser pour la conception du robot :

Voici dessous l'ensemble des tâches réaliser lors des différentes étapes de la réalisation de ce projet. 

image.png

Diagramme de Gantt :

Voici ci dessous le diagramme de Gantt prévisionnel du projet. Celui-ci est amené à être modifié selon l'avancement du projet. 

image.png

2. Conception détaillé du robot

2.1 Schéma électronique :

Pour la réalisation du schéma électronique, nous avons tout d'abord fait la liste de tout le matériel nécessaire à la bonne conception de celle-ci. La carte électronique est segmenté en plusieurs parties: 

  • Nous avons  tout d'abord l'élément central, l'Arduino. Il s'agit du microcontrôleur, c'est à dire le "cerveau" de la carte. Celui-ci est relié à chaque composant afin de les faire fonctionner entre eux.
  • Ensuite nous avons la partie des servomoteurs visualisés ici par des autocoms. 
  • Nous avons également ajouté une partie debug pour la partie des 4 modes à réaliser. Nous avons ajouter un bouton pour activer ou non les modes. Et nous avons ajouter une led rgb pour deux intérêts, d'une par pour pouvoir afficher l'état ou l'avancement du mode en court, il s'agit donc d'une aide pour debug. Et il y a également un côté esthétique. 
  • Enfin nous avons l'alimentation et le joystick modélisé également par des autocoms. 

image.png

Pour modélisé la carte nous avons fait le choix d'utiliser le logiciel KiCad pour deux raisons. LA première est que ce logiciel a déjà été utilisé par certains membres du groupe. Et la seconde pour son côté pratique qui nous permettra si le temps nous le permet d'imprimer une carte électronique(PCB). Pour rendre le projet encore plus attrayant. 

2.2 Équations de mouvement du robot

Dans cette section, nous nous concentrerons sur la manière pratique de gérer le mouvement du robot dessinateur. Notre objectif est de comprendre comment convertir les coordonnées souhaitées de la pointe du stylo sur la surface de dessin en mouvements précis des articulations du robot. Pour ce faire, nous aborderons les principes de base de la cinématique directe, qui nous permettent de déterminer la position du stylo en fonction des angles des articulations du robot.

Ensuite, nous explorerons le modèle géométrique inverse, une méthode essentielle pour programmer le mouvement du robot avec précision et efficacité. Ce modèle nous permettra d'établir les équations qui relient les coordonnées de la pointe du stylo aux angles des articulations du robot, fournissant ainsi un cadre pratique pour contrôler le mouvement du robot dessinateur dans diverses situations.

Modèle géométrique inverse

image.png

image.png

image.png

image.png

Nous avons ensuite réalisé une esquisse de notre robot sur SolidWorks pour vérifier les équations. En rendant les cotations des angles pilotées, nous pouvons introduire une position de la pointe du stylo, et obtenir les angles correspondants, avec la prise en compte des longueurs des bielles du robot. On observe que les valeurs concordent avec celles données par les équations.

image.png

Nous avons ensuite fait un code python pour calculer les valeurs des angles à partir de la position de la pointe du stylo:

image.png

image.png

On observe que les valeurs obtenues avec SolidWorks concordent avec celles obtenues par les équations.

On peut valider le modèle géométrique.

On prendra en particulier pour simplifier les calculs une structure de losange formée par les bielle 1 2 3 et 4 .

2.3 Conception de la structure du code et de l'interface

Pour structurer notre code, nous avons d'abord conçu l'interface utilisateur à l'aide du matériel fourni.
Cette interface permet de répondre aux exigences du cahier des charges en assurant un changement dynamique entre différents modes de dessins et une interruption rapide du processus en cas de besoin. 

Logigramme de l'interface :

Notre interface est composé du bouton démarrage, du joystick et d'un bouton de changement de mode.

On a choisit, pour rendre notre interface plus compacte d'implémenter le système suivant, où l'appui sur le bouton changement de Mode suivi d'un mouvement du joystick permettra de changer entre 4 modes.


L'appui sur le joystick permet par ailleurs d'interrompre ou de reprendre de manière aisée et rapide le dessin.

Capture d'écran 2024-05-29 162655.png

Détaillons le logigramme du code pour le mouvement du stylo et le changement de l'état Stylo levé/Stylo bas :

Changement de position :

On voit que les nouvelles valeurs des angles dépendent d'elles mêmes.
On implémentera lors de nos tests 2 codes différents pour le calcul de la nouvelle position:


Le premier calculera les nouvelles positions à partir des positions actuelles -> Plus rapide

Le deuxième utilisera la dichotomie pour résoudre l'équation du mouvement ->Plus précis mais calcul très coûteux

Logigramme Mouvement Joystick.png

Changement d'état :

Le guidage du moteur 3 ainsi que l'angle de la rotation pour le changement de l'état restent à définir.

Logigramme Appuie sur Joystick.png

2.4 Écriture du code

A partir de ce logigramme nous avons réalisé la création du code. Le code comporte cinq parties:

1) Dessin de la ligne continue de 5 cm:
// Tracer une ligne droite horizontale dans le sens des x négatifs
void move_in_line(double x_start, double y_start, double length, int steps, double l_1, double l_2, double l_3, double l_4, double l_5) {
    double step_size = length / steps;
    // double time_per_step = 10000.0 / steps; // 10 secondes (10000 ms) divisé par le nombre de steps
    unsigned long total_time = 9800; // Temps total en millisecondes (10 secondes)
    unsigned long time_per_step = total_time / steps;
    unsigned long start_time = millis(); // Start time
    
    for (int i = 0; i <= steps; i++) {
        double x_p = x_start - i * step_size; //Tracer la ligne dans le sens des x négatifs
        double y_p = y_start;
        
        double theta_1 = calculate_theta_1(x_p, y_p, l_1, l_4, l_5);
        double theta_2 = calculate_theta_2(x_p, y_p, theta_1, l_1, l_2, l_3, l_4, l_5);

        // Convertir les angles en degrés
        double theta_1_deg = theta_1 * 180 / M_PI;
        double theta_2_deg = theta_2 * 180 / M_PI;

        // Déplacer les servos aux angles calculés
        servo1.write(theta_1_deg);
        servo2.write(180 - theta_2_deg);

        // Afficher les angles actuels dans le moniteur série
        Serial.print("Step ");
        Serial.print(i);
        Serial.print(": Theta_1 = ");
        Serial.print(theta_1_deg);
        Serial.print(", Theta_2 = ");
        Serial.println(theta_2_deg);

        // delay(time_per_step);  // Délai pour chaque étape

        // Attendre jusqu'au temps approprié pour le prochain pas
        unsigned long current_time = millis();
        unsigned long next_step_time = start_time + (i + 1) * time_per_step;
        while (current_time < next_step_time) { // Boucle while remplace le delay
            current_time = millis();
        }
    }

    // Vérification finale du temps écoulé
    unsigned long actual_end_time = millis();
    Serial.print("Temps total: ");
    Serial.println(actual_end_time - start_time);
    
}
2) Dessin de la ligne discontinue de 5 cm:
// Tracer une ligne droite discontinue
void move_in_line_disc(double x_start, double y_start, double length, int steps, double l_1, double l_2, double l_3, double l_4, double l_5) {
  servo3.write(90);
  double step_size = length / steps;
  unsigned long total_time = 9800;  // Temps total en millisecondes (10 secondes)
  unsigned long time_per_step = total_time / steps;
  unsigned long start_time = millis();  // Start time

  for (int i = 0; i <= steps; i++) {
    double x_p = x_start - i * step_size;  // Tracer la ligne dans le sens des x négatifs
    double y_p = y_start;

    double theta_1 = calculate_theta_1(x_p, y_p, l_1, l_4, l_5);
    double theta_2 = calculate_theta_2(x_p, y_p, theta_1, l_1, l_2, l_3, l_4, l_5);

    // Convertir les angles en degrés
    double theta_1_deg = theta_1 * 180 / M_PI;
    double theta_2_deg = theta_2 * 180 / M_PI;

    // Déplacer les servos aux angles calculés
    servo1.write(theta_1_deg);
    servo2.write(180 - theta_2_deg);

    // Lever et abaisser le stylo pour créer une ligne discontinue
    if (i % 10 < 5) {
      servo3.write(90);  // Abaisser le stylo
    } else {
      servo3.write(100);  // Lever le stylo
    }

    // Afficher les angles actuels dans le moniteur série
    Serial.print("Step ");
    Serial.print(i);
    Serial.print(": Theta_1 = ");
    Serial.print(theta_1_deg);
    Serial.print(", Theta_2 = ");
    Serial.println(theta_2_deg);

    // Attendre jusqu'au temps approprié pour le prochain pas
    unsigned long current_time = millis();
    unsigned long next_step_time = start_time + (i + 1) * time_per_step;
    while (current_time < next_step_time) {  // Boucle while remplace le delay
      current_time = millis();
    }
  }
  servo3.write(100);
  // Vérification finale du temps écoulé
  unsigned long actual_end_time = millis();
  Serial.print("Temps total: ");
  Serial.println(actual_end_time - start_time);
}

3) Dessin du cercle continu de rayon 2.5 cm:
// Utiliser les équations paramétriques d'un cercle pour calculer les positions des points autour du cercle

void move_in_circle_half1(double center_x, double center_y, double radius, int steps, double l_1, double l_2, double l_3, double l_4, double l_5) {
    unsigned long total_time = 4800; // Total time in milliseconds (10 seconds)
    unsigned long time_per_step = total_time / steps;
    unsigned long start_time = millis(); // Start time

    for (int i = 0; i <= steps; i++) { 
        // Calcul des coordonnées x et y pour le cercle
        double angle = 1 * M_PI * i / steps; // Angle en radians
        double x_p = center_x + radius * cos(angle);
        double y_p = center_y + radius * sin(angle);

        double theta_1 = calculate_theta_1(x_p, y_p, l_1, l_4, l_5);
        double theta_2 = calculate_theta_2(x_p, y_p, theta_1, l_1, l_2, l_3, l_4, l_5);

        // Convertir les angles en degrés
        double theta_1_deg = theta_1 * 180 / M_PI;
        double theta_2_deg = theta_2 * 180 / M_PI;

        // Déplacer les servos aux angles calculés
        servo1.write(theta_1_deg);
        servo2.write(180 - theta_2_deg);

        // Afficher les angles actuels dans le moniteur série
        Serial.print("Step ");
        Serial.print(i);
        Serial.print(": Theta_1 = ");
        Serial.print(theta_1_deg);
        Serial.print(", Theta_2 = ");
        Serial.println(theta_2_deg);

        // Attendre jusqu'au temps approprié pour le prochain pas
        unsigned long current_time = millis();
        unsigned long next_step_time = start_time + (i + 1) * time_per_step;
        while (current_time < next_step_time) {
            current_time = millis();
        }
        //delay(time_per_step);
    }

    // Vérification finale du temps écoulé
    unsigned long actual_end_time = millis();
    Serial.print("Temps total: ");
    Serial.println(actual_end_time - start_time);
}

// Utiliser les équations paramétriques d'un cercle pour calculer les positions des points autour du cercle
void move_in_circle_half2(double center_x, double center_y, double radius, int steps, double l_1, double l_2, double l_3, double l_4, double l_5) {
    unsigned long total_time = 4800; // Total time in milliseconds (10 seconds)
    unsigned long time_per_step = total_time / steps;
    unsigned long start_time = millis(); // Start time

    for (int i = 0; i <= steps; i++) { 
        // Calcul des coordonnées x et y pour le cercle
        double angle = 1 * M_PI * i / steps; // Angle en radians
        double x_p = center_x - radius * cos(angle);
        double y_p = center_y - radius * sin(angle);

        double theta_1 = calculate_theta_1(x_p, y_p, l_1, l_4, l_5);
        double theta_2 = calculate_theta_2(x_p, y_p, theta_1, l_1, l_2, l_3, l_4, l_5);

        // Convertir les angles en degrés
        double theta_1_deg = theta_1 * 180 / M_PI;
        double theta_2_deg = theta_2 * 180 / M_PI;

        // Déplacer les servos aux angles calculés
        servo1.write(theta_1_deg);
        servo2.write(180 - theta_2_deg);

        // Afficher les angles actuels dans le moniteur série
        Serial.print("Step ");
        Serial.print(i);
        Serial.print(": Theta_1 = ");
        Serial.print(theta_1_deg);
        Serial.print(", Theta_2 = ");
        Serial.println(theta_2_deg);

        // Attendre jusqu'au temps approprié pour le prochain pas
        unsigned long current_time = millis();
        unsigned long next_step_time = start_time + (i + 1) * time_per_step;
        while (current_time < next_step_time) {
            current_time = millis();
        }
        //delay(time_per_step);
    }

        // // Position finale
         double x_f = center_x - radius * cos(M_PI / 6);
         double y_f = center_y - radius * sin(M_PI / 6);

         double theta_1_f = calculate_theta_1(x_f, y_f, l_1, l_4, l_5);
         double theta_2_f = calculate_theta_2(x_f, y_f, theta_1_f, l_1, l_2, l_3, l_4, l_5);

         // Convertir les angles en degrés
         double theta_1_deg_f = theta_1_f * 180 / M_PI;
         double theta_2_deg_f = theta_2_f * 180 / M_PI;

         // Déplacer les servos aux angles calculés
         servo1.write(theta_1_deg_f);
         servo2.write(180 - theta_2_deg_f);

    // Vérification finale du temps écoulé
    unsigned long actual_end_time = millis();
    Serial.print("Temps total: ");
    Serial.println(2*(actual_end_time - start_time));
}

4) Dessin du cercle discontinue de rayon 2.5 cm:
void move_in_circle_half1_disc(double center_x, double center_y, double radius, int steps, double l_1, double l_2, double l_3, double l_4, double l_5) {
  unsigned long total_time = 4800;
  unsigned long time_per_step = total_time / steps;
  unsigned long start_time = millis();
  servo3.write(90);

  for (int i = 0; i <= steps; i++) {
    double angle = 1 * M_PI * i / steps;
    double x_p = center_x + radius * cos(angle);
    double y_p = center_y + radius * sin(angle);

    double theta_1 = calculate_theta_1(x_p, y_p, l_1, l_4, l_5);
    double theta_2 = calculate_theta_2(x_p, y_p, theta_1, l_1, l_2, l_3, l_4, l_5);

    double theta_1_deg = theta_1 * 180 / M_PI;
    double theta_2_deg = theta_2 * 180 / M_PI;

    servo1.write(theta_1_deg);
    servo2.write(180 - theta_2_deg);

    if (i % 10 < 5) {
      servo3.write(90);  // Stylo en bas
    } else {
      servo3.write(100);  // Stylo en haut
    }

    Serial.print("Step ");
    Serial.print(i);
    Serial.print(": Theta_1 = ");
    Serial.print(theta_1_deg);
    Serial.print(", Theta_2 = ");
    Serial.println(theta_2_deg);

    unsigned long current_time = millis();
    unsigned long next_step_time = start_time + (i + 1) * time_per_step;
    while (current_time < next_step_time) {
      current_time = millis();
    }
  }
  unsigned long actual_end_time = millis();
  Serial.print("Temps total: ");
  Serial.println(actual_end_time - start_time);
}

void move_in_circle_half2_disc(double center_x, double center_y, double radius, int steps, double l_1, double l_2, double l_3, double l_4, double l_5) {
  unsigned long total_time = 4800;
  unsigned long time_per_step = total_time / steps;
  unsigned long start_time = millis();

  for (int i = 0; i <= steps; i++) {
    double angle = M_PI + M_PI * i / steps;
    double x_p = center_x + radius * cos(angle);
    double y_p = center_y + radius * sin(angle);

    double theta_1 = calculate_theta_1(x_p, y_p, l_1, l_4, l_5);
    double theta_2 = calculate_theta_2(x_p, y_p, theta_1, l_1, l_2, l_3, l_4, l_5);

    double theta_1_deg = theta_1 * 180 / M_PI;
    double theta_2_deg = theta_2 * 180 / M_PI;

    servo1.write(theta_1_deg);
    servo2.write(180 - theta_2_deg);

    if (i % 10 < 5) {
      servo3.write(90);  // Stylo en bas
    } else {
      servo3.write(100);  // Stylo en haut
    }

    Serial.print("Step ");
    Serial.print(i);
    Serial.print(": Theta_1 = ");
    Serial.print(theta_1_deg);
    Serial.print(", Theta_2 = ");
    Serial.println(theta_2_deg);

    unsigned long current_time = millis();
    unsigned long next_step_time = start_time + (i + 1) * time_per_step;
    while (current_time < next_step_time) {
      current_time = millis();
    }

  }
  servo3.write(100);
  unsigned long actual_end_time = millis();
  Serial.print("Temps total: ");
  Serial.println(actual_end_time - start_time);
}
5) Dessin en mode manuel (avec le joystick) :
void loop() {
 // Lire les valeurs du joystick
    int vrxValue = analogRead(VrxPin);
    int vryValue = analogRead(VryPin);

    // Inverser la valeur du joystick pour l'axe Y
    vryValue = joystickMax - vryValue;

    // Vérifier si le joystick est centré (dans la tolérance)
    bool joystickCentered = (abs(vrxValue - (joystickMax / 2)) < joystickCenterTolerance) &&
                            (abs(vryValue - (joystickMax / 2)) < joystickCenterTolerance);

    if (!joystickCentered) {
        // Mapper les valeurs du joystick aux coordonnées (xp, yp)
        double target_x_p = map(vrxValue, joystickMin, joystickMax, minX, maxX);
        double target_y_p = map(vryValue, joystickMin, joystickMax, minY, maxY);

        // Lissage des mouvements
        current_x_p += (target_x_p - current_x_p) * smoothingFactor;
        current_y_p += (target_y_p - current_y_p) * smoothingFactor;
    }


    double theta_1 = calculate_theta_1(current_x_p, current_y_p, l_1, l_4, l_5);
    double theta_2 = calculate_theta_2(current_x_p, current_y_p, theta_1, l_1, l_2, l_3, l_4, l_5);

    // Convertir les angles de radians en degrés
    int angleServo1 = int(theta_1 * 180 / M_PI);
    int angleServo2 = 180 - int(theta_2 * 180 / M_PI);

    Serial.print("Theta_1 = ");
    Serial.println(theta_1 * 180 / M_PI);
    Serial.print("Theta_2 = ");
    Serial.println(theta_2 * 180 / M_PI);

    servo1.write(angleServo1);
    servo2.write(angleServo2);

    delay(100);
  
}

Nous avons remarqué que du à l'encombrement du robot et les limites des angles des servo-moteurs, nous ne pouvons pas atteindre toutes les positions. Ainsi nous avons restreint le robot à une zone de dessin :

Drawing_area.png

2.5 Conception mécanique du robot

La conception mécanique du robot écrivain est essentielle pour assurer sa stabilité, sa précision et sa facilité d'utilisation. Pour la réalisation de celui-ci nous nous sommes inspiré du Wedraw de Cozmo que nous avons trouvé original. Notre robot est composé d'un corps principal sur lequel sont montés deux servomoteurs pour contrôler les bras. Les bras, joints au niveau de leur main, supportent le crayon utilisé pour le traçage des figures sur la surface de la plaque support.

Description du Robot

Le corps principal du robot est conçu pour abriter l'électronique de contrôle ainsi que les mécanismes de mouvement. Les deux servomoteurs, placés de manière symétrique de chaque côté du corps, assurent les mouvements des bras dans le plan horizontal de la feuille. À l'extrémité de chaque bras se trouve une articulation permettant le mouvement du crayon dans toutes les directions nécessaires pour dessiner les figures spécifiées dans le cahier des charges.

Ci dessous notre vue 3D de notre robot. Les couleurs ont été apportés pour amener du contraste dans notre structure afin de mieux visualiser les composants. 

7l9image.png

Choix des matériaux 

Lors de ce projet, nous avons fait le choix de privilégier certains matériaux. Nous avons choisi en priorité l'utilisation de la découpe laser pour la fabrication des pièces principales de la structure, notamment le corps principal du robot et les bras articulés. La découpe laser offre une grande précision dans la réalisation des pièces, permettant ainsi d'obtenir des assemblages parfaitement ajustés et une structure globalement robuste. De plus, ce processus de fabrication est rapide et efficace, ce qui nous permet de produire les pièces simplement. 

Quant aux pièces de l'effecteur, telles que le support du crayon et les éléments de fixation, nous avons opté pour l'impression 3D. Ce procédé nous offre une grande flexibilité dans la conception des pièces, nous permettant ainsi de réaliser des formes complexes. L'impression 3D est très utile pour les petites pièces mais peut vite devenir un problème si nous devions réaliser de grande pièce. C'est pour cela nous avons privilégier la découpe laser pour les pièces structurant notre projet. 

Choix de la structure général 

En ce qui concerne la disposition des composants mécaniques, nous avons décidé de placer les deux servomoteurs sur le même axe verticale. Cette disposition simplifie non seulement les équations de mouvement du robot, mais elle offre également une répartition uniforme des charges.

Les bras du robot sont articulés à l'extrémité du corps principal, permettant ainsi une grande liberté de mouvement pour le crayon utilisé dans le traçage des figures sur la surface de la plaque support. Cette conception garantit également une précision optimale dans l'exécution des dessins. Celle-ci nous permet donc de séparer  la partie utilisateur du bras mécanique.

Maintien de la structure

Afin de maintenir la structure en place nous avons fait le choix de prendre des tiges filetés pour serrer la structure sur elle même. Des écrous maintiendrons le tout en place. Nous avons fait le choix de cette solution puisqu'elle présente plusieurs avantages. La première est la simplicité de mise en place. Et la seconde est le fait de pouvoir accéder facilement au composant si l'on veut faire de la maintenance. Nous avons besoin seulement de dévisser 4 écrous. 

Mécanisme de Relevage du Crayon

Pour relever le crayon du support horizontal lorsqu'il n'est pas en cours d'utilisation, nous avons envisagé plusieurs solutions. Initialement, l'idée était de soulever le corps du robot, mais des préoccupations ont été soulevées quant à la capacité du servomoteur à supporter la charge de tout le système sans que la précision ne soit affecté. Nous nous sommes finalement rabattu sur la seconde solution. Nous avons donc placé un servomoteur au niveau du stylo qui viendra directement lever celui-ci sans avoir à relever l’ensemble de la structure.

Afin de lever le stylo de manière linéaire nous avons fait le choix d'une glissière. Un principe souvent utilisé en mécanique et simple à mettre en œuvre. 

Voici ci dessous les différentes vu de l'intérieur de notre robot :

image.png

Ci-joint le fichier SolidWorks du projet

Bilan du travail de l'équipe

  • Séance 1: Après avoir pris connaissance du sujet du projet, nous nous sommes directement mis à la recherche et à l'exploration de robots similaires existants pour s'en inspirer et nous aider à construire une idée concrète de notre but.

  • On s'est également réparti les tâches grâce à un diagramme de Gantt et à une liste des objectifs à atteindre.
    Nous avons enfin entamé la CAO après avoir établi des sketchs du robot et nous avons également commencé à chercher les équations du mouvement, indispensables par la suite.

  • Séance 2: Durant cette séance, on a réussi à finir, comme prévu la CAO, le schéma du branchement préliminaire ainsi que le calcul des équations du mouvement, adaptés à la structure "losange" de notre robot pour simplifier par la suite les programmes. On a ensuite commencé à s'interroger sur la logique suivie par notre robot surtout sur différentes manières de changer de mode. Après une bonne réflexion, pour prendre le moins d'espace possible et pour rendre les interactions plus rapides, on a décidé d'implémenter une interface permettant de contrôler le robot grâce à un seul bouton et du mouvement du joystick. On a pour cela établi les logigrammes correspondants.

  • Séance 3: Lors de cette séance, on  a finalisé la conception du robot en prévoyant les solutions de guidages et de roulements à considérer pour le mouvement. Nous avons également commencé à coder tout d'abord en insistant sur une bonne structure du code pour simplifier les tests et la résolution d'éventuels bugs. On a aussi décidé d'utiliser la découpe laser pour la création de notre robot, vu qu'elle est plus rapide, économique et convenable quant aux dimensions et aux formes du robot.

  • Séance 4 : Pendant cette séance, on a tâché de construire notre robot et de l'assembler. On a testé un premier code sur le robot mais en vain. En effet, une partie de notre modèle géométrique n'était pas assez adapté à la structure de notre robot, à cause des contraintes réelles du montage. À ce moment, on a décidé qu'il était judicieux de se partager la tâche de la programmation sur deux personnes, Ilyes, qui essaiera d'adapter le modèle géométrique aux contraintes réelles notamment celle de la zone de dessin grâce à des tests successifs et Fares, qui continuera à coder un programme final, complet, qui intègrera les résultats trouvés par Ilyes. 

  • Séance 5 : La dernière séance avant le rendu, on s'est retrouvé face à plusieurs problèmes notamment du côté de la programmation, vu que le programme complet ne fonctionnait pas , la zone de dessin étant très particulière, mais aussi du côté de l'assemblage du robot car certaines pièces n'étaient pas parfaitement faites par la découpe laser et on a eu besoin de les remplacer. Heureusement, on a pu, mais dans des programmes séparés, effectuer chacune des figures du cahier des charges , mais avec une certaine imprécision vu la nature expérimentale des constantes appliquées.

Guide d'utilisation :

  • Démarrage : brancher le câble Arduino. 
  • Le robot se met dans une position initiale (-50,100) par rapport à son repère.
  • Choix du Mode de fonctionnement : Appuyer sur le bouton Mode puis sélectionner grâce au mouvement du Joystick un des 4 Modes de fonctionnement :→

→Vers le haut → Mode 1: Active le dessin en trait continu

→Vers la bas → Mode 2: Active le dessin en trait discontinu

→Vers la droite → Mode 3: Dessine un trait de 5 cm selon le type de trait choisi (Mode 1 ou 2)

→Vers la gauche → Mode 4: Dessine un cercle de 2.5 cm de rayon selon le type de trait choisi (Mode_1 ou Mode_2)

  • Bouton Pause : Appuyer sur le bouton du joystick (hormis lors des dessins automatiques en mode_3 et 4), permet de mettre le stylo en position haute et donc de déplacer le stylo sans dessiner. Réappuyer sur le bouton permet de remettre le stylo ne position basse et de continuer le fonctionnement.
  • En dehors du mode 3 et 4, déplacer le joystick permet de déplacer le stylo librement.