2
$\begingroup$

I try to measure Euler angles from an IMU, but some discontinuities happens during measurement, even in vibrationless environment, as shown in the images below.

Can someone explain which type of filter will be the best choice to filter this type discontinuities?

Discontinuities in Euler angle measurement

enter image description here enter image description here

$\endgroup$
  • 1
    $\begingroup$ Check out this question, it may be similar to your problem. $\endgroup$ – Brian Lynch Oct 25 '15 at 10:50
  • $\begingroup$ I couldn't remove spikes with median filter or I dont know how to correctly implement median filter. $\endgroup$ – lsn Oct 25 '15 at 11:28
  • $\begingroup$ A quick and dirty solution is to choose some maximum change in your reading and reject samples that are greater than that limit. But this could be indicative of a problem with your data acquisition. $\endgroup$ – Brian Lynch Oct 25 '15 at 11:33
  • $\begingroup$ but I cant define tresholds coz it measure angles dynamically between -180º and +180º. $\endgroup$ – lsn Oct 25 '15 at 11:59
  • $\begingroup$ Sure you can, apply it to the absolute value of the change in your reading. $\endgroup$ – Brian Lynch Oct 25 '15 at 12:00
2
$\begingroup$

Here are my two suggestions for dealing with this problem:

Use a median filter, which replaces each value of your signal with the median of the values in a small window around each one. Here is some pseudo-code, where x is your original signal, y is the filtered signal, N is the number of points in your signal, and W is the number of points in the median filter window.

for (k = 1 to N) { y[k] = median of samples x[k-W+1] to x[k] }

If you are using MATLAB then you can use the function medfilt1 to do this, or the function median to make your own filter (see this), whereas if you are using a language like C++ then you may need to write your own functions (see this).

The other option is to simply check the magnitude of the change in the signal and reject any sample whose change is beyond some threshold. Something like this:

if (abs(x[k] - y[k-1]) > threshold) { y[k] = x[k-1] } else { y[k] = x[k] }

EDIT:

Taking a look at your data, it looked suspiciously like an angle wrapping issue, but around 180 deg instead of 360 deg. The spikes disappear if you double the signal then apply an angle wrap (using MATLAB's wrapToPi for example). The plot below shows the doubled signal in blue and the doubled signal after wrapping in red.

enter image description here

Here is the code I used:

sensorData = dlmread('sensor.txt');
t = sensorData(:,1);
x = sensorData(:,2);

x2 = 2*x;
y = wrapToPi(x2*(pi/180))*(180/pi);

figure
hold on;
plot(t,x,'k','linewidth',2);
plot(t,x2,'b','linewidth',2);
plot(t,y,'r','linewidth',2);
$\endgroup$
  • $\begingroup$ Thnx @Brain but l couldnt achieve yet $\endgroup$ – lsn Oct 25 '15 at 15:52
  • $\begingroup$ You mean you were able to get those two approaches working but they didn't help? Or you can't get those approaches working at all? $\endgroup$ – Brian Lynch Oct 25 '15 at 22:21
  • $\begingroup$ I think both of them. I also used simulink median filter block with different sample numbers but the result is same. $\endgroup$ – lsn Oct 26 '15 at 6:24
  • $\begingroup$ When you say "the same", do you mean the result after filtering is exactly the same as your input? Or that it is different but still has spikes? $\endgroup$ – Brian Lynch Oct 26 '15 at 6:45
  • $\begingroup$ Sorrt bro, yes its same as the input. median filter block or matlab function doesn't change the result. I think there is a missing point but l couldnt find it out to correctly implement it. Nonetheless simulink block could do the task u describe but it didnt work also. $\endgroup$ – lsn Oct 26 '15 at 6:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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