モバイルセンサ融合と姿勢推定

生の加速度・ジャイロは単体では使い物にならない。融合の原理と姿勢推定・歩数の仕組みを押さえれば、ドリフトや電力を制御できる高精度なモーション機能を実装できる。

応用モバイルセンサ姿勢推定CoreMotioniOS/Android電力効率最終更新: 2026-07-29
3つの要点
TL;DR
  1. 加速度計は重力ノイズに弱く、ジャイロは積分で漂う。両者の弱点を周波数分割で補い合うのが相補・カルマン系フィルタの核心で、CoreMotionやSensorManagerはこの融合を内部で完結させたattitudeを返す。
  2. 姿勢(attitude)はロール・ピッチ・ヨーの3自由度。加速度と磁気で絶対基準を得られる2軸に対し、ヨーは磁気に頼るため磁気外乱で最も崩れやすい。
  3. センサレート・バッチング・ハードウェア歩数計は電力トレードオフの三点セット。高レート常時取得よりFIFOバッチングやコプロセッサ委譲がバッテリを大きく左右する。

生センサはなぜ単体で使えないのか

スマートフォンには加速度計・ジャイロスコープ・磁気センサ(磁力計)というMEMS慣性センサが載っていますが、どれも単体では姿勢や動きを正しく表せません。それぞれが異なる物理量を、異なる誤差特性で測っているからです。

加速度計は重力を含む合力(比力)を測ります。端末が静止していれば重力ベクトルの向きから傾きを復元できますが、端末を振ればユーザーの動きによる加速度が重力に重畳し、どこまでが傾きでどこからが運動かを区別できません。逆にジャイロスコープは角速度を測るため回転そのものは高精度に追えますが、角度を得るには積分が必要で、微小なバイアス誤差が時間とともに累積し、姿勢が少しずつ漂う(ドリフトする)性質を持ちます。磁気センサは地磁気から絶対的な方位を与えてくれますが、周囲の金属やスピーカーの磁石、電流が作る磁場の外乱に極めて弱いという弱点があります。

三者の誤差特性は周波数帯で相補的

加速度計と磁気センサは長期的には正しい基準(重力・地磁気)を指しますが、高周波の振動やノイズに弱い。ジャイロは短期的な速い回転を正確に追えますが、低周波では積分ドリフトが効いてくる。つまり「低周波は加速度・磁気が正しく、高周波はジャイロが正しい」という周波数帯での役割分担が成立します。センサ融合とは、この相補性を利用して各センサの得意な帯域だけを採用する処理に他なりません。

融合の原理:相補フィルタとカルマンフィルタ

最も直感的な融合が相補フィルタです。ジャイロを積分した姿勢にハイパスフィルタを、加速度・磁気から算出した姿勢にローパスフィルタをかけ、両者を足し合わせます。擬似コードで書くと次のようになります。

# alpha は 0.98 前後(1に近いほどジャイロ寄り)
angle = alpha * (angle + gyro * dt) + (1 - alpha) * accel_angle

第1項がジャイロの短期追従(ハイパス)、第2項が加速度の長期基準(ローパス)を担い、両者のカットオフ周波数が一致するよう alpha を選びます。軽量で実装しやすい一方、センサノイズを統計的に扱わないため最適ではありません。

より原理的な手法がカルマンフィルタで、状態(姿勢とジャイロバイアス)とその不確かさを共分散として保持し、ジャイロによる予測とセンサ観測を、それぞれの分散に応じた重み(カルマンゲイン)で統合します。回転を表す状態が非線形になるため、実際にはクォータニオンを状態に持つ拡張カルマンフィルタ(EKF)が広く使われます。重要なのは、これらの融合が推定の信頼度を動的に調整する点です。端末が激しく動いて加速度が信用できない局面ではジャイロの重みを上げ、静止して加速度が信用できる局面では加速度の重みを上げる、という切り替えが確率的に行われます。

オイラー角のジンバルロック

ロール・ピッチ・ヨーというオイラー角は直感的ですが、ピッチが90度に近づくとロールとヨーの回転軸が縮退し、一意に表せなくなるジンバルロックが起きます。このためフィルタ内部の姿勢表現にはクォータニオンや回転行列を使い、UIへ渡す最終段でのみオイラー角へ変換するのが定石です。地の文で3軸の集合を書くときも {roll, pitch, yaw} のように扱いは分けて考えます。

プラットフォームAPI:CoreMotionとSensorManager

こうした融合を、アプリ開発者が毎回EKFから実装する必要はありません。iOSとAndroidはOS側で融合を済ませた高レベルなAPIを提供します。

観点iOS (CoreMotion)Android (SensorManager)
生センサCMAccelerometer / CMGyro / CMMagnetometer を個別取得TYPE_ACCELEROMETER / TYPE_GYROSCOPE / TYPE_MAGNETIC_FIELD
融合済み姿勢CMDeviceMotion の attitude(CMAttitude、内部はクォータニオン)TYPE_ROTATION_VECTOR(融合済みの回転ベクトル)
ユーザー加速度userAcceleration(重力を除去済み)と gravity を分離提供TYPE_LINEAR_ACCELERATION と TYPE_GRAVITY で分離
歩数・歩行CMPedometer / CMMotionActivity(動作分類)TYPE_STEP_COUNTER / TYPE_STEP_DETECTOR
更新方式pull(現在値参照)と push(ハンドラ登録)SensorEventListener へコールバック

CoreMotionのCMDeviceMotionは、加速度・ジャイロ・磁気を融合したattitudeに加え、重力成分(gravity)とユーザー由来の加速度(userAcceleration)を分離して返します。この「重力とユーザー加速度の分離」こそ融合の恩恵で、生の加速度計だけでは不可能だった判定が可能になります。AndroidのTYPE_ROTATION_VECTORも同様に融合済みで、getRotationMatrixgetOrientationを通じて方位角・傾斜角へ変換できます。TYPE_LINEAR_ACCELERATIONは重力を差し引いた運動加速度のみを返す派生(合成)センサで、内部で融合が働いています。

attitude の基準系を意識する

CoreMotionのattitudeは初期化時の基準系を選べます。xArbitraryZVerticalは起動時の向きを基準にする(磁気に依存しない)ため磁気外乱に強く、ヨーの絶対方位が不要なゲームやジェスチャ検出に向きます。一方xTrueNorthZVerticalは真北を基準とし磁気センサを使うため、ARや方位表示には必要ですが磁気キャリブレーション(8の字を描く動作)と外乱の影響を受けます。ヨー軸だけが磁気に依存するという非対称性を理解しておくと、方位が突然飛ぶ不具合の切り分けが速くなります。

歩数推定と動作分類

歩数計(ペドメータ)は、融合されたモーションデータの応用例です。単純な加速度のピークカウントではなく、実際には歩行に特有の周期的パターンを認識します。歩行は上下・前後方向に約1.5〜2.5Hzの準周期的な加速度を生むため、この帯域のパターンマッチングやピーク検出で1歩を数え、走行やジョギングとは周期と振幅で区別します。iOSのCMPedometerはさらに歩数だけでなく距離・ペース・階段の昇降まで推定し、CMMotionActivityは静止・歩行・走行・自転車・自動車といった動作分類(アクティビティ認識)を確信度付きで返します。

横にスクロール

モバイルセンサ融合と姿勢推定について、歩数推定と動作分類を中心に端末内外の処理経路と設計判断を示す図
「歩数推定と動作分類」の処理境界と、実装・計測・判断の要点を整理します。

ここで実装上決定的に重要なのが、これらの処理がどこで動くかです。歩数のように常時計測したい機能を、アプリのCPUを起こし続けて実装するとバッテリが持ちません。そこで両プラットフォームとも、メインのアプリケーションプロセッサとは別の低消費電力コプロセッサ(センサハブ、iOSのMotionコプロセッサに相当)に歩数計測を委譲します。アプリが停止・サスペンド中でもコプロセッサが歩数を数え続け、アプリが起きたときにまとめて読み出せる設計です。このバックグラウンドでの継続計測は、/mobile-development/mobile-background-execution-limits/ が定める実行制限の下でも動作するよう、OS側が特別に用意した経路だと理解すると位置づけが明確になります。

センサレート・バッチング・電力のトレードオフ

センサ機能の電力を左右する最大の要素は、サンプリングレートと配信方式です。加速度計を200Hzで常時取得しコールバックのたびにCPUを起こせば、たとえ処理が軽くてもCPUがスリープに落ちきれず電力を浪費します。これは無線の間欠通信と同じ「起床回数が電力を支配する」構造で、詳しくは /mobile-development/mobile-battery-power-profiling/ の電力設計と地続きです。

FIFOバッチングという解

現代のセンサハブはハードウェアFIFOバッファを持ち、サンプルを一定量ためてからまとめてアプリへ配信できます。iOSではCMSensorRecorderによる記録や各APIのバッチ配信、AndroidではSensorManagerのregisterListenerに渡すmaxReportLatencyUs(最大遅延)がこれに当たります。最大遅延を1秒に設定すれば、センサハブは1秒分のサンプルをFIFOにためてから1回だけCPUを起こすため、200Hzでも起床は毎秒1回で済みます。サンプルの時間分解能は保ちつつCPUの起床頻度だけを下げられる点が要諦で、リアルタイム性が不要なログ用途では効果が絶大です。

設計判断低電力寄り高精度・低遅延寄り
サンプリングレート10〜50Hz(歩数・傾き検出)100〜200Hz(ジェスチャ・AR)
配信方式FIFOバッチング(maxReportLatency大)即時コールバック(遅延最小)
処理の担い手センサハブ/コプロセッサに委譲アプリCPUでリアルタイム処理
融合済みかOS提供の融合済みAPIを利用生センサを取得し独自EKFで融合

ここにレート選択の原則が現れます。姿勢や方位のように人間の動きに追従すれば十分な用途では50Hz程度で足り、レートを上げても電力を食うだけで体感は変わりません。逆にARのヘッドトラッキングや素早いジェスチャ判定では、遅延1フレームが破綻を招くため高レートと即時配信が要ります。センサ融合の恩恵を活かしつつ電力を抑える設計は、「必要なレートを見極め、許される限りバッチングでCPU起床を減らし、常時計測はコプロセッサへ逃がす」という三段構えに集約されます。なお高レートのモーションデータは歩容から個人を推定しうる機微情報であり、iOS・Androidともにモーション権限の同意を要求します。この扱いは /mobile-development/mobile-app-sandbox-permissions/ の権限モデルの一部です。

設計・レビューで問われる勘どころ

加速度計とジャイロの誤差が周波数帯で相補的であること、融合はその相補性を利用してドリフトと運動加速度の混入を同時に抑えること、そしてヨー(方位)だけが磁気に依存するため磁気外乱で最も崩れやすいこと。これらは頻出の論点です。実装面では、姿勢表現にクォータニオンを使いジンバルロックを避けること、常時計測はコプロセッサへ委譲すること、バッチングの最大遅延がリアルタイム性と電力のトレードオフを直接制御することを押さえておきたいところです。

まとめ

モバイルのモーション機能は、単体では使えない3種のMEMSセンサを、周波数帯での相補性に基づいて融合することで初めて実用になります。加速度・磁気が与える長期的な絶対基準と、ジャイロが与える短期的な高精度追従を、相補フィルタやクォータニオンEKFで統合し、CoreMotionのattitudeやAndroidのTYPE_ROTATION_VECTORとして提供されるのが現代の構図です。歩数のような常時計測は低消費電力コプロセッサへ委譲し、サンプリングレートとFIFOバッチングでCPUの起床頻度を制御する。この融合の原理と電力トレードオフの両輪を理解することが、ドリフトせず電池も食わないモーション機能を設計する条件になります。

モバイル開発の記事ガイド

モバイルセンサ融合と姿勢推定を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

モバイル

比較で見る軸

難易度: advanced / カテゴリ: モバイル開発 / タグ数: 6

導入後に効く点

姿勢(attitude)はロール・ピッチ・ヨーの3自由度。加速度と磁気で絶対基準を得られる2軸に対し、ヨーは磁気に頼るため磁気外乱で最も崩れやすい。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
モバイル開発
タグ数
6

判断チェックリスト

  • 自社の用途が「モバイル / センサ」に近いか確認する。
  • 強みである「加速度計は重力ノイズに弱く、ジャイロは積分で漂う。両者の弱点を周波数分割で補い合うのが相補・カルマン系フィルタの核心で、CoreMotionやSensorManagerはこの融合を内部で完結させたattitudeを返す。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

モバイルセンサ姿勢推定CoreMotioniOS/Android