You are here
Tip Deflections Zeroing and Filtering
At the end of the last chapter, we managed to combine data from multiple proximity sensors. We arrived at a place where we had one DataFrame containing the AoAs for a single blade. We are now more than halfway through our journey. In order to reach our promised goal of inferring blade vibration characteristics, we now convert these AoAs into tip deflections. The process entails:
 Zeroing the AoAs to remove the static part of the signal.
 Scaling the AoAs by the rotor's radius, thereby yielding the tip deflection in units of microns.
 Filtering the tip deflections to remove high frequency noise.
In this chapter, we explore multiple techniques to perform this transformation. You may ultimately use only one approach. Rest assured you'll find some application for the other ones in future, even if its unrelated to BTT.
Outcomes
Understand that AoAs are offset by a constant value. This offset is unrelated to the blade's vibration.
Understand that the normalized AoAs can be multiplied by the rotor radius to obtain tip deflections.
Understand that the tip deflection signal may contain nonvibration related components that are proportional to the shaft speed.
Understand that a low pass filter can be used to smooth the tip deflections.
Understand that the peaktopeak vibration can be used to identify resonance events.
Write a single function that zeroes, scales and filters the rotor blade AoAs.
Following along
The worksheet for this chapter can be downloaded here .
You can open a Google Colab session of the worksheet here: .
You need to use one of these Python versions:
Zeroing the AoAs
Let's load a new dataset into memory. The dataset was acquired from the same rotor as used in the previous chapters. The dataset has measurements from three eddy current probes for a runup and rundown of the rotor:
I've included the functions we've created in the previous chapter into the bladesight
module. Specifically, the get_rotor_blade_AoAs
function from the previous chapter's coding exercises have been added to the btt
module. It can now be used as a single entrypoint to convert the OPR zerocrossing times and the proximity probe ToAs into rotor blade AoA DataFrames.

We import the list annotation. The
get_rotor_blade_AoAs
function returns a list of DataFrames. Each DataFrame contains the AoAs for a single blade.Why did I not return one big DataFrame instead? Because we want to analyze each blade individually. We may want to compare the vibration of different blades. It's easier to achieve if the DataFrames are separate.
In the code above we've stipulated that probe 2 is 10 degrees from probe 1. Probe 3 is 20 degrees from probe 1. We also stipulate there are 5 blades. The function returns a list of DataFrames, one for each blade. The top of the first DataFrame is shown in Table 1 below:
n  n_start_time  n_end_time  Omega  ToA_p1  AoA_p1  ToA_p2  AoA_p2  ToA_p3  AoA_p3 

0  0.202061  0.460325  24.3286  0.205687  0.0882288  0.212988  0.265845  0.220066  0.438032 
1  0.460325  0.716163  24.5592  0.463899  0.087785  0.471097  0.264557  0.478046  0.435233 
2  0.716163  0.967917  24.9576  0.719673  0.0876073  0.726748  0.264189  0.733604  0.435293 
3  0.967917  1.21753  25.1716  0.971393  0.0874948  0.978406  0.26402  0.98519  0.434798 
4  1.21753  1.46356  25.5385  1.22097  0.0877474  1.2279  0.264713  1.23458  0.435487 
The AoAs for each probe are plotted against the revolution number in Figure 2 below.
In Figure 2 above, there are three seemingly horizontal lines that represent the AoAs for the blade at probes one, two and three respectively. Each line has a constant AoA offset. This constant is the average distance traveled by the shaft from the start of each revolution until the blade reaches the probe.
This constant offset is unrelated to the deflection of the blade. We therefore say the values in Figure 2 are not zeroed. We need to remove the static part of the signal before we can proceed with the analysis.
Normalization and scaling
One of the simplest ways to remove the static part of the signal is to subtract the mean of the AoA column from each AoA value. We can use the code below to achieve this.
The normalized AoA column can now be scaled with the rotor radius to calculate the tip deflection.
Recall that the distance traveled along an arc is given by the formula:
The code below shows how to do this:
The engineering drawing for the blisk used in these measurements is presented in Figure 3 below.
The rotor's radius is 162mm, or 162000 \(\mu\)m. I like to express tip deflection in microns. This is a personal preference.
The resulting tip deflections are presented in Figure 4 below.
In Figure 4 above, the tip deflections no longer have a constant offset. All the tip deflection values are between +1000 µm. The tip deflections change suddenly at multiple locations. Whether the change in tip deflection is positive or negative depends on the probe's location and the vibration frequency and phase.
One such location is indicated by callout A. We refer to these events as resonance events. Drag across the plot to zoom into the resonance event. Each probe's tip deflections have different shapes at the resonance. This is counterintuitive, because the blade's vibrational state can surely not change much within a single shaft revolution. This behavior is because of aliasing. But we're getting ahead of ourselves. We'll discuss aliasing in the next chapter. For now, you just need to understand that the tip deflections measured at different probes have different shapes, and that there exists a perfectly sensible explanation for this.
Are the tip deflections safe?
The tip deflections in Figure 4 above are within the safe limits for this particular blade. You need to perform a FEA to determine the safe limits for your blade.
Piecewise linear detrending
We have done well to remove the static offset from each probe's signal. Unfortunately, some static effects that have nothing to do with tip deflection are still present in the signal.
From Figure 4 it seems as though the tip deflections change proportionally to the shaft speed. It is unlikely this change is related to tip deflection. Shaft speed related shifts can occur for many reasons. In this case, the proportional change in tip deflection is due to the fact that the eddy current probes used here have a limited bandwidth. The amplitude of the pulses (as discussed in Chapter 2) therefore become smaller as the shaft speed increases. This causes the ToAs to be triggered later. This later triggering manifests itself as apparent tip deflection changes.
Let's remove this proportional change with a detrending algorithm.
A detrending algorithm is a simple algorithm that removes a static trend from a signal. The Python library scipy
has a builtin detrending algorithm.
This function fits and subtracts a linear curve from the signal. A linear curve, though, is not what we need. In Figure 4 above, there are multiple regions with different linear trends. This is especially true the moment the shaft speed reverses around revolution 1436. Linear trend changes are observed in other regions as well.
Fortunately, the detrending algorithm allows us to specify breakpoints where the linear trend changes. From Figure 4 above, I've eyeballed the breakpoints between linear sections at shaft revolutions 217, 1128, 1436, 1784, and 2670. The breakpoints are indicated by the dotted lines in Figure 4 above (one breakpoint is indicated by callout B).
The detrending algorithm can be applied for all three probes with the code below:
The detrended tip deflections are shown in Figure 5 below.
Thats much better ! The tip deflections from each probe are now centered around zero. We can now trust that the tip deflection variations are caused by blade vibration.
This approach gives us great control over the zeroing process. It would, however, be better to automatically remove these trends.
Order domain polynomial detrending
We can gain some intuition about removing shaft speed related effects with a scatterplot of tip deflection vs shaft speed. The scatterplot is presented in Figure 6 below.
From Figure 6 above, the tip deflections for probes 2 and 3 seem to decrease, on average, as the shaft speed increases. Probe 1's tip deflections exhibit a smaller correlation. The resonance events within these signals seem to be short lived as a function of shaft speed.
This allows us to fit a highorder polynomial to the tip deflections vs shaft speed. The polynomial represents the shaft speed related effects in the tip deflections. By subtracting the evaluated polynomial from each signal, we end up with a signal that only contains the tip's dynamic vibration.
The polynomial can be fit with the code below:
 Here, I've selected a polynomial order of 11. This was the first value I tried. You may need to experiment with different polynomial orders to find the best one for your case. Maybe you could write an algorithm that automatically determines this polynomial order. If you do, please let me know .
The detrended tip deflections are presented in Figure 7 below.
Great ! We've managed to remove the static, nonvibration related part of the signal. We can now move on to the next step of the analysis, filtering.
Poorly conditioned polynomial fit
When you use polynomial detrending, you may receive a Polyfit may be poorly conditioned
warning. This happens for one of three reasons:
 The polynomial order is too high. You can reduce the polynomial order to remove the warning.
 The shaft speed is constant. This means there is no shaft speed variety to fit against. You should choose an order of 0 or 1 for constant speed cases.
 Your data is wrong. If the data passed to the algorithm is spurious or incorrect, the algorithm will still attempt to fit a polynomial to it. This will result in a poorly conditioned fit. You should check your data for errors.
Tip
Zeroing can be achieved in many different ways. I've presented you with one simple method to get you going. It is, however, a discipline on its own. Maybe you can come up with different ways of zeroing the signal. If you do, please let me know .
Filtering
We've now removed the static part of the signal. We have, essentially, implemented a highpass filter on our signals. We still have high frequency noise in our signals. We can remove this noise with a lowpass filter.
Once again, the scipy
package in Python comes to the rescue. There are multiple filters in the scipy.signal
module. We demonstrate two methods here:
 A Butterworth filter.
 A Gaussian filter.
Butterworth filter
A Butterworth filter is a lowpass filter. It is often implemented in analogue systems, but we can implement it digitally with the scipy.signal.butter
function. The code below shows how to implement a Butterworth filter.
 The
butter
function is responsible for designing the filter. The order parameter,N
, and the cutoff frequencyWn
, can be adjusted. Each different combination of the two results in a different frequency response. I will not discuss filter design in this tutorial. Primarily because I am not an expert in filter design. The important parameter here is the cutoff frequencyWn
. The larger this value, the more high frequency components will be permitted to stay. In our case, the faster our resonances occur, the higher we want this cutoff. I think 0.3 is a good initial value to use.  The
filtfilt
function applies the filter. The first argument is the filter coefficients, and the second argument is the signal to filter. Thefiltfilt
function is a forwardbackward filter. This means it applies the filter twice, once forward, and once backward. This is done to remove phase shifts caused by the filter. The result is a filtered signal, but it has the same phase as the original signal.
The butterworth filter is simple to implement. It works well for most cases.
Gaussian filter
A Gaussian filter is a lowpass filter often used in image processing. It is implemented below:
 The
gaussian_filter1d
takes as its first argument the signal to filter, and as its second argument the standard deviation of the Gaussian filter. The larger the standard deviation, the smoother the signal will be. A standard deviation of 1 means the Gaussian kernel has a standard deviation of 1 shaft revolution. You need to experiment with different values to determine what works best for your case.
Filter comparison
We show the effects of both filters in Figure 8 below.
From Figure 8 above, the Gaussian filter and the Butterworth filter performs well. The Gaussian filter leaves a bit more high frequency noise. That should not bother us.
When would which method perform better?
To be honest, I have no idea. I've used both filters in the past, and I've never noticed a significant difference between the two. I've used the Butterworth filter more often, because in my experience, the people who use Butterworth filters have moustaches. Engineers with moustaches built the modern world.
Tip
It is not mandatory to remove the noise in the signal for frequency analysis. Some algorithms, such as the ones we'll cover in subsequent chapters, work better with the noise removed. There are, however, algorithms that are robust against noise. It is therefore a good idea to keep the raw signal around for later analysis if need be.
PeaktoPeak vibration
A well established concept in vibration analysis is the peaktopeak vibration. It is simply the difference between the maximum and minimum values of a signal within a certain timeframe. The peaktopeak vibration gives us a nice tool to combine the tip deflections from each probe into a single value.
The peaktopeak vibration for each blade is the difference between the minimum value and the maximum value inside each revolution.
We can achieve this with the code below:
The peaktopeak vibration for the first blade is presented in Figure 9 below.
In Figure 9 above, the peaktopeak vibration is an indicator that represents the maximum range between the tip deflections within every revolution. It is simpler to identify resonance events with this signal than with multiple probe signals.
In most of our plots, we've also included the shaft speed on a secondary yaxis. You may have noticed there is a symmetry to the resonances in Figure 9 above. This symmetry occurs because we measured on a runup and rundown, and the vibration is synchronous. We'll delve into synchronous vibration in the next chapter. For now, you only have to understand a blade will experience resonance at a particular shaft speed. Whether we traverse this shaft speed on the runup or rundown is irrelevant.
We can use this concept with a scatterplot of the peaktopeak values vs the shaft speed in Figure 10 below.
The order domain scatterplot, shown in Figure 10 above, beautifully reveal resonance events. These events occur on both the runup and the rundown. We've indicated the resonance events with arrows in Figure 10 above.
Tip
Please note the peaktopeak vibration is not the same as the vibration amplitude. It is a quick and dirty way to visually spot resonances with the aliased tip deflections. It is not a replacement for a proper frequency inference.
Conclusion
In this chapter, we converted raw AoAs to tip deflections. The tip deflection values represent the dynamic vibration of the blade. All the static components have been removed. We've also used the peaktopeak vibration to identify resonance events.
In the next chapter, we will delve into the concept of synchronous vibration and sampling.
Outcomes
Understand that AoAs are offset by a constant value. This offset is unrelated to the blade's vibration.
Understand that the normalized AoAs can be multiplied by the rotor radius to obtain tip deflections.
Understand that the tip deflection signal may contain nonvibration related components that are proportional to the shaft speed.
Understand that a low pass filter can be used to smooth the tip deflections.
Understand that the peaktopeak vibration can be used to identify resonance events.
Write a single function that zeroes, scales and filters the rotor blade AoAs.
Acknowledgements
Thanks to Justin Smith and Alex Brocco for reviewing this chapter and providing feedback.
Coding exercises
1. AoA to Tip Deflection algorithm
We've performed several steps in this chapter to zero and filter a signal. We want to combine these steps into a single function that scales, zeroes and filters a signal.
Write a function called get_blade_tip_deflections_from_AoAs
, accepting these arguments:
 A DataFrame that contains the raw AoA values of a rotor blade. This is a DataFrame from the output of the
get_rotor_blade_AoAs
function.  A polynomial order to use for detrending.
 A cutoff frequency to use for the butterworth filter.
and returns a new DataFrame with the zeroed and filtered tip deflections. Also include the peaktopeak vibration levels.
Reveal answer (Please try it yourself before revealing the solution)
Usage example: