How to Account for Numerical Integration Error?
Mostrar comentarios más antiguos
I'm working on a project using an Arduino Uno and an Adafruit gyroscope. I'm collecting gyroscope data, saving the data to a text file, and importing the data into MATLAB to operate on it. The gyroscope provides me with angular velocity data whereas I am interested in angular position. To get angular position from angular velocity, I use cumtrapz to numerically integrate my data. I also have implemented a three-point weighted average filter to smooth my gyro data as well as averaged a portion of the data to correct for the initial gyro offset.
Everything in my script is working as it should, however, I'm noticing that when I bring my gyro back to the starting position at the end of a movement, my integrated angular position data does not return to zero. However, the angular velocity data with the help of my filter and offset correction does return to zero. This makes it clear that my final offset is a result of the integration process.
From what I've read online so far, it seems that using cumtrapz and numerical integration in general results in a small amount of error. I remember from my Calc I class that using trapezoidal integration is, of course, only an approximation, so some error is to be expected.
My question is how can I take this error into account and correct for it in my integrated angular position data? I've attached some screenshots of my raw angular velocity data, filtered angular velocity data, and my integrated angular position data.
Thank you for your help in advance.
1 comentario
John D'Errico
el 30 de Jun. de 2016
I'm moved Nick's answer into a comment, here as a way to include the code:
clear; clc; close all;
% Import gyroscope data from delimitied text file
gyroData = dlmread('float7.txt',',');
% Convert time from ms to seconds
time = gyroData(:,1) .* .001; % seconds
% Define raw angular velocities (deg/sec) for each axis
xRaw = gyroData(:,2);
yRaw = gyroData(:,3);
zRaw = gyroData(:,4);
% Filter gyro data using filter function
[xFilt, yFilt, zFilt] = filterGyroData(xRaw,yRaw,zRaw);
% Sample first 100 data values to calculate offset
xOff = xFilt(1,1:100);
yOff = yFilt(1,1:100);
zOff = zFilt(1,1:100);
% Average initial offset values
xAvg = mean(xOff);
yAvg = mean(yOff);
zAvg = mean(zOff);
% Correct filtered data initial offset
xCorr = xFilt - xAvg;
yCorr = yFilt - yAvg;
zCorr = zFilt - zAvg;
% Convert values to radians per second
xDataRad = deg2rad(xCorr);
yDataRad = deg2rad(yCorr);
zDataRad = deg2rad(zCorr);
% Use cum. numerical integration to obtain angular position (radians)
xAngPosRad = cumtrapz(time,xDataRad);
yAngPosRad = cumtrapz(time,yDataRad);
zAngPosRad = cumtrapz(time,zDataRad);
% Convert values back to degrees
xAngPosDeg = rad2deg(xAngPosRad);
yAngPosDeg = rad2deg(yAngPosRad);
zAngPosDeg = rad2deg(zAngPosRad);
% Plot raw angular velocity
figure(1);
plot(time,xRaw,time,yRaw,time,zRaw);
title('Raw Angular Velocity');
xlabel('Time (sec)'); ylabel('Angular Velocity (deg/sec)');
legend('x','y','z');
% Plot filtered angular velocity
figure(2);
plot(time,xCorr,time,yCorr,time,zCorr);
title('Filtered Angular Velocity')
xlabel('Time (sec)'); ylabel('Angular Position (degrees)');
legend('x','y','z');
% Plot filtered angular position
figure(3);
plot(time,xAngPosDeg,time,yAngPosDeg,time,zAngPosDeg);
title('Filtered Angular Position');
xlabel('Time (sec)'); ylabel('Angular Position (degrees)');
legend('x','y','z');
end
Respuesta aceptada
Más respuestas (1)
John D'Errico
el 30 de Jun. de 2016
0 votos
In order to compute the error of a numerical integration as an approximation, you would need to know the true function, and the true integral.
The fact is, you don't KNOW the true function. You don't KNOW the true integral!
So you cannot account for the unknowable.
That being said, I don't KNOW that you don't have a bug in your code.
6 comentarios
NickPK
el 30 de Jun. de 2016
John D'Errico
el 30 de Jun. de 2016
Editada: John D'Errico
el 30 de Jun. de 2016
Please post comments as a COMMENT, not as an answer. Or simply attach it to your question as an m-file.
As well, why did you feel the need to comment out the entire script? I had to remove all of the spurious percent signs that you put in.
NickPK
el 30 de Jun. de 2016
John D'Errico
el 30 de Jun. de 2016
Editada: John D'Errico
el 30 de Jun. de 2016
The trick with the code button is to past in the code, THEN select it, THEN click on the "{} Code" button. If you click on the code button with nothign selected, then is adds a spurious if true conditional, I assume to show you where you need to include your code. It just confuses people though.
All the "{} Code" button really does is insert two spaces before every selected line. Lines indented with two spaces at the start are recognized as lines of code.
So this is interpreted as a line of code, and highlighted as such.
And this is not.
The only difference was I indented the first line above.
NickPK
el 30 de Jun. de 2016
John D'Errico
el 30 de Jun. de 2016
Ok, I looked at your code. My first inclination is that you filtered it, which must of course introduce some error too. I'll need to look more carefully at what you have done.
Categorías
Más información sobre Multirate Signal Processing en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!