|I guess if you use LabView this is what the code looks like too...|
The flux estimator takes the phase voltage and phase current as inputs, and runs them through the constitutive equation for a round-rotor permanent magnet motor:
The result of the integral form of the equation is the phase flux linkage. This, like back EMF, contains information about the position of the rotor. Unlike back EMF, it doesn't vary with speed, which makes it a nicer quantity to estimate in most cases.
Doing an integration in software on real signals is not always practical. Ideally, the voltage and current are purely AC signals. But in real life they may have some DC offset for a variety of reasons. The current sensors may not be well-zeroed. Even so, the zero value may drift and there will always be at least some offset at the minimum resolution of the sensor. The voltage comes directly from the known PWM values, but it could also be biased due to rounding or other numerical issues.
Any bias on the input signals would cause a pure integrator to ramp the output up to infinity. For that reason, it's common to implement an integrator as a low-pass filter instead. At high frequencies, the a low-pass filter with the appropriate gain behaves the same as a pure integrator. That gain happens to be exactly the same as the time constant. Another way to think about it is that it's a pure integrator in series with a high-pass filter. This lead to the same transfer function and behavior: integrating frequencies above cutoff but attenuating any DC bias.
Attenuate...but not eliminate.
The pseudo-integrator's DC gain is the time constant of the low-pass filter. So, although it won't ramp off to infinity, there will still be some DC bias in the flux estimate and it will get worse as the time constant for the low-pass filter is increased. This creates a bit of a trade-off, since increasing the time constant can help improve the low-speed performance of the flux estimator but will cause more flux estimate bias. Here's what the flux estimate looked like on the CineStar 6 QC-3328 motors at approximately hover speed:
Before attempting to reduce the current sensor offset, I took out the easier problem, which is the voltage offset. The 3-phase sinusoidal voltages are generated according to an 8-bit sine look-up table (LUT) which stores 256 numbers between 0 and 255 that trace out the amplitude of a sine wave. As it turns out, the actual average of these numbers is 127.5, not 127. This alone could shift the flux waveform up by (0.5/255)(25V)(6ms) = 294μWb. Just by switching to more precise math when calculating the voltage on each phase, I was able to eliminate this source of offset immediately:
There's an interesting pattern present in this data which I think was caused by sitting at a very steady speed for pretty much the entire capture. Maybe now that the flux waveform isn't being clipped, things settle in to a more regular pattern. Or maybe I just happened to sit at exactly the right RPM for aliasing like this to occur. Either way, to confirm that it wasn't a problem I had just introduced, I redid the test and varied the speed a lot more:
Here, the current is more varied because I was accelerating and decelerating a lot. But the flux waveform is still clean and centered around zero. I wasn't sure how much this fix would improve the performance of the sensorless position estimate. For sure, you can hear the effects of the waveform clipping on certain motors. Here's a GIF of all three flux/current waveforms to better show the difference:
The third, most unbiased flux estimate also produces the most uniformly-spaced and scaled current signals, which is probably a good thing in terms of efficiency. The flux zero-crossings will be evenly spaced, which should improve the position estimate and the FOC. Initial bench tests seem good, but I'm really looking forward to putting the improved version on all six ESCs and doing another CineStar flight test, this time with a Watt Meter.
Sorry for the boring all-math post. But it was interesting to see an immediately obvious cause-effect relationship in this quick and simple fix.