User avatar
PHPower
Posts: 84
Joined: Tue Jan 01, 2013 7:48 pm
Location: PACA
Contact: Website

Projet PiX (Drone, Quadricopter)

Thu May 23, 2013 9:24 pm

Salut tout le monde !

Comme certains d'entre vous le savent, je construit (ou développe ?) un drone, enfin plutôt un quadri-copter, basé sur une Raspberry Pi (sans blague ...).
J'ai créé ce topic pour éviter de polluer l'ancien qui était dédié à l'utilisation du PCA9685 de chez Adafruit (http://www.raspberrypi.org/phpBB3/viewt ... 65&t=39442)

Le matériel utilisé :
  • Cadre X600
  • Moteur 2212KV Brushless
  • Variateurs 25 Ampères (chinois, qui encaisse que jusqu'à 80Hz malheureusement)
  • Hélices 1045 Carbone
  • Contrôleur moteur Adafruit Servo Controller (PCA9685)
  • Gyroscope / Accéléromètre / Magnétomètre / Altimètre : AltIMU (pololu)
  • Raspberry Pi Model B 512Mb
  • Divers Cables et connecteurs
Ce qui fonctionne actuellement :
  • Gestion des moteurs un à un (et en c++ :D)
  • Gestion des communications via socket
  • Gestion de la manette XBOX 360
  • Gestion des directions

Problèmes actuels :
  • Réduire le temps de latence qu'il y a entre le mouvement du joystick et la variation de puissance

Questions en suspens :
  • Faire calculer les puissances de chaque moteur par la Pi ou par le PC qui pilote ?
Dernière vidéo :
http://www.youtube.com/watch?v=rHobVeiR ... e=youtu.be

Si vous avez des questions ou des suggestions, n'hésitez surtout pas :)
Last edited by PHPower on Mon Jul 08, 2013 2:35 pm, edited 2 times in total.

laurent
Posts: 315
Joined: Thu Jul 26, 2012 11:24 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Fri May 24, 2013 8:28 am

Salut,
Vraiment très intéressant, ça donne envie de s'y mettre :D
Pourrais-tu m'envoyer en MP des liens vers tes fournisseurs pour tout ce qui est brushless et variateurs ?

Pour les variateurs, j'imagine que ce sont des modèles qui prennent un signal PPM ? D'où le faible taux de rafraîchissement ?
Ca pose vraiment un problème sur le temps de réaction ?

Ca peut être intéressant de faire, ou trouver un variateur perso qui prend un signal en série. Idéalement RS485/422 comme ça tu aurais juste besoin d'un maître et tous tes contrôleurs en esclave sur la même liaison.

Pour ce qui est du contrôle, ça peut être sympa d'avoir un Rpi au lieu d'un PC ? Avec un bon joystick USB ça doit être faisable.

J'ai récemment commandé des modules de data RF (à base de CC1101 pour 433MHz et nRF24L01 pour du 2.4GHz). J'aurais déjà pas mal de travail pour implémenter et/ou adapter un bout de soft pour les utiliser, mais je pense qu'ils seraient plus adaptés pour du contrôle que du WiFi ou BT (moins de latence).

Déjà que je manquais de temps libre, faut vraiment pas que je traîne sur ton topic :mrgreen:

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Fri May 24, 2013 10:08 am

Salut ,
laurent en fait ca fonctionne en RC normalement comme ca :
radio => recepteur => ESCs => moteurs
en bleu c'est du PPM , en rouge c'est (presque) du PWM
pour les drones y'a toujours une carte controleur qui va recuperer 4 canaux PPM (gaz , derive , profondeur , aileron) , regarder les valeurs de capteur(s) (au moins un gyroscope) et faire accelerer ou ralentir certains moteurs en consequence , voila ce genre de carte : http://www.multiwii.com/connecting-elements , wii parcequ'au depart ca utilisait le gyroscope et l'accelerometre d'une wiimote , aujourd'hui ca se vend tout fait en avec des capteurs mieux adaptés (ca a gardé quand meme le nom "multiwii") , c'est open source donc on peu "magouiller" ca un peu comme on veut , ou plutôt comme on peut :mrgreen:

ici y'a pas de radio ni de recepteur (enfin si mais en wifi , pas en PPM) donc le "hack" c'est de pas utiliser de carte controleur (c'est le RPI qui fait office de controleur) et remplacer la transformation du recepteur (PPM=>PWM) donc juste envoyer du (presque) PWM aux ESCs

PHPower , pour la latence faudrait voir comment c'est fait au niveau du code et pour calculer la puissance des moteurs en fait c'est déjà ce que tu fais en envoyant la commande de vitesse :mrgreen:

laurent
Posts: 315
Joined: Thu Jul 26, 2012 11:24 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Fri May 24, 2013 10:59 am

D'acc, merci pour ces précisions ;)
Quelques questions cependant :
La carte à base de gyroscope sert bien à asservir en position le quadricoptère pour qu'il soit stable ?
Si oui, il n'y a pas de risque que le Rpi ne soit pas adapté pour de l'asservissement ? (temps de réponse et OS non temps-réel).
Dans beaucoup d'exemples sur ces quadricoptères, on voit des cartes à µC. Si elles sont beaucoup moins puissantes qu'un Rpi, elles sont parfaitement contrôlables niveau timing, et répondent ainsi mieux aux contraintes temps-réel (j'ai déjà fait de l'asservissement PID, et c'est moins facile avec un OS "lourd").

Je pense que ça peut devenir par contre très intéressant dans une configuration Rpi+µC (Arduino ou autre), où la carte µC s'occupe du temps réel (contrôle moteur par rapport au gyro/accéléromètre) et où le Rpi s'occupe de la transmission RF/WiFi (avec un petit module caméra en prime).
D'autant qu'un Rpi peut permettre de donner une autonomie supplémentaire (dans le contrôle/pilotage), et peut accueillir une large panoplie de capteurs et périphériques, rapprochant davantage de la définition de "drone" ;)

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Fri May 24, 2013 11:59 am

oui en effet , Raspbian est pas fait pour du temps reel (meme si il se debrouille pas trop mal) car il est fait pour du multitaches , ils en parlent ici rapidement de 4:30 a 5:30 http://vimeo.com/18547238 et un peu plus loins ils expliquent qu'ils utilisent donc xenomai , un peu apres 9:00 sur 2 minutes (sur une foxboard G20 mais c'est aussi un ARM qui tourne normalement sur debian , un peu l'ancetre du RPI)

laurent
Posts: 315
Joined: Thu Jul 26, 2012 11:24 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Fri May 24, 2013 12:10 pm

L'excellent blog de Christophe Blaess relate l'installation et l'utilisation de Xenomai sur Rpi :
http://www.blaess.fr/christophe/2012/08 ... pberry-pi/

Après, il faut maîtriser les contraintes soft du temps réel, ce qui est loin d'être trivial, mais ça peut valoir le coup :)

User avatar
PHPower
Posts: 84
Joined: Tue Jan 01, 2013 7:48 pm
Location: PACA
Contact: Website

Re: Projet DCY'Fly (Drone, Quadricopter)

Fri May 24, 2013 4:45 pm

Salut Laurent !

Content que mon projet te plaise ! Pour mon fournisseur, c'était un vendeur chinois sur eb*y, mais depuis la mise à jour on ne peut plus les commander :/

Tu m'as fait pensé que ma RPi tourné sous RaspBian qui n'est pas adapté à la situation. Quel OS me conseil tu pour que j'ai le meilleur temps de réponse ?

Pour les variateurs, je pourrais pas te dire quel signal ils prennent, j'ai juste compris comment les faire fonctionné sur le PCA9685 grâce aux signaux que m'a expliqué ToOnS

Pour le controle via un stick et un RPi, j'avais pensé à intégrer une RPi dans le dock motorola Atrix, mais je veux d'abord que ce soit fonctionnel sur PC avant de me lancer sur le "PC pilote".
Je pense que ça peut devenir par contre très intéressant dans une configuration Rpi+µC (Arduino ou autre), où la carte µC s'occupe du temps réel
Y'aurait il un moyen de "booster" la Pi ?

@ToOnS : j'ai commandé de quoi faire l'alimentation de la Pi depuis un BEC :D reste plus qu'a attendre la livraison et pouvoir enfin le voir voler (ou pas)

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Fri May 24, 2013 4:58 pm

tu as déjà tout ce qu'il te faut pour l'alimenter avec un bec des esc qui d'apres tes esc est de 5v 2A (tu sais le fil rouge entre le jaune et le noir , lui tu le mets sur le 5V du GPIO et voila tu alimentes le RPI via la batterie , idir si tu nous lis ne le fait pas car tes esc sortent du 5.5V et tu en a déjà fait les frais :oops: ) , voler non tu pourras pas sans gyroscope ca sera impossible a tenir car meme si les moteurs tournent a la meme vitesse c'est jamais equilibré pile poile , il va se retourner comme une crepe

User avatar
PHPower
Posts: 84
Joined: Tue Jan 01, 2013 7:48 pm
Location: PACA
Contact: Website

Re: Projet DCY'Fly (Drone, Quadricopter)

Fri May 24, 2013 10:55 pm

Quand je dit que j'ai acheter ce qu'il faut, j'entend par la une rallonge PWM. Par contre, il faut que la Pi soit démarrer avant de mettre le jus aux variateurs, sinon ils prennent pas la commande. ça va être compliqué sachant que c'est un variateur qui alimente la PI :/

Si la Pi est alimentée par le micro usb, et que je branche la batterie, donc pendant un instant elle est alimenté et par le micro usb et par le GPIO. Est-ce que ça peut me la grillé, ou c'est fait exprés pour pas que ça grille ? xD

Pour le faire voler sans gyro j'ai pensé a un système de calibration, les joystick serait trés peu sensible, et on pourrait régler la stabilité. Une fois stabilisé, on appuierait sur une touche, et il sauvegarderait sa configuration de stabilité :) T'en pense quoi ?

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 11:28 am

Salut ,
normalement ca demarre meme si c'est alimenté avant le RPI , ca ca vient du code

pour l'alim en uUSB et en GPIO en meme temps ... il me semble que quelqu'un l'a déjà fait sans le vouloir ici : http://www.raspberrypi.org/phpBB3/viewt ... 43#p351843 (le post de PHPower :lol: )
PHPower wrote:Tu as les mêmes type de moteur que moi

Sur l'exemple de Frank Buss :

Variateur + et - sur la batterie
Fiche commande comme Frank Buss sur le RPi (remplace le blanc par le jaune)

Et les 3 cables de l'ESC au moteur

Je peux t'assurer que ça fonctionne !

Fais nous des photos de ton installation

justement tu peux pas le stabiliser sans gyro , comme l'aire est un fluide les hélices vont finir par le pousser dans un sens ou dans l'autre donc tu auras moins de portance la ou y'aura moins d'aire , il va commencer a pencher du coté ou y'a le moins d'aire , c'est la que le gyro te dit "attention ca penche" et que le programme doit accelerer ce coté pour retablir (voir aussi decellerer l'autre coté).
sans gyro tu as pas "attention ca penche" , c'est tes yeux qui devront le faire mais ca va tellement vite que le temps ca passe par "tes yeux => ton cerveau => tes mains" il est déjà retourné , pour te donner une idée de la vitesse a laquelle ca se retourne : http://www.youtube.com/watch?v=uArlZU928Lw (bon y'a un gyro et tout ce qu'il faut et notre ami chadock est loin d'etre debutant , le probleme vient d'ailleur dans ce cas , c'est juste pour te montrer que y'a pas le temps de reagir a la vitesse ou ca va) , personne peut stabiliser sans gyro c'est trop dur (et ca peut/va pencher sur 2 axes en meme temps dans ce cas c'est encore 10 fois plus dur) , en plus de ca faut gerer tout le reste comme eviter de le sateliser a cause de trop de vitesse ou a l'inverse de l'enterrer a cause de pas assez de vitesse au debut crois moi que c'est pas evidant , on voit aussi dans la video , enfin on entend , le travail du gyro lorsque chadock attrape le pied en vole , le gyro dit a la carte "ca penche c'est pas normal" , la carte essai de compensser en accélérant

User avatar
PHPower
Posts: 84
Joined: Tue Jan 01, 2013 7:48 pm
Location: PACA
Contact: Website

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 1:21 pm

Plop, j'avais pas pensé au code de Frank Buss pour le coup (trop évident !) , et je pense que je vais le démarrer comme ça quand j'aurais reçus mes rallonge PWM pour faire l'alimentation GPIO.

Le beep quand le programme n'est pas démarré ne vient pas de mon code puisque le programme n'est pas démarré justement, en faite, je crois qu'ils beep pour dire qu'ils sont connecté à la commande, mais que celle ci ne leur envoie rien.

Cette vidéo me fait légèrement pensé à mon "accident" avec le drone :/
Du coup j'ai commandé l'AltIMU que je pourrait monter dans 3 semaines quand je rentrerais chez moi.
Pour le montage sur l'I2C tu m'avais dit que je pouvais rebranché par dessus le SCA et SCL du PCA9685, si tu peux m'en dire d'avantage, ou même un petit schéma :p

Au niveau des commandes "droite/gauche" "avant/arriere" "haut/bas" tu me conseil de jouer sur combien de pourcents, parce que sans hélice, jouer avec 20% me parait beaucoup déjà (je veux pas qu'il se retourne comme une crêpe)

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 2:16 pm

en fait quand ca beep ca veut dire que les moteurs sont pas armés (que les gaz on pas été mis a 0) donc que les moteurs tourneront pas tant que tu mets pas 0 de gaz , c'est une securité pour s'assurer en RC que y'a pas le manche de la telecommande a fond quand tu alimentes les moteurs comme c'est des hachoirs ca peu etre dangereux (souvient toi de tes doigts :D) , verifis que tu as 1ms quand tu demarres (biensur si les esc sont calibré a 1ms sinon verifis que as bien le temps que tu as utilisé pour le calibrage de la vitesse basse)

pour I2C : https://fr.wikipedia.org/wiki/I2C#Topologie (sauf que tu as pas maitre 2 et que les résistances sont déjà sur le RPI) , ou ici peu etre mieux expliqué : http://electro8051.free.fr/I2C/busi2c.htm

pour le % de vitesse je peux pas t'aider ca depand de trop de parametres : poid du hachoir volant , capacité des moteurs a supporter la charge , taille des hélices ... , faut faire des essais en y allant tout doucement par pas de 1%
puis algoritemant parlant avec le gyro quand tu auras bien degrossi , accelerer gentillement jusque l'angle commance a diminuer et si l'angle continu a augmenter accelerer 2 , 3 ou 4 fois plus fort peu etre une piste ici : http://www.youtube.com/watch?v=-dKI2X2yFac

pour le temps de latence du 1er post j'ai un peu reflechi (vous moquez pas ca m'arrive des fois) et les esc sont reglés en sortie d'usine pour accelerer linéairement (car ils peuvent etre en prise avec un demultipicateur en plastique par exmple sur les helico ou sur le ladybird et acceler d'un coup casserait le demultiplicateur) ici y'a pas de demultiplicateur , l'helice est directement sur le moteur alors on peu acceler fort d'un seul coup donc regler les esc pour.
pour regler faut faire comme ca : http://www.youtube.com/watch?v=HcqfvJHQeck
en mettant :
Brake – OFF
Battery Type – Ni-xx (meme si c'est une lipo , sinon ca va tout couper d'un coup)
Cut Off Type – Soft-Cut
Cut Off Voltage – Low
Start Mode – Normal
Timing Mode – Middle
Music/Li-Po Cells (ca on s'en fou un peu)
Governor Mode – OFF

User avatar
PHPower
Posts: 84
Joined: Tue Jan 01, 2013 7:48 pm
Location: PACA
Contact: Website

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 5:47 pm

J'ai pas encore regardé la vidéo, mais tu me dit qu'on peut calibrer les ESC pour qu'ils envoie la patate directement ?

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 6:13 pm

oui c'est ca , c'est "timing" qui fait ca , il peu etre sur low (ca accelere doucement meme si tu mets a fond jusque la vitesse voulue) , medium (ca accelere moyennement jusque la vitesse voulue) et high qui va donner directement la vitesse sans phase d'acceleration.
y'a aussi un firmware special pour drone (a flasher dans les esc , je sais pas si c'est fesable avec tes esc) , le firmware simonk qui lui envoie vraiment toute la sauce et bcp plus vite , on voit la difference sur la 1ere video du post precedent dans "test three", quand il bouge tres vite les gaz y'a un moteur qui accelere vite et l'autre le temps qu'il accelere la manette des gaz est déjà baissé donc il a presque meme pas le temps de demarrer

User avatar
PHPower
Posts: 84
Joined: Tue Jan 01, 2013 7:48 pm
Location: PACA
Contact: Website

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 7:02 pm

J'ai calibré les moteurs un par un, et j'ai toujours cette latence :/

J'ai fait une vidéo pour illustré ma latence : http://www.youtube.com/watch?v=HbSsCKZw ... e=youtu.be

Sinon cela peut-il venir des échange sockets ?

Voici mon schéma d'échange de données :
PC > RPI : Commandes (droite/gauche ... )
RPI > PC : Renvoie les commandes recus
PC > RPI : Commandes ok
RPI > PC : bien recu le ok

La taille des commandes transmise c'est 3 double (floats)

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 7:27 pm

ah oui ca ressemble plus a un probleme de transmission des infos , pour en etre sur si tu peux brancher le RPI sur un ecran et faire la meme chose mais en écrivant les 3 valeurs recus a l'ecran tu sauras , si a l'ecran ca s'ecrit aussitôt la communication va bien , si a l'ecran tu a le meme retard la communication va mal
apres c'est etonnant d'avoir autant de decalage entre l'emission et la reception , si je me trompe pas un float c'est 64 bit donc 4 octets ce qui fait que tu envois 12 octets , 12 octets en wifi ca va vite (meme si on double pour le check ca donne 24 octets et si on rajoute les "ok" ca fait 28) :lol:
ou encore le traitement , les float c'est long a convertir je crois , peu etre qu'en envoyant des octets plutôt que des floats (ou des strings ?) tu gagnerais un peu ? en plus cette manette envoie des octets au PC donc pas de conversion de ce coté , pour les gâchettes c'est de 0x00 a 0xFF si je me souvient bien (j'avais pas la 360 mais la "original" des toutes 1ere xbox)

User avatar
PHPower
Posts: 84
Joined: Tue Jan 01, 2013 7:48 pm
Location: PACA
Contact: Website

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 8:44 pm

Je pense que ça vient de mon code, sur l'affichage console je vois le "lag".

Pour info voici mon code :

PC

Code: Select all

#include "network.h"

#include <SFML/Graphics.hpp>

#include <iostream>
#include <iomanip>
using namespace std;

int main(){
	
	SOCKET sock;
	SOCKET csock;
	_init_socket_server(&sock, &csock); 

	while(true){

		sf::Joystick::update() ;
		if(!sf::Joystick::isConnected(0)){
			cout << colorCout("Please link your controller !","red") << endl; 
			continue;
		}
		if(	!sf::Joystick::hasAxis(0, sf::Joystick::V) || 
			!sf::Joystick::hasAxis(0, sf::Joystick::X) || 
			!sf::Joystick::hasAxis(0, sf::Joystick::R) || 
			!sf::Joystick::hasAxis(0, sf::Joystick::Z)	){
			cout << colorCout("Your controller doesn't appear to be compatible !","red") << endl; 
			cout << colorCout("Now will exit ...","red",1) << endl; 
			break;
		}

		double vertical, horizontal, z; 

		vertical = 		(sf::Joystick::getAxisPosition(0, sf::Joystick::V)) ; 
		horizontal = 	(sf::Joystick::getAxisPosition(0, sf::Joystick::X)) ; 
		z = 			((sf::Joystick::getAxisPosition(0, sf::Joystick::R)+100)/2) - ((sf::Joystick::getAxisPosition(0, sf::Joystick::Z)+100)/2);

		if(vertical < 20 && vertical > -20) vertical = 0; 
		if(horizontal < 20 && horizontal > -20) horizontal = 0; 
		if(vertical < 0) vertical = vertical + 20 ; 
		if(vertical > 0) vertical = vertical - 20 ; 
		if(horizontal < 0) horizontal = horizontal + 20 ; 
		if(horizontal > 0) horizontal = horizontal - 20 ; 	

		system("clear"); 
		cout << "Vertical : " << vertical << endl ; 
		cout << "Horizontal : " << horizontal << endl ; 
		cout << "Z : " << z << endl ; 

		Controls Movements; 
		Movements.V = vertical; 
		Movements.H = horizontal; 
		Movements.I = z; 

		Controls Movements_confirm; 
		Movements_confirm.V = vertical + 30; 
		Movements_confirm.H = horizontal + 30; 
		Movements_confirm.I = z + 30; 

		send(csock, &Movements, sizeof(Movements), 0);
		recv(csock, &Movements_confirm, sizeof(Movements_confirm), 0);

		bool verif = false; 
		
		if(	Movements.V == Movements_confirm.V && 
			Movements.H == Movements_confirm.H && 
			Movements.I == Movements_confirm.I ){
			verif = true; 
		}

		send(csock, &verif, sizeof(verif), 0);
		verif = false ;
		recv(csock, &verif, sizeof(verif), 0);		

		if(!verif){
			cout << colorCout("All data hasn't been received !","red") << endl; 
		}else{
			cout << colorCout("All data has been received !","green") << endl; 
		}

		sf::Joystick::update() ;
		if(sf::Joystick::isButtonPressed(0, 1)){
			break;	
		} 


	}







    closesocket(csock);
    closesocket(sock);

	return true; 

}

Drone

Code: Select all

#include <Python.h>
#include "network.h"
#include "lib.h"


#include <iostream>
#include <iomanip>


#include <string>
#include <limits.h>
#include <unistd.h>



using namespace std;

int main( int argc, char** argv)
{

    PCA9685* Controller = new PCA9685(250); 
    ESC* FL = new ESC(Controller,0); 
    ESC* FR = new ESC(Controller,2); 
    ESC* RL = new ESC(Controller,3); 
    ESC* RR = new ESC(Controller,1);    
    system("sleep 10");
	SOCKET sock;
	_init_socket_client(&sock);  

    double min_4_rotation = 6; 
    double max_4_rotation = 90; 
    double percent_movements = 10; 
        
    while(true){


        Controls Movements; 
        Movements.V = 999; 
        Movements.H = 999; 
        Movements.I = 999; 

        recv(sock, &Movements, sizeof(Movements), 0);
        send(sock, &Movements, sizeof(Movements), 0);

        bool verif = false; 
        recv(sock, &verif, sizeof(verif), 0);
        send(sock, &verif, sizeof(verif), 0);

        cout << " ------------------------ " << endl; 
        cout << verif << endl ; 
        cout << "Vertical : " << Movements.V << endl ; 
        cout << "Horizontal : " << Movements.H << endl ; 
        cout << "Z : " << Movements.I << endl ; 

        if(!verif){
            cout << "Erreur de transmission ! " << endl; 
            FL->setPercent(0); 
            FR->setPercent(0); 
            RL->setPercent(0); 
            RR->setPercent(0);             
            break; 
        }

        // valeurs stables (pour faire semblant qu'il y a le gyro)
        double  stab_fl = 10.11, 
                stab_fr = 10.25, 
                stab_rl = 10.23, 
                stab_rr = 10.19; 

        double  val_fl = 0, 
                val_fr = 0, 
                val_rl = 0, 
                val_rr = 0; 

        double  max_motor_min = 0; 
        double  min_motor_min = 999; 
        
        max_motor_min = stab_fl ; 
        if(stab_fr >= max_motor_min) max_motor_min = stab_fr ; 
        if(stab_rl >= max_motor_min) max_motor_min = stab_rl ; 
        if(stab_rr >= max_motor_min) max_motor_min = stab_rr ; 
        
        min_motor_min = stab_fl ; 
        if(stab_fr <= min_motor_min) min_motor_min = stab_fr ; 
        if(stab_rl <= min_motor_min) min_motor_min = stab_rl ; 
        if(stab_rr <= min_motor_min) min_motor_min = stab_rr ; 

        val_fr -= percent_movements*Movements.H/100;
        val_rr -= percent_movements*Movements.H/100;
        val_fl += percent_movements*Movements.H/100;
        val_rl += percent_movements*Movements.H/100;                        

        // V 
        val_fl += percent_movements*Movements.V/100;
        val_fr += percent_movements*Movements.V/100;
        val_rl -= percent_movements*Movements.V/100;
        val_rr -= percent_movements*Movements.V/100;                                

        // I 
        val_fl += Movements.I*0.50;
        val_fr += Movements.I*0.50;
        val_rl += Movements.I*0.50;
        val_rr += Movements.I*0.50;     

        // Default
        val_fl += stab_fl;
        val_fr += stab_fr;
        val_rl += stab_rl;
        val_rr += stab_rr;


        if( val_fl < min_4_rotation ||
            val_fr < min_4_rotation ||
            val_rl < min_4_rotation ||
            val_rr < min_4_rotation )
        {
            double tmp_min = val_fl; 
            if(val_fr <= tmp_min) tmp_min = val_fr ; 
            if(val_rl <= tmp_min) tmp_min = val_rl ; 
            if(val_rr <= tmp_min) tmp_min = val_rr ;
            tmp_min = (min_4_rotation - tmp_min); 
            val_fl += tmp_min;
            val_fr += tmp_min;
            val_rl += tmp_min;
            val_rr += tmp_min;     
        }

        if( val_fl > max_4_rotation ||
            val_fr > max_4_rotation ||
            val_rl > max_4_rotation ||
            val_rr > max_4_rotation )
        {
            double tmp_max = val_fl; 
            if(val_fr >= tmp_max) tmp_max = val_fr ; 
            if(val_rl >= tmp_max) tmp_max = val_rl ; 
            if(val_rr >= tmp_max) tmp_max = val_rr ;
            tmp_max = (max_4_rotation - tmp_max); 
            val_fl += tmp_max;
            val_fr += tmp_max;
            val_rl += tmp_max;
            val_rr += tmp_max;     
        }        

        system("clear"); 
        cout << "val_fl = " << val_fl << endl ; 
        cout << "val_fr = " << val_fr << endl ; 
        cout << "val_rl = " << val_rl << endl ; 
        cout << "val_rr = " << val_rr << endl ; 
        FL->setPercent(val_fl); 
        FR->setPercent(val_fr); 
        RL->setPercent(val_rl); 
        RR->setPercent(val_rr); 

    }






    closesocket(sock);                 

	return true; 

}
Peut être que cela vient de la Pi qui doit calculer les valeurs des moteurs ?

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 11:06 pm

c'est trop pour moi la , je suis faché avec le C(++) , j'en fait que sous la torture.
recv(sock, &verif, sizeof(verif), 0);
send(sock, &verif, sizeof(verif), 0);

cout << " ------------------------ " << endl;
cout << verif << endl ;
cout << "Vertical : " << Movements.V << endl ;
cout << "Horizontal : " << Movements.H << endl ;
cout << "Z : " << Movements.I << endl ;
coté RPI tu recois et tu renvois puis tu ecris aussitôt , ca ok je comprend apres je peu pas te dire si c'est long , faudrait mettre un cout << "fin de boucle" << endl ; a la derniere ligne de la boucle et regarder si ca s'ecrit aussitôt apres "Z : xxxxxxxxx" , si y'a "lag" entre les 2 ecritures alors c'est bien que le RPI arrive pas a calculer ca assez vite.
pendant que tu y'es mets en un aussi en debut de boucle et un avant le recv pour voir si le lag est entre le debut de boucle et le recv (donc quand tu envois les infos a la carte moteurs) aussi pour voir si c'est entre le recv et le send (dans ce cas c'est la communication qui lag)
aussi je me demande si RECV est pas bloquant , c'est a dire que tant que pas de reception la boucle est bloquée au RECV , dans ce cas faudra passer par thread (ou une fonction non bloquante) pour recevoir parceque si ca bloque la boucle il va pas aller lire le gyro et ... scratch :mrgreen:

User avatar
PHPower
Posts: 84
Joined: Tue Jan 01, 2013 7:48 pm
Location: PACA
Contact: Website

Re: Projet DCY'Fly (Drone, Quadricopter)

Sat May 25, 2013 11:22 pm

Effectivement le recv est bloquant, et je le veux bloquant pour vérifier que les paquets ont été transmis.

Pour le gyro, je vais passer par des threads comme tu l'as dit.

4 variables global pour dire quel moteur doit être a combien pour être stable.
Ces 4 variables seront modifiées par le thread du gyro.

Code: Select all

        // valeurs stables (pour faire semblant qu'il y a le gyro)
        double  stab_fl = 10.11,
                stab_fr = 10.25,
                stab_rl = 10.23,
                stab_rr = 10.19; 
en gros, les valeurs stab_XX, seront modifiées par le threads du gyro ^^

Pour les cout en début et fin de boucle, je ferais ça demain, mes voisins vont me maudire si je fait ça maintenant ! xD

EDIT :

J'ai fait les test, et le problème vient des calculs !
Début de boucle : T = 0
Fin de reception de données : T = 0150 (ms)
Fin de boucle : T = 1450 (ms)
(valeurs moyennes)

Je pense que je vais envoyé les valeurs du fake gyroscope au PC, et c'est lui qui calculera la puissance de chaque moteurs.
Je ferais une "issue de secours" si le drone perds la liaison, alors c'est lui qui calcul les puissances des moteurs ^^

EDIT 2 :

Je cherché des bricoles sur eb*y, et je suis tombé sur une boutique qui avait des caméra Pi à 33 euros (moins cher que chez kub*i) et en stock. Ni une ni deux, j'ai cliqué sur "acheter" (rhaaaa la commande en un clic c'est pas bon pour le porte monnaie !).
Bref ! je prévoie donc de la monté sur le drone, et je pense que ça serais cool de la monter sur deux servo, pour pouvoir la faire bouger :)

Du coup, je me suis dit, tient, si on faisait le même glitch que pour alimenter la Pi avec les variateurs.
Est-ce que ça marcherais ?

Image

EDIT 3 :

J'ai pensé au problème de la porté du Wi-Fi cette nuit (toute la nuit oui ! ) et j'en suis venu à me dire qu'utiliser le 3G+ serait une bonne idée, j'aurais un débit d'environs 200Ko/s c'est donc suffisant pour échanger 16 octets assez rapidement ! :lol:

Le problème c'est que chez l'opérateur où j'ai mon abonnement 3G+, bah c'est que je peu pas faire de port forwarding, du coup pour me connecter en SSH au Pi ça va être la misère.
Si quelqu'un a une idée sur comment on peut faire :)

laurent
Posts: 315
Joined: Thu Jul 26, 2012 11:24 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Mon May 27, 2013 8:29 am

PHPower wrote:Salut Laurent !

Content que mon projet te plaise ! Pour mon fournisseur, c'était un vendeur chinois sur eb*y, mais depuis la mise à jour on ne peut plus les commander :/

Tu m'as fait pensé que ma RPi tourné sous RaspBian qui n'est pas adapté à la situation. Quel OS me conseil tu pour que j'ai le meilleur temps de réponse ?

Pour les variateurs, je pourrais pas te dire quel signal ils prennent, j'ai juste compris comment les faire fonctionné sur le PCA9685 grâce aux signaux que m'a expliqué ToOnS

Pour le controle via un stick et un RPi, j'avais pensé à intégrer une RPi dans le dock motorola Atrix, mais je veux d'abord que ce soit fonctionnel sur PC avant de me lancer sur le "PC pilote".
Je pense que ça peut devenir par contre très intéressant dans une configuration Rpi+µC (Arduino ou autre), où la carte µC s'occupe du temps réel
Y'aurait il un moyen de "booster" la Pi ?

@ToOnS : j'ai commandé de quoi faire l'alimentation de la Pi depuis un BEC :D reste plus qu'a attendre la livraison et pouvoir enfin le voir voler (ou pas)
Salut,
Désolé pour la réponse tardive :oops:
Pour ce qui est de l'OS, quelque soit le GNU/Linux supporté (Arch, Raspbian, Fedora,...) tu auras un OS à temps partagé et non temps réel, donc pas de maîtrise absolue de la réactivité, du temps de réponse, du déterminisme...
Deux solutions cependant :
- Tuner le noyau intégré à ces distributions, donc le recompiler en jouant sur les modes d'ordonnanceur et la période de celui-ci (de mémoire on peut choisir la politique d’ordonnancement et la réactivité), ce qui donne une marge de manoeuvre intéressante sans pour autant répondre à des contraintes temps-réel dures.
- Passer à un noyau temps réel, ou plutôt à un patch du noyau Linux existant, comme Xenomai. Par contre, ça implique un développement spécifique par la suite (l'application doit tirer parti des priorités temps réel). Mais là on aboutit à un OS qui répond avec une excellente réactivité à des contraintes temps-réel (le temps de réactivité a été mesuré sur le précédent blog cité).

En fait, c'est pour cela que je parlais d'adjoindre au Rpi une carte à µC, comme un Arduino, ou une carte maison. Cette carte à µC s'occuperait de l'asservissement des moteurs par rapport à l'accéléromètre/gyroscope (le fameux "attention ça penche -> correction" (c) ToOnS :P ).
Le Rpi aurait alors juste à envoyer la consigne moteur à cette carte (et éventuellement les divers paramètres).
Un µC sans OS a cet avantage d'avoir un timing parfaitement contrôlable, ce qui s'avère parfait pour du contrôle moteur et de l'asservissement (certains µC ont même de DSP qui aident l'asservissement).

Dans le domaine (j'y bosse :mrgreen: ), il est très courant de retrouver le duo gros CPU (ou SoC) sous OS lourd avec petit micro (voire même FPGA) sans OS. ;)

Pour des projets sans grosses contraintes, il est intéressant de tout rationaliser sous la même plateforme (ex : une carte genre Rpi qui gère absolument tout). Quand les contraintes commencent à devenir pointues et différentes par nature, ça devient plus intéressant de répartir sous différentes architectures.
Dans le cas d'un drone, imaginez qu'un accès Wi-Fi monopolise l'OS et bloque pendant 100ms la boucle d'asservissement du contrôle moteur, qui équilibre le drone ? C'est l'instabilité, voire le crash assuré.

LeSanglier
Posts: 226
Joined: Fri Jan 11, 2013 8:11 pm
Location: In Hell with God
Contact: Website

Re: Projet DCY'Fly (Drone, Quadricopter)

Mon May 27, 2013 8:58 am

Bonjour,

Pourquoi n'utilisez vous pas de l'Arduino et les shields gyroscopiques adéquate ?
Compte tenu que le Raspberry Pi et le la distribution Raspbian n'est pas vraiment optimisé pour ce type d'application. A la rigueur faire un montage de l'Arduino et du Raspberry.
Mon blog sur le Raspberry Pi : http://framboisepi.fr/
Pour avoir plus de chance d'avoir une réponse à votre question,
allez sur le forum français Rasberry Pi : http://forum.raspfr.org

User avatar
PHPower
Posts: 84
Joined: Tue Jan 01, 2013 7:48 pm
Location: PACA
Contact: Website

Re: Projet DCY'Fly (Drone, Quadricopter)

Mon May 27, 2013 10:32 am

Plop tout le monde !

Merci de vos réponses :)

Je suis partie sur une base de RPi parce que j'y connais vraiment rien en electronique mais vraiment rien du tout ! (ça se voit je pense :lol: ) Du coup je préfère commencer avec le Pi et apprendre au fur à mesure. Je passerais au arduino c'est certains, mais pas tout de suite.
Dans le cas d'un drone, imaginez qu'un accès Wi-Fi monopolise l'OS et bloque pendant 100ms la boucle d'asservissement du contrôle moteur, qui équilibre le drone ? C'est l'instabilité, voire le crash assuré.
Je pensais en faite utiliser des threads, ce qui empêcherais ce genre de problème. Qu'en pensez-vous ?

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Mon May 27, 2013 12:14 pm

Faut un vrai defi , pas simplement brancher un arduino ( une multiwii ) , ca c'est juste du lego c'est trop facil , tout est déjà fait (bon d'un autre coté comme ca c'est sur que ca marche)
Apperement c'est possible de le faire "voler" sans "realtime" et sans arduino : http://www.raspberrypi.org/phpBB3/viewt ... 37&t=35746
pour alimenter les servo de la cam il te reste 3 bec qui servent a rien encore ou avec la carte adafruit il y'a déjà du courant qui doit arriver sur le cable rouge del fiche de commande.

laurent
Posts: 315
Joined: Thu Jul 26, 2012 11:24 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Mon May 27, 2013 12:30 pm

PHPower wrote:Plop tout le monde !

Merci de vos réponses :)

Je suis partie sur une base de RPi parce que j'y connais vraiment rien en electronique mais vraiment rien du tout ! (ça se voit je pense :lol: ) Du coup je préfère commencer avec le Pi et apprendre au fur à mesure. Je passerais au arduino c'est certains, mais pas tout de suite.
En fait je ne suggérais pas l'un ou l'autre, mais bien les deux.
Ils n'ont pas la même utilité.
- Le Rpi est là pour gérer des trucs lourds (liaison WiFi, 3G, GPS, RF, module caméra, etc...), sans contrainte temps réel dure (besoin d'un temps de réaction précis et prévisible).
- La carte µC (Arduino ou autre) est là pour gérer les trucs rapides et légers (stabilité, contrôle moteur)
L'un pilotant l'autre.
Ca ne veut pas dire que tu ne peux pas réussir qu'avec le Rpi, mais la tâche ne sera peut-être pas aussi facile que tu le penses.
PHPower wrote:
Dans le cas d'un drone, imaginez qu'un accès Wi-Fi monopolise l'OS et bloque pendant 100ms la boucle d'asservissement du contrôle moteur, qui équilibre le drone ? C'est l'instabilité, voire le crash assuré.
Je pensais en faite utiliser des threads, ce qui empêcherais ce genre de problème. Qu'en pensez-vous ?
Les threads, comme les processus (applications), sont totalement contrôlés par l'OS.
Petit topo sur le multi-tâche : pour te donner l'impression que deux threads tournent en parallèle alors que ton système n'a qu'un processeur, ton OS va découper chaque threads et va les exécuter chacun morceau, par morceau, très rapidement.
Ces "morceaux" ne peuvent avoir plus d'une certaine durée, sans quoi le plus long bloquerait le système (cas du multitâche coopératif), donc ils ont une durée max, et après ils se font interrompre pour que les autres threads aient leur tour d'exécution.

Or, suivant l'OS et ses paramétrages, cette durée max de "morceau" peut-être assez longue. Pas pour notre perception humaine (qui croît toujours que deux threads s'exécutent en même temps), mais trop pour un bout de logiciel de l'autre thread qui doit attendre son tour, et dont le développeur présumait qu'il s'exécutait d'une traite sans interruption.

C'est très très très simplifié. Il existe plusieurs types de multi-tâche, plusieurs types d'ordonancement
(un peu de lecture : http://fr.wikipedia.org/wiki/Ordonnance ... nnancement )

Ensuite, il faut savoir que les threads de ton application ne sont pas les seuls à s'exécuter sur ton système. Il y a les autres applications et le système lui-même.
Et tout se beau monde cohabite dans le même espace d'exécution.

Il se peut alors qu'à un moment, un processus qui est utilisé par le système ne prenne pas tout son "morceau" de temps max qui peut lui être accordé, il rendra alors vite la main à ton soft, alors qu'à un autre moment, il prendra tout son "morceau" de temps alloué, et retardera d'autant le retour à ton soft.

ToOnS
Posts: 492
Joined: Sat Mar 23, 2013 10:29 am

Re: Projet DCY'Fly (Drone, Quadricopter)

Mon May 27, 2013 1:47 pm

pour les problèmes de vitesse de calculs c'est peu etre le coup de passer a la bibliotheque python qui lui plait pas trop , c'est les setpercent c'est ca ? (meme punition en commentant les setpercent pour voir si ca lag encore)
ca me parait violent les :

Code: Select all

void PCA9685::_init_(){
        setenv("PYTHONPATH", "./python_dependencies/Adafruit_PWM/", 0);
        Py_SetProgramName((char*) "Adafruit_PWM"); 
        Py_Initialize();		
        PyRun_SimpleString("from Adafruit_PWM_Servo_Driver import PWM\n"
                                "import time\n"
                                "pwm = PWM(0x40, debug=True)\n");		
	}

Code: Select all

void PCA9685::setPWMFreq(int _frequency){
		string cmd = (string) "pwm.setPWMFreq(" + int2str(_frequency) + (string) ")\n";
        PyRun_SimpleString(cmd.c_str());
        PyRun_SimpleString("time.sleep(5)\n");        
	}

Code: Select all

void PCA9685::setPWM(int channel, int on, int off){
		string cmd = "pwm.setPWM(" + int2str(channel) + (string) "," + int2str(on) + (string) "," + int2str(off) + (string) ")\n";
        PyRun_SimpleString(cmd.c_str());
	}
allez on se prend de courage meme si on aime pas ca et que ca fait peur on essai en C(++) , ca doit donner un truc du genre :

PCA9685.h

Code: Select all

#ifndef _PCA9685_H
#define _PCA9685_H
#include <inttypes.h>
#include "I2C.h"
// Register Definitions


#define MODE1 0x00			//Mode  register  1
#define MODE2 0x01			//Mode  register  2
#define SUBADR1 0x02		//I2C-bus subaddress 1
#define SUBADR2 0x03		//I2C-bus subaddress 2
#define SUBADR3 0x04		//I2C-bus subaddress 3
#define ALLCALLADR 0x05     //LED All Call I2C-bus address
#define LED0 0x6			//LED0 start register
#define LED0_ON_L 0x6		//LED0 output and brightness control byte 0
#define LED0_ON_H 0x7		//LED0 output and brightness control byte 1
#define LED0_OFF_L 0x8		//LED0 output and brightness control byte 2
#define LED0_OFF_H 0x9		//LED0 output and brightness control byte 3
#define LED_MULTIPLYER 4	// For the other 15 channels
#define ALLLED_ON_L 0xFA    //load all the LEDn_ON registers, byte 0 (turn 0-7 channels on)
#define ALLLED_ON_H 0xFB	//load all the LEDn_ON registers, byte 1 (turn 8-15 channels on)
#define ALLLED_OFF_L 0xFC	//load all the LEDn_OFF registers, byte 0 (turn 0-7 channels off)
#define ALLLED_OFF_H 0xFD	//load all the LEDn_OFF registers, byte 1 (turn 8-15 channels off)
#define PRE_SCALE 0xFE		//prescaler for output frequency
#define CLOCK_FREQ 25000000.0 //25MHz default osc clock
//! Main class that exports features for PCA9685 chip
class PCA9685 {
public:
	PCA9685(int,int);
	virtual ~PCA9685();


	void setPWMFreq(int);
	void setPWM(uint8_t, int, int);
	void setPWM(uint8_t, int);
	int getPWM(uint8_t);


private:
	I2C *i2c;
	void reset(void);
};
#endif
PCA9685.cpp

Code: Select all

#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <stdio.h>      /* Standard I/O functions */
#include <fcntl.h>
#include <syslog.h>		/* Syslog functionallity */
#include <inttypes.h>
#include <errno.h>
#include <math.h>


#include "PCA9685.h"


//! Constructor takes bus and address arguments
/*!
 \param bus the bus to use in /dev/i2c-%d.
 \param address the device address on bus
 */
PCA9685::PCA9685(int bus, int address) {
	i2c = new I2C(bus,address);
	reset();
	setPWMFreq(1000);
}


PCA9685::~PCA9685() {
	delete i2c;
}
//! Sets PCA9685 mode to 00
void PCA9685::reset() {


		i2c->write_byte(MODE1, 0x00); //Normal mode
		i2c->write_byte(MODE2, 0x04); //totem pole


}
//! Set the frequency of PWM
/*!
 \param freq desired frequency. 40Hz to 1000Hz using internal 25MHz oscillator.
 */
void PCA9685::setPWMFreq(int freq) {


		uint8_t prescale_val = (CLOCK_FREQ / 4096 / freq)  - 1;
		i2c->write_byte(MODE1, 0x10); //sleep
		i2c->write_byte(PRE_SCALE, prescale_val); // multiplyer for PWM frequency
		i2c->write_byte(MODE1, 0x80); //restart
		i2c->write_byte(MODE2, 0x04); //totem pole (default)
}


//! PWM a single channel
/*!
 \param led channel to set PWM value for
 \param value 0-4095 value for PWM
 */
void PCA9685::setPWM(uint8_t led, int value) {
	setPWM(led, 0, value);
}
//! PWM a single channel with custom on time
/*!
 \param led channel to set PWM value for
 \param on_value 0-4095 value to turn on the pulse
 \param off_value 0-4095 value to turn off the pulse
 */
void PCA9685::setPWM(uint8_t led, int on_value, int off_value) {
		i2c->write_byte(LED0_ON_L + LED_MULTIPLYER * (led - 1), on_value & 0xFF);
		i2c->write_byte(LED0_ON_H + LED_MULTIPLYER * (led - 1), on_value >> 8);
		i2c->write_byte(LED0_OFF_L + LED_MULTIPLYER * (led - 1), off_value & 0xFF);
		i2c->write_byte(LED0_OFF_H + LED_MULTIPLYER * (led - 1), off_value >> 8);
}


int PCA9685::getPWM(uint8_t led){
	int ledval = 0;
	ledval = i2c->read_byte(LED0_OFF_H + LED_MULTIPLYER * (led-1));
	ledval = ledval & 0xf;
	ledval <<= 8;
	ledval += i2c->read_byte(LED0_OFF_L + LED_MULTIPLYER * (led-1));
	return ledval;
}
Last edited by ToOnS on Mon May 27, 2013 6:08 pm, edited 2 times in total.

Return to “Français”