Join Steven Lipton for an in-depth discussion in this video Altimeter, part of Advanced iOS App Development: Core Motion.
[Narrator]- As you just heard in later model devices, the altimeter measures barometric pressure in kilopascals through core motion. You do not reach it in device motion or even the motion manager, but as a raw sensor. Let's add some code to our fencing project to detect altitude changes. Make a new function in the fencing demo called 'myAltimeter'. Close the console. Just above 'myDeviceMotion', make a new function called 'myAltimeter'.
Check for the availability of the altimeter. You do that with the 'isRelativeAltitudeAvailable' class function. If it's not available, print to the console that we don't have one in the else statement. Altimeters only have push updates. We'll make an altimeter object and then start updates.
First, head up to the top of the code and make a property for the class for the altimeter. We'll do a 'let altimeter = CMAltimeter'. Back in the 'myAltimeter' function, start the updates: 'altimeter.startRelativeAltitudeUpdates', and we'll use the one with the handler and the operation queue.
We'll change it to the operation queue of main, and the handler; on that, press return so that we get the closure set up for us. We'll make the first one altitude, and the second one error, for the error. 'Tab', and then we enter the code here. First I'll check for 'altitude' being nill, and there's no data. 'if let altitude = altitude'; altitude has two properties: pressure, and relative altitude.
Both are NS numbers, so I'll downcast them both to doubles. We'll do a 'let pressure = altitude.pressure as Double' and 'let relAltitude = altitude.relativeAltitude', again as a double.
Finally, I'll print both to the console. Print, quotes, pressure, and I'll set my pressure to pressure, and I'll set 'altitudeChange' to relative altitude. Like all other sensors, you'll need to stop the altimeter. For our application, I'm going to stop it when we leave the view in 'viewWillDisappear'.
And what I'll do is just like I've been doing before, as I'll just do an 'altimeter' and just tell it to stop, and there it is: 'stopRelativeAltitudeUpdates', like so. Now go to 'viewDidAppear', comment out 'myDeviceMotion'. Underneath it, put 'myAltimeter', so that we're measuring just the altimeter in this version of what we're doing. We're set to run, so get your phone ready, go ahead and build and run, core motion launches, and we start getting pressure and altitude changes.
My device is sitting on the table, and it appears to be sinking through the table as we sit here, and I am moving back and forth a little bit: it's floating in and out of the table by about seven tenths of a centimeter, and then it floats up and floats down. So we've got some changes to the actual amounts that are here. Let's add a little more code to understand what's going on here a little bit better, so stop the app and close the console.
At the top of the 'myAltimeter' function, I want you to add two variables. The first one is going to be called 'first' and set that to true, we're going to use this as a flag to say this is the first time we've got something, and 'var firstPressure', and that's going to be zero to start with as a double. And now we'll go into our closure here, and grab the initial pressure from the device and see how much it varies over time.
After giving the relative altitude, add this: 'if first firstPressure = pressure', and 'first = false'. This now sets 'firstPressure' to the first pressure reading that we get. And now after we've done that, we can subtract it by doing 'let pressureChange = firstPressure - pressure'.
Now I can add that in the middle here to my print statement, and I'm going to do a pressure change. And then run again, and you can see that we have some variations in pressure here, but it's not too bad on this time. Now today we have fair weather where I am, so it's not making a big difference.
If we were, for example, getting a thunderstorm nearby, that would be changing this to a little bit more of a degree than we have right now of a very small change like it has here. You can see that the altitude is actually changing a little bit: we're now three centimeters above the table, apparently, even though the phone itself is sitting on my table, so it's got some numbers that are a little weird. You've got to also remember that these numbers themselves have a relative value, because where you are will make a difference on what they are.
I'm sitting here at 178 feet above sea level, or 54 meters, and that's giving me these numbers that I have now. You can start seeing my altitude changes, now I am floating one meter above my desk, or apparently my phone is, at least. So that is what's going on here, and you don't get exactly accurate values. You can also get your base values being very different, because right now, if you look at my pressure, it's about 100.96 here. In Denver, Colorado, you're going to be seeing that number to be 84, and that's where you're going to really see true altitude changes, is where you're seeing changes up and down, of about three or four kilopascals.
But, small changes like this are kind of hard to really see here, and so that's a little bit of a problem with this system. It is great for variations greater than 500 meters, so if you're doing a running app and you wanted to get an altitude change, that would be great for telling you how fast you're going up a mountain. But its accuracy below that is kind of questionable. It is a low-power option compared to using the GPS in core location, which can be a lot more accurate, but drains power a lot faster. You could, of course, get a reference from GPS at various times, and use both of them together to get you a good reference frame, and then use that reference frame over and over again, sort of like pedometer does with distance and pace.
You, as a developer, will have to decide exactly how to go about doing this though.
- Reading Core Motion data
- Understanding Core Motion methods
- Creating a pedometer app
- Using pace and distance data from Core Motion
- Pushing and pulling device motion data
- Accessing the altitude sensors
- Working with the motion activity manager (CMMotionActivityManager)