TacoCopter

TacoCopter

16 devlogs
84h 47m
•  Ship certified
Created by njfdev

A custom-built drone with a flight controller programmed from scratch in Rust for a Raspberry Pi Pico 2, along with a desktop application. No other drone project like this one exists.

Timeline

Ship 1

1 payout of shell 1566.0 shells

njfdev

4 months ago

njfdev Covers 16 devlogs and 84h 41m

It has been a fun journey. This last little update is just some improvements to the Blackbox interface. Now you can choose where to download the log file, and you will get a status message on completion (or failure).

I also finally added a README.md (but it has been WAYYY too long).

Update attachment

We are SO BACK!!

I have GREATLY improved performance by removing unnecessary chunks of code, allowing me to increase the update frequency from 200hz to 500hz!!! This 2.5x increase in speed has greatly improved stability! I also added filtering to the IMU signal to prevent noise!

Before, the motors would become dangerously hot due to the jitteriness (from noise and lower update frequency), and now they can stay cold to the touch after a short flight!! 🎉

I also fixed and improved many broken things in the interface.

I've FINALLY 😮‍💨 gotten blackbox logging working on my drone (essentially logging mid-flight to gain better insight into what the drone is doing). I mangled with linker scripts and different libraries in order to get logging fast enough to not slow down the control loop, and to be able to download the data over USB to a nice .csv formatted file.

Speaking of that .csv blackbox file, I can open it in a program like PlotJuggler to help tune my PID loop. Unfortunately, with all the changes, I can't get my drone off the ground anymore, so THAT is my next challenge to tackle. :)

Update attachment

OPTIMIZATION, OPTIMIZATION, OPTIMIZATION.
READABLE CODE, READABLE CODE, READABLE CODE.

I don't have much to show for it, but I spent so much time cleaning up my flash code with macros (Rust lingo for code that writes code) and switching away from a blocking filesystem library (I'm looking at you, littlefs2 👀).

Update attachment

I am back from vacation! And just before I left, I was flying the drone around more aggressively until the firmware panicked midair, and crashed down, breaking yet another propeller!!! 😥

So, I made lots of small improvements: proper error handling instead of just giving up, saving panic messages, only running the USB updater when a USB cable is connected, and fixing the onboard current monitor from clipping.

With these improvements, I am starting to get more comfortable doing more acrobatic maneuvers with the drone again (although it is still a bit unstable), as you can see in the video!

I finally got proper gyroscope calibration working!! It took way too long, but I got persistent storage to the flash working with a request/response system and fixed a bug where I was calibrating on the already calibrated values (causing unwanted results).

I also increased the stack size to prevent random things from breaking (THIS SOLVED A LOT OF STRUGGLES). I also improved the battery level estimation.

Update attachment

I have FINALLY gotten the drone to fly again!!

I got my propellers and fixed some remaining bugs causing random crashes, and now it flies again!! In the video, you can see me testing some agility for PID tuning.

Got some gyroscope calibration logic kind of working.

I am having a lot of random crashes, which I can't really debug well, so I worked on setting up an old Raspberry Pi Pico as a debugger probe for my flight controller.

Update attachment

Not much to show for it, but I spent a lot of time getting persistent key-value storage set up for my Raspberry Pi Pico 2 to store important things (like accelerometer calibration) for the drone flight controller.

I also created an interface to show the sensor calibration values, but right now it isn't interactive.

Update attachment

I just made improvements to logging today. I switched from a custom logging macro in Rust to use the log crate and make a custom logger for it so I can have different types of logging levels (e.g., error, warn, info). Along with this, I improved reliability, and now display the type of log in my configurator app with color coding!!

Update attachment

Did a touch of redesigning my flight controller configurator app, but mainly I made huge progress with my ultrasonic sensor!!!

I have been putting off trying to improve timing logic for it (and tried giving more priority, which just slowed down everything), but finally programmed a driver using the PIO feature on Raspberry Pi Picos. This beautiful Programmable Input Output (PIO) feature basically allows me to write custom assembly code to handle my ultrasonic sensor that runs on a dedicated onboard core designed for I/O. The program in the image is the assembly implementation, which happens to be my first successful PIO program!!

With my new PIO ultrasonic sensor driver, I get great performance/speed/reliability, and the readings from the sensor are the most stable I've seen IN MY LIFE (when standing still, the registered distance basically does not change).

Update attachment

Worked on executor optimization and made the status LED (the green one) blink proportionally to the update frequency (useful for determining slowdowns visually).

I also figured out how to overclock the Raspberry Pi Pico 2 running the flight controller and successfully got it to 300MHz (double the base speed)! Getting it to work was really annoying because Embassy (the environment for interfacing with the device) has different behavior for certain things when using the version on crates.io vs GitHub (WHY???).

With some testing, I figured out that the USB task in Embassy can and will crash the system if there is too much strain on the executor (WHICH IS LIKELY WHAT CAUSED THE CRASH BREAKING MY PROPELLERS).

On a totally unrelated note, did you know that using Embassy's Timer::after method can strain the executor at high frequencies, but looping with yield_now().await doesn't?!? I made this change on all my high frequency update loops and now it runs without crashing!!

Update attachment

Basically just a lot of clean up. I addressed 119 warnings, moved 1500 lines of code out of my main.rs file, addressed 349 errors associated with that, and finally reorganized which of the 2 cores runs each task on my flight controller.

The result of all of this was cleaner code and a 2x performance bump (a max update frequency of ~~250Hz to ~~500Hz).

Update attachment

Oh no... Did a lot of code refactoring and some optimization, and now the flight controller fails more often. It failed mid-flight, leading to my worst crash yet, and unfortunately, with broken props... Time to wait on an order for new ones. 😞

Update attachment

Ouch, looks cool though! Hope you can fix it soon.

After attempting to work on altitude holding for my drone flight controller, I had a couple of large drops (causing the battery holder to come off), and still don't have it working really at all. On my most recent flight, I noticed the flight controller was struggling, which means I am going to spend a lot of my time optimizing before fixing altitude holding (tbh, my code is pretty messy).

Rishi Sadu Rishi Sadu 6 months ago

THATS FRICKING COOL