Find the pivot angle using location
I need to find the steering angle of a vehicle, measured in degrees.
Updating location points at regular intervals (1 s). Therefore, during the turn, the device makes 4-5 points. I schematically depicted this in the picture.
Is it possible to calculate the rotation angle using Location? If possible, how?
What I have tried:
- Create two geometric vectors from points 3, 4 and 1, 2 respectively and find the angle between these vectors. The coordinates of the vectors that I calculated as
Vector1 (lat2 - lat1; lon2 - lon2)
. Not sure if this approach can be applied to location coordinates. - Use
location1.bearingTo(location2)
. But this does not give the expected results. It looks like it gives "compass" results. I could somehow use the perkhabs, but I'm not sure. - Also tried a few trigonometric formulas like here or here or. They didn't give the expected angle.
EDIT: Solution
The accepted answer works great. But to complete the answer, I have to show this method angleDifference
. This works for me:
public int getAngleDifference(int currentAngle){
int r = 0;
angleList.add(currentAngle);
if (angleList.size() == 4) {
int d = Math.abs(angleList.get(0) - angleList.get(3)) % 360;
r = d > 180 ? 360 - d : d;
angleList.clear();
}
return r;
}
I add points to the list until there are 4 and then calculate the difference in angles between the 1st and 4th points to get the best results.
Hope this helps someone!
source to share
Approach 1 does not work as you described: Lat, Lon are not Cartesian coordinates (one degree of longitude expressed in meters is not one degree of latitid, this is only true at the equator). You first had to convert to a (local) cartesian system.
Error in the drawing: Angle indicated by "?" is on the wrong side. Most likely, you need an angle: 180 -? In your example, the car is getting less than 90 ° even though your angle is showing more than 90 °. To better understand, draw another drawing where the car turns to the left just 10 degrees. In your drawing it will be 170 °, which is not correct.
Approach 2) works better, but you need to sum the angle differences. You have to write yourself a method
double angleDifference(double angle1, double angle2);
It looks simpler than this, although the code is only a few lines long. Make sure you have some test cases that test the 360 ° crossing behavior. Example
(pivot from bearing 10 to bearing 350) should either give 20 or -20, depending on whether you want the method to give an absolute estimate or a relative angle
source to share
vect1 = LatLon2 - LatLon1; // vector subtraction
vect2 = LatLon4 - LatLon3;
By definition of a dot product, it has the property:
vect1.vect2 = ||vect1||*||vect2||*Cos(theta)
Here the notation breaks down
The term vect1.vect2
is the dot product vect1
and vect2
.
The general view of the dot product can be divided into components w v1 = <x1,y1>
and v2=<x2,y2>
for two arbitrary vectors v1
and the v2
dot product will be:
v1.v2 = x1*x2 + y1*y2
and the value of some arbitrary vector v
is:
||v|| = sqrt(v.v); which is a scalar.
The above is equivalent to the Euclidean distance formula with x and y components:
||v|| = sqrt(x^2 + y^2)
Getting an angle
Find the value for theta
given two vectors vect1
and vect2
:
theta = Math.ArcCos(vect1.vect2/(||vect1||*||vect2||))
source to share