Aller au contenu


Photo
- - - - -

Rattler :Voiture de course autonome pour la TRR2019 de retour en 2022


39 réponses à ce sujet

#21 Oracid

Oracid

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 6 019 messages
  • Gender:Male

Posté 30 septembre 2019 - 08:11

Pour détecter le portique, il me semble qu'une flagelle (de 1m), c'est ce qu'il y a de plus simple.
Et encore, la fixation et l'actionnement d'un switch, ce n'est pas forcement simple.
Bon courage.

#22 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 412 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 02 octobre 2019 - 04:27

Bon comme tout était assemblé, je n'avais plus qu'à taper quelques lignes de codes pour réaliser le premier essais de ce robot ... 

Et comme j'ai un couloir assez long chez moi, la piste d'essai était toute désignée... 

Voici donc la vidéo du tout premier essai réalisé en autonome, à vitesse minimale hard codé: 

Je crois que j'ai eu un peu de chance avec mes premiers réglages =)

 

Le capot de la voiture n'a pas été mis pour la vidéo car je vais encore travailler sur la voiture mais oui il sera mis à la fin ;)

 

 

Code qui a été fait pour le moment: 

J'ai combiné

 => mes explication donnée ici sur la réception des signal d'un radio commande et sur l'usage du pinchange interrupt pour avoir l'acquisition des 6 voies de ma radio en utilisant non pas un timer mais le pinchange interrupt sur le Port K ( de A8 à A13) , 

=> l'exemple de test du tf mini plus sur le Serial 1 et j'ai multiplié le code pour le faire aussi sur le serial 2 et le serial 3 afin de lire mes 3 distances 

=> Le fait de piloter un servo tout simple avec la lib servo.h qui me sert à piloter la direction et la vitesse de la voiture 

 

Contenu du code : 

 

Initialisation : 
Initialisation des pins 

initialisation des serial 

initialisation des interruptions 

 

en interruption : lecture de la radiocommande, 

 

Loop

lecture des distances 

Si channel radio reçu il y a pas trop longtemps

 si channel de controle du mode Automatique 

  modeAuto 

 sinon

  modeManuel 
Sinon 

 Arrêt

 

 

 

Le mode Auto est assez simple pour le moment : 

 

 direction = ( distanceGauche - distanceDroite)
 Si  (distanceMilieu >  distanceArrêt)
  vitesse = vitesseMinimum 

 sinon 
  Arret();
 

 

Dès que j'ai une solution pour m'arrêter à la fin du parcours je m'inscrit officiellement x) 
 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 


#23 Oracid

Oracid

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 6 019 messages
  • Gender:Male

Posté 02 octobre 2019 - 08:27

Bon, et bien, cela m'a l'air très bien.
Où en es-tu pour la détection du portique ?

#24 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 412 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 02 octobre 2019 - 10:16

Où en es-tu pour la détection du portique ?

 

Justement ... 

 

 

Dès que j'ai une solution pour m'arrêter à la fin du parcours je m'inscrit officiellement x) 
 

 

 

Pour le moment j'ai rien ...  Je pourrais mesurer le temps que met la voiture en moyenne pour faire le circuit ... Mais bon niveau fiabilité ... 

 

Une grande perche d'1m60 sur la voiture ... 

Il y a une couleur pour l'arrivée sinon ... 

Bref ... je cherche ...

 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 


#25 Oliver17

Oliver17

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 2 758 messages
  • Gender:Male
  • Interests:Glenn

Posté 03 octobre 2019 - 08:32

Et mettre un capteur de distance pointant vers le haut qui dit que lorsqu'il passe sous le portic (au bout d'un certains nombres de tours si nécessaire) et bien le véhicule stop.

En mettant un p'tit VL53L, 


signature_01.png -->

 

Mon Tipeee
 


#26 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 412 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 03 octobre 2019 - 08:48

Mettre un capteur de distance qui pointe vers le haut c'est exactement ce que je me suis résolu à faire ... D'où la question sur la largeur du portique pour savoir si il est suffisamment large pour qu'on puisse le détecter en passant dessous ... 

 

Advienne que pourra ^^ De toute façon j'ai pas le temps de faire autre chose ... J'espère que je vais réussir à pas me faire disqualifier x)
 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 


#27 Oracid

Oracid

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 6 019 messages
  • Gender:Male

Posté 03 octobre 2019 - 09:06

Le portique a une hauteur de 90cm. C'est un demi cercle. Sa largeur doit être d'environ 20cm.
Un de tes détecteurs laser devrait faire l'affaire.
Une temporisation sur un circuit de 110m est irréaliste.
C'est ce que je vais faire, mais pour 10m.

#28 Sandro

Sandro

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 1 082 messages
  • Gender:Male

Posté 03 octobre 2019 - 10:25

Une idée (pas testée) serait de mettre sur le robot un détecteur de champ magnétique (un simple capteur tout/rien suffit) entouré d'un peu de fer. Ensuite tu attache un aimant au bout d'une longue tige en bois que tu place verticalement sur le fer et le capteur : la tige sera maintenue par l'aimant, et quand tu passe sous le portique elle se fera arracher par l'impact et tu détecte ainsi la disparition de l'aimant.

 

Alternativement, si tu n'as pas de capteur magnétique en stock, un bouton poussoir bien placé peut aussi faire l'affaire.

 

La difficulté est d'avoir quelque chose d'assez solide pour que ça reste en place durant la course, mais pas trop pour que ça tombe à l'arrivée.

S'il n'est pas autorisé d'abandonner des pièces du robot, alors il suffit de rajouter une ficelle ou une charnière pour éviter de perdre la tige.



#29 Thot

Thot

    Membre passionné

  • Membres
  • PipPipPip
  • 305 messages
  • Gender:Male
  • Location:Toulouse
  • Interests:Artiste Roboticien, prendre les dernières techno et les mettre sur scène... telle est ma devise.
    Gestuelle et conscience artificielle.
    Bipédie et quadrupédie

Posté 03 octobre 2019 - 12:12

Attention, pendant la course, on passe deux fois sous le portique. Il faut compter et bien initialiser le comptage au départ (l'erreur fait que le robot s'arrête au bout de 10m...)

"Il n'y a rien de plus étrange pour l'homme que son image" RUR, Karel Capek
Caliban Midi - Art - Terroir et Robotique


#30 Sandro

Sandro

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 1 082 messages
  • Gender:Male

Posté 03 octobre 2019 - 12:25

bon, s'il faut passer 2 fois sous le portique, alors mon idée ne marche pas



#31 Oracid

Oracid

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 6 019 messages
  • Gender:Male

Posté 03 octobre 2019 - 06:59

Attention, pendant la course, on passe deux fois sous le portique. Il faut compter et bien initialiser le comptage au départ (l'erreur fait que le robot s'arrête au bout de 10m...)

C'est vrai que le départ se situe avant le portique et non pas sous le portique.
Je trouve ton idée quand même très intéressante.
La flagelle n'est pas obligée de s'arracher. Elle pourrait osciller autour d'un axe transversal et serait retenue par élastique.
Le détecteur pourrait ainsi se trouver à une position distante. Ce n'est pas toujours possible avec un interrupteur.

#32 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 412 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 06 octobre 2019 - 06:26

Pour ceux qui n'ont pas pu voir la voiture en directe, voici quelques photo de la version finale de mon robot qui a été nommé Rattler pour l'occasion au vu des Autocollants qui étaient sur le chassis ^^ 

Avec la coque : 

 

20191006_182057.jpg

20191006_182146.jpg

Sans la coque : 

20191006_182536.jpg

 

20191006_182502.jpg

On remarquera donc le quatrième TF Mini plus qui a été ajouté à l'arrière du robot et qui permet de détecter le portique : ça marche super bien !  Au final j'ai eu plus de mal à régler " l'autopilote " qu'à valider la détection du portique. 

 

Aucune impression 3D n'a été effectuée, la chance à fait que le capteur rentrait pile poile dans le trou disponible et l'aileron arrière le maintenant parfaitement en place ... 

 

Par contre attention : Si vous souhaitez utiliser 4 TF mini sur une arduino, et si vous décidez de brancher un TF mini sur les pins RX et TX de votre arduino il vous faudra choisir une petite astuce ... Voir le sujet sur le test du TF Mini plus   Il est aussi possible d'utiliser un softSerial pour contourner ce problème ...  

Pour ma part afin de régler le problème  j'ai décidé de brancher uniquement le pin TX du TF mini plus sur le pin RX de l'arduino en passant par un interrupteur. Il me faut donc d'abord allumer le robot puis une fois qu'il est bien allumé basculer l'interrupteur pour connecter le TF Mini plus à l'arduino.  De même pour programmer l'arduino il me suffit d'appuyer sur cet interrupteur pour déconnecter le TF mini plus. 

 

Petite photo de l'interrupteur qui a été ajouté :

20191006_185740.jpg
 

C'est un interrupteur " très gros " pour le besoin ... Cela aurait parfaitement fonctionné avec un interrupteur miniature ou avec ce petit interrupteur  . Mais si j'ai choisi le plus gros, c'est surtout pour qu'il soit pratique à basculer sans le voir et qu'il y avait une place parfaitement adaptée à se taille ... 

 

On remarquera aussi le câble usb  AB de programmation, rangé dans la voiture, déjà câble sur l'arduino, prêt à être dégainer pour reprogrammer la voiture sans avoir à ouvrir le châssis. 

 

On ne le voit pas mais j'ai changé le servomoteur de la voiture d'origine par un servomoteur plus puissant et surtout plus rapide, car le servomoteur d'origine était un peu lent ... 

 

Concernant le résultat, bien que la mécanique ( avec changement de servomoteur ) était correcte et que l'électronique était au point et fiable,  j'ai manqué de temps pour la partie programmation, et surtout le " réglage de l'autopilote " . 

Mon meilleur temps fut de 1m06s pour les 110m là où le meilleur à réussi à le faire en 23s66" ... J'ai donc encore de gros progrès à faire. 

 

Voici la structure du code que j'ai utilisé et que vous pouvez réutiliser sur un projet similaire  : 

 

// Code réalisé par Mike118 de Robot Maker dans le cadre de la Toulouse Robot Race 2019
// Ce code est prévu pour une arduino méga car necessite plusieurs ports série 
// L'arduino méga contrôle une voiture de course radio commandée équipée d'un servomoteur pour la direction 
// et d'un driver de moteur brushless se pilotant comme un servomoteur pour gérer la vitesse 
// Une radio commande 6 voie standard est branchée sur les pins A8 à A13 
// 4 TF Mini plus sont branchés sur les 4 ports séries de l'arduino mega pour surveiller la présence d'obstacle en haut à gauche à droite et au milieu
// Le capteur du haut est branché sur le serial 0 en passant par un interrupteur 
// => L'arduino doit être allumée avant de connecter le TF mini sur le serial 0 avec l'interrupteur sinon l'arduino ne demarre pas
// => De même pour programmer l'arduino le TF mini ne doit pas être connecté sur le serial 0 sinon vous ne pourrez pas téléverser votre code
// Le tf mini regardant à gauche est branché sur le Serial 1, celui à droite sur le Serial 2 et celui du milieu est branché sur le sérial 3. 
// Le départ du mode autonome se fait avec le channel 2 de la radio commande 
// l'arret du mode autonome se fait par la detection d'un portique par le capteur du haut
// Un mode manuel permet de contrôler la voiture avec les channels radio 0 et 1 
// Pour plus d'info sur la Toulouse Robot Race : http://toulouse-robot-race.org/

#include <Servo.h>

#define SPEEDPIN 6      // Pin de controle du driver qui gère la vitesse commandé comme un servomoteur 
#define SPEEDMIN 1000   // Valeur en microsecondes permettant d'aller à fond en marche arrière 
#define SPEEDMAX 2000   // Valeur en microsecondes permettant d'aller à fond en marche avant 

#define DIRPIN 7        // Pin de controle du servomoteur de direction  
#define DIRMIN 600      // Valeur en microsecondes permettant de braquer à fond pour aller à droite
#define DIRMAX 2500     // Valeur en microsecondes permettant de braquer à fond pour aller à gauche

Servo speedControl;
Servo dirControl;

// RC INPUT
#define NBCHANNEL 6                   // nombre de channel de radiocommande
#define NEUTRE 1480                   // valeur du neutre de la radiocommande 
#define DIVISEUR 5                    // valeur pour remettre à l'echelle de -100 à 100 les temps reçu de la Radiocommande 
#define PORTMASK 0b00111111           // Masque permettand de définir les pins connectés à la radio 
#define PORTOFSET 0                   // Offset de pins sur le port 
#define TIMEOUT 50                    // sécurité : coupe le robot si pas de signal radio pendant 50 ms
volatile uint16_t channel[NBCHANNEL]; // Stock les temps de la radiocommande
volatile bool signalRadio = false;    // booleen indiquant qu'un signal radio a été reçu
uint32_t reftimeout = 0;              // dernière fois qu'on a reçu un signal radio 

// Distances en cm fournies par le TF Mini Plus 
uint16_t distanceGauche = 0;
uint16_t distanceDroite = 0;
uint16_t distanceMilieu = 0;
uint16_t distanceHaut = 0; 

bool isEndRun = false;
bool isAutoMode = false;

#define NBPASSAGE 1                      // nombre de fois où le robot doit passer sous le portique 
uint8_t npassage = 0;                    // nombre de passage sous l'arche 
uint32_t momentDetectionPortique = 0;    // dernière fois où on est passé sous le portique

// Setter 

void setSpeedControl(int speedValue){
  speedValue = constrain(speedValue, -100, 100);
  speedControl.writeMicroseconds(map(speedValue, -100, 100, SPEEDMIN, SPEEDMAX));
}

void setDirControl(int dirValue){
  dirValue = constrain(dirValue, -100, 100);
  dirControl.writeMicroseconds(map(dirValue, -100, 100, DIRMAX, DIRMIN));
}

// Getter 

// Retourne un signal compris entre -100 et 100 pour chaque channel radio
int getCommande(uint8_t i) {
  if(i < NBCHANNEL )  
    return constrain((int)(channel[i] - NEUTRE)/DIVISEUR, -100, 100);  // simple formule pour transformer les temps radio reçu en valeur comprise entre  -100 et +100   
  else 
    return 0; 
}


// Fonction d'initialisation du Pin Change Interrupt sur le pin donné
void pciSetup(uint8_t pin)
{
    *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin));   // enable
    PCIFR  |= bit (digitalPinToPCICRbit(pin));                    // nettoyage des interruption
    PCICR  |= bit (digitalPinToPCICRbit(pin));                    // activation de interruption du groupe
}
 

ISR (PCINT2_vect) {                                     // ISR lié au port K ( PIN A8 to A15)
 static uint8_t oldetat = 0;                            // variable qui stock l'ancien état des pins de la radio sur le port K 
 static uint32_t startValue[NBCHANNEL] = {0};           // variable qui stock le temps de départ de chaque channel 
 uint8_t etatcourant = PINK & PORTMASK;                 // état courant des pins RC on met à jour tous les channels d'un coup en lisant le port complet et on met à 0 les bits lus des channels non utilisés
 if(etatcourant != oldetat) {                           // on regarde si il y a un changement entre le courant et le précédent
  uint32_t tempsUs = micros();                          // on enregistre le temps en microseconde
  signalRadio = true;                                   // On met à jour le bouléen indiquant que le signal radio est mis à jour
  
  for( uint8_t i = PORTOFSET; i < NBCHANNEL + PORTOFSET; i++) {  // pour chaque channel
   bool val = etatcourant >> i & 1;                              // on regarde l'etat actuel de ce channel
   bool old = oldetat >> i & 1;                                  // on regarde l'ancien état de channel 
   if( val != old){                                              // changement sur ce channel? 
    if(val) startValue[i] = tempsUs;                             // si oui : rising ? => on enregistre le temps start pour ce channel
    else channel[i] = tempsUs - startValue[i];                   // sinon c'est un falling => On enregistre le temps depuis le rising de ce channel 
   }  
  }
  oldetat = etatcourant;                                         // on stock l'état actuel dans l'état courant. 
 }
}

 
void setup() {  

  // initialisation de la direction et de la vitesse à 0 
  speedControl.attach(SPEEDPIN);
  setSpeedControl(0);
  dirControl.attach(DIRPIN);
  setDirControl(0);
  
  // intitialisation des ports série 
  Serial.begin(115200);
  Serial1.begin(115200);
  Serial2.begin(115200);
  Serial3.begin(115200);
  
  // initialisation des pins d'interruption de la radiocommande 
  for (int i = A8 + PORTOFSET; i < A8 + PORTOFSET + NBCHANNEL; i++) {  //
      pinMode(i,INPUT);          // même si par default c'est en entré on met le pin en entré pour que ça soit bien clair.
      pciSetup(i);               // activation de l'interruption 
  }

}
 
 
void loop() {
  
  // Lecture des TF Mini
  distanceHaut = readTFMini0();
  distanceGauche = readTFMini1();
  distanceDroite = readTFMini2();
  distanceMilieu = readTFMini3(); 

  // Traitement de la radio
  if(signalRadio) {                 // Si signal radio reçu
   if(getCommande(2) < 0) {         // commande pilotant le mode manuel 
    modeManuel();                   // on exécute le mode manuel 
    isAutoMode = false; 
   } else isAutoMode = true;       // sinon c'est qu'on lance le mode autonome        
   reftimeout = millis();          // on actualise la reference pour le timeout
   signalRadio = false;            // on remet à 0 le booléen Radio
  } else if (millis() - reftimeout > TIMEOUT ) // perte du signal radio 
    setSpeedControl(0);

  // Gestion de l'auto pilote et de l'arrêt par détection du portique 
  if(isAutoMode) {   // si on est en mode autonome
   if( distanceHaut > 70 && distanceHaut < 160 && (millis()- momentDetectionPortique) > 3000 ) {  // si on détecte le portique et qu'on l'a pas détecté dans les 3 dernières secondes 
      momentDetectionPortique = millis();                                                         // on enregistre le moment de la détection, permet d'éviter de détecter plusieurs fois le portique 
      npassage ++;                                                                                // on compte le nombre de fois qu'on a passer le portique 
      if(npassage > NBPASSAGE) {                                                                  // si on dépasse le nombre de fois qu'on doit passer sous le portique
        isEndRun = true;                                                                          // fin du run il faudra réinitialiser l'arduino pour relancer un run
        setSpeedControl(0);                                                                       // On met la vitesse à 0 
      }
    }
    if(isEndRun == false) modeAuto();     // si on est pas à la fin du run on lance le pilotage autonome
    else setSpeedControl(0);              // sinon on s'arrête 
  }
  
}

void modeAuto() {
  int autoAngle = 0;
  int autoSpeed = 0;
  
  // "add your magic here" 
  // modifier autoAngle et autoSpeed en fonction de 
  // distanceGauche distanceDroite distanceMilieu
  
  setDirControl(autoAngle);
  setSpeedControl(autoSpeed);

}

// Pilotage de la voiture en fonction des channel 0 et 1 de la radioCommande 
void modeManuel() {
 setDirControl(getCommande(0));  
 setSpeedControl(getCommande(1)); 
}

// Fonctions de réception des valeurs de TF Mini 

uint16_t readTFMini0() {
 uint8_t current;
 static uint8_t n = 0;
 static uint8_t sum = 0;
 static uint16_t distance = 0;
 static uint16_t distanceOut = 0;
 
 while(Serial.available()) {
  current = Serial.read();

  switch(n) {

   case 0:
    if(current == 0x59) {
     sum += current;
     n++;
    }
    break;

   case 1:
    if(current == 0x59) {
     sum += current;
     n++;
    } else
     n = 0;
    break;

   case 2:
    distance = current;
    sum += current;
    n++;
    break;

   case 3:
    distance += current << 8;
    sum += current;
    n++;
    break;

   case 4:
    sum += current;
    n++;
    break;

   case 5:
    sum += current;
    n++;
    break;

   case 6:
    sum += current;
    n++;
    break;

   case 7:
    sum += current;
    n++;
    break;

   case 8:
    if(sum == current)
      distanceOut = distance;
    sum = 0;
    n = 0;
    break;

  }
 }
 return distanceOut;  //  retourne toujours la dernière bonne valeur reçue.
}

uint16_t readTFMini1() {
 uint8_t current;
 static uint8_t n = 0;
 static uint8_t sum = 0;
 static uint16_t distance = 0;
 static uint16_t distanceOut = 0;
 
 while(Serial1.available()) {
  current = Serial1.read();

  switch(n) {

   case 0:
    if(current == 0x59) {
     sum += current;
     n++;
    }
    break;

   case 1:
    if(current == 0x59) {
     sum += current;
     n++;
    } else
     n = 0;
    break;

   case 2:
    distance = current;
    sum += current;
    n++;
    break;

   case 3:
    distance += current << 8;
    sum += current;
    n++;
    break;

   case 4:
    sum += current;
    n++;
    break;

   case 5:
    sum += current;
    n++;
    break;

   case 6:
    sum += current;
    n++;
    break;

   case 7:
    sum += current;
    n++;
    break;

   case 8:
    if(sum == current) 
      distanceOut = distance;
    sum = 0;
    n = 0;
    break;

  }
 }
 return distanceOut;  //  retourne toujours la dernière bonne valeur reçue.
}


uint16_t readTFMini2() {
 uint8_t current;
 static uint8_t n = 0;
 static uint8_t sum = 0;
 static uint16_t distance = 0;
 static uint16_t distanceOut = 0;
 
 while(Serial2.available()) {
  current = Serial2.read();

  switch(n) {

   case 0:
    if(current == 0x59) {
     sum += current;
     n++;
    }
    break;

   case 1:
    if(current == 0x59) {
     sum += current;
     n++;
    } else
     n = 0;
    break;

   case 2:
    distance = current;
    sum += current;
    n++;
    break;

   case 3:
    distance += current << 8;
    sum += current;
    n++;
    break;

   case 4:
    sum += current;
    n++;
    break;

   case 5:
    sum += current;
    n++;
    break;

   case 6:
    sum += current;
    n++;
    break;

   case 7:
    sum += current;
    n++;
    break;

   case 8:
    if(sum == current)
      distanceOut = distance;
    sum = 0;
    n = 0;
    break;

  }
 }
 return distanceOut;  //  retourne toujours la dernière bonne valeur reçue.  
}


uint16_t readTFMini3() {
 uint8_t current;
 static uint8_t n = 0;
 static uint8_t sum = 0;
 static uint16_t distance = 0;
 static uint16_t distanceOut = 0;
 
 while(Serial3.available()) {
  current = Serial3.read();

  switch(n) {

   case 0:
    if(current == 0x59) {
     sum += current;
     n++;
    }
    break;

   case 1:
    if(current == 0x59) {
     sum += current;
     n++;
    } else
     n = 0;
    break;

   case 2:
    distance = current;
    sum += current;
    n++;
    break;

   case 3:
    distance += current << 8;
    sum += current;
    n++;
    break;

   case 4:
    sum += current;
    n++;
    break;

   case 5:
    sum += current;
    n++;
    break;

   case 6:
    sum += current;
    n++;
    break;

   case 7:
    sum += current;
    n++;
    break;

   case 8:
    if(sum == current) 
        distanceOut = distance;
    sum = 0;
    n = 0;
    break;

  }
 }
 return distanceOut;  //  retourne toujours la dernière bonne valeur reçue.
}



// Fonctions utilitaires de debuggage pour vérifier qu'on reçoit bien des valeurs cohérentes : 

void displayChannel() {
 for(uint8_t i = 0; i < NBCHANNEL; i++) {
  for(uint8_t j = 0; j < i; j++) {
   Serial.print("===");
  }
  Serial.println(getCommande(i));
 } 
 Serial.println("");
}

void displayTfMini() {
   Serial.print(F("Time : "));
   Serial.println(millis());
   Serial.print(F(" Gauche : "));
   Serial.println(distanceGauche);
   Serial.print(F("Milieu : "));
   Serial.println(distanceMilieu);
   Serial.print(F("Droite : "));
   Serial.println(distanceDroite);
   Serial.print(F("Haut : "));
   Serial.println(distanceHaut);
   Serial.println("");
}

Il vous faudra bien entendu compléter  la fonction " modeAuto() " avec votre propre algorithme de pilotage automotique.  A vous de faire des essais ;)  


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 


#33 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 412 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 06 octobre 2019 - 06:41

Quelques conseils en vrac pour ceux qui souhaiteraient participer à la toulouse robot race :  

 

=> Si le but c'est de chercher à la performance, choisir des capteurs fiable en extérieur  Comme par exemple le TF Mini plus  : pas besoin d'en avoir 4, il est possible d'en utiliser que 3 voir même 2 ...   

 

=> Avoir un robot "accessible" / facile à manipuler : Prévoir de pouvoir facilement reprogrammer ou changer la batterie sans avoir à tout démonter

 

=> Prévoir quelques pièces de rechanges ( perso je n'en ai pas eu besoin mais Oracid a eu quelques soucis de servomoteurs par exemple )

 

=> Monitorer l'état de sa batterie et avoir 2 batteries avec une alarme pour lipo ( Un concurrent a eu sa batterie de morte car trop déchargée sans être monitorée ... ) et mettre en charge sa batterie dès que vous la changez. 

=> Ajouter des roulettes de protection sur les côtés pour pouvoir gentiment frotter sur le bord en toute sécurité. 

 

=> Avoir un protocole simple pour lancer le robot.

 

=> Avoir un arrêt d'urgence sans fil ... Pratique pour arrêter les robots rapide ... 

=> Avoir un bouton d'arrêt d'urgence physique ... 

 

=> Une coque de protection peut aider à protéger le robot de l'eau si il pleut par exemple ... 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 


#34 Oracid

Oracid

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 6 019 messages
  • Gender:Male

Posté 07 octobre 2019 - 05:17

J'ajouterais que les tests sont très importants.
A chaque essai/test, Mike progressait de 10" à chaque fois, ce qui est énorme.
Donc, venir le jour même au lieu de la veille, n'est pas un bon plan.

#35 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 412 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 17 septembre 2022 - 09:44

Bon vu que la TRR 2022 se rapproche   je ressort Rattler du placard... Je vais en profiter pour faire quelques modifications, la première, je ne sais pas si elle sera très utile ou pas c'est de lui ajouter une carriole à l'arrière : 

Ci joint quelques photo : 
20220703_232117.jpg

20220703_232242.jpg

20220703_232325.jpg

 

Comme vous pourrez le constater la carriole est équipée de roues montées sur des codeurs et est montée sur des roulements qui grâce à la gravité devraient permettre de faire en sorte que les roues touchent toujours le sol. 
 

 

J'ai utilisé un peu d'impression 3d , 4 roulements 3mm avec collerettes , 2 encodeurs , 2 roues pololu 80mm . 
Le but va être d'utiliser les codeurs pour estimé le trajet parcourus sur la piste ... 

La moyenne des deux codeurs me donnera la distance linéaire approximativement parcourue, la différence des deux me diras si je roule droit ou pas ... Et je compte combiner cela avec une imu MPU9250 en utilisant uniquement la fonctionnalité gyromètre...


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 


#36 pat92fr

pat92fr

    Membre passionné

  • Membres
  • PipPipPip
  • 325 messages

Posté 17 septembre 2022 - 03:15

Je découvre ce thread. Très intéressant !

 

Sur la TT-01 de 2019 (Neunoiel), l'odométrie se basait sur un capteur à effet Hall et un aimant collé à la couronne de transmission. 

Pour estimer la distance parcourue, je comptais le nombre de tours (un par passage d'aimant). 

Pour estimer la vitesse instantanée, je mesurais la durée entre deux passages d'aimant.

La précision était correcte et le dispositif assez léger.



#37 Sandro

Sandro

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 1 082 messages
  • Gender:Male

Posté 18 septembre 2022 - 08:35

Avec des capteurs donnant une impulsion par tour, tu veux estimer la distance parcourue et à une idée approximative de la vitesse.

En revanche, avec des encodeurs optiques comme ceux de Mike, tu peux avoir 2400 signaux par tour. Si on arrive à faire en sorte que les roues sur lesquelles sont montées les encodeurs ne glissent pas, alors on est assez précis pour ne pas seulement calculer la distance parcourue, mais aussi l'orientation et la position du robot. Je penses que si on aligne parfaitement le robot au départ, et que les encodeurs ne glissent pas, il devrait même être possible de faire un tour de piste uniquement avec les encodeurs. (sur un projet scolaire, on mettait plusieurs minutes à atteindre les 1m d'erreur avec un robot roulant vers 20-30cm/s).

 

La grande difficulté, c'est de réussir à ce que les roues des encodeurs touchent en permanance le sol, et ne glissent jamais, pour ça :

- éviter si possible de placer les encodeurs sur les roues motrices (qui glissent très souvent)

- prévoir un système de "suspensions" pour s'assurer que les roues des encodeurs touchent toujours le sol (Mike a choisi d'utiliser la gravité pour pousser vers le bas (idem pour mon projet étudiant), et un pivot gauche/droite pour compenser les différences de hauteur entre la gauche et la droite (on avait deux systèmes indépendants, un à gauche du robot, l'autre à droite)).

- éviter tout glissement latéral des roues des encodeurs. Pour ça, l'idéal, c'est de mettre les encodeurs au niveau du centre de rotation du robot (on avait fait un robot à 6 roues, 4 motrices, et les 2 du milieu pour les encodeurs). Pour une navigation générale, placer les encodeurs à l'arrière est un mauvais choix (en particulier si le robot peut tourner sur place, dans quel cas les codeurs glisseraient latéralement sans tourner). Dans le cas de Mike, ce dernier point est moins critique, premièrement car le robot est de type "avance + direction" au lieu de "vitesse gauche+vitesse droite", ce qui empêche de tourner sur place. De plus, le robot avancera beaucoup plus vite qu'il tournera, ce qui devrait minimiser les glissements. Et vu que monter les encodeurs au milieu du robot aurait été plus compliqué, je comprends le choix de Mike. Pour les vrais dérapages, de toute façon, il n'y a pas de solution

 

Autres astuces :

- placer les encodeurs le plus éloignés possible l'un de l'autre (ie l'un le plus à gauche possible, l'autre le plus à droite possible, plutôt que de les mettre vers le milieu) : ça permet d'avoir plus de tours d'encodeurs lors des virages, donc d'augmenter la précision de l'orientation.

- si on veut le maximum de précision, il faut un micro-controleur avec 4 entrées interruptions (par exemple une arduino mega, mais pas une Uno qui n'en a que 2). Avec seulement 2 entrées d'interruptions, ça marche aussi, mais on perd la moitié des signaux

- utiliser des roues avec un bon grip (j'aurais pris des roues avec un revêtement en "caoutchouc" synthétique bien adhérent plutôt que des roues "crantées")



#38 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 412 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 18 septembre 2022 - 11:46

Vu que des gens s'intéressent à ce thread, je me dis que je vais pouvoir compléter un peu mes propos,

 

Si on reprend point par point les points de Sandro pour les compléter en faisant un parallèle avec mon cas : 

=> Oui mon but c'est de pouvoir à la fois avoir une estimation de la distance linéaire parcourue, et si possible si c'est assez fiable de la position x y z du robot. 
Le sol de la mini TRR comme vu sur les photo présentes sur ce sujet sur la toulouse robot race 2022 semble s'y prêter beaucoup mieux que lors des précédentes compétitions ( Sol à peu près lisse indoor vs pavé extérieurs pas du tout lisse auparavant ) et donc ça devrait pouvoir être possible. J'espère pouvoir être capable de faire un tour de piste juste avec les codeurs ...

 

=> éviter de mettre le codeur sur les roues motrice, c'est exactement pour cette raison que j'ai fais le choix de les mettre sur des roues folles et pas directement sur le moteur ( en plus ça ne permettrait pas de faire la position x y z du robot ... ) ni sur les roues motrices ...

=> Réussir à ce que la roue codeuse ne glisse pas par rapport au sol / utiliser un système de suspension : Sandro a très bien résumé ma façon de faire et le pourquoi de mes deux axes de libertés, je rajouterais néanmoins un point : Si j'ai choisis de faire un système en un morceau plutôt que deux systèmes indépendants c'est pour limiter le nombre de pièce, faciliter l'assemblage ( qui s'est fait sur un espace de la voiture existant sans faire aucune modifications sur le châssis) et aussi maîtriser l'espacement entre les roues pour le garder " fixe ", ce paramètre est important dans le cadre de la mesure de l'angle parcourue par le robot. 
De plus en le faisant en une seule pièce c'est plus facilement " reproductible pour éventuellement l'accrocher sur différents robots " ou le tester " manuellement " sans la voiture. 


=> éviter tout glissement latéral : En effet il faut mettre les encodeurs sur l'axe de rotation du robot, et dans le cadre d'une voiture avance + direction comme mon robot, oui le point est moins critique car le robot ne peut pas tourner sur lui même, par contre si on regarde bien l'axe de rotation se trouve non pas au milieu du robot mais sur l'axe des roues arrières ( les roues avant pivotent pour diriger la voiture mais les roues arrièrent restent parallèles ) , du coup en théorie c'est pas au milieu de la voiture qu'il fallait mettre les codeurs ... 
Dans mon cas en plus de ne pas vouloir le faire en deux pièces, je ne voulais pas non plus que les roues folles dépasse de la largeur de la voiture ( afin de limiter la possibilité d'avoir des chocs sur les roues codeuses ) du coup mettre le bloc codeur à l'arrière de la voiture au plus proche des roues arrières était le moyen le plus optimisé respectant mes contraintes et en étant au plus proche de l'axe de rotation du robot ... Le décalage est j'espère suffisamment mineur pour ne pas affecter la précision ( surtout qu'il y a aussi un petit peut de jeu mécanique aussi mais pas sur roulement cette fois ci , qui devrait permettre d'aider à compenser ce petit décalage ) 

 

=> En effet je ne prévois pas de faire du drift, cela fausserait les calculs avec les codeurs, et cela résulterait surtout d'un défaut de maîtrise du véhicule, mais si cela devait arriver j'ai toujours des capteurs imu + télémètre qui devraient pouvoir me permettre de me recaler sur le chemin ...

 

 

=> concernant le fait d'éloigner les codeurs l'un de l'autre, en effet plus l'espacement est grand mieux c'est pour la précision du calcul angulaire pour mesurer l'orientation du robot. Du coup j'ai fait au plus grand que je pouvais qui restait entre les roues motrices arrières avec une marges suffisante pour s'assurer que ça ne taperait pas dans les roues motrices ... sachant que je ne voulais pas que les roues folles des codeurs dépassent sur les côté de la voiture

 

=> Concernant la précision de manière plus générale, oui il est plus intéressant d'utiliser les encodeurs en quadratures au complet pour augmenter la résolution totale exploitable seulement mentionner uniquement ce paramètre n'est pas suffisant : 

  • Il est tout à fait possible d'utiliser la résolution de deux codeurs en quadrature même sur un microcontrôleur qui n'a que 2 entrées interruptions comme une arduino uno, ou nano, il existe pour cela plusieurs astuces très différentes
    1) utiliser deux porte logique hardware xor  et utiliser 2 gpio de plus soit 6 gpio au lieu de 4 l'idée : le codeur droit est branchée sur un xor, le gauche sur un autre, les sorties du xor sont branchées sur les interruptions, dès qu'il y a un changement une interruption est déclenchée, et il suffit de récupérer l'état des deux codeurs associés pour faire le traitement, de préférence mettre toutes les broches des codeurs sur un même port pour faire une lecture directement sur un registre  (mais nécessite l'ajout hardware et consomme 2 broches )
    2) utiliser des interruptions software ( et donc on utilise de 4 gpio ) mais c'est parfois " lourd " en code si on creuse les librairies ...
    3) faire un code optimisé avec du pulling en continue de l'état de broches et ne pas utiliser d'interruption du tout ( il est très important de mettre toutes les broches sur un même port pour ce genre de chose 
  • Si on utilise que la moitié de la résolution maximale du codeur on peut toujours choisir un codeur avec deux fois plus de résolutions pour avoir le même résultat ( seul bémole c'est en général un peu plus cher ) 
  • C'est bien d'avoir beaucoup de résolution sur un codeur mais il faut avoir un mcu qui est capable de suivre la cadence en terme de fréquence ... Et cela se calcule et se vérifie ... Pour un arduino cadencé à 16Mhz, aller à des fréquences au delà de 1Mhz ne me semble pas indiqué ( j'ai jamais essayé d'aller à ce genre de fréquence d'acquisition sur un arduino ... )
  • Avoir trop de résolution, en plus de pouvoir être contre productif si on se rapproche de la fréquence du MCU peut être complètement inutile ... Si on veut une résolution au milimètre ça sert à rien d'avoir une résolution à 0.0001mm... en général il faut chercher à avoir une acquisition d'au moins 10x l'ordre de grandeur de la résolution de mesure souhaité... Si je veux une résolution au mm, il faut que ma mesure soit entre le dixième et le centième de mm ... Au delà c'est pas utile ... 

    Dans mon cas j'ai des roues de 80mm de diamètre avec 2400 ticks codeurs de résolution par tours de roues ( 2400 tick pour 251.2 mm parcourus ) ce qui me donne une résolution codeur d'acquisition proche de 0.1 mm ... Ce qui devrait me permettre d'avoir une résolution de mesure réelle aux alentours du mm. Ce qui devrait être bien plus que suffisant pour un robot qui est censé parcourir environ 100m et où le besoin réél de précision devrait être de l'ordre du cm ...  

    Concernant la fréquence d'acquisition, si on prend les champions qui font environ 100m en 20s, on est en moyenne à du 5000mm / s  (18 km/h ) sur nos deux codeurs, ce qui fait en arrondissant  2 * 50 000 ticks / s ( car on a deux codeurs et une résolution d'environ 0.1mm / ticks )  soit 100 000 ticks / s  en moyenne ... Au pire des cas si la vitesse max est de 4 fois la vitesse moyenne on se retrouve à des piques ) 400 000 ticks / secondes ... 400KHz  < 1Mhz  < 16Mhz , donc on peut supposer que même à pleine vitesse une arduino uno cadencée à 16 Mhz serait suffisante pour ce genre d'application ...  Il faudra bien entendu bien optimiser le code surtout lorsqu'on est à pleine vitesse ...  

    Pour en revenir sur cette vitesse max de pointe avec des acquisition de codeurs à 400Khz elle n'est même pas censé être atteignable par ma voiture pour plusieurs raison :
    72 Km/h sur une piste comme celle de la TRR c'est beaucoup trop, même en pointe dans la ligne droite... la piste n'est pas si large et il faut freiner après ... 
    69 Km/h c'est la vitesse max qui a été mesurée par un utilisateur qui a la même voiture que moi en étant en configuration de batterie 3S ... or moi je suis en 2S (pour le moment ) et dans cette configuration 2S le même utilisateur à mesurer une pointe de vitesse à 51 Km/h 
     
    Et quand on voit comment la voiture bouge à cette vitesse c'est pas super rassurant pour une piste de la largeur de la TRR :P 
    Si déjà j'arrive à aller lors de ma vitesse de pointe en ligne droite aux alentours de 30km/h je serais je pense déjà content :P 

    En conclusion je pense que le choix technique est plutôt bon au vu du besoin  =) Du moins de ces deux points de vues.

=> Concernant le grip, les roues pololu que j'ai pris ont un pneu en silicone qui offre un grip de très bonne qualité ! Les crans sont très petits et ne gênent pas au contraire, je dirais que si on regarde d'un point de vu microscopique la légère déformation de ces crans augmente légèrement la capacité du grip des roues. ( C'est un peu le même principe que la déformation d'une roue gonflable augmente son adhérence de par l'augmentation (légère) de sa surface de contact. 

 

=> Autre points qui ont pas forcément été évoqués : un des inconvénients de ma solution : Son poids, je l'ai pas pesé, c'est pas si lourd, mais c'est toujours plus qu'une solution comme celle de path92, en plus le risque de casse est plus élevé... Enfin je ne sais pas comment ça va se comporter mon système de "suspension " à pleine vitesse ... Si les roues se décollent du sol le système deviendrait inutile ... Mais j'espère que je n'aurais pas ce problème.

 

Bon après bien entendu, j'ai aussi fait par rapport à ce que j'avais en stock sur la boutique robot maker et je reste curieux de connaître vos avis et remarques sur le sujet =)
 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 


#39 Oracid

Oracid

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 6 019 messages
  • Gender:Male

Posté 19 septembre 2022 - 06:57

je reste curieux de connaître vos avis et remarques sur le sujet =)

Si je devais faire un suiveur de ligne roulant, avec les compétences que toi, Thot et Pat avez, je m'inspirerais de ça, https://www.robot-ma...ylens/?p=115247

Pour 2022, c'est un peu tard, mais pour 2023 . . .



#40 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 412 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 19 septembre 2022 - 07:53

Si je devais faire un suiveur de ligne roulant, avec les compétences que toi, Thot et Path avez, je m'inspirerais de ça, https://www.robot-ma...ylens/?p=115247

Pour 2022, c'est un peu tard, mais pour 2023 . . .

 

Tu as pas forcément exactement les même compétences que nous mais tu es largement au moins sur la même ligne que nous ;)  et voir même plus avancé sur certains points grâce à ton grand nombre d'itérations ;)
Savoir faire simple est un art, et tu es plutôt bon dedans ;) Tes réalisations sont super ! =)

Après il y a une grosse différence entre les " voitures de courses " comme celles de pat et moi, et les robots pcb des méxicains du lien que tu donnes ...

On est dans deux catégories différentes où le dimensionnement est loin d'être le même,  à la base nos voitures ce sont des robots qui ont été fait pour la TRR en extérieur avec son sol en pavé ...  et pas forcement pour la TRR mini avec son sol lisse ...

Le sol super lisse est complètement noir comme sur la compétition des suiveurs de ligne que tu as indiqué ce sont des conditions très différentes et beaucoup plus " maîtrisées " / "gentilles " que les conditions de la TRR ... 

Ensuite même si les robots de cette compétitions sont rapide je pense que nos voitures de courses peuvent physiquement aller beaucoup plus vite que les robots pcb ... 

Quoi qu'il en soit ça ne retire rien à la qualité des robots mexicains et oui il y aurait quand même des points d'inspiration à prendre
=> Le suivi de ligne au lieu du suivi de bordure avec 3 capteurs  ( mais potentiellement plus délicat dans le cadre de la TRR )
=> Le modèle 2WD au lieu du stear drive comme nos voiture de course ( qui à l'avantage de permettre de pouvoir faire de virages plus serrés mais on en a pas forcément besoin dans la TRR, pas de virage en épingle / pas besoin de tourner sur soit même )


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 




Répondre à ce sujet



  


0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users