Question

I having some problem on the iPhone/iPad compass development.

The trueHeading taken from the CLHeading alway give me the '-1' value, I'm stuck here. Here is my code:

self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
self.locationManager.headingFilter = 0.5; //1 degrees
[self.locationManager startUpdatingHeading];

I also found out something, that is when I on the map app or the compass app which has use the location stuff, the trueHeading value suddenly read correct. I wonder what is the cause, any idea? It happen on both iPhone4 and on the iPad.

It also happen whenever I off the Location Services in settings and re-enable it, it will become unable to read the correct trueHeading value, i wonder because the location services cannot be enable by the app I creating?

anyway, thank in advance

---My Solution---

see below.

Was it helpful?

Solution 3

---My Solution---

What I did was, add in the [self.locationManager startUpdatingLocation] to before or after the [self.locationManager startUpdatingHeading]; (when Location Services is off & re-enable from the Settings). I'm not sure this is a good solution, but this is what I did to make it work, if you have any better solution please share.

OTHER TIPS

to avoid the heading keep returning -1.000000, not JUST run startUpdatingHeading but run startUpdatingLocation together, this helps.

Try using this...

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate=self;
    locationManager.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
    // Start heading updates. 
    if (locationManager.headingAvailable && locationManager.locationServicesEnabled) 
    {
        locationManager.headingFilter = kCLHeadingFilterNone; 
        [locationManager startUpdatingHeading];
    }

and after doing this CLLocationManager delegate methods calls

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {

    // Use the true heading if it is valid. 
    [lblAccuracy setText:[NSString stringWithFormat:@"%.1fmi",newHeading.headingAccuracy]]; 
}

But this coding works on device not in simulator...

Happy coding..

I had some trouble with the location manager myself and found out that for me it helped to unplug the iPhone from the computer when testing. Somehow the calibration alert only popped up after unplugging the iPhone.

I had this same problem. I moved startUpdatingHeading into a button action, then moved it back to where the CLLocationManager is allocated -- where it had been working fine -- and it started returning only -1.

I rebooted my iPad and it started working again. Hopefully it stays that way.

Edit: Nope, it didn't stay that way. I had to use startUpdatingLocation too. Won't this wear down the battery though? I set desiredAccuracy to kCLLocationAccuracyThreeKilometers, because I am not using location data anyway.

A TRUE reading requires knowing the magnetic variation for the place where you are using the compass. From the previous discussion, it appears to be that the function that corrects the true direction from magnetic direction needs your location for obtaining the variation value. If you don't like to use the location GPS information in your code, I suggest reading the magnetic reading and correct the value by yourself. You need to obtain the variation for the desired location first then apply the following formula: T=M ± V, where T is the true direction, M is the compass magnetic reading and V is the variation. Use "+" for East and "-" for West. I found the allowing web site provide the variation(magnetic declination) for any needed location: http://www.geomag.nrcan.gc.ca/calc/mdcal-eng.php.

When location services are off, the didUpdateHeading delegate method returns only the magnetic heading. You can use it according to your needs. According to Apple docs..

To begin the delivery of heading-related events, assign a delegate to the location manager object and call its startUpdatingHeading method. If location updates are also enabled, the location manager returns both the true heading and magnetic heading values. If location updates are not enabled, the location manager returns only the magnetic heading value.

Working on this problem now. I can get updates from Core Motion when I use SpriteKit. It's about being able to call a function continuously like once a frame (1/60th of a second) or every few frames. Without using SpriteKit, the documentation says to invoke the updates within a closure, which I assume will be on their own thread and up to you to release.

There's an algorithm for converting the magnetometer readings to actual degrees relative to true north. Picture a graph that looks like the time domain function of alternating current and you'll see that interpolating the data is a simple matter of applying Maxwell's equations. Here's an example on honeywell

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top