Drone et occulus rift : Différence entre versions

De Wiki d'activités IMA
(Spécifications de WiringPi et branchement)
(Test avec)
Ligne 284 : Ligne 284 :
  
 
Ici on va utiliser la librairie de wiringPi <softPwm.h>, les spécifications de la librairie sont disponibles à cette adresse[http://wiringpi.com/reference/software-pwm-library/].
 
Ici on va utiliser la librairie de wiringPi <softPwm.h>, les spécifications de la librairie sont disponibles à cette adresse[http://wiringpi.com/reference/software-pwm-library/].
 +
 +
Voici un code sommaire permettant de contrôler un servo moteur sur sa plage d'action (ici 0 à 180 degrés) :
 +
 +
<pre>#include <wiringPi.h>
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <stdlib.h>
 +
#include <softPwm.h>
 +
 +
#define PIN_0 1
 +
 +
int main(int argc, char *argv[]){
 +
        int pos =0;
 +
        char reponse = ' ';
 +
        if(wiringPiSetup() == -1){
 +
                printf("Bug\n");
 +
                exit(1);
 +
        }//si l'initialisation de wiringPi échoue, on arrête le programme
 +
 +
        pinMode(PIN_0,OUTPUT); //dédfinition de la gpio 1 comme sortie
 +
        digitalWrite(PIN_0,LOW);//son etat initial est à létat bas
 +
        softPwmCreate(PIN_0,0,500);//creation de la pwm
 +
 +
        do{
 +
 +
                printf("Position à 0°:\n");
 +
                softPwmWrite(PIN_0,25);
 +
                delay(2000);
 +
                printf("Position à 90° :\n");
 +
                softPwmWrite(PIN_0,16);
 +
                delay(2000);
 +
                printf("Position à 180° : \n");
 +
                softPwmWrite(PIN_0,8);
 +
                delay(2000); //les positions sont arbitraires pour ma maquette sinon elle sera liée dans le futur aux accelero de l'oculus
 +
                do{
 +
                        printf("Voulez-vous continuer (0/N)\n");
 +
                        scanf("%c",&reponse);
 +
                }while(reponse != 'O' && reponse !='N');
 +
        }while(reponse == 'O');
 +
 +
        printf("Au revoir\n");
 +
        return 0;
 +
}</pre>
 +
 +
Et voici une vidéo illustrant le code ci-dessus :
 +
 +
[[Média:Exemple.ogg]]

Version du 13 mars 2016 à 19:51

Cahier des charges

Présentation générale du projet

Contexte

Depuis quelques années seulement, les drones se sont popularisés dans le domaine de l'utilisation civile.

Équipés de caméras, ils peuvent être utilisés pour lutter contre l'insécurité, surveiller des manifestations ou pour savoir le nombre de personnes prises au piège d'un immeuble en flammes.

Ils peuvent être aussi utilisés pour la prise de vues aériennes.

Drone pour prise de vues aériennes
Drone civil OnyxStar Fox-C8 XT en vol

Description du projet

L'objectif de ce projet est de concevoir et implémenter, sur un drone de bonne manufacture, un système embarqué capable de diffuser un flux vidéo en 3D stéréoscopique sur un casque de réalité virtuelle.

De plus, nous avons eu deux idées pour la gestion du drone :

Schéma de la première idée
Schéma de la deuxième idée

La première idée est de contrôler le drone en position directement via les mouvements de la tête à l'aide du casque, et nous aurions simplement fixé une caméra sur le drone pour pouvoir nous repérer.

La deuxième idée, retenue après discussion avec notre encadrant M. Dequidt, est de contrôler le drone en position via une télécommande par exemple.

Nous aurions cependant une caméra fixée sur le drone capable de tourner suivant deux axes et contrôlée via les mouvements de la tête grâce au casque. Un ordinateur embarqué (type Raspberry) récupérera en liaison sans fil les informations (inclinaison par ex.) du casque pour agir sur les moteurs en plus d'envoyer le flux vidéo des caméras.

Contraintes

  • Notre système embarqué ne devra pas excéder le poids de charge du drone (1kg).
  • Il faudra pouvoir alimenter notre système soit via l'alimentation du drone, soit à l'aide d'une source d'énergie supplémentaire.
  • La communication entre le drone, la télécommande pour piloter le drone et l'oculus doit se faire depuis une distance raisonnable (au moins 20 mètres).

Choix techniques : Matériel et Logiciel

  • Matériel
    • x1 ou x2 Caméras (résolution 800x600 minimum) pour récupérer des images depuis le drone, la vision 3D sera soit faite grâce à deux caméras, soit grâce à une caméra suivi d'un traitement d'image plus poussé.
    • x1 Raspberry Pi 2 pour le traitement d'image lié aux caméras, l’émission et réception du flux vidéo et le contrôle de la ou les caméras à distance. [Fournie 27/01/2015]
    • x1 Dongle Wifi (compatible Raspberry Pi 2, Wi-Pi par exemple) pour la communication sans fil entre l'utilisateur du drone et la structure montée sur le drone.[Fourni 27/01/2015]
    • x1 Drone de bonne manufacture (déjà commandé par l'école)
    • x1 Oculus Rift (déjà commandé par l'école)
    • x1 Servomoteurs pour faire pivoter selon 2 axes la structure où seront fixés les caméras (360°).[1 fourni 27/01/2015]
    • X1 Micro Servomoteur pour piloter "" (180°) Acheté par les élèves
    • X1 breadboard
    • X10 fils mâle/mâle
  • Logiciel
    • Solidworks ou un autre logiciel de modélisation 3D pour concevoir les différents supports de la structure.
    • Tout logiciel de traitement de texte pour la programmation (certainement C)
  • Autres
    • Utilisation de l'imprimante 3D du FabLab pour concevoir les différents supports de la structure.

Calendrier prévisionnel

Avancement du Projet

Semaine 1 (25 janv - 30 janv)

  • Rassemblement du matériel disponible à l'école (manque Oculus et Drone)
  • Recherche sur internet pour une batterie, deux caméras

Semaine 2 (1 fev - 6 fev)

  • Documentation sur la Raspberry (configuration des GPIO)
  • Installation et configuration de la Raspberry (connexion automatique sur réseau local)
  • Installation des bibliothèques pour la commande des servomoteurs via Raspberry
  • Premiers essais de commande des servos : problème au niveau des librairies
  • Premières idées sur la structure du support caméra pour 3D Stéréoscopique

Semaine 3 (8 fev - 13 fev)

  • Résolution (partielle) du problème de librairie pour contrôler les servomoteurs (toutes les fonctions non disponibles)
  • Précision angulaire d'environ 10° avec la fonction de contrôle utilisée (insuffisant) //screens videos inc.
  • Début de conception de support pour fixer la Raspberry et la batterie externe sur le drône
  • Réception du drone

Semaine 4 (22 fev - 27 fev)

  • Résolution complète du problème de librairie pour contrôler les servomoteurs
    • Nouvelle fonction de la librairie utilisée pour le contrôle des servomoteurs
    • Précision angulaire d'environ 0,1° avec la nouvelle fonction de contrôle utilisée mais sur une plage de 120° au lieu de 180° //screens videos inc.
  • Essais et recherches pour contrôler les servomoteurs précisément et sur une plage plus grande
  • Problème de Wifi qui se déconnecte tout seul
    • On essayera de transformer la Raspberry en Hotspot pour voir si c'est mieux
    • Sinon on utilisera une borne wifi (solution mieux adaptée dans ce cas)
  • Discussion avec notre tuteur (M. Dequidt)
    • Mise au point sur l'avancement du projet
    • Une salle va nous être prêtée pour effectuer les tests au moment venu (plafond de 6m pour le drone)
    • L'Oculus, prêté par un laboratoire ne va pas tardé à arrivé
    • Notre tuteur se propose de passer quelques heures avec nous pour travailler sur la manière de récupérer les valeurs de l'accéléromètre de l'Oculus

Semaine 5 (29 fev - 5 mars)

  • Installation et paramétrage de la Raspberry en tant que point d'accès wifi
    • Point d'accès wifi sur la Raspberry impossible à faire fonctionner (problème au niveau du DHCP...)
    • On verra plus tard pour le wifi, à ce qu'il parait le réseau de l'école "fonctionne très bien" du coup on pourrait travailler dessus
  • OpenCV
    • Documentation
    • Compilation et test de fonctionnement sur une machine indépendante
  • Diverses méthodes étudiées vis à vis des flux vidéo des deux caméras
    • Motion, OpenCV, (et d'autres à ajouter car j'ai plus les noms) //screens videos inc.
    • Streaming sur une page internet ?
  • On reste pour l'instant sur le fait d'être précis mais limité de 120 degrés en angle pour la commande des servomoteurs

Semaine 6 (7 mars - 12 mars)

  • Travail sur l'Oculus DK2 dans les locaux de l'IRCICA avec notre tuteur (M. Dequidt)
    • Recherche sur le SDK pour comprendre le fonctionnement "logiciel" de l'Oculus
    • Code minimaliste et fonctionnel (testé sur OSX) récupérant les valeurs de l'orientation de l'Oculus
  • OpenCV est un peu trop lourd pour la Raspberry et peut être inadéquate pour l'utilisation qu'on souhaite en faire
  • Nouveaux objectifs
    • On va essayer d'ouvrir deux flux vidéos en même temps sur Raspberry
    • Tester la compilation du code minimaliste sur Windows et Linux
    • Tester le code avec un Oculus DK1 pour juger de la compatibilité du code
    • Trouver un moyen pour diffuser les valeurs sur le réseau (certainement de la même manière qu'en Tutorat S&R)

Test effectués

Gestion des caméras

Dans un premier temps, nous avons du réfléchir comment récupérer deux flux de caméras branchées en USB sur notre Raspberry Pi 2. Nous étions parti sur la bibliothèque d'Intel OpenCv, mais étant gourmande et assez difficile d'utilisation, et beaucoup trop puissante pour ce que l'on veut faire, on s'est dirigé vers une autre solution. Pour cela, on utilisera motion.

Installation de motion

sudo apt-get update 
sudo apt-get updrade 
sudo apt-get install motion
sudo apt-get install apache2 

On utilisera apache2 pour diffuser notre flux vidéo, depuis notre navigateur web, en local.

Configuration de motion

Tout d'abord, nous allons configurer motion à partir de deux fichiers :

nano /etc/motion/motion.conf

Et nous allons chercher les lignes suivantes et changer quelques paramètres :

deamon on (au lieu de off)
width 320
height 240
framerate 90

Dans le champ Live Webcam serveur

webcam_maxrate 24
webcam_localhost off
#rajoutez les lignes suivantes en dessous de la ligne précédente
thread /home/pi/webcam/cam1.conf
thread /home/pi/webcam/cam2.conf

Nous avons rajouter deux thread pour donner la configuration des deux caméras. Pour cela :

cd /home/pi
mkdir webcam
cd webcam
nano cam1.conf
 ls /dev/vid*
/dev/video0  /dev/video1

Puis mettre la configuration suivante et faire de même pour la cam2.conf :

videodevice /dev/video0
webcam_port 8081

On a donc la cam1 qui est lu sur le port 8081 et la cam2 sur le port 8082.

Si on veut lancer le flux au démarrage de la Rasperry Pi :

nano /etc/default/motion
start_motion_daemon=yes

Lire le flux vidéo sur le navigateur web

On a installer apache2 précédemment, nous allons créer une page web minimal permettant d'afficher en même temps nos deux flux vidéo. Pour cela :

nano /var/www/webcam.html

Puis on récupère le flux via ce code minimaliste :

<html>
<head>
<title>Raspberry Pi Webcams</title>
<head>
<body>
<h1>Raspberry pi Webcaméras</h1>
<a href="http://raspberrypi:8081/">
<img src="http://raspberrypi:8081/" alt="Camera1"></a> 
<a href="http://raspberrypi:8082/">
<img src="http://raspberrypi:8082/" alt="Camera2"></a> 
</body>
</html>

Pour démarrer et arrêter le service (attention à bien être en root §sudo bash)

service motion start
service motion stop

Pour visualiser les flux de notre page web sur notre navigateur :

http://raspberrypi/webacam.html

On peut mettre l'adresse de la Rpi à la place de "raspberrypi" via :

ifconfig

Ainsi, on obtient bien la diffusion de nos deux streams de caméra en USB à partir d'une raspberry pi 2 :

Rpi cam.jpg

Une vidéo du branchement des différents éléments:

Média:Video branchement.mp4

Une vidéo qui montre le flux en directe :

Média:Test-cam-final.mp4

Gestion des GPIO pour contrôle de servo-moteur

Dans les rubriques suivantes, on a décidé pour l'instant d'utiliser les bibliothèques de WiringPi <SoftServo.h> et <SoftPwm.h>.

installation de WiringPi

Tout d'abord, on a besoin d'installer git pour récupérer WiringPi :

apt-get install git-core

Pour obtenir WiringPi via Git :

git clone git://git.drogon.net/wiringPi

Au premier clone, lors de l'installation :

cd wiringPi
git pull origin

Puis, pour construire avec le script fourni :

cd wiringPi
./build

Spécifications de WiringPi et branchement

la documentation de wiringPi disponible en :

   -En français[1]
   -En anglais[2]

Pour vérifier que le programme est bien installé :

gpio -v

Pour lire les entrées et les sorties sur les gpio de la Pi :

gpio readall

On obtient ainsi le résultat suivant dans un terminal :


Terminal-gpio.png


et on branche comme spécifié ci-dessus le servo moteur qui a besoin d'une alimentation en +5V 0V. Puis on récupère le signal sur le gpio n°1 en pin n° 12 :


Brachement-servo.jpg

Test avec <sofPwm.h>

Ici on va utiliser la librairie de wiringPi <softPwm.h>, les spécifications de la librairie sont disponibles à cette adresse[3].

Voici un code sommaire permettant de contrôler un servo moteur sur sa plage d'action (ici 0 à 180 degrés) :

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <softPwm.h>

#define PIN_0 1

int main(int argc, char *argv[]){
        int pos =0;
        char reponse = ' ';
        if(wiringPiSetup() == -1){
                printf("Bug\n");
                exit(1);
        }//si l'initialisation de wiringPi échoue, on arrête le programme

        pinMode(PIN_0,OUTPUT); //dédfinition de la gpio 1 comme sortie
        digitalWrite(PIN_0,LOW);//son etat initial est à létat bas
        softPwmCreate(PIN_0,0,500);//creation de la pwm

        do{

                printf("Position à 0°:\n");
                softPwmWrite(PIN_0,25);
                delay(2000);
                printf("Position à 90° :\n");
                softPwmWrite(PIN_0,16);
                delay(2000);
                printf("Position à 180° : \n");
                softPwmWrite(PIN_0,8);
                delay(2000); //les positions sont arbitraires pour ma maquette sinon elle sera liée dans le futur aux accelero de l'oculus
                do{
                        printf("Voulez-vous continuer (0/N)\n");
                        scanf("%c",&reponse);
                }while(reponse != 'O' && reponse !='N');
        }while(reponse == 'O');

        printf("Au revoir\n");
        return 0;
}

Et voici une vidéo illustrant le code ci-dessus :

Média:Exemple.ogg