IMA3/IMA4 2018/2020 P17
Sommaire
- 1 Présentation générale
- 2 Analyse du projet
- 3 Préparation du projet
- 4 Réalisation du Projet
Présentation générale
Ce projet est mené en collaboration avec Marion Binninger, ergothérapeute à APF (Association Paralysés de France) Environnement et encadré par Alexandre Boé , Xavier Redon , Thomas Vantroys. Selon l'organisation mondiale de la santé (OMS) environ 1.25 millions de personnes meurent chaque année des suites d'accidents de la route . Dans le cas particulier des enfants ce problème est à prendre avec beaucoup de sérieux étant donnée la circulation de plus en plus dense dans le monde . Notre projet a pour but de mettre un accent sur les difficultés attentionnelles des enfants,qui sont un frein à leurs déplacements et à l'autonomie et de trouver une solution .
Description
Ce projet a pour but d'aider un jeune ayant d'importantes difficultés attentionnelles et des réactions impulsives à se déplacer en ville . Étant donné plusieurs cas réels, due à l'inattention des enfants en traversants la rue ,on a pensé à étudier différentes solutions à base de capteurs (luminosité, son, voire caméra) pour remonter une alarme lors de l'approche d'une rue.
Objectifs
Le principal déficit d'attention à corriger est la traversée de rues et pour cela nous avons pour objectifs de :
- choisir des capteurs appropriés à la détection de l'approche des voitures .
- définir les conditions de réaction des capteurs (intensité des sons , distance....).
- analyser la réponse des capteurs et la comparer aux consignes que nous auront définies .
- Selon le résultat de la comparaison , une alerte doit être déclenchée si nécessaire pour attirer l'attention de la personne concernée .
Analyse du projet
Positionnement par rapport à l'existant
Analyse du premier concurrent
Notre premier concurrent serait l'accompagnant de l'enfant tel que les parents,la nounou.
Avantages :
- avoir une personne consciente comme accompagnant est certainement plus sécurisé et donne aux parents plus de garantie sur l'état de leur enfant .
- avoir une personne qui s'adapte aux différentes situations qui se présentent et trouve des solutions adéquates .
- éviter une grosse dépense pour notre produit .
Inconvénients :
- limite l’indépendance de l'enfant et donc son autonomie dans la rue .
- éviter que l'enfant soit éternellement assisté ce qui provoquerait à la longue des problèmes en confiance en soi .
- le tuteur doit être toujours disponible ce qui n'est pas toujours facile .
Analyse du second concurrent
Notre second concurrent serait Direct Line, une société d’assurance qui a collaboré avec le cabinet d’architecture Umbrellium pour créer un nouveau «Smart Crossing», baptisé Starling Crossing, conçu pour aider à maintenir la sécurité des piétons. En effet, encore sous une forme de prototype , ce nouveau <smart crossing> n'est pas encore appliqué dans notre vie quotidienne. Avantages:
- Il est apte à satisfaire tous les cas possibles sur le trafique.
- Il n'est pas restreint à un type de personnes.
- Il est disponible à tout moment, car il est appliqué sur la route.
- C'est l'Etat qui sponsorise l'application de ce produit.
Inconvénients:
- Le Coût de l'application du produit est excessivement cher.
- Il utilisent énormément de capteurs, de cameras ... , qu'une panne peut endommager le fonctionnement du système.
Scénario d'usage du produit ou du concept envisagé
Je m'appelle Nino, je suis un petit garçon plein de vie, j'aime m'amuser avec mes amis. Mes parents me laisse aller à l'école tout seul, comme un grand garçon, j'aime beaucoup car je rencontre mes amis en chemin. Mais.. depuis mon accident, je ne suis plus aussi indépendant, mes parents m'ont pris une nounou qui me dépose tous les matins à l'école car depuis mon accident j'ai des troubles attentionnels, je perds très vite ma concentration et donc mes parents ont vraiment peur de me laisser traversé la route tout seul. Cependant, depuis peu ils m'ont achetés un "..." et son utilisation est tellement facile, il me permet de reprendre ma concentration surtout lorsque je traverse la route, il m'alerte losqu'une voiture se rapproche de moi. Ainsi, mes parents n'ont plus peur de me laisser partir à l'école seul comme un grand, je suis si content, mon accident m'avait enlevé mon indépendance et aujourd'hui, je me sens comme les autres enfants.
Questions difficiles
- quelles types de capteurs doit-on utiliser pour réaliser ce projet ? (répondu en partie préparation de projet)
- comment choisir le type d'alimentation pour maintenir le fonctionnement du dispositif toute la journée sans devoir utiliser bes batteries lourdes ?
- Comment faire pour assembler les composants dans une carte électronique assez petite pour ne pas être encombrant?
Réponses aux Questions difficiles
- Le dispositif étant destiné à un usage quotidien et pour pallier au problème d'autonomie, nous pouvons utiliser une batterie rechargeable qui tiendra en autonomie pendant toute l'utilisation par l'enfant.
- Pour réduire l'encombrement du dispositif, nous voulons dessiner un schéma PCB sur le logiciel Altium.
Bibliographie et webographie
- https://www.evolving-science.com/environment-smart-cities/smart-crossing-designed-make-pedestrians-safer-00429
- http://umbrellium.co.uk/initiatives/starling-crossing/
- https://www.carnetdumaker.net/articles/mesurer-une-distance-avec-un-capteur-ultrason-hc-sr04-et-une-carte-arduino-genuino/#principe-de-fonctionnement-du-capteur
Préparation du projet
- <<Que choisir entre LIDAR ,RADAR et ultrasons ? Quel est le plus adéquat pour notre projet ?>>
- Que souhaite-on mesurer? la distance entre l'enfant et les voitures.
- Quelle condition environnementale? Un environnement urbain.
- Quelle distance entre l'émetteur et la cible? Environ plus de 50m.
- ULTRASON:
La mesure par ultrason est basé sur les ondes sonores, ils sont insensibles aux couleurs, à la brillance et à la transparence. Cependant, son utilisation est adéquat pour une surveillance de volume et pour les distances courtes moins de 8m.
- LIDAR:
La mesure par lidar est basé sur la détection et l'estimation de la distance par la lumière. il s'agit d'une technologie de mesure à distance fondée sur l'analyse des propriétés d'un faisceau de lumière renvoyé vers son émetteur. Cette technique est parfaite lorsqu'on souhaite une indication de position précise, elle est idéale pour les petits objets et à une distance allant jusqu'à 200m. L'utilisation de la technologie LiDAR 2D ou 3D est adéquate lorsqu’une indication de position précise ou une classification d’objet sera requise, ou bien lorsqu’une grande zone de numération sera impérative (Champs de vue horizontal jusqu’à 360°, Champs de vue vertical jusqu’à 15°). Par contre, il est vivement déconseillé d’utiliser cette méthode sur de l’eau, ou dans un environnement difficile (fortes chutes de neige, pluie, brouillard, poussière…).
- RADAR:
Le fonctionnement du RaDAR est proche de la technologie par ultrasons, il permet de calculer la distance, le mouvement et l’angle. Le radar va devoir mesurer à plusieurs reprises. Les données vont être comparées et vérifiées, et si les résultats sont identiques alors l’objet sera reconnu. C’est ce que l’on appelle le suivi (ou tracking). La technologie RaDAR sera préconisée pour la détection d’objet volumineux car il y aura une plus grande surface de réflexion (RCS) et sera donc plus facile à détecter. L’objet à détecter sera de préférence métallique (le métal étant un réflecteur parfait pour cette technique de mesure). Le RaDAR est capable de mesurer de grands volumes jusqu’à plusieurs dizaines (voir centaines) de mètres, mêmes dans des conditions météorologiques extrêmes (pluie, neige , etc).
- <<Quels capteurs sont adéquats pour notre projet?>>:
- HB100 microwave : détecte la distance et calcule la vitesse de tout les objets qui se trouvent dans un rayon de 16m avec un angle de 72° horizentalement.
- Capteur infrarouge C7288 ou Amg8833: detécte la présence des personnes et/ou d'animaux à une distance maximale de 7m.
- utilisation : le capteur amg8833 détecte la présence
- Conclusion:
D'après l'analyse de ces trois types de captations, il en découle que le radar est le plus adéquat à notre projet. En effet, nous aurons besoin d'une grande surface de réflexion, et notre cible principale sera les voitures.
Cahier des charges du groupe
Pour répondre aux besoins de l'enfant souffrant de troubles attentionnels ,on propose:
- Pour le calcul de la vitesse des voitures, on utilisera un capteur .
- Pour alerter l'enfant du danger (voitures, vélos...) on utilisera une vibration ou une alarme .
- Pour assurer l'énergie qui sera consommée par notre produit, on utilisera une batterie qui doit être légère.
- Pour implanter l'algorithme, on utilisera un arduino.
Cahier des charges des équipes
Equipe 1
Hua Jing et Mahmoudi Sanae :
- Ecriture de code .
- Branchement de dispositif: Arduino , capteur ultason , vibreur.
- Tester des programmes .
- Améliorer le fonctionnement du programme .
Equipe 2
Raouto Emilie
- Recherche des informations sur le dispositif et répondre aux questions suivantes :quel est le meilleur capteur à utiliser, quel types d'alimentation il faut utiliser ,
- Remplissage de WIKI .
- Préparations des questions à poser lors de la visite de l'enfant ;
- rejoindre l'équipe 1 pour améliorer le code .
Choix techniques : matériel et logiciel
Pour réaliser notre projet, on veut tester notre idée avec un capteur ultrason, un vibeur et un Arduino. On utilise les composants électroniques suivants:
Composant | Image |
---|---|
Capteur ultrasons HC-SR04 |
|
Vibreur |
|
Arduino MEGA 2560 |
Equipe 1 & Equipe 2
CAPTEUR HC-SR04
Le capteur HC-SR04 est un capteur à ultrason low cost. Ce capteur fonctionne avec une tension d'alimentation de 5 volts, dispose d'un angle de mesure de 15° environ et permet de faire des mesures de distance entre 2 centimètres et 4 mètres avec une précision de 3mm (en théorie, dans la pratique ce n'est pas tout à fait exact).
Pour l'information de ce capteur on a trouvé plusieur sites comme https://randomnerdtutorials.com/complete-guide-for-ultrasonic-sensor-hc-sr04/ https://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/
Le MONTAGE
L'alimentation 5V de la carte Arduino va sur la broche VCC du capteur. La broche GND de la carte Arduino va sur la broche GND du capteur. La broche D2 de la carte Arduino va sur la broche TRIGGER du capteur. La broche D3 de la carte Arduino va sur la broche ECHO du capteur. La broche D9 de la carte Arduino est connectée à un vibreur .
Liste des tâches à effectuer
Equipe 1
- 1.Connaĩtre le datasheet de capteur ultrson qu'on a choisi.
- 2.Connecter des branches de capteur ultrason, vibreur et Arduino
- 3.Tester le vibreur
- 4.Tester le capteur avec le code exemple pour mesurer le distance
- 5.Ajouter le code de calculer la vitesse selon distance
- 6.Installer le condition de activer le vibreur
- 7.Améliorer le programme pour fonctionner bien
Equipe 2
- 1.Chercher des informations des différents capteurs sur Internet
- 2.Comparer les capacités entre des capteurs
- 3.Trouver le capteur qui satisfait meilleur notre projet
- 4.Chercher des informations pour répondre les quesions difficiles
- 5.Remplir le reste de Wiki
- 6.Préparer des qustions pour enfant
- 7.Améliorer le code dont Equipe 1 a fait
Calendrier prévisionnel
Le calendrier prévisionnel peut se concrétiser sous la forme d'un diagramme de GANTT.
Equipe 1
Equipe 2
Réalisation du Projet
Projet S6
Eventuellement créer des sous-pages par équipe avec le compte-rendu des réunions de groupe sur cette page principale.
Semaine 4
- Lecture de sujet
- Chercher plus d'information sur l'état des enfants qui souffrent des troubles attentionnels pour trouver la bonne solution qui va satisfaire les besoins de l'enfant
- Poser le maximum de questions pour bien comprendre le sujet .
- Débuter le scénario d'usage.
- Recherche de différentes solutions pour notre problème.
Semaine 5
Lors de cette séance, nous avons eu l'opportunité de rencontrer une intervenante extérieure pour mieux comprendre le sujet et améliorer le scénario d'usage. Etant donné que notre dispositif sera utilisé par un enfant handicapé , cette séance nous a surtout permis de se mettre dans la peau de l'utilisateur pour mieux assimiler ses besoins, comprendre les attentes éventuelles et ainsi réfléchir à une solution adéquate.
La séance a commencé par un petit pitch pour que l'intervenante ait une idée assez globale de notre projet. Après ce pitch nous avons eu quelques remarques instructives pour nous améliorer. Puis nous avons dû donner une perception du projet en utilisant de nouvelles méthodes efficaces et inhabituelles telles que des cartes et des legos.
A partir des informations collectées suite à cette réflexion, nous avons pu imaginer un usager type , c'est l'étape de la 'collecte'. Avec les cartes qui étaient à notre disposition nous avons créer un scénario d'usage en s'appuyant sur l'image d'un usager type (voir image).
Au terme de cette séance, nous avons améliorer notre scénario d'usage, nos idées sur le projet étaient un peu plus claires, et enfin nous avons pu lister plusieurs questions à poser à l'enfant lors d'une éventuelle rencontre.
Semaine 6
- Recherche de types de captation entre(LIDAR,RADAR et Ultrasons ) et caractéristiques de chacun d'eux et par conséquent nous avons choisi d'utiliser le RADAR car ses caractéristiques correspondaient à nos attentes .
- Élaborer le cahier de charge .
Semaine 7
Durant cette séance on a débuter l'écriture de notre code (langage pour Arduino) parmi les principales fonctions dans notre code :
- Fonction pour mesurer la distance entre le capteur ultrason et les objet qui l'entoure .
- Fonction pour le calcul de la vitesse en se basant sur deux distances mesurées successivement avec un delay de 200 ms .
- Fonction qui permettra d'activer la vibration dans le cas où on a dépassé la limite de la vitesse (la voiture se rapproche de l'enfant ) .
- Branchement entre arduino, capteur et keyboard .
Semaine 8
Continuer le code et le tester . Ajout de la vibreur dans notre Montage .
Semaine 9
- Connection de la vibration sur l'arduino (broche ~9).
- Structuration du programme en sous-programmes.
- Adaptation du programme pour prendre en compte la vibration ,si la vitesse est supérieure à 20cm/s.
Semaine 10
Améliorer le code et s'assurer que ça fonctionne bien. corriger tous ce qui manquait sur le Wiki.
const byte TRIGGER_PIN = 2; // Broche TRIGGER const byte ECHO_PIN = 3; // Broche ECHO const byte vibration = 10; //Beoche vibreur const unsigned long MEASURE_TIMEOUT = 25000UL; // 25ms = ~8m à 340m/s Constantes pour le timeout const float SOUND_SPEED = 340.0 / 1000; //Vitesse du son dans l'air en mm/us long distance0 = 0; int cpt =0; void setup() { /* Initialise le port série */ Serial.begin(115200); /* Initialise les broches */ pinMode(TRIGGER_PIN, OUTPUT); digitalWrite(TRIGGER_PIN, LOW); // La broche TRIGGER doit être à LOW au repos pinMode(ECHO_PIN, INPUT); pinMode(vibration, OUTPUT); digitalWrite(vibration,LOW); } float test_dis() //mesurer la distance et calculer la vitesse { /* 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); delay(1000); /* 3. Calcul la distance à partir du temps mesuré */ float distance_mm = measure / 2.0 * SOUND_SPEED; return distance_mm; } void loop() { if(cpt > 1 ) { digitalWrite(vibration,HIGH); //si il y a deux 0.5s on trouve la vitesse > 5.0 on active vibration cpt = 0; delay(1000); } if(cpt==0) { digitalWrite(vibration,LOW); } float dis0=test_dis(); //mesurer la distance ancient en mm Serial.print(F(" Distance0: ")); Serial.print(dis0/10); delay(100); //attendre 0.5s pour mesurer le 2ème distance float dis1=test_dis(); //mesurer la distance nouvelle en mm Serial.print("cm Distance1: "); Serial.print(dis1/10); Serial.print("cm "); float vitesse_cm_s=( (dis0 - dis1 ) / 10.0) * 10 ; if(vitesse_cm_s > 5.0) cpt=cpt+1; //chaque fois la vitesse est > 5.0 cm/s cpt s'incrmente 1 else cpt = 0; Serial.print(F(" Cpt: ")); Serial.print(cpt); Serial.print(F(" Vistesse: ")); Serial.print(vitesse_cm_s); Serial.println(F(" cm/s")); /* Délai d'attente pour éviter d'afficher trop de résultats à la seconde */ delay(100);// en ms }
Semaine 11
- Fabrication du boitier:
Nous avons pris rendez-vous au fabricarium, on a fait une formation d'une heure pour apprendre à utiliser la découpe laser. A l'issue de cette formation, nous avons pris des mesures adéquates pour fabriquer le boitier qui abritera les éléments de notre dispositif. De ce fait, nous avons fait en sorte que le boitier soit le plus petit possible pour permettre qu'il soit facilement transportable.
Semaine 12
- Rencontre avec Souleyman:
Nous nous sommes rendu à l'Institut d'Education Motrice de Lille, une école spécialisée Jules Ferry, afin de rencontrer Souleyman. Dans une première approche, nous nous sommes présentés afin de faire plus ample connaissance avec lui. Nous avons pu en savoir plus sur son handicap et aussi échanger avec sa tutrice. Suite à cet échange, on a pu éclaircir nos idées sur ses besoins et nous avons découvert que son bras gauche est moins actif, nous avons dû modifier la structure du dispositif. Ensuite, nous avons tester le prototype de notre produit et avoir les remarques de la tutrice. Et pour finir, grâce à celle-ci, nous avons eu d'autres recommandations dans le but de répondre parfaitement aux besoins de l'enfant parmi lesquelles:
- Une alerte sonore/vocale
- Un téléphone comme gps
- Informer l'enfant qu'il peut traverser(car il reste longtemps dans la vérification).
Cette rencontre a vraiment été bénéfique pour nous, dans l'optique où nous avons pu mieux comprendre les besoins de Souleyman et améliorer le dispositif pour le semestre suivant.
Documents Rendus
Projet S7
Semaine 1
La Fusion
Suite au différents changements dans le groupe, il y a eu une fusion entre le groupe p18 et le nôtre en vue de la proximité de nos sujets respectifs. Dans les deux projets, il y a plusieurs modules communs, donc pour un travail efficace nous travaillons ensemble en se répartissant les tâches.
Module | P17&P18 | P18 |
---|---|---|
Capteurs |
Distance |
Relief, profondeur |
Actionneurs |
Minis moteurs vibrants |
Moteurs DC pour la main |
Energie |
Batterie |
Autonomie d'une/deux heures Batterie dans un sac à dos |
PCB gérant les actionneurs et les parties sonores |
Gestion enregistrements sonores Moteurs vibrants |
Moteurs pour la main Liaison série vers les données des capteurs |
Répartition des Tâches
- Equipe 1: Actionneurs(vibreur avec puissance variable, son) -> Laurine et Clara
- Equipe 2: Capteurs(distance, profondeur) -> Emilie, Nour et Caroline
- Equipe 3: Cartes(FPGA ou microcontrôleur) -> Jing et Ming
Cependant, nous avons des tâches spécifique à notre groupe telles que: l'énergie à utiliser et la solution pour pouvoir capter les feux de circulation. A la fin du S7, notre objectif est d'avoir la liste du matériels afin de réaliser le dispositif final.
Composants choisis
- Un capteur de distance-> RPLiDAR A1M8-360 Degree LaserScanner Kit - 12M RangeRoHS
- UneRaspberry pi 3 ou 4
- Une batterie
- Un webcam: Elle sera combiné avec la raspberry pi pour un traitement d'images
Semaine 2
Après la fusion en semestre 7, on a séparé en 3 groupes pour faire une liste de composants possibles pour notre produit final et ensuite on choisira des composants qui suffisent meilleur nos besoins dans 2 ou 3 semaines pour on peut commencer faire de travaux suivants.
Pendant cette séance, avec le suggestion du prof, monsieur Alexandre Boé, nous avons trouvé une première liste des différent matériaux possibles pour notre poejet, pour cela on cherche des différent produit sur Internet et compare leur performance:
Equipe 1 :
- Vibreurs : La question est: Quel est le meilleur moyen pour faire varier l'intensité des vibrations dans le but de créer une communication entre le prototype et l'enfant (P17) surtout pour les urgences.
- Choix des moteurs pour la main, plus efficaces que ceux du prototype.
- Partie son : module MP3 pour sélectionner et lire enregistrements sur une carte microSD. Éventuel besoin d'un adaptateur jack/USB pour les écouteurs.
Equipe 2 :
- Recherche pour le choix entre deux capteurs le D415 et le D435, pour savoir s'ils seraient adéquats pour les différents besoins
Equipe 3 :
- Recherche des informations ou datasheet de FPGA, micro-processeur comme ATMEGA328 ou un produit qui déjà existe comme un Arduino ou une Raspberry.
- Comparer leurs performances selon notre besoins et nous avons faire une première préférence: une raspberry 3 est parfaitement suffisant de notre projet mais on n'est pas sûr. Et notre deuxième préférence est un micro-processeur comme ATMEGA328. On va demander les profs avec ces quesions pendant la prochaine séance.
Semaine 3
Avant cette séance on a déjà une primière liste de matériaux qui nous semblent possible pour notre projet, donc pendant cette séance nous avons tout d'abord enrichi notre liste pour nos matériaux peuvent suffire les besoins en différents environnement. Ensuite nous voulons démander des consigne du prof monsieur Alexandre Boé pour vérifier si nos matériaux sont possible, est-ce qu'on est dans la bonne direction, cependant malheureusement on n'a pas le temps à la fin de la séance.
Equipe 1 :
- Mettre en place différents stades de vibrations en fonction de la dangerosité d'un obstacle. Pour cela nous allons faire vibrer les moteurs par intermittence. Nous avons défini trois stades de danger. En premier, pour donner une indication, des vibrations séparées par un délai important. Dans le cas d'un obstacle ou d'un changement de relief plus important, le délai sera raccourci. Enfin, en cas de grand danger, les moteurs vibreraient en continu.
- Partie son :
Choix du module MP3 DFR0299 pour stocker et exploiter les enregistrements d'indications sonores.
Pour connecter les écouteurs, on placerait un port jack directement sur le PCB.
Équipe 2 :
- Besoin d'une Raspberry Pi 4 pour pouvoir traiter les images en utilisant une webcam (P17).
Équipe 3 :
- Vérifier si avec une Raspberry Pi 3 on peut contrôller un capteur de distance et un webcam pour scanner l'environnement de la Rue et envoyer les commandes pour avtiver un son et une vibration, surtout sa compléxité et son coût d'énergie, aussi son coût d'argent.
- Vérifier les même qustions pour des micro-processeur et FPGA.
Groupe :
- Discuter avec lesquels matériaux sont mieux pour notre cas, comme on sait qu'un enfant (le garçon Souleyman dans notre situation) qui a des limites, par emxemple, ce n'est pas réaliste de porter un produit lourd etc. Nous avons aussi discuté sur papier pour faire une liaison entre différentes parites.
Semaine 4
Donc pendant cette séance nous avons tout d'abord démandé la faisabilité de notre produit final par des composants dans notre deuxième liste au prof Alexandre Boé, avec des consignes il nous a montré, aussi il nous a montré un prototype d'un produit pour nous comprendre miexu des idées. Donc nous avons décidé de utiliser une raspberry pi 3 pour contrôller le webcam et aussi notre capteur de distance qui est un lidar parmi les choix possible.
Cepandant, nous avons mal compris ce que monsieur Alexandre Boé disait: il nous présentait des avantages et des inconvénients de la raspberry et du micro-processeur, mais on pensait que faut mieux faire une liaison de la raspberry et le micro-processeur et c'est pourquoi on va faire un PCB dans la suite. (C'est le commentaire ajouté après la soutenance)
Après nos recherches sur les capteurs D415 et D435 nous avons conclus qu'ils n'étaient pas adéquat pour nos besoins. Comme dans notre situation faut mieux le capteur de distance peut envoyer la distance de l'environnement, c'est-à-dire un ^capteur qui peut scanner l'environnement de 360 degrés .Donc nous avons définitivement pris comme capteur le Rplidar.
- Un capteur de distance-> RPLiDAR A1M8-360 Degree LaserScanner Kit - 12M RangeRoHS
- Ce capteur est beaucoup utilisé pour éviter des obstacles et pour la sécurité.Ce RPLIDAR A1M8 permet la mesure de distances de 0,15 à 12 m sur 360° grâce à un moteur autorisant une rotation complète. Cette rotation permet par exemple la cartographie de pièces, la modélisation d'un objet ou tout simplement l'évaluation d'une distance ce qui nous intéresse dans notre cas. Il peut communiquer via une liaison UART avec un microcontrôleur mais également avec un PC via une liaison micro-USB. La mesure de distance est basée sur une triangulation émise par le laser et autorise une acquisition rapide des mesures (8000 mesures par secondes). La fréquence d'échantillonnage est adaptée automatiquement en fonction de la vitesse de rotation du capteur Lidar par rapport à sa base.
- Caractéristiques importants de RPlidar A1M8
- Fréquence de mesure: 8000 mesures/sec
- Poids: 170 g
- Remarques
- Ce module peut être utilisé en intérieur et en extérieur mais est non résistant à l'eau.
- L'appareil ne peut pas effectuer de mesure si il est directement exposé aux rayons du soleil.
- L'appareil n'est pas trop lourd par rapport à sa précision de détection.
- L'appareil peut détecter tous les degrés de l'envrionnement.
- Raspberry pi : : Nous utilisons ce composant pour faire du traitement d'image dans le but de distinguer la couleur d'un feu de signalisation en utilisant une caméra webcam et aussi pour envoyer des commandes au lidar et recevoir des réponses.
- Pour ce faire, nous pouvons utiliser la librairie Opencv qui donne la possibilité de combiner une raspberry et une caméra. Elle a été dévéloppé par Intel spécialisé dans plusieurs domaines de traitement d'images: lire, écrire et afficher une image et aussi calculer le niveau d'histogramme de couleur.
- Lien our plus d'informations concernant l'installation de la librairie: https://www.pihomeserver.fr/en/2014/01/22/raspberry-pi-home-server-utiliser-opencv-avec-la-pi-camera/
Semaine 5
Comme au premier temps, on pense que il faut faire un PCB pour connecter la raspberry et un micro-processeur, qui est un peu près la même idée qu'autre groupe P18 donc pendant cette séance, après concevoir un plan de 3 vues pour le prototype sur un bras droite, et ensuite on commencer dessiner le schéma de la carte.
Tout d'abord, nous proposon notre prototype se met en 2 bras d'un enfant pour chaque lidar peut scanner 180 degrés de son coté. Ensuite on propose le webcam doit être en face du prototype donc il peut prendre des images ou des vidéo en face, c'est-à-dire la même direction d'avancement du enfant. Respectant ces consigne au-dessus, on propose un plan de 3 vues suivant:
En ce moment là nous avons aussi étudié le fonctionnement du lidar A1M8, un est le format de la sortie du lidar et un autre est des broches pour connecter la raspberry et le lidar.
- Le format contient 4 petites parties en mode normal qui sont:
- La distance en mm
- L'orientation en degré
- Le signe de commence un nouveau boucle en booléen
- La qualité de scannage en entiers entre 0 et 255
- Les broches pour connecter la raspberry et le lidar sont:
- Soit on utilise une un port USB comme un périphérique
- Soit on utilise une liaison série par RX/TX
Ensuite après discuter avec le groupe P18, on a choisi une liste de composant pour faire une carte PCB qui connecte la raspberry. Pour réaliser cette connexion, on propose mettre 40 broches au-dessous de la carte PCB qu'on va faire et au-dessur de la raspberry. Et les vibreurs et le port jack pour faire le son sont dans la carte aussi. Suivre des consignes, on propose une solution sur papier:
Semaine 6
Comme nous avons déjà proposé une solution de la carte PCB, donc pendant cette séance, nous avons faire le schéma d'abord sur le logiciel Altium et ensuite le PCB.
Cependant, nous avons eu des problèmes, c'est sur le logiciel Altium, il y a des composants qui ne sont pas là dans le bibliothèque, du coup c'est à nous de convevoir ces composants, considérant avec un autre logiciel Fritzing qui a un peu près la même fonction donc on a décidé de changer le logiciel. Ensuite, pendant cette séance nous avons conçu un schéma:
Et selon ce schéma, on fait un PCB en respectant la connexion dans le schéma précédent:
Cependant on est dans la mauvaise direction comme nous avons mal compris au début, en effet on n'a pas besoin de faire ce schéma ni le PCB, et le micro-processeur ATMEGA328 non plus car avec un raspberry c'est déjà suffisant. (c'est le commentaire ajouté après la soutenance)
Semaine 7
Comme nous avons déjà conçu le schéma et le PCB dans la séance précédente, pendant cette séance, on vérifie si avec ce PCB on peut réaliser notre but. Et comme nous avons vite fait le PCB donc on le corrige un peu pour il nous semble plus clair. Sauf cela, cette séance on a aussi un traval à faire, c'est l'environnement de la raspberry, c'est-à-dire comment on choisit le système installé dans la raspberry et comment on implémente nos algorithemes sur la raspberry, avec quel langage.
A la fin de la séance, on a décidé:
- Utiliser le système Raspbian avec un Desktop pour faciliter l'affichage et visualisation quand on a besoin. C'est différent que nous avons vu en cours TP Réseau.
- Utiliser la méthode de ssh qu'on a vu en cours de système pour faire la connexion surtout pour nous 3 peuvent travailler en même temps.
Documents Rendus
Projet S8
Semaine 1
Après la soutenance on a compris qu'on était dans la mauvaise direction donc on réfléchit dessus. Pendant cette primière séance, nous avons décidé de séparé les travaux en 3 parties, chaqu'un fait sa partie et à la fin on fait une fusion de 3 équipes:
- Equipe1: Webcam -> Ming Chen
- Equipe2: Lidar + Configuration de la raspberry -> Jing Hua
- Equipe3: MP3 Player -> Emilie Raouto
Donc on sépare la tâche totale en 3 partie:
- Une partie de webcam pour détecter les feux qui doit connaître le feu rouge, et si le feu maintenant est rouge il doit envoyer un message pour activer le vibreur et aussi le son.
- Une partie de lidar pour scanner l'environnement de l'utilisateur, et si une voiture (ou une chose rapide, un vélo par exemple) qui approche avec une vitesse dangereuse, il doit envpyer un message pour activer le vibreur et le son pareil qu'un webcam. Dans notre cas ici on considère avec 20km/h est déjà dangereuse dans la ville pour l'enfant souleyman.
- Une partie de actionneur qui contient 3 vibreurs et un haut-parleur. On utilise 3 vibreurs pour indiquer les niveaux de l'alerte qui dépend de la vitesse de la voiture et la distance entre la voiture et l'utilisateur.
Donc pendant cette séance chaqu'un étudie sa tâche et aussi la configuration de la raspberry. Tous les travaux de préparation doivent être fait avant des matériaux arrivent.
Semaine 2
Configuration
Avant préciser dans chaque tâche, on a demandé un raspberry pi 3 pour commencer la configuration par des étapes suivants:
- Tout d'abord, j'ai implémenté le système Raspbian sur la raspberry avec la carte SD, le système Raspbian est un système basé du système Debian Linux qui peut être implémenté dans chaque version de raspberry. On peut trouver des différentes versions sur le site officiel de raspberry. Ici j'ai choisi la version avec un desktop pour faciliter des testes avec l'affichage.(à la fin pour le produit final on n'a plus besoin de l'affichage, c'est juste pour tester l'algoritheme)
- Ensuite, j'essaie la connextion entre le pc et la raspberry par la liaison série en utilisant minicom puis je peux autoriser la connexion ssh sachant que l'addresse de raspberry est connu dans le même réseau après une configuration de Internet que je vais présenter dans la suite. Et pour le desktop il faut autoriser VNC qui est dans la même fenêtre que ssh. La commande sur terminal pour vérifier si la raspberry est bien connecté sur une interface de PC:
ls /dev/ttyUSB* lsusb
Après vérifier la connextion sur la raspberry, on utilise le minicom pour communiquer. Ensuite, il nous demande d'entrer le mot de passe, par défaut est raspberry. Jusqu'à maintenant on peut communiquer la raspberry avec ce terminal qui est le même pour un système Debian Linux. Le premier étape pour configurer la raspberry on tape la commande suivante:
sudo raspi-config
On peut voir une fenêtre avec un liste de configuration qu'on peut modifier:
Ici on choisit 5:Interface Options et on a une fenêtre suivante:
Et dans cette fenêtre on peut autoriser 2.SSH et 3.VNC pour la connexion en distance avec un termianl et avec un desktop.
Webcam
Pour la partie webcam,le but de cette partie est d'identifier le feu rouge, de rappeler à l'enfant de se concentrer sous forme de vibration lorsque le feu rouge est allumée.Donc,je pense que ma tâche peut être divisée en trois parties: 1. Écrivez un programme pour identifier des couleurs et des formes spécifiques. 2. Complétez la procédure ci-dessus afin que lorsqu'une forme d'une couleur spécifiée est reconnue, le vibreur se déclenche pour alerter l'enfant. 3. Optimisation. (En testant les procédures terminées, en découvrant les limites des procédures pour optimiser notre installation)
À s7, nous avons finalement décidé de programmer sur la base de RaspberryPi. Après avoir consulté les informations, j'ai trouvé une excellente bibliothèque de vision pour identifier les images --- openCV.
openCV
Le nom complet d'OpenCV est Open Source Computer Vision Library, qui est une bibliothèque de vision par ordinateur multiplateforme qui peut être utilisée pour développer des programmes de traitement d'image, de vision par ordinateur et de reconnaissance de formes en temps réel.Du coup,je pense que ce logiciel peut m'aider beaucoup.
Lidar
Pour la partie lidar, la tâche est de scanner l'environnement, c'est-à-dire 360 degrés au tour de l'utilisateur (dans notre prototype est 180 degrés car on veut tester le fonctionnement pour un côté d'adord), puis envoyer ces valeur dans un tableau (c'est juste pour suivre le format du code donné par l'entreprise sur github) à la raspberry pour qu'elle peut calculer la vitesse de chaque élément mobile (normalement on considère un élément avec une vitesse 0 ou avec une petite vitesse) selon le tableau. Et si cette vitesse arrive à la limite qu'on propose au début, la raspberry va contrôler ses sorties pour avtiver le vibreurs.(Comme au début l'équipe n'ai pas fait la fusion avec l'équipe 3 qui fait la partie son de la rasberry, le seul actionneur pour instant est de vibreur)
Semaine 3
Configuration
A la base du travail qu'on a réalisé la semaine dernière, il nous reste seulement le dernier étape avant nous pouvons commencer la manipulation sur nos ordinateurs en distance. C'est la connextion de l'Internet. Pour cela, tout d'abord il faut créer un fichier de configuration de l'internet par vim:
vim /etc/wpa_supplicant/wpa_supplicant.conf
Ici wpa_supplicant.conf est une fichier de configuration de WiFi sur Linux qui a un contenu suivant:
Avec ssid le nom de WiFi, psk le mot de passe de WiFi et priority le prioirité de la connextion. Pour plus de détail, dans nos testes, on utilise le partage de connextion sur nos portable. Et le plus grande la valeur de priority, le plus prioritaire de cette connextion. Ensuite avant utiliser SSH ou VNC, il faut savoir l'addresse de raspberry dans le réseau de WiFi, on a 2 méthodes pour l'instant:
- On utilise un logiciel s'appelle Advanced IP Scanner sur le PC, il peut nous donner le nom, l'addresse IP, l'addresse MAC et le fabriquant de chaque périphérique qui sont connectés dans le même réseau local, avec un exemple au-dessous:
- Sinon on peut utilser:
ifconfig
Avec cette commande on peut aussi avoir l'addresse de la raspberry pour faire une connextion SSH ou VNC. Jusqu'à maintenant on peut utiliser la commande suivante pour faire une connextion SSH dans n'importe quel terminal sur un PC:
ssh pi@172.20.10.3
Ici l'addresse IP est l'addresse qu'on a trouvé avec la méthode précédente. Et on peut voir la réponse au-dessous:
Et pour la connextion VNC est un peu près la même méthode sachant l'addresse IP de la raspberry, on utilise l'outil "connextion en distance" sur le système Windows:
On juste entre l'addresse IP dans la fenêtre de clique connecter ensuite on peut voir la fenêtre pour entrer le nom et le mot de passe de la raspberry:
Pareil que la raspberry qu'on a vu en cours Réseau en semestre 7, le nom on met pi et le mot de passe est raspberry. Ensuite on peut voir le desktop qu'on avait prévu en semestre 7:
Jusqu'à maintenant on a tout finir la préparation de la réalisation de projet, et maintenant on commence à travailler sur le webcam et le lidar. En ce moment, on a aussi fait une étude sur xrdp qui a la même fonction que VNC. Avec les commandes suivantes on peut utiliser le desktop aussi:
sudo apt-get install xrdp sudo apt-get install vnc4server tightvncserver sudo apt-get install xubuntu-desktop echo "xfce4-session" >~/.xsession sudo service xrdp restart
Installation du openCV
Après avoir décidé d'utiliser la bibliothèque openCV, le premier travail a été de l'installer sur le Raspberry Pi.Voici les principales étapes de mon installation:
1.Nous avons d'abord configuré le système d'exploitation Raspbian pour le Raspberry Pi.
2.J'ai entré la commande suivante sur la ligne de commande. Cette commande signifie ouvrir le fichier des modules avec l'éditeur nano:
sudo nano /etc/modules
J'ai ajouté une ligne à la fin de ce fichier:
bcm2835-v4l2
3.J'entre la commande:
vcgencmd get_camera
4.Les résultats suivants ont été obtenus:
Cela prouve que la caméra est correctement connectée.
Jusqu'à présent, le travail de préparation était terminé et j'ai commencé à installer OpenCV sur Raspberry Pi sous Python2. 5.
sudo apt-get install libopencv-dev sudo apt-get install python-opencv
6.J'ai ensuite testé OpenCV sur Python2. Je tape python2 sur la ligne de commande et appuyez sur Entrée:
import cv2
Ensuite, je suis entré:
cv2 .__ version__
Les résultats suivants sont apparus, prouvant que l'installation a réussi:
Ensuite, j'ai installé OpenCV sur Raspberry Pi exécutant Python3.
1.Tout d'abord, j'ai ouvert l'interface de ligne de commande et entré la commande suivante pour installer la bibliothèque de calcul scientifique Python numpy:
sudo pip3 install numpy
2.J'ai ensuite installé les bibliothèques requises par OpenCV:
sudo apt-get install build-essential git cmake pkg-config -y sudo apt-get install libjpeg8-dev -y sudo apt-get install libtiff5-dev -y sudo apt-get install libjasper-dev -y sudo apt-get install libpng12-dev -y sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev -y sudo apt-get install libgtk2.0-dev -y sudo apt-get install libatlas-base-dev gfortran -y
3.J'ai ensuite commencé à télécharger OpenCV:
cd wget https://github.com/Itseez/opencv/archive/3.4.0.zip wget https://github.com/Itseez/opencv_contrib/archive/3.4.0.zip
Alors, j'ai déballé ces deux archives:
cd /home/pi/Downloads unzip opencv-3.4.0.zip unzip opencv_contrib-3.4.0.zip
4.Ensuite, j'ai défini les paramètres de compilation:
cd /home/pi/Downloads/opencv-3.4.0 mkdir build cd build
5.Ensuite, j'ai défini les paramètres CMAKE:
[[cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D OPENCV_EXTRA_MODULES_PATH=/home/pi/Downloads/opencv_contrib-3.4.0/modules -D BUILD_EXAMPLES=ON -D WITH_LIBV4L=ON PYTHON3_EXECUTABLE=/usr/bin/python3.5 PYTHON_INCLUDE_DIR=/usr/include/python3.5 PYTHON_LIBRARY=/usr/lib/arm-linux-gnueabihf/libpython3.5m.so PYTHON3_NUMPY_INCLUDE_DIRS=/home/pi/.local/lib/python3.5/site-packages/numpy/core/include ..]]
La figure suivante montre que cmake s'avère efficace:
6.La dernière et la plus importante étape: compiler(Cela a pris beaucoup de temps.)
cd /home/pi/Downloads/opencv-3.4.0/build make sudo make insall
7.Après l'avoir installé, tapez python3 dans la ligne de commande et appuyez sur Entrée:
import cv2 cv2.__version__
Le résultat montré dans la figure ci-dessous montre qu'OpenCV a été installé avec succès dans l'environnement Python3.
Semaine 4
Choix du langage d'assemblage
Du code réalisable basé sur Raspberry Pi, C ++ nous est plus familier. Une raisson est que nous avons beaucoup étudié sur le langage C qui se semble C++ en cours, et une raison est que nous avons aussi cours OSCA qui contient une partie de le langage C++ pendant ce semestre. Et de plus, nous utiliserons beaucoup le C ++ dans les études ultérieures. Après avoir consulté nos coéquipiers, nous avons décidé d'utiliser le langage C ++ pour la programmation.
Allume la webcam.
Afin de détecter la position de le feu rouge en temps réel, je dois d'abord allumer le webcam du Raspberry Pi.
VideoCapture cap(0); if ( !cap.isOpened() ) { cout << "Cannot open the cam" << endl; return -1; }
Mais le webcam ne marche pas, après avoir consulté les informations en ligne, j'ai trouvé une solution: J'ai modifié / etc / modules et ajouté une ligne: bcm2835-v412。 Ensuite, j'ai redémarré, ls -l / dev / video0 et j'ai trouvé mon webcam.
Capture en temps réel depuis le webcam
Mat imgOriginal; bool bSuccess = cap.read(imgOriginal); // read a new frame from video if (!bSuccess) //if not success, break loop { cout << "Cannot read a frame from video stream" << endl; }
Cela déclare une image du type 'Mat'--imgOriginal, puis il existe une variable booléenne nommée bSuccess, qui est utilisée pour déterminer si l'acquisition d'image est réussie.
Etudes de fonctionnement de lidar
Après une recherche sur Internet, on a trouvé le datasheet de notre lidar RPLIDAR A1M8:
Fichier:Datasheet RPLIDAR A1M8.pdf
et le Development Kit User Manual:
Fichier:Development kit RPLIDAR A1M8.pdf
aussi on a une source le plus importante qui est le support sur github:
Pendant cette séance dont j'ai étudié des fichiers de type .h qui sont inclus au début dans l'exemple sur le github et aussi fait une simulation sur papier pour silmuler un cas simple dans la rue que je vais présenter dans la suite.
Donc dans mes études, les 5 fichiers de tête sont important car ils nous donnent des fonctions de base, des définitions très utiles qui permettent de implémenter le code facilement. Ici on va présenter plusieurs définitions importantes dans ces fichiers qui sont:
- Dans le fichier "rplidar.h" on inclut les 4 autres fichiers comme cela dans notre code on a besoin de faire seulement une inclure de cette fichier.
- Dans le fichier "rptypes.h" on a défini des structures et des vairables qui ne conernent pas le lidar comme
typedef uint32_t _u32;
- Dans le fichier "rplidar_driver.h" on a défini la class RPlidarDriver qui est le plus important interface dans le SDK(Software Development Kit). En effet ici on peut l'implémenter directement et on peut l'appliquer comme il a montré dans les exemples qu'il donne.Pour montrer un peu la principal, on donne quelque exemple suivants:
1.La fontion qui ouvert un port spécial pour connecter une cible qui est un périphérique RPLIDAR en communication sériale.
virtual u_result connect(const char *, _u32, _u32 flag = 0) = 0;
2.La fonction qui déconnecte le périphérique RPLIDAR et ferme le port de la communication sériale.
virtual void disconnect() = 0;
3.La fontion qui vérifie le résultat de la connextion.
virtual bool isConnected() = 0;
4.La fonction qui permet de commencer scanner les data de l'environnement.
virtual u_result startScan(bool force, bool useTypicalScan, _u32 options = 0, RplidarScanMode* outUsedScanMode = NULL) = 0;
5.La fonction qui récupère l'état de la sante de RPLIDAR.
virtual u_result getHealth(rplidar_response_device_health_t & health, _u32 timeout = DEFAULT_TIMEOUT) = 0;
6.La fonction qui stocke des mesures de l'environnement dans le nœud en l'ordre montant de la valeur de l'angle.
virtual u_result ascendScanData(rplidar_response_measurement_node_hq_t * nodebuffer, size_t count) = 0;
- Dans le fichier "rplidar_protocol.h" on a défini quelque structures de base et certain variables.
- Dans le fichier "rplidar_cmd.h" on a défini des structures et des variables de demandes et réponses de la communication. Je vais lister celui qui sont importants:
1.La structure de nœud où on stocke les mesure des distance, l'orientation, qualité de scan.
typedef struct _rplidar_response_measurement_node_t { _u8 sync_quality; // syncbit:1;syncbit_inverse:1;quality:6; _u16 angle_q6_checkbit; // check_bit:1;angle_q6:15; _u16 distance_q2; } __attribute__((packed)) rplidar_response_measurement_node_t;
2.La structure d'état où on stocke des informations du lidar.
typedef struct _rplidar_response_device_info_t { _u8 model; _u16 firmware_version; _u8 hardware_version; _u8 serialnum[16]; } __attribute__((packed)) rplidar_response_device_info_t;
3.La structure d'état où on stocke niveau de la santé du lidar
typedef struct _rplidar_response_device_health_t { _u8 status; _u16 error_code; } __attribute__((packed)) rplidar_response_device_health_t;
Ce sont le base avant étudier certaines applications qu'il donne pendant la prochaine séance.
Semaine 5
openCV
Après avoir configuré la caméra la semaine dernière, j'ai commencé à réfléchir à la façon d'utiliser openCV pour reconnaître les feux de circulation. Tout d'abord, je dois comprendre les différents fichiers de bibliothèque dans openCV.
I.HighGUI
Le module HighGUI comprend les entrées et sorties multimédias, la capture vidéo, l'encodage et le décodage d'images et de vidéos, et les interfaces d'interface graphique. Les fonctions principales sont:
1. imread (): lire une seule image dans OpenCV. 2. imshow (): affiche une image dans la fenêtre spécifiée. 3. NamedWindow (): créez une fenêtre. Si vous affichez simplement des images, vous pouvez utiliser imread () et imshow (). Mais lorsque vous devez utiliser le nom de la fenêtre avant d'afficher la fenêtre, vous devez utiliser cette fonction. 4. imwrite (): fichier image de sortie. 5. createTrackbar (): créez un curseur qui peut ajuster la valeur et attachez le curseur à la fenêtre spécifiée, qui est souvent utilisée en conjonction avec une fonction de rappel.
II.imgproc
1.Filtrage linéaire
Il est généralement utilisé pour débruiter et fonctionner avec différents noyaux de convolution. Les paramètres spécifiques sont visibles https://docs.opencv.org/3.2.0/d4/d86/group__imgproc__filter.html
blur() GaussianBlur() medianBlur() bilateralFilter()
2.Traitement morphologique(Morphology Operations)
Autrement dit, c'est un noyau (matrice) qui est prédéfini pour traiter l'image d'entrée. Chaque pixel dépend des pixels environnants. Différents noyaux sont utilisés pour obtenir des sorties différentes, donc le noyau est la clé. Érosion et dilatation: Prenez les valeurs minimale et maximale dans la plage du noyau de convolution, respectivement. Étant donné que l'image est une image en noir et blanc, le blanc est la valeur du pixel du sujet et le noir est l'arrière-plan. -cv :: erode: opération de corrosion, prendre une petite valeur, le blanc devient noir et la figure rétrécit. -cv :: dilate: opération de dilatation, par opposition à la corrosion. Sur la base de ces deux opérations, il existe également des opérations d'ouverture, de fermeture, de gradient morphologique, de chapeau haut de forme et de chapeau noir. Pour plus de détails, consultez https://docs.opencv.org/trunk/d3/dbe/tutorial_opening_closing_hats.html
Après avoir connu le principe de la corrosion et du gonflement, vous pouvez également extraire des lignes spéciales dans l'image, telles que des lignes horizontales et verticales.
3.Pyramides d'images(Image Pyramids)
Zoom sur l'image. Il existe deux méthodes courantes:
Pyramide gaussienne Pyramide laplacienne
Gauss est utilisé ici. Noyau gaussien:
Lors de la réduction: l'image est convoluée avec un noyau gaussien, puis même les lignes et les colonnes sont supprimées et le motif est réduit au quart de l'original. Lors d'un zoom avant: le noyau gaussien est utilisé pour la convolution pour estimer les pixels manquants. OpenCV propose deux fonctions:
pyrUp () pyrDown ()
4.Opérations de seuillage(Thresholding Operations)
Espace colorimétrique HSV:
hue(couleur): décrit la couleur, utile lors de la division d'objets en fonction de la couleur
saturation: du blanc au noir.
Value: décrit la luminosité ou la densité de la couleur
Espace colorimétrique RVB:
Trois canaux de chaque couleur ne peuvent pas être utilisés pour segmenter des objets en fonction de la couleur. L'espace colorimétrique peut être converti avec la fonction cv :: cvtColor ()
// Convert from BGR to HSV colorspace cvtColor(frame, frame_HSV, COLOR_BGR2HSV);
Autres fonctions principales:
threshold (): segmente une image en fonction d'un certain seuil. inRange (src, low, up, dst): En bref, il s'agit d'extraire les pixels de l'image src avec des couleurs entre low et up to dst, qui est une version avancée de la fonction de seuil.
5.Détection de lignes droites
Une ligne droite est détectée sur la base des bords détectés.
Si (x0, y0) est une valeur fixe dans la formule ci-dessus, alors toute paire (θ, rθ) représente un groupe de droites passant par (x0, y0). Si un groupe de lignes à trois points a une ligne droite commune, les trois points sont colinéaires.
HoughLines (): obtenir (θ, rθ) de la ligne droite détectée HoughLinesP (): obtenez les deux extrémités d'une ligne droite
Détecter les cercles: commencez par détecter les bords pour déduire le centre du cercle, puis trouvez le rayon le plus approprié pour le centre du cercle fixe. Utilisez cette fonction HoughCircles ().
6.Détection des contours
Les dérivés sont utilisés ici. Le bord de l'image est la zone où la valeur de pixel change considérablement, c'est-à-dire que le taux de changement de valeur de pixel est grand, c'est-à-dire la valeur dérivée. OpenCV fournit la fonction Sobel ().
Sobel(src_gray, grad_x, ddepth, 1, 0, ksize, scale, delta, BORDER_DEFAULT); Sobel(src_gray, grad_y, ddepth, 0, 1, ksize, scale, delta, BORDER_DEFAULT);
src_gray: Dans notre exemple, l'image d'entrée. Ici c'est CV_8U grad_x / grad_y: l'image de sortie. ddepth: La profondeur de l'image de sortie. Nous l'avons défini sur CV_16S pour éviter le débordement. x_order: Ordre de la dérivée dans la direction x. y_order: Ordre de la dérivée dans la direction y. scale, delta et BORDER_DEFAULT: Nous utilisons des valeurs par défaut.
Ici, les bords grad_x et grad_y dans les directions x et y sont respectivement calculés puis ajoutés pour obtenir les bords de l'image.
Vous pouvez également utiliser la deuxième valeur dérivée pour être 0 pour déterminer le bord. OpenCV fournit la fonction Laplacian ().
Fonction cv :: Canny
7.Transformation affine
cv :: remap: transformer les pixels, comme retourner l'image horizontalement getAffineTransform: récupère la matrice de transformation du rayonnement cv :: warpAffine: Transformer selon la matrice de transformation, warp. cv :: getRotationMatrix2D: rotation
Etudes de l'application
Dans le github on peut trouver 3 applications de base, dans notre cas, nous pouvons prendre une application simple et le modifier pour suffre la demande dqns le cahier de charge. Les 3 fonctions sont:
- Ultra_simple qui permet de scanner l'environnement et envoyer les data tout le temps, avec la commande 'ultra_simple /dev/ttyUSB0' si le RPLIDAR est connecté sur ttyUSB0. On peut aussi entrer 'ultra_simple' directement car dans le fichier on vous dit si on n'a pas entré le numéro de l'interface, par défaut est ttyUSB0.
- Simple_grabber qui permet de scanner l'environnement et l'afficher dans terminal un diagramme de rectangle pour visualiser l'environnement avec la même commande précédente. Cette fonction ne peut que montrer comment on utilise certaines fonctions car on n'a pas besoin de faire une partie d'affichage.
- Frame_grabber qui permet de scanner l'environnement et l'afficher sur une fenêtre qui peut nous donner un photo de la vu en haut.
Donc d'après ces 3 fonctions qu'on a, nous pouvons commencer à concevoir notre algoritheme pour chercher des voitures ou des choses mobiles avec une grande vitesse.
Pour un premier teste, on veut commencer par détecter la vitesse d'un point(ou plutôt une orientation) par l'étapes suivantes:
1.On fixe un point/une orientation supposant que c'est cette orientation où la voiture vient. On propose l'orientation dans l'axe de RPLIDAR est 0 degré pendant notre test. Et ici il faut montrer cet axe de RPLIDAR pour on peut imaginer le fonctionnement:
2.Ensuite on va mesurer la distance d1 entre l'obstacle et le RPLIDAR qui est 12 mètres maximal pour un moment t1 de cette direction.
3.Dans certains temps, on utilise la fonction delay(x) avec un paramètre x qui représente le temps en ms.
4.Ensuite on va mesurer la deuxième distance d2 de cette même direction sachant le temps passé entre ces 2 mesures pour un moment t2.
5.Avec des valeurs on mesure pendant les dernières étapes, on peut calculer la vitesse de cette voiture par la formule suivante:
7.Comparer la vitesse qu'on obtient avec la vitesse de dangeureuse qui est normalement la vitesse de la voiture dans la rue. Si la vitesse qu'on obtient est plus grande que la vitesse de dangeureuse, on va activer des vibreurs(dans un premier test on a 1 vibreur, mais après ce test on va avoir plus de vibreur
Cependant, avec cette méthode on ne peut que trouver seulement un résultat approxmatif car ici le vrai temps entre 2 mesures n'est pas x ms. Même si nous n'avons pas forcément besoin une valeur exacte, mais est-ce qu'on a une méthode qui est plus optimal? Et pour la taile de l'échantillon on fixe à 1 pour l'instant.
Semaine 6
La conception spécifique de la section webcam
Après avoir compris les principales fonctions de openCV, je pense que pour réaliser la fonction d'identification des feux de circulation, vous devez commencer par la manière la plus simple d'identifier les feux rouges. Pour y parvenir, je pense que ma fonction peut être divisée en les parties suivantes:
1. Détectez la position de la lumière rouge de la webcam en temps réel.(Déjà réalisé)
2. Reconnaître le rouge avec l'espace HSV.
3. Binarisez la partie rouge d'origine en blanc et le reste en noir.
4. Tracez un cercle sur la zone rouge.
5. Démarrez le shaker.
6. Améliorez et complétez.
Reconnaître le rouge avec l'espace HSV
- Modèle HSV
Il est difficile de trouver la gamme exacte de rouge en contrôlant les canaux RVB, j'ai donc choisi l'espace HSV. HSV (Hue, Saturation, Value) est un espace colorimétrique créé à partir des caractéristiques intuitives des couleurs. Les paramètres de couleur dans le modèle HSV sont: teinte (H: teinte), saturation (S: saturation) et luminosité (V: valeur). Un espace colorimétrique créé par A. R. Smith en 1978, également connu sous le nom de modèle hexagonal.
Teinte (H: teinte): Mesurée en termes d'angles, allant de 0 ° à 360 °, en comptant dans le sens antihoraire du rouge, 0 du rouge, 120 ° du vert et 240 ° du bleu. Leurs couleurs complémentaires sont: 60 ° pour le jaune, 180 ° pour le cyan et 300 ° pour le magenta;
Saturation (S: saturation): La valeur varie de 0,0 à 1,0. Plus la valeur est élevée, plus la couleur est saturée. Luminosité (V: valeur): La valeur va de 0 (noir) à 255 (blanc).
- Du modèle RVB au modèle HSV
Soit (r, g, b) les coordonnées rouge, verte et bleue d'une couleur, et leurs valeurs sont des nombres réels compris entre 0 et 1. Soit max l'équivalent du plus grand de r, g et b. Soit min la plus petite de ces valeurs. Pour trouver la valeur (h, s, v) dans l'espace HSV, où h ∈ [0, 360) est l'angle de teinte de l'angle, et s, v ∈ [0,1] est la saturation et la luminosité, calculées comme suit:
max=max(R,G,B) min=min(R,G,B) if R = max, H = (G-B)/(max-min) if G = max, H = 2 + (B-R)/(max-min) if B = max, H = 4 + (R-G)/(max-min) H = H * 60 if H < 0, H = H + 360 V=max(R,G,B) S=(max-min)/max
Il existe une fonction dans OpenCV qui peut directement convertir des modèles RVB en modèles HSV. Notez que dans OpenCV, H ∈ [0, 180), S ∈ [0, 255] et V ∈ [0, 255]. Nous savons que la composante H peut représenter fondamentalement la couleur d'un objet, mais les valeurs de S et V doivent également être dans une certaine plage, car S représente le degré de mélange de la couleur représentée par H et le blanc, ce qui signifie que le plus petit S, Plus la couleur est blanche, plus elle est claire; V représente le degré de mélange de la couleur représentée par H et le noir, c'est-à-dire que plus le V est petit, plus la couleur est noire.
Il s'agit d'une gamme floue, avec des parties de violet classées comme rouges.
- Réalisé
Mat imgHSV; vector<Mat> hsvSplit; cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV);//Convert the captured frame from RGB to HSV split(imgHSV, hsvSplit); equalizeHist(hsvSplit[2],hsvSplit[2]); merge(hsvSplit,imgHSV);
imgHSV est une image obtenue en convertissant l'espace RVB d'imgOriginal en espace HSV, puis en séparant les trois canaux de HSV. La fonction cvEqualizeHist est utilisée pour égaliser l'histogramme, qui peut transformer une image plus claire en une image plus profonde (c'est-à-dire améliorer la luminosité et le contraste de l'image). cvMerge: Combinez plusieurs images monocanal en une image multicanal, donc j'obtiens une image dans l'espace HSV. Et en ajustant la valeur de HSV, toutes les zones non rouges peuvent être filtrées.
Binarisation
La binarisation consiste à convertir une image couleur en noir et blanc pur. cvtColor peut convertir l'image en image en niveaux de gris, mais pas en image binaire. CvThreshold est une fonction de binarisation. La partie rouge d'origine de l'image obtenue est blanche et le reste est noir.
Montage
Semaine 7
Tracez un cercle sur la zone rouge
Utilisez d'abord la transformation de cercle de Hough pour détecter le cercle: la fonction cvHougeCircles a plusieurs paramètres: la première est l'image d'entrée, la seconde est la mémoire, la troisième est la méthode et l'algorithme et la quatrième est la résolution: lorsqu'elle est définie sur 1, La résolution est la même, la résolution 2 est normale et la cinquième est la distance minimale entre deux cercles que l'algorithme peut clairement distinguer. Les deux suivants sont des seuils, suivis des rayons maximum et minimum du cercle qui peuvent être trouvés. cvPoint est un type de données dans OpenCV et représente un point en deux dimensions. centre est le centre du cercle. En fait, dessiner le centre du cercle et dessiner le cercle sont la même chose. La fonction cvCircle est utilisée, mais lorsque le rayon du cercle dessiné est 0, il devient le centre du cercle de dessin.
vector<Vec3f> circles; HoughCircles( imgThresholded, circles, CV_HOUGH_GRADIENT,1.5, 10, 200, 100, 0, 0 ); for( size_t i = 0; i < circles.size(); i++ ) { Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); int radius = cvRound(circles[i][2]); //Dessiner le centre du cercle circle( imgThresholded, center, 3, Scalar(0,255,0), -1, 8, 0 ); //Dessinez un contour de cercle circle( imgThresholded, center, radius, Scalar(155,50,255), 3, 8, 0 ); }
Démarrez le shaker
Après avoir dessiné le cercle rouge, nous pouvons démarrer le vibreur pour réaliser le rappel. Tout d'abord, j'ai ajouté les bibliothèques nécessaires au vibreur:
#include <wiringPi.h>
Ensuite, j'ai initialisé le vibreur:
if(-1==wiringPiSetup()) { cerr<<"setup error\n"; exit(-1); } pinMode(7,OUTPUT);
Enfin, nous démarrons le vibrateur après avoir détecté la lumière rouge, le temps de vibration est de 3 secondes:
digitalWrite(7,HIGH); delay(3000); digitalWrite(7,LOW);
Semaine 8
Améliorez et complétez En raison des différentes conditions d'éclairage à différents moments, il est préférable d'avoir une interface de contrôle pour ajuster le HSV en temps réel afin que l'effet d'identification du rouge soit le meilleur. OpenCV a une interface graphique dédiée pour écrire des fonctions, ce qui est également très pratique pour écrire.
La conception et la réalsiation d'une première méthode de approximative du Lidar
Pendant cette séance on a ajouté le code pour notre deuxième cas:
- La voiture n'approche pas directement vers l'utilisateur mais ils vont se rencontrer dans un certain temps.
Et ici selon le consigne du prof, on utilise 2 notions qui sont points immobiles et points mobiles.
Si on calcule la vitesse de tous les points de 360 degrés, on trouve il y a des points mobiles et des points immobiles. Points mobiles sont des points qui ont une distance change de temps en temps, points immobiles sont des points qui ont une distance fixée ou change pas beaucoup. Et le calcul de la vitesse d'un point est utilisé pour détecter d'une voiture en approche directement vers l'utilisateur.
Donc ici on propose un algoritheme pour détecter une voiture n'approche pas directement ver l'utilisateur avec le principe suivant: dans chaque scan du lidar, on sauvegarde les distances de 3 angles(30°, 45°et 60°) dans 3 variables(distance_30, distance_45 et distance_60), et si il y une voiture en approche, sûrement ces 3 variables qui sont la distance entre la voiture et le lidar suivent la formule: distance_30<distance_45<distance_60, comme cela on peut dire approximativement la voiture et l'utilisateur peut-être se rencontrer dans le futur donc on lance l'alerte.
On utilise 3 conditions pour fixer le moment où on peut sauvegarder la valeur de mesure.
Pour les 2 résultats au-dessus, on voit que la distance est négative car je ne met pas la condition
nodes[pos].distance_q2/4.0f>200
Après ajouter cette condition, on peut trouver la distance sauvegardé dans nos variables sont égaux à 0 qui n'est pas possible car si la valeur de mesure est inférieur que 200mm alors on l'abandonne cette mesure.
Semaine 9
La conception et la réalsiation d'une deuxière méthode de l'approximation du Lidar
Pendant cette semaine, selon le consigne des profs, on trouve que notre ancienne méthode ne marche pas, et donc on propose une deuxième méthode avec le principal suivant:
On trouve tout d'abord le point de gravité de la voiture(on fait un algoritheme pour chercher ces points à chaque temps et on propose la voiture va droit), et ensuite on créer un repère qui va présenter la voiture sur 2 coordoonnées polaires pour connaître à quelle distance la voiture va passer au plus près et à quel instant. A la fin on va traiter le temps t dans lequel la voiture passera au plus près et la distance dis entre la dernière mesure de la voiture et l'utilisateur.
Dans ce cas, si t est petit et dis est petit aussi c'est très grave et on va alerter fortement pour que l'utilisateur avertir vite. Si t est grand et dis est petit c'est moins grave parce que la voiture peut-être en train de freiner donc on va alerter moins fort. Si dis est supérieur que 5m c'est pas grave donc on n'alerte pas.
Le calcul sur papier pour trouver la droite de mouvement de la voiture
Tout d'abord on crée un repère des coordoonnées polaires comme au-dessous:
On propose que point O présente la position de l'utilisateur, et P2 est le premier point de gravité de la voiture, P1 est le deuxième point de gravité de la voiture, et y est l'axe qui est aussi la direction de mouvement de l'utilisateur. Et dans chaque mesure on connaît la distance r et l'angle theta de chaque point(on propose r1,theta1,r2,theta2 sont connus).
Donc on peut représenter P1, P2:
Ici on remplace r1*sin(theta1) par x1, r1*cos(theta1) par y1, r2*sin(theta2) par x2, et r2*cos(theta2) par y2 pour simplifier le calcul.
Sachant les positions de P1 et P2, on peut calculer la droite du mouvement de la voiture(avec une condition theta1<theta2, sinon la voiture va plus loin):
Ensuite on peut trouver la position au plus près est:
Donc le temps t pour passer de la postion P1 à cette position au plus près est:
Maintenant on a le temps t et la distance dis puis on va la comparaison avec les paramètres qu'on impose. Et cette comparaison sera faite dans la prochaine partie qui va présenter le code.
Algoritheme pour trouver le point de gravité de la voiture à chaque temps
Pour trouver ces points, on propose stocker les mesures entre 0 degré et 90 degrés car ce lidar traite seulement la voiture en droit et avant. Ensuite dans chaque deux mesure successifs on compare la distance de point avec le même angle, si ces distance changent beaucoup(comme de 12m à 5m) cela veut dire il y a un objet(la voiture dans notre cas) appraît, et ce point on l'appelle le point mobile. Par contre, le points qui ont une distance presque constante on l'appelle le points immobile. Si il y une voiture, apparament les points de certaines angles successifs vont tout changer donc ces points sont tous le point mobile et on prend la distance moyenne et l'angle moyenne comme le point de gravité de cette voiture.
Algoritheme pour calculer le temps entre 2 mesure successifs
Comme nous avons montré au début, pour calculer la droite, c'est mieux si on prend la deuxième mesure(recherche de point mobile) dans un second après prendre la première mesure. Si les 2 mesures sont trop proche, l'erreur est plus grande. Avant cette séance on utilise la fonction clock() qui n'est pas assez précis, donc cette séance on préfère utiliser la fonction gettimeofday(). A la place de montrer le code lourd, ici on met un exemple de cette fonction pour montre l'idée comment on calculer le temps entre 2 mesures:
struct timeval debut; struct timeval fin; unsigned long difference; gettimeofday(&debut,NULL); delay(1000); gettimeofday(&fin,NULL); difference = 1000000* (fin.tv_sec-debut.tv_sec)+ fin.tv_usec-debut.tv_usec; printf(“la différence est %ld\n”,difference);
Comme dans cette fontion le résultat est en microseconde(μs), on divise 1000 000 pour le présenter en second. C'est un peu près la même que clock() mais plus précis. Et on l'appelle avec debut quand on prend la première mesure et fin quand on prend la deuxième mesure.
Semaine 10
La introduction supplémentaire de la deuxière méthode de l'approximation du Lidar
Pendant ces 2 semaines qui est la vacance de Pâque, on a réussi à une implémentation de l'algorithme avec des équations mathématiques qu'on a calculé pendant la semaine dernière, mais il y a quelque part qui n'est pas précis. Donc avant présenter le détail du code, nous allons préciser quelque définition ici:
1.L'ordre de mesure de 2 points de gravités successif Pour faire une droite dans le repère qu'on a fait, il faut trouver 2 points pour fixer une droite, et comme on suppose que l'utilisateur marche vers la flèche positif de l'axe y, et selon le calcul au'on a fait, il y a aura un danger si et seulement si l'angle de point P1 est plus petit que l'angle de point P2, et même pour la distance.
Donc dans notre code, on va tout d'abord chercher un point de gravité dans la zone entre 0 degré et 90 degrés qui est notre point P2 avec un angle 'angle2'. Ensuite, on fait un petit delay pour la voiture avance une certaine distance, et puis on cherche le deuxième point de gravité dans la zone entre 0 degré et 'angle2' degrés. Si ce n'est pas le cas on utilise un variable s'appelle 'presence_voiture' qui représente la présence de la voiture, si on n'a pas détecté un point de gravité pendant ces 2 mesures, on pose cette variable à 0, et si cette varibale égale à 0, il n'y a pas de l'alerte. Parce que si dans un scan de l'environnement le lidar n'a pas pris la mesuer de quelquel angle, il va mettre 0 comme la valeur de distance de cet angle, donc on ajoute cette nouvelle variable 'presence_voiture' pour choisir les mesures utiles. Par exemple, si il y une distance égale à 0, on abandonne cette mesure et pose 'presence_voiture' égale à 0, donc il faut attendre la prochiane detection de point de gravité.
2.La méthode pour trouver le point le plus proche Ici pour trouver ce point, on propose une méthode de l'approximation qui n'est pas précis dans la semaine 9.
Le principle de cette méthode est:
On pose que la vitesse de l'utilisateur est négligeable par rapport à la voiture. Donc le point le plus proche est un point sur la droite. Cette droite on peut trouver par 2 points de gravités qu'on a. Et on a déjà fait un calcul général sur papier pour trouver une droite sachant les coordonnées des 2 point sur cette droite.
Donc maintenant on sait que le point o qui a les coordonnées (0,0) est la position de l'utilisateur et supposant qu'on a 2 points de gravités avec la méthode présentée au-dessus, on veut trouver le point le plus proche. Aussi il y a une limite pour ce point, c'est: ce point il faut se situe dans la zone où les coordonnées x et y sont tous positifs, car sinon la voiture ne va jamais se rencontrer avec l'utilisateur(même principe pour le produit sur le bras à gauche, chaque produit est responsable pour chaque côté)
Donc, on peut trouver le point le plus proche à le point o est le point sur l'axe y, aussi ce point est sur la droite en même temps.
3.La méthode pour calculer la vitesse de la voiture et le temps pour la voiture passera au point le plus proche Ici on suppose qu'on a le point le plus proche de l'utilisateur qui est le point au-dessus. Pour calculer la vitesse, on mesure le temps entre le moment où on mesure le point de gravité P2 et le moment où on mesure le point de gravité P1 avec la fonction 'gettimeofday()', et la distance de ces 2 points est facile de calculer par la méthode qu'on propose pendant la semaine 9. Ensuite on calcule la distance entre le point de gravité P1 et le point le plus proche comme on a vu en semaine 9 et ici on reprend l'équation:
Donc on voit que avec cette distance, et sachant la vitesste de la voiture, on peut calculer le temps pour la voiture passera au point le plus proche, et avec ce temps et le distance entre l'utilisateur et le point le plus proche, on peut établir un système de l'alerte selon le niveau d'urgence.
Le code principal
Dans cette partie nous allons présenter des codes important en C++ pour montrer comment réaliser ces algoritheme en détail.
if (IS_OK(op_result)) { drv->ascendScanData(nodes, count); } op_result = drv->grabScanData(new_nodes, count); if (IS_OK(op_result)) { drv->ascendScanData(new_nodes, count); for (int pos2 = 0; pos2 < 2000 ; pos2=pos2+1) if( ((nodes[pos2].angle_q6_checkbit >> RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT)/64.0f<90) && ((new_nodes[pos2].angle_q6_checkbit >> RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT)/64.0f<90) && (nodes[pos2].distance_q2/4.0f!=0) && (new_nodes[pos2].distance_q2/4.0f!=0) && fabs(nodes[pos2].distance_q2/4.0f-new_nodes[pos2].distance_q2/4.0f)>1000 ) { presence_voiture=1; num2=pos2; gettimeofday(&debut,NULL); dis2= (nodes[pos2].distance_q2/4.0f>new_nodes[pos2].distance_q2/4.0f)?new_nodes[pos2].distance_q2/4.0f:nodes[pos2].distance_q2/4.0f; angle2=(nodes[pos2].angle_q6_checkbit >> RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT)/64.0f; x2 = dis2 * sin(angle2*PI/180.0f); y2 = dis2 * cos(angle2*PI/180.0f); /*printf("theta: %03.2f Dist: %08.2f \n ", //pour montrer si on a trouve le point de gravite (new_nodes[num1].angle_q6_checkbit >> RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT)/64.0f, new_nodes[num1].distance_q2/4.0f); */ break; } else { presence_voiture=0; } }
Problèmes rencontrés