I figured I should finally share the dissertation I produced for the Picopter project. It outlines the design of most of the platform, going into greater detail in regards to the design and implementation of the quaternion extended Kalman filter I implemented. I'd be happy to answer any questions in regards to this filter.
Link to dissertation temporarily removed
I finally managed to get access to a decent camera on a day with good weather! The following video is mostly demonstrating the quadrotors stability under the new four-state Kalman filter I have implemented, that estimates both the current pitch/roll and two gyroscope biases. Most of the flight is hands-off, with the occasional input to correct for wind and inevitable position drift.
I feel this angle control is pretty much perfect, so I will now be moving on to integrating extra sensors to allow for direct velocity and position control. I'm excited to see just how complex I can make the navigation system before the Pi cracks, but it seems for now despite using unoptimized double precision floating point math for everything it still has plenty of headroom to go!
The (rather messy) code is available at https://github.com/big5824/Picopter. Now that the first stage is finished I can start going through cleaning up the spaghetti of test code, but that will have to wait for now.
Over the past few weeks I've been working on a raspberry pi powered quadrocopter, finally cumulating in todays first test flight! This flight went infinitely better than I expected, as it seems I have guessed nearly perfect PID gains.
The Picopter is currently based on the same filtering and control algorithms as my previous platform, however now all of the processing is handled by the on-board Raspberry Pi. This initially seems rather counter intuitive, as time sliced operating systems like Linux are not as predictable in their execution time as a simple real-time microcontroller program, but I've found in practice preemption allows the main control loop to run at a very reliable frequency. This now means the copter can perform the same as a basic microcontroller powered platform, but also has heaps of CPU time leftover to run things such as an SSH interface to my laptop via a wireless adapter, the logging of every scrap of data imaginable to the on-board SD card (think 200MB per flight), and the potential for complex route mapping and real-time integration into something like Google maps.
I'll continue PID tuning over the next few days, and will hopefully be able to acquire a better camera to obtain some better quality video. For now, here's some more phone quality pictures:
Some more videos of the quad, with the camera on a tripod and mounted to the frame. The wind had picked up quite a bit when I filmed this, so stationary hovering was a lot harder.
Just a quick 30 second clip of the new frame flying, along with the new PID loop and filtering algorithm. It still looks a bit drifty as I didn't have time to get it trimmed correctly, shown by the constant listing to the left.
After much research it appears the best solution to this issue is to use two nested PID loops. The inner loop will control the quads angular velocity, while the outer loop will control the quads angle by setting the target angular velocity. In hindsight this is a much more intuitive approach, as the motors are used to control angular velocity, not angle, so trying to control the angle directly is a poor approach.
Tuning the angular velocity loop will require the quad to be able to rotate indefinitely on its single axis jig whilst streaming data, something the current rs232 cable restricts, so an XBee will need to be integrated. Also, my current Euler angle representation doesn't allow any rotation past 180 degrees due to the singularity at this point caused by the 180 -> -180 degrees jump, so I will need to move to a better singularity-free representation.
The two main candidates for this are quaternions, a complex but computationally efficient concept using three imaginary and one real axes, or a direction cosine matrix, a 3x3 matrix storing the cosines of the angles between the three axes of the reference rotation (the gravity vector in this case) and the three axes of the rotated system.
Due to this large code rewrite and PCB redesign I will postpone implementing this until after summer when I have more free time, hopefully using it as my third year research project. Therefore for now I will try to improve the PID loop as much as I can, and hopefully spend more time actually flying instead of designing.
Now my exams are finally over I have started cracking on again with the quad. Over the past few days I've made a massive number of improvements:
- Improved signal loss handling. The previous method used the watchdog timer to initiate a reset upon a signal loss, effectively leaving the quad dead in the water. I've now freed up a timer peripheral and configured it to disable all the motors upon signal loss. However the main difference is this method can instantly resume once the signal is reestablished, so a momentary glitch won't result in a guaranteed crash.
- Improved filtering. I've now configured the MPU6050 to use its on-board digital low pass filter, massively reducing noise, and I've switched to a second order complementary filter, again improving signal quality.
Original angle estimate I was flying with (green is the filter output, red is the integrated gyroscope output).
After configuring LPF.
With 2nd order complementary filter.
- Added code to calibrate the ESC's on every startup. This means every ESC is now balanced, and I'm using the full ESC throttle range unlike the last model.
- Designed a Labview interface, allowing me to monitor the sensor outputs and modify the PID constants on the fly. Screenshot.
Thanks to this interface it is now a much simpler task to tune the PID coefficients, so for now the quad is sat in its frame while I get the PID re-tuned for the new ESC throttle curve and filter response. However, I've ran into the problem of having to choose between good disturbance rejection and good command tracking. By increasing the coefficients I can make the quad perfectly lock onto an angle, allowing for near perfect hovering, but this increased differential term makes the quad incredibly slow to respond to commands, making flying the thing a nightmare. I need to do further research into how to solve this, or if PID is really the best tool for this problem.
I will probably aim for somewhere in the middle tomorrow, then take it off its frame to see how the new filters really perform, which I have high hopes for.
Since I've been getting a lot of requests for the source code I figured I might as well make it public and easy to access. I've tried my best to get a git repository set up, so hopefully if you follow this link you should be able to view the full source: https://github.com/big5824/Quadrocopter
It's all written for the dsPIC33FJ128GP202 in MPLAB using the C30 compiler, so in theory you should be able to open the .mcp project file and successfully compile everything. The only required change I can think of is for some reason the IDE didn't like some of my includes when referenced to the root directory, so I gave in and just used a full path, meaning you will need to edit this to suit your enviroment.
After around five or six crashes, I think it is safe to say I have tested the quad to destruction. The good news is I have identified a bug that occurs when yawing and pitching/rolling at the same time, which seems to cause the quad to list to one side, and also happens to be the perfect scapegoat for me to blame all my crashes on. However sadly it is now exam season for me, so I'm banishing myself from any further work on this site or the quad until after the 1st of June, at which with some forward planning I should also be recieving my new frames and props. 😀
Over summer I expect to be tweaking the control loop to achieve a better response, possibly by controlling the quads angular velocity as well as its angle, along with hopefully producing a new control board with a GPS, a magnemometer, a barometer, and most importantly an x-bee for wireless telemetry. But until then, I need to get cracked on with some work 😉
Today was mostly spent practising and seeing just what the quad can do. I am absolutely amazed at the rate at which it can climb, even while I still have it limited to 2/3 throttle it is still able to shoot into the air like a rocket, rapidly becoming just a speck in the distance. I seriously wonder if the frame would be able to stand the acceleration of it's full unrestricted throttle 😀
However, after a very fast decent from around 100m I now see that the lack of gravity during freefall is going to play havoc on the sensor filters. This is because the gyroscopes use the noisy accelerometer readings to zero themselves to cancel out their drift, which normally over a decent period of time supplies a pretty accurate orientation estimate. However, when in freefall, the accelerations across all the axes will drop to nearly zero, causing the atan2 function to output wildy varying angles, offsetting the gyroscopes. The result of this was a very confused quadrocopter only a few meters off the ground, ending with a hard landing. To solve this I need to add some code to disregard the accelerometer values when their magnitude drops much lower than g, which will probably be usable for a few seconds before the gyro drift has chance to build.
The second less technical problem occured when I got rather cocky in a field and managed to lose track of the quadrocopters orientation, resulting in a very painful encounter with a tree. A lot of the frame was broken (again), but I think with more glue and struts I should be able to salvage this frame, or at least keep it going long enough until my new carbon fibre frame arrives.