How to identify whether compass is heading towards the location or not? - iphone

I am developing a project in augmented reality where a compass shows the direction to the destination.That works fine but i want to check whether the current heading is pointing towards the destination or not.
Can any one suggest me a method to do it?
I have searched a lot in Google couldn't find any method?
Thanks in advance

You need the absolute bearing from your location to your target location
Unfortunately CLLocation doesn't have a call for this but you can find the algo in this question.
CLLocation Category for Calculating Bearing w/ Haversine function
So lets say the bearing is 90 degrees
Then you get the phone bearing to north.
While you are getting location updates you also have course update with CLLocation.
The course might also be 90 degrees
SO find the difference between the two, 90 - 90 = 0! you are dead on target :) You will need to rationalise the numbers to 0 - 360 in the event say you are facing north (0 degrees) and your target is behind you (180 degrees) resulting in -180. If you end up with a negative number just add 360.
I find the magnetic field compass to be very very fidgety, so it looks much nicer if you have some sort of exponential moving average for changes in the phones bearing.

Related

iOS is it possible to convert CLLocation into some sort of XYZ metric coordinate system?

I'm building an augmented reality game, and working with CLLocation is rather cumbersome.
Is there some way to locally approximate CLLocation as XYZ coordinate, expressed in meters with the origin starting at some arbitrary point (for example the initial position when the game was started)?
Lets say I'm working with a 1 mile radius and do not really care about the curvature of the earth. Is it possible to approximate or somehow simplify the location based calculations for local position tracking?
Alternatively, is there a coordinate system that can be used with CLLocation that also incorporates the roll, pitch, yaw of the CMAttitude as well as compass orientation?
Clarification: As far as I understand, the problem with latitude and longitude is that their units vary in size, depending on the position on the globe. I should've specified that X,Y,Z should be in standard units, like meters or feet.
Thank you!
The Haversine formula may be useful.
I found a good article on it at http://www.jaimerios.com/?p=39 with code examples.
You could get the initial point at the app's launch and calculate the relative points based on the user coordinates as he or she moves. Admittedly, this is not super elegant, but if you are just trying to do some simple comparisons based on the user's location relative to an arbitrary origin, this should work. For the Z, Alex Stone's suggestion of calculating it based on the altitude should be fine.

Maths behind iPhone AR ToolKit

I'm using iPhone ARToolkit and I'm wondering how it works.
I want to know how with a destination location, a user location and a compass, this toolkit can know it user is looking to that destination.
How can I know the maths behind this calculations?
The maths that AR ToolKit uses is basic trigonometry. It doesn't use the technique that Thomas describes which I think would be a better approach (apart from step 5. See below)
Overview of the steps involved.
The iPhone's GPS supplies the device's location and you already have the coordinates of the location you want to look at.
First it calculates the difference between the latitude and the longitude values of the two points. These two difference measurements mean you can construct a right-angled triangle and calculate what angle from your current position another given position is. This is the relevant code:
- (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second {
float longitudinalDifference = second.longitude - first.longitude;
float latitudinalDifference = second.latitude - first.latitude;
float possibleAzimuth = (M_PI * .5f) - atan(latitudinalDifference / longitudinalDifference);
if (longitudinalDifference > 0) return possibleAzimuth;
else if (longitudinalDifference < 0) return possibleAzimuth + M_PI;
else if (latitudinalDifference < 0) return M_PI;
return 0.0f;
}
At this point you can then read the compass value from the phone and determine what specific compass angle(azimuth) your device is pointing at. The reading from the compass will be the angle directly in the center of the camera's view. The AR ToolKit then calculates the full range of angle's currently displayed on screen as the iPhone's field of view is known.
In particular it does this by calculating what the angle of the leftmost part of the view is showing:
double leftAzimuth = centerAzimuth - VIEWPORT_WIDTH_RADIANS / 2.0;
if (leftAzimuth < 0.0) {
leftAzimuth = 2 * M_PI + leftAzimuth;
}
And then calculates the right most:
double rightAzimuth = centerAzimuth + VIEWPORT_WIDTH_RADIANS / 2.0;
if (rightAzimuth > 2 * M_PI) {
rightAzimuth = rightAzimuth - 2 * M_PI;
}
We now have:
The angle relative to our current position of something we want to display
A range of angles which are currently visible on the screen
This is enough to plot a marker on the screen in the correct position (kind of...see problems section below)
It also does similar calculations related to the devices inclination so if you look at the sky you hopefully won't see a city marker up there and if you point it at your feet you should in theory see cities on the opposite side of the planet. There are problems with these calculation in this toolkit however.
The problems...
Device orientation is not perfect
The value I've just explained the calculation of assumes you're holding the device in an exact position relative to the earth. i.e. perfectly landscape or portrait. Your user probably won't always be doing that. If you tilt the device slightly your horizon line will no longer be horizontal on screen.
The earth is actually 3D!
The earth is 3-dimensional. Few of the calculations in the toolkit account for that. The calculations it performs are only really accurate when you're pointing the device towards the horizon.
For example if you try to plot a point on the opposite side of the globe (directly under your feet) this toolkit behaves very strangely. The approach used to calculate the azimuth range on screen is only valid when looking at the horizon. If you point your camera at the floor you can actually see every single compass point. The toolkit however, thinks you're still only looking at compass reading ± (width of view / 2). If you rotate on the spot you'll see your marker move to edge of the screen, disappear and then reappear on the other side. What you would expect to see is the marker stay on screen as you rotate.
The solution
I've recently implemented an app with AR which I initially hoped AR Toolkit would do the heavy lifting for me. I came across the problems just described which aren't acceptable for my app so had to roll my own.
Thomas' approach is a good method up to point 5 which as I explained above only works when pointing towards the horizon. If you need to plot anything outside of that it breaks down. In my case I have to plot objects that are overhead so it's completely unsuitable.
I addressed this by using OpenGL ES to plot my markers where they actually are in 3D space and move the OpenGL viewport around according to readings from the gyroscope while continuously re-calibrating against the compass. The 3D engine handles all the hard work of determining what's on screen.
Hope that's enough to get you started. I wish I could provide more detail than that but short of posting a lot of hacky code I can't. This approach however did address both problems described above. I hope to open source that part of my code at some point but it's very rough and coupled to my problem domain at the moment.
that is all information needed. with iphone-location and destination-location you can calculate the destination-angle (with respect to true north).
The only missing thing is to know where the iPhone is currently looking at which is returned by the compass (magnetic north + current location -> true north).
edit: Calculations: (this is just an idea: there may exist a better solution without a lot coordinate-transformations)
convert current and destination location to ecef-coordinates
transform destination ecef coordinate to enu (east, north, up) local coordinate system with current location as reference location. You can also use this.
ignore the height-value and use the enu-coordinate to get the direction: atan2(deast, dnorth)
The compass returns already the angle the iPhone is looking at
display the destination on the screen if dest_angle - 10° <= compass_angle <= dest_angle + 10°
with respect to the cyclic-angle-space. The constant of 10° is just a guessed value. You should either try some values to find out a useful one or you have to analyse some properties of the iPhone-camera.
The coordinate-transformation-equations become much simpler if you assume that the earth is a sphere and not an ellipsoid. Most links if have postet are assuming an wgs-84 ellipsoid becasue gps also does afaik).

IOS Core location - Find out nearest branch

I have create a program to find out my current location using IOS corelocation framework.It works fine.
I need to create a program that list nearest branchaes of a shop chain, while a user travel with the phone.My data base contains the branches details with Latitude and lognitude.How i compare with these details to find out the nearest branch.
Help is highly appreciated.Anybody knows any example program
Thanks,
VKS
You can make use of distanceFromLocation: method of CLLocation.
distanceFromLocation:
Returns the distance (in meters) from the receiver’s location to the
specified location.
(CLLocationDistance)distanceFromLocation:(const CLLocation
*)location
Parameters
location
The other location.
Return Value
The distance (in meters) between the two locations.
Discussion
This method measures the distance between the two locations by tracing
a line between them that follows the curvature of the Earth. The
resulting arc is a smooth curve and does not take into account
specific altitude changes between the two locations.
Availability
Available in iOS 3.2 and later.
By using this method to get the distances of the shops with your current location, you can then sort the list based on the distance to get the nearest branch
VKS, I got to solve the exact same problem too now (using apptarget iOS 5). Do you have any example code / snippets / tips to share for this problem, that I assumed you solved a long time ago? The above is very good explanation from 7KV7, but some examples will speed up my process a lot. Thank's :-)

How can we find the angle between two locations defined by latitude or longitude

I do not want any code but want to get reference that how can we find the angle between two locations defined by Latitude or Longitude...
If you do have reference then Please help me to solve my problem...
Thanx in advance....
The formula to calculate bearing is:
θ = atan2( sin(Δlong).cos(lat2), cos(lat1).sin(lat2) − sin(lat1).cos(lat2).cos(Δlong) )
Bearing is a direction to move from one location to another location (starting from north and then clockwise). While angle in 2D starts from the east and then counter clockwise. So if an angle is what you need, later you'll need to add 90 degree to the result and then revert it (add minus).
Reference:
http://www.movable-type.co.uk/scripts/latlong.html
try the Atan method
Math.Atan2(x1-x2,y1-y2)
Try this website, it does all the calculations for you. Whereas the formulas, those can be found on wiki or any other sites. I like this site cos it managed to help me settle a lot of problems. And even if this web tool was developed in San Francisco, even I am from Singapore. This will work.
Latitude and Longitude web tool

How to detect if device is headed towards a specific point direction

I have my current location from CLLocation,
and I have another location- also an CLLocation.
I would like to detect when my device is heading towards that other location.
(I can calculate the distance in meters between this points- but can't workout
the calculation of an accurate angle to compare with the device current heading)
Thanks.
How about using CLLocation's built-in course property?
To Be deleted
One approach could be to continuously calculate the distance between current location and target location. if the distance decreases, your device is moving towards the the target.
In a real world szenario (car in city, car in mountainous country e.g. Switzerland) this doesn't work. You would need some array of way-points (e.g. intersections) that lead towards the target and continuosly look for the closest waypoint.