iOS core motion detect forard / backward tilt

你。 提交于 2019-12-08 01:30:18

问题


I am using the iOS core motion framework to detect if the device is tilted forward or backwards. See image for details: http://i.stack.imgur.com/2Ojw5.jpg

Using the pitch value a can detect this movement but I can not distinguish between forward AND backward.

More details:

I try to detect if there is a movement (tilting forward and backward) in either the forward area OR backward area (see updated sketch).

The problem with the pitch is that it starts with a value of about 1.6 if the device is in an upright position. And the value decreases the same when I am tilting it towards a horizontal potion either forward or backward. The same behavior applies to the accelerometer y value.

It looks like I miss something in the whole core motion thing. ANy Ideas

thanks christian


回答1:


Using attitude pitch, leaning forward and backward are indistinguishable. However with quaternions you can calculate pitch, and if you convert radians to degrees,

  • 0 means the device is on its back
  • 90 means it's standing up
  • 180 means it's on its face

The opposite hemisphere of rotation is 0 to -180. Here's the code:

func radiansToDegrees(_ radians: Double) -> Double {
    return radians * (180.0 / Double.pi)
}

let quat = motionData.attitude.quaternion
let qPitch = CGFloat(radiansToDegrees(atan2(2 * (quat.x * quat.w + quat.y * quat.z), 1 - 2 * quat.x * quat.x - 2 * quat.z * quat.z)))



回答2:


Try this:

// Create a CMMotionManager
CMMotionManager *mManager = [(AppDelegate *)[[UIApplication sharedApplication] delegate] sharedManager];
// Check whether the accelerometer is available
if ([mManager isAccelerometerAvailable] == YES) {
    [mManager setAccelerometerUpdateInterval: .02];
    [mManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
        [self updateGravityWithAccelerometerX:accelerometerData.acceleration.x y:accelerometerData.acceleration.y z:accelerometerData.acceleration.z];
    }];
}

This will call updateGravityWithAccelerometerData every .02 seconds. You should be able to create that method and use NSLog to watch the values change to decipher what you are looking for. I believe you are looking for the acceleration.y value.




回答3:


You are right, pitch works that way, considering the 4 typical quadrants (http://en.wikipedia.org/wiki/Quadrant_(plane_geometry)) and the counterclockwise direction:

  • Quadrant I, values range from 0 to PI/2 (or 0 to 90 in degrees).
  • Quadrant II, values range from PI/2 to 0 (or 90 to 0 in degrees).
  • Quadrant III, values range from 0 to -PI/2 (or 0 to -90 in degrees).
  • Quadrant IV, values range from -PI/2 to 0 (or -90 to 0 in degrees).

Considering this looks pretty obvious that you cannot difference between the phone leaning forwards or backwards.

I have recently faced the same problem for an iOS app that counts the number of flips that the phone does. Apple has rejected it so I have published it on GitHub, may be useful for you:

Flip Your Phone! - https://github.com/apascual/flip-your-phone




回答4:


You don't want to read the accelerometer for tilt. Accelerometer is for detecting differences in movements. You want the gyroscope so you can determine the absolute attitude (i.e. yaw, pitch and roll). In your case it sounds like you just want roll.

Use startDeviceMotionUpdatesToQueue and then attitude.roll for front and back and attitude.pitch for side to side. Here is what I did in Swift:

    func motion(data: CMDeviceMotion){  

    let pitch = data.attitude.pitch
    let roll = data.attitude.roll

    let dampener:Float = -0.25 // the ball was rolling too fast

    var forward_force = Float(1.6 - roll) * dampener  //1.6 is vertical
    var side_force = Float(pitch) * dampener  // 0 is untilted when rotating cw/ccw

    ballNode.physicsBody?.applyForce(SCNVector3Make(side_force, 0, forward_force), atPosition: SCNVector3Make(0, 0, 0), impulse: true)

}

With this you can see if it tilted frontward or backward based on whether the roll is greater than or equal to 1.6 which is approximately straight up.



来源:https://stackoverflow.com/questions/20379830/ios-core-motion-detect-forard-backward-tilt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!