Hi all,

Our quadrirotor Drone is about to be finalized and we are currently trying to find out the regulation coefficients. To do that, we built a kind of seesaw which makes the drone only rotating on one axis (rolling, pitching and yaw).

The Inertial measurement unit (IMU) is a Sparkfun (http://www.sparkfun.com/products/9623)  Razoe 9 DoF. The boot offers a compatibility with Arduino which allows us to modify and load code, especially a good version calculating Euler angles with 3 gyros, 3 accelerometers and 3 magnetometers. To conclude, this IMU is compatible with Attitude and Heading Reference System (AHRS). The code can be found by following this link: http://code.google.com/p/sf9domahrs/.

The only constraint is the initialisation of this IMU which involves placing the drone in a horizontal position. This is how the IMU will build its reference. I was really surprised by the precision and by the motor noise. The IMU values vary between                +- 0.2° on shorts periods and the drift only depends on magnetometers. Outside, it hardly never varies. Inside, take care about your screens/TVJ.

Then, we decided to command our drone with angle information given by our IMU. NB: we don’t use a radio control but xBees in order to have a proper telemetry.

We have a « false » simulator remote control to pilot the drone sending angles  (after a processing on the PC) varying from +20° to -20° for the rolling and pitching. Moreover, there is an increment step for the yaw. There is a handle which only command the global motor power.

We finally use 3 PID for the three axis managing motors (rolling, pitching, yaw). The PID algorithm used is:

deltaMoteur = Function(consignAngle, globalPower) * (consignAngle + PID(consignAngle, imuAngle);

Our PID is described as following:

 error = consignAngle - imuAngle;
 sumError += error;
 PID = Kp * (error)   +   Ki * sumError  +  Kd * (lastError - error);
 lastError = error;

Here is our implementation:

PID PART:

 public double calcPID(double consign, double measure) {
      double error;
      
      // Reset de sumError when a consign change occurs
      if (consign != lastConsign){
         sumError = 0;
         lastConsign = consign;
      }
      
      deltaCommand = consign;
      // Compute angle error
      error = consign - measure;
      // Proportional coefficient applied to current error and converted to a motor command by consignCoef
      deltaCommand += error * kProportional;
      // Increment angle error
      sumError += error;
      // Integral coefficient applied to current error and converted to a motor command by consignCoef
      deltaCommand += sumError * kIntegral;
      // Derivative coefficient applied to current error and converted to a motor command by consignCoef
      deltaCommand += (lastError - error) * kDerivative;
      lastError = error;
      return consignCoef*deltaCommand;
   }

The function returns a deltaCommand. You can see below the code used to set our motors:

REGULATION PART:

 // Motor initialisation to a global power

      FrontMotor = RightMotor = BackMotor = LeftMotor = puissanceGlobale;

      // PHI calculation : rolling
      deltaRollingCommand = phiPID.calcPID(Consign.phi, IMUData.phi);
      RightMotor = RightMotor + deltaRollingCommand;
      LeftMotor = LeftMotor - deltaRollingCommand;

      // THETA calculation : pitching
      deltaPitchingCommand = thetaPID.calcPID(Consign.theta, IMUData.theta);
      frontMotor = frontMotor - deltaPitchingCommand;
      BackMotor = BackMotor + deltaPitchingCommand;

      // PSI calcaulation : yaw
      deltaYawCommand = psiPID.calcPID(Consign.psi, IMUData.psi);
      frontMotor = frontMotor + deltaYawCommand;
      RightMotor = RightMotor - deltaYawCommand;
      BackMotor = BackMotor + deltaYawCommand;
      LeftMotor = LeftMotor - deltaYawCommand;

To approximate, we first consider that Function(consignAngle, globalPower) is a linear function (which is most probably false) and we replace this function by a constant : consignCoef.

We found this constant by measuring motor powers function of angles. To be realistic we are going to build a look-up table and approximate.

Now, I would have some questions:

When you use a regulation function of angles, do you use the same approach?

We have some difficulties to have a fast stabilization of the drone. However, we notice important oscillation when the PID coefficients are too high. Does it come from the integral calculation? Is it really relevant to reset the sumError when the consign changes? Shouldn’t we use a sliding window to integrate?

What is your approach to find out the PID coefficients?

I know that the derivative is noise sensitive: should I filter IMU values? How could I find cut-off filter frequencies (low-pass filter, high-pass filter, order X filter, etc…) ?

Looking forward to hearing from your advices/notes soon.

Sincerely

Guillaume

Views: 633

Reply to This

Social Networking

Contests

Season Two of the Trust Time Trial (T3) Contest has now begun. The fourth round is an accuracy round for multicopters, which requires contestants to fly a cube. The deadline is April 14th.

A list of all T3 contests is here

Groups

Advertisement

© 2013   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service