加速度計を使用したiPhoneソフトウェア開発の原則

この記事では、iPhoneの加速度計の動作原理を説明し、加速度計を主要コンポーネントとして使用するアプリケーションの例を示し、加速度計の使用に関する推奨事項を示します。 また、Webアプリケーションで加速度計を使用する方法も示します。 一部の資料は、「 加速度計の助けを借りてスクロールする 」という記事から引用したものです。



加速度計とは何ですか?



ウィキペディアに目を向ける:

加速度計 (lat。Accelero-私は加速し、μετρέω-私は測定します)-見かけの加速度の投影を測定するデバイス。 見かけの加速度は、質量に作用する非重力の力の結果であり、この質量の大きさを指します。 加速度計は、絶対直線加速度の投影の測定と、重力加速度の投影の間接測定の両方に使用できます。 最後のプロパティは、傾斜計を作成するために使用されます。 加速度計は慣性航法システムの一部であり、それらの助けを借りて得られた測定値が統合され、キャリアの慣性速度と座標を取得します。 電子加速度計は、多くの場合モバイルデバイス(特に電話)に組み込まれ、歩数計、空間内の位置を決定するセンサー、ディスプレイの自動回転などの目的で使用されます。 ゲーム機では、ボタンを使用せずに、空間を回したり、揺れたりするなどして、加速度計を使用して制御します




Appleは、携帯電話に加速度計を実装した最初の会社ではありませんが、それを最初にうまく行っています。



加速度計はどのように使用できますか?



技術的な部分に移る前に、加速度計を使用する既製のアプリケーションを見てみましょう。



いくつかの基本的な例:








iBeerを使用すると、仮想ビールを飲むことができます。







iBoobsは、Appleの検閲部門を通過していないプログラムです。







他のプログラムの概要は、以下のリンクで見つけることができます。



理論のビット



iPhone内の加速度センサーは、シリコンボディ、シリコンスプリングセット、電流の3つの要素を使用します。 シリコンスプリングは、電流を使用してシリコンボディの位置を決定します。 iPhoneの電源を入れると、シリコンスプリングを流れる電流に変動があります。 加速度センサーはこれらの変動を検出し、ディスプレイ上の画像の必要な変更についてiPhoneに通知します。



iPhoneは、 MEMS 3軸モーションセンサーを使用しています。 ±2g /±8gスマートデジタル出力ピッコロ加速度計の仕様は、こちらからダウンロードできます



静止時、デバイスが動かない場合、測定された加速度は重力に等しく、統一されたと見なされます。 座標軸上のこの力の投影値の比率は、空間内のデバイスの回転角度を示します。 iPhoneが動いている場合、投影値に基づく追加の変換を使用して、デバイスが加速する加速量を計算できます。



これは加速であり、デバイスの速度ではないことに注意してください。 つまり、iPhoneが地面に落ち始めると、加速度値の投影はすべての軸で値0になります-iPhoneは無重力状態になります:)そして、エレベータで適切な加速度で上昇すると、重力の値は加速度の時間で増加します。



加速度計インターフェース



いくつかの事実:


クラス:


プロトコル:




座標軸



座標X、Y、Zは、推測できるように、空間内のデバイスの座標(位置)を示していないことにすぐに注意します。 実際、次のことを意味します。







Axis Axis Accelerometer iPhone



iPhoneの任意の向きの場合、加速度データは、加速度ベクトルの投影に従って軸に沿って分布します。



iPhoneの任意の位置での座標軸上の重力ベクトルの投影

任意のiPhone位置のベクトル計算



加速度計をプロジェクトに接続します



必要な情報はすべて、 UIAccelerationクラスのオブジェクトによって蓄積されます。UIAccelerationクラスは、すべての軸上のデータと、指定された相対測定時間を決定できるタイムマーカーを返します。

数量。 このクラスのデータに直接アクセスすることはできません。この情報はデリゲートUIAccelerometerDelegateを介してのみ取得できます。これは、実装のための単一のメソッドを提供します

accelerometer:didAccelerateUIAccelerationクラスのオブジェクトが返す先 。 デリゲートを割り当て、呼び出しをaccelerometer:didAccelerate:に初期化するには、 UIAccelerometerクラスを使用します。



加速度計を接続するには、applicationDidFinishLaunchingメソッドに次のコードを記述する必要があります。



  [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0 / kUpdateFrequency];
 [[UIAccelerometer sharedAccelerometer] setDelegate:self]; 




setUpdateIntervalメソッドはデータリフレッシュレートを設定します。kUpdateFrequencyは、データを受信する頻度を示す係数です。



たとえば、 #define kUpdateFrequency 60.0の場合、1秒あたり60のポーリングを取得します。



さらに、デリゲートクラスのヘッダーファイルでUIAccelerometerDelegateプロトコルを指定する必要があります。



  @interface AppDelegate:NSObject <UIApplicationDelegate>
 @interface accelerometerAppDelegate:NSObject <UIApplicationDelegate、UIAccelerometerDelegate> 




デリゲートクラスのdidAccelerateメソッドに加速度計のデータ処理ロジックを追加する必要があります。



  -(void)加速度計:(UIAccelerometer *)加速度計didAccelerate:(UIAcceleration *)加速度
 {
     //イベントデータを取得します
     UIAccelerometValue x、y、z; 
    
     x = accelerator.x;
     y = accelerator.y;
     z = accelerator.z;
 } 




備考:



加速度計のセットアップ:





値の受信を停止するには、次のコードを呼び出す必要があります。

 -(void)disableAccelerometerEvents
 {
 UIAccelerometer * acc = [UIAccelerometer sharedAccelerometer];
 acc.delegate = nil;
 } 




傾斜角



幾何学的には、次のように加速度計の動作を表示できます。



図から、角度は逆正接関数を使用して計算できることがわかります。



フロート角= atan2(y、-x);



加速度計の位置は図で見ることができます:





回転角度情報を使用して画面の向きを変更できます。



  -(void)加速度計:(UIAccelerometer *)加速度計didAccelerate:(UIAcceleration *)加速度
 {
	 //現在のデバイスの角度を取得します
	 float xx =-[加速度x];
	 float yy = [加速度y];
	フロート角= atan2(yy、xx); 
 
	 //角度を1.5に追加して、ラベルを視聴者に対して常に水平に保ちます。
	 [interfaceOrientationLabel setTransform:CGAffineTransformMakeRotation(angle + 1.5)]; 
 
	 //角度の詳細については、ブログをご覧ください。 明らかなはずです
	 //ここでカスタムshouldAutorotateToInterfaceOrientation-eventを起動できます。
	 if(angle> = -2.25 && angle <= -0.75)
	 {
		 if(deviceOrientation!= UIInterfaceOrientationPortrait)
		 {
			 deviceOrientation = UIInterfaceOrientationPortrait;
			 [interfaceOrientationLabel setText:@ "UIInterfaceOrientationPortrait"];
		 }
	 }
	 else if(angle> = -0.75 && angle <= 0.75)
	 {
		 if(deviceOrientation!= UIInterfaceOrientationLandscapeRight)
		 {
			 deviceOrientation = UIInterfaceOrientationLandscapeRight;
			 [interfaceOrientationLabel setText:@ "UIInterfaceOrientationLandscapeRight"];
		 }
	 }
	 else if(angle> = 0.75 && angle <= 2.25)
	 {
		 if(deviceOrientation!= UIInterfaceOrientationPortraitUpsideDown)
		 {
			 deviceOrientation = UIInterfaceOrientationPortraitUpsideDown;
			 [interfaceOrientationLabel setText:@ "UIInterfaceOrientationPortraitUpsideDown"];
		 }
	 }
	 else if(角度<= -2.25 ||角度> = 2.25)
	 {
		 if(deviceOrientation!= UIInterfaceOrientationLandscapeLeft)
		 {
			 deviceOrientation = UIInterfaceOrientationLandscapeLeft;
			 [interfaceOrientationLabel setText:@ "UIInterfaceOrientationLandscapeLeft"];
		 }
	 }
 } 




サンプルアプリケーションをここからダウンロードします



例1.加速度計を使用したスクロール


後壁と地面の間の角度が45度になる空間でのデバイスの位置の基準点を取ります。 この場合、Y軸上の重力の投影は-0.7になります。 デバイスを垂直位置に少し近づけて拒否した場合、垂直から30度の角度に達したら、リストを最後まで回転させる必要があると想定します。 逆に、水平位置から30度以下の角度に達すると、リストを先頭に向ける必要があります。

最初の場合、装置に沿って向けられたY軸上の重力の投影の絶対値は0.86になります。 この値がどこから来たのか分からない人は、単位長さベクトルの座標軸への投影のジオメトリと計算を思い出してください。 2番目の場合、同じ値は0.5です。 スクロールを実装するには、UITableViewクラスのscrollToRowAtIndexPath:atScrollPosition:animated:メソッドを使用します。



 -(void)加速度計:(UIAccelerometer *)加速度計didAccelerate:(UIAcceleration *)加速度{double absY = fabs(acceleration.y);  if(absY <= 0.5){//リストの一番上までスクロール[viewController.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];  } else if(absY> = 0.86){//リストの最後までスクロール[viewController.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([list count]-1)inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];  }} 




フィルター



基本的に、 ハイパスhigh-pass )とローパスlow-pass )の2つのフィルターが使用されます。 これらのフィルターは、「ジッター」の影響を除去するために使用できます。

遅いターンなど



ローパスフィルターを使用してデバイスの向きを見つけ、ハイパスフィルターを使用して揺れを判断します。



最も単純なローパスフィルターは、次のコードを実装します。

  #define FILTERFACTOR 0.1
値=(newAcceleration * FILTERFACTOR)+(previousValue *(1.0-FILTERFACTOR));
 previousValue = value; 




最も単純なハイパスフィルターは、次のコードを実装します。



  #define FILTERFACTOR 0.1
値= newAcceleration-(newAcceleration * FILTERFACTOR)+(previousValue *(1.0-FILTERFACTOR));
 previousValue = value; 




例2. AccelerometrGraph


加速度計の動作を研究するための優れたプログラム-3つの座標の値の変化を示します。 Appleの公式Webサイトからダウンロードできます。



通常モードでは、受信した情報を正確に表示します。 また、通常のターンを遮断し、揺れにのみ応答するフィルターを使用することもできます(基本的に、実際のアプリケーションでは必要な場合があります)。



例3. iBells




iBells(appstoreへのリンク)は、ユーザーの操作に応答してベルの音を再生するエンターテイメントプログラムです。



このプログラムの開発者として、次の問題を解決する必要がありました。





振動に対する正しい応答は、ハイパスフィルターを使用して実現できます。



  -(void)acceleratorWithX:(フロート)x Y:(フロート)y Z:(フロート)z
 {
     //渡された座標に二重フィルタリングを使用します
    加速[0] = x * kFilteringFactor +加速[0] *(1.0-kFilteringFactor);
     x = x-加速[0];
    
    加速[1] = y * kFilteringFactor +加速[1] *(1.0-kFilteringFactor);
     y = y-加速度[1];
     
    加速[2] = z * kFilteringFactor +加速[2] *(1.0-kFilteringFactor);
     z = zは加速度です[2]。
 } 




kFilteringFactor-ランダムな変動に対する反応の「減衰」係数。 このパラメーターは、要件に応じて個別に選択する必要があります。



間隔は単純に測定されます:

  NSDate * now = [NSDate date];
     NSTimeInterval interval = [現在timeIntervalSinceDate:self.lastPlayedTime];
           
     //再生時間条件を確認します
     if(間隔> minTimeDelta)
     {
         [セルフプレイ];
     } 




lastPlayedTime変数は、最後の再生時間、 minTimeDelta-音楽ファイルを再生できる最小期間をキャプチャします。



私は最近、揺れ検出する別の方法を見つけました



  //シェイクを宣言する前に、少なくとも2つの軸でシェイクが十分に強いことを確認します。
 //「十分に強い」とは、Gの「クライアントが提供するしきい値よりも大きい」ことを意味します。
 static BOOL L0AccelerationIsShaking(UIAcceleration * last、UIAcceleration * current、double threshold){
        ダブル
                 deltaX = fabs(last.x-current.x)、
                 deltaY = fabs(last.y-current.y)、
                 deltaZ = fabs(last.z-current.z);

        帰る
                 (deltaX>しきい値&& deltaY>しきい値)||
                 (deltaX>しきい値&& deltaZ>しきい値)||
                 (deltaY>しきい値&& deltaZ>しきい値);
 }

 @interface L0AppDelegate:NSObject {
         BOOL履歴
         UIAcceleration * lastAcceleration;
 }

 @property(保持)UIAcceleration * lastAcceleration;

 @end

 @implementation L0AppDelegate

 -(void)applicationDidFinishLaunching:(UIApplication *)application {
         [UIAccelerometer sharedAccelerometer] .delegate = self;
 }

 -(void)加速度計:(UIAccelerometer *)加速度計didAccelerate:(UIAcceleration *)加速度{

         if(self.lastAcceleration){
                 if(!histeresisExcited && L0AccelerationIsShaking(self.lastAcceleration、accelerator、0.7)){
                         histeresisExcited = YES;

                         / *シェイクが検出されました。 ここで何をしたいのですか。  * /

                 } else if(histeresisExcited &&!L0AccelerationIsShaking(self.lastAcceleration、accelerator、0.2)){
                         histeresisExcited = NO;
                 }
         }

         self.lastAcceleration =加速;
 }

 //適切な@synthesizeおよび-deallocボイラープレートコード

 @end 




Webアプリケーションで加速度計を使用する



Safariに新しいonorientationchangeメソッドが追加されました。これは、位置が90%変化したときに機能します。 以下は、Webページの向きを変更するために使用できるJavaScriptコードです。



 関数updateOrientation(){
     / *
         window.orientationは、iPhoneがポートレートモードかどうかを示す値を返します。 
        画面を左にした横長モード、または横長モード 
        画面を右に向けて。 
     * /
     var orientation = window.orientation;

    スイッチ(方向) 
     {
        ケース0:
             / *
                ポートレートモードの場合、ボディのクラス属性をポートレートに設定します。 
                その結果、本文に一致するすべてのスタイル定義[class = "portrait"] 
                 iPhoneOrientation.cssファイルの宣言が選択され、使用されます 
                 「iPhoneまたはiPod touchのオリエンテーションイベントの処理」をスタイル設定します。
             * /
             document.body.setAttribute( "class"、 "portrait");
        
             / *
                 「iPhoneまたはiPod touchのオリエンテーションイベントの処理」に説明的なメッセージを追加します 
             * /
             document.getElementById( "currentOrientation")。innerHTML 
                 = "現在、縦向きになっています(下部にあるホームボタン)。";
            休憩; 

        ケース90:
             / *
                画面を左に向けた横向きモードの場合、 
                ボディのクラス属性をlandscapeLeftに設定します。 
                この場合、本文に一致するすべてのスタイル定義[class = "landscapeLeft"] 
                 iPhoneOrientation.cssファイルでの宣言は 
                 「iPhoneまたはiPod touchの向きイベントの処理」のスタイル設定に選択および使用されます。
             * /
             document.body.setAttribute( "class"、 "landscapeLeft");
             document.getElementById( "currentOrientation")。innerHTML 
                 = "横向きになり、左に回転します(右にホームボタン)。";
            休憩;

        ケース-90: 
             / * 
                画面が右になっている横向きモードの場合、 
                ボディのクラス属性をlandscapeRightに設定します。 
                ここでは、本文に一致するすべてのスタイル定義[class = "landscapeRight"] 
                 iPhoneOrientation.cssファイルの宣言が選択され、使用されます 
                 「iPhoneまたはiPod touchのオリエンテーションイベントの処理」をスタイル設定します。
             * /
             document.body.setAttribute( "class"、 "landscapeRight");
            休憩;
     }

 window.onorientationchange = updateOrientation;

 <div id = "currentOrientation" style = "font-size:40px;">
          縦向きになりました(下部にある[ホーム]ボタン)</ div> 




Webページの例は、 こちらこちらでご覧いただけます



加速度計とシミュレータ



明らかな理由により、シミュレータでアプリケーションをテストすることはできません。 これを行うには、実際のデバイスを使用します。



リンクを使用すると、シミュレーターにデータを転送する方法を確認できます(ここからダウンロードできます)。 しかし、実際のデバイスはまだそこで使用されているため、実用的な

これには意味がありません。 ただ楽しみのために。



リンクと追加資料











PSこの記事の著者はアレクサンダー・クラコヴェツキー( sashaeve )です。 招待してくれてありがとう、 スピークス



All Articles