matlab-fuse-inertial-sensors について
MATLAB Navigation Toolbox で慣性センサー融合フィルターを選択、実装、調整するためのスキルです。センサー構成、必要な出力、リアルタイム処理かバッチ処理かに応じた選択を案内します。
主な機能
- 01センサー構成に応じたフィルター選択
- 02設定済み・柔軟型フィルターの案内
- 03タイムスタンプとデータ間隔の処理
- 04フィルターノイズ調整の案内
- 05状態と姿勢の結果表示
活用シーン
- 01IMU と GPS の測定値の融合
- 02センサー構成に合うフィルターの選択
- 03真値を用いたフィルターノイズ調整
- 04タイムスタンプ間隔を含む記録の処理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-fuse-inertial-sensorsインストール後、Claude Code で/matlab-fuse-inertial-sensorsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
manifest.yamlreferences/attitude-filters.mdinscf.mdinsekf.mdnavigation-filters.md詳細
使用する場合
MATLAB Navigation Toolbox で、慣性センサーフュージョンフィルターを選択、実装、または調整する場合に使用します。
使用しない場合
- 慣性センサーを使わない、ビジョンのみ、または LiDAR のみの SLAM:代わりに nav SLAM 関数を使用してください
- センサーのシミュレーションまたはデータ生成のみを行う場合:フィルターは不要です
- Simulink のモデルベースのセンサーフュージョン
フィルターの選択
ステップ 1 — 設定済みフィルターか、柔軟なフィルターか?
設定済みフィルターは、次のセンサーの組み合わせをそのまま扱えます。
- 加速度計 + 磁力計のみ(ジャイロなし)
- 加速度計 + ジャイロ(磁力計なし、GPS なし)
- 加速度計 + ジャイロ + 磁力計
- 加速度計 + ジャイロ + 磁力計 + 高度計
- 加速度計 + ジャイロ + GPS(地上車両、磁力計なし)
- 加速度計 + ジャイロ + GPS + 単眼ビジュアルオドメトリー(地上車両)
- 加速度計 + ジャイロ + 磁力計 + GPS(同期レート)
- 加速度計 + ジャイロ + 磁力計 + GPS(レートが混在、またはサンプルが欠落)
Is your sensor set one of the above?
│ No ─────────────────────────────────────────────────────► Step 2B (Flexible)
│ Yes
▼
Need a custom motion model (constant-velocity, bicycle, etc.)?
│ Yes ────────────────────────────────────────────────────► Step 2B (Flexible)
│ No
▼
Need RTS smoothing, StateCovariance output, or optimizer-based tune()?
│ Yes ────────────────────────────────────────────────────► Step 2B (Flexible)
│ No
▼
Batch-only processing (no real-time predict/fuse loop needed)?
│ Yes ────────────────────────────────────────────────────► Step 2B (Flexible)
│ No
▼
Step 2A (Configured)
ステップ 2A — 設定済みフィルターを選択する
What output do you need?
│
├─ Orientation only (no position)
│ │
│ ├─ Accel + Mag only (no gyro)
│ │ └──► ecompass [function, not object; single-shot; useful for filter init]
│ │
│ ├─ Accel + Gyro (no mag)
│ │ └──► imufilter [heading drifts over time without mag]
│ │
│ ├─ Accel + Gyro + Mag
│ │ ├──► ahrsfilter [default; KF-based, statistically tunable]
│ │ └── lowest compute cost needed?
│ │ └──► complementaryFilter [gain-based only; no KF, no tune()]
│ │
│ └─ Accel + Gyro + Mag + Altimeter
│ └──► ahrs10filter [adds altitude + vertical velocity output]
│
└─ Full pose (orientation + position + velocity)
│
├─ No motion constraints (aerial, or ground vehicle without side-slip constraint)
│ ├─ Accel + Gyro + Mag + GPS, all sensors sync
│ │ └──► insfilterMARG
│ └─ Accel + Gyro + Mag + GPS, mixed rates or dropped samples
│ └──► insfilterAsync
│
└─ Ground vehicle with zero side-slip constraint
├─ Accel + Gyro + GPS
│ └──► insfilterNonholonomic
└─ Accel + Gyro + GPS + monocular visual odometry
└──► insfilterErrorState
ステップ 2B — 柔軟なフィルターを選択する
Need real-time fusion, StateCovariance output, or optimizer-based tune()?
│ Yes ──► insEKF [production use; full KF; real-time and batch APIs]
│ No
▼
Batch-only processing, no covariance needed, quick setup (R2026a+)?
└──► insCF [complementary filter; gain-based; not for production]
データの準備
サンプルレート
SampleRate(グループ A のフィルター)と IMUSampleRate(グループ B のフィルター)は、実際のデータレートと一致している必要があります。不一致があるとノイズモデルが直接スケーリングされ、すべてのフィルター出力が損なわれます。insfilterAsync、insEKF、insCF はタイムスタンプ駆動であり、レートプロパティはありません。
まずタイムスタンプを秒に変換してから、レートを推定します。
tSec = rawTimestamp / 1e6; % µs → s; divide by 1e3 for ms, or skip if already seconds
fs = 1 / median(diff(tSec));
タイムスタンプが使用できない場合(すべて同一、または結果が有限値でない場合):
if numel(unique(tSec)) < 2 || ~isfinite(fs)
fs = 100; % use the stated or datasheet rate
end
時間間隔
すべての状態を保持するフィルターは、記録の中断(タイムスタンプの大きな飛び)の間に誤差が蓄積します。各中断箇所でデータを分割し、各セグメントの開始時にフィルターをリセットしてください。
gapThreshold = 5 / fs; % 5× the expected sample interval
gapIdx = find(diff(tSec) > gapThreshold);
segments = [1; gapIdx+1]; % start index of each segment
グループ A の System object フィルター(imufilter、ahrsfilter、complementaryFilter):セグメント間で release(filt) を呼び出します。これにより、調整済みのノイズプロパティをすべて保持したまま、状態がリセットされます。
グループ B およびその他のフィルター:各セグメントの開始時にフィルターオブジェクトを再構築します。
実装
選択したフィルターのリファレンスファイルを参照してください。
| フィルターグループ | リファレンス |
|---|---|
| 姿勢フィルター | references/attitude-filters.md |
| ナビゲーションフィルター | references/navigation-filters.md |
insEKF | references/insekf.md |
insCF | references/inscf.md |
調整
tune のシグネチャは 2 種類あります。取り違えはよくある間違いです。
- シグネチャ A(
imufilter、ahrsfilter)— フィルターをその場で変更します。tune(filt, sensorData, groundTruth) - シグネチャ B(
ahrs10filter、insfilterMARG、insfilterAsync、insfilterNonholonomic、insfilterErrorState、insEKF)— ノイズ構造体を返します。tunedNoise = tune(filt, tunernoise(filt), sensorData, groundTruth)
tune では調整できないフィルター:
ecompass、complementaryFilter— tune メソッドはありません。プロパティを手動で調整してくださいinsCF— 代わりにgainparts(filt, sensorName, value)を使用してください
insEKF のみ:tunerconfig にはフィルターのインスタンスが必要です。tunerconfig('insEKF') ではなく、tunerconfig(filt) を使用してください。
tunerconfig
| プロパティ | デフォルト | 説明 |
|---|---|---|
MaxIterations | 20 | この反復回数後に停止します |
ObjectiveLimit | 0.1 | コストがこの値を下回ると停止します |
Display | "iter" | "iter" は各反復の進行状況を表示し、"none" は出力を抑制します |
Cost | "RMS" | "RMS" は RMS 誤差を最小化し、"Custom" は CustomCostFcn を使用します |
CustomCostFcn | [] | 関数ハンドルです。Cost = "Custom" の場合にのみ有効です |
フィルター別の tunernoise フィールド名
シグネチャ B のフィルターでは、tune を呼び出す前に tunernoise(filt) が必要です。シグネチャ A のフィルター(imufilter、ahrsfilter)では tunernoise を使用しません。tune がノイズプロパティを直接インプレースで変更します。
| フィルター | tunernoise が返すフィールド |
|---|---|
ahrs10filter | MagnetometerNoise、AltimeterNoise |
insfilterMARG | MagnetometerNoise、GPSPositionNoise、GPSVelocityNoise |
insfilterAsync | AccelerometerNoise、GyroscopeNoise、MagnetometerNoise、GPSPositionNoise、GPSVelocityNoise |
insfilterNonholonomic | GPSPositionNoise、GPSVelocityNoise |
insfilterErrorState | MVOOrientationNoise、MVOPositionNoise、GPSPositionNoise、GPSVelocityNoise |
insEKF | filt.SensorNames + Noise のサフィックスで命名されます(例:AccelerometerNoise、GPSNoise) |
フィールドには ...Noise のサフィックスが付きます。これを省略するのはよくある間違いです。
結果の可視化
tunerPlotPose は OutputFcn コールバックです。tunerconfig に渡すと、各チューニング反復中に姿勢推定をリアルタイムでプロットします。これはチューニング後に単独で呼び出すプロット関数ではありません。フィルターとデータの引数を渡して直接呼び出すと、エラー(「入力引数が多すぎます」)になります。
config = tunerconfig(filt);
config.OutputFcn = @tunerPlotPose;
tunedNoise = tune(filt, tunernoise(filt), sensorData, groundTruth, config);
チューニング後に可視化するには、フィルターの状態を抽出し、グラウンドトゥルースと比較して手動でプロットします。設定可能なフィルター(ahrs10filter、insfilterMARG、insfilterAsync、insfilterNonholonomic、insfilterErrorState)には pose() メソッドがあります。これを使用してください。insEKF と insCF には pose() メソッドがありません。代わりに stateparts(filt, 'Orientation')、stateparts(filt, 'Position') などを使用してください。バッチワークフローでは、estimateStates の出力タイムテーブルからプロットします。
TunableParameters の制御、カスタムコスト関数、ログ記録や早期停止のための OutputFcn などの高度なパターンについては、references/insekf.md と references/navigation-filters.md を参照してください。
規則
-
参照座標系:既定値は
"NED"です。ENU を使用するには、次のようにします。- 設定可能なフィルターオブジェクト(
imufilter、ahrsfilter、complementaryFilter、ahrs10filter、insfilterMARG、insfilterAsync、insfilterNonholonomic、insfilterErrorState):filt.ReferenceFrame = "ENU" ecompass(オブジェクトではなく関数):名前と値のペアの前に、位置引数orientationFormatが必要です。ecompass(a, m, 'quaternion', 'ReferenceFrame', 'ENU')のように指定します。省略すると、「入力番号 3、FORMAT... が必要です」というエラーになります。insEKF/insCF:構築後はReferenceFrameは読み取り専用です。構築時にinsOptions/insCFOptionsを使用して設定します。
- 設定可能なフィルターオブジェクト(
-
姿勢の出力:既定では
quaternionオブジェクトです。 -
GPS 位置入力:度/度/メートル単位の LLA ベクトルです。
-
サンプルレートのプロパティ:
imufilter、ahrsfilter、complementaryFilter:SampleRateahrs10filter、insfilterMARG、insfilterNonholonomic、insfilterErrorState:IMUSampleRateinsfilterAsync、insEKF、insCF:サンプルレートのプロパティはありません(各センサーが独自のタイムスタンプを持ちます)。
-
ReferenceLocation:フュージョンループを開始する前に、insfilterMARG、insfilterAsync、insfilterNonholonomic、insfilterErrorStateに設定する必要があります。insEKF/insCFの場合は、代わりにinsGPS/insCFGPSセンサーオブジェクトに設定します。
スキルに関するフィードバック
このスキルのガイダンスが間違っていた、不完全だった、または機能しなかった場合は、応答にプレーンテキストの フィードバックマーカーを出力してから、タスクを続けてください。
形式:NAV-SKILL-FEEDBACK [matlab-fuse-inertial-sensors] [category]: what failed; what you did instead
カテゴリ:wrong-command(コマンドが不正または古い)、missing-guidance(手順の記載漏れ)、
discovery-failure(提示された方法が機能しなかった)、platform-issue(環境固有の問題)
Copyright 2026 The MathWorks, Inc.