1
$\begingroup$

I need your help. Unfortunately I don't have background in signal processing, but have a problem in this field. I'm helping a friend with an interactive art project. It has parts that move based on rotation and periodic manner on predefined path subject to tolerances in the mechanics (and noise in the hall sensor to measure). We need to predict the movement up to 100 ms in the future and would like to use the periodic nature of the movement.

The movement follows roughly a sine shape, but with one part of the curve not 100% symmetric as a pure single frequency sine would be.

I tried applying an FFT on the data and then with the inverse FFT predicting how the movement would continue. Unfortunately this didn't work. See the original (orange) and predicted (blue) signal are fully off.

EDIT: one problem may be that the input data is not 100% evenly sampled. I tried adding resampling it in Octave but could not make this work yet. Also the sampling is not so much uneven that I would expect the result be so drastically off.

I generated the GNU Octave code for that with ChatGPT.

enter image description here

Here is the Octave code used:

% Load data from the file
data = load('data.txt');

% Extract timestamp and angle columns
timestamp = data(:, 1);
angle = data(:, 2);

% Subtract the first timestamp as the base
timestamp_base = timestamp(1);
timestamp_relative = timestamp - timestamp_base;

% Plot the original data
figure;
plot(timestamp_relative, angle, 'o-');
xlabel('Relative Timestamp (nanoseconds)');
ylabel('Angle (degrees)');
title('Original Data');
grid on;

% Apply FFT with Hamming windowing
n = length(angle);
window = hamming(n);
fft_result = fft(angle .* window);
frequencies = 1e9 * (0:(n/2))/n;

% Extrapolate time series by 20 seconds with 10-millisecond resolution
extrapolation_duration = 20; % seconds
new_timestamp = timestamp(end) + (1:0.01:(extrapolation_duration - 0.01)) * 1e9; % in nanoseconds

% Use IFFT to reconstruct extended angle values
extrapolated_fft_result = [fft_result; zeros(int64(extrapolation_duration * fs), 1)];
extrapolated_angle = ifft(extrapolated_fft_result);

% Ensure both extrapolated_angle and new_timestamp have the same length
min_length = min(length(extrapolated_angle), length(new_timestamp));
extrapolated_angle = extrapolated_angle(1:min_length);
new_timestamp = new_timestamp(1:min_length);

% Plot the extended data
figure;
plot(new_timestamp, extrapolated_angle, 'o-', 'DisplayName', 'Extrapolated Data');
hold on;
plot(timestamp, angle, 'o-', 'DisplayName', 'Original Data');
xlabel('Timestamp (nanoseconds)');
ylabel('Angle (degrees)');
title('Extended Data using FFT with Hamming Windowing');
legend('Location', 'best');
grid on;

EDIT: I adjusted the access permissions. Here is the data file (column 1 is the time stamp, column 2 the information (angle), column 3 can be ignored:

Does anybody have guidance in which direction best to go here?

Best regards Alex

$\endgroup$
4
  • $\begingroup$ The link to the data file is access restricted. $\endgroup$
    – Jdip
    Commented Feb 27 at 16:08
  • $\begingroup$ If by "uneven" sampling you mean non-uniform, you would have to use interp1, not resample, to do this right. As for the forecasting, have you tried removing the hamming window from the FFT result? The envelope of extrapolated data looks fairly similar to that of a hamming window. $\endgroup$
    – Baddioes
    Commented Feb 27 at 16:49
  • $\begingroup$ That feels like a solvable problem, but you need to give us access to the date file. $\endgroup$
    – Hilmar
    Commented Feb 28 at 7:21
  • $\begingroup$ Thanks for the comments here and looking into it. I updated ther access permissions to the file. Before I trief without hamming window. It looked the same. Yes with "uneven" I meant the samples are not spaces always the same. Mostly 10ms but it varies to some extend. "resample" also had the problem that I could not install into my version of Octave. It had dependency problems that I could not resolve $\endgroup$ Commented Feb 28 at 12:33

1 Answer 1

0
$\begingroup$

If the waveform is believed to be representative, what about doing a time-domain autocorrelation, finding the peak periodicity and extending based on that?

$\endgroup$
4
  • $\begingroup$ Thanks for the proposal. As said, I'm not really into the terms and may misunderstand. What I tried initially was to basically detect one full cycle as kind of a reference and than match that into the time series to extend. This in general worked, but had a problem. The forecasted value is used in an animation. Even very small discontinuities/jumps become immediately visible. Now the periodicity has a variation (due an cheap electro motor powering the system). It didn't even with a good amount of effort to perfectly align the cycles. Hence, the idea with FFT to have a perfect continuity. $\endgroup$ Commented Feb 29 at 2:57
  • $\begingroup$ Did you try a short crossfade in the transition? Is it more important that the prediction is correct, or to avoid discontinuities? $\endgroup$
    – Knut Inge
    Commented Feb 29 at 8:21
  • $\begingroup$ Avoiding discontinuities is more has higher priority then precision. Cross fade mean to work with amount of overlap and then e.g. average this. Yes this I tried. But directly in the C++ implementation. Also the mathing is not so straight forward. I tried to this my minimising the sum of the norms of the differences. This approached ended up to be quite complex and hard to debug. Therefore I'm thinking whether the FFT approach would be more simpel to do? Any chance here on any other ideas? If not then I've to back to this matching approach $\endgroup$ Commented Feb 29 at 12:20
  • 1
    $\begingroup$ Thx. I've implemented that approach. It works. Time domain auto correlation + crossfading $\endgroup$ Commented Mar 23 at 21:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.