We receive live relative-altitude updates from CMAltimeter.startRelativeAltitudeUpdates(to:withHandler:) on iPhone. CMAltitudeData inherits CMLogItem.timestamp, which the documentation describes as the time when the item is valid and as seconds since device boot.
We need to determine whether a pressure measurement's event time falls inside an application operation bounded by a supported monotonic clock. Could Apple clarify the supported contract for CMAltitudeData.timestamp on iOS?
-
Does
CMAltitudeData.timestampuse the same epoch and rate asmach_absolute_time(),DispatchTime.uptimeNanoseconds,CACurrentMediaTime(), orProcessInfo.systemUptime? If only some are compatible, which ones? -
Does it advance or pause during device sleep, device lock, application suspension, and background execution? In particular, are its sleep/suspension semantics guaranteed to match any of the clocks above?
-
Is there a supported API for converting
CMLogItem.timestampto a hostCMClock/Mach time, or for sampling “now” in the exact same clock domain used byCMAltitudeData.timestamp? -
Are the answers contractual across supported iPhone hardware and iOS releases, or are they implementation details that applications should not rely on?
-
If direct comparison is not supported, what Apple-supported clock or conversion mechanism should an application use to compare a
CMAltitudeDataevent time with two application-side monotonic operation boundaries?
The question concerns clock semantics only. A minimal reproducer can be supplied if requested, but no application identifier, production data, sensor values, or user data is required to answer it.
Your point that the altimeter does not perform its own timestamping raises one remaining question: what event does CMAltitudeData.timestamp represent—receipt of a sensor reading by the system, creation of the Core Motion event, or an estimate of when pressure was measured?
locationd collects and stores the data from our various sensors, and that data store* is what then sends the motion events you receive. SO, generally speaking, its behavior is probably closer to this:
*Just to clarify, this doesn't mean that locationd specifically stores every reading it receives and then sends it to your app at some later point. The process of sending data to clients and storing that data all happens as part of the same process.
CMAltitudeData.timestamp represent—receipt of a sensor reading by the system
However, the problem here is that the details of exactly how our sensors generate and process data vary considerably across our full device range and, in fact, a huge part of locationd's "job" is to provide relatively consistent behavior across a very wide range of sensor implementations. Putting that in more concrete terms, if these differences ACTUALLY matter to your app’s implementation, then I think you're expecting a level of precision that the system was never really designed to provide.
Can a newly delivered event contain an older or filtered pressure measurement whose age is not represented by that timestamp?
No.
For implementation, is comparing that timestamp directly with operation boundaries sampled using ProcessInfo.systemUptime, while monitoring for unexpected divergence, a reasonable approach for this coarse association?
You'll need to test it for yourself, but yes, I expect it will work well. One suggestion on that point— if you're planning on integrating this into an existing, mature implementation, I would strongly suggest writing a VERY simple test app that does nothing but collect the sensor data you're interested in and correlate them with ProcessInfo.systemUptime (or any other source you want to try). I'd probably test "all" the time sources at once just to see how things compared, but the details there don't matter. Partly this is just to quickly confirm that this works the way you want, both so you can avoid wasted effort now and so you can validate things in the future. The "pro move" here would actually be to integrate this into your long-term testing process, so that you'll immediately notice if/when something were to change.
However, the bigger issue is that "real" app implementations often work very differently than people realize, and that disconnect can end up causing large amounts of wasted time and effort. The best way to counter that is to start with a clear understanding of what the "basic" behavior is, so that when something different happens, you'll start by looking at your app’s implementation, not the data.
That leads to here:
"Separately, does CMDeviceMotion (gyroscope/accelerometer) timestamping follow the same software-stamping path, or is IMU data timestamped closer to the sensor?"
Down this path lies madness. The problem here is that:
-
There's no meaningful time difference between those two cases.
-
Even if there were a meaningful time difference, there's no way your app can account for or compensate for that difference, so it still doesn't matter.
Since you mentioned CMDeviceMotion, a few other tips/tricks that might be useful:
-
If you're using motion data to drive your interface, the best way to do that is by directly using the latest sample property (CMMotionManager.deviceMotion) in your interface rendering code, NOT by receiving the data on a queue and routing it to your interface. Trying to collect and route the data yourself only introduces additional latency and complexity, which is why the properties exist in the first place.
-
If you're doing user activity tracking, I'd strongly recommend using APIs like CMSensorRecorder or CMBatchedSensorManager, NOT CMMotionManager. CMMotionManager delivers data at a far higher rate than meaningful user analysis requires (humans don't really move at 50hz), so a proper CMDeviceMotion implementation ends up needing to batch up events anyway. Even worse, most of the motion analysis issues I've seen with CMDeviceMotion are caused by the app interfering with its own event delivery, then failing to account for the distortion those delays created. All of those issues go away if you use our non-"real time" APIs.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware