Quadcoptor Software Control

I haven’t quite yet forgotten about my quadcoptor project. It was on hold while I was schooling, but now that’s over I’ve picked it up again. I don’t currently have a good setup for the hardware, so I’ve been focusing on software. Specifically, the controller.

The controller dovetails quite nicely from the work on my thesis, which makes me feel a bit accomplished. Much of the research I did on underwater thrusters was based in part on propellers from aeronautics, so much of the same physics and controller properties apply. So the next thing I’m going to work on is this controller.

From the outset, I have a couple of goals for my design. First, the microprocessor I’m initially using is the Arduino, which is an AVR micro-controller. I suspect I’ll have to optimize out most of the added Arduino dev libraries and write everything by hand to get it to run fast enough, but I’m going to worry about optimization after getting the controller into a state I like. For the controller, I have three basic goals:

  • Auto-leveling
  • Position adjustment based on forward/reverse/up/down/left/right commands.
  • Heading/Tilt adjustment based on heading/pitch/roll commands.

The adjustments will be inputs of some sort, either manual or some high-level controller. The controller should be able to translate a ‘left’ command into appropriate changes to the propellers to move the quadcoptor appropriately. This isn’t trivial due to the under-actuated configuration, but it also isn’t terribly difficult either. I’d like to do it in software so that the pilot, especially a human pilot, doesn’t have to think about which propeller should be doing what.

The auto-leveling is there to keep the quadcoptor stable and aloft in the absence of other commands. It also makes for a helpful feature for manual piloting.

I’m starting with the auto-leveling, and will make decisions on the input controls based on that. That seems like a good enough decision to me, and it gives me a good place to start.

I decided to build the auto-leveler using quaternions instead of Euler angles. This seems like a good decision for a couple of reasons. For one, as expounded in many places, quaternions aren’t subject to gimbal lock as Euler angles are. For another, tracking and control via quaternions can be done without nearly as many trig functions, which are computationally expensive. (It’s possible I won’t need trig functions at all, which would be even better.) Also, I really want to wrap my head around quaternions and how to use them. This seems like a good way to do that. There’s a lot of research to draw on for both quadcoptor control and using quaternions, which I’ve found to be quite useful.

I started writing it all out in C. Since my workspace isn’t currently setup to work with the Arduino directly, I spent a bit of time building a debug environment so I can work on code compiled for x386 that can be easily switched to the AVR without much modification. Mainly it’ll be stubbing out hardware accessor functions to be written later. I spent some time digging through the AVR manual for things like register sizes and good C-types to use from the beginning to make sure I don’t get accidentally burned by something trivial. For example, the default ‘int’ size in gcc-avr is 2 bytes, whereas the default for x86 is 4 bytes. Simple things. (I’m sure there are plenty of other ‘simple things’ that will get me.) I also poked around at some of the hardware definitions to build some of my sensor structs correctly, though that’s getting a bit ahead of myself.

I realized, after specing out a bunch of code in C and testing it, that I could pretty easily write the same structure in Matlab and have all the fancy graphing tools add in for free for analyzing the controller. It didn’t take me very long to jump on that bandwagon.

At this point, I have the basic structure in place. I did some basic calculations on the physical properties of a quadcoptor (using the ‘spherical cow’ approach to estimating various things like mass, inertia matrix and such-like that maybe I’ll get more into next time) and now I can follow the path and rotation of my hypothetical quadcoptor and build my controller around it. And I can see the output with fancy graphs, which I’ve started to do.

There are a couple things I’m still missing. First, I’m assuming I know already the translation between ‘This is the force I want out of the propeller’ and ‘this is the input to the motor’. This is a non-trivial problem that will require some experimentation, which I’ll get to later. Second, I haven’t made any calculations on the physical properties of the motor itself. This would include the spin-up and response time to commands. I want to put in a basic model for these before I make too much headway into a controller design. My design currently includes a gyroscope, accelerometer and a height sensor so I’m sticking with those inputs so far, though that may change at some point.

So far, with not too much work (outside the significant amount of head-scratching involved to wrap my head around quaternions), I’ve implemented a basic controller. There’s been a significant number of sources I’ve pulled from throughout the internet, but the significant ones I’ve used I’ll point out here:

I implemented the basic attitude control from Fresk and Nikolaopoulos, but I haven’t spent any time tuning so it’s wildly unstable at the moment. It’s a nicely simple controller, but I may go a different route at some point. I’m going to play around with it some.

Next time I’ll show some of the work I did and possibly some graphs. Everyone loves graphs, after all.


  1. wren romano says:

    Quaternions are fun :) Octonions are where my head starts to hurt

    I’d never heard of the gimbal lock problem before; once I learned what a “gimbal” is, it all made sense though. It’s really interesting to see it phrased as a topological problem (cf., wikipedia). Even though I ran into Euler angles back as a kid (a friend of mine was big into flight simulators), I never really thought much about them mathematically

Leave a Reply