iphone - Using the Device motion instead of Accelerometer, Gyroscope and Magnetometer - iphone

If I'm on iOS4, not using a specific handler, and needing the same update interval, what is the difference using the Device motion instead of specific Accelerometer, Gyroscope and Magnetometer updates ?
What happens if one of those 3 features is not available on the device if I use the Device motion ?
I mean, what will return deviceMotionAvailable if one of those feature is not available ?

In iOS 4 the magnetometer is not yet included in device motion API but handled by CLLocationManager (this changed in iOS 5). So if you have a gyro and an accelerometer, deviceMotioAvailable will return true independent of magnetometer. On the other hand if the gyro is missing you will always get false and you need to stay with accelerometerData.
Because Device Motion has one timestamp for both sensors, you will get reliable interpolated values for both sensors. Otherwise Device Motion wouldn't be able to do sensor fusion, the main advantage why this is the preferred way.
You can not rely on a fix frequency for CLLocationManager. didUpdateHeading is called whenever the system 'thinks' it should be. To get the different time coordinates between CLLocationManager and CMDeviceMotion normalised, you can have a look at NSTimeInterval to unix timestamp

Related

How to maximize battery life on Movesense sensor?

I have a use case where the Movesense sensor will be used occasionally (say, an hour a day) and I'd like to maximize battery life. Is there a way to put it into a sleep state, and then wake it in response to some user action? For example, shut off Bluetooth and all sensors but the accelerometer, and then wake them up with the accelerometer detects that it's being moved or tapped.
I see that the Movesense sensor can be put in "PowerOff" or "FullPowerOff" state. In these states is it completely shut down, or is it possible to continue to monitor the accelerometer?
Yes, it is possible. You can check hr_wakeup_sample:
https://bitbucket.org/suunto/movesense-device-lib/src/887714f3b42496988cce6055b3ccf8b8c99a6846/samples/hr_wakeup_app/?at=master
The device is waking up when you put your fingers to the metal pins (on the bottom).
Also you can change this line:
asyncPut(WB_RES::LOCAL::COMPONENT_MAX3000X_WAKEUP::ID,
AsyncRequestOptions(NULL, 0, true), (uint8_t) 1);
https://bitbucket.org/suunto/movesense-device-lib/src/887714f3b42496988cce6055b3ccf8b8c99a6846/samples/hr_wakeup_app/HrWakeupApp.cpp?at=master&fileviewer=file-view-default#HrWakeupApp.cpp-132
to use this API:
https://bitbucket.org/suunto/movesense-device-lib/src/887714f3b42496988cce6055b3ccf8b8c99a6846/MovesenseCoreLib/resources/movesense-api/component/lsm6ds3.yaml?at=master&fileviewer=file-view-default#lsm6ds3.yaml-119

How to record the acceleration or speed after throwing the iPhone in the air?

I am writing an app which will need to record the acceleration or speed while the iPhone is in the air.
I know when throwing the iPhone upward, when reaching the highest point, the speed will be 0, and the acceleration will be max. I'll need the data.
Does the iPhone have any sensor to record the data??
Yes, you have the CMMotionManager capable of that:
CMMotionManager Apple Doc
You will need to monitor the acceleration.

iOS - Geofencing with WiFi turned off

I have code that creates a geofence on my iPhone that will trigger some code to be executed when didExitRegion gets called. However, I have found that when I have WiFi switched off that didExitRegion never gets triggered.
Is WiFi required for monitoring region changes on iOS?
My desired accuracy is set to kCLLocationAccuracyHundredMeters.
I am testing on iOS 6.1 and iPhone 4.
Here is my code for setting up location monitoring:
- (id)init {
self = [super init];
if (self) {
CLLocationManager *manager = [[CLLocationManager alloc] init];
manager.delegate = self;
manager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
manager.distanceFilter = RADIUS/10.0;
manager.headingFilter = kCLHeadingFilterNone;
self.locationManager = manager;
self.authorizationStatus = [CLLocationManager authorizationStatus];
}
return self;
}
Thanks
iOS devices use three methods to discover user location. From (usually) most accurate to least accurate they are:
GPS hardware
By identifying nearby wifi networks
Cell Tower Triangulation
If your app doesn't use GPS or is not running (ie. has previously been terminated), the device will attempt to use methods 2 and 3 above to locate the user. So the device's ability to locate the user (when the GPS hardware is not in use or there is a weak GPS signal) depends on the availability of wifi networks and cell towers. The more wifi networks and cell towers, the better the location accuracy. Therefore, when a user enters or exits a monitored region (ie. crosses a "geofence"), it is impossible to predict exactly when the user will receive the notification if at all. (Of course, if the region in question is always the same, the device will more or less locate the user with the same degree of accuracy on each occasion).
Here's the relevant documentation from the Location Awareness Programming Guide:
The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters.
So, wifi is not required for region monitoring to work, but with it enabled, your device will have a better chance in determining whether or not the user has crossed a region's geofence.
If you turn off WiFi, your location accuracy lowers. If you don't have GPS signal(inside some buildings), you will not get any location updates. Have you tried this when you are outside, or if you used the location simulator to test?
Also, WiFI is not required for geofence function if you have GPS(iPhones or iPad with sims).
Weird weird stuff can happen without wifi using core location. To help in your case I would get rid of the distance filter, that can mess with things and it is not very helpful. I would probably only use kCLLocationAccuracyBest for anything where I need the accuracy required to set up a geofence. Using other accuracies and filters for me would sometimes through the gps meter off by 1000 meters and take a minute or two to correct itself. If this is too much battery then set up a system where it turns off and on based on how far away it is from the fence.

iPhone motion data blocked by Compass Calibration setting

My app has an augmented reality camera view which uses CMMotionManager to find heading relative to true north. However, I am finding that if the user switches OFF Location Services / System Settings / Compass Calibration, then the device motion data stops returning sensible values (in particular the gravity vector values), and makes the app useless. Quite a few people do this because they believe doing so saves battery life.
Does anyone know exactly what this setting does to the device or to CMMotionManager?
How can my app determine what it is set to?
Does setting it OFF necessarily mean that CMMotionManager won't work?
You can check your true heading value in your heading delegate. If the device calibration is "off" in the setting then this value will be static and equal to "-1" every time. SO you can check in the heading delegate
if (new.heading == -1)
{
//Calibration in setting is Off
}
else
{
//Calibration is On
}
Hope this work. As it works for me.
Thanks and Regards
Abhishek Goyal

iPhone Proximity Sensor

Can the iPhone SDK take advantage of the iPhone's proximity sensors? If so, why hasn't anyone taken advantage of them? I could picture a few decent uses.
For example, in a racing game, you could put your finger on the proximity sensor to go instead of taking up screen real-estate with your thumb. Of course though, if this was your only option, then iPod touch users wouldn't be able to use the application.
Does the proximity sensor tell how close you are, or just that something is in front of it?
There is a public API for this. -[UIApplication setProximitySensingEnabled:(BOOL)] will turn the feature on. BTW, it doesn't seem to be using the light sensor, because proximity sensing would tweak out in a dark room.
However, the API call basically blanks the screen when you hold the phone up to your face. Not useful for interaction, sadly.
Assuming you mean the sensor that shuts off the screen when you hold it to your ear, I'm pretty sure that is just an infrared sensor inside the ear speaker. If you start the phone app (you don't have to be making a call) and hold something to cast a shadow over the ear speaker, you can make the display shut off.
When you asked this question it was not accessible via the public API. You can now access the sensor's state via UIDevice's proximityState property. However, it wouldn't be that useful for games, since it is only an on/off thing, not a near/far measure. Plus, it's only available on the iPhone and not the iPod touch.
Evidently the proximity sensor will never turn on if the status bar is in landscape orientation.
i.e, if you call:
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
You will no longer get the proximity:ON notifications.
This definitely happens on OS 3.0, I can't test it on a 2.X device since I don't have one with a proximity sensor.
This seems like a bug.
The proximity sensor works via measuring IR reflectance. If you hold the iPhone up to a webcam, you can see a small, pulsing IR LED.
There's a lot of confusion between the proximity sensor and the ambient light sensor. The iPhone has both. The Touch does not have a proximity sensor, making it a poor choice for user input. It would be a bad idea anyway since Apple isn't obligated to locate it in the same place in future devices; you aren't supposed to know or care where it is.
The proximity sensor works by pulsing an infrared LED and measuring the amount of reflectance. You can see this using your iSight camera (most digital cameras are sensitive to IR.) Just launch Photo Booth, initiate a call (or play a voicemail) on the phone and point it at your iSight camera. Note the flashing light next to the earpiece; cover it with your finger and the screen will go black.
The ambient light sensor's API is evidently private at this point.
Just to update, this is possible.
device = [UIDevice currentDevice];
// Turn on proximity monitoring
[device setProximityMonitoringEnabled:YES];
// To determine if proximity monitoring is available, attempt to enable it.
// If the value of the proximityMonitoringEnabled property remains NO, proximity
// monitoring is not available.
// Detect whether device supports proximity monitoring
proxySupported = [device isProximityMonitoringEnabled];
// Register for proximity notifications
[notificationCenter addObserver:self selector:#selector(proximityChanged:) name:UIDeviceProximityStateDidChangeNotification object:device];
As benzado points out, you can use:
// Returns a BOOL, YES if device is proximate
[device proximityState];
There is no public API for this.
In iPhone 3.0 there is official support for the proximity sensor. Have a look at UIDevice proximityMonitoringEnabled in the docs.
If you aren't aiming for the AppStore, you can read my articles here on getting access to those:
Proximity Sensor: http://iphonedevwiki.net/index.php/AppleProxShim
Ambient Light Sensor: http://iphonedevwiki.net/index.php/AppleISL29003
Evidently the proximity sensor will never turn on if the status bar is in landscape orientation.
i.e. if you call:
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
You will no longer get proximity:ON notifications.
This definitely happens on OS 3.0, I can't test it on a 2.X device since I don't have one with a proximity sensor.
This seems like a bug.
answered Jul 22 '09 at 5:49
Kevin Lambert
I've encoutered this problem too. It took me a long time to figure out the real reason of why the proximity sensor is not working. When orientation is UIInterfaceOrientationLandscapeLeft or UIInterfaceOrientationLandscapeRight, proximity sensor does not work; while in portrait mode it works well. My iPhone is iPhone 4S (iOS SDK 5.0).
Those proximity sensors are basically a matrix of conductors. The vertical "wires" are tracks on one side of a thin sheet of insulator, the horizontal ones are on the other side. The intersections function as capacitors. Your finger carries an electrostatic charge, so capacitance of each junction varies with proximity. FETs amplify the signal and biasing sets a threshold. In practice the circuit is more complex than that because it has to detect a relative change and reject noise.
But anyway, what the sensor grid tells you is that a field effect has been sensed, and that field effect is characteristic of object about the size of a fingertip and resting on the surface of the display. The centroid of the capacitive disturbance is computed (probably by hardware) and the coordinates are (presumably) reported as numbers on a port most likely brought to the attention of the device OS by an interrupt. In something as sexy as an iPhone there's probably a buffer of the last dozen or so positions so it can work out direction and speed. Probably these are also computed by hardware and presented as numbers on the same port.
#Dipak Patel & #Coderer
You can download working code at
http://spazout.com/google_cheats_independent_iphone_developers_screwed
It has a working implementation of proximityStateChanged a undocumented method in UIApplication.
Hope this helps.
To turn the screen off it's conceivable that more than one sensors is used to figure out if the screen should be turned off or not. The IR proximity sensor described by Cryptognome in conjunction with the Touch screen sensor described by Peter Wone could work out if the iphone is being held close to your face (or something else with a slight electric charge) or if its just very close to something in-animate.