Giter VIP home page Giter VIP logo

drone-flight-controller's Introduction

Quadcopter PID implementation

Build Status License: MIT

flight

1. Introduction

This Arduino sketch provides a flight controller for an X quadcopter based on an Arduino Uno board and the MPU6050 sensor.

Basically, this automation routine is an implementation of a digital PID with a refresh rate of 250Hz. The method used to calculate PID coefficients is Ziegler Nichols method. The frame of the quadcopter is based on the F450.

You can use this to calibrate your ESCs.

A detailed article is available here (in french).

(i) Currently under active development.

2. Requirements

Arduino libraries:

3. Pin connection:

       +-------------------------+
       |        MPU-6050         |
       |                         |
       | 3V3  SDA  SCL  GND  INT |
       +--+----+----+----+----+--+
          |    |    |    |
          |    |    |    |
+---------+----+----+----+----------------+
|        3.3V  A4   A5  GND               |
|                                         |
|                                         |
|                 Arduino Uno             |
|                                         |
| #4   #5   #6   #7   #8   #9  #10   #11  |
+--+----+----+----+----+----+----+----+---+
   |    |    |    |    |    |    |    |
  (M1) (M2) (M3) (M4)  |    |    |    |
                       |    |    |    |  
                       |    |    |    |
                    +--+----+----+----+---+
                    | C1   C2   C3   C4   |
                    |                     |
                    |     RF Receiver     |
                    +---------------------+
  
Legend:
Mx: Motor X
Cx: Receiver channel x

4. Configuration

4.1 Remote configuration

By default, this sketch uses the mode 2 for RF remote, according to the following picture:

remote modes

The channel mapping is then:

Channel Command
1 ROLL
2 PITCH
3 THROTTLE
4 YAW

To change the channel mapping, update the function configureChannelMapping according to your needs:

void configureChannelMapping() {
    mode_mapping[YAW]      = CHANNEL4;
    mode_mapping[PITCH]    = CHANNEL2;
    mode_mapping[ROLL]     = CHANNEL1;
    mode_mapping[THROTTLE] = CHANNEL3;
}

4.2 PID tuning

The default PID coeffcient values might work for an F450-like quadcopter. However, you can tune them in the global variable declaration section:

// PID coefficients
float Kp[3] = {4.0, 1.3, 1.3};    // P coefficients in that order : Yaw, Pitch, Roll
float Ki[3] = {0.02, 0.04, 0.04}; // I coefficients in that order : Yaw, Pitch, Roll
float Kd[3] = {0, 18, 18};        // D coefficients in that order : Yaw, Pitch, Roll

5. Quadcopter orientation

 Front
(1) (2)     x
  \ /     z ↑
   X       \|
  / \       +----→ y
(3) (4)
  • Motor 1: front left - clockwise
  • Motor 2: front right - counter-clockwise
  • Motor 3: rear left - clockwise
  • Motor 4: rear left - counter-clockwise

Paper plane

  • Left wing up implies a positive roll
  • Nose up implies a positive pitch
  • Nose right implies a positive yaw

The MPU6050 must be oriented as following:

  • X axis: roll
  • Y axis: pitch
  • Z axis: yaw

6. Start/stop

This sketch comes with a safety process: to start the quadcopter, move the left stick of the remote in the bottom left corner. Then move it back in center position.

To stop the quadcopter, move the left stick in the bottom right corner.

State machine

7. Debug

If you need to print debug messages, make sure to init Serial at 57600 bauds:

void setup() {
  Serial.begin(57600);
  // ...
}

void loop() {
  Serial.println(measures[ROLL]);
  // ...
}

drone-flight-controller's People

Contributors

lobodol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

drone-flight-controller's Issues

Question

Please, how can I proceed if I want to control a hexacopter using your code?

Error calculation

Currently, errors are calculated like this : measure - instruction.
The sign of this operation is inverted as it should be : instruction - measure.
It makes more sens like this.

PID controller must be updated consequently.

Code Not Compiling.

Within your void setup TWBR, PCIR,PCMSK0 are all not declared in this scope. Can you please help.

QUESTION

Bonjour. Ce n'est pas pour relever un soucis mais plutôt pour une aide. J'aimerais savoir comment procéder pour adapter ce travail à un hexacoptère(drone à 6 moteurs).

Not working

I did calibrate all ESC. After that, I did all connections and uploaded the code..but nothing happens.
Sometimes the motor rotates(not controllable).

Need sample values

Still working on a simulation using your code. But I need same sample data either for expected results of

#ifdef ALL
    Serial.print(measures[ROLL]);
    Serial.print(",");
    Serial.print(measures[PITCH]);
    Serial.print(","); 
    Serial.print(measures[YAW]);
    Serial.print(","); 
    Serial.print(angular_motions[ROLL]);
    Serial.print(",");
    Serial.print(angular_motions[PITCH]);
    Serial.print(","); 
    Serial.println(angular_motions[YAW]);
  #endif
  #ifdef THROTTLEOUT
    Serial.print(pulse_length_esc1);
    Serial.print(",");
    Serial.print(pulse_length_esc2);
    Serial.print(","); 
    Serial.print(pulse_length_esc3);
    Serial.print(","); 
    Serial.println(pulse_length_esc4);
  #endif

Expectation is that if quad is at rest (let say in air - simulation) all engines get the same pulse. My result
1

But I expect that esc1 .. esc4 get the same pulselenght. Throttle is set to 1300 and the rest to 1500 (Stick in middle position).

And this are values from measures and angular_motion.
2

Strange isn't it?

I've tested MPU6050 using different methods and it's working fine. i.e Madwick, ....

Use constants for status

Currently, the function isStarted() uses hard-coded values 0, 1 & 2 to manage status.
Using constants instead would be more conveniant.
For instance :

#define STOPPED  0
#define STARTING 1
#define STARTED  2

int status = STOPPED;

bool isStarted()
{
  return status == STARTED;
}

It is then easier to understand what is done is this function.

Still not working (in static simulation?)

Hi, its f41ard again.

esc1 and esc2 are constant at 1000 and 2000
esc2 and esc4 around 1500

I've disabled Interrupt routine and set all 4 input channel to 1500 (stick in the middle).
Simulate start and started.

Debugging measures and angle-motion looks fine compared with other MPU code.
Strange, isn't it.

My wokwi simulation works ????
Simulation https://wokwi.com/arduino/projects/324025061980766802
Have look as soom as yaw,roll,pitch active it didn't work.
If I set yaw=pitch=ray=512 -> mapped to (2500-450)/2 (Stick in the middel) servos simulationg esc's receive strange signals.

I would guess that static simulation may not work ;-<
Time to build the hardware ;->

Question

Hi and thank you for this. Im working on implementing this for another board and had a behavior question.

If without controller input the nose say pitched up, I would expect
A.) The front motors slow down
B.) Back motors speed up
C.) Some combination of both

When I log the motor speed and without touching the controller and pitch say the nose up, I notice the motor speeds do not change as I would expect.

Is this expected? Would any motor speed change come solely from the controller.

Thank you.

Declare shared variables as volatile

Variables shared between ISR functions and normal functions should be declared "volatile". This tells the compiler that such variables might change at any time, and thus the compiler must reload the variable whenever you reference it, rather than relying upon a copy it might have in a processor register.
In receiver.h

See http://gammon.com.au/interrupts

battery_voltage

Hi Man,

Don't understand how to set battery voltage. What's the default battery_voltage?
And how to connect Li battery to Arduino MLB pin? Can you explain detail. Thanks very much
bool isBatteryConnected() {
// Reduce noise with a low-pass filter (10Hz cutoff frequency)
battery_voltage = battery_voltage * 0.92 + (analogRead(0) + 65) * 0.09853;

return battery_voltage < 1240 && battery_voltage > 800;

}

Do you have any update plan on the Arduino Drone? Like GPS, Pan&Tilt...

Stop using Servo library

Servo library generates servo-signals with a frequency of 50Hz which is too low for a decent quadcopter application.
Instead, servo-signals must be manually generated with a frequency of, let's say 250Hz.
It gives a period of 4ms. A maximum pulse duration is about 2ms. It then lets 2ms to do other calculation (read MPU, read receiver, do PID automation).

Doubt

In which variable are u storing the values given by the transmitter

Thanks

Not working

I did all connections n uploaded the code..but nothing happens..its not even arming.

A question about SCL frequency

Hello. I don't realize why you set the SCL frequency into 400KHz with changging the TWBR into 24.
I think the TWBR should be 12, and I refered to the "twi.h" and "twi.c".
I find this sentense :
"TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;" F_CPU = 16000000, TWI_FREQ = 100000L .
If we want to change TWI_FREQ to 4000000, the TWBR should be 12.
Hope you teach me how to caculate, please !
Vielen Dank!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.