Catégorie:RobotGEII

De troyesGEII
Aller à : navigation, rechercher


Description et présentation du Projet

Présentation du championnat



Le concours de robotique des IUT GEII est une compétition organisée par l'IUT de Cachan. Cette rencontre a plusieurs objectifs qui supplantent la partie compétitive :

                - La mise en œuvre des compétences des étudiants
                - La promotion de l'IUT GEII et des études techniques en générale
                - Un échange entre étudiants et avec les enseignants

L'état d'esprit de la compétition se veut être conviviale et favorise le fair-play.

Règle du jeu



Les robots seront placé sur une piste carré de 8m x 8m,recouverte de moquette bleue marine sur laquelle serons placés des obstacles de 15cm de haut.Les robots serons placés chacun dans un coin, l'objectif est de traverser le plus rapidement possible la piste d'un coin à son opposé en évitant les obstacles (qui changerons de positions à chaque manche) ainsi que les collisions avec les autres robots (ils doivent impérativement se contourner par la droite). Les robots ont 90 secondes pour réaliser leurs leurs objectif, au delà de ce délais, la manche s’arrête.

Structure du robot



le règlement détaillé est disponible ici:

http://www.gesi.asso.fr/coupe_robotique_des_iut/images/2016/reglement_Robot_2016_V003.pdf


Mécanique


Le robot sera construit à partir d’un kit imposé par le comité d’organisation, comprenant le châssis (support métallique en U), les moteurs, les roues, les engrenages et la batterie. Les parties liées à la motorisation ne doivent pas être modifiées. La batterie peut être remplacée à l’identique.

Média:Nouveau_chassis.zip

http://www.vgies.com/robot-iut-bot-base-mobile/


Design


Le design est libre : il donnera lieu à un prix du design, indépendamment de la course. La coque en plastique moulé blanc n’est pas obligatoire.


Alimentation


Le robot sera autonome en énergie. Il utilise obligatoirement la batterie 12 V 1.2 Ah au plomb gélifié fournie pour la partie motorisation. L’alimentation reste libre pour la partie commande.

Arrêt d'urgence


L’arrêt d’urgence fourni doit être opérationnel, rester facilement accessible et impérativement couper la partie puissance.

Prise jack


l'organisation fourni un jack de départ, il devra obligatoirement être utilisé  : au top départ, un étudiant de l’équipe le retire, permettant au robot de s’élancer.

Dimensions


Les dimensions maximales sont les suivantes; hauteur 30 cm, largeur 30 cm, longueur 40 cm. Le dispositif destiné à faire éclater le ballon ne peut sortir du gabarit que dans la zone d’arrivée. Le tube destiné à porter le ballon de couleur n'est pas a prendre en compte dans la taille du robot, c'est la seule exception.

Ballon


Chaque coin est identifié au moyen d’une couleur. Chaque robot en course porte un ballonde la même couleur que son coin d’arrivé. Le ballon est fourni. Il mesure au moins 10 cm de diamètre lorsqu’il est donné à l’étudiant qui a en charge de démarrer le robot. Le robot doit être doté d’un tube vertical dont l’extrémité haute est situé entre 30 cm et 31 cm au dessus de la moquette pour servir de support au ballon. Le robot doit être doté d’un dispositif d’accrochage à la base du ballon dans les 5 derniers centimètres du tube. Le ballon sera mis en place par l’étudiant en charge de démarrer le robot.

Indicateur d'arrivée


Lorsque le robot est arrivé à sa zone d’arrivée, il doit s’arrêter puis, une fois totalement arrêté faire éclater son ballon. C’est à l’instant précis où, alors qu’il est arrêté au dessus de sa zone d’arrivée et que son ballon éclate que l’arrivée est considérée comme validée. Un robot qui éclate son ballon ou qui déploie le système destiné à crever son ballon sans être arrivé ou avant d’être complètement immobile ne marquera aucun point quelque soit son rang.

Carte ultrason (Alexandre.N)

programme de test des capteurs US :

int trig = 36;
int echo = A9;
long lecture_echo;
long cm;


void setup()
{
  pinMode(trig, OUTPUT);
  digitalWrite(trig, LOW);
  pinMode(echo, INPUT);
  Serial.begin(9600);
}

void loop()
{
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  lecture_echo = pulseIn(echo, HIGH);
  cm = lecture_echo / 58;
  Serial.print("Distance : ");
  Serial.print(cm);
  Serial.println(" cm");
  delay(100);
}



programme final des capteur US :

#include <util/delay.h>
#define distUSmini 30

/*  _Trigger_
    37 - PC0
    36 - PC1
    35 - PC2
    34 - PC3
    33 - PC4
    32 - PC5
    31 - PC6

    _Echo_
    8 - PK0
    9 - PK1
    10 - PK2
    11 - PK3
    12 - PK4
    13 - PK5
    14 - PK6
*/


boolean toggle1 = 0;
volatile unsigned long t[8];
unsigned long tfin, tdebut, d;
volatile boolean recpt;
volatile boolean newmesure = false;
volatile char numCapt;
volatile uint8_t USmode;


void setup() {
  Serial.begin(115200);

  pinMode(37, OUTPUT);
  pinMode(36, OUTPUT);
  pinMode(35, OUTPUT);
  pinMode(34, OUTPUT);
  pinMode(33, OUTPUT);
  pinMode(32, OUTPUT);
  pinMode(31, OUTPUT);

  cli();
  TCCR2A = 0;
  TCCR2B = 0;
  OCR2A = 156;
  TCCR2B |= (1 << WGM12);
  TCCR2B |= (1 << CS11);
  TCCR2B |= (1 << CS10);
  TCCR2B |= (1 << CS12);
  TIMSK2 |= (1 << OCIE1A);
  PCICR |= 1 << PCIE2;
  sei();
}


ISR(TIMER2_COMPA_vect)
{
  static boolean start = true;

  if (start == true)
  {
    if (USmode == 0) numCapt = 7;
    if (USmode == 1) numCapt = 0;

    if (numCapt != 7) //mode1
    {
      numCapt++;
      if (numCapt == 2) numCapt = 0; //à retirer quand 7 capteurs
    }
    TCCR2B &= ~((1 << CS12) | (1 << CS10));
    OCR2A = 150;
    if (numCapt == 7) // mode0
    {
      PORTC = 0b01111111;
      PCMSK2 = 0b01111111;
    }
    else
    {
      PORTC = 1 << numCapt;
      PCMSK2 = 1 << numCapt;
    }
  }
  else
  {
    PORTC = 0;
    recpt = false;
    TCCR2B |= ((1 << CS12) | (1 << CS10));
    OCR2A = 30;
  }
  start = !start;
}

ISR(PCINT2_vect)
{
  if (recpt == false)
  {
    tdebut = micros();
    recpt = true;
  }
  else
  {
    tfin = micros();
    if ((tfin - tdebut) > 50)
    {
      t[numCapt] = tfin - tdebut;
      recpt = false;
      newmesure = true;
    }
  }
}

void loop() {
  setUSmode(0);
  static unsigned long dateAffichage = 0, dateActuelle;
  dateActuelle = millis();
  if (newmesure == true)
  {
    //t = tfin - tdebut;
    if ((dateActuelle - dateAffichage) > 200)
    {
      //if
      dateAffichage = dateActuelle;
      //d = t / 58;
      Serial.print("Duree 0: ");
      Serial.print(t[0], DEC);
      Serial.println(" us.");
      Serial.print("Duree 1: ");
      Serial.print(t[1], DEC);
      Serial.println(" us.");
      Serial.print("Duree 2: ");
      Serial.print(t[2], DEC);
      Serial.println(" us.");
      Serial.print("Duree 3: ");
      Serial.print(t[3], DEC);
      Serial.println(" us.");
      Serial.print("Duree 4: ");
      Serial.print(t[4], DEC);
      Serial.println(" us.");
      Serial.print("Duree 5: ");
      Serial.print(t[5], DEC);
      Serial.println(" us.");
      Serial.print("Duree 6: ");
      Serial.print(t[6], DEC);
      Serial.println(" us.");
      Serial.print("Duree 7: ");
      Serial.print(t[7], DEC);
      Serial.println(" us.");
    }
    newmesure = false;
  }
}

void setUSmode(uint8_t mode)
{
  if (mode == 0) {
    USmode = 0;
    //numCapt=7;
  }
  if (mode == 1) {
    USmode = 1;
    //numCapt=0;
  }

}

Capteur US.jpg

Carte gestion des moteurs (Johan)

Carte Moteur

Cette carte permet la transmission des commandes de l'arduino aux deux moteurs. Elle traduit les signaux envoyer par la carte arduino pour les deux moteurs. Cette carte est un module HG7881CP Stepper 2-Channel DC Motor Driver. Il coûte environ 3.5 euros.

Modmot.jpg


En connectant cette carte au moteur et à l'arduino, on a pu piloter les moteurs et les calibrer. En effet, les moteurs n'ont pas exactement le même couple. Il faut donc trouver leurs vitesses minimales et maximales pour les calibrer. On a ainsi les même vitesses sur les deux moteurs.

Voici un programme qui fait faire une ligne droite au robot :

Fichier:Prog 4.zip

Carte Alimentation

Cette carte fait le lien entre la batterie et le reste du robot. Elle est composée de deux modules. On les a ajusté différement :

                  - Un transformateur 12V-5V
                  - Un régulateur de 12V

Voici un module :

Module.JPG





Le but recherché est de pouvoir alimenter la carte arduino, les autres cartes et les moteurs. De plus, cette solution est assez simple à mettre en place et peu coûteuse (environ 2euros/module).

Carte ultrason (Vincent)

Presentation

La carte ultrason joue un rôle essentiel dans les déplacements de notre robot, elle est chargée de détecter les obstacles de manière précise et rapide afin d'informer le robot sur leur position pour qu'il puisse réagir et les éviter. Pour détecter les obstacles nous utilisons le module HC-SR04 permettant l'acquisition d'une information de distance.

HC-SR04.jpg

  • Présentation du module HC-SR04 : Le HC-SR04 est un module ultrason permettant l'évaluation d'une distance de 2cm à 4m. La mesure est réalisée "sans contact". Le module est composé d'un émetteur et d'un récepteur ultrason ainsi qu'une électronique de contrôle. Le fonctionnement de ce module s'apparente à celui d'un sonar de sous marin et sa mise en œuvre est relativement simple car il est prêt à l'emploi et possède 4 pattes: un GND, un VCC, un triger pour effectuer la mesure et un Écho pour le résultat de la mesure.

Conception de la carte ultrason

Cahier des charges



Tout d'abord, pour la conception de cette carte, nous utiliseront 7 modules ultrason afin de donner le plus d'informations possible sur les obstacles positionnés sur la trajectoire du robot. Le module HC-SR04 n’étant pas répertorié par Eagle nous devons donc commencer par créer le composant, ainsi que son empreinte qui comportera la taille réelle du composant sur Eagle.

Symbole du module HCSR04 Empreinte du module HCSR04

Cahier des charges:

  • Alimentation du micro-contrôleur séparée de l'alimentation des capteurs ultrason
  • Utilisation d'un micro-contrôleur (ATtiny88) pour gérer plus facilement les mesures des capteurs
  • Condensateur de découplage pour chaque capteur ultrason afin d'éviter le bruit
  • Bornier SPI pour communiquer avec les autres cartes du robot
  • Angle de 30° entre les capteurs pour gérer plus facilement le déplacements du robot



Ensuite nous devons choisir un microcontrôleur afin de piloter cette carte: on choisira un AT TINY 88 car il possede 2 port (C et D) dont on se servira pour gerer les 7 triger et les 7 echo des modules ultrason. Ce microcontrôleur permet aussi une communication SPI dont on se servira pour communiquer avec les autres cartes du robot.

Le bornier utilisé pour la liaison SPI doit répondre à des normes : Symbole du module HCSR04

Schéma, board, typon et schéma de connexion de la carte ultrason


Voici les différents schémas utiles de la carte ultrason:

texte alternatif

Todo.jpg On peut voir sur le schéma éléctrique que les 7 modules ultrason sont reliés sur les deux ports du micro-contrôleur.

board de la carte ultrason

Todo.jpg Voici le board de la carte ultrason.

tipon de la carte ultrason

Todo.jpg Ici les typons utiles à la réalisation de la carte.


texte alternatif

Todo.jpg Voici le Schéma des connexions de la carte ultrason.


Voici les fichiers Eagle de la carte ultrason:

Média:Carte Ultrason.sch
Média:Carte ultrason.brd

Programmation de la carte ultrason

Premiers tests

Après la réalisation de la carte ultrason, nous avons effectués plusieurs tests pour vérifier son bon fonctionnement. Tout d'abord nous avons constaté une erreur: sur l'empreinte du composant HC-SR04, nous avons inversé le GND et le VCC, ce qui a par la suite causé des problèmes sur la carte. Nous avons donc corrigé ce problème, et avons effectué d'autres tests comme celui de la continuité.


Todo.jpg Nous avons ensuite testé le fonctionnement des 7 capteurs ultrason utilisé à l'aide du programme arduino si dessous qui nous transmettait par la liaison série la distance mesurée par le capteur:

/* Pinmapping */
const byte TRIGGER_PIN = 2; // Broche TRIGGER
const byte ECHO_PIN = 3;    // Broche ECHO
 
/* Constantes */
const long MEASURE_TIMEOUT = 25000L; // 40Hz = 25ms = ~8m à 340m/s
 
/* setup() */
void setup() {
   
  /* Pour l'affichage des résultats */
  Serial.begin(9600);
   
  /* Initialisation des broches */
  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  digitalWrite(TRIGGER_PIN, LOW); // DOIT être à LOW au repos
   
  /* Message d’accueil */
  Serial.println(F("~~ HC-SR04 ~~"));
}
 
/* loop() */
void loop() {
  
  /* 1) Lance une mesure de distance en envoyant une impulsion HIGH de 10µs sur la broche TRIGGER */
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);
  
  /* 2) Mesure le temps entre l'envoi de l'impulsion ultrasonique et son écho (si il existe) */
  long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);
   
  /* 3) Calcul la distance à partir du temps mesuré */
  long mm = measure / 2 * 0.34;
   
  /* Affiche les résultats en mm, cm et m */
  Serial.print(F("Distance: "));
  Serial.print(mm);
  Serial.print(F("mm ("));
  Serial.print(mm / 10.0, 2);
  Serial.print(F("cm, "));
  Serial.print(mm / 1000.0, 2);
  Serial.println(F("m)"));
   
  /* Délai d'attente pour éviter d'afficher trop de résultats à la seconde */
  delay(60);
}




programme de communication SPI : Ce programme permet d'établir la communication entre la carte ultrason (esclave) et la carte Arduino (maître). Pour vérifier le bon fonctionnement de la communication il suffit de programmer le micro-contrôleur de la carte ultrason pour qu'il transmette une valeur sur la liaison serie.

#include <SPI.h> //master 
void setup (void) 
{ 
  Serial.begin(115200);
  digitalWrite(SS, HIGH);
  // ensure SS stays high for now
  // Put SCK, MOSI, SS pins intooutput mode
  // also put SCK, MOSI into LOWstate, and SS into HIGH state.
  // Then put SPI hardware into Mastermode and turn SPI on
  SPI.begin ();
  // Slow down the master a bit
  SPI.setClockDivider(SPI_CLOCK_DIV128);
}
// end of setup 
void loop (void) 
{
  uint8_t c,a;
  // enable Slave Select
  digitalWrite(SS, LOW);
  // SS is pin 10
  // send test string
  a=SPI.transfer (10);
  digitalWrite(SS, HIGH);
  Serial.println(a,DEC);
  // disable Slave Select
  delay (100);
  // 1 seconds delay
}


Carte Codeur (Alexandre.L)

Comunication SPI arduino

Principe de la communication SPI sur Arduino

Une liaison SPI (Serial Peripheral Interface) est un bus de données série synchrone, qui opère en Full-duplex. Les circuits communiquent selon un schéma maître-esclaves, où le maître s'occupe totalement de la communication. Plusieurs esclaves peuvent coexister sur un même bus, dans ce cas, la sélection du destinataire se fait par le Slave Select.


SPI three slaves.svg.png

on dispose donc des pattes suivantes:

  • MOSI : Master Output Slave Input, le maître parle l'esclave écoute
  • MISO : Master Input Slave Output, le maître écoute, l’esclave parle
  • SLK : Serial Clock, Horloge de synchronisation généré par le maître
  • SS : Slave Select, utilisé si on dispose de plusieurs esclaves pour sélectionner avec lequel on communique



Echanges de données en SPI:



Maintenant que le principe de fonctionnement de la liaison SPI est éclaircit, intéressons nous aux échanges de données
SPI 8-bit circular transfer.svg.png

Todo.jpg on notera que les données circulent de manière circulaire; le bit 7 du master arrive sur b0 du slave, tandis que b7 du slave est envoyé sur b0 du master. il y a un décalage des bits contenus dans le registre SPDR (registre qui stock les données recues et envoyées sur la liaison SPI).

programme minimum Arduino de communication SPI:



Avec ces quelques bases, nous pouvons comprendre le programme Arduino suivant qui établit une communication quelques peu rudimentaire, mais qui illustre les fonctions Arduino utilisées pour créer une communication SPI:
Todo.jpg la carte Arduino Uno que nous utilisons possède déjà des pattes dédiées à la communication SPI:

  • MOSI : Pin 11
  • MISO : Pin 12
  • SCLK : Pin 13
  • SS : Pin 10
  • N'oublions pas de connecter les masses Arduino ensembles pour que la tension de référence soit la même




Programme maître:

// Written by Nick Gammon
// February 2011


#include <SPI.h>

void setup (void)
{

  digitalWrite(SS, HIGH);  // ensure SS stays high for now

  // Put SCK, MOSI, SS pins into output mode
  // also put SCK, MOSI into LOW state, and SS into HIGH state.
  // Then put SPI hardware into Master mode and turn SPI on
  SPI.begin ();

  // Slow down the master a bit
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  Serial.begin(115200);
  
}  // end of setup


void loop (void)
{

  char c,r;

  // enable Slave Select
  digitalWrite(SS, LOW);    // SS is pin 10

  // send test string
  for (const char * p = "Hello, world!\n" ; c = *p; p++)
    Serial.write(SPI.transfer (c));
  Serial.write('\n');
  // disable Slave Select
  digitalWrite(SS, HIGH);

  delay (1000);  // 1 seconds delay 
}  // end of loop




Programme esclave:

// Written by Nick Gammon
// February 2011


#include <SPI.h>

char buf [100];
volatile byte pos;
volatile boolean process_it;

void setup (void)
{
  Serial.begin (115200);   // debugging
  
  // turn on SPI in slave mode
  SPCR |= bit (SPE);

  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);
  
  // get ready for an interrupt 
  pos = 0;   // buffer empty
  process_it = false;

  // now turn on interrupts
  SPI.attachInterrupt();

}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
  static uint8_t i=0;
byte c = SPDR;  // grab byte from SPI Data Register
  
  // add to buffer if room
  if (pos < sizeof buf)
    {
    buf [pos++] = c;
 //   SPDR=i;
 //   i++;
    // example: newline means time to process buffer
    if (c == '\n')
      process_it = true;
      
    }  // end of room available
    
}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  if (process_it)
    {
    buf [pos] = 0;  
    Serial.println (buf);
    pos = 0;
    process_it = false;
    }  // end of flag set
    
}  // end of loop


Conception et réalisation de la carte codeur

Pour concevoir et réaliser la carte, nous devons respecter les contraintes suivantes:

  • pas de pistes au dos de la carte : la carte sera fixée et plaquée sur le châssis (à cause de l'espace occupé par les moteurs), le contact entre le dos de la carte et le châssis va créer des court-circuits si des pistes sont au dos. De plus pour des raisons de coût et de simplicité de réalisation cela est préférable.
  • la position des codeurs sera fixe : ils seront placés précisément sous les roues dentées fixées sur les axes des moteurs.
  • les pistes devrons être courtes : les grandeurs circulant sur la carte sont très faibles et seront donc facilement perturbées par les champs électriques et magnétiques.
  • choix et emplacement du connecteur : ces derniers n'ont pas de contraintes, le connecteur sera placé simplement de la manière la plus avantageuse pour le routage, et à la fois de manière accessible pour le connecter facilement.



Conception: Schéma électrique et Routage


choix des composants:

  • nous avons choisis un connecteur droit pour ça simplicité de branchement
  • les codeurs seront des Tcut 1300 du constructeur Vishay

Tcut1300.png


voici le schéma électrique:

Schema electrique-carteCodeur.png

Codeur et mesure

Todo.jpg ce schéma est plutôt simple, il est constitué d'une partie qui alimente les codeurs et d'une partie qui récupère les mesures des codeurs. Ces mesures sont renvoyé via le connecteur vers une autre carte qui analysera ces données.
Correspondance des pattes du connecteur (vue du board):

  • Patte n°1 : mesure codeur EME1 (Gauche)
  • Patte n°2 : +Vcc alimentation
  • Patte n°3 : mesure codeur EME2 (droite)
  • Patte n°4 : mesure codeur EME2 (Gauche)
  • Patte n°5 : GND masse
  • Patte n°6 : mesure codeur EME1 (droite)



BoardCarteCodeur.png

Todo.jpg on notera que les pistes sont relativement proches et que le connecteur va être difficile à souder mais cela reste envisageable. Des trous de perçage sont prévus sur la carte pour la fixer et la plaquer sur le chassi



Programme test de la carte codeur


programme de test : ce programme à pour but de valider ou non le bon fonctionnement des codeurs, il permet d'afficher le nombre d'encoches passées sur chaque roue. On peut ainsi tester si les mesures effectuées par la carte sont valides, le sens des roues etc...


Média:Codeurs.ino.zip


Gestion du déplacement du robot



équations du positionnement


Le positionnement du robot sera calculé en traitant les informations de mesures reçues sur des petits déplacements, le fait d'effectuer ces mesures sur des petits déplacements limitera l'erreur de positionnement et augmentera la précision de calcul.


Il y a deux manières d'approximer la trajectoire parcourue par le robot :


  • En utilisant des segments de droites : On considère alors que le robot va en ligne droite sur toute la période de calcul. Ceci revient à supposer que les deux roues ont une vitesse constante et identique sur cet portion de trajectoire. A la fin de cet portion, on corrige l'orientation du robot en fonction de la différence de distance parcourue par les deux roues.


  • En utilisant des arcs de cercles : On considère alors que le robot se déplace et change d'orientation en suivant un arc de cercle pendant le temps . Ceci revient à considérer que chacune des roues a une vitesse constante sur la période mais que les vitesses des 2 roues ne sont pas identiques.





positionnement par segement


On peux alors calculer les positionnement en calculant la distance parcouru et le temps de trajet des 2 roues :


positionnement par segement


Et avec ces équations, obtenir à la position du robot (coordonnées x,y)


positionnement par segement




programme de test : ce programme à pour but de valider le calcul des équations ci-dessus. Grâce au nombre d'encoches comptées sur chaque roue,il permet d'afficher la position en x du robot, sa position en y (voir axes ci-dessus), sa position angulaire et le nombre d'encoches comptés. On peut ainsi tester si les calculs effectuées renvoient une distance et un angle valide.


Média:MesurePosition.ino.zip


Programmes de déplacement



Suite a ces programmes nous avons commencé à essayer de nous rapprocher un peu plus d'un premier objectif: rendre le robot capable de se déplacer précisément. Nous avons donc travaillé sur un programme qui fait réaliser au robot un déplacement en ligne droite et s’arrête au bout d' 1 mètre. La difficulté ici a été de maintenir une trajectoire rectiligne ce qui implique une correction de trajectoire en permanence à cause de certains facteurs (les roues ne tournent pas à la même vitesse, glissement...)

programme de déplacement sur 1m : Le robot se déplace en ligne droite sur 1 mètre, un mode de fonctionnement en commentaire permet d'augmenter sa vitesse progressivement au démarrage pour éviter les glissements, elle atteint une vitesse maximum constante, puis ralentit progressivement pour s’arrêter.


Média:Deplacement 1m.ino.zip


système de fin de course (ballon) (Maxime)

Sous-catégories

Cette catégorie comprend seulement la sous-catégorie ci-dessous.

Pages dans la catégorie « RobotGEII »

Cette catégorie comprend 4 pages, dont les 4 ci-dessous.