Detect the iPhone rotation spin? - iphone

I want to create an application could detect the number of spin when user rotates the iPhone device. Currently, I am using the Compass API to get the angle and try many ways to detect spin. Below is the list of solutions that I've tried:
1/ Create 2 angle traps (piece on the full round) on the full round to detect whether the angle we get from compass passed them or not.
2/ Sum all angle distance between times that the compass is updated (in updateHeading function). Let try to divide the sum angle to 360 => we could get the spin number
The problem is: when the phone is rotated too fast, the compass cannot catch up with the speed of the phone, and it returns to us the angle with latest time (not continuously as in the real rotation).
We also try to use accelerometer to detect spin. However, this way cannot work when you rotate the phone on a flat plane.
If you have any solution or experience on this issue, please help me.
Thanks so much.

The iPhone4 contains a MEMS gyrocompass, so that's the most direct route.
As you've noticed, the magnetometer has sluggish response. This can be reduced by using an anticipatory algorithm that uses the sluggishness to make an educated guess about what the current direction really is.
First, you need to determine the actual performance of the sensor. To do this, you need to rotate it at a precise rate at each of several rotational speeds, and record the compass behavior. The rotational platform should have a way to read the instantaneous position.
At slower speeds, you will see a varying degree of fixed lag. As the speed increases, the lag will grow until it approaches 180 degrees, at which point the compass will suddenly flip. At higher speeds, all you will see is flipping, though it may appear to not flip when the flips repeat at the same value. At some of these higher speeds, the compass may appear to rotate backwards, opposite to the direction of rotation.
Getting a rotational table can be a hassle, and ensuring it doesn't affect the local magnetic field (making the compass useless) is a challenge. The ideal table will be made of aluminum, and if you need to use a steel table (most common), you will need to mount the phone on a non-magnetic platform to get it as far away from the steel as possible.
A local machine shop will be a good place to start: CNC machines are easily capable of doing what is needed.
Once you get the compass performance data, you will need to build a model of the observed readings vs. the actual orientation and rotational rate. Invert the model and apply it to the readings to obtain a guess of the actual readings.
A simple algorithm implementation will be to keep a history of the readings, and keep a list of the difference between sequential readings. Since we know there is compass lag, when a difference value is non-zero, we will know the current value has some degree of inaccuracy due to lag.
The next step is to create a list of 'corrected' readings, where the know lag of the prior actual values is used to generate an updated value that is used to create an updated value that is added to the last value in the 'corrected' list, and is stored as the newest value.
When the cumulative correction (the difference between the latest values in the actual and corrected list exceed 360 degrees, that means we basically don't know where the compass is pointing. Hopefully, that point won't be reached, since most rotational motion should generally be for a fairly short duration.
However, since your goal is only to count rotations, you will be off by less than a full rotation until the accumulated error reaches a substantially higher value. I'm not sure what this value will be, since it depends on both the actual compass lag and the actual rate of rotation. But if you care only about a small number of rotations (5 or so), you should be able to obtain usable results.

You could use the velocity of the acceleration to determine how fast the phone is spinning and use that to fill in the blanks until the phone has stopped, at which point you could query the compass again.

If you're using an iPhone 4, the problem has been solved and you can use Core Motion to get rotational data.
For earlier devices, I think an interesting approach would be to try to detect wobbling as the device rotates, using UIAccelerometer on a very fine reporting interval. You might be able to get some reasonable patterns detected from the motion at right angles to the plane of rotation.

Related

I want to calculate spped of android device using accelerometers sensor only not with GPS?

I need to create an app that Calculates the moving car velocity/speed, with x/y/z speed.
My idea is using device's accelerometer.
I am using Sensor.TYPE_ACCELEROMETER and getting ax,ay,az (acceleration in x,y,z direction). how to get sped of device. Lots of physics formulas suggested by people to get speed but any one of then not giving correct speed compared to GPS. Please tell me code or good link which solve my problem.
That would be very difficult. To calculate the speed of the device, you need to calculate the integral of the acceleration. But to do so, you need to very accurately know for very dense points in time both the device's rotation and its acceleration. Assuming you do have those things, you simply need to take the device's initial speed, and for each point in time add to it (rotation matrix * acceleration vector * time to next measurement). That's probably the most accurate thing you can that is simple enough.

Get position from accelerometer

I am working in a monocular 3D Mapping project, and I need every time both position and rotation (angle).
To filter Gyroscope Data, I decided to use the "compass" and set 0 value to the angle if it's north.
But to get the position, I will need to double integrate the accelerometer value with a small sampling step (1ms) and 7 values mean filter.
I think this will make position more accurate. But does someone have an idea about the error range ? for example, in 10 meters, How much the error will be.
And does anyone have a better idea?
The sensors are from STM32F3 Discovery Board
Thanks
The STM32F3 has two sensors you'd be using:
LSM303DLHC accelerometer and magnetometer
L3GD20 3-axis digital gyroscope.
The sensor accuracy should appear somewhere in the datasheet. Since you'll be using several sensors, you'll have to calculate the total error over the time your measuring. Note, the error won't be a single number like 10 meters because it will accumulate over time. If you had a GPS or some other way of determining your position you'd be able to limit your accumulated error.
What you're doing sounds like an Inertial Measurement Unit. If you haven't already, I'd recommend reading up on that and also Dead Reckoning.

Finding distance using accelerometer in iPhone

Please suggest some beginning point in this process of finding distance displaced by an iPhone. The requirement of accuracy in current system is in cm, and displacement can be in 3D.
What I have already done is
1. Tried using sound to calculated distance between between 2 iPhones, but I need distance calculation with one iPhone only, i.e need displacement.
2. Tried CMMotionManager and its accelerometer data, but values received is helpless.
I think I need a good filter to get useful data out of that junk. I already used Kalman Filter and gone through link
iphone accelerometer speed and distance,
How to calculate distance using accelerometer using iphone sdk?,
How do I measure the distance traveled by an iPhone using the accelerometer?,
Basic calculus behind this problem is in the expression
Tried DCT-II algorithm and Multidimensional DCTs to filter data.
I dont know what did I miss, or where should I go from here, as it is hard to believe that no one has used accelerometer for such an accuracy, because there are so many practical examples of it being used for greater accuracy.
Please provide me some pointer that suggest some way out of current situation.
You can't achieve cm accuracy. The reason is, surprisingly, the orientation error.
The above link contains some tips what you can do if you need displacement.
An even better alternative is to use orientation in you application, if you can.

iPhone - What does the gyroscope measures? Can I get an absolute degree measurement in all axis?

I am relatively new to iPhone development and I am playing with the gyroscope, using Core Motion. After a few tests, this is my question.
What information is exactly the gyroscope measuring? absolute angles? I mean, suppose I hold my phone in portrait, at exactly 90 degrees and start sampling. These may be not the correct values, but suppose that at this position, the gyroscope gives me 0, 0 and 0 degrees for yaw, pitch and roll.
Now I throw my iphone in the air and as it goes up it rolls at random a high number of full turns in all axis and returns to my hand at the same position as before. Will the gyroscope read 0,0,0 (meaning that it has the same position as before = absolute angle) or not?
If not, there's a way to measure absolute degrees in all axis? As absolute degrees I mean assuming 0,0,0 as the position it was when the sampling started.
thanks
The gyroscope measures many things for you, and yes, one of these is "absolute angles". Take a look at the docs on CMDeviceMotion. It can give you a rotation rate, which is how fast the device is spinning, and it can give you a CMAttitude. The CMAttitude is what you're calling "absolute angles". It is technically defined as:
the orientation of a body relative to
a given frame of reference
The really nice thing is that normal gyroscopes, as noted in the other answer, are prone to drift. The Core Motion framework does a lot of processing behind the scened for you in an effort to compensate for the drift before the measurements are reported. Practically, I've found that the framework does a remarkable (though not perfect) job at this task. Unless you need long term precision to a magnetic pole or something, the attitude reported by the framework can be considered as a perfect relative attitude measurement, for all intents and purposes.
The iPhone uses accelerometers for its internal angle measurements, which means they are relative to the Earth's gravity. That's about as absolute as you're going to get, unless you need this program to work in space, too.

Compensating compass lag with the gyroscope on iPhone 4

I've been experimenting with the compass and gyroscope on iPhone 4 and would like some help with an issue I'm having. I want to compensate for the slowness of the compass by using data from the gyroscope.
Using CMMotionManager and its CMDeviceMotion object (motionManager.deviceMotion), I get the CMAttitude object. Correct me if I'm wrong (please), but here is what I've deduced from the CMAttitude object's yaw property (I don't need pitch nor roll for my purposes):
yaw ranges from 0 to PI when the phone is pointing downwards (as indicated by deviceMotion.gravity.z) and swinging counterclockwise and 0 to -PI when swung clockwise
when the device is pointing upwards, yaw ranges from -PI to 0 and PI to 0, respectively
and from the compass data (I'm using locationManager.heading.magneticHeading), I see that the compass gives values from 0 to 360, with the value increasing when swinging clockwise
All right, so using all of this information together, I'm able to get a value I call horizontal that, regardless of whether the device is pointing up or down, will give values from 0 to 360 and increase when the device is swung clockwise (though I am still having trouble when deviceManager.gravity.z is around 0 -- the yaw value freaks out at this gravity.z value).
It seems to me that I could "synchronize" the horizontal and magneticHeading values, using a calculated horizontal value that maps to magneticHeading, and "synchronize" the horizontal value to magneticHeading when I feel the compass has "caught up."
So my questions:
Am I on the right track with this?
Am I using the gyro data from CMDeviceMotion properly and the assumptions I listed above correct?
Why might yaw freak out when gravity.z is around 0?
Thank you very much. I look forward to hearing your answers!
Just trying to answer... correct me if i'm wrong..
1.Yes you are on the right track
2.gravity in CM is already "isolated" from user gravity (gravity value caused by user acceleration) thats why there is two gravity, the "gravity" and "userAcceleration" its on apple CM documentation
// Note : not entirely isolated //
3.
if you have a gravity 0 it mean that the coresponding axis is perpendicular with gravity.
gravity.z is the iPhone screen thats why it -9.82m/s2 if you put on the desk with screen upright, actualy it hard to get 0 or maximum value of the gravity due to the sensor noise (it's normal, all sensor has a noise expecially cheap sensor).
what i do on my apps is I will switch my reference axis to other axis (in your case may be x or y) for certain limits, how the strategy is depend on the purpose or which side is your reference.
the other thing is, gyro is fast but its not stable, you need to re-calibrate the value for several interval. In my case every 5 second. I've experiment with gyro for calculating angle between two plane, i try with exacly 90 degree ruler and it will give an error about 0.5 degree every second try and keep increasing, but thats is mine, maybe others have a better method for avoid the error.
below is my steps "
Init
Read gravity XYZ -> Xg Yg Zg
Check if Xg < 0.25 If TRUE try Yg then Zg // Note 1 = 1g = 9.82 m/s^2
Read the compass and gyro
Configure and calibrate the gyro using the compass and calulate based on which axis i use in point 3.
If 5 second is pass then recalibrate, read the compass
If the the difference with gyro reading is > 5 degree skip recalibartion the gyro.
If the the difference with gyro reading is < 5 degree calibrate the gyro using compass value
Note: for number 7 : is to check if the phone affected with magnetic field or near huge steel such or high voltage electrical line or in noisy and heavy equipment in factory plant.
Thats all... Hope this could help you...
And sorry for my english..
Here is an example of an iPhone app where the compass get compensated with the gyroscope. Code and project can be seen here:
http://www.sundh.com/blog/2011/09/stabalize-compass-of-iphone-with-gyroscope/
The direction of the yaw axis vector is undefined when in zero gravity (or free fall, or close enough).
In order to do synchronization while in motion, you need to create a filter for your "horizontal" value that has the same lag/delay response characteristics as the magnetic compass. Either that, or wait until motion stops long enough for both values to settle before recalculating the offset.
Answer to question 1 is Yes, question 2 you are on the right track but you could use a variable name that is not 'horizontal', question 3 is answered by hotpaw2 and also a yaw in a chopper or helicopter at near zero altitude would alert the pilot with an alarm. There is a time lag because part of the software is local while there are other factors which can slow it down including access to a sensor for detecting magnetic waves, the device position and direction, preparing the graphic output for the compass display, computing and outputting data from the gyro and sensors through a relatively slow interface, using a general purpose handheld device not custom designed for the type of task being asked of it.