Rio McMahon

Hugo | Personal Web | Font Awesome | Photo Credit - Ian Stafford GC2K19 Part 5 - Control

Tipsy Write-up Navigation
Previous: State Estimation
Next: Outcomes/Summary

NOTE: The majority of the theory for the state estimate and PID controller was inspired by and heavily adapted from Brian Dwyer’s excellent write up on the subject. You can read about it here.


I implemented an empirically tuned PID controller to handle the control for Tipsy. I’ve gotten a lot of mixed input from all the research I’ve done online in terms of which terms are needed; generally people just use PD controllers. Since everything is empirically tuned I just went ahead and included the I term for my project submittal - this is definitely a future area for exploration/tuning.

The controller is attempting to minimize the error in the calculated θ where an optimal condition is θ = 0° as defined in the schematic below:

It was noted that during the tuning process, Tipsy had a tendency to fall backwards more than forwards. I suspect there was a small eccentricity between the center of mass and the centerline of Tipsy which induced a secondary moment that was not necessarily accounted for somewhere within the control/state estimation. Accordingly, the controller was ultimately updated to minimize error such that the optimal condition was θ = ~1°. This was an inelegant and lazy (but simple!) way to account for the fact that no center of mass calculations were actually done.

The control algorithm used was:

which, when implemented into my code looked like:

    void PID_Controller(){
        errork1 = errork;                       // store error at time step k-1
        errork = theta - target_angle;          // calculate current error 
                                                //     (deviation from vertical)
        pfactor = Kp*errork;                    // calculate proportional term
        dfactor = Kd*(errork-errork1);          // calculate derivative term
        ifactor = ifactor + Ki*errork;          // calculate integral term    
        PID_out = pfactor + dfactor + ifactor;  // update PID output

Tuning was done empirically which involved iteratively uploading tweaked gains to the chip, taking a sip of beer, and seeing how Tipsy performed. Eventually the gains selected for the project presentation were:

These gains/tweaked variables produced decent (but not perfect) balancing behavior.