Implementing a custom flight controller using ArduPilot codebase

I am a controls engineer and I am trying to implement a non-linear control scheme on my aircraft. The aircraft I am using is a blimp and so its dynamics are deeply contrasting to AP vehicles. For this reason, rather than spending time modifying the AP source code, I thought of using the libraries from the codebase and writing the code myself. I am not an embedded systems programmer so I won’t be able to write any HAL code myself. I plan to implement it on a BeagleBone Blue and I have a few questions regarding the same:

  1. How can I use just the ArduPilot Libraries to write my own code for my aircraft? I mean something along the lines of creating a runAircraft.cpp file as:

    #include “AP_Common/AP_Common.h”
    //-------------------more includes------------------//

    /--------------run some functions from AP libraries-----------------/

  2. I tried this by cloning the AP code base and in the libraries folder, compiling with gcc locally on BBBlue but it throws a “file not found error”. What am I doing wrong here?

  3. I was told a RTOS is essential for a Flight Controller, is there any tutorial on how to install, implement and use an RTOS on the blue?

  4. While implementing my own Flight Control Scheme in the manner mentioned before, will I need to use RTOS?

Any help is greatly appreciated as this is stalling my project in a major way!

EDIT: My objective translates to replaced the AC_PID library with my own to control the vehicle. And so, keeping this and the fact that its a research project in mind, I thought it best to use only the libraries and write the rest of the code myself.

PS: Here are the results for attitude stabilisation of my control scheme on a quadrocopter:

The control signal generated:

Attitude vs Time:

1 Like

There are a couple of things. I think first we need to get your build environment sorted out with just a straight clone of the main repo, before getting into the other stuff.
It’s faster to cross-compile from a pc than use the bb, and if you’re developing it’ll pay off. You can do it natively, but I think that can wait.
Follow the appropriate instructions here: and let me know how you go.
Re RTOS: ideally, yes: the kernel Mirko uses has RT patches, although isn’t ‘hard’ real-time. I’d suggest for a blimp it’s plenty good enough, particularly noting that the PRU’s are also used.

1 Like

Thanks for that response. I have forked, cloned and now created a branch for my changes. What would the next steps be? To re-iterate, I just want to be able to use the AP libraries. The actual Copter/GCS?waypoint functionalities are not necessary and I would like to do away with them to keep the code simple. Thanks for your time!

PS: Here is the error thrown when i try to write a file which only has
> #include “AP_Common/AP_Common.h”

in it . Also, the file is saved in the libraries folder and is compiled with gcc.

Your patience with my newbie-ness is much appreciated!!!

No worries.
Yeah, trying to compile like that isn’t going to work. That file calls others, etc etc.
The ‘simple’ approach probably isn’t the simplest, as you’ll find you keep needing to re-introduce stuff like telemetry, modes, rc, etc etc.
So ‘simple’ imho is modifying the existing codebase as little as possible, or even just using the existing ‘usercode’ hooks.
Are you open to that?

I see what you mean by re-introducing stuff. But just for confirmation, if I had a plan as:

  • Include all the relevant libraries needed such as the HAL, the InertialSensor, the AHRS etc.

  • Write the code for the controller (effectively replacing AC_PID), the different loops, the flight modes etc.

Would this be feasible? If so what are the challenges I will face?

If not, my original plan was just to create a “replacement” for the AC_PID library to implement my own controller. Is that what you refer to when you say “modifying the existing…” ??

I could do this, but you see, the main objective is to change the controller, in this case PID, to my own… this won’t achieve that if I am correct?

EDIT - My apologies for not being clear enough! What my objective translates to roughly is to replace the AC_PID library with my own to control the vehicle.

The usercode is basically an entry point to the scheduler, you can pretty much do anything from there.
Replacing the controller isn’t trivial. ArduPilot isn’t a simple inner/outer (stability/position) pid loop. There’s actually a number of cascaded controllers, particularly in Loiter. Leonard’s done a pretty amazing job.
For your use case, I’m guessing stability is not controlled, so you are looking specifically at a position controller. Is this correct?



  • Apologies, but I did not understand what you meant by saying:
  • I know its not a simple PID and also I have seen the cascaded PID loop structure. My aim is to have total control of the quadrotor, both position and attitude, by running a sliding mode controller on the attitude loop and a fuzzy controller on the position loop. For this implementation I was planning to go in stages, beginning with stabilise, and then moving on to trajectory tracking in 3d space. I have an idea about how to implement my position controller and hence want to try that out.

  • The functionality of the AP platform begin reduced to nil doesn’t matter to me as I need to merely demonstrate the effectiveness of my control scheme. So if I were to elucidate my requirements again:

    1. Gain access to using all the libraries to be able to extract angle data, heading data, filters, motor control etc
    2. Be able to integrate these libraries into code that I will write myself, that is, my own flight modes etc.

Is it really not possible to just use the AP libraries as simple peripheral_drivers, filter_libraries etc specific to my board to suit my needs?

I seem to have trouble including only the AP_HAL libraries… is this a pointer to anything???

I agree with James. I would not want to start from scratch or even try to gut every thing and build a simple control system. Again I agree with James that you want to only replace what you need to and leave the rest in tact. So it will require some time studying the code to figure out how to best implement your controller. There is a group I know that was able to replace the attitude controller and rate controller with an explicit model following architecture.
i am more familiar with arducopter so I will give you the basics of the flow of the code. In the file arducopter.cpp is where the scheduler and main and fast loop reside. So the main loop called “loop” runs the fast loop and the scheduler. IMO the fast loop runs all of the critical function to controlling the aircraft. It calls the low level rate controller and the motors output. It also calls update flight mode which effectively runs the upper level navigation and attitude controller routines.
You’ll find in the arducopter directory along with the arducopter.cpp file, files for each flight mode which is called by the update flight mode routine in the fast loop. That is where you could put calls to your own controller. The calls in the flight mode routines are designed to provide target values for the rate controller to use for aircraft control. So the output of the rate controller is just the pitch, roll, yaw, and throttle outputs to the motors library. The motors library handles how the independent controls are mixed to accomplish the desired aircraft motion.
As far as the RC control input, you will find the RC loop is called in the scheduler and are used to determine the pilot desired inputs which is passed to the position or attitude controller.
I hope this is not too confusing. You will need to dig into the code to see what I’m talking about.

1 Like

@Thalaivar If you are looking to introduce a new vehicle library. The most basic thing to get started is to implement setup() and loop() methods. End the .cpp method with AP_HAL_MAIN_CALLBACKS(object). So for instance, you are creating ArduBlimp project. The first thing you would compile would look something like this:

//file: Blimp.h

class Blimp {
    void setup();
    void loop();
    //declare some internal methods

//file: Blimp.cpp
Blimp::Blimp() : val(0)
 //initialise members
//Allocate memory to members
//file: ArduBlimp.cpp
#include "Blimp.h"

Blimp blimp;
// Static Scheduler List, refer other vehicles to understand the concept of scheduler callbacks

void Blimp::setup() {
     //do one time stuff here, like initialisations

void Blimp::loop() {
    //do recursive stuff here, like scheduler run


Once done with that, you would need to start pulling in relevant methods from other vehicle libraries, like INS, RCIN RCOUT and Mavlink to start with, But all the methods will trace their roots to above calls (setup and loop). Other vehicle libraries are the best reference. To make things easier to understand, checkout AntennaTracker Vehicle directory, which is much less complicated.

And how can I speed the initial few debugging sessions, such as for example, just seeing if IMU is being read etc AFAIK, every time I make a change, I will have to build the code with waf on my machine, scp to blue and try it out there… is there a better way? Also, I think i can leave the wscript file pretty much as it is for ArduCopter?

I think you should be able to build on-board, It will take a long time for the first time, but subsequent build will be shorter. . Another idea is to edit python scripts under Tools/ardupilotwaf to add --upload option enabling to automatically scp the flight stack over to your board and even start it.
Yes, you should be able to use wscript from ArduCopter


Dear Thalaivar, have you implemented your controller? I am planning to implement my own controller and it is highly appreciated if you could help me how should I do it.

In case anyone is interested, the custom controller support for Arducopter has been implemented. You can read all about its features either in the blog post or the wiki.

Hello, Emre Saldiram.
First, congratulations for your work, it’s amaizing!
I have doubt, does your work address both the attitude controller and the position controller? For example, if I want to put a controller in the outer loop (position controller) can I get it for your work?

Other question: If I already have a library, can I call it in my custom controller?

Thanks in advance.