stabilisateur de drone

a marqué ce sujet comme résolu.

Salut tout le monde , je suis en troisième année universitaire et je dois soutenir mon sujet qui est la conception et la réalisation d’un stabilisateur de drone .J’ai essayer de constituer un programme Arduino pour l’asservissement PID a partir de certaines sources , mais quand je le téléverser les moteur ne fonctionne déjà pas avec la vitesse moyenne ( throttle). svp demande votre aide. Voici mon programme sur Arduino Uno:

#include "Wire.h"

int gyro_address = 0x68,a=0;
int16_t acc_x,acc_y,acc_z,gyro_x,gyro_y,gyro_z,temp;
double acc_x_bis,acc_y_bis,acc_z_bis,gyro_z_bis,gyro_y_bis,gyro_x_bis;
double acc_x_cal,acc_y_cal,acc_z_cal,gyro_z_cal,gyro_y_cal,gyro_x_cal;
float angle=0,error,setpoint=0,error_variation=0,error_last=0,pid_integral_last=0,pid_derivative=0,pid_proportionnel=0,pid_integral=0,control=0,timer_channel_1;
float timer_channel_2,loop_timer,esc_1,esc_2,esc_loop_timer;
const float kp=2;
const float ki=3;
const float kd=4;
const float throttle=1400;

void MPU_config(){
  // configuration de l'accéléromètre
  Wire.beginTransmission(gyro_address);
  Wire.write(0x1C);   // registre qui contient les bits de configuration AFS_SEL
  Wire.write(0x00);   // AFS_SEL = 0 (10) échelle = 16384
  Wire.endTransmission(true);

  // Configuration du gyromètre
  Wire.beginTransmission(gyro_address);
  Wire.write(0x1B);   // registre qui contient les bits de configuration FS_SEL
  Wire.write(0x00);   // FS_SEL=0 échelle = 131
  Wire.endTransmission(true);
}

void MPU_read_data(){
  Wire.beginTransmission(gyro_address);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(gyro_address,14);
  acc_x = Wire.read()<<8 | Wire.read();
  acc_y = Wire.read()<<8 | Wire.read();
  acc_z = Wire.read()<<8 | Wire.read();
  gyro_x = Wire.read()<<8 | Wire.read();
  gyro_y = Wire.read()<<8 | Wire.read();
  gyro_z = Wire.read()<<8 | Wire.read();
  acc_x_bis = (float)acc_x /16384;
  acc_y_bis = (float)acc_y /16384;
  acc_z_bis = (float)acc_z /16384;
  gyro_x_bis = (float)gyro_x /131;
  gyro_y_bis = (float)gyro_y /131;
  gyro_z_bis = (float)gyro_z /131;
  if(a==2000){
    acc_x_bis-=acc_x_cal;
    acc_y_bis-=acc_y_cal;
    acc_z_bis-=acc_z_cal;
    gyro_x_bis-=gyro_x_cal;
    gyro_y_bis-=gyro_y_cal;
    gyro_z_bis-=gyro_z_cal;
  
    
  }
 
}    
    void MPU_cal(){
        
      for (a = 0; a <= 2000 ; a ++)  {   
                              
       MPU_read_data();
       
       
        gyro_x_cal += gyro_x_bis;                                              
        gyro_y_cal += gyro_y_bis;                                               
        gyro_z_cal += gyro_z_bis;                                               
        acc_x_cal += acc_x_bis;                                              
        acc_y_cal += acc_y_bis;                                               
        acc_z_cal += acc_z_bis-1;  
   }             
                                                                 
      gyro_x_cal /= 2000;                                                        
      gyro_y_cal /= 2000;                                                        
      gyro_z_cal /= 2000;    
      acc_x_cal /= 2000;                                                        
      acc_y_cal /= 2000;                                                        
      acc_z_cal /= 2000;
       

}

void pid_balance(){
  error=setpoint-angle;
  error_variation=error-error_last;
  pid_proportionnel = kp*error;
  pid_integral =pid_integral_last+ki*error ;
  pid_derivative = kd*error_variation;
  control = pid_proportionnel+pid_integral+pid_derivative;
  error_last=error;
  pid_integral_last=pid_integral;
 
 esc_1=throttle;
 esc_2=throttle;
  
  
 // Serial.print("esc_ =  ");
  //Serial.println(esc_1);
  //Serial.print("esc_2 =  ");
  //Serial.println(esc_2);
}
 

 void esc_pulse_output(){
   loop_timer = micros();                                                    //Set the timer for the next loop.

  PORTD |= B01100000 ;                                               //Set digital outputs 4,5.
  timer_channel_1 = esc_1 + loop_timer;                                     //Calculate the time of the faling edge of the esc-1 pulse.
  timer_channel_2 = esc_2 + loop_timer;                                     //Calculate the time of the faling edge of the esc-2 pulse.
 
  while(PORTD >= 16){                                                       //Stay in this loop until output 4,5 are low.
    esc_loop_timer = micros();                                              //Read the current time.
    if(timer_channel_1 <= esc_loop_timer)PORTD &= B01000000;                //Set digital output 4 to low if the time is expired.
    if(timer_channel_2 <= esc_loop_timer)PORTD &= B00100000;  //Set digital output 5 to low if the time is expired.
  }
 }
  
  

void setup() {
  Wire.begin();
  
  Serial.begin(9600);
  Wire.beginTransmission(gyro_address); // Begins a transmission to the I2C slave (GY-521 board)
  Wire.write(0x6B); // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  
  MPU_config();
  MPU_read_data();
      
  MPU_cal();
  pid_balance();
}

void loop() {
  MPU_read_data();
    //Serial.print("acc_x =  ");
  //Serial.println(acc_x_bis);
//Serial.print(" | acc_y = ");
// Serial.println(acc_y_bis);
 // Serial.print(" | acc_z = ");
// Serial.println(acc_z_bis);
 
  //Serial.print(" | gyro_x = ");
  //Serial.println(gyro_x_bis);
  //Serial.print(" | gyro_y = ");
  //Serial.println(gyro_y_bis);
  //Serial.print(" | gyro_z = ");
  //Serial.println(gyro_z_bis);
 //  Serial.print(" | esc_1 = ");
  //Serial.println(esc_1);
   //Serial.print(" | esc_2 = ");
  //Serial.println(esc_2);
  
  angle= atan2((double)acc_y,(double)acc_z )*180/PI; // 180/PI permet d'avoir la valeur en °
  Serial.println(angle);
  pid_balance();
  esc_pulse_output();
  
  

 
delay(200);
}  
 


Un conseil: quand tu demandes de l’aide, écris un code minimal qui reproduit ton problème.

float timer_channel_1,timer_channel_2,loop_timer,esc_1,esc_2,esc_loop_timer;
const float throttle=1400;

 void esc_pulse_output(){
   loop_timer = micros();                                                    //Set the timer for the next loop.

  PORTD |= B01100000 ;                                               //Set digital outputs 4,5.
  timer_channel_1 = esc_1 + loop_timer;                                     //Calculate the time of the faling edge of the esc-1 pulse.
  timer_channel_2 = esc_2 + loop_timer;                                     //Calculate the time of the faling edge of the esc-2 pulse.
 
  while(PORTD >= 16){                                                       //Stay in this loop until output 4,5 are low.
    esc_loop_timer = micros();                                              //Read the current time.
    if(timer_channel_1 <= esc_loop_timer)PORTD &= B01000000;                //Set digital output 4 to low if the time is expired.
    if(timer_channel_2 <= esc_loop_timer)PORTD &= B00100000;  //Set digital output 5 to low if the time is expired.
  }
 }

void setup() {
  Serial.begin(9600);
 esc_1=throttle;
 esc_2=throttle;
}

void loop() {
  esc_pulse_output();
delay(200);
}  

normalement, tout le reste n’est pas utilisé, tu peux donc faire le test pour vérifier que ce n’est pas un problème liée au temps d’execution du reste du code, et ensuite nous demander de l’aide avec 8 fois moins de lignes de codes à lire, ce qui nous demande moins d’effort.

Si ce code reproduit bien le problème, il faudrait regarder les signaux générés avec un oscilloscope.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte