Ceresの自動微分とEKF SLAM

前回,Ceresの自動微分モジュールの抜き出し方を調べたので,せっかくなので実際にこれを使ってEKF SLAMの微分計算を自動化してみました.

基本的には前と同じでAutoDiffを使って微分計算するんですが,今回はラムダ関数にauto引数を渡すことでコードを簡潔にしてみました.C++14以降なら,だいたい以下のような感じで関数fの微分が求められます.

Eigen::Vector2d vel = ...;  // linear & angular velocity
Eigen::Vector3d pose = ...; // current robot pose
Eigen::Vector3d new_pose;
Eigen::Matrix<double, 3, 3, Eigen::RowMajor> jacobian;

auto f = [&](const auto* x, auto* z) {
  z[0] = x[0] + vel[0] * cos(x[2]);
  z[1] = x[1] + vel[0] * sin(x[2]);
  z[2] = x[2] + vel[1];
  return true;
};

double* x = pose.data();
double* z = new_pose.data();
double* J = jacobian.data();

ceres::internal::AutoDiff<decltype(f), double, 3> ad;
ad.Differentiate(f, &x, 3, z, &J);

かなり適当に実装しましたが一応それなりに動いている風です.実際はこの程度の問題であればUKFを使ってしまえば微分なしでいけるんですが,自動微分モジュールを汎用的に使う方法を試したということで.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください