At our workshop this week, we did some hands-on testing of our control theory knowledge with an aerodynamically-driven balance beam–basically just an electrically controlled fan that blows to lift up a weighted board. The idea was to capture the difficulties of UAV control in a simpler and slightly less dangerous system. Little did we know what we were signing up for! (Arduino code and data after the break.)
The idea with the aero balance board demo is you need to adjust the fan power until the board just levitates, and keep adjusting the power to keep the board exactly horizontal. Trying it by hand with an R/C controller, it wasn’t at all easy to pilot the thing to stay still! The problem is the board has rotational inertia, which makes it very easy to overshoot your target position.
We thought this would be very simple to automate using an Arduino to command the motor power, and an accelerometer to measure the board’s orientation (indirectly, by measuring the X component of the gravitational acceleration vector). Simple proportional control immediately overshot the stable point due to inertia, and just flailed around repeatedly missing the target. We expected as much–proportional control doesn’t work well on systems that have inertia.
Adding a derivative term, however, didn’t stabilize the system at all! Here’s a spreadsheet chart showing the basic problem:
You need a strong derivative term, shown in orange above, to compensate for the system’s inertial response–when the error is dropping fast, the control system needs to back off immediately or the system will overshoot.
But see how the orange derivative term is jumping all over the place? In reality, it’s even worse–this chart shows an average over 10 adjacent samples! The problem is there’s a huge amount of noise in an accelerometer when there’s a brushless fan motor with a ten inch prop spinning at 5,000 RPM right next to it! See how there’s not too much noise at the very beginning, before the motor spins up?
Clearly, we need some sort of filtering. It worked well to smooth out the final motor power command using a time average, computing:
motor power = 10% new target + 90% old motor power
This smooths out shocks, allowing us to use a strong derivative term to compensate for inertia. The end result? Clean, authoritative control without overshoot. There’s still a little ringing, because I don’t have the parameters tuned perfectly.
Wanna try it? You can download the Arduino source code, and connect an ADXL335 accelerometer to the analog pins. Attach the Arduino’s digital pin 5 to the white PWM line of a brushless motor speed controller for a 3-phase fan motor and propeller, and tie its black ground line to the Arduino’s ground. Program the Arduino, apply 12V to the speed controller, and stand back–run it without a prop first! Open the Arduino serial monitor to get logged time, error, and derivative values in a spreadsheet friendly format (see the data above in spreadsheet format).