Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Robot de poursuite de ligne basé sur l'intelligence artificielle (IA)

Composants et fournitures

Arduino Nano
× 1
Emetteur-récepteur RF Bluetooth sans fil Seeed
× 1
Module de capteur infrarouge IR Amazon Web Services Lumière photoélectrique réfléchissante
× 1
Servo à rotation continue Sony
× 1
Batterie Android 4,8 V
× 1

Applications et services en ligne

Arduino IDE

À propos de ce projet

Après avoir développé le robot Pick &Place basé sur Arduino, l'idée était de développer un robot suiveur de ligne basé sur l'IA intelligente artificielle. Développer un simple robot de suivi de ligne était bon pour le débutant, juste ce dont il avait besoin pour ajouter une sorte de capteurs infrarouges au lieu de servomoteurs dans mon récent projet. "L'idée était de tester mes compétences chez niveau avancé".

Même si c'était une tâche difficile, une sorte de recherche en ligne m'a beaucoup aidé.

Pourquoi un robot de suivi de ligne basé sur l'IA est-il nécessaire ?

Quand vient l'IA c'est la technologie récente qui a le potentiel de changer l'environnement mondial et donc la vie humaine efficace. Un rêve qui peut devenir réalité en mettant l'intelligence à nos robots pour comprendre les problèmes de la vie réelle et les résoudre en conséquence, ce rêve ne peut se réaliser que grâce à Intelligence Artificielle c'est pourquoi tout le monde en parle.

  • Il peut être utilisé dans la chaîne d'assemblage/de production.
  • Autobus de prise en charge des passagers.

Bien que mon prototype de robot puisse être un peu intelligent, ce n'est qu'un début pour moi d'orienter mes projets vers l'IA. Ainsi, ici, je vais essayer d'expliquer étape par étape le développement d'un robot de suivi de ligne utilisant l'intelligence artificielle dans un langage assez simple. En raison d'un manque de ressources, je ne construirai pas de robot mais je peux très bien expliquer comment pouvez-vous le construire en faisant une sorte de recherche. J'essaierai de fournir des codes précis qui fonctionneront sur votre IDE Arduino, afin que vous pouvez développer votre premier robot IA assez facilement.

Vous pouvez me soutenir sur Patreon d'ici :http://bit.ly/31NfQ6A

"Vous pouvez trouver l'appareil aux tarifs les moins chers aux USA sur la description de cette vidéo il suffit de cliquer sur le vidéo ."

Venons-en maintenant au projet "Un robot suiveur de ligne basé sur l'IA !".

UTILISATION DE CAPTEURS INFRAROUGES

Notre projet comprend 7 capteurs infrarouges comme indiqué sur le schéma.

  • 5 pour le contrôle PID
  • 1 pour la détection de gauche
  • un autre pour la détection du côté droit.

Rôle des 5 capteurs de contrôle PID :Ces 5 capteurs seront utilisés pour générer respectivement une sortie numérique haute ou basse (1, 0).

Le capteur centré par rapport à la ligne noire, seul ce capteur produira HIGH (1). Le résultat également possible de ce capteur pourrait être :-

  • 10000
  • 11000
  • 01000
  • 01100
  • 00100
  • 00110
  • 00010
  • 00011
  • 00001
  • 00000
  • 11111

Viennent maintenant les deux autres capteurs pour les résultats possibles à gauche et à droite

Capteur extrême gauche :sortie analogique haute ou basse

Capteur extrême gauche :sortie analogique haute ou basse

Pour stocker la valeur de 5 capteurs créons une variable tableau.

dans LFSensor[5]={1,1,1,1,1} ; 

Pour stocker la valeur des capteurs gauche et droit nous utiliserons un entier

int farleft_sensor=0 ; 

Comme nous le savons, nous avons 5 capteurs qui peuvent être utilisés pour stocker le chemin gauche et droit emprunté par le robot dans un tableau. Alors

LFSensor[0] =digitalRead(lineFollowSensor0) ;
LFSensor[1] =digitalRead(lineFollowSensor1) ;
LFSensor[2] =digitalRead(lineFollowSensor2) ;
LFSensor[ 3] =digitalRead(lineFollowSensor3) ;
LFSensor[4] =digitalRead(lineFollowSensor4) ;
farRightSensor =analogRead(farRightSensorPin);
farLeftSensor =analogRead(farLeftSensorPin);

RÈGLE DE LA MAIN GAUCHE DU LABYRINTHE :

regarder cette vidéo pour comprendre la règle de la main gauche du labyrinthe

En bref, la règle de la main gauche peut être décrit comme :

  • Placez votre main gauche sur le mur.
  • Commencez à avancer
  • À chaque intersection et dans tout le labyrinthe, gardez votre main gauche en contact avec le mur sur votre gauche.
  • Finalement, vous arriverez au bout du labyrinthe. Vous n'emprunterez probablement pas le chemin le plus court et le plus direct, mais vous y arriverez.

Donc, la clé ici est d'identifier les intersections , définissant le cours à suivre en fonction des règles ci-dessus. Concrètement, dans notre genre de labyrinthe 2D, nous pouvons trouver 8 types d'intersections différents (voir la première image ci-dessus) :

En regardant la photo, on peut se rendre compte que les actions possibles aux intersections sont :

À une "Croix "

  • Aller à gauche, ou
  • Aller à droite, ou
  • Allez tout droit
  • À une "Croix "Aller à gauche, ou aller à droite, ou aller tout droit

Dans un "T " :

  • Aller à gauche, ou
  • Aller à droite
  • Dans un "T " : Aller à gauche ou à droite

À un "Droit seulement " :

  • Aller à droite
  • À un "Droit seulement " : Aller à droite

À un "À gauche seulement " :

  • Aller à gauche
  • Dans un "À gauche seulement " : Aller à gauche

A "Droite ou Gauche " :

  • Aller à gauche, ou
  • Allez tout droit
  • À "Droite ou gauche " : Aller à gauche ou aller tout droit

À "Droite ou à droite " :

  • Aller à droite, ou
  • Allez tout droit
  • À "Droite ou à droite " : Aller à droite ou aller tout droit

Dans une "impasse " :

  • Revenir en arrière (« Demi-tour »)
  • Dans une "Impasse ":Retour ("De retour")

À "Fin du labyrinthe " :

  • Arrêtez
  • À "Fin du labyrinthe " : Stop

Mais, en appliquant la "règle de la main gauche", les actions seront réduites à une option chacune :

  • À une "croix" :aller à gauche
  • À un "T" :aller à gauche
  • À "Droite uniquement" :aller à droite
  • À une "gauche uniquement" :aller à gauche
  • À une "Droite ou à gauche" :aller à gauche
  • À un "droit ou à droite" :allez tout droit
  • Dans une « impasse » :Revenir en arrière (« Tu fais demi-tour »)
  • Au "Fin du Labyrinthe" : Stop

Nous y sommes presque! "Soyez calme !"

Lorsque le robot atteint une « impasse » ou la « fin d'un labyrinthe », il est facile de les identifier, car il n'existe pas de situations ambiguës (nous avons déjà implémenté ces actions sur le robot suiveur de ligne, vous vous souvenez ?). Le problème est lorsque le robot trouve une " LIGNE " par exemple car une ligne peut être une " Croix " (1) ou un " T " (2). De plus, lorsqu'il atteint un "virage à gauche ou à droite", il peut s'agir d'un simple virage (options 3 ou 4) ou d'options pour aller tout droit (5 ou 6). Pour découvrir exactement de quel type d'intersection se trouve le robot, une étape supplémentaire doit être franchie :le robot doit parcourir un « pouce supplémentaire » et voir ce qui va suivre (voir la deuxième image ci-dessus, à titre d'exemple).

Ainsi, en termes de flux, les actions possibles peuvent maintenant être décrites comme :

Dans une "IMPASSE" :

  • Revenir en arrière (« Demi-tour »)
  • Dans une " IMPASSE " :Revenez en arrière (" Demi-tour ")

À une "LIGNE" :

  • Courez un pouce supplémentaire
  • S'il y a une ligne :C'est une "Croix" ==> Aller à GAUCHE
  • S'il n'y a pas de ligne :c'est un "T" ==> Aller à GAUCHE
  • S'il y a une autre ligne :c'est la "Fin du Labyrinthe" ==> STOP
  • À une "LIGNE" :Courez un pouce supplémentaire S'il y a une ligne :C'est une « Croix » ==> Aller à GAUCHES'il n'y a pas de ligne :c'est un « T » ==> Aller à GAUCHE S'il y a une autre ligne :c'est la « Fin du Labyrinthe » ==> ARRÊTER

À un « VIRANT À DROITE » :

  • Courez un pouce supplémentaire
  • s'il y a une ligne :c'est une ligne droite ou droite ==> Aller TOUT DROIT
  • S'il n'y a pas de ligne :c'est une droite uniquement ==> Aller à DROITE
  • À un « VIRANT À DROITE » :Courez un centimètre supplémentaire s'il y a une ligne :C'est une Droite ou à Droite ==> Aller TOUT DROITS'il n'y a pas de ligne :c'est une Droite Seulement ==> Aller à DROITE

Lors d'un "VIRAGE A GAUCHE" :

  • Courez un pouce supplémentaire
  • s'il y a une ligne :c'est une ligne droite ou à GAUCHE ==> Aller à GAUCHE
  • S'il n'y a pas de ligne :c'est une GAUCHE uniquement ==> Aller à GAUCHE
  • Lors d'un « VIREMENT À GAUCHE » :Courez un centimètre supplémentaire s'il y a une ligne :C'est une Droite ou GAUCHE ==> Aller à GAUCHES'il n'y a pas de ligne :c'est une GAUCHE Seulement ==> Aller à GAUCHE

Notez qu'en fait, en cas de « TOUR À GAUCHE », vous pouvez sauter le test, car vous prendrez de toute façon à GAUCHE. J'ai laissé l'explication plus générique uniquement pour plus de clarté. Au vrai code, je sauterai ce test.

Voici quelques problèmes qui peuvent survenir lors de la réalisation de ce projet.

Sujet connexe

RÉSOLUTION DU PROBLÈME DU PILOTE Arduino

regarder cette vidéo pour résoudre le problème du pilote Arduino :


Code

  • RoBot_Maze_Solve_2
  • Fonctions
  • Fonctions générales.
  • sensorFuntions
  • RobotDefines.h
  • MotorFuntions
RoBot_Maze_Solve_2C/C++
/*--------------------------------------------- ---------------------7 capteurs Smart Robot - Maze Solver et Line Follower avec contrôleur PID programmable via BT ==> Mouvement de base basé sur Nano Mouse Robot, développé par Michael Backus (http://www.akrobotnerd.com/ )==> Suivi de ligne basé sur http://samvrit.tk/tutorials/pid-control-arduino-line-follower-robot/?ckattempt=1==> CRÉDIT à Patrick McCabe pour le chemin Solving Code, visitez patrickmccabemakes.com!! Marcelo Jose Rovai - 23 avril 2016 - Visitez:http://mjrobot.org---------------- -------------------------------------------------- -*/#include #include "robotDefines.h"String command;String device;// BT Module#include SoftwareSerial BT1(10, 11); // El pin 10 es Rx y el pin 11 es Tx//----------------------------------- ----------void setup() { Serial.begin(9600); BT1.begin(9600); pinMode(ledPin, SORTIE); pinMode(boutonPin, INPUT_PULLUP); // capteurs de suivi de ligne pinMode(lineFollowSensor0, INPUT); pinMode(lineFollowSensor1, INPUT); pinMode(lineFollowSensor2, INPUT); pinMode(lineFollowSensor3, INPUT); pinMode(lineFollowSensor4, INPUT); // servos leftServo.attach(5); rightServo.attach(3); BT1.print("vérifier les constantes PID à envoyer au Robot"); Serial.print("vérifier les constantes PID à envoyer au Robot"); BT1.println('\n'); while (digitalRead(buttonPin) &&!mode) { checkBTcmd(); // vérifie si une commande est reçue de la télécommande BT manualCmd (); commande =""; } checkPIDvalues(); mode =ARRÊTÉ ; état =0 ; // 1ère passe}boucle vide() { ledBlink(1); BT1.println("Démarrer le premier passage"); Serial.println("Démarrer le premier passage"); readLFSsensors(); labyrintheRésoudre(); // Première passe pour résoudre le labyrinthe ledBlink(2); BT1.println("Fin du premier passage"); Serial.println("Fin du premier passage"); while (digitalRead(buttonPin) &&!mode) { checkBTcmd(); // vérifie si une commande est reçue de la télécommande BT manualCmd (); commande =""; } BT1.println("Démarrage du 2e passage"); Serial.println("Démarrage du 2e passage"); indexchemin =0 ; état =0 ; Optimisation du labyrinthe (); // exécuter le labyrinthe aussi vite que possible ledBlink(3); BT1.println("Fin du 2e passage"); Serial.println("Fin du 2e passage"); while (digitalRead(buttonPin) &&!mode) { checkBTcmd(); // vérifie si une commande est reçue de la télécommande BT manualCmd (); commande =""; } mode =ARRÊTÉ ; état =0 ; // 1ère passe pathIndex =0; pathLength =0;}
FonctionsC/C++
void mazeSolve(void){ while (!status) { readLFSsensors(); switch (mode) { case NO_LINE:motorStop(); allerEtTourner (GAUCHE, 180); recIntersection('B'); Pause; case CONT_LINE :runExtraInch(); readLFSsensors(); if (mode !=CONT_LINE) {goAndTurn (LEFT, 90); recIntersection('L');} // ou c'est un "T" ou une "Croix"). Dans les deux cas, va à GAUCHE else mazeEnd(); Pause; cas RIGHT_TURN:runExtraInch(); readLFSsensors(); if (mode ==NO_LINE) {goAndTurn (RIGHT, 90); recIntersection('R');} else recIntersection('S'); Pause; cas LEFT_TURN :goAndTurn (LEFT, 90); recIntersection('L'); Pause; case FOLLOWING_LINE:followLine(); Pause; } }}//---------------------------------------------- void recIntersection(char direction){ path[pathLength] =direction; // Stocke l'intersection dans la variable de chemin. pathLength ++; simplifierPath(); // Simplifier le chemin appris.}//----------------------------------------- ------void mazeEnd(void){ motorStop(); BT1.print("La fin ==> Chemin :"); for(int i=0;i "); Serial.println(pathLength); état =1 ; mode =ARRÊTÉ;}//-------------------------------------------- ---void followLine(void){ //readLFSsensors(); calculerPID(); motorPIDcontrol(); }//------------------------------------------------ -------------------------------------------// Simplification du chemin. La stratégie est que chaque fois que nous rencontrons une// séquence xBx, nous pouvons la simplifier en supprimant l'impasse. Par// exemple, LBL -> S, car un seul S contourne l'impasse // représentée par LBL.void simplifierPath(){ // ne simplifie le chemin que si l'avant-dernier virage était un 'B' if( pathLength <3 || path[pathLength-2] !='B') return ; int totalAngle =0; int je; for(i=1;i<=3;i++) { switch(path[pathLength-i]) { case 'R':totalAngle +=90; Pause; cas 'L' :totalAngle +=270 ; Pause; cas 'B' :totalAngle +=180 ; Pause; } } // Récupère l'angle sous la forme d'un nombre compris entre 0 et 360 degrés. TotalAngle =TotalAngle % 360 ; // Remplace tous ces tours par un seul. switch(totalAngle) { case 0:path[pathLength - 3] ='S'; Pause; cas 90 :path[pathLength - 3] ='R' ; Pause; cas 180 :path[pathLength - 3] ='B' ; Pause; cas 270 :path[pathLength - 3] ='L' ; Pause; } // Le chemin est maintenant plus court de deux étapes. pathLength -=2; } //------------------------------------------------------------ ------------------------------------------------ void mazeOptimization ( void){ while (!status) { readLFSsensors(); switch (mode) { case FOLLOWING_LINE:followLine(); Pause; case CONT_LINE :if (pathIndex>=pathLength) mazeEnd (); else {mazeTurn (chemin[cheminIndex]); pathIndex++;} break; case LEFT_TURN :if (pathIndex>=pathLength) mazeEnd (); else {mazeTurn (chemin[cheminIndex]); pathIndex++;} break; case RIGHT_TURN :if (pathIndex>=pathLength) mazeEnd (); else {mazeTurn (chemin[cheminIndex]); pathIndex++;} break; } } }//----------------------------------------------- --------void mazeTurn (char dir) { switch(dir) { case 'L':// Tourner à gauche goAndTurn (LEFT, 90); Pause; case 'R' :// Tourner à droite goAndTurn (RIGHT, 90); Pause; case 'B' :// Revenir en arrière goAndTurn (RIGHT, 800); Pause; case 'S' :// Aller tout droit runExtraInch(); Pause; }}
Fonctions Générales.C/C++
void ledBlink(int times){ for (int i =0; i 0) { Serial.print("Commande reçue de BT ==> "); Serial.println(appareil); commande =appareil ; appareil ="" ; //Réinitialiser la variable BT1.flush(); } }//---------------------------------------------- ---------------------------void manualCmd(){ switch (command[0]) { case 'g':mode =FOLLOWING_LINE; Pause; cas 's' :motorStop(); // éteindre les deux moteurs break ; cas 'f' :motorForward(); Pause; cas 'r':motorTurn(RIGHT, 30); Arrêt moteur(); Pause; cas 'l' :motorTurn(LEFT, 30); Arrêt moteur(); Pause; cas 'b' :motorBackward(); Pause; cas 'p' :Kp =commande[2] ; Pause; cas 'i' :Ki =commande[2] ; Pause; cas 'd' :Kd =commande[2] ; Pause; }}//---------------------------------------------- --------------------------void sendBTdata (int data) // envoie des données à BT{ digitalWrite (ledPin, HIGH); BT1.print("Données d'Arduino"); BT1.print(données); BT1.print(" xx"); BT1.println('\n'); digitalWrite (ledPin, LOW);}//----------------------------------------- ----------------void calculerPID(){ P =erreur; I =I + erreur ; D =erreur-précédenteError ; Valeur PID =(Kp*P) + (Ki*I) + (Kd*D) ; erreur précédente =erreur;}//-------------------------------------------- -------------void checkPIDvalues(){ BT1.print("PID:"); BT1.print(Kp); BT1.print(" - "); BT1.print(Ki); BT1.print(" - "); BT1.println(Kd); Serial.print("PID:"); Serial.print(Kp); Serial.print(" - "); Serial.print(Ki); Serial.print(" - "); Serial.println(Kd); }//------------------------------------------------ void testLineFollowSensors(){ int LFS0 =digitalRead(lineFollowSensor0) ; int LFS1 =digitalRead(lineFollowSensor1) ; int LFS2 =digitalRead(lineFollowSensor2) ; int LFS3 =digitalRead(lineFollowSensor3) ; int LFS4 =digitalRead(lineFollowSensor4) ; Serial.print ("LFS:L 0 1 2 3 4 R ==> "); Serial.print (LFS0) ; Serial.print (" "); Serial.print (LFS1) ; Serial.print (" "); Serial.print (LFS2) ; Serial.print (" "); Serial.print (LFS3) ; Serial.print (" "); Serial.print (LFS4) ; Serial.print (" ==> "); Serial.print (" P:"); Serial.print (P); Serial.print (" I:"); Serial.print (I); Serial.print (" D:"); Serial.print (D); Serial.print (" PID:"); Serial.println (PIDvalue);}
sensorFuntionsC/C++
//--------------------------------------------- ----------------/* lire les valeurs des capteurs de ligne Sensor Array Error Value0 0 0 0 1 4 0 0 0 1 1 3 0 0 0 1 0 2 0 0 1 1 0 1 0 0 1 0 0 0 0 1 1 0 0 -1 0 1 0 0 0 -2 1 1 0 0 0 -3 1 0 0 0 0 -4 1 1 1 1 1 0 Robot trouvé ligne continue - teste si une intersection ou une fin of maze0 0 0 0 0 0 Robot n'a trouvé aucune ligne :tournez à 180o*/void readLFSsensors(){ LFSensor[0] =digitalRead(lineFollowSensor0) ; LFSensor[1] =digitalRead(lineFollowSensor1) ; LFSensor[2] =digitalRead(lineFollowSensor2) ; LFSensor[3] =digitalRead(lineFollowSensor3) ; LFSensor[4] =digitalRead(lineFollowSensor4) ; farRightSensor =analogRead (farRightSensorPin); farLeftSensor =analogRead (farLeftSensorPin); if ((LFSensor[0]==1 )&&(LFSensor[1]==1 )&&(LFSensor[2]==1 )&&(LFSensor[3]==1 )&&(LFSensor[4]==1 )) {mode =CONT_LINE; error =0;} else if((LFSensor[0]==0 )&&(farRightSensor "); Serial.print (farRightSensor); Serial.print (" mode:"); Serial.print (mode); Serial.print (" erreur:"); Serial.println (erreur); }//------------------------------------------------ ------------void readLateralSensors(void){ }
RobotDefines.hC/C++
int mode =0;# définit STOPPED 0# définit FOLLOWING_LINE 1# définit NO_LINE 2# définit CONT_LINE 3# définit POS_LINE 4# définit RIGHT_TURN 5# définit LEFT_TURN 6const int power =250;const int iniMotorPower =250;const int adj =0;float adjTurn =8;int extraInch =200;int adjGoAndTurn =800;const int ledPin =13;const int buttonPin =9;// LFSensor plus à gauche est "0"const int lineFollowSensor0 =12; const int lineFollowSensor1 =18 ; const int lineFollowSensor2 =17 ; const int lineFollowSensor3 =16;const int lineFollowSensor4 =19;const int farRightSensorPin =0; //Broche analogique A0const int farLeftSensorPin =1; //Broche analogique A0const int THRESHOLD =150;int farRightSensor =0;int farLeftSensor =0;int LFSensor[5]={0, 0, 0, 0, 0};// contrôleur PIDfloat Kp=50;float Ki=0;float Kd=0;float error=0, P=0, I=0, D=0, PIDvalue=0;float previousError=0, previousI=0;#define RIGHT 1#define LEFT -1Servo leftServo;Servo rightServo; //------------------------------------------------ -//Définitions et variables spécifiques de Maze Phase 2 (optimisation) char dir ; // La variable chemin stockera le chemin que le robot a pris:// 'L' pour gauche// 'R' pour droite// 'S' pour tout droit (passant tout droit à travers une intersection)// 'B' pour retour (U-turn)char path[100] ="";char non signé pathLength =0; // la longueur du pathint pathIndex =0;unsigned int status =0; // résolution =0; atteindre la fin =1
MotorFuntionsC/C++
void motorStop(){ leftServo.writeMicroseconds(1500); rightServo.writeMicroseconds(1500); retard(200);}//------------------ --- void motorForward(){ leftServo.writeMicroseconds(1500 - (power+adj)); rightServo.writeMicroseconds(1500 + puissance);}//-------------------------------------- -------void motorBackward(){ leftServo.writeMicroseconds(1500 + puissance); rightServo.writeMicroseconds(1500 - puissance);}//-------------------------------------- -------void motorFwTime (temps entier non signé){ motorForward(); temporisation); Arrêt moteur();}//--------------------------------------------- --void motorBwTime (temps int non signé){ motorBackward(); temporisation); Arrêt moteur();}//--------------------------------------------- -----void motorTurn(int direction, int degrés){ leftServo.writeMicroseconds(1500 - (iniMotorPower+adj)*direction); rightServo.writeMicroseconds(1500 - iniMotorPower*direction); délai (arrondi(adjTurn*degrees+20)); Arrêt moteur();}//--------------------------------------------- --------void motorPIDcontrol(){ int leftMotorSpeed ​​=1500 - (iniMotorPower+adj) - PIDvalue ; int rightMotorSpeed ​​=1500 + iniMotorPower - PIDvalue ; // La vitesse du moteur ne doit pas dépasser la contrainte maximale de la valeur PWM (leftMotorSpeed, 1000, 2000); contraindre (rightMotorSpeed, 1000, 2000); leftServo.writeMicroseconds(leftMotorSpeed); rightServo.writeMicroseconds(rightMotorSpeed); //Serial.print (PIDvalue); //Serial.print (" ==> Gauche, Droite :"); //Serial.print (leftMotorSpeed); //Série.print (" "); //Serial.println (rightMotorSpeed);}//-------------------------------------- -------------void runExtraInch(void){ motorPIDcontrol(); retard (extraPouce); Arrêt moteur();}//--------------------------------------------- --------void goAndTurn(int direction, int degrés){ motorPIDcontrol(); delay(adjGoAndTurn); motorTurn(direction, degrés);}

Schémas


Processus de fabrication

  1. Robot évitant les murs basé sur Raspberry Pi – FabLab NerveCentre
  2. Un robot mobile avec un évitement d'obstacles basé sur la vision
  3. Robot « artistique » à NPE
  4. Automatisation :ligne de robot repensée
  5. Bosch ajoute l'intelligence artificielle à l'industrie 4.0
  6. Ligne de robots SCARA élargie
  7. L'intelligence artificielle est-elle une fiction ou une mode ?
  8. L'intelligence artificielle aide le robot à reconnaître les objets au toucher
  9. Robots d'intelligence artificielle