Combine X and Y accelerations to calculate resultant angle and acceleration - math

Calculate resultant acceleration from x and y.
Calculate angle of resultant acceleration.

You can use vector maths to calculate the vector's length and angle:
length = sqrt(x * x + y * y)
angle = atan2(y, x) //this might be changed depending on your angle definitions

You dont need the x and y acceleration, just calculate the acceleration as speed change per time.
For Gps i reccommend to use the speed attribute of the location, which is much more accurate then the positions.
If you dont have speed, then calculate speed as distance per time.
Distance: use any distance formula you find for calculate distance between two lat/lon coordinates.
If you want to use the values you got from the acceleration sensor, then you should use 3-axis acceleration vector:
See also how-do-i-get-the-total-acceleration-from-3-axes
One further tipp to check if implementation is plausible:
Sum up all your (one dimension) accelerations, they shoud be near 0.

If you want the direction of the acceleration with respect to the world coordinate system, then you have to register for both TYPE_ACCELEROMETER and TYPE_MAGNETIC_FIELD. Using the results you call getRotationMatrix and then multiply the accelerometer values by this matrix will give you the coordinates of the acceleration in term of the world coordinate system. The first 2 coordinates would be the x and y coordinates.
Actually you better also register for TYPE_GRAVITY and pass the results together with the magnetic field results to the getRotationMatrix, so that you do not have to filter accelerometer values yourself.

Related

Average height of a point based on nearby points

I have a situation in my game. I am experimenting with terrain generation.
I have a bunch of peaks, whose position and elevation i know.
I have a point which is surrounded by all these peaks. I know its position. I am trying to calculate the elevation of this point.
I would like to calculate the height of this point, based on how close/far it is to each of these peaks, and the elevation of each of these peaks.
Example:
Peak 1 is at (0,0), with an elevation of 500
Peak 2 is at (100,100), with an elevation of 1000
Peak 3 is at (0,100), with an elevation of 750
If my point is at (99,99), i want the elevation of this point to be as close to 1000.
What is the name of this problem?
If you already have a solution to this, that too will be much appreciated.
Note: In addition, it will be helpful if the formula/equation also allows me to generate negative elevations. for example, a point midway between all the peaks could as well be under sea level. Any formula i can menatally think of usually gives me just positive results. I assume some kind of 'Slope' must be considered to allow this.
One equation i though of so far is
P1.height * (Sum of all distances - distance from P1)/(Sum of all distances) +
P2.height * (Sum of all distances - distance from P2)/(Sum of all distances) +
... Pn.height * (Sum of all distances - distance from Pn)/(Sum of all distances)
Thank you.
To draw the peaks your game needs to convert the coordinates of the peaks to screen coordinates.
Such calculation is usually done by multiplying a matrix with the vector containing the coordinates (in java AWT such matrix would be called a transform).
What you need is the inverse of that matrix so that you can apply it to your screen coordinates.
So the solution is:
get the matrix that is used for rendering the terrain
calculate the inverse matrix
apply it to your screen coordinates
And it might even be more efficient not to use the original matrix to calculate the inverse matrix but use the parameters (zero point, scale factors and rotation angle) which were used to calculate the original matrix. The same parameters can be used to calculate the inverse matrix.

Scale vector along plane

I'm trying to apply friction to a 3D collision. The information I have is:
The velocity of the collision
The surface normal of the collider
An arbitrary friction coefficient (0 - 1 inclusive)
What I would like to do is multiply the portion of the velocity that is parallel to the plane by the friction coefficient, while leaving the portion parallel to the normal intact.
How can I go about performing this operation?
I was thinking perhaps this will involve the use of the dot-product, but then I started reading about matrices, then vector projection, and now I'm pretty lost.
I was able to solve the problem by doing the following:
Get a tangent vector for the normal
Use the normal and the tangent vector to get a rotation matrix for the surface
Use the inverse of the rotation matrix to transform the velocity vector
Scale the x and z components of the transformed vector by the friction coefficient
Use the rotation matrix to transform the velocity back again
I doubt this is the most efficient way of doing it, but it seems to have worked.
If you can do vector addition, scalar multiplication (i.e. multiplying a vector by a number) and the dot product, then this is all you need:
Vin = (V•Vnormal)Vnormal
Vpar = V - Vin
Vpar = kVpar (where k is the coefficient, and "=" means assignment)
Vin = -Vin
V = Vin + Vpar

How to get the rotational speed around 2 axes by a given set of position vectors

I have a huge set of normalized position vectors. The vector-set is recorded by a special measurement device, while the device is rotate around two axes. Every position vector is also a combination of gravitational values for X, Y, and Z at a defined time. My assignment is to get the rotational speed of the both axes.
The coordinate system of the measurement device is rotated by circa 45° around the z-axis in relation to the coordinate system of machine.
The z-axis of the measurement device parallel to the z-axis of the machine.
I have tried to convert the carthesian coordinates to spherical coordinates. For this i used the Qt-Framework and MATLAB. As a result I got 2 angles and a radius. In my opinion the radius is not important. But the 2 angles don’t fit my problem, because I need the rotational speed of machine around the machine Z-axis and the X-axis. At this point it is important to know that the rotational speed is so slow that gravity-vector pointed always with 1g in to the ground. The X-,Y-, and Z-values of the measurement device represents the orientation subject to the gravity-vector . For example if the Z-axis pointed to the Ground the value is nearly 1. And if the axis is parallel to the ground (also orthogonal to the gravity-vecot) the value is nearly zero.
If the machine only rotates around the Z-axis I can get the period of one rotation very easy. The plot of the Y-values and X-values subject to the time is a sine or cosine. So I can get period by searching for the zero point, the maxima or the minima.
rotation around the z-axis
But this solution fit only the 1axis-problem. If the machine rotates additional around the X-axis the measured X-, Y-, and Z-values are combinations of both rotations. I have no idea how I can fix my problem.
rotation around the machines z-axis and x-axis: the rotation starts after 55s!
Another idea is the inverse kinematic but for this I need the dimensions of the machine and the exact point where the measurement device is mounted.
rotation around 1 axis
Dataset rotation around 1 axis
rotation around 2 axis
Dataset rotation around 2 axes
How can I start or go ahead?
I have tried to visualize the rotational process with this picture.
I tried to put this in as a comment, but there is a length limit there. So, some clarifying questions / intermediate conclusions:
Thanks for the figures! So it looks from your 4th figure above, the one showing 2-axis x-y-z sine waves, and from your diagram of the machine, like you have three coordinate systems: The first is the earth frame, call it x1,y1,z1, as you show it in "machine picture" diagram. The second frame call it x2,y2,z2 rotates about both the x1 and the x2 axes (they remain parallel). The third frame x3,y3,z3 is the one that rotates about the z2 (=z3) axis. Your accelerometers are fixed in the x3,y3,z3 coordinate frame.
Your single-axis data set has z3=z2 aligned with earth z1, and spins about z, so that x3 and y3 spin around sampling gravity in quadrature sine waves.
In your second data set, the outer gimbal x1=x2 rotates at a constant rate, giving rise to the perfect sine wave on the z accelerometer, while the inner z3=z2 gimbal also spins perhaps at a constant rate, but now the accelerometers on x3 and y3 have their amplitudes modulated by multiplying by the cosine of the x1/x2 rotation angle.
Does all this sound right?
One other thing we always need to know when estimating velocity from position measurements is some kind of model or concept of how your system changes in time: Can we assume some maximum angular acceleration? Or can we assume that once the rotation(s) come up to speed, that they are constant? That will become especially important in trying to stitch the z2/z3 gimbal angle over the times when the x1/x2 angle passes through +/-pi/2 radians, where the z2/z3 angle becomes momentarily unobservable because the x and y accelerometers are orthogonal to the gravity vector and will just show noise. It will also help us to decide if the x1/x2 gimbal went up to pi/2 and back down again, or kept turning in the same direction to > pi/2, because both motions look the same on the z accelerometer, and the z2/z3 angle is unobservable there.
Simple answer:
Use two-argument arctangent.
The roll angle is atan2(ay, ax).
The pitch angle is atan2(az, sqrt(ax*ax + ay*ay)).
Then time-difference these to get angle rates.
This oversimplified solution has a number of problems, but it's a good place to start.
Probably the key you need is this: You must transform the x and y accelerations from measurement coordinates to machine coordinates before estimating the pitch about the machine x axis. This requires you to first know the roll angle (about the machine z axis). In matlab sytax,
[x_machine; y_machine] = [cos(roll) -sin(roll); sin(roll) cos(roll)] * [x_meas; y_meas].
z_machine = z_meas, always.
Given x,y,z in machine coordinates, you can directly estimate the pitch angle and rate about the machine x axis:
pitch = atan2(z_machine, -y_machine) (right hand rule about the machine x axis; positive acceleration pointing down);
pitch_rate = -asin((xyz_i cross xyz_i-1)_x) / dt_i,
where in English, the rate is computed from the arcsine of the x_machine component of the cross product of the latest machine coordinate acceleration vector with the previous one, divided by the time between them (1/8 of a second in your case).
The same approach works for estimating roll and roll rate (about the machine z axis):
roll = atan2(-x_meas, -y_meas) * cos(pitch) / abs(cos(pitch));
roll_rate = -asin((xyz_meas_i cross xyz_meas_i-1)_z) * cos(pitch) / abs(cos(pitch)) / dt_i.
It is a chicken-and-egg problem, where you need to know the pitch and roll to estimate pitch and roll and their rates. So you need to start off with a good guess of the correct pitch and roll angles (to within 15 degrees or so should be fine).
All of the measurements are noisy, so the estimates will be also. The rate estimates especially so. So you will want to filter the estimates in time. Propagate your pitch and roll angle estimates in time using your filtered angle rate estimates.
Also, your roll angle and rate estimates become pure noise as pitch is near +/-pi/2, so you should probably weight down the inputs to the roll filters by something like cos^2(pitch).

How to convert Yaw, Pitch, Roll and Acceleration value to cartesian system?

I am having readings of Yaw, pitch, Roll, Rotation matrix, Quaternion and Acceleration. These reading are taken with frequency of 20 (per second). They are collected from the mobile device which is moving in 3D space from one position to other position.
I am setting reference plane by multiplying inverse matrix to the start postion. The rest of the readings are taken by considering the first one as a reference one. Now I want to convert these readings to 3D cartesian system.
How to convert it? Can anyone please help?
Ok basically yaw, pitch and roll are the euler angles, with them you got your rotation matrix already.
Quaternions are aquivalent to that, with them you can also calculate the rotation matrix you need.
If you have rotation matrices R_i for every moment i in your l=20secs interval. Than these rotations are relative the the one applied at R_(i-1) you can calculate their rotation relative to the first position. So A_i = R_1*...*R_i but after all you could also just safe the new direction of travel (safes calculations).
So asuming that the direction of travel is d_0 = (1,0,0) at first. You can calculate the next by d_i = R_i*d_(i-1) (always norm d_(i-1) because it might get smaller or bigger due to error). The first position is p and your start speed is v_0 = (0,0,0) and finally the acceleration is a_i. You need to calculate the vectorial speed v_i for every moment:
v_i = v_(i-1) + l*a_i*A_i*d_0 = v_(i-1) + l*a_i*d_i
Now you basically know where you are moving, and what kind of speed you use, so your position p_i at the moment i is given by:
`p_i = p_0 + l * ( v_1 + v_2 + ... + v_i)`
For the units:
a_i = [m/s^2]^3
v_i = [m/s]^3
p_i = [m]^3
Precision
Now some points to the precision of your position calculation (just if you want to know how good it will work). Suppose you have an error e>= ||R_i*v-w|| (where w is the correct vector). in the data you calculate the rotation matrices with. Your error is multipling itself so your error in the i moment is e_i <= e^i.
Then because you apply l and a_i to it, it becomes:
f_i <= l*a_i*e^i
But you are also adding up the error when you add up the speed, so now its g_i <= f_1+...+f_i. And yeah you also add up for the position (both sums over i):
h_i <= g_1+...+g_i = ΣΣ (l*a_i*e^i) = l* ΣΣ (a_i*e^i)
So this is basically the maximum difference from your position p_i to the correct position w (||p_i - w|| <= h_i).
This is still not taking in account that you don't get the correct acceleration from your device (I don't know how they normally do this), because correct would be:
a_i = ||∫a_i(t) dt|| (where a_i(t) is vectorial now)
And you would need to calculate the difference in direction (your rotation matrix) as:
Δd_i = (∫a_i(t) dt)/a_i (again a_i(t) is vectorial)
So apart from the errors you get from the error in your rotations from your device (and from floating point arithmetic), you have an error in your acceleration, I won't calculate that now but you would substitute a_i = a_i + b_i.
So I'm pretty sure it will be far off from the real position. You even have to take in account that you're speed might be non zero when it should be!
But that beeing said, I would really like to know the precision you get after implementing it, that's what always keept me from trying it.

Triangulating GPS coordinates

Say you have n GPS coordinates how could you work out the central GPS point between them?
In case it helps anyone now or in the future, here's an algorithm that's valid even for points near the poles (if it's valid at all, i.e. if I haven't made a silly math mistake ;-):
Convert the latitude/longitude coordinates to 3D Cartesian coordinates:
x = cos(lat) * cos(lon)
y = cos(lat) * sin(lon)
z = sin(lat)
Compute the average of x, the average of y, and the average of z:
x_avg = sum(x) / count(x)
y_avg = sum(y) / count(y)
z_avg = sum(z) / count(z)
Convert that direction back to latitude and longitude:
lat_avg = arctan(z_avg / sqrt(x_avg ** 2 + y_avg ** 2))
lon_avg = arctan(y_avg / x_avg)
Depends on what you mean by the central GPS point. You could simply take the average of all the points, as suggested by Stephen - but keep in mind that GPS coordinates are not continuous - this will fail spectacularly around discontinuities such as the poles.
In most cases you'll need to convert to a coordinate system that doesn't have this issue.
You could also look at all the points bounded by it, calculated all the distances to each GPS point, and minimize the sum of the distances to all the GPS points. You'll need to look into great circle calculations for this.
Further, each GPS might have a higher or lower degree of uncertainty, you should take that into account and weight them accordingly.
What exactly are you trying to find out?
-Adam

Resources