I found this issue with distanceFromLocation function where the return value is not accurate. Please confirm if I did it wrongly or the function is buggy.
CLLocation *locA = [[CLLocation alloc] initWithLatitude:5.321008 longitude:100.290131];
CLLocation *locB = [[CLLocation alloc] initWithLatitude:5.321008 longitude:100.290138];
CLLocationDistance distance = [locA distanceFromLocation:locB];
NSLog(#"distance: %f, locA: %f,%f, locB: %f,%f",distance,locA.coordinate.latitude,locA.coordinate.longitude,locB.coordinate.latitude,locB.coordinate.longitude);
The output is:
distance: 0.775644, locA: 5.321008,100.290131, locB: 5.321008,100.290138
Both locations are near and should be less than 10 meters. However, the function return larger distance. Checked with site such as http://jan.ucc.nau.edu/~cvm/latlongdist.html and the distance should be:
Distance between 5.321008N 100.290131E and 5.321008N 100.290138E is 0.0008 km
Your answer is in meters if you convert it to kilemeters you get 0.000775 km which is roughly the same. see reference documentation from apple for more.
This is a GPS issue with iPhones, not a coding problem.
Since iphones are meant primarily to do other things, the maker does not put in heavy duty GPS chips - like Sirf Star III, for example. This would kill battery lifetime. Instead the phone relies partially on another protocol mandated for cell phones since 9/11, which calculates distance from cell towers and does trilateration to get an approximate value. Trilateration works in conjuction with the the weaker GPS chipset, if the chipset can find 4 satellites. The result is that iphones often are of by more than 40 feet when using the GPS function. BTW normal hand-held GPS units like Garmin (not surveryors differential GPS units) often are off by as much as 2-3 meters.
Look up differential GPS on Wikipedia to get more on this.
Related
I'm trying to track the distance a user has moved over time in my application using the GPS. I have the basic idea in place, so I store the previous location and when a new GPS location is sent I calculate the distance between them, and add that to the total distance. So far so good.
There are two big issues with this simple implementation:
Since the GPS is inacurate, when the user moves, the GPS points will not be a straight line but more of a "zig zag" pattern making it look like the user has moved longer than he actually have moved.
Also a accuracy problem. If the phone just lays on the table and polls GPS possitions, the answer is usually a couple of meters different every time, so you see the meters start accumulating even when the phone is laying still.
Both of these makes the tracking useless of coruse, since the number I'm providing is nowwhere near accurate enough.
But I guess that this problem is solvable since there are a lot of fitness trackers and similar out there that does track distance from GPS. I guess they do some kind of interpolation between the GPS values or something like that? I guess that won't be 100% accurate either, but probably good enough for my usage.
So what I'm after is basically a algorithm where I can put in my GPS positions, and get as good approximation of distance travelled as possible.
Note that I cannot presume that the user will follow roads, so I cannot use the Google Distance Matrix API or similar for this.
This is a common problem with the position data that is produced by GPS receivers. A typical consumer grade receiver that I have used has a position accuracy defined as a CEP of 2.5 metres. This means that for a stationary receiver in a "perfect" sky view environment over time 50% of the position fixes will lie within a circle with a radius of 2.5 metres. If you look at the position that the receiver reports it appears to wander at random around the true position sometimes moving a number of metres away from its true location. If you simply integrate the distance moved between samples then you will get a very large apparent distance travelled.for a stationary device.
A simple algorithm that I have used quite successfully for a vehicle odometer function is as follows
for(;;)
{
Stored_Position = Current_Position ;
do
{
Distance_Moved = Distance_Between( Current_Position, Stored_Position ) ;
} while ( Distance_Moved < MOVEMENT_THRESHOLD ) ;
Cumulative_Distance += Distance_Moved ;
}
The value of MOVEMENT_THRESHOLD will have an effect on the accuracy of the final result. If the value is too small then some of the random wandering performed by the stationary receiver will be included in the final result. If the value is too large then the path taken will be approximated to a series of straight lines each of which is as long as the threshold value. The extra distance travelled by the receiver as its path deviates from this straight line segment will be missed.
The accuracy of this approach, when compared with the vehicle odometer, was pretty good. How well it works with a pedestrian would have to be tested. The problem with people is that they can make much sharper turns than a vehicle resulting in larger errors from the straight line approximation. There is also the perennial problem with sky view obscuration and signal multipath caused by buildings, vehicles etc. that can induce positional errors of 10s of metres.
How to calculate Altitude from GPS Latitude and Longitude values.What is the exact mathematical equation to solve this problem.
It is possible for a given lat,lon to determine the height of the ground (above sea level, or above Referenz Elipsoid).
But since the earth surface, mountains, etc, do not follow a mathematic formula,
there are Laser scans, performed by Satelites, that measured such a height for e.g every 30 meters.
So there exist files where you can lookup such a height.
This is called a Digital Elevation Modell, or short (DEM)
Read more here: https://en.wikipedia.org/wiki/Digital_elevation_model
Such files are huge, very few application use that approach.
Many just take the altidude value as delivered by the GPS receiver.
You can find some charts with altitude data, like Maptech's. Each pixel has a corresponding lat, long, alt/depth information.
As #AlexWien said these files are huge and most of them must be bought.
If you are interest of using these files I can help you with a C++ code to read them.
You can calculate the geocentric radius, i.e., the radius of the reference Ellipsoid which is used as basis for the GPS altitude. It can be calculated from the the GPS latitude with this formula:
Read more about this at Wikipedia.
What is the unit in which core location framework gives the "Accuracy" (distance) for iBeacons. According to my knowledge it should be in Meters. But, in my app I have placed some beacons in distance of 19 Meters (63 foot) and the accuracy value of beacon from the framework is coming to be greater than 25 also sometimes.
The unit of CLBeacon.accuracy is in meters, but as you have witnessed, it is only a rough estimate. At short distances of 3 meters or less, the estimate will usually be within a meter. At longer distances it can be off by 10 meters or more.
This error is due to radio noise, multipath and attenuation. Estimation errors are a fundamental limitation of the technology, so you must set expectations appropriately.
Read more here: http://developer.radiusnetworks.com/2014/12/04/fundamentals-of-beacon-ranging.html
I am trying to build an IOS application that counts claps. I have been watching the WWDC videos on CoreAudio, and the topic seems so vast that I'm not quite sure where to look.
I have found similar problems here in stackoverflow. Here is one in C# for detecting a door slam:
Given an audio stream, find when a door slams (sound pressure level calculation?)
It seems that I need to do this:
Divide the samples up into sections
Calculate the energy of each section
Take the ratio of the energies between the previous window and the current window
If the ratio exceeds some threshold, determine that there was a sudden loud noise.
I am not sure how to accomplish this in Objective-C.
I have been able to figure out how to sample the audio with SCListener
Here is my attempt:
- (void)levelTimerCallback:(NSTimer *)timer {
[recorder updateMeters];
const double ALPHA = 0.05;
double peakPowerForChannel = pow(10, (0.05 * [recorder peakPowerForChannel:0]));
lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;
if ([recorder peakPowerForChannel:0] == 0)
totalClapsLabel.text = [NSString stringWithFormat:#"%d", total++];
SCListener *listener = [SCListener sharedListener];
if (![listener isListening])
return;
AudioQueueLevelMeterState *levels = [listener levels];
Float32 peak = levels[0].mPeakPower;
Float32 average = levels[0].mAveragePower;
lowPassResultsLabel.text = [NSString stringWithFormat:#"%f", lowPassResults];
peakInputLabel.text = [NSString stringWithFormat:#"%f", peak];
averageInputLabel.text = [NSString stringWithFormat:#"%f", average];
}
Though I see the suggested algorithm, I am unclear as to how to implement it in Objective-C.
You didn't mention what sort of detection fidelity you are looking for? Just checking for some kind of sound "pressure" change may be entirely adequate for your needs, honestly.
Keep in mind however that bumps to the phone might end up being a very low frequency and fairly high-powered impulse such that it will trigger you detector even though it was not an actual clap. Ditto for very high frequency sound sources that are also not likely to be a clap.
Is this ok for your needs?
If not and you are hoping for something higher fidelity, I think you'd be better of doing a spectral analysis (FFT) of the input signal and then looking in a much narrower frequency band for a sharp signal spike, similar to the part you already have.
I haven't looked closely at this source, but here's some possible open source FFT code you could hopefully use as-is for your iphone app:
Edit:
https://github.com/alexbw/iPhoneFFT
The nice part about graphing the spectral result is that it should make it quite easy to tune which frequency range you actually care about. In my own tests with some laptop software I have, my claps have a very strong spike around 1kHz - 2kHz.
Possibly overkill for you needs, but if you need something higher fidelity, then I suspect you will not be satisfied with simply tracking a signal spike without knowing what frequency range led to the signal spike in the first place.
Cheers
I used FFT for my App https://itunes.apple.com/us/app/clapmera/id519363613?mt=8 . Clap in the frequency domain looks like a (not perfect) constant.
Regards
Simmilar with Direction between 2 Latitude/Longitude points in C#
but with objective-c
Also I want a formula that works for large distance near the pole if it's possible.
You'll need the following complete but rather difficult stuff. A slightly easier description is found on wikipedia.
Or you could save yourself a lot of time and use CLLocation's distanceFromLocation method:
distanceFromLocation:
Returns the distance (in meters) from the receiver’s location to the specified location.
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.
http://developer.apple.com/library/ios/DOCUMENTATION/CoreLocation/Reference/CLLocation_Class/CLLocation/CLLocation.html#//apple_ref/occ/instm/CLLocation/distanceFromLocation: