Monday, June 18, 2012

Get down from there, flux. You're not DC. You're not even a real measured quantity.

I recently fixed a nagging problem with the flux estimator, maybe the key part of my sensorless field-oriented control method. I'm in the process of writing up my current approach to sensorless control, so I've finally been generating some nice figures (ones that aren't made in PowerPoint) that will hopefully explain some of the math better than I can in words. Here's what the flux estimator looks like:

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:

There are a few things to notice. One is that the current waveforms are offset by at least 1-2A. (Look at the maximum and minimum current on each phase.) With a nominal phase resistance of 46mΩ and a filter time constant of 6ms, that would lead to a flux bias of (2A)(46mΩ)(6ms) = 552μWb. This is almost half of the expected flux amplitude, and it shows in the flux waveform, which is shifted up by quite a bit. The flux estimator has a saturation parameter, set to 1500μWb, and you can see the top of the waveform being clipped in this data.

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:

The clipping of the flux linkage waveform at 1500μWb is no longer present, but there's still a good amount of bias. The next step I took was to have the current sensors auto-zero at the start of the program. It's an obvious and common thing that I neglected to do mostly because I kept saying, "I'll do it later," and I didn't realize how much it would matter to the flux estimator. After adding in a simple auto-zeroing routine, the flux is now back to dead center:

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.


  1. Hi,

    How this filter time constant has to be calculated.

    1. This is actually a question that requires a more detailed answer. I am writing up a complete description of this sensorless method which will have the full answer. But here I will just give a short answer:

      The time constant should be significantly longer than the commutation period at the slowest speed for which sensorless operation is desired. So, if the electrical frequency is 40Hz at the lowest sensorless speed, for example, the filter time constant should be much larger than 1s/40. However, if the time constant is too long, then current sensor bias can lead to drift and instability. So those are the two constraints.

      More details to come. Thanks for asking!

  2. Thank you very much for you nice post!