迅捷陀螺仪偏航,俯仰,滚动 [英] Swift gyroscope yaw, pitch, roll

查看:64
本文介绍了迅捷陀螺仪偏航,俯仰,滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的学校做一个项目,一个编程课程.我正在Swift中使用Xcode.我想制作一个使用陀螺仪的应用程序.我不知道,但是由于Xcode的一些错误,我不知道如何解决该问题,但我不知道如何解决.运行程序时显示严重错误:在解开Optional值时意外发现nil (lldb)" 我项目的主要内容是使用陀螺仪在iPhone屏幕上以度为单位显示旋转(偏航,俯仰,横滚).如果有人帮助我,我将不胜感激.先感谢您.

I'm doing a project for my school, for a programming subject. I'm working in Xcode in Swift. I would like to make an application that uses Gyroscope. I don't know but somehow it won't run on my iphone because of some errors in Xcode that I don't know how to fix.When I run the program is says "fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)" The main thing of my project is to display rotations (yaw,pitch,roll) in degrees on iphone screen using gyroscope. I would be really grateful if someone help me with this. Thank you in advance.

ViewController中的代码:

The code in my ViewController:

import UIKit
import CoreMotion

class ViewController: UIViewController {

    var currentMaxRotX: Double = 0.0
    var currentMaxRotY: Double = 0.0
    var currentMaxRotZ: Double = 0.0

    let motionManager = CMMotionManager()

    @IBOutlet var rotX : UILabel! = nil
    @IBOutlet var rotY : UILabel! = nil
    @IBOutlet var rotZ : UILabel! = nil

    @IBOutlet var maxRotX : UILabel! = nil
    @IBOutlet var maxRotY : UILabel! = nil
    @IBOutlet var maxRotZ : UILabel! = nil


    @IBOutlet weak var RollLabel: UILabel! = nil

    @IBOutlet weak var PitchLabel: UILabel! = nil

    @IBOutlet weak var YawLabel: UILabel! = nil

    override func viewDidLoad() {

        if motionManager.gyroAvailable {

            if !motionManager.gyroActive {
                motionManager.gyroUpdateInterval = 0.2
                motionManager.startGyroUpdates()
                //motionManager = [[CMMotionManager alloc]init]; should I use this ???
                //motionManager.deviceMotionUpdateInterval = 0.2;
                //motionManager.startDeviceMotionUpdates()

                 motionManager.startGyroUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler: {(gyroData: CMGyroData!, error: NSError!)in
                     self.outputRotationData(gyroData.rotationRate)
                     if (error != nil)
                     {
                         println("\(error)")
                     }
                 })      
            }
       } else {
              var alert = UIAlertController(title: "No gyro", message: "Get a Gyro", preferredStyle: UIAlertControllerStyle.Alert)
              alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
              self.presentViewController(alert, animated: true, completion: nil)
    }


     super.viewDidLoad()
    }

    // radians to degrees
    func radians(fromDegrees degrees: Double) -> Double {
        return 180 * degrees / M_PI
    }

    func outputRotationData(rotation:CMRotationRate)
    {
        rotX.text = NSString(format:"Rotation X: %.4f",rotation.x)
        if fabs(rotation.x) > fabs(currentMaxRotX)
        {
            currentMaxRotX = rotation.x
        }

        rotY.text = NSString(format:"Rotation Y: %.4f", rotation.y)
        if fabs(rotation.y) > fabs(currentMaxRotY)
        {
            currentMaxRotY = rotation.y
        }
        rotZ.text = NSString(format:"Rotation Z:%.4f", rotation.z)
        if fabs(rotation.z) > fabs(currentMaxRotZ)
        {
            currentMaxRotZ = rotation.z
        }

        maxRotX.text = NSString(format:"Max rotation X: %.4f", currentMaxRotX)
        maxRotY.text = NSString(format:"Max rotation Y:%.4f", currentMaxRotY)
        maxRotZ.text = NSString(format:"Max rotation Z:%.4f", currentMaxRotZ)

        var attitude = CMAttitude()
        var motion = CMDeviceMotion()
        motion = motionManager.deviceMotion
        attitude = motion.attitude


        YawLabel.text = NSString (format: "Yaw: %.2f", attitude.yaw)    //radians to degress NOT WORKING
        PitchLabel.text = NSString (format: "Pitch: %.2f", attitude.pitch)//radians to degress NOT WORKING
        RollLabel.text = NSString (format: "Roll: %.2f", attitude.roll)//radians to degress NOT WORKING
      }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

推荐答案

在这两行中,您使用的是隐式解包的可选对象:您在不使用?!的情况下使用它们,但是如果出现以下情况,它们将使程序崩溃他们是nil.在这种情况下,motionManager.deviceMotionnil,因为您没有在该访问之前调用motionManager.startDeviceMotionUpdates().

In these two lines you're working with implicitly unwrapped optionals: you use them without ? or !, but they'll crash your program if they're nil. In this case, motionManager.deviceMotion is nil because you haven't called motionManager.startDeviceMotionUpdates() prior to that access.

您的viewDidLoad方法是执行此操作的正确位置:

Your viewDidLoad method is the right place to do this:

override func viewDidLoad() {

    if motionManager.gyroAvailable {
        motionManager.deviceMotionUpdateInterval = 0.2;
        motionManager.startDeviceMotionUpdates()

        motionManager.gyroUpdateInterval = 0.2
        motionManager.startGyroUpdatesToQueue(NSOperationQueue.currentQueue()) {
           [weak self] (gyroData: CMGyroData!, error: NSError!) in

           self?.outputRotationData(gyroData.rotationRate)
           if error != nil {
               println("\(error)")
           }
        }
    } else {
        // alert message
    }

    super.viewDidLoad()
}

还有一些其他更改:

  1. 您无需在startGyroUpdatesToQueue()之前致电startGyroUpdates().
  2. Swift使用跟踪闭包,用于像这样的完成处理程序-更好地编写和读取.
  3. 为避免引用循环,请在完成处理程序内将self声明为weak-然后在访问self时需要使用可选链接.
  1. You don't need to call startGyroUpdates() before startGyroUpdatesToQueue().
  2. Swift uses trailing closures for completion handlers like this one - nicer to write and read.
  3. To avoid a reference cycle, declare self as weak inside a completion handler - this then requires using optional chaining when accessing self.

这篇关于迅捷陀螺仪偏航,俯仰,滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆