¿No puedo integrar PID en mi Quadcopter? ¿Es este el camino correcto?

0

Estoy trabajando en mi quadcopter. Ahora mismo estoy probando el despegue y el ángulo de balanceo. Intenté integrar la biblioteca PID en mi código, pero sigue generando 100 y mi quadcopter se dispara. Ahora mismo solo doy 1,1,1 para kp, ki y kd. Sé que esto no está bien, pero como dije, solo estoy jugando. Aquí está mi código. ..

    #define CHNL_HIGH 1900
      #define CHNL_LOW 1100

      #define THROTTLE_CHNL 2
      #define CW1_IN 9
      #define CW2_IN 10
      #define CW3_IN 11
      #define CW4_IN 12
      #define ARM_DEG 21
      #define THROTTLE_FLAG 1
      Servo servoCW1;
      Servo servoCW2;
      Servo servoCW3;
      Servo servoCW4;

      int servoCW1_DEG = 0;
      int servoCW2_DEG = 0;
      volatile uint8_t bUpdateFlagsShared;
      volatile uint16_t unThrottleInShared;
      volatile int throttleOffset; 
      uint32_t ulThrottleStart;

      float ypr[3]; // yaw pitch roll

      //Define Variables we'll be connecting to
      double Input_roll,rollOffset,Setpoint_roll;


      PID myPID(&Input_roll, &rollOffset, &Setpoint_roll,1,1,1, DIRECT);

      // Set the FreeIMU object
      FreeIMU my3IMU = FreeIMU();

      void setup() { 
        Serial.begin(115200);
        Wire.begin();

        delay(5);
        my3IMU.init(); // the parameter enable or disable fast mode

         //initialize the variables we're linked to

        Setpoint_roll = -5.00;

        //turn the PID on
        myPID.SetMode(AUTOMATIC);
        myPID.SetOutputLimits(-100.00, 100.00);

        servoCW1.attach(CW1_IN);
        servoCW2.attach(CW2_IN); 

        servoCW3.attach(CW3_IN);
        servoCW4.attach(CW4_IN);

        Serial.println("GET IT");
        arm();
        attachInterrupt(0, calcThrottle,CHANGE);


        delay(5);
      }


      void loop()
      {

        static uint16_t unThrottleIn;
        static uint8_t bUpdateFlags;

        // check shared update flags to see if any channels have a new signal
        if(bUpdateFlagsShared)
        {
          noInterrupts(); 

          bUpdateFlags = bUpdateFlagsShared;

          if(bUpdateFlags & THROTTLE_FLAG)
          {
            unThrottleIn = unThrottleInShared;
          }

          bUpdateFlagsShared = 0;

          interrupts(); // we have local copies of the inputs, so now we can turn interrupts back on

        }

       if(bUpdateFlags & THROTTLE_FLAG)

       {
            throttleChange(unThrottleIn);


       }
        my3IMU.getYawPitchRoll(ypr);
        Input_roll = ypr[2];
        myPID.Compute();
        rollChange(rollOffset);
        bUpdateFlags = 0;
      }



      void rollChange(double rollOffset)
      {
        int valCW1 = servoCW1.readMicroseconds();
        int valCW2 =  servoCW2.readMicroseconds();
      Serial.print("offset:       ");
        Serial.println(rollOffset);
        valCW1 = valCW1 + rollOffset;
        valCW2 = valCW2 - rollOffset;
       Serial.print("valCW1:       ");
        Serial.println(valCW1);

        Serial.print("valCW2:      ");
        Serial.println(valCW2);
         Serial.println("");
          Serial.println("");

        servoCW1.writeMicroseconds((int)valCW1);
        servoCW2.writeMicroseconds((int)valCW2);
      }
      void arm()
      {

        servoCW1.write(ARM_DEG);
        servoCW2.write(ARM_DEG);

        servoCW3.write(ARM_DEG);
        servoCW4.write(ARM_DEG);

      }

      void throttleChange(int cha_val)
      {


          servoCW1.writeMicroseconds(cha_val);
          servoCW2.writeMicroseconds(cha_val);

          servoCW3.writeMicroseconds(cha_val);
          servoCW4.writeMicroseconds(cha_val);

      }

      void calcThrottle()
      {
        if(digitalRead(THROTTLE_CHNL) == HIGH)
        {
          ulThrottleStart = micros();
        }else
        {

          unThrottleInShared = (uint16_t)(micros() - ulThrottleStart);
          bUpdateFlagsShared |= THROTTLE_FLAG;
        }
      }

Obtengo un rollOffset del controlador PID. Y la acción se realiza en la función rollchange (). Mi punto de ajuste es -5.00.

Problema: El PID produce 100 la mayor parte del tiempo. Y, no creo que esté ayudando a alcanzar mi punto de ajuste, sino que realmente lo está destruyendo. Así que mi pregunta es si realmente estoy usando la salida de PID de la manera correcta.

    
pregunta Rabin

1 respuesta

2

La salida de PID está generalmente diseñada para ser conectada directamente en la salida como su variable de control. Eso significa sin ninguna resta de adiciones. Me da la impresión de que su código requeriría algunas correcciones importantes. Sin embargo, como una solución rápida de bodge, puedes intentarlo así:

valCW1 =  rollOffset;
valCW2 = - rollOffset;
     

INCORRECTO: el resultado general debe ser positivo.

No solo necesitas un PID, sino más. Uno para tirar, uno para desviar, uno para lanzar, uno para altitud. Después de obtener todas las salidas PID, las agrega y las conecta directamente a sus variables valCWX. Quizás algo de esta manera (renombrado como compensación a resultado ):

valCW1 = altitudeResult + rollResult + yawResult;
valCW2 = altitudeResult - rollResult + yawResult;
valCW3 = altitudeResult + pitchResult - yawResult;
valCW4 = altitudeResult - pitchesult - yawResult;

Con esto, y algo de suerte, deberías poder controlar la cosa por completo. Pero una cosa más viene a la mente. Valor de fijación.

Sospecho que Arduino ya tiene una función restricción (x, min, max) . Aplica esto a tus salidas.

    
respondido por el Dzarda

Lea otras preguntas en las etiquetas