Tuesday, 23 April 2013

Reading on FFT

Today I finished all my exams and I am back to the project. As Karon asked, I have just started reading on Fast Fourier Transformations and below is my report on that.

Introduction:
A physical process can be described in 2 ways:
1. using time domain. In this case we will have a quantity as a function of time. h(t)
2. using frequency domain. In this case the amplitude H is given as a function of frequency. H(f). f can take any value and H(f) is usually a complex number.
h(t) and H(f) are both representations of the same function. To go back and forth between these 2 representations, one uses the Fourier transform equations. 
if t is measured in seconds, then the frequency is in cycles per second (hertz). we can also have the Fourier transformations on angular frequency.
The total power in a signal is the same whether we compute it in the time domain or in the frequency domain. 
Sometimes we want to know how much power is contained in the frequency interval between f and f+df in which case we usually consider f to be from 0 to infinity. Based on that we define PSD (one sided power spectral density) and the total power is the integral of PSD from 0 to infinity. 
something of interest is the PSD per unit time. This is computed by taking a long but finite stretch of h(t) and finding a function that is equal to h(t) in this stretch and 0 anywhere else, then computing the PSD of this function and dividing it by the length of the stretch. 

Fourier Transform of Discretely Sampled Data:
for any sampling interval t, there is a frequency f called the Nyquist critical frequency given by f = 1/2t.
This comes from the fact that a critical sampling of a sine wave is two sample points per cycle; one to sample the positive peak and one to sample the negative peak.
The Nyquist critical frequency is important for 2 reasons:
1. Sampling Theorem:

  • (Definition) Band-Limiting is the limiting of a signal's Fourier transform or PSD to zero above a certain finite frequency. 
This says that if a signal is known to be bandwidth limited to the Nyquist critical frequency we can get the entire information content of the signal by sampling it at a rate equal to twice the maximum frequency(which I guess is the critical frequency).

2. Aliasing:
This happens when the signal is not bandwidth limited to less than the Nyquist critical frequency.

we also define the discrete Fourier transform to find the Fourier transform of a discrete sample of h(t).
The complexity seems to be O(N^2) in the first look because of a vector matrix multiplication that requires multiplying N^2 complex numbers. But it can also be done in O(N log N) operations using fast Fourier transform.

Fast Fourier Transform (FFT):
The idea is we can compute the discrete Fourier transform of length N, by summing two discrete Fourier transforms of length N/2, one formed from the even-numbered points of the original N and one from the odd-numbered points.
Next, each of those two discrete Fourier transforms can be written as the sum of two other half length discrete Fourier transform and that is how the better complexity is obtained.
The easiest case is for N to be a power of two. If the length of our data is not a power of two, we should pad it with 0s.
FFT uses bit reversal which is reversing the order of the bits so 001 will turn to 100. so given the original vector of data fj, we will rearrange it in bit-reversed order and the adjacent numbers in the resulting vector are the exact order in which we need to access them inorder to compute the Fourier transforms. To note is that the first half of the vector would be the even-numbered points of the original N and the second half would be the odd numbered points.
Thus the FFT algorithms has two sections. The first section sorts the data in bit-reversed order. The second section has an outer loop that is executed logN times calculating the transforms of different lengths.
since we had N points sampled originally, the whole algorithm now takes O(N log N) time.
The above algorithm is known as Cooley-Tukey algorithm.

FFT in Two or More Dimensions:
suppose we have a two dimensional function h(k1, k2). The 2-dimensional discrete Fourier transform H(n1, n2) is defined (very similar to one dimensional) as
it can easily be seen that one can compute a 2-dimensional Fourier Transform by taking one dimensional Fourier transforms sequentially on each index of the original function.
The above function can be generalized to L dimensions in a similar way.


Thursday, 11 April 2013

April 11 2013

To-Do-List:
1. compare the initial static pressure map to the final one and show how much the static pressure has changed over time
2. Run the program with all different modules and make sure everything runs smoothly.

Details:
1. compare the initial static pressure map to the final one and show how much the static pressure has changed over time
I wrote another function for doing this called: compareInitialFianl.m
The way they are compared is using all() function on the rows and summing the result up. if the result is 10 that means the two matrices are exactly the same. a result of 0 means there is some difference.

2. Run the program with all different modules and make sure everything runs smoothly.
The program runs smoothly but I had two main problems:

  • If I subtract the initial static offset from the pressure map, taking the log2 will result in complex numbers which will cause an error when displaying the picture on the plot.
  • If I take the log2 of both the initial static offset and the pressure map and then subtract them, the image showing the centroid will not be as correct as I wish. (sometime, it will even go out of the boundary of the map)
What's left?
figuring out why subtracting will give these weird results and how we can solve the issues.
I fixed this issue by subtracting the static offset from the pressure map after taking the log2 from both but also taking the absolute value of the elements of the resulting matrix. I found out that some values in the pressure map could decrease compared to the initial static map and thus the subtraction could cause negative numbers which would affect the centroid and the pictures. But taking the absolute value seems to give reasonable results.


Wednesday, 10 April 2013

April 10 2013

To-Do-list:


1. collect a static sample while the creature is not being touched at the start and end of every collection
2. modularize the code
3. record both the code collection version number + static offset data in the same file

Details:
1. collect a static sample while the creature is not being touched at the start and end of every collection
at the very first iteration of the while loop which collects data as many times as we need samples, a static pressure map will be collected without the user touching the creature. Same will be done at the very last iteration.
At every iteration, the static_initial_pressure_map will be subtracted from the value matrix (which is the pressure matrix) to ensure that the environment noise is reduced as much as possible.
At the very last iteration, another static sample is collected and compared to the initial static pressure map to see how much the environment noise has changed over the data collection phase.

2. record both the code collection version number + static offset data in the same file
both static offset pressure maps (the initial one and the final one) are saved within the same file.
the version number will depend on how the pressure map is processed.

3. modularize the code
The following functions were added to the code:

  • centroid.m: calculates the x and y location of centroid given the pressure map
  • preProcess.m: changes the pressure map and returns a new map as well as a version number. This can later be used to track how the pressure map had been modified.
  • analyze.m: is responsible for any kind of analyzing the data. For example the centroid will be calculated in this function.
What's left?
compare the final static pressure map with the initial one. The thing that is making it difficult is a finding a good method for comparing two matrices and say how much they are similar. I thought about subtracting them and use the resulting matrix to say whether much as been changed but I am not sure how good this method is for comparing two matrices.

Tuesday, 9 April 2013

April 09 2013

To-Do-List:

1. collect a static sample while the creature is not being touched at the start and end of every collection
2. modularize the code
3. record both the code collection version number + static offset data in the same file

Details:
1. Modularizing the code
Today, I spent some time breaking up the large code into smaller chunks that each do a single task only. These pieces include the following functions:
dataCollection.m : responsible for reading the data and preprocessing it
Read.m: responsible only for reading the data off the robot
SaveData.m : responsible only for saving all the data to a file including code collection version number and the static offset

Wednesday, 3 April 2013

April 03 2013

To-Do-List:

modify the centroid code to account for inverse pressure numbers.

Details:

The maximum possible number that we can see in the pressure map is 1023 and it should correspond to zero force/pressure. But we never see that because of many different sources of measurement error such as noise, electrical current leaking, etc. We cannot have negative numbers for the pressure. If you ever see negative numbers in the pressure matrix, it means the code is buggy.
The simplest approach to convert these numbers is to subtract them all from 1023. Then zero pressure will correspond to zero (which we will never observe because of measurement error) and max pressure will correspond to 1023 (we will probably see lots of that in the matrix). Just try that one and see how it works.
The second approach I will suggest is to take the logarithm of the numbers in the matrix (base 2) and subtract them all from 10. Don't ask me why and try it too. I'll tell you more about it only if it works 

At this point, I only changed the centroid method to calculate the centroid position accounting for the inverse pressure numbers.

1. subtracting each element of the pressure matrix from 1023. 
Using this method, the centroid when the creature is not moving and is in NoTouch position, is calculated to be (5.8, 2.7) which is around the middle of the sensor but more to the upper right corner which as Kerem pointed out is the actual place the extra pressure is mounted.

2. taking logarithm of the numbers in the matrix in base 2 and subtracting them all from 10.
Using this method, the centroid for the same position is calculated to be (5.3, 3.1) which is roughly equal to the other method of calculation but has moved to the right by 1 more block, getting closer to the black spot.

Tuesday, 2 April 2013

April 02 2013

To-Do-List:

Implementing the function to calculate the centroid of the pressure sensor.

Details:
The previous function calculated a number, but we were looking for an x and a y so I changed the function to calculate a position.
Running it as a test without touching the creature will give me position (4,8) as the centroid which does not seem too strange not being (3,5) since the wires are having extra pressure on the sensor and even without any touch we have a black spot at the very bottom of the map.
According to the picture though, one would guess that the centroid should be around (2,3) rather than (4,8). Reason for the seemingly wrong numbers is that the pressure map seems to have numbers that are inversely correlated with the pressure exerted. For example, when the creature is not touched (the above picture), the pressure associated is 0 for the black spot and on average 670 for the white spots.