0

私は Apple のEvent Handling Guide for iOSから作業しています。の近くに記載されている pull メソッドを使用していますstartAccelerometerUpdates。センサーから読み取る必要があるのは 1 回だけなので、pull メソッドは私の目的には問題ありません。

iPhone 4、iPad Mini、および iPad Retina の以下のコードではaccelerometerDatagyroDataおよびへの呼び出しから nil を取得しています。isGyroAvailable isMagnetometerAvailable YES` . 2 つの質問:magnetometerDataisAccelerometerAvailable,, andeach return

startAccelerometerUpdatesとからの結果をどのように決定しstartGyroUpdatesますか? それらはvoid関数なので、決して失敗しないと仮定できますか? (それ以外の場合は、 をスローまたは返しますBOOL)。

accelerometerDatagyroDataおよびへの呼び出しから最後のエラーを取得するにはどうすればよいmagnetometerDataですか?

編集:[NSThread sleepForTimeInterval:0.150f]センサーからデータを取得するために電話する必要がありました。それ以下の場合、センサーは有効なデータを生成しません。

スリープは 3 番目の質問を追加します: ハードウェアが存在するときにデータが確実に到着するようにするには、どのくらいの時間一時停止する必要がありますか?

前もって感謝します。

static CryptoPP::RandomPool pool;
static dispatch_once_t once = 0;

dispatch_once(&once, ^{
    CryptoPP::SecByteBlock seed(32);
    CryptoPP::OS_GenerateRandomBlock(true, seed.data(), seed.size());
    pool.IncorporateEntropy(seed.data(), seed.size());
});

// First, send in all the uninitialized data. Then:
//  sesnors[0,1,2] use accelerometer, if available
//  sesnors[3,4,5] use gyroscope, if available
//  sesnors[6,7,8] use magnetometer, if available
CryptoPP::SecBlock<double> sensors(3 * 3);
pool.IncorporateEntropy(sensors.BytePtr(), sensors.SizeInBytes());

CMMotionManager* mgr = [[CMMotionManager alloc] init];
if(mgr) {

    [mgr startAccelerometerUpdates];
    [mgr startGyroUpdates];
    [mgr startMagnetometerUpdates];

    [NSThread sleepForTimeInterval:0.150f];

    if([mgr isAccelerometerAvailable]) {
        CMAccelerometerData* accelData = [mgr accelerometerData];
        if(accelData) {
            sensors[0] = [accelData acceleration].x;
            sensors[1] = [accelData acceleration].y;
            sensors[2] = [accelData acceleration].z;
        }
    }

    if([mgr isGyroAvailable]) {
        CMGyroData* gyroData = [mgr gyroData];
        if(gyroData) {
            sensors[3] = [gyroData rotationRate].x;
            sensors[4] = [gyroData rotationRate].y;
            sensors[5] = [gyroData rotationRate].z;
        }
    }

    if([mgr isMagnetometerAvailable]) {
        CMMagnetometerData* magnetData = [mgr magnetometerData];
        if(magnetData) {
            sensors[6] = [magnetData magneticField].x;
            sensors[7] = [magnetData magneticField].y;
            sensors[8] = [magnetData magneticField].z;
        }
    }

    pool.IncorporateEntropy(sensors.BytePtr(), sensors.SizeInBytes());

    [mgr stopMagnetometerUpdates];
    [mgr stopGyroUpdates];
    [mgr stopAccelerometerUpdates];
    [mgr release], mgr = nil;
}
4

1 に答える 1

1

これを行う場合:

mgr startAccelerometerUpdates];
[mgr setAccelerometerUpdateInterval:0.01f];

つまり、0.01 秒後まで情報の受信を開始せず、それでもメイン スレッドがアイドル状態の場合にのみ更新を受信します

データをチェックする前に 0.01 秒待っているのではなく、実際には約 0.00000000001 秒待っています。よくわかりませんが、もっと長く待っても、メインスレッドをアイドル状態にする必要があるかもしれません。

ドキュメントに戻って、センサーから情報を読み取る方法を確認する必要があると思います。

ブロックを使用してモーション データを処理することをお勧めします。

[mManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
    // process data
}];

一度だけ必要な場合は、最初の値を受け取った直後に加速度計を停止するように指示できます。

于 2013-09-01T06:38:03.120 に答える