This post will detail an experiment in which the wave sensor was attached to a rotating arm at three different diameters. These diameters were 40cm, 60cm and 80cm. For each diameter, measurements were taken at two speeds to get an idea of how rotation frequency affects measurement accuracy. This gives a total of 6 sets of data.
The speeds will be referred to as speed 1 and speed 2. With speed 2 being around 1.5 to 2 times faster than speed 1.
Two seperate methods of resetting the integration counter were used and compared. The first is detecting the peaks of the acceleration signal using this to reset the integration, the second method is using the zero crossings as the reset point.
Zero crossing method:
Speed 2 :
Peak detect method:
The results are very encouraging. In particular it was interesting that the zero crossing method provides results very similar to the peak detect method of integration reset. Zero crossing would be the preferred method for an embedded system because it takes much less processing power to detect zero crossings compared to peaks.
In post #5 I outlined the steps used to go from vertical acceleration to vertical displacement and how the results were completely off. I think I’ve figured out what was going wrong. The reason why each of the displacement graphs at the end of the post look so totally different just by changing the integral reset points is because of a negative offset to the velocity signal. I think of it as a negative DC offset, as in the average value of the signal is not zero. This causes huge problems when you go to integrate the signal. Lets take a look at the vertical acceleration signal again:
You may notice that there is a negative offset of somewhere around -0.15 or thereabouts. I was actually correcting for this because without the correction, the first integration to obtain velocity goes completely mad. So I was offset correcting this z-axis acceleration and then double integrating to get displacement. This was the cause of all of my issues. It turns out that even if I offset correct the acceleration signal, the velocity signal may still have an offset present in it. If it does have an offset and you integrate again to get displacement, the displacement is totally off.
Lets take a look at an example graph with which does not offset correct the velocity signal before integrating to get displacement:
The blue vertical lines indicate the seperate chunks of data, with everything being split based on the minima of the acceleration signal. You may notice that the velocity signal has a slight positive bias. When this signal is integrated to get the bottom graph of displacement, the displacement starts at zero but does not return to zero as you would expect as the rotating arm is rotating in a circle.
Now lets take a look at the graphs when you do offset correct before each integration step:
This plot finally makes some sense, and to make things better, the average displacement for the 5 chunks of data is 41.7cm. This measurement has an error of 4.25 %. The results from offset correcting are very encouraging but more testing needs to be done to verify that this hasn’t been a lucky one off where the end result happens to match the expected displacement of 40cm. I’ve drilled extra mounting holes into the stick at a radius of 20cm, 40cm and 60cm. I’ll repeat the above experiment for each of those heights to verify that the process actually works.
In this post I will go into detail about the steps I’m currently using to go from vertical acceleration data from the IMU to vertical displacement and the issues I’m having.
Step 1: Getting acceleration data
The first step is to setup the rotating arm with the IMU attached, rotate it for a fixed amount of time, say 60 seconds and capture the raw linear acceleration data for the z-axis which is the vertical axis. See below video for an example of the rotating arm.
Note that this video is just an example of the arm rotating. All of the data used in this post was obtained with the arm set to a 40cm diameter and a rotation speed of approximately 0.2Hz. The recorded z-axis acceleration data looks something like this:
Step 2 : Filtering acceleration signal
As it is, this signal is too noisy to work with and so it is first filtered before any other signal processing steps occur. The low-pass filtered signal is shown in orange below:
Step 3 : Peak detection
Now that we have a relatively smooth signal to work with, peak detection is relatively simple. The orange x marks on the graph below mark the peaks and troughs of the signal.
Step 4: Break signal into chunks and double integrate each chunk
These peak detection points are used to break the signal into chunks where each chunk is separately integrated twice to go from acceleration chunks to displacement chunks. The displacement chunks can then be graphed which looks like this:
Note that I’m using dots to represent the points instead of a continuous line so you can actually see the separate displacement data chunks. Another issue is that the way in which the signal is broken into chunks drastically affects the end result. The above image was obtained by detecting the minima and maxima and breaking the signal into chunks at those points. If you break the signal at just the minima you get the following displacement graph:
By using the maxima to reset the integration you get this graph:
Remember that the actual arm diameter was 40cm so we should see a maximum displacement of 40cm. Take the above image for example. The first blueline on the left goes from approximately 0.2m down to -0.5m which is a total displacement of 0.7 meters. The rightmost blue line is a better example of what I’m looking for. It goes from 0.2 down to -0.2 which is exactly what the expected result would be. I’ll do some more testing over the next few days to try and narrow down what the problem is. It may just be that the accelerometer itself has quite a lot of drift even with the short integral reset periods.
The idea of the time series displacement graph is that you can double integrate acceleration to get displacement but also periodically reset the integration to prevent massive integral drift.
At the moment, the python script I have can take a csv file with x,y,x linear acceleration which is output from the BNO555 IMU. The script then looks at only the z-axis acceleration and finds the minima of the data. It then splits the z-axis acceleration data into chunks using each of the minima as break points. It then double integrates each of these chunks seperately to return displacement chunks. It then stitches all of these displacement chunks back together and plots them. The output looks something like this:
One thing I’ve noticed is that the values I’m getting do not match the length of the rotating arm. After researching other academic articles about inertial wave measurement devices, it is apparent that the accuracy of the measurement is inversely proportional to the frequency and the amount of acceleration involved. I won’t go into too much detail right now, suffice it to say that I will be modifying the speed of rotation of the stick and the length to see how that affects the accuracy of my height measurements.
Some papers online mention using the zero crossings as integration reset points. I tried this method also as it uses way less compututational power than finding the minima. The results from the zero crossing method is shown below:
This graph doesn’t look anywhere near as good as the first and the values are completely different compared to the minima detection method. The seperate displacement chunks that have been stitched together do not match up perfectly meaning the last point of one chunk is quite far away from the first point of the next chuck. This artificially adds high frequency components into the data. As the frequency content of the data is really important I’m not sure if this method is viable without adding in more steps to stitch the displacement chunks together in a smoother way.
The parameter I’m interested in getting correct is maximum displacement. This should be around the length of the stick which is 1.5 meters. The way I calculate this parameter is by looking at each of the displacement chunks and finding the maximum displacement by subtracting the absolute value of the largest displacement from the absolute value of the smallest displacement value in a given chunk. I do this for all of the displacement chunks and average out the maximum displacement value from each.
When using the peak detection method this value of maximum displacement comes out as 1.81 meters.
With the zero crossing method this value of maximum displacement is 1.83 meters.
This represents roughly a 20% error for both methods of measurement. I’ve done some thinking about why these values are so far off and I think it’s mainly to do with the rotating arm setup. A 1.5 meter diameter of rotation may have been a bit ambitious as a starting point. Due to the uneven weighting of the arm, the imu experiences a swing effect when near the bottom of a rotation and there is a spike in the acceleration values as shown in the image below. I think this effect is causing issues with my results so I’m going to reduce the diameter of rotation and vary the frequency of rotation to see what effect that has.