For our software, the critical portion is the main control loop that keeps the quadrotor flying at the desired attitude (roll, pitch, yaw) and altitude. It is essential that this control loop operates fast enough to respond to disturbances. From my research into what other quadrotor groups have done I have found that 50Hz to 75Hz is sufficient for flying. So for our project we need to analyze our system and determine if we can achieve the desired rate.
The first component to consider is the inertial measurement unit (IMU). The IMU that we have selected is the CHR-UM6-LT IMU. From the datasheet, it can output at up to 300 Hz. On the output we have the ESCs that control the motors. These expect a control pulse every 20ms, so that is on update rate of 50Hz. Most stock components can run with a slightly faster update rate, and we can select ESCs that are designed for a faster rate. In any case, we have guarenteed support for 50Hz updates with the hardware we have.
Now we need to consider the software control loop. I've broken the math into three blocks: attitude control, altitude control, and motor control. The attitude control block and altitude control block can be done in parallel, and their output fed into the motor control block. Luke and I will be writing the code in Propeller Assembly using the Float32 floating point library.
The Float32 documentation includes timings and space requirements for each of the mathematical functions. If we count the operations required for each block we can then calculate an estimate of running time and space.
Quantity | + | - | * | / | cos | sin | asin | acos | atan2 | sqrt | quat* | Sum | |||||||||
Moment | 1 | 6 | 20 | 11 | 3 | 4 | 0 | 2 | 2 | 0 | 3 | 52 | ops | ||||||||
Altitude | 3 | 1 | 4 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 11 | ops | ||||||||
Motor Speed | 14 | 10 | 18 | 10 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 56 | ops | ||||||||
Sum | 18 | 17 | 42 | 22 | 3 | 4 | 0 | 2 | 2 | 4 | 5 | 119 | ops | ||||||||
Our control loop has 119 mathematical operations. The number sounds small, but it is slightly misleading. In the next table we see that the time to execute an addition or multiplication is much less than it is to calculate arcsin or arccos. For quaternion multiplication we assume that one multiply has 6 floating point additions, 6 floating point subtractions, and 16 floating point multiplies. This follows from the quaternion multiplication formula. In summary, since we have the number of each operation, we can calculate the total times:
100 MHz | + | - | * | / | cos | sin | asin | acos | atan2 | sqrt | quat* | Sum | |||||||||
Time (uS) | 4 | 4 | 8 | 11 | 78 | 75 | 261 | 265 | 117 | 174 | 225 | ||||||||||
Moment | 4 | 23 | 168 | 116 | 234 | 298 | 0 | 531 | 234 | 0 | 675 | 2283 | uS | 438 | Hz | 2283 | uS | ||||
Altitude | 11 | 4 | 34 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 450 | 509 | uS | 1964 | Hz | uS | |||||
Motor Speed | 53 | 38 | 151 | 106 | 0 | 0 | 0 | 0 | 0 | 694 | 0 | 1042 | uS | 959 | Hz | 1042 | uS | ||||
Sum | 68 | 65 | 353 | 232 | 234 | 298 | 0 | 531 | 234 | 694 | 1125 | 3835 | uS | 261 | Hz | 3326 | 300 | Hz | |||
w/o Parallel | w/ Parallel | ||||||||||||||||||||
Finally, we are interested in code size. The floating point library has a number of required support functions that do things such as convert to and from floating point, compare floats, and so on that require space. We also assume that 4 longs on average are used to setup each operation. This gives us:
(w/ 4 extra) | + | - | * | / | cos | sin | asin | acos | atan2 | sqrt | quat* | Float | Trunc | Cmp | Pack | Upck | Extra | ||||
Size(longs) | 24 | 6 | 18 | 19 | 2 | 45 | 36 | 5 | 25 | 28 | 15 | 13 | 17 | 22 | 25 | 42 | 30 | Ops + Support | |||
Moment | 28 | 30 | 98 | 63 | 14 | 61 | 0 | 49 | 33 | 0 | 27 | 13 | 17 | 22 | 25 | 42 | 30 | 552 | |||
Altitude | 36 | 10 | 34 | 23 | 0 | 0 | 0 | 0 | 0 | 0 | 23 | 13 | 17 | 22 | 25 | 42 | 30 | 275 | |||
Motor Speed | 80 | 46 | 90 | 59 | 0 | 0 | 0 | 0 | 0 | 44 | 0 | 13 | 17 | 22 | 25 | 42 | 30 | 468 | |||
Sum | 96 | 74 | 186 | 107 | 14 | 61 | 36 | 13 | 33 | 44 | 35 | 13 | 17 | 22 | 25 | 42 | 30 | 848 | 1295 | ||
Sum w/o dup. | |||||||||||||||||||||
All in all, the code performance estimates are looking very promising. We should be able to achieve 100Hz update rates without too much trouble. The actual programming is unlikely to pose a challenge since we have the equations laid out in the exact order necessary for implementation.
Many have been asking if we are flying yet. No, sorry, we are not. Both Luke and I have been working full time on this, but there are many details to be concerned about. We are getting closer though. In the next week I plan on working on the thrust/torque test stand, and once that is done I'll start programming the control loops and the like.
The current version of the tables in this post can be found at this link.