quietlychris / quadcopter

Early work on an embedded Linux-only flight controller for a quadcopter in Rust
GNU General Public License v3.0
12 stars 3 forks source link

Consider using RPi's PWMs #1

Open braincore opened 3 years ago

braincore commented 3 years ago

You note that the Odroid-C4 was chosen because it has six HW PWMs as opposed to RPi's 2.

I discovered that the RPi can provide 4+ reliable PWM signals via DMA. It's the approach taken by http://abyz.me.uk/rpi/pigpio/ which can be used via rust with https://github.com/braincore/rust_pigpio

I examined the signal with an oscilloscope while the quadcopter was at rest, and it appeared reliable, though I'm hesitant to say it never skipped under load as I don't remember exactly how the DMA buffer is loaded. NOTE: It does consume one of the RPi's cores pretty significantly.

Here's a video: https://streamable.com/hjbia

quietlychris commented 3 years ago

@braincore First, that video is super cool. Is the flight controller for that written completely in Rust? I'm sure quite a few folks (me included) would be really interested in seeing what that looks like under the hood. Or, honestly, even if it's not completely in Rust.

Hmm, that's interesting. I knew the DMA was possible on the Broadcom chips, but didn't know how that would effect CPU usage. If it's only one thread, I think that might be do-able. At least on the Odroid during "flight" (it's not actually flying because I'm in the slow process of switching over to a new chassis, but is doing all the expected I/O), one thread is pegged at 100%, with the other three sitting between 25-50%. I believe the single thread is reading in the IMU, although it might be writing the sysfs_pwm channels too. Either way, adding a dedicated PWM thread would most likely max out only 2/4, which shouldn't be too problematic. It would probably make it more accessible to other people too--way more people have an RPi laying around than a C4 board.

On the other hand, I'm a little hesitant to switch away from the sysfs_pwm crate because I really like that it's somewhat platform-agnostic. The Odroid-C4 uses an Amlogic S905X3 SoC, but if at some point they discontinue it or a different board gets released with a chipset that also has 4+ hardware PWM, it should ("should" is dangerous, I know) be really easy to port this code over. My understanding (and I could be wrong, so please correct me if so!) is that Broadcom isn't always exactly forthcoming about their chip details, so RPi-specific solutions comparatively often end up being quite a bit tailored to those boards in particular.

braincore commented 3 years ago

Yup, flight controller is completely written in Rust (couple years old). Gosh, it's on GitHub as private, and I always thought I'd spend the time to dress it up for release, but never got around to it. I'll just set it to public anyway in the next couple of days so you can check it out.

I tested several boards (BeagleBoard, FriendlyElec, ...) but ultimately came back to RPi because its ubiquity means that:

  1. Others have hit the problems you will and solved them. This spans kernel issues, distro issues, compiler issues, dependency issues, and also hardware (cpu features, power issues, expansions).
  2. The project is more accessible to others because RPi is the runaway winner in the space.

If I were doing this today, I'd investigate the RPi 4 compute module (I built off of the RPi 3B+), using the RPi Pico as a microcontroller companion, and the NVIDIA Jetson. I'd also be excited to use the new camera, because the old one was terrible. Too bad the state of the GPU on the RPi is so poor.

The PWM interface is simple enough that I wouldn't worry about platform-agnosticism.

quietlychris commented 3 years ago

Okay, awesome! Yeah, definitely interested in taking a look :) Honestly, I spent a fair amount of time a couple years ago playing around with an RPi4, and didn't really find it worth the effort. It seems like it was great for certain projects, but then even tasks like getting an I2C connection working reliably (I think there was a bug around clock-stretching) ended turning into multi-hours affairs while experimenting with config files. It's totally possible that things have changed in the meanwhile, though, maybe I should take another look.

The Jetson Nano is something I've spent some time working on for computer vision (the Stereolabs ZED camera uses CUDA under the hood, making the Jetson series really the only game in town), but haven't really spent much time on accessing anything that's not over a USB connection. IIRC correctly, I believe that Armbian is getting pretty close to supporting a build for it, so that could be a possibility.

I think I'm personally going to be sticking to sysfs_pwm for now, but may look into using other GPIO pins eventually, potentially as something that could be enabled as a feature flag.