I need to compute the amplitude of a certain frequency band as the input to a PID algorithm. My system looks like this:
[Sine Generator] -> [Actuator] -> [Physical complex coupling] -> [Sensor]
^ |
| |
+--[PID Control Algorithm] <---- [FFT Amplitude computation] <----+
The PID controller adjusts the amplitude of the sine wave until the sensor and FFT register the correct amplitude in the output signal. In order to have a performant system, I need to compute the amplitude as quickly as possible so that the PID controller can make adjustments based on the most recent events.
In normal analysis, I would use data from the future to calculate the amplitude at a given point in time, but that information is not available when I need it. As a result, the input data is all from the past. (Also, during the initial start-up of the system, I have no data at all!) The number of missed cycles is dependent on my window size - for accuracy, I would like it to be as large as possible, but for latency, I would like it to be as small as possible (I have abundant processing power, that's not a significant constraint yet).
Due to windowing, the dominant samples used as input to the FFT are several cycles before the present time and the most recent, most important samples are only very slightly weighted. The obvious solution would be to adjust the windowing function such that the most recent cycles are heavily weighted - essentially, using just one side of a windowing function. However, this does not seem to preserve the desired effects of the windowing function, as explained (somewhat circuitously) in this question: FFT with asymmetric windowing?.
I've also tried inverting and mirroring the data, which works when the input signal is a pure sine wave (of varying amplitude) at a zero-crossing, but introduces artifacts at other times. I've begun looking into the Goertzel algorithm and sliding DFTs, but those seem to only improve the difficulty of the computation and not the latency of the result.
How can I reduce the lag associated with sampling a real-time signal?