Using Matlab to integrate accelerometer data into velocity and position

21,390

Solution 1

I'm a bit confused what you mean when you say that you can't just use the cumulative area under the curve. That is the integral, so if you want to integrate acceleration data to get velocity and position, it is exactly what you need. If you accuracy is poor, then maybe you need higher quality accelerometer data, but that cannot be helped in post-processing.

I would recommend simply using cumsum() or cumtrapz() to integrate your data.

Solution 2

If you need something quick and vectorized, use cumtrapz. Assuming that vector tcontains the measurement times, that vector acccontains the acceleration measurements and that the initial position is pos0 while the initial velocity is vel0, I'd write:

velocity = vel0 + cumtrapz(t,acc);
positions = pos0 + cumtrapz(velocity);

i you only have some measurement points cumtrapz might be one of the best solution with respect to accuracy and simplicity.

Hope this helps.

A.

Solution 3

You can use use a spline to exactly represent your discretized acceleration data, then integrate the area under that to get the velocity, and then again to get position.

You'll need to determine what method you're going to use to extrapolate acceleration values between sample points. In general a cubic spline does a very good job representing "real world" accelerations, while linear splines are the easiest to work with and still give fairly good results.

Note that your results will vary on how good your original readings were, and how frequent they are being sampled at. If you want an exact instantaneous velocity/position with high precision, you'll probably want to use a sensor which measures those directly.

Share:
21,390
Lynn Robbins
Author by

Lynn Robbins

Updated on April 30, 2020

Comments

  • Lynn Robbins
    Lynn Robbins about 4 years

    I have test accelerometer data and need to use Matlab to find velocity and position. I need the actual data points for both velocity and position, though, not just the cumulative area under the curve. I have sample data that I am using and have been able to accomplish this through fairly lengthy and specific vectorization coding, but I need to find a more general method. I cannot just use a curve fit and then estimate the area because I have discrete data and cannot afford to have any error. This method of essentially calculating the area of each rectangle is the most accurate way. I have my attempts so far below:

    %Variables
    
    clear
    
    DeltaTime=0.2; %10 Hz sampling rate 
    
    Acceleration=[0, 1, 2, 4, 3, 1, 2]; %Sample random data set
    
    TTime=(0.2:DeltaTime:1.4); 
    
    VelocityL=zeros(size(Acceleration));
    
    VelocityLL=zeros(size(Acceleration));
    
    %Velocity
    
    DeltaVelocityVect=Acceleration*DeltaTime;
    
    VelocityV=[sum(DeltaVelocityVect(1)),sum(DeltaVelocityVect(1:2)),...
        sum(DeltaVelocityVect(1:3)), sum(DeltaVelocityVect(1:4)), sum(DeltaVelocityVect(1:5))...
        sum(DeltaVelocityVect(1:6)), sum(DeltaVelocityVect(1:7))];
    
    %Position
    
    DeltaPositionVect=VelocityV*DeltaTime;
    
    PositionV=[sum(DeltaPositionVect(1)),sum(DeltaPositionVect(1:2)),...
        sum(DeltaPositionVect(1:3)), sum(DeltaPositionVect(1:4)), sum(DeltaPositionVect(1:5))...
        sum(DeltaPositionVect(1:6)), sum(DeltaPositionVect(1:7))];
    

    I have solved this all by hand and graphed it both on paper and on Matlab and the above works. The length of the data sets will vary, though, so it will not work in the long term. I have tried to use looping to solve this problem since the index can be easily altered to fit any length of vector while maintaining the sampling rate, but I have not been able to get it to output the actual data points. I need a general form of the above.

    for index=1:length(Acceleration); 
      DeltaVelocityLoop(index)= DeltaTime*Acceleration(index);
    end
    
    for index2=1:7
      VelocityL(index2)= sum(DeltaVelocityLoop(index2));
      VelocityLL=VelocityLL+DeltaVelocityLoop(index2);
    end
    

    This is my 10th attempt so it includes repetition. VelocityL returns the exact same vector as DeltaVelocityLoop (without the previous areas summed, which is the goal). VelocityLL simply returns the total area under the curve written the length of vector Acceleration. Please let me know if you have any ideas on how I can get around this roadblock.

    • Itamar Katz
      Itamar Katz over 13 years
      If you need the actual data points, acceleration alone is not enough, you will need 2 constants of integration, for example initial position and initial velocity. Besides, keep in mind that in such a scheme you will have an accumulated error, so if you are integrating over a long time, you might get unreliable results.