[SevArduPilot] Aide au pilotage d'avion RC...

Bonjour,

Je vous présente ici mon projet, ce post fait office de référence pour expliquer le projet dans sa globalité, ce topic n'a pas pour but d'héberger des points techniques, je préfère ouvrir des sujets à part.

Le fil est structuré comme suit :

  1. Les points en cours (& ceux déjà traités)
  2. Présentation Globale
  3. Schéma & Digramme temporel
  4. Le code

1) Les points "traités" ou "en cours" sur ce forum

Chaque point est un lien vers un sujet dédié :

2) Présentation Globale

Tout d'abord, un petit rappel sur le fonctionnement d'un avion RC, ainsi qu'en dessous, comment j'intègre mon arduino la-dedans :

L'avion RC du prototype sera un EPPIM (c'est un avion destiné plutôt à l'immersion) qui a des proriété de vol plutôt 3D, une tite photo :

Il fait 80cm d'envergure & on vole 10 minutes avec cet avion qui pèse dans les 450gr à vide et qui peut serainnement monter à 600gr une fois équipé.

Ensuite quelques exemples d'utilisation imaginés :

3) Schéma & Digramme temporel

Le schéma actuel :

Une petit "diagramme" temporel des entrées/sorties RC :

4) Le code

Le code actuel qui comprend :

  • La lecture du PPM avec detection de coupure radio (failsafe)
  • la génération des signaux servo
// Lecture PPM6ch & écriture PWM V002
// C'est le timer1 qui est utilisé pour les 2 fonctions

#define LEDPINO 13 //La LED "locale" de l'Arduino

boolean endTrame=0,failsafe=0,firstEdge=1;

// Données de capture du Rx
volatile unsigned int vchUp[8];
volatile unsigned int vchPos[6];
unsigned int chPos[6];
byte curEdge;

// Données de génération des signaux servo
volatile unsigned int ocr1a,ocr1b;

void setup()
{
  // Pin setup
  pinMode(13,OUTPUT); //Arduino LED
  pinMode(9,OUTPUT); //Timer1 PWM1 (OCR1A)
  pinMode(10,OUTPUT); //Timer1 PWM2 (OCR1B)
  digitalWrite(13,HIGH); //Allumage de la LED de l'Arduino

  // Sortie DEBUG
  Serial.begin(57600);

  // Timer1 setup
  TCCR1A=B10100000; // OCR2A/OCR2B : falling mode, timer: normal mode
  TCCR1B=B00000010; // 2MHz (arround 0.5µs precision), with falling edge CAPTUREPIN detection
  TIMSK1=B00100001; // Activate CAPTUREPIN interrupt & OVF interrupt
}

ISR(TIMER1_CAPT_vect)
{
  vchUp[curEdge]=TCNT1; // Capture des timestamp 1 à 6
  curEdge++;
  if (curEdge>7) {     // A partie du 7ème...
    OCR1A=ocr1a;     //Ecriture de OCR1A & OCR1B (c'est le bon moment)
    OCR1B=ocr1b;
    TCNT1=0;           // RESET du counter pour éviter le FailSafe
    TCCR1A=B11110000; // OCR2A/OCR2B : En mode front montant
    TCCR1C=B11000000; // OCR2A/OCR2B : Déclenchement
    TCCR1A=B10100000; // OCR2A/OCR2B : En mode front descendant
    if ((vchUp[7]-vchUp[1]) > 30000) {        //Si la trame totale dépasse 15ms - Trame KO ou mauvaise synchro
      curEdge=0;            //Remise à 0 du compteur de fronts                      
    }
    else                                          //Sinon, une bonne trame est capturée, on calcule donc la valeur des canaux
    curEdge=1;
    for (int i=0;i<6;i++) {
      vchPos[i]=(vchUp[i+2]-vchUp[i+1])/2; //Mesure des canaux, divisé par 2 pour obtenir des µs
    }
    endTrame=1;           // Pour dire à la MainLoop que de nouvelles valeurs sont dispo
  }
}

ISR(TIMER1_OVF_vect)
{
  TCCR1A=B11110000; // OCR2A/OCR2B : En mode front montant
  TCCR1C=B11000000; // OCR2A/OCR2B : Déclenchement
  TCCR1A=B10100000; // OCR2A/OCR2B : En mode front descendant
  OCR1A=ocr1a;     //Ecriture de OCR1A & OCR1B (c'est le bon moment)
  OCR1B=ocr1b;
  failsafe=1;  // Le compteur à attends sa limite (32ms), on déclenche donc le FailSafe
}

void loop()
{
  if (endTrame==1) {
    cli();
    for (int i=0;i<6;i++) {
      chPos[i]=vchPos[i]; //Recpoie de la valeur des canaux
    }
    sei();
    endTrame=0;
    if (failsafe){ 
      failsafe=0;
      Serial.println("End of FailSafe");
    }

    // La 1ere partie "intelligente" du code se trouve ICI
    // Elle n'est jouée que si les canaux ont "bougé"

    for (int i=0; i < 6; i++){ // Iimprimer les valeurs des canaux sur le port série
      Serial.print(chPos[i]);
      Serial.print(";");
    }

    ocr1a=(chPos[4]*2); // La position du Servo1 est celle du canal 5
    ocr1b=(chPos[5]*2); // La position du Servo2 est celle du canal 6
    Serial.print(ocr1a);
    Serial.print(";");
    Serial.print(ocr1b);
    Serial.println(";");

  }

  // La 2eme partie "intelligente" du code se trouve ICI
  // Elle est jouée à chaque tour de boucle

    if (failsafe) Serial.println("FAILSAFE");

}

Sev

ce sujet est peu de peu technique. et beaucoup de termes électriques ont été décrits. ce post est très instructif pour ceux qui sont des experts dans le domaine de la RC.

Le projet est en pause car j'ai acheté ceci :
http://www.drotek.fr/shop/fr/72-multiwii-mpu6050-hmc5883-ms5611.html

Après avoir téléversé de code MultiWii dedans, hé bien ça fait déjà beaucoup de chose et très bien (notamment régulation PID).

Je ne crois pas qu'un capteur d'ultra-sons puisse maintenir l'altitude, ça ne porte pas assez loin (forte atténuation de ces fréquences dans l'air), mais un baromètre oui.

L'idée était tirée du Drone Parrot (v1) sur lequel ça fonctionne très bien, voir trop bien, puisque sa trajectoire de vol reflétait trop bien les asperités du sol, ce qui m'est parfois pas souhaité (vol par dessus un muret).

La véritable question était, est-ce exportable sur un avion dont le vol n'est pas de type stationnaire.

En tout cas, Parrot est de ton avis puisqu'ils ont implementé des baromètres sur leur drone v2.

Moi au contraire, je pense qu'un capteur d'ultra-sons peut marcher, s'il ne dépasse pas une certaine altitude.