How convert raw data to useful angles? - c

I use Gyro L3GD20 and STM32F4 microcontroller. I get this data from gyro sensor.
0, -1, -1, -2, -3, -4, -5, -6, -6, -5, -3, -4, -4, -5, -6, -5, -3, -3, -3, -3, -3, -4, -4, -4, -3, -3, -3, -3, -5, -5, -5,
-4, -4, -4, -5, -5, -6, -6, -5, -5, -6, -6, -8, -9, -10, -10, -11, -12, -14, -16, -17, -16, -14, -12, -11, -10, -8, -7, -8,
-8, -8, -8, -6, -5, -4, -4, -2, -2, -3, -2, -2, -2, -2, -1, -2, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3,
4, 4, 4, 5, 6, 6, 6, 7, 8, 8, 9, 9, 8, 9, 10, 12, 15, 19, 17, 13, 9, 9, 14, 19, 8, 15, 15, 17, 17, 18, 17, 14, 14, 15, 15,
11, 7, 5, 5, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
This relates to the angular-velocity along the x-axis.
I would like to extract angle from raw data.
Piece of code
while(1)
{
if(measure)
{
///20 ms///.
L3GD20_Read(&L3GD20_Data);
int16_t x = L3GD20_Data.X;
USART_putint(USART2, _x, 10);
USART_SendData(USART2, ',');
measure = 0;
}
}
Thank You in advance.

A MEMS gyroscope is an angular velocity sensor where the output proportional to degrees-per-second. To obtain relatve orientation from angular-velocity, you must integrate over time, which will get you the change in angle over that time. Essentially the change in angle is proportional to the sum of all angular-velocity samples.
The L3GD20 is a three-axis sensor so can provide output for yaw, pitch and roll. It has an I2C/SPI digital interface and performs the sampling and timing for you, and places the data in a FIFO, so you probably should not second guess that timing by only reading at 20ms intervals; rather you should read all available data in response to the data-ready interrupt. (The mimimum output data rate of the part is 95 samples per second, so you are loosing data when reading at 50sps). How you do that depends on the API you are using. It has programmable sensitivity of 250, 500 or 2000 degrees per second; you should use the lowest value practical to get the highest resolution.
#define GYRO_FS_DPS 250
#define GYRO_ABS_SAMPLE_MAX 0x7fff
long x_integrator = 0 ;
while(1)
{
while( /* L3GD20 data available */ )
{
L3GD20_Read( &L3GD20_Data ) ;
x_integrator += L3GD20_Data.X ;
}
...
}
Then relative orientation in degrees is determined at any time by:
orientation = ((x_integrator * GYRO_FS_DPS) / GYRO_ABS_SAMPLE_MAX) % 360 ;
Ultimately you need to clearly understand the part's datsheet, it is a very flexible and configurable part and exactly how you process its data will depend a great deal on how you have set it up.

Related

Finding the index of the minimum value in a list of arrays

Let's say I have a list with multiple arrays:
L = [
array([-10, -8, -3, 2, 1]),
array([-9, -4, -1, 3, 5]),
array([-11, -5, -4, 0, 10])
]
How can I find the index of the lowest value the most efficiently?
For my example, the minimum value is -11 and the index is (2, 0), so the output should be (0, 2).
What about the following?
import numpy as np
L = [
np.array([-10, -8, -3, 2, 1]),
np.array([-9, -4, -1, 3, 5]),
np.array([-11, -5, -4, 0, 10])
]
L_2d = np.array(L)
min_index = np.unravel_index(L_2d.argmin(), L_2d.shape)
(min_index[0], min_index[1])

Find the difference between all integers in an array

I have an array of integers in Ruby. I want to find the differences between each number and every other number.
I can do it with one of the integers and find the difference between it and all the other numbers but I can't work out how to iterate twice per se.
Here is what I have:
def stock_picker(ary)
ary.map {|a| ary[0] - a }
end
stock_picker [1, 2, 3, 4, 5]
#=> [0, -1, -2, -3, -4]
When I run the above for ary[1] instead of ary[0] I get:
[1, 0, -1, -2, -3]
For ary[2] it's:
[2, 1, 0, -1, -2]
and so on. But How can I generate the differences for all numbers in ary regardless of its size?
The expected result is:
[0, -1, -2, -3, -4, 1, 0, -1, -2, -3, 2, 1, 0, -1, -2, 3, 2, 1, 0, -1, 4, 3, 2, 1, 0]
More compact version:
arr.product(arr).map { |a,b| a - b }
It appears you want the following.
def doit(arr)
arr.flat_map { |n| arr.map { |m| n-m } }
end
doit [1, 2, 3, 4, 5]
#=> [0, -1, -2, -3, -4, 1, 0, -1, -2, -3, 2, 1,
# 0, -1, -2, 3, 2, 1, 0, -1, 4, 3, 2, 1, 0]
See Enumerable#flat_map.

Select columns in numpy

Assumes there is an index and a matrix L
>>> index
(array([0, 2, 3, 3]), array([0, 2, 2, 3]))
>>> L
array([[ 1, -1, -5, -10],
[-15, 0, -1, -5],
[-10, -15, 10, -1],
[ -5, -10, 1, 15]])
I want to select the columns according to the index[1], I've tried:
>>> L[:,index[1]]
array([[ 1, -5, -5, -10],
[-15, -1, -1, -5],
[-10, 10, 10, -1],
[ -5, 1, 1, 15]])
but the result is not i expected, what I expected is:
>>> for i in index[1]:
... print L[:,i]
[ 1 -15 -10 -5]
[-5 -1 10 1]
[-5 -1 10 1]
[-10 -5 -1 15]
How can i get the expected result without for loop? and why this unexpected result comes out? Thanks.
You simply need to transpose it:
L[:,index[1]].T
# ^ transpose
By using a transpose, the columns are rows and vice versa. So here (you can transpose before the selection, and then use L.T[index[1],:]) we first make the selection and then turn the columns into rows.
This produces:
>>> L[:,index[1]].T
array([[ 1, -15, -10, -5],
[ -5, -1, 10, 1],
[ -5, -1, 10, 1],
[-10, -5, -1, 15]])
Note that of course behind the curtains there are still some loops that are done. But these are done outside Python and thus are more efficient.

Efficient way of doing numerical integration on a 2d array with variable integration length

I asked a question here about numerically integrating on a 2d array with fixed length. Now what if the integration length is not fixed? For each cell as the starting point, I want to keep integrating until it encounters a cell with value of the opposite sign. So suppose in a column from bottom to top it is [1,2,5,4,-2,-3,2], if I do the integral for the first element, it will integrate the first four elements (they are all positive). If I start from the fifth element, it will just integrate -2 and -3. Are there any ways to vectorize it or speed it up instead of using a double for loop to first find the integration length for each cell and then do the integral?
Or a simplified problem is just to integrate the positive elements:
example:
data = [
-2, -1, 4, -2,-1;
1, 2, 3, 4, 5;
5, -4, -3, 2, 5;
3, -3, -9, 5, 7;
2, -2, 7, -5, 1;
2, 3, 1, -3, -3]
integrated_data = [
0, 0, 7, 0, 0;
13, 2, 3, 11, 18;
12, 0, 0 7, 13;
7, 0, 0, 5, 8;
4, 0, 8, 0, 1;
2, 3, 1, 0, 0]
A vectorization solution in MATLAB
data = [
-2, -1, 4, -2,-1;
1, 2, 3, 4, 5;
5, -4, -3, 2, 5;
3, -3, -9, 5, 7;
2, -2, 7, -5, 1;
2, 3, 1, -3, -3];
data1 = [-ones(1,size(data,2)) ;flipud(data)]
df = find([-1 ;diff((data1(:))>=0)] == 1)-1;
data1(data1<0) =0;
c1 = cumsum(data1(:));
data1(df) = data1(df) - [0 ;diff(c1(df))];
c2 = cumsum(data1(:));
c2(data1==0)=0;
c2=reshape(c2,size(data1));
result = flipud(c2(2:end,:))

Python Array append vectors and then sum the elements of the array positionwise (not elementwise)

first of all I explain what I would like to do. I have a function which gives me some lists. These lists have the same number of elements and they contain numbers, which represents positions on the x-axis. For example one of them is [-11, -6, -5, -4, -1, 1, 3, 4, 6, 7], another one is [-11, -6, -5, -3, -1, 1, 2, 4, 5, 7]. The entries will always be integers and in ascending order.
I want to run this function many times and at the end "sum-up" all these vectors in a particular way. Imagine that each vector shows the position of a person in the x-axis. I want to know, at the end of say q experiments, how many people there are in each position. However, they do not all start from -11 or end at 7.
For example [-13, -8, -3, -1, 0, 1, 2, 4, 5, 7] or [-12, -7, -2, -1, 0, 1, 3, 4, 5, 6] are other two valid output from the function.
How can I do that?
My idea was to create a loop, compute the function, and store these lists into an array and then use some weird matrix operation. However I am absolutely stuck, this is my attempt, where rep_assign_time2(n,p,m) is the function that gives me the lists:
def many_experiments(n,p,m,q):
jj = 0
vector_min = []
vector_max = []
a = np.array([])
while jj < q:
s = rep_assign_time2(n,p,m)
a = np.concatenate((a,s), axis = 0) # I add s as an element of a
for k in range(a.shape):
ma = max(a[k])
mi = min(a[k])
vector_min.append(mi)
vector_max.append(ma)
minimum = min(vector_min)
maximum = max(vector_max)
And then I have NO IDEA on how to create an operation that does what I want. I've been thinking for an hour and still no clue. Do you have any idea?
You are in luck with NumPy, as there's a built-in for it as np.unique. It gives us both such unique labels (axis positions in this case) and their counts at each such label. So, let's say you have the lists stored as a list, thus a list of lists as A, you could simply do -
unq,counts = np.unique(A,return_counts=True)
Sample run -
In [33]: A = [[-11, -6, -5, -4, -1, 1, 3, 4, 6, 7], \
...: [-11, -6, -5, -3, -1, 1, 2, 4, 5, 7],\
...: [-13, -8, -3, -1, 0, 1, 2, 4, 5, 7],\
...: [-12, -7, -2, -1, 0, 1, 3, 4, 5, 6]]
In [34]: unq,counts = np.unique(A,return_counts=True)
In [35]: unq
Out[35]:
array([-13, -12, -11, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1,
2, 3, 4, 5, 6, 7])
In [36]: counts
Out[36]: array([1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 4, 2, 4, 2, 2, 4, 3, 2, 3])
In [40]: import matplotlib.pyplot as plt
In [41]: # Plot the results
...: plt.bar(unq, counts, align='center')
...: plt.grid()
...: plt.show()
...:

Resources