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
Tags:
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.1282 members
183 members
675 members
5 members
116 members
© 2013 Created by Chris Anderson.
Powered by
