After setting up the crazyflie as a blimp and performing various tests, one primary issue was noticed when attempting to control the blimp. This issue was in the yaw control; I noticed that for large yaw inputs, the blimp would not turn left or right. Instead, the left and right motors would alternate between on and off, with either just the left or just the right motor on at a time. The rate of alternation was initially proportional to the yaw input, but would slowly increase over time.
After investigating the way this yaw input is processed, I found a few things:
The crazyflie controllers for attitude can either be configured as rate controllers or position/angle controllers. By default, roll and pitch are position controllers, meaning that giving an input for pitch or roll will direct the crazyflie to drive the pitch or roll to an exact angle. However, by default, yaw is a rate controller, meaning that giving an input for yaw will direct the crazyflie to drive the rate of change of yaw to an exact d(angle)/dt. We do not need the blimp to remain at one exact angle, just to be able to turn, and so the rate controller for yaw is, currently, sufficient. Yaw position control could eventually be useful depending on the use case.
The rate of alternation would slowly increase over time. Given that the yaw rate is controlled by a PID controller, the most likely cause of the slow increase in alternation rate is the integral component of the PID control. Integral control should be unnecessary for our system and will likely only make it more difficult to control. This is due to the differing dynamics of the blimp (when compared to the crazyflie); the blimp will never be able to reach the desired rate (if it is too high) because it simply cannot turn as fast as a quadcopter. Consequently, the error in yaw rate will always be nonzero and the integral control will end up saturating the yaw control, making yaw no longer able to be controlled manually.
Removing Integral Control: Considering all of this, I decided to remove integral control from the crazyflie by setting all k_i (integral gains) to zero. To do this, I modified the crazyflie firmare in the 'pid.h' file (the process for modifying firmware is discussed in my previous blog post). The modifications can be seen in the image below (commented values are the original gains).
- The crazyflie's yaw rate control is actually set by the yaw position controller in addition to the rate controller. The crazyflie will use the set yaw rate (user input) to compute the desired yaw angle that would result from that rate over time. It then further computes a PID-controlled 'desired' rate that will allow it to smoothly and efficiently reach the desired yaw angle. This desired rate is then fed into the actual rate controller, which achieves that rate. That approach works well until the desired yaw angle it computes grows larger than 180 degrees in magnitude due to the slow turning of the blimp. After passing 180 degrees, this angle is capped and rolls over to -180 degrees. Once this occurs, the crazyflie will stop turning in the direction it was turning, as it now believes it must rotate in the opposite direction to reach the desired angle (resulting in the alternation issue).
Fixing Alternation Issue: To fix this, a more direct approach can be implemented for controlling yaw rate, which is to directly feed the user input into the yaw rate controller (circumventing the yaw position controller). This will avoid the angle rollover issue. To do this, I modified the 'controller_pid.c' file as shown in the picture below (the commented code is the original function call).
I tested the updated firmware on my blimp setup and did not notice any alternation, even for large yaw rate inputs or over long periods of time.