I'm having little trouble in order to control the Arduino Micro Quadcopter that we are building. This quadcopter is built for a programmed flight sequence.
It has an MPU6050 as the IMU, 4 coreless motors, 4 MOSFETs and an Arduino Nano as the chip. We use PWM to control the speeds of the motors.
We are building this drone to perform a sequence of movements. Let's say : Going up for sometime, then going left, then going right, and atlast landing.
I'm using a complementary filter in order to fuse the values of accelerometer angles and gyro angles.
The code for it is :
void recordRegisters() {
Wire.beginTransmission(0b1101000);
Wire.write(0x3B);
Wire.endTransmission();
Wire.requestFrom(0b1101000, 14);
while (Wire.available() < 14);
accelX = Wire.read() << 8 | Wire.read();
accelY = Wire.read() << 8 | Wire.read();
accelZ = Wire.read() << 8 | Wire.read();
temperature = Wire.read() << 8 | Wire.read();
gyroX = Wire.read() << 8 | Wire.read();
gyroY = Wire.read() << 8 | Wire.read();
gyroZ = Wire.read() << 8 | Wire.read();
if (cal_int == 2000)
{
gyroX -= gyro_x_cal;
gyroY -= gyro_y_cal;
gyroZ -= gyro_z_cal;
}
}
void calcComplementaryFilter() {
recordRegisters();
gyroX = gyroX / 65.5;
gyroY = gyroY / 65.5;
gyroZ = gyroZ / 65.5;
accelX = accelX / 4096.0;
accelY = accelY / 4096.0;
accelZ = accelZ / 4096.0;
double dt = (double)(micros() - timer) / 1000000;
timer = micros();
rollAngle = atan2(accelY, accelZ) * 180 / PI;
pitchAngle = atan2(accelX, sqrt(accelY * accelY + accelZ * accelZ)) * 180 / PI;
roll = 0.99 * (roll + gyroX * dt) + 0.01 * rollAngle;
pitch = 0.99 * (pitch + gyroY * dt) + 0.01 * pitchAngle;
yaw = gyroZ;
}
void calibrateGyroscope() {
for (cal_int = 1; cal_int <= 2000; cal_int++)
{
recordRegisters();
gyro_x_cal += gyroX;
gyro_y_cal += gyroY;
gyro_z_cal += gyroZ;
}
gyro_x_cal /= 2000;
gyro_y_cal /= 2000;
gyro_z_cal /= 2000;
}
void updateMotorSpeeds() {
// Assume that the throttle is always constant for now.
front_left_motor_speed= (throttle - pitch - roll - yaw);
front_right_motor_speed= (throttle + pitch - roll + yaw);
back_left_motor_speed= (throttle - pitch + roll + yaw);
back_right_motor_speed= (throttle + pitch + roll - yaw);
}
void goUp() {
Serial.println("Going up......");
for(; throttle <= 200; throttle++) {
calcComplementaryFilter();
computePID();
controlMotorAlgorithm(); // assigns motor values
writePWMToAllMotors(); // does analogWrite() based on values set before
delay(25);
}
}
With due credits to the author of the above code, I'm able to get the values of roll, pitch and yaw. I'm using the updateMotorSpeeds() function to assign the proper values for the 4 motors. The problems I'm are facing are :
- Are the motor mixing values correct ? (from the updateMotorSpeeds() function)
- I'm not sure whether to use a PID controller for stabilization of the quadcopter?
- What should be the motor values for the sequence of movements that I had mentioned above?