Log in

View Full Version : Quadcopter on an 18F25K20



achilles03
- 2nd September 2023, 21:00
Yep, you can do a quadcopter on an 18F chip with PBP. I found this question in a post from a long time ago, but that thread is now closed. I'd been working a quadcopter on and off for maybe the past year and a half and finally got it all put together. It's obviously not as sleek as most of the commercial drones out there, but my main goal wasn't really aesthetics. I'm in the process of tweaking controller gains to make it more stable.

9463

All the piece parts were under $4 (including the custom PCB) except for the RC receiver (12$). Most of the structure is just 3D printed PLA or homemade carbon fiber parts (center plate and arms).

It runs a 200Hz complimentary filter at 64Mhz and the program code is just under 18k, although there's some fat in the code I could cut out and make more efficient. I'll go out on a limb and say that I think you could do a drone on a higher-end 16F chip if you left off the magnetometer and/or went with a 100Hz filter (if it didn't affect controllability).

Also a big thanks to Darrel Taylor. I didn't know him, but his instant interrupt contributions were invaluable to getting all the functionality needed to service the RC receiver inputs and the motor duty cycles. I can also tell from his posts he was generous with his knowledge and time to help others.

Dave

HenrikOlsson
- 2nd September 2023, 21:44
Nice work Dave!
I'd love to see some more details, what sensors or IMU? How was the complementary filter implemented?
I'm not into drones but I have a two-wheel robot that's supposed to balance but aint...I sort of lost interest in it but I'd like to see a PBP implementation of a complementary or Kalman filter.

/Henrik.

retepsnikrep
- 3rd September 2023, 16:04
Yes we would like to see your code.
Nice job..

achilles03
- 3rd September 2023, 19:19
The code is about 1400 lines at this point (probably could/should be shorter - plenty of white space) and definitely not streamlined and would probably offer a wealth of lessons on how not to comment your code. There's also some possible IP I might want to protect. However I can answer some of the questions. I will say the hardest part of the code was to figure out how to do everything with 16bit integers (there's a lot of special multiplications like '*/' and '**' I had to use).

It uses a MPU6050 (i.e. GY-521 module you can get on ebay for <2$ each), which is a 6 DOF accelerometer and a Honeywell HMC5883L magnetometer (GY-273 module - also cheap on ebay). If you anyone uses the GY-273 module, be careful as some are actually a QMC5883L which is a clone of the Honeywell version and requires a different address, but will still work ok.

I modeled a couple filters in Matlab, some using quaternions, others using a DCM (direct cosine matrix). I also looked at Madgwick and Mahony filters, which are types of complimentary filters typical for drones, and ended up throwing away both of those options also. Ultimately I settled on a variation of the DCM method that tracks just 2 vectors: up and east. Then I started writing the code in PBP using the Matlab code as the basis for the filter. The overall loop looks something like this:


Take new gryo/accel/mag readings
Turn on motors that need to be turned on, preload the highbyte of timer1 based on when the first motor needs to turn off, and start timer1
Calculate the 3x3 transformation matrix based on the gyro readings. This is tricky as the DCM needs to be normalized (or pretty close), which is really hard to do with 16bit integer math and (I think) impossible to do quickly. This was challenging to figure out.
Transform the Vz (up) and Vx (east) vectors using the 3x3 transformation matrix
Calculate the Vza (up) and Vxa (east) vectors based on the accelerometer and magnetometer measurement. These vectors are not orthogonal, so I do a cross-product of Vza (accelerometer) with the magnetometer vector which gives me an east vector (Vxa) that is orthogonal to the Vza vector. Also, if the acceleration is <0.5g or >2g, or if the magnitude of the magnetic vector is <50% or >200% of the earth's expected field strength, OR if the cross-product result indicates Vza and the magnetometer vector are <7.5deg apart, the code considers the Vza and Vxa vectors invalid sets a variable "vbit" to 0.
If vbit=1 (good accel and mag readings), blend 255/256th of the Vx and Vz vectors with 1/256th of the Vxa and Vza vectors
Calculate a running average of the rotational velocities (informs the 'D' component of the PD control of the motors)
Calculate motor gains based on RC throttle setting
Adjust motor gains based on the running average rotational velocities and how far away the drone is from the Vz vector
Adjust motor gains AGAIN based on roll/pitch inputs from the RC receiver
Repeat


All the while, a low priority timer1 interrupt turns motors off when they need to turn off, and a high priority interrupt measures the ppm pulse durations coming in from the RC receiver on timer0, and timer3 is used to maintain a 200Hz filter rate. There's several vector normalizations that occur during the loop which are needed to make the math consistent and prevent compounding errors from round-off. There's a few functions that were necessary, like calibrating the magnetometer when it powers on (that was actually the most enjoyable part cause the code is "good enough" and I knocked that out in a couple hours).

Hopefully that answered some questions. If y'all have anymore, I can try to answer those also. At some point I might be able to post some snippets of the code that could be useful elsewhere.

Dave

Ioannis
- 4th September 2023, 13:52
Congrats on the great achievment! Really impressed by the into on what the firmware does.

Looking forward to details of the program.

Ioannis

HenrikOlsson
- 4th September 2023, 19:27
If I truly understood the math behind it I could probably write it in PBP but I really don't and that, my friends, is why my robot has never balanced properly for more than a couple of seconds before bursting into oscillation and crashing violently :-)
I managed to get the compensation routines for the BME280 (https://www.picbasic.co.uk/forum/content.php/558-BME280-Example) to work pretty well on PBP and that's some pretty intense math (in my mind) but this matrix transform stuff is like black magic to me.

I think this goes to show just what is possible with PBP if you know what you're doing. Kudos Dave, really nice job!

achilles03
- 24th November 2023, 22:15
I had put some of the final tuning on the back burner for a while, but have ironed out a few bugs and tuned the control gains so it flies decently. It's a large frame with a hefty moment of inertia, so it's a little sluggish when it flies compared to smaller drones. I may trim the arms or work on the control gains to see if I can make it a little more responsive.

Here's a short test flight. Hopefully this youtube link works:

https://www.youtube.com/watch?v=s5Ox-artXEE