I have yet to find useful information on GPS sample/output rate in iPhones. Please direct me to any useful and relevant articles I missed. Also please let me know how to make my post more clear.
Actual behavior: iPhone XR outputs GPS samples at slow rates, around one sample every 6 seconds, but occasionally with two samples in a more rapid succession (e.g. 1.5 seconds, although very seldomly). This occurs when sitting still, when quickly walking and shaking phone around around, and with various different assignments for CLLocationManager.desiredAccuracy.
Expected/optimistic behavior: Quicker GPS sample outputs from my iPhone XR, like those in this video right here. I am aware that this video is from 2017, although I don't know what makes this significant. https://www.youtube.com/watch?v=XyncTJdXbbw&t=5m20s
Discussion: I need GPS samples for a project, and I'd ideally like it to be sampled at 1.0+ Hz. I have written programs on Swift and downloaded apps which log and graph my iPhone XR's GPS data, but my sampling rate of my GPS data seems to be inconsistent and very slow, around one measurement every 6 seconds.
I have a lot of questions, which include:
- Does iPhone XR have a well-defined GPS output rate?
- What factors affect it?
- Where can I find this information better documented?
- How can I increase the output rate of the GPS?
I am new to working with iOS as well as knowing through what methods iPhones calculate GPS coordinates. I have heard that iPhone GPS can output data at 1 Hz, although I haven't found this officially documented yet.
I am aware I can specify the desiredAccuracy and distanceFilter in my Swift program, but the desiredAccuracy parameter seems not to have much effect on my coordinate precision or my output rate. My iPhone XR is on iOS 13.4.1, and my 128 GB phone is almost completely full with photos in case that makes some weird difference. I'm removing those photos just to clean up now.
I included my Swift program below. It is very basic, and I don't know how to code in Swift, so feel free to inform me if I'm doing things incorrectly. At the last time I ran it successfully (two days ago), my iPhone was on iOs 13.3 or so, Mac OS on 10.13 or so. The Swift program should be as basic as possible, single-view app with storyboard UI. If necessary, I can provide updates on newer OS/iOS/Xcode versions once I clean my phone and get some stuff to work.
I can't find my console output text file, so I'll upload something once I am able to. I suppose answer with the assumption that my output occurs every 6 +/- 0.05 seconds.
//
// ViewController.swift
// CoreMotionExample
//
// Created by COVID-19 on 11/17/19
// Copyright © 2019 COVID N. Teen. All rights reserved.
//
import UIKit
import CoreMotion
import CoreLocation
class ViewController: UIViewController {
let motionManager = CMMotionManager()
let locationManager = CLLocationManager()
var timer: Timer!
let start = Date()
var time_prev = 0.0
var elapsedTime = 0.0
let verbose = false;
override func viewDidLoad() {
super.viewDidLoad()
motionManager.startAccelerometerUpdates()
motionManager.startGyroUpdates()
motionManager.startMagnetometerUpdates()
motionManager.startDeviceMotionUpdates()
locationManager.requestAlwaysAuthorization()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.startUpdatingLocation()
timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: true)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first
{
if(true)
{
print(location.coordinate, "\n")
elapsedTime = time_prev - start.timeIntervalSinceNow
print("Time elapsed: ", elapsedTime, "\n")
time_prev = start.timeIntervalSinceNow
}
}
}
@objc func update() {
// IMU/MARG/INS data:
if let accelerometerData = motionManager.accelerometerData
{
if(verbose)
{
print("Accelerometer data:\n",accelerometerData, "\n")
}
}
if let gyroData = motionManager.gyroData
{
if(verbose)
{
print("Gyroscope data:\n", gyroData,"\n")
}
}
if let magnetometerData = motionManager.magnetometerData
{
if(verbose)
{
print("Magnetometer data:\n", magnetometerData,"\n")
}
}
if let deviceMotion = motionManager.deviceMotion
{
if(verbose)
{
print("deviceMotion data:\n", deviceMotion,"\n")
}
}
//GPS/Location data:
//Nothing successful here, see above
}
}
extension ViewController: CLLocationManagerDelegate {
// handle delegate methods of location manager here, also nothing here
}