Tuesday, February 14, 2012
Learning about Quaternions and Whatnot
Lot's of progress has been made over the past week, and I'm satisfied with the progress. I have been working on interfacing the CHR-UM6 IMU device. It's actually rather complex to interface to, mainly because it's a complicated device. There's approximately 50 registers or so, and numerous configuration options. In any case, I'll be writing the device driver for that. Should be lots of fun.
Luke and I also worked on assembling the frame on Friday. We got the motors up and running, and did some basic tests. Exciting stuff! Luke blogged about it, so check it out.
Finally, I also did some research into quadcopter control theory. Turns out that (no surprise) it's really complex. Quadcopters have so many different things going on concurrently, and so to control it all requires lot's of math. The best paper that I have found so far is "Design and Implementation of a Structured Flight Controller for a 6DoF Quadrotor Using Quaternions" (paper here, and html link here). This paper and the others have lot's of theory, but it appears that at the base of it all is a simple idea: your airframe is rotated to a certain orientation, and your control program has a desired orientation for the airframe. Then the program simply calculates the motor outputs necessary to rotate from the current orientation to the desired orientation, and you're flying.
Unfortunately, a quadcopter has any number of different problems. When the quadrotor is moving sideways through the air, the propeller blades "flap": the leading edge is pushed up above the plane of rotation, and the trailing edge below. When a quadrotor is moving up or down through the air, the moving airflow through the propellers creates a different amount of thrust relative to a stationary hover. In addition, each motor and blade is slightly different, so the same control input to each motor will produce a different thrust. Together, these (and more!) small things add up to make it much more difficult to control a quadrotor.
This leads to my critical question of the week: what is the basic control model of a quadcopter, and what are it's limits?
So, I'll be exploring that, along with writing as much low level driver code as I can get. I'll need to write some code to process the quaternion math: each iteration through a control loop will take an estimated ~10 quaternion multiplications. Each quaternion multiplication takes 16 multiplies and 12 adds, each of which is floating (or fixed) point. Since the Propeller doesn't have a hardware multiplier or FPU we'll have to come up with a way of working around that. The object exchange has a very nice floating point object (here) that has all the routines written for floating point. It even has timing for the function calls, from which I calculated that one quaternion multiplication will take about 1ms at 100MHz clock speed, using the provided code. But, if I modify that code and write a new object I anticipate that it will take somewhere around 0.2ms to complete a multiplication. At ~10 multiplications per control loop, it will be able to run at 500Hz.
All this took in excess of 30 hours to work on.
Next week, I'll be learning more about quaternions and quadrotor control, and I'll do some device driver programming to break up the monotony.