RC India
Welcome Guest, please login or register.
 
Pages: [1]   Go Down
0 Members and 1 Guest are viewing this topic. Topic Tools Topic Tools 
Read
« on: December 22, 2018, 02:05:30 PM »
sainatarajan
Heli Lover
Active Member
**

Reputation Power: 1 
sainatarajan has no influence.
Offline Offline

City: Chennai
State: Tamil Nadu
RC Skills: Beginner
Posts: 2
Join Date: Dec, 2018




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 :

1. Are the motor mixing values correct ? (from the updateMotorSpeeds() function)
2. I'm not sure whether to use a PID controller for stabilization of the quadcopter?
3. What should be the motor values for the sequence of movements that I had mentioned above?
4. Also I am calculating complementary filter and computing PID values every time I increase my throttle by 1 in the goUp() function. Am I right in doing so?
Logged
 

Read
« Reply #1 on: December 22, 2018, 05:23:41 PM »
Dharmik
Heli Lover
Forum Hero

*****

Reputation Power: 13 
Dharmik has no influence.
Offline Offline

City: Bharuch
State: Gujarat
RC Skills: Beginner
Posts: 1097
Join Date: Sep, 2011



look interesting project. if you have any video after flashing this code then it might help further. have you assigned pinout to the motors? also

controlMotorAlgorithm(); // assigns motor values
writePWMToAllMotors()

these two functions code seems missing above.
Logged
 

Read
« Reply #2 on: December 22, 2018, 09:02:03 PM »
saikat
Plane Lover
Forum Hero
*****

Reputation Power: 14 
saikat has no influence.
Offline Offline

City: Tezpur
State: Tripura
RC Skills: Expert
Posts: 1130
Join Date: Jul, 2009



Firstly post complete code ....
Eg : how do you assign variable throttle , pitch , yaw  roll etc...

Secondly to get proper motor pwm value , put standard transmitter receiver - fly the programmed
sequence and record each motor pwm values using avr input capture interrupts
Then you can use those values to programme your processor

Logged

 

Read
« Reply #3 on: December 24, 2018, 02:33:15 PM »
sainatarajan
Heli Lover
Active Member
**

Reputation Power: 1 
sainatarajan has no influence.
Offline Offline

City: Chennai
State: Tamil Nadu
RC Skills: Beginner
Posts: 2
Join Date: Dec, 2018




void mdhdrone::initPIDController() {

rollPID.begin();          // initialize the PID instance
pitchPID.begin();          // initialize the PID instance
yawPID.begin();          // initialize the PID instance
 
  rollPID.setpoint(0);    // The "goal" the PID controller tries to "reach"
  pitchPID.setpoint(0);    // The "goal" the PID controller tries to "reach"
  yawPID.setpoint(0);    // The "goal" the PID controller tries to "reach"
 
  rollPID.tune(1, 0.1, 0.5);   
  pitchPID.tune(1, 0.1, 0.5);   
  yawPID.tune(1, 0.1, 0.5);   
 
  rollPID.limit(0, 255);
  pitchPID.limit(0, 255);
  yawPID.limit(0, 255);
}

void mdhdrone::setupMPU() {
Wire.beginTransmission(0b1101000);
    Wire.write(0x6B);                 
    Wire.write(0b00000000);           
    Wire.endTransmission();
   
    Wire.beginTransmission(0b1101000);
    Wire.write(0x1B);                 
    Wire.write(0x08);                 
    Wire.endTransmission();

    Wire.beginTransmission(0b1101000);
    Wire.write(0x1C);                 
    Wire.write(0x10);                 
    Wire.endTransmission();

    Wire.beginTransmission(0b1101000);
    Wire.write(0x1A);                 
    Wire.write(0x03);                 
    Wire.endTransmission();           
}

void mdhdrone::recordRegisters() {

    Wire.beginTransmission(0b1101000);
    Wire.write(0x3B);                 
    Wire.endTransmission();
    Wire.requestFrom(0b1101000, 14); 
   
    //Serial.println("Pre while loop");
    while (Wire.available() < 14);
    //Serial.println("Post while loop");
    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 mdhdrone::controlMotorAlgorithm() {

front_left_motor_speed= (int)(throttle - pitchPIDOutput - rollPIDOutput + yawPIDOutput);
front_right_motor_speed= (int)(throttle - pitchPIDOutput + rollPIDOutput - yawPIDOutput);
back_left_motor_speed= (int)(throttle + pitchPIDOutput - rollPIDOutput - yawPIDOutput);
back_right_motor_speed= (int)(throttle + pitchPIDOutput + rollPIDOutput + yawPIDOutput);

/*I am mapping it because sometimes the values goes out of range*/
front_left_motor_speed= map(front_left_motor_speed, -15, 280, 0, 255);
front_right_motor_speed= map(front_right_motor_speed, -15, 280, 0, 255);
back_left_motor_speed= map(back_left_motor_speed, -15, 280, 0, 255);
back_right_motor_speed= map(back_right_motor_speed, -15, 280, 0, 255);

}

void mdhdrone::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 mdhdrone::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 mdhdrone::startTimer() {
timer= micros();
}

void mdhdrone::goUp() {
Serial.println("Going up......");
for(; throttle <= 255; throttle++) {
mdhdrone::calcComplementaryFilter();

rollPIDOutput= rollPID.compute(roll);
pitchPIDOutput= pitchPID.compute(pitch);
yawPIDOutput= yawPID.compute(yaw);

mdhdrone::controlMotorAlgorithm();

mdhdrone::printMotorValues();
mdhdrone::writePWMToAllMotors();
delay(25);
}
}

void mdhdrone::comeDown() {
Serial.println("Coming down......");
for(; throttle > 1; throttle--) {
mdhdrone::calcComplementaryFilter();

rollPIDOutput= rollPID.compute(roll);
pitchPIDOutput= pitchPID.compute(pitch);
yawPIDOutput= yawPID.compute(yaw);

mdhdrone::controlMotorAlgorithm();

mdhdrone::printMotorValues();
mdhdrone::writePWMToAllMotors();
delay(50);
}
}

void mdhdrone::writePWMToAllMotors() {
analogWrite(front_left_pin, front_left_motor_speed);
analogWrite(front_right_pin, front_right_motor_speed);
analogWrite(back_left_pin, back_left_motor_speed);
analogWrite(back_right_pin, back_right_motor_speed);
}


Thanks for your suggestions..
I have posted the entire code without the getter and setter functions.
The mini-drone tries to lift but falls from my hand when we were testing it out in the ground. I can definitely feel a lot of thrust from the motors and it lifts up for a second and then traverses an inverted U path to the ground. What can be the reason for this?
Logged
 

Pages: [1]   Go Up
Jump to:  

Related Topics
Subject Started by Replies Views Last post
Thermocole plane flight issues
Tools, Materials and Building Techniques
alok roxx 8 8760 Last post May 30, 2011, 06:50:20 PM
by alok roxx
Mini quadcopter with arduino
Multirotors
shivela39 5 4585 Last post September 02, 2013, 10:46:18 AM
by manojswizera
Arduino as flight controller???
Multirotors
rohan123 17 8391 Last post September 05, 2014, 10:57:51 PM
by rohan123
Flight controller with Arduino due
Self-designed, DIY and College Projects
ghoshatanu56 8 6030 Last post June 23, 2015, 10:52:17 PM
by jayeshjain88
Arduino Quadcopter
Multirotors
Aravind298 8 4416 Last post March 20, 2018, 01:31:27 AM
by Erpoyo