Posts

Showing posts with the label filters

filtering motorized ride segments with power estimation: finally done (for now)

Image
I implemented the biexponential filter, along with power filtering, in my motorized segments detection code. This program, along with my other Garmin Perl codes, can be found here . I made a few changes from previous descriptions. One is I changed the anaerobic time constant to 120. This is more the upper end, rather than the median, of typical numbers. This may provide a bit more margin against falsely identifying a segment as motorized. The other change I made was to separate the altitude-smoothing time constant from the anaerobic time constant. Oversmoothing of altitude can result in the overprediction of power when a rider descends small dips. I set the default to 30 seconds. I also added some speed smoothing but only 5 seconds. Without any speed smoothing and there's too much effect from when the Garmin occasionally spits out a single point with ridiculously high speed. But too much longer than 5 seconds and I lost more of the train segments in Italy where the tra...

exponential filter impulse response for altitude data smoothing

Image
Linear filters are characterized by their impulse responses. To test my exponential filter algorithm, I created an input data set with zero-value points randomly spaced in time. At zero I put a finite approximation to a unit impulse: ‒0.01, 0 0, 100 0.01 0 I then ran this through my exponential filter in various ways. One way is to run the points in time-forward order. This is the "causal" approach: I'm analyzing data as it comes, and I want a smoothed result as I am receiving data. Also causal is to run the smoothed curve again through the exponential filter. You'd expect this second smoothed result to be even smoother than the first time through, and of course it is. Then there's a single and double application of the exponential filter in reverse time order. You'd expect the result to be flipped from the forward-time order (there's nothing special about forward time versus reverse time which should make the shape different; if it were th...

exponential filtering algorithm

Here I'll briefly describe the algorithm for filtering data with an exponential convolution. First, I'll define the following: n: an index for the point in the series. The first point is n = 1, the next n = 2, the next n = 3, etc. y n : the series of unfiltered points data values, for example altitudes. t n : the series of unfiltered points time values. Δt: the time separation of the data for uniformly spaced time points. Δt n : when time is not necessarily uniformly spaced, Δt n ‒Δt n‒1 . τ: the smoothing time constant. u n : normalized time values, t n / τ. Δu: Δt / τ (for uniformly spaced time points). Δu n : Δt n / τ. z n : the series of smoothed time points. So using these definitions, I want to convert from the unsmoothed series y n to the smoothed series z n . First, if an initial point is encountered, we start things rolling with the following: z 0 = y 0 Then assuming uniformly spaced data, a naive approach is the following: z n = z n‒1 exp...

smoothing Garmin altitude profiles for power estimation

Image
Recall that I was contemplating using power in lieu of speed for determining whether a Garmin FIT file contains motorized segments. The speed criterion was fairly simple: if the data indicate the user got 500 meters ahead of a 14 m/sec pace over any segment, that segment was judged to be a portion of motorized travel. The entire region between load/unload opportunities was thus tagged and pruned. While cyclists may be able to sustain a high speed for short periods, by requiring they get a certain distance ahead of a threshold pace requires they exceed that pace for an extended time, or vastly exceed it for a shorter time. Example of critical power model applied to more realistic curve In the power-time domain,the critical power model accounts for that ability to sustain high intensity for short times, but only a lower intensity for longer times. The critical power model is very similar to the criteria used for speed: it says a rider, given sufficient time, can do a given amoun...

vibrational modes and filtering

Image
Last post, I discussed how road vibration transmits a spectrum of acceleration to the frame, which excites oscillation modes in the relatively complex bike-rider system. MIT measurements showed oscillations near 30 Hz (of lesser magnitude, less in carbon fiber than in steel and Al) and near 50 Hz (of greater magnitude, more in Al than in carbon fiber or steel). I generated simulated noise spectra with, successively, a direct ground noise component at 0 Hz, then a mode at 30 Hz, then an additional mode at 50 Hz. The magnitudes of the latter two modes were based on the MIT data. Here's the curves. As you can see, the 30 Hz and 50 Hz modes have a large effect on the acceleration: simulated vibration data in frame, adding modes Now suppose I was trying to extract cadence from such accelerometer data. All of this would be considered "noise": not part of a ±1 g oscillation as the gravity vector spins in a circle relative to spindle coordinates. Essentially I want the noi...

Filters 2.0: frequency response

Image
Now I'll go through the frequency response of my "new favorite" filters. These are all trigonometric functions, so no need for integration by parts, as long as I use a few trigonometric identities. I was even able to skip most of the expanding trigometric functions in terms of their complex exponential equivalents. I'll spare the details and cut to the chase. Here's the filters again: In each case assume an input function: f(t) = f 0 sin ωt, and where the output function is f*(t). In each case I'll explicitly include the time shift to make the filter causal, so I'll represent the output function delayed as f*(t + τ). This is the reason I've changed my definition of τ here: it now represents the half-width of the filter function; a more direct representation of the delay. cos 2 (π/2 Δt/τ): I analyzed this before, but with a slightly different form. The result: f*(t + τ) = 2π f0 sin(ωt) sin(ωτ) / [ωτ (1 ‒ ω²τ²/π²)]. ‒3π/2 cos(π/2 Δt/τ) sin(π Δt/τ...

filters 2.0

Image
I've gone on quite long enough about filters. But I think I'm finally getting it right. So it's my blog, after all, and the whole point is I can write about what I want. So I'm going to stick with filters a bit longer... I'm trying to figure this stuff out for myself. As I noted last time, after thinking about it, I realized I could do all the filtering I needed with strictly trigonometric functions, and trigonometric functions have attractive mathematical features (particularly, their exceptional smoothness, and their tendency to average to zero). It's just a matter of selecting the function. The goal is to smooth the data (reduce high frequency components) while optionally also reducing low frequency components. The criteria are: The area of the absolute value of the function should be one. The function needs to transition to zero smoothly, which is to say with a continuous slope, at the edges. This helps to reduce high frequency components. If the fun...

Filters 1.0: frequency response

Image
Okay, so why all this interest in the rather boring subject of convolution functions for filtering? Well, a few things. The most recent reason is having fun playing with MetriGear Vector data. Sure, I could have fun playing with PowerTap data (and I actually have a Powertap, while I don't have a Metrigear Vector). But Saris is all hush-hush with its numbers, while MetriGear is much more open: they've for example published data on their excellent blog , and when the pedals go to market, they promise to provide a much higher rate of data reporting than one gets from existing meters, typically one sample per second (or the Powertap famous sample per 1.26 seconds). Additionally the Vector will provide a lot more information. Of particular interest to me at the moment is how to process accelerometer data. Accelerometer data tends to be noisy, both from errors in measuring the actual acceleration, and in accelerations other than those of the pedals turning in circles. So to ...

A one-step band-pass

Image
So far, I've been doing band pass filtering by a low pass followed by differentiation. This involves first a convolution to realize the smoothing, then a difference function for the differentiation. But now that I think about it, it's better to avoid the difference function and accomplish the full band pass filtering with a single convolution. Okay, you can stop laughing now. I know this is all super-basic-DSP-stuff. I'm afraid I never actually took a class in DSP. So laugh if you want. I can take it. Anyway, the low-pass filter used last time was the following: f*(t) = (2 / πτ) ∫ d Δt · cos²(Δt / τ) f(t ‒ Δt), where here the limits of integration are again from ‒π/2 τ to +π/2 τ. This can be turned into a band pass filter by simply multiplying the convolution function by Δt / τ: f*(t) = (K / τ) ∫ d Δt · (‒Δt / τ) cos²(Δt / τ) f(t ‒ Δt). A plot, after applying the delay by π/2 τ: I suppose we should calculate K. The integral of the absolute value of the convolution fu...

Band Pass Filtering: SCORE SQUARED!

Image
In the last post, I showed how a truncated cosine wave did a better job than an exponential function at smoothing data. The goal was to produce a band pass filter, which filtered fluctations occuring at both high and low frequencies, leaving only those in a desired band. Differentiation was used for the high-pass part. But the differentiation canceled out the low-pass effect of the exponential smoothing. The truncated cosine smoothing was strong enough to retain its low-pass character even after the differentiation step. Here I consider another form of smoothing: a cosine squared. The exponential weighting function jumps discontinuously to zero. The truncated cosine has a continuous value to zero but a discontinuous slope when it is clamped at zero. The cosine squared, on the other hand, has a continuous slope as well when it is held at zero. The three filter shapes are shown in the following plot. They are shown with the time shift I mentioned last time so to be causal. Only ...

Band Pass Filtering: SCORE!

In the last post, I showed how a simple-minded effort at band-pass filtering failed miserably. Basically the attempt was to apply a simple low-pass exponential weighted rolling average as a low-pass filter, then follow up with differentiation, which cuts out the low-frequency stuff. The problem was the differentiation basically undid the low-pass filtering of the exponential averaging. What was left was a high pass filter, not a band pass. Of course I could look this stuff up on Wikipedia or even (gasp!) an actual book (remember those?). But I that would hardly be redemption. Better to dive in and convince myself I still remember something from that expensive college education.. So to retain both high and low-pass characteristics after differentiation what's needed is a better low-pass: it needs to cut off high frequencies faster than the 1/ω behavior of the exponential smoothing. I previously proposed a truncated sine wave Let's try that (or a truncated cosine wave: same...

Band-pass filtering: FAIL!

Last time on the subject of the MetriGear Vector, I posted some comments on filtering noisy data. Honestly, I hope my college professors weren't reading that one.... I might find myself back in school having had my undergraduatee EE degree revoked. 6.003 redux. What I'd proposed was exponential smoothing followed by differentiation. Exponential smoothing is a convolution with an exponential function. The result is, where f*(t) is the smoothed function, and f(t) is the original function: f*(t) = (1 / τ) ∫ d Δt · exp(‒Δt / τ) f(t ‒ Δt), where the integral is from 0 to ∞. In this case, where we're dealing with pedaling motion, pedaling at constant cadence yields a sinusoidal motion. For example: f(t) = f 0 sin ωt, where ω is the angular velocity. For those of us who were never very good at memorizing integration tables, it's easier to express the sin function in terms of its equivalent in complex exponentials, where i is the unit imaginary number: f(t) = f 0 [ ...