09/24/2019 at 00:30 •
I spent the best part of 2 days now trying to tune this thing to fly the way I want... it is not easy! The primary problem I am having is with attitude response. The rates response is solid, and by reducing the cutoff frequency of the gyro filter, I have really been able to tighten up the rates controller. Attitude control on the other hand has been a struggle. I want to ONLY use proportional gain, however I am seeing that at large angle errors the response is very sluggish, however I cannot crank up the P gain any higher otherwise I get oscillations at hover. I think this problem is more complicated than simply controller tuning, there is probably a significant effect from airframe vibration coupled with my rudimentary attitude estimator. I think moving to an EKF -- and fusing in mag data -- would clean up the attitude estimation around hover dramatically. I really should implement logging so that I can verify these suspicions... yet another thing to do.
Overall I am extremely happy with the project, and I have effectively accomplished what I set out to do: make a drone fly. I will surely work on this project off and on for quite some time, but for now I want to turn my attention to solving real world problems. This has been a great learning exercise and an awesome experience, I can't wait for what's next!
09/22/2019 at 22:15 •
Spent the first few hours of the day getting everything ready for flight testing. I implemented the yaw controller, added the plumbing, and found some ballpark gains. I fiddled with the rate controller gains for Pitch and Roll a little bit more, and then began iterative flight testing for fine tuning the gains. I realized quickly that I needed a level horizon calibration, so I implemented that. The vehicle felt slugging and hard to control, requiring a lot of over compensation with the sticks. I realized I need both stick expo as well as to allow the attitude controller to command a higher angular rate setpoint to increase responsiveness. Increasing the maximum angular rate made my P gain for the attitude controller too high, so I had to dial that back as I cranked up the max allowable rates. It took a little while to find the sweet spot for attitude controller gains, stick expo, and max angular rates, but I finally landed on something that feels solid.
09/22/2019 at 05:35 •
Ha, it's always funny to look back at yesterday's problem after having solved it. You feel so dumb for not seeing it right away! It's a bittersweet feeling, but the feeling of solving a hard problem -- even if it was only hard because you're a simpleton -- feels so good.
Last night, after depleting all of my batteries juice and retiring to relaxation, I realized what was wrong. I was trying to tune for both impulse response and steady state. The problem was, I was trying to put the quad on edge. This is absolutely not helpful. I got confused by the language in the PX4 docs about the rate tuning process, where it was suggested to tilt the vehicle on edge to tune the I gain. I realize now that they were implying while flying the vehicle. Duh. The test fixture was effectively a moment arm on the quad as soon as it rotated about the dowel! After reading many articles on the interwebs, I decided to only test for impulse response (poke the drone) and step response (oscillate with fixed speed between shallow angles). I started by finding the correct P gain (2/3 * frequency_begin_oscillations) and then dialed in D with P and I set to zero. After finding "ballpark" values for P and D. I used the step response to factor in I gain, and dialed P back a bit further...
...Rate controller tuned!
I am not sure the impact of this overshoot in the step response, and I am also a little bit concerned about the rise time. I was primarily trying to avoid heavy ringing and in some cases minor high frequency oscillations with previous more aggressive tunes I had set up.
Next was the attitude controller, but that's just P gain so was quite easy to find a good initial value. I did one last "hold in hand" test, and then went to flight test it. It flew! It was actually very smooth, although the attitude control was noticeably sluggish. I haven't implemented the yaw controller yet (been busy, stuff and things) so it is quite difficult to fly. The yaw controller should be quick and easy (rates only), so I am planning on tomorrow being a flight testing day!
09/21/2019 at 06:02 •
Put my batteries thru the ringer today. Scrounged the internet and began to experiment with some heuristics for PID tuning. Finally landed on a method that I am committing to. I think I am near the ballpark value I want to be at for `P`, I need to see how high I can take `D` such that I reduce overshoot / oscillations given a step input. I added in a little bit of `I` at the end, I think I need to reduce it or take it out until I dial in P and D. I should note, I am only tuning the pitch rate controller right now, so that's what these plots are.
I am prefiltering the gyro data used for the control signal using a low pass filter with a cutoff of 80Hz. The gyro itself has a hardware DLPF at 92Hz. I am sampling the gyro at 1kHz, I might want to think about using a different kind of filter for the prefiltering.
P = 0.3
I = 0.06
D = 3.0
Step input: 10 degree step with angular rate of 60 dps
Step input: 45 degree step with angular rate of 80 dps
I need more `I` gain clearly, however I am not sure how to add it in without inducing oscillations. It looks like I overshoot quite a bit initially, which means the `P` gain could probably come down a little bit.
09/20/2019 at 05:14 •
I need to tune my rates controller, so I decided to build a jig. I ran by home depot and collected some supplies, and then stopped by Mark Sauder's house and he let me borrow some tools to create the jig, thanks Mark! Eager to get these controllers tuned and to use my newly built jig, I modified the code to only enable pitch rate control. Not knowing a good starting point for my gains, I chose P = 0.001 and left everything else at zero. As soon as I armed, the quad immediately started spinning around the dowel, promptly flinging the RC receiver off the breadboard. The kill switch on my controller is the only way to kill the motors. I stood there panicking for about 20 seconds as I watched it go round and round, the dowel visibly weakening with every violent rotation. I finally grabbed my nearby notebook and shoved it into the action. It took a few seconds to subdue the thrashing, but I was finally able to grab the battery and cut power.
Needless to say, the dowel on the jig snapped and my notebook is torn to shreds. I lost a diode on the FrSky while reworking it, so I fixed it by just shorting the pads. Thankfully everything still works, so I'm ready to try again tomorrow once I buy a new dowel.
Lesson of the day: strap down the damn receiver!!! (and write a better failsafe for drivers that crash..!!!!..@#!!)
Update: I had motor wires 1/2 and 3/4 reversed. Doh.
09/19/2019 at 07:14 •
I almost finished this project and this is the first time I've really written anything more than what is in the README. I decided to take on this project in early August 2019. It has been a huge amount of work but I am extremely satisified with how far it has come given starting from nothing and having never designed an entire embedded system from scratch. I am eager to continue on with other projects, so I decided to hold off on the full quaternion estimation and control scheme, as it would be quite time consuming to fundamentally learn how the algorithms work (this project is about fundamentals).
A lot of the inspiration in design has been taken from PX4 and ROS. I favored reducing complexity and increasing ease of use by using the C++ standard library and STL. This does use more flash. This does use dynamic memory allocation (allocates once at the beginning). You do have to be more careful about what you do and how you do it. However it offers enormous flexability to write better code that is easier to understand. I didn't really implement anything more than "bare minimum" other than the DispatchQueue, which I used as a tool to familiarize myself better with FreeRTOS, timers, and scheduling in general.
Smashed my head into the wall trying to make the drone fly. Learned a lot, but definitely went at it with guns blazing and failed to notice obvious problems with the implementation. Fixed those problems and ultimately led me to understand what actually needs to be considered. Decided to build a test rig for tuning pitch/roll rate controllers. I will be able to independently control roll/pitch on a fixture with a rotating center beam, which the vehicle mounts to. I will also be able to connect via serial to view the data in real time thanks to my real time plotting python script. I have considered just writing the driver for a telemetry radio so I don't need hardwired PC serial... just one more thing to do.