Questions:
Hey there I have a pic16f882 and an MMA7360L accelerometer and i'm trying to convert the x and y axis readings into vectors to be able to calculate the accelerometers position from a given point at any given time. I already have the readings stored from the accelerometer but i'm not sure how i would now go about integrating these to reach position. Any help would be greatly appreciated, thanks in advance, ali
Code:
Method 2B. Accurate to -1.2%..+0.8%. Requires up to four constant multiplies.
This method refines Levitt/Morris method.
int magnitude2B(int x, int y)
{
int mx;
int mn;
x = abs(x);
y = abs(y);
mx = max(x, y);
mn = min(x, y);
if(mx >= 3*mn)
return mx + mn/8;
else if (mx >= 5/4*mn)
return mx*7/8 + mn/2;
else
return mx*3/4 + mn*21/32;
}
There are several approximate methods for finding magnitude. They vary in their
complexity and accuracy. Here is a list of some options:
Method 1. Accurate up to -0..+8%. Requires a multiply by a constant.
int magnitude_Robertson(int x, int y)
{
int mx;
int mn;
x = abs(x);
y = abs(y);
mx = max(x, y);
mn = min(x, y);
return mx + mn*k;
}
The method is apparently due to:
Robertson, G.H., "A Fast Amplitude Approximation for Quadrature Pairs", Bell Sys. Tech. J.,
Vol. 50, Oct. 1971, pp.2849-2852.
The constant k is chosen to minimize error in one of different ways (average error, absolute error,
peak-to-peak error, standard deviation, etc) and efficient to compute the multiply.
A few examples:
1/2, 3/8, 1/4: suggested by Robertson
sqrt(2)-1 ~= 106/256: minimizes p-p error (also, zero error at multiples of 45 deg)
Method 2. Accurate to 2.8%. Requires three constant multiplies.
int magnitude_Levitt(int x, int y)
{
int mx;
int mn;
x = abs(x);
y = abs(y);
mx = max(x, y);
mn = min(x, y);
if(mx >= 3*mn)
return mx + mn/8;
else
return mx*7/8 + mn/2;
}
See B.K Levitt, G.A. Morris, "An Improved Digital Algorithm for Fast Amplitude
Approximations of Quadrature Pairs", DSN Progress Report 42-40, May and June 1977, pp 97-101.
<a href="http://tmo.jpl.nasa.gov/progress_report2/42-40/40L.PDF">http://tmo.jpl.nasa.gov/progress_report2/42-40/40L.PDF</a>
Method 3. Accurate up to -1.5%...+0%. Requires a divide, multiply, and a constant multiply.
int magnitude3(int x, int y)
{
int mx;
int mn;
x = abs(x);
y = abs(y);
mx = max(x, y);
mn = min(x, y);
if(mx == 0)
return mx;
return mx + mn*mn/mx*k;
}
The constant k is chosen similarly to method 1. For example, k=sqrt(2)-1~=106/256 again
minimizes the p-p error. The method is due to Nikolai Golovchenko. :)
Method 4. Accurate up to -0.5%..+0%. Requires a divide, multiply, and two constant multiplies.
This is a piecewise refinement of method 3. Vector (x,y) is assumed to be
rotated to the range of 0 to 45 deg (i.e. x=mx and y=mn as in examples above)
b = y/x
if b <= 0.5
b += b * 0.14 // ~5/32
else
b += (1-b) * 0.14
r = x + y * b * 106/256
Method 5: Theoretically arbitrary accuracy. Requires a divide and two multiplies.
r = x + y * lookup(y/x)
lookup() - a function that represents a table with linear interpolation.