Outils pour utilisateurs

Outils du site


wiki:god:not_today:home

Ceci est une ancienne révision du document !


Not Today

I - Présentation de l’équipe

Les membres et leurs parcours

Nous sommes une équipe composée de 5 personnes de L3 Informatique :

  • Julien Gourraud (bac STI, DUT informatique)
  • William Lavoué (bac SSI spé SI)
  • Salmane Kechkar (bac S)
  • Yacine Boukhelif(bac S)
  • Emeric Goga (bac S, 1ère année en PEIP)
Pourquoi participer à cette compétition

Nous sommes très intéressés par cette compétition, car nous voulons mettre en places nos connaissances diverses en Informatique et Électronique, mais également pour le défi technique. La conception et la réalisation d’un drone sera une expérience valorisante tant sur le plan personnel que professionnel. De plus, elle nous permettra de nous confronter aux différents défis que représente le travail en équipe.

La répartition des tâches au sein de l’équipe

Nous avons réparti le travail de la manière suivante

  • William : Conception de la structure / Électronique
  • Julien : Électronique / Programmation
  • Yacine Boukhelif : Impression 3D
  • Salmane : Programmation / Modélisation mathématique
  • Emeric : Programmation / Mécanique

II - Type de drone

La structure

Nous avons choisi de réaliser un quadricoptère en X, car ce modèle représente un bon com-promis entre le prix de fabrication et la simplicité de conception ainsi que par la richesse de la documentation disponible. La structure (cf ci-dessous) sera réalisée à partir de plaques usinées et de tubes en fibres de carbone et les éléments d’assemblage imprimés en ABS. Nous avons choisi cette solution pour sa robustesse, sa légèreté et sa facilité de réalisation avec les moyens fournis par le PMCLab.

Plan 3D du drone

L’électronique et la mécanique du drone

Nous avons choisi des hélices de 10 pouces afin d’avoir un drone stable. Pour les faire tourner, nous avons décidés de prendre des moteurs tournant à une vitesse modérée. La position de l'ensemble sur les tubes sera variable.

Nous avons choisi de faire nous-mêmes la partie électronique du drone avec une carte bien connue : l’Arduino Due. Son avantage est sa simplicité d’utilisation, cette dernière est programmée grâce à son environnement de développement. Elle comporte de nombreuses Entrées/Sortie, ce qui permet de se connecter au mieux à nos différents composants.

Concernant la commande, nous avons opté pour une communication Radio, car c’est un mode de communication très robuste et simple d’utilisation. L'émetteur radio (une manette) comporte 6 canaux, quatre d’entre eux servent à la manœuvre du drone. Il nous en reste donc 2 pour d’autres applications telles qu’un changement de mode grâce au modification des PID.

Pour l’IMU, nous avons choisi une carte Adafruit qui comporte les 3 composants essentiels :

  • LSM303DLHC : accéléromètre 3 Axes / magnétomètre 3 Axes
  • L3GD20 : gyroscope 3 Axes
  • BMP180 : Baromètre

Les moteurs triphasé sont contrôlés à l’aide d’ESCs. Ces derniers sont alimentés par la batterie et contrôlés par la carte Arduino.

Ci-dessous, le montage électronique de notre drone.

IV - Choix et prix des composants

Hélice (10 pouces) + Moteur (15 A max / 935KV) : 11.96*5 = 60 € http://www.hobbyking.com/hobbyking/store/__43884__MT2213_935KV_MultiStar_Motor_and_Propeller_Combo_10_4_5_CW_CCW.html

ESC(20 A) : 16*4 = 64 € http://hobbyking.com/hobbyking/store/__42549__Afro_HV_20A_MultiRotor_ESC_High_Voltage_3_8s.html

Carte de distribution : 4 € http://hobbyking.com/hobbyking/store/__27035__Hobby_King_Octocopter_Power_Distribution_Board.html

Carte Adruino Due : 36 € http://store.arduino.cc/index.php?main_page=product_info&cPath=11_12&products_id=243

Mannette + Recepteur RC (6 canaux / 2,4Ghz) : 44 $ = 35 € * 20% = 42 € http://www.hobbypartz.com/exrc62tr.html

IMU (10 degrés de liberté) : 29$ = 24 € * 20% = 28.8 € http://www.adafruit.com/product/1604

Batterie (Lipo 5200mAh / 3S / 11.1V) : 22.18€ *2 = 44.36€ http://www.hobbyking.com/hobbyking/store/__62884__MultiStar_High_Capacity_3S_5200mAh_Multi_Rotor_Lipo_Pack.html

Moniteur de batterie (Alarme en cas de batterie faible): 1.59€ http://hobbyking.com/hobbyking/store/__22749__On_Board_Lipoly_Low_Voltage_Alarm_2s_3s.html

Chargeur de batterie : 18.39€ http://www.hobbyking.com/hobbyking/store/__7028__Turnigy_Accucel_6_50W_6A_Balancer_Charger_w_Accessories.html

Ubec (Alimentation de Arduino : 11.1V vers 9V): 4.70 € http://hobbyking.com/hobbyking/store/__52862__X9_PRO_9V_3A_UBEC_2_5S_Lipoly_7_2_21v_.html

Filtrage des vibrations : 2 € http://www.hobbyking.com/hobbyking/store/__40612__Vibration_Damping_Ball_50gram_8_pcs_bag_.html

Plaque de fibre de verre (1,5mm / 1000*500mm) : 34,90 € http://www.masterplatex.de/epages/62236671.sf/de_DE/?ObjectPath=/Shops/62236671/Products/%22FR4%20schwarz%22/SubProducts/0%2C5-FR4-schw-M

Tube Carbone (300*16*14mm) : 4*2.81 = 11.24€ http://www.hobbyking.com/hobbyking/store/__13215__Carbon_Fiber_Round_Tube_330x16x14mm.html

Velcro : 2.22€ http://www.hobbyking.com/hobbyking/store/__9374__Polyester_Velcro_Peel_n_stick_adhesive_side_V_STRONG_1mtr_.html

Achat de visserie en petite quantité directement chez Bricorama ou LeroyMerlin : 30 € Total : 60 + 64 + 4 + 36 + 42 + 28.8 + 44.36 + 1.59 + 18.39 + 4.70 + 2 + 34.9 + 11.24 + 2.2 + 30 = 384 €

V - Machines-outils

Nous avons utilisé la découpeuse laser pour usiner les 2 plaques de fibre de verre qui servent de “corps” pour le drone. L’imprimante 3D nous as servi pour réaliser nos éléments d’assemblage :

  • La fixation des bras sur le corps
  • La fixation des moteur sur les bras

L’informatique du drone

La programmation se fera sur la carte Arduino grâce à l'environnement de développement Ar-duino.

#include “Wire.h” #include <Adafruit_Sensor.h> #include <Adafruit_LSM303_U.h> #include <Adafruit_L3GD20_U.h> #include <Adafruit_BMP085_U.h> #include <Adafruit_10DOF.h>

#include <Servo.h>

#include <PID_v1.h>

// /VARIABLE RADIO/ // int vitesse = 0; const int pinCh1 = A0; const int pinCh2 = A1; const int pinCh3 = A2; const int pinCh4 = A3; const int pinCh5 = A4; micros when the pin goes HIGH volatile unsigned long timer_start1; volatile unsigned long timer_start2; volatile unsigned long timer_start3; volatile unsigned long timer_start4; volatile unsigned long timer_start5; difference between timer_start and micros() is the length of time that the pin was HIGH - the PWM pulse length. volatile int pulse_time1; volatile int pulse_time2; volatile int pulse_time3; volatile int pulse_time4; volatile int pulse_time5; Pour mapper les commandes entre 0 et 100 const int minCh1 = 1190; const int minCh2 = 1160; const int minCh3 = 1137; const int minCh4 = 1125; const int minCh5 = 9999; const int maxCh1 = 1930; const int maxCh2 = 1810; const int maxCh3 = 1790; const int maxCh4 = 1890; const int maxCh5 = 9999; double ch1 = 0; double ch2 = 0; double ch3 = 0; double ch4 = 0; double ch5 = 0; volatile int last_interrupt_time1; volatile int last_interrupt_time2; volatile int last_interrupt_time3; volatile int last_interrupt_time4; volatile int last_interrupt_time5; // /VARIABLES IMU*/ //

/* Assign a unique ID to the sensors */ Adafruit_10DOF dof = Adafruit_10DOF(); Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301); Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(30302); Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(18001);

/* Update this with the correct SLP for accurate altitude measurements */ float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;

double pitchKi = 0.5; double pitchKp = 0; double pitchKd = 1;

double rollKi = 2; double rollKp = 5; double rollKd = 1;

double yawKi = 2; double yawKp = 5; double yawKd = 1;

double pitchIN; double rollIN; double yawIN;

double pitchOUT; double rollOUT; double yawOUT;

IN,OUT,SETPOINT PID pidPitch(&pitchIN, &pitchOUT, &ch2, pitchKp, pitchKi, pitchKd, REVERSE); PID pidRoll(&rollIN, &rollOUT, &ch1, rollKp, rollKi, rollKd, REVERSE); PID pidYaw(&yawIN, &yawOUT, &ch4, yawKp, yawKi, yawKd, DIRECT); int pitchMin = -30; int pitchMax = 30; int rollMin = -30; int rollMax = 30; int yawMin = -180; int yawMax = 180; // /VARIABLES MOTORS/ // Objet servo pour controler les diff�rents moteurs Servo motor1, motor2, motor3, motor4;

const int pinM1 = 9; const int pinM2 = 10; const int pinM3 = 11; const int pinM4 = 6;

int speedM1 = 0; int speedM2 = 0; int speedM3 = 0; int speedM4 = 0; int speedM1M3 = 0; int speedM2M4 = 0;

int pinKill = 3; volatile int stopAll = 0;

// /*MAIN*/ // void setup() { Serial.begin(115200); initSensors(); initInterrupt(); initPID(); initMotors(); 15 SECONDES pinMode(pinKill, INPUT_PULLUP); attachInterrupt(pinKill, kill, CHANGE); pinMode(13, OUTPUT); } void loop() { Serial.println(stopAll); if (stopAll>2) { digitalWrite(13, HIGH); turn the LED on (HIGH is the voltage level) delay(500); wait for a second digitalWrite(13, LOW); turn the LED off by making the voltage LOW delay(500); } else { getSensor(); getRadio();map les cannaux de 0 � 100 calcSpeed();calcul en fontion des commandes et du PID la vitesse � appliquer aux moteurs updateMotors();met � jour la vitesse des moteurs / TEST_affichagePitch(); TEST_affichageCanaux(); TEST_affichageMoteur(); } } // /FONCTIONS RADIO*/ // void isr1() { record the interrupt time so that we can tell if the receiver has a signal from the transmitter last_interrupt_time1 = micros(); if the pin has gone HIGH, record the microseconds since the Arduino started up if (digitalRead(pinCh1) == HIGH) { timer_start1 = micros(); } otherwise, the pin has gone LOW else { only worry about this if the timer has actually started if (timer_start1 > 0) { record the pulse time pulse_time1 = 1)

1)
volatile int)micros() - timer_start1);
    //restart the timer
    timer_start1 = 0;
  }
}
} void isr2() {
last_interrupt_time2 = micros();
if (digitalRead(pinCh2) == HIGH) {
  timer_start2 = micros();
}
else {
  if (timer_start2 > 0) {
    pulse_time2 = ((volatile int)micros() - timer_start2);
    timer_start2 = 0;
  }
}
} void isr3() {
last_interrupt_time3 = micros();
if (digitalRead(pinCh3) == HIGH) {
  timer_start3 = micros();
}
else {
  if (timer_start3 > 0) {
    pulse_time3 = ((volatile int)micros() - timer_start3);
    timer_start3 = 0;
  }
}
} void isr4() {
last_interrupt_time4 = micros();
if (digitalRead(pinCh4) == HIGH) {
  timer_start4 = micros();
}
else {
  if (timer_start4 > 0) {
    pulse_time4 = ((volatile int)micros() - timer_start4);
    timer_start4 = 0;
  }
}
} void isr5() {
last_interrupt_time5 = micros();
if (digitalRead(pinCh5) == HIGH) {
  timer_start5 = micros();
}
else {
  if (timer_start5 > 0) {
    pulse_time5 = ((volatile int)micros() - timer_start5);
    timer_start5 = 0;
  }
}
} void initInterrupt() {
timer_start1 = 0;
timer_start2 = 0;
timer_start3 = 0;
timer_start4 = 0;
timer_start5 = 0;
attachInterrupt(pinCh1, isr1, CHANGE);
attachInterrupt(pinCh2, isr2, CHANGE);
attachInterrupt(pinCh3, isr3, CHANGE);
attachInterrupt(pinCh4, isr4, CHANGE);
attachInterrupt(pinCh5, isr5, CHANGE);
} void getRadio() {
ch1 = map(pulse_time1, minCh1, maxCh1, rollMin, rollMax); //ROLL
ch2 = map(pulse_time2, minCh2, maxCh2, pitchMin, pitchMax); //PITCH
ch3 = map(pulse_time3, minCh3, maxCh3, 0, 100); //VITESSE
ch4 = map(pulse_time4, minCh4, maxCh4, yawMin, yawMax); //YAW
ch5 = map(pulse_time5, minCh5, maxCh5, 0, 100);
} void TEST_affichageCanaux() {
Serial.print("CH1 : ");
Serial.print(pulse_time1);
Serial.print("-->");
Serial.print(ch1);
Serial.print(" - CH2 : ");
Serial.print(pulse_time2);
Serial.print("-->");
Serial.print(ch2);
Serial.print(" - CH3 : ");
Serial.print(pulse_time3);
Serial.print("-->");
Serial.print(ch3);
Serial.print(" - CH4 : ");
Serial.print(pulse_time4);
Serial.print("-->");
Serial.println(ch4);
} // /*FONCTIONS IMU/ // void initSensors() { if (!accel.begin()) { Serial.println(F(“Ooops, no LSM303 detected … Check your wiring!”)); while (1); } if (!mag.begin()) { Serial.println(“Ooops, no LSM303 detected … Check your wiring!”); while (1); } if (!bmp.begin()) { Serial.println(“Ooops, no BMP180 detected … Check your wiring!”); while (1); } } void getSensor() { sensors_event_t accel_event; sensors_event_t mag_event; sensors_event_t bmp_event; sensors_vec_t orientation; /* Calculate pitch and roll from the raw accelerometer data */ accel.getEvent(&accel_event); if (dof.accelGetOrientation(&accel_event, &orientation)) { /* 'orientation' should have valid .roll and .pitch fields */ Serial.print(F(“Roll: ”)); Serial.print(orientation.roll); Serial.print(F(“; ”)); Serial.print(F(“Pitch: ”)); Serial.print(orientation.pitch); Serial.print(F(“; ”)); rollIN = map(orientation.roll, -180, 180, -100, 100); pitchIN = map(orientation.pitch, -180, 180, -100, 100); } /* Calculate the heading using the magnetometer */ mag.getEvent(&mag_event); if (dof.magGetOrientation(SENSOR_AXIS_Z, &mag_event, &orientation)) { /* 'orientation' should have valid .heading data now */ Serial.print(F(“Heading: ”)); Serial.print(orientation.heading); Serial.print(F(“; ”)); yawIN = map(orientation.heading, -180, 180, -100, 100); } /* Calculate the altitude using the barometric pressure sensor */ bmp.getEvent(&bmp_event); if (bmp_event.pressure) { /* Get ambient temperature in C */ float temperature; bmp.getTemperature(&temperature); /* Convert atmospheric pressure, SLP and temp to altitude */ Serial.print(F(“Alt: ”)); Serial.print(bmp.pressureToAltitude(seaLevelPressure, bmp_event.pressure, temperature)); Serial.print(F(“ m; ”)); /* Display the temperature */ Serial.print(F(“Temp: ”)); Serial.print(temperature); Serial.print(F(“ C”)); } Serial.println(F(“”)); delay(250); } void TEST_affichagePitch() { Serial.print(“Yaw:”); Serial.print(yawIN); Serial.print(“ - Kp:”); Serial.print(pitchKp); Serial.print(“ - Ki:”); Serial.print(pitchKi); Serial.print(“ - Kd:”); Serial.print(pitchKd); Serial.print(“ - CH2:”); Serial.print(ch2); Serial.print(“ - PitchIN:”); Serial.print(pitchIN); Serial.print(“ - PitchOUT:”); Serial.println(pitchOUT); } void TEST_affichageRoll() { Serial.print(“RollIN : ”); Serial.print(rollIN); Serial.print(“ - RollOUT : ”); Serial.println(rollOUT); } void TEST_affichageYaw() { Serial.print(“YawIN : ”); Serial.print(yawIN); Serial.print(“ - YawOUT : ”); Serial.println(yawOUT); } // /*FONCTION CALCUL*/ // void initPID() { pidPitch.SetMode(AUTOMATIC); pidPitch.SetOutputLimits(-20, 20); pidRoll.SetMode(AUTOMATIC); pidRoll.SetOutputLimits(-20, 20); pidYaw.SetMode(AUTOMATIC); pidYaw.SetOutputLimits(-180, 180); } void calcSpeed() { noInterrupts(); pidPitch.Compute(); pidRoll.Compute(); pidYaw.Compute(); interrupts(); speedM1M3 = ((-100 + yawOUT) / 100) * ch3;
speedM2M4 = ((100 + yawOUT) / 100) * ch3;
speedM1 = ((100 + rollOUT) / 100) * speedM1M3;
speedM2 = ((100 + pitchOUT) / 100) * speedM2M4;
speedM3 = (((-100 + rollOUT) / 100)) * speedM1M3;
speedM4 = (((-100 + pitchOUT) / 100)) * speedM2M4;
/*.....calcul des valeurs ci dessous avec les ch et le PID......*/
} void TEST_affichageMoteur() {
Serial.print("M1 :");
Serial.print(speedM1);
Serial.print(" - M2:");
Serial.print(speedM2);
Serial.print(" - M3:");
Serial.print(speedM3);
Serial.print(" - M4:");
Serial.println(speedM4);
} // /*FONCTIONS MOTORS*/ /**/ Initialisation des moteurs : 5 SECONDES void initMotors() { Serial.println(“InitMotors”);
delay(5000);
motor1.attach(pinM1);
motor2.attach(pinM2);
motor3.attach(pinM3);
motor4.attach(pinM4);
//  motor1.write(170);
//  motor2.write(170);
//  motor3.write(170);
//  motor4.write(170);
//  Serial.println("Brancher ALIM!!");
//  delay(5000);  //BRANCHER ALIM
motor1.write(0);
motor2.write(0);
motor3.write(0);
motor4.write(0);
delay(5000);
} Mise a jour de la vitesse des moteur en fontion des variables globales void updateMotors() { vitesse = map(ch3, 0, 100, 0, 160); motor1.write(vitesse); motor2.write(vitesse); motor3.write(vitesse); motor4.write(vitesse); } void kill() { Serial.println(“Interrupt”); stopAll++; motor1.write(0); motor2.write(0); motor3.write(0); motor4.write(0); } === Les problèmes rencontré === === III - Évolution possible du drone === Nous souhaitons faire évoluer notre drone s’il nous reste du temps (et de l’argent). Nous ajouterions un GPS et un Raspberry Pi au drone. Le but serait de : - Faire voler le drone avec la manette en sauvegardant le chemin pris grâce aux coordonnées GPS - Faire voler le drone sur le même passage Le coût de cette amélioration serait d’environ 100€ : Carte GPS : 50 € Antenne GPS : 10 € Raspberry Pi : 40 € === VI - Sites de nos recherches === * Wiki de Game of Drone 2013-2014 * Adafruit * Site officiel Arduino * Instructable * HobbyKing * DiyDrones === VII - Conclusion === On va gagner!
wiki/god/not_today/home.1426636599.txt.gz · Dernière modification: 2016/09/11 11:00 (modification externe)