Robot de guidage : Différence entre versions
(→Matériel à acheter) |
|||
(29 révisions intermédiaires par 3 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
== Présentation == | == Présentation == | ||
− | + | <include nopre noesc src="/home/pedago/pimasc/include/video-RobotGuidage-iframe.html" /> | |
+ | Ce projet s'inscrit dans le cadre de notre quatrième année d'étude au département IMA de l'école d'ingénieur Polytech'Lille. | ||
+ | Il a été proposé par le département R&D de l'entreprise Oxylane dans le cadre d'une coopération avec le département. | ||
+ | L'objectif de ce projet est de créer un robot de guidage qui devrait être utilisable dans un magasin quel qu'il soit. | ||
+ | Ce robot devrait être capable de se localiser dans un magasin suivant les produits recherchés, le principe étant que le client puisse sélectionner les produit sur une tablette tactile associée au robot. Ce dernier commandé par un contrôleur arduino relié à la tablette devrai utiliser des point de repères afin de déterminer l'emplacement de chaque rayon. | ||
+ | L'ensemble du matériel nécessaire ( robot, tablette, capteur, etc...) à ce projet sont commandés via des fournisseur et sur proposition des étudiants au tuteur de projet. | ||
+ | Les étapes de réalisation de ce projet sont détaillées dans les parties suivantes. | ||
+ | <br style="clear: both;"> | ||
== Préparation du projet == | == Préparation du projet == | ||
=== Matériel requis === | === Matériel requis === | ||
+ | *Robot + capteurs | ||
+ | *Tablette | ||
+ | *Arduino | ||
+ | *Outils de programmation | ||
=== Matériel à acheter === | === Matériel à acheter === | ||
− | |||
* Platine ADK | * Platine ADK | ||
* Robot | * Robot | ||
Ligne 15 : | Ligne 25 : | ||
== Avancement du projet== | == Avancement du projet== | ||
− | === Objectifs | + | === Objectifs des différentes séances === |
+ | |||
+ | '''1ere séance''': Lors de cette première séance Nous nous sommes fixés comme objectifs d'effectuer une recherche des caractéristiques du robot de guidage et une conception d'un cahier des charges réduit. Il s'est donc agit de faire une recherche sur internet des différents modèles de robots respectant notre budget. | ||
+ | |||
+ | |||
− | + | '''2ème séance''': La deuxième séance s'est axée sur l'installation des différents paquets nécessaires pour créer une application Android permettant l'affichage d'un message sur l'écran de la tablette tactile. | |
+ | |||
+ | |||
+ | '''3ème et 4ème séance''': Ces 2 séances sont axées sur la création d'une application Android permettant de sélectionner une liste de produit et de commander le robot par la suite. Il s'agit donc de créer une base de données comportant les objets et les selections effectuées par l'utilisateur. | ||
+ | |||
+ | '''5ème séance''': Les bases de données ayant été créées il faut à présent relier ces bases à notre interface utilisateur de manière à stocker les images et les différentes informations du magasin et des choix utilisateurs. | ||
=== Réalisations concrètes === | === Réalisations concrètes === | ||
Ligne 24 : | Ligne 43 : | ||
==== Première séance ==== | ==== Première séance ==== | ||
+ | Nous avons effectué des recherches sur internet concernant différents modèles de robot pouvant respecter le cahier des charges. Nous avons comparé différents modèles et avons choisi un robot mobile FB004 fabriqué par FiveBot. | ||
+ | |||
+ | 2 fournisseurs différents proposent ce robot : Robotshop à 751.83 euros et génération robots à 705 euros ( seul problème chez ces derniers le robots n'est pas en stock) . Ce robot possède les caractéristiques indiqué ci dessous. | ||
+ | |||
+ | Ainsi afin de respecter la norme de taille d'environ 1,5m pour un utilisateur humain, nous avons décidé de rajouter des barres en alluminium commandées chez radiospares | ||
+ | |||
+ | ''( Disponibilité disponible(s) - En stock pour livraison le lendemain | ||
+ | Code RS 493-8319 | ||
+ | Fabricant Bosch Rexroth | ||
+ | Référence fabricant R987160855 | ||
+ | Etat RoHS | ||
+ | Sans objet) | ||
+ | '' | ||
+ | Pour abaisser le centre de gravité du robot complet nous utiliserons des roulettes de soutients qui permettront de gérer l'équilibre de robot | ||
+ | |||
+ | |||
+ | La liste des éléments livrés par commande reste la meme quel que soit le fournisseur du robot | ||
+ | |||
+ | |||
+ | [[Fichier:Robot1.jpg]] [[Fichier:Robot2.jpg]] | ||
+ | |||
+ | Kit Robot Mobile à 2 Roues Motrices Compatible Arduino | ||
+ | |||
+ | |||
+ | |||
+ | Caractéristiques techniques du robot Fivebot FB-004 | ||
+ | ''Châssis | ||
+ | |||
+ | * Apparence : châssis circulaire | ||
+ | * Longueur : 357mm | ||
+ | * Largeur : 313mm | ||
+ | * Hauteur : 267mm | ||
+ | * Garde au sol : 39mm | ||
+ | * Matériau du châssis : Aluminium, acier | ||
+ | * Vitesse max : 0.8m/s | ||
+ | * Propulsion : 2 roues motrices différentielles, 1 roue libre | ||
+ | * Pente franchissable : 20° | ||
+ | * Charge utile : 10kg | ||
+ | * Compatibilité mini-ITX : Oui | ||
+ | |||
+ | Encodeurs | ||
+ | |||
+ | * Technologie : optique | ||
+ | * Nombre de voies : 2 | ||
+ | * Résolution : 12 tops par tour de roue | ||
+ | |||
+ | Alimentation | ||
+ | |||
+ | * Batterie : 12V Ni-Mh | ||
+ | * Chargeur : Recharge lente Vin : 100-240V – Vout : 2.4-12V | ||
+ | * Durée de charge : 2 heures | ||
+ | * Autonomie : 30 minutes en continu | ||
+ | |||
+ | Roues | ||
+ | |||
+ | * Diamètre : 143mm | ||
+ | * Largeur : 30mm | ||
+ | * Matériau : polyuréthane | ||
+ | |||
+ | Motorisation | ||
+ | |||
+ | * Type : Faulhaber 12V DC sans fer | ||
+ | * Puissance : 17W | ||
+ | * Vitesse de rotation : 120 tours par minute | ||
+ | * Diamètre : 30mm | ||
+ | * Longueur : 42mm | ||
+ | * Longueur totale : 85mm | ||
+ | * Longueur de l’axe : 35mm | ||
+ | * Diamètre de l’axe : 6mm | ||
+ | * Courant à vide : 75mA | ||
+ | * Courant en charge : 1400mA | ||
+ | * Rapport de boîte de vitesse : 64 :1 | ||
+ | |||
+ | Carte de contrôle principale | ||
+ | |||
+ | * Microcontrôleur ATMEGA328 | ||
+ | * 14 Entrées / Sorties numériques | ||
+ | * 6 canaux de PWM | ||
+ | * 8 Entrées / Sorties analogiques | ||
+ | * Interface USB | ||
+ | * Circuit de protection électrique | ||
+ | * Interface série niveau TTL | ||
+ | * Support du module radio APC220 | ||
+ | * 5 interfaces I2C | ||
+ | * Électronique de commande moteur 2A max | ||
+ | * Alimentation : USB ou alimentation externe 7-12V | ||
+ | * Ports d’alimentations disponibles : 5V/3.3V stabilisées et alimentation batterie | ||
+ | |||
+ | Carte d’extension | ||
+ | |||
+ | * Contrôle de 2 moteurs supplémentaires | ||
+ | * Support RS-485 | ||
+ | * Support module Xbee | ||
+ | |||
+ | Programmation | ||
+ | |||
+ | * Environnement de programmation Arduino | ||
+ | * AVR Studio avec programmation par USB | ||
+ | '' | ||
+ | |||
+ | |||
+ | |||
+ | Pour l'utilisation du robot, nous avons prévu en ce qui concerne l'alimentation d'utiliser des points de chargements muraux. | ||
+ | Les suivis de trajectoire seront quant à eux adaptés à notre rythme d'avancement dans le projet. Nous partons tout de meme dans l'idée d'utiliser des capteur RFID au final. Nous essayerons avant cela de réaliser des suivi de lignes colorées ou blanches. | ||
+ | |||
+ | |||
+ | ==== Deuxième séance ==== | ||
+ | |||
+ | Nous avons installé les différents paquets java et eclipse nécessaire pour réaliser les programmes sous android. | ||
+ | Nous avons connu de nombreux problèmes lors de l'installation des plugins sur eclipse. Ces problèmes ont été dus en premier lieu à un problème de proxy que nous avons par la suite configuré puis à un problème de lien de téléchargement qui n'était plus existants. Nous avons alors récupéré un dossier de plugins déjà téléchargés que nous avons associé au logiciel. | ||
+ | Nous avons alors créé une application affichant " hello world" sur l'écran d'une tablette ( Motorola XOOM). | ||
+ | Le code correspondant à l'affichage d'un message sur l'écran est le suivant: | ||
+ | |||
+ | '''package com.google.android.hellosdz; | ||
+ | |||
+ | import android.app.Activity; | ||
+ | |||
+ | import android.os.Bundle; | ||
+ | |||
+ | import android.widget.TextView; | ||
+ | |||
+ | public class HelloSdZ extends Activity | ||
+ | |||
+ | { | ||
+ | |||
+ | @Override | ||
+ | |||
+ | public void onCreate(Bundle savedInstanceState) { | ||
+ | |||
+ | super.onCreate(savedInstanceState); | ||
+ | |||
+ | TextView tv = new TextView(this); | ||
+ | |||
+ | tv.setText("Hello World !"); | ||
+ | |||
+ | setContentView(tv); | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | ''' | ||
+ | |||
+ | La tablette utilisée: [[Fichier:2011-01-05-moto-xoom-3.jpg]] | ||
+ | |||
+ | |||
+ | |||
+ | ==== Troisième et quatrième séances ==== | ||
+ | |||
+ | Nous avons conçu une application permettant à l'utilisateur de sélectionner un produit suivant une galerie. | ||
+ | Pour Cela nous avons d'abord utilisé une base de d'images correspondant au produits. L'utilisateur peut ainsi choisir le produit et appuyer sur un bouton pour valider. | ||
+ | Cette première version, nous avons pensé l'améliorer en utilisant une base de données permettant de modifier plus facilement les données enregistrées. | ||
+ | Nous avons donc commencé par étudier la syntaxe du SQLite avec Android à l'aide d'un exemple portant sur une base de données de livres. Le programme nous permet ainsi de réaliser 3 opérations: entrez une donnée, modifier une donnée et supprimer une donnée. | ||
+ | Ceci nous permet d'envisager des choix multiples pour l'utilisateur qui verra le robot corriger l'ordre de ses choix suivant la distance de chaque produit. | ||
+ | |||
+ | |||
+ | ==== Cinquième séance ==== | ||
+ | |||
+ | Nous avons amélioré l'interface utilisateur de la tablette en incluant des boutons "add" "delete" et "confirm". Ces derniers permettant à l'utilisateur d'ajouter un produit à une liste ou de la supprimer et également de la valider cette liste. | ||
+ | Nous n'avons par contre pas pu tenir nos objectifs vis à vis de la base de données. En effet nous créé une base de données de produit et avons réussi à faire correspondre les informations produits avec certaines images produits. Mais au niveau de l'application sur la tablette le fonctionnement ne correspond pas à celui attendu puisque les images n'apparaissent pas lorsqu'on relie la base de donnée et seule les informations sont visibles. Nous avons donc pensé à une nouvelles méthode d'approches qui pourrait simplifier l'interface. L'objectif final étant surtout la communication entre la tablette et le robot. | ||
+ | |||
+ | |||
+ | ==== Sixième septième et huitième séances ==== | ||
+ | |||
+ | A cause des nombreux décalages dans l'emploi du temps des projets suivant les filières, certaines parties n'ont pu être effectuées correctement. Cepedant durant les 3 séances , nous nous sommes rapprochés de notre application finale sur la tablette avec les différents paramètres des bases de données gérant les listes de produits. Nous avons entamé la programmation sous arduino en installant les différentes librairies et logiciels pour la communication tablette arduino. | ||
+ | Nous avons établis un plan de communication défini par un transfert de certaines informations( numero produit, numero rayon) vers le arduino devant ensuite commander le robot. | ||
+ | |||
+ | ==== A partir de la neuvième scéance ==== | ||
+ | |||
+ | Code obtenu lors des scéances qui ont suivi. | ||
+ | |||
+ | |||
+ | package com.android.projet; | ||
+ | |||
+ | import java.util.ArrayList; | ||
+ | import java.util.HashMap; | ||
+ | |||
+ | import android.view.*; | ||
+ | import android.app.Activity; | ||
+ | import android.app.AlertDialog; | ||
+ | import android.content.DialogInterface; | ||
+ | import android.content.DialogInterface.OnClickListener; | ||
+ | import android.os.Bundle; | ||
+ | import android.widget.AdapterView.OnItemClickListener; | ||
+ | import android.widget.*; | ||
+ | |||
+ | public class ProjetActivity extends Activity { | ||
+ | |||
+ | //Création d'une instance de ma classe ProduitsBDD | ||
+ | |||
+ | private ListView maListViewPerso; | ||
+ | int j = 0; | ||
+ | |||
+ | ProduitsBDD produitBdd = new ProduitsBDD(this, 1, "magasin"); | ||
+ | ProduitsBDD choixBdd = new ProduitsBDD(this, 1, "client"); | ||
+ | |||
+ | |||
+ | //Création de la ArrayList qui nous permettra de remplir la listView | ||
+ | ArrayList<HashMap<String, String>> listItem = new ArrayList<HashMap<String, String>>(); | ||
+ | |||
+ | |||
+ | |||
+ | /** Called when the activity is first created. */ | ||
+ | @Override | ||
+ | public void onCreate(Bundle savedInstanceState) { | ||
+ | |||
+ | super.onCreate(savedInstanceState); | ||
+ | setContentView(R.layout.main); | ||
+ | |||
+ | |||
+ | //Création d'un produit | ||
+ | Produit produit1 = new Produit("d1d1", "fruits-cerise"); | ||
+ | Produit produit2 = new Produit("d1g1","fruits-orange"); | ||
+ | Produit produit3 = new Produit("g1d1", "légumes-aubergine"); | ||
+ | Produit produit4 = new Produit("g1g1", "légumes-pommedeterre"); | ||
+ | Produit produit5 = new Produit("d2d1", "vetements-chemise"); | ||
+ | Produit produit6 = new Produit("d2g1", "vetements-pantalon"); | ||
+ | Produit produit7 = new Produit("g2d1","chaussures-botte"); | ||
+ | Produit produit8 = new Produit("g2g1", "chaussures-basket"); | ||
+ | Produit produit9 = new Produit("d3d1", "high tech-tablette"); | ||
+ | Produit produit10 = new Produit("d3g1", "high tech-pc"); | ||
+ | Produit produit11 = new Produit("g3d1", "cuisine-four"); | ||
+ | Produit produit12 = new Produit("g3g1", "cuisine-marmite"); | ||
+ | Produit produit13 = new Produit("d4d1", "petit déjeuner-pain"); | ||
+ | Produit produit14 = new Produit("d4g1", "petit déjeuner-lait"); | ||
+ | Produit produit15 = new Produit("g4d1", "hygiene-Mr propre"); | ||
+ | Produit produit16 = new Produit("g4g1", "hygiene-Mir"); | ||
+ | Produit produit17 = new Produit("d5d1", "beauté-maquillage"); | ||
+ | Produit produit18 = new Produit("d5g1", "beauté-shampoing"); | ||
+ | Produit produit19 = new Produit("g5d1", "boisson-soda"); | ||
+ | Produit produit20 = new Produit("g5g1","boisson-vin"); | ||
+ | |||
+ | choixBdd.open(); | ||
+ | choixBdd.upgrade(); | ||
+ | choixBdd.close(); | ||
+ | |||
+ | |||
+ | //On ouvre la base de données pour écrire dedans | ||
+ | produitBdd.open(); | ||
+ | |||
+ | produitBdd.upgrade(); | ||
+ | //On insère le produit que l'on vient de créer | ||
+ | produitBdd.insertProduit(produit1); | ||
+ | produitBdd.insertProduit(produit2); | ||
+ | produitBdd.insertProduit(produit3); | ||
+ | produitBdd.insertProduit(produit4); | ||
+ | produitBdd.insertProduit(produit5); | ||
+ | produitBdd.insertProduit(produit6); | ||
+ | produitBdd.insertProduit(produit7); | ||
+ | produitBdd.insertProduit(produit8); | ||
+ | produitBdd.insertProduit(produit9); | ||
+ | produitBdd.insertProduit(produit10); | ||
+ | produitBdd.insertProduit(produit11); | ||
+ | produitBdd.insertProduit(produit12); | ||
+ | produitBdd.insertProduit(produit13); | ||
+ | produitBdd.insertProduit(produit14); | ||
+ | produitBdd.insertProduit(produit15); | ||
+ | produitBdd.insertProduit(produit16); | ||
+ | produitBdd.insertProduit(produit17); | ||
+ | produitBdd.insertProduit(produit18); | ||
+ | produitBdd.insertProduit(produit19); | ||
+ | produitBdd.insertProduit(produit20); | ||
+ | |||
+ | |||
+ | |||
+ | Gallery gallery = (Gallery) findViewById(R.id.gallery1); | ||
+ | gallery.setAdapter(new ImageAdaptergallery(this)); | ||
+ | gallery.setOnItemClickListener(new OnItemClickListener() { | ||
+ | public void onItemClick(AdapterView<?> parent, View v, int position, long id) { | ||
+ | chooser(position); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | //Bouton visualiser liste | ||
+ | final Button button = (Button) findViewById(R.id.button1); | ||
+ | button.setOnClickListener(new View.OnClickListener() { | ||
+ | public void onClick(View v) { | ||
+ | remplirtable(); | ||
+ | affichageliste(); | ||
+ | |||
+ | } | ||
+ | }); | ||
+ | |||
+ | |||
+ | |||
+ | //bouton supprimer liste | ||
+ | final Button button2 = (Button) findViewById(R.id.button2); | ||
+ | button2.setOnClickListener(new View.OnClickListener() { | ||
+ | public void onClick(View v) { | ||
+ | choixBdd.open(); | ||
+ | choixBdd.upgrade(); | ||
+ | choixBdd.close(); | ||
+ | listItem.clear(); | ||
+ | j=0; | ||
+ | affichageliste(); | ||
+ | |||
+ | } | ||
+ | }); | ||
+ | produitBdd.close(); | ||
+ | } | ||
+ | |||
+ | |||
+ | protected void chooser(int num) { | ||
+ | produitBdd.open(); | ||
+ | choixBdd.open(); | ||
+ | |||
+ | Produit produitchoisiFromBdd = produitBdd.getProduitWithid(num+1); | ||
+ | GridView gridview1 = (GridView) findViewById(R.id.gridview1); | ||
+ | //GridView gridview = (GridView) findViewById(R.id.gridview); | ||
+ | if(produitchoisiFromBdd != null){ | ||
+ | |||
+ | choixBdd.insertProduit(produitchoisiFromBdd) ; | ||
+ | //On affiche les infos du produit dans un Toast | ||
+ | Toast.makeText(this, produitchoisiFromBdd.toString(), Toast.LENGTH_LONG).show(); | ||
+ | gridview1.setAdapter(new Image2Adapter(this, num)); | ||
+ | } | ||
+ | //else { | ||
+ | //Toast.makeText(this,"LISTE PLEINE !!!!\n Veuillez valider votre liste ou la supprimer", Toast.LENGTH_LONG).show(); | ||
+ | //} | ||
+ | |||
+ | remplirtable(); | ||
+ | affichageliste(); | ||
+ | produitBdd.close(); | ||
+ | choixBdd.close(); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | /** | ||
+ | protected void agencement() | ||
+ | { | ||
+ | int i; | ||
+ | Produit produitchoisiFromBdd; | ||
+ | Produit fin = new Produit("fin","fin"); | ||
+ | choixBdd.open(); | ||
+ | |||
+ | for(i=1; i<choixBdd.getcountproduit();i++) | ||
+ | { | ||
+ | if (choixBdd.getProduitWithid(i) == fin) | ||
+ | { produitchoisiFromBdd = choixBdd.getProduitWithid(i); | ||
+ | if (choixBdd.getProduitWithid(i+1)!=null); | ||
+ | {choixBdd.updateProduit(i, choixBdd.getProduitWithid(i+1)); | ||
+ | choixBdd.updateProduit(i+1, produitchoisiFromBdd);} | ||
+ | } | ||
+ | } | ||
+ | choixBdd.close(); | ||
+ | } | ||
+ | |||
+ | **/ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | protected void remplirtable() | ||
+ | { | ||
+ | |||
+ | Produit produitchoisiFromBdd; | ||
+ | |||
+ | |||
+ | choixBdd.open(); | ||
+ | listItem.clear(); | ||
+ | |||
+ | int i=1; | ||
+ | //On affiche les infos du produit dans un Toast | ||
+ | for(i=1;i<=choixBdd.getcountproduit();i++) | ||
+ | { | ||
+ | produitchoisiFromBdd = choixBdd.getProduitWithid(i); | ||
+ | if (produitchoisiFromBdd != null){ | ||
+ | HashMap<String, String> map = new HashMap<String, String>(); | ||
+ | map.put("titre", produitchoisiFromBdd.toString2()); | ||
+ | map.put("description", "Produit"); | ||
+ | map.put("img", String.valueOf(R.drawable.x)); | ||
+ | listItem.add(map); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | choixBdd.close(); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | protected void affichageliste (){ | ||
+ | maListViewPerso = (ListView) findViewById(R.id.listview); | ||
+ | //Création d'un SimpleAdapter qui se chargera de mettre les items présents dans notre list (listItem) dans la vue affichageitem | ||
+ | SimpleAdapter mSchedule = new SimpleAdapter (ProjetActivity.this.getBaseContext(), listItem, R.layout.affichageitem, | ||
+ | new String[] {"img", "titre", "description"}, new int[] {R.id.img, R.id.titre, R.id.description}); | ||
+ | //On attribut à notre listView l'adapter que l'on vient de créer | ||
+ | maListViewPerso.setAdapter(mSchedule); | ||
+ | maListViewPerso.setOnItemClickListener(new OnItemClickListener() { | ||
+ | @SuppressWarnings("unchecked") | ||
+ | public void onItemClick(AdapterView<?> a, View v, int position, long id) { | ||
+ | //on récupère la HashMap contenant les infos de notre item (titre, description, img) | ||
+ | HashMap<String, String> map = (HashMap<String, String>) maListViewPerso.getItemAtPosition(position); | ||
+ | //on créer une boite de dialogue | ||
+ | AlertDialog.Builder adb = new AlertDialog.Builder(ProjetActivity.this); | ||
+ | //on attribut un titre à notre boite de dialogue | ||
+ | adb.setTitle("suppression produit"); | ||
+ | //on insère un message à notre boite de dialogue, et ici on affiche le titre de l'item cliqué | ||
+ | adb.setMessage("suppression de : "+map.get("titre")); | ||
+ | //on indique que l'on veut le bouton ok à notre boite de dialogue | ||
+ | adb.setPositiveButton("Ok", null); | ||
+ | //adb.setNegativeButton("Annuler", null); | ||
+ | //on affiche la boite de dialogue | ||
+ | adb.show(); | ||
+ | |||
+ | |||
+ | listItem.remove(position); | ||
+ | choixBdd.open(); | ||
+ | choixBdd.removeProduitWithID(position+1); | ||
+ | choixBdd.close(); | ||
+ | remplirtable(); | ||
+ | affichageliste(); | ||
+ | |||
+ | |||
+ | } | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | |||
+ | } | ||
=== Résultats === | === Résultats === | ||
+ | |||
+ | |||
+ | == Rapport == | ||
+ | |||
+ | [[media:rapport_projet_robot_guidage.pdf]] |
Version actuelle datée du 1 juin 2012 à 16:22
Présentation
Ce projet s'inscrit dans le cadre de notre quatrième année d'étude au département IMA de l'école d'ingénieur Polytech'Lille.
Il a été proposé par le département R&D de l'entreprise Oxylane dans le cadre d'une coopération avec le département.
L'objectif de ce projet est de créer un robot de guidage qui devrait être utilisable dans un magasin quel qu'il soit.
Ce robot devrait être capable de se localiser dans un magasin suivant les produits recherchés, le principe étant que le client puisse sélectionner les produit sur une tablette tactile associée au robot. Ce dernier commandé par un contrôleur arduino relié à la tablette devrai utiliser des point de repères afin de déterminer l'emplacement de chaque rayon.
L'ensemble du matériel nécessaire ( robot, tablette, capteur, etc...) à ce projet sont commandés via des fournisseur et sur proposition des étudiants au tuteur de projet.
Les étapes de réalisation de ce projet sont détaillées dans les parties suivantes.
Préparation du projet
Matériel requis
- Robot + capteurs
- Tablette
- Arduino
- Outils de programmation
Matériel à acheter
- Platine ADK
- Robot
- capteur
- quincaillerie
Avancement du projet
Objectifs des différentes séances
1ere séance: Lors de cette première séance Nous nous sommes fixés comme objectifs d'effectuer une recherche des caractéristiques du robot de guidage et une conception d'un cahier des charges réduit. Il s'est donc agit de faire une recherche sur internet des différents modèles de robots respectant notre budget.
2ème séance: La deuxième séance s'est axée sur l'installation des différents paquets nécessaires pour créer une application Android permettant l'affichage d'un message sur l'écran de la tablette tactile.
3ème et 4ème séance: Ces 2 séances sont axées sur la création d'une application Android permettant de sélectionner une liste de produit et de commander le robot par la suite. Il s'agit donc de créer une base de données comportant les objets et les selections effectuées par l'utilisateur.
5ème séance: Les bases de données ayant été créées il faut à présent relier ces bases à notre interface utilisateur de manière à stocker les images et les différentes informations du magasin et des choix utilisateurs.
Réalisations concrètes
Séances
Première séance
Nous avons effectué des recherches sur internet concernant différents modèles de robot pouvant respecter le cahier des charges. Nous avons comparé différents modèles et avons choisi un robot mobile FB004 fabriqué par FiveBot.
2 fournisseurs différents proposent ce robot : Robotshop à 751.83 euros et génération robots à 705 euros ( seul problème chez ces derniers le robots n'est pas en stock) . Ce robot possède les caractéristiques indiqué ci dessous.
Ainsi afin de respecter la norme de taille d'environ 1,5m pour un utilisateur humain, nous avons décidé de rajouter des barres en alluminium commandées chez radiospares
( Disponibilité disponible(s) - En stock pour livraison le lendemain Code RS 493-8319 Fabricant Bosch Rexroth Référence fabricant R987160855 Etat RoHS Sans objet) Pour abaisser le centre de gravité du robot complet nous utiliserons des roulettes de soutients qui permettront de gérer l'équilibre de robot
La liste des éléments livrés par commande reste la meme quel que soit le fournisseur du robot
Kit Robot Mobile à 2 Roues Motrices Compatible Arduino
Caractéristiques techniques du robot Fivebot FB-004 Châssis
- Apparence : châssis circulaire
- Longueur : 357mm
- Largeur : 313mm
- Hauteur : 267mm
- Garde au sol : 39mm
- Matériau du châssis : Aluminium, acier
- Vitesse max : 0.8m/s
- Propulsion : 2 roues motrices différentielles, 1 roue libre
- Pente franchissable : 20°
- Charge utile : 10kg
- Compatibilité mini-ITX : Oui
Encodeurs
- Technologie : optique
- Nombre de voies : 2
- Résolution : 12 tops par tour de roue
Alimentation
- Batterie : 12V Ni-Mh
- Chargeur : Recharge lente Vin : 100-240V – Vout : 2.4-12V
- Durée de charge : 2 heures
- Autonomie : 30 minutes en continu
Roues
- Diamètre : 143mm
- Largeur : 30mm
- Matériau : polyuréthane
Motorisation
- Type : Faulhaber 12V DC sans fer
- Puissance : 17W
- Vitesse de rotation : 120 tours par minute
- Diamètre : 30mm
- Longueur : 42mm
- Longueur totale : 85mm
- Longueur de l’axe : 35mm
- Diamètre de l’axe : 6mm
- Courant à vide : 75mA
- Courant en charge : 1400mA
- Rapport de boîte de vitesse : 64 :1
Carte de contrôle principale
- Microcontrôleur ATMEGA328
- 14 Entrées / Sorties numériques
- 6 canaux de PWM
- 8 Entrées / Sorties analogiques
- Interface USB
- Circuit de protection électrique
- Interface série niveau TTL
- Support du module radio APC220
- 5 interfaces I2C
- Électronique de commande moteur 2A max
- Alimentation : USB ou alimentation externe 7-12V
- Ports d’alimentations disponibles : 5V/3.3V stabilisées et alimentation batterie
Carte d’extension
- Contrôle de 2 moteurs supplémentaires
- Support RS-485
- Support module Xbee
Programmation
- Environnement de programmation Arduino
- AVR Studio avec programmation par USB
Pour l'utilisation du robot, nous avons prévu en ce qui concerne l'alimentation d'utiliser des points de chargements muraux. Les suivis de trajectoire seront quant à eux adaptés à notre rythme d'avancement dans le projet. Nous partons tout de meme dans l'idée d'utiliser des capteur RFID au final. Nous essayerons avant cela de réaliser des suivi de lignes colorées ou blanches.
Deuxième séance
Nous avons installé les différents paquets java et eclipse nécessaire pour réaliser les programmes sous android. Nous avons connu de nombreux problèmes lors de l'installation des plugins sur eclipse. Ces problèmes ont été dus en premier lieu à un problème de proxy que nous avons par la suite configuré puis à un problème de lien de téléchargement qui n'était plus existants. Nous avons alors récupéré un dossier de plugins déjà téléchargés que nous avons associé au logiciel. Nous avons alors créé une application affichant " hello world" sur l'écran d'une tablette ( Motorola XOOM). Le code correspondant à l'affichage d'un message sur l'écran est le suivant:
package com.google.android.hellosdz;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloSdZ extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Hello World !");
setContentView(tv);
}
}
Troisième et quatrième séances
Nous avons conçu une application permettant à l'utilisateur de sélectionner un produit suivant une galerie. Pour Cela nous avons d'abord utilisé une base de d'images correspondant au produits. L'utilisateur peut ainsi choisir le produit et appuyer sur un bouton pour valider. Cette première version, nous avons pensé l'améliorer en utilisant une base de données permettant de modifier plus facilement les données enregistrées. Nous avons donc commencé par étudier la syntaxe du SQLite avec Android à l'aide d'un exemple portant sur une base de données de livres. Le programme nous permet ainsi de réaliser 3 opérations: entrez une donnée, modifier une donnée et supprimer une donnée. Ceci nous permet d'envisager des choix multiples pour l'utilisateur qui verra le robot corriger l'ordre de ses choix suivant la distance de chaque produit.
Cinquième séance
Nous avons amélioré l'interface utilisateur de la tablette en incluant des boutons "add" "delete" et "confirm". Ces derniers permettant à l'utilisateur d'ajouter un produit à une liste ou de la supprimer et également de la valider cette liste. Nous n'avons par contre pas pu tenir nos objectifs vis à vis de la base de données. En effet nous créé une base de données de produit et avons réussi à faire correspondre les informations produits avec certaines images produits. Mais au niveau de l'application sur la tablette le fonctionnement ne correspond pas à celui attendu puisque les images n'apparaissent pas lorsqu'on relie la base de donnée et seule les informations sont visibles. Nous avons donc pensé à une nouvelles méthode d'approches qui pourrait simplifier l'interface. L'objectif final étant surtout la communication entre la tablette et le robot.
Sixième septième et huitième séances
A cause des nombreux décalages dans l'emploi du temps des projets suivant les filières, certaines parties n'ont pu être effectuées correctement. Cepedant durant les 3 séances , nous nous sommes rapprochés de notre application finale sur la tablette avec les différents paramètres des bases de données gérant les listes de produits. Nous avons entamé la programmation sous arduino en installant les différentes librairies et logiciels pour la communication tablette arduino. Nous avons établis un plan de communication défini par un transfert de certaines informations( numero produit, numero rayon) vers le arduino devant ensuite commander le robot.
A partir de la neuvième scéance
Code obtenu lors des scéances qui ont suivi.
package com.android.projet;
import java.util.ArrayList; import java.util.HashMap;
import android.view.*; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; import android.widget.AdapterView.OnItemClickListener; import android.widget.*;
public class ProjetActivity extends Activity {
//Création d'une instance de ma classe ProduitsBDD
private ListView maListViewPerso; int j = 0;
ProduitsBDD produitBdd = new ProduitsBDD(this, 1, "magasin"); ProduitsBDD choixBdd = new ProduitsBDD(this, 1, "client");
//Création de la ArrayList qui nous permettra de remplir la listView ArrayList<HashMap<String, String>> listItem = new ArrayList<HashMap<String, String>>();
/** Called when the activity is first created. */
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);
//Création d'un produit Produit produit1 = new Produit("d1d1", "fruits-cerise"); Produit produit2 = new Produit("d1g1","fruits-orange"); Produit produit3 = new Produit("g1d1", "légumes-aubergine"); Produit produit4 = new Produit("g1g1", "légumes-pommedeterre"); Produit produit5 = new Produit("d2d1", "vetements-chemise"); Produit produit6 = new Produit("d2g1", "vetements-pantalon"); Produit produit7 = new Produit("g2d1","chaussures-botte"); Produit produit8 = new Produit("g2g1", "chaussures-basket"); Produit produit9 = new Produit("d3d1", "high tech-tablette"); Produit produit10 = new Produit("d3g1", "high tech-pc"); Produit produit11 = new Produit("g3d1", "cuisine-four"); Produit produit12 = new Produit("g3g1", "cuisine-marmite"); Produit produit13 = new Produit("d4d1", "petit déjeuner-pain"); Produit produit14 = new Produit("d4g1", "petit déjeuner-lait"); Produit produit15 = new Produit("g4d1", "hygiene-Mr propre"); Produit produit16 = new Produit("g4g1", "hygiene-Mir"); Produit produit17 = new Produit("d5d1", "beauté-maquillage"); Produit produit18 = new Produit("d5g1", "beauté-shampoing"); Produit produit19 = new Produit("g5d1", "boisson-soda"); Produit produit20 = new Produit("g5g1","boisson-vin");
choixBdd.open(); choixBdd.upgrade(); choixBdd.close(); //On ouvre la base de données pour écrire dedans produitBdd.open();
produitBdd.upgrade(); //On insère le produit que l'on vient de créer produitBdd.insertProduit(produit1); produitBdd.insertProduit(produit2); produitBdd.insertProduit(produit3); produitBdd.insertProduit(produit4); produitBdd.insertProduit(produit5); produitBdd.insertProduit(produit6); produitBdd.insertProduit(produit7); produitBdd.insertProduit(produit8); produitBdd.insertProduit(produit9); produitBdd.insertProduit(produit10); produitBdd.insertProduit(produit11); produitBdd.insertProduit(produit12); produitBdd.insertProduit(produit13); produitBdd.insertProduit(produit14); produitBdd.insertProduit(produit15); produitBdd.insertProduit(produit16); produitBdd.insertProduit(produit17); produitBdd.insertProduit(produit18); produitBdd.insertProduit(produit19); produitBdd.insertProduit(produit20);
Gallery gallery = (Gallery) findViewById(R.id.gallery1); gallery.setAdapter(new ImageAdaptergallery(this)); gallery.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int position, long id) { chooser(position); } });
//Bouton visualiser liste final Button button = (Button) findViewById(R.id.button1); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { remplirtable(); affichageliste(); } }); //bouton supprimer liste final Button button2 = (Button) findViewById(R.id.button2); button2.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { choixBdd.open(); choixBdd.upgrade(); choixBdd.close(); listItem.clear(); j=0; affichageliste(); } }); produitBdd.close(); }
protected void chooser(int num) { produitBdd.open(); choixBdd.open();
Produit produitchoisiFromBdd = produitBdd.getProduitWithid(num+1); GridView gridview1 = (GridView) findViewById(R.id.gridview1); //GridView gridview = (GridView) findViewById(R.id.gridview); if(produitchoisiFromBdd != null){ choixBdd.insertProduit(produitchoisiFromBdd) ; //On affiche les infos du produit dans un Toast Toast.makeText(this, produitchoisiFromBdd.toString(), Toast.LENGTH_LONG).show(); gridview1.setAdapter(new Image2Adapter(this, num)); } //else { //Toast.makeText(this,"LISTE PLEINE !!!!\n Veuillez valider votre liste ou la supprimer", Toast.LENGTH_LONG).show(); //} remplirtable(); affichageliste(); produitBdd.close(); choixBdd.close(); }
/** protected void agencement() { int i; Produit produitchoisiFromBdd; Produit fin = new Produit("fin","fin"); choixBdd.open(); for(i=1; i<choixBdd.getcountproduit();i++) { if (choixBdd.getProduitWithid(i) == fin) { produitchoisiFromBdd = choixBdd.getProduitWithid(i); if (choixBdd.getProduitWithid(i+1)!=null); {choixBdd.updateProduit(i, choixBdd.getProduitWithid(i+1)); choixBdd.updateProduit(i+1, produitchoisiFromBdd);} } } choixBdd.close(); } **/
protected void remplirtable() {
Produit produitchoisiFromBdd; choixBdd.open(); listItem.clear(); int i=1; //On affiche les infos du produit dans un Toast for(i=1;i<=choixBdd.getcountproduit();i++) { produitchoisiFromBdd = choixBdd.getProduitWithid(i); if (produitchoisiFromBdd != null){ HashMap<String, String> map = new HashMap<String, String>(); map.put("titre", produitchoisiFromBdd.toString2()); map.put("description", "Produit"); map.put("img", String.valueOf(R.drawable.x)); listItem.add(map); } } choixBdd.close(); } protected void affichageliste (){ maListViewPerso = (ListView) findViewById(R.id.listview); //Création d'un SimpleAdapter qui se chargera de mettre les items présents dans notre list (listItem) dans la vue affichageitem SimpleAdapter mSchedule = new SimpleAdapter (ProjetActivity.this.getBaseContext(), listItem, R.layout.affichageitem, new String[] {"img", "titre", "description"}, new int[] {R.id.img, R.id.titre, R.id.description}); //On attribut à notre listView l'adapter que l'on vient de créer maListViewPerso.setAdapter(mSchedule); maListViewPerso.setOnItemClickListener(new OnItemClickListener() {
@SuppressWarnings("unchecked")
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
//on récupère la HashMap contenant les infos de notre item (titre, description, img)
HashMap<String, String> map = (HashMap<String, String>) maListViewPerso.getItemAtPosition(position); //on créer une boite de dialogue AlertDialog.Builder adb = new AlertDialog.Builder(ProjetActivity.this); //on attribut un titre à notre boite de dialogue adb.setTitle("suppression produit"); //on insère un message à notre boite de dialogue, et ici on affiche le titre de l'item cliqué adb.setMessage("suppression de : "+map.get("titre")); //on indique que l'on veut le bouton ok à notre boite de dialogue adb.setPositiveButton("Ok", null); //adb.setNegativeButton("Annuler", null); //on affiche la boite de dialogue adb.show(); listItem.remove(position); choixBdd.open(); choixBdd.removeProduitWithID(position+1); choixBdd.close(); remplirtable(); affichageliste(); } }); }
}