Bachelor's Thesis: LaunchPad Flight Controller
I recently got my bachelor’s degree in electrical engineering. As I wrote in an earlier blog post I decided to implement a custom flight controller on a Tiva C Series TM4C123G LaunchPad for my project.
Currently it supports several different modes including acro/rate mode, self level mode, heading hold and altitude hold. Below is a series of videos demonstrating the different modes:
The source is available on Github: https://github.com/Lauszus/LaunchPadFlightController as usual including the report I wrote.
I would really recommend anyone that is interested in this sort of thing to read through it for a deeper understanding on the fundamental theory and how it is implemented on a flight controller in practice.
It consists of three parts. The first part presents a theoretical model and the equations used to estimate the attitude and altitude of the quadcopter. The second part describes how the system is implemented on the microcontroller and lists the hardware used for the project.
The final part measures the performance of the flight controller by logging the data in real time. This data is then compared to the simulated results based on a theoretical model simulated using Simulink.
Flight modes
In total there are four different flight modes supported by the flight controller. The first one is acro/rate mode, which only uses the gyroscope to stabilise the quadcopter. This mode is mainly used for advanced pilots and acrobatic manoeuvres. In this mode the aileron and elevator stick inputs indicate the desired rotation rate of the quadcopter. Thus, if the user wants the quadcopter to rotate fast clockwise along its roll axis the aileron input can be put all the way to the right.
Self-level mode
The second mode is self-level mode, which is activated when the AUX1 channel is more than -10. In this mode the aileron and elevator stick inputs control the roll and pitch angle, respectively. The quadcopter will go back to horizontal once the user centers the sticks. This is especially useful for beginners and in the other flight modes.
Heading hold mode
The yaw angle, also know as heading, is used to keep the quadcopter fixed at the same heading if no rudder input is applied. This mode uses the gyroscope and magnetometer in order to estimate the yaw angle.
Heading hold is activated if the AUX1 channel is above 50.
Altitude hold mode
Altitude hold is activated by setting the AUX2 channel to more than 0. Note that self-level mode needs to be activated as well for it to activate. It is recommended to use heading hold mode in this mode as well, so the user does not have to apply any throttle or rudder input.
In this mode the position of the throttle stick corresponds to the absolute height of the quadcopter i.e. if the throttle stick is all the way up, which makes it stay at a height of approximately 1.5 m while it will stay at a height of 5 cm if the throttle is all the way at the bottom.
I limited the maximum height to 1.5 m as this proved to be the practical limitation of the ultrasonic sensor even though the specification for the ultrasonic sensor said that the maximum distance is 3 m, as the sensor starts to have several false readings when it gets close to its limit. This is especially critical due to the relatively slow update rate of only 40 Hz.
Android application
Similarly to my full size balancing robot I wrote an Android application in order to adjust the PID coefficients and various other settings. This allows me to easily tune and configure the flight controller on the fly without the need to reprogram it. I am a big fan of this approach as it speeds up development time considerably.
The communication between the microcontroller and Android application is done via Bluetooth. In order to make sure that the data is properly parsed on both sides a protocol inspired by the MultiWii project was implemented. A detailed description of the protocol can be found in the report I linked to earlier.
The full source code for the Android application can be found at the following Github repository: https://github.com/Lauszus/LaunchPadFlightControllerAndroid.
PCB
If you want to try it out you can order the PCB I have made: https://www.oshpark.com/shared_projects/9DC5cp8e and order the sensors yourself. The schematic and board file is also available at Github as well: https://github.com/Lauszus/LaunchPadFlightController/tree/master/PCB.
I might start selling the flight controller as a kit in the future if there is a demand for it. I will probably also work on soldering the different sensors directly onto the PCB instead of using breakout boards. Furthermore I would also work on integrating the microcontroller directly onto the PCB instead of relying on the LaunchPad. This should make the flight controller both cheaper and physically smaller.
Parts list
A list of the parts used on the PCB can be found below:
- MPU-9250 3-axis gyroscope, 3-axis accelerometer and 3-axis magnetometer or MPU-6500 3-axis gyroscope and 3-axis accelerometer and HMC5883L 3-axis magnetometer
- BMP-180 barometer
- HC-06 Bluetooth module
- HC-SR04 ultrasonic sensor
- Active buzzer
- BC547 NPN transistor
Note that you will only need either the MPU-9250 or the MPU-6500, but you will have to buy a HMC5883L separately if using the MPU-6500.
You will at least need the 3-axis gyroscope and 3-axis accelerometer, as the other sensors can easily be deactivated in the Makefile.
Furthermore you will need an existing quadcopter to mount the flight controller on. My current list of hardware components can be found below:
- Motors: Dualsky 980kv
- ESC’s: Hobby King 20A ESC 3A UBEC (F-20A) – flashed with SimonK bs_nfet with OneShot125 and COMP_PWM = 1
- Propellers: 10×4.5
- Frame: Hobby King Q450 V3 Glass Fiber Quadcopter Frame 450 mm
- LiPo: Turnigy 3300mAh 3S 30C Lipo Pack
- RX: OrangeRX R615X
- TX: Turnigy 9XR flashed with OpenTX
- TX module: OrangeRX 2.4GHz transmitter module
Future improvements
If you read through my report you might realise that I did not get altitude hold based on the barometer and accelerometer working before the hand-in, but I actually got it working before my defence. Currently it still needs a little more work before I will merge it into master, but if you want to take a look at it, it can be found at the following pull request.
Furthermore I will work on adding support for the ADNS-3080 optical flow sensor, which measures the change in x- and y-position of the quadcopter. Thus by integrating, an estimate of the position in the xy-plane can be obtained. In combination with altitude hold this would allow the quadcopter to stay in the same altitude and position close above ground without user adjustments!
That is all for now. If you have any questions or comment just leave them below and I will get back to you as soon as possible.
Amazing work!!!!!! I’m pretty sure we’ll be reading about you some day cuz you’ll be doing more excellent work!.
I’m trying to achive somethig like that, I was checking your code about the kalman filter and I’m wondering where do I get this value:
double gyroZrate = gyroZ / 131.0; // Convert to deg/s
The 131.0 value… It’s a Razor IMU SEN-10736 ROHS
@Erick Medina
It is called the gyro sensitivity and is used in order to convert the raw values into deg/s. You should read a post I wrote a long time ago for more information: http://forum.arduino.cc/index.php?topic=58048.
Oh, I found the issue in the App:
At Germany we write 70,50 and in English 70.50
So inside BluetoothProtocol.java at public void parseData(byte msg[], int offset, int length)
line 381 I added Locale.ENGLISH to avoid the comma and getting a dot as decimal separator.
// TODO: Just store this as an int
bundle.putString(LaunchPadFlightControllerActivity.ROLL_ANGLE, String.format(Locale.ENGLISH, “%.2f”, (float) roll / 100.0f));
bundle.putString(LaunchPadFlightControllerActivity.PITCH_ANGLE, String.format(Locale.ENGLISH, “%.2f”, (float) pitch / 100.0f));
bundle.putString(LaunchPadFlightControllerActivity.YAW_ANGLE, String.format(Locale.ENGLISH, “%.2f”, (float) yaw / 100.0f));
@Dirk
You are more than welcome to send a pull request with the change if you want to?
Btw we use comma here in Denmark as well 😉
Hello Kristian,
I am developing a multirotor controller with EK-TM4C1294XL which should rather similar to TM4C123G. I have not invested and do not want to invest in a Transmitter/Receiver. I am developing it as UAV – so no need to to control via Radio. I want to just give it some instructions like Go Up, Move to a particular location then Get Down.
I was searching on web if somebody has done something similar and fell on your post. I will go through your code and see if I can reuse some parts of your work.
All advice is welcome.
Thanks.