0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CasADiでFATROPを使用してモデル予測制御を行う

Posted at

FATROPとは

FATROPは、高速で幅広いクラスの最適制御問題をサポートし、高い数値的堅牢性を実現することを目的とした非線形最適制御問題ソルバーです。最適制御問題の構造を活用しロボットの動作計画や制御を高速に計算することができます。

本記事ではCasADiでFATROPを使用する方法を説明し、実際にモデル予測制御に使用して計算時間を計測してみた結果についてまとめます。

CasADiで使用する手順

FATROPはCasADiのソルバーとしてサポートされているのでビルドオプションで指定するだけで使用することができます。

ビルド方法

以下の手順でビルド、インストールを行います。

# 依存関係のインストール
sudo apt install -y git cmake gcc g++ gfortran pkg-config liblapack-dev pkg-config coinor-libipopt-dev --install-recommends

# CasADiのクローン
git clone https://github.com/casadi/casadi.git casadi
echo "export CMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH:$HOME/local/"" >> ~/.bashrc
source ~/.bashrc
cd casadi
mkdir build
cd build

# FATROPを使用できるようにオプション指定してビルド
cmake .. -DWITH_IPOPT=ON -DWITH_FATROP=ON -DWITH_BUILD_REQUIRED=ON
make -j$(nproc)
sudo make install

# 共有ライブラリのパスを通す
sudo ldconfig

プログラム内での使用方法

プログラムから使用する際には、IPOPTや他のnlpソルバと同様にソルバー名にfatropを指定すればよいです。

casadi::Dict config;
casadi::MXDict casadi_prob;
casadi::Function solver = casadi::nlpsol("solver", "fatrop", casadi_prob, config);

またFATROPは一般の非線形最適化ソルバとしても機能しますが、これとは別に最適制御問題の問題構造に特化した動作モードがあり、使用するには最適制御問題の問題構造に合うように問題の定式化を行い、辞書型のオプションで設定を行う必要があります。

casadi::Dict config;
config["structure_detection"] = "auto";

std::vector<bool> equality; // 制約が等式制約か不等式制約か
config["equality"] = equality;

以上の設定をすることで最適制御問題の構造を自動で検出し、効率的に解いてくれます。

ベンチマーク用プログラム

今回は自作のCasADi用MPCライブラリを用いて、exampleのシミュレーションの実行時間を計測し、ソルバーごとにどれほど違いが生まれるのかを調べます。

実験に使用するソルバー

IPOPTの線形ソルバー

IPOPTは内部で使用する線形ソルバーを選択することができます。デフォルトではMUMPSが使用されますが、アカデミックライセンスや法人ライセンスでHSLを購入することで高速なソルバーを選択することもできます。詳しくは以下の記事を参照してください。

実験するソルバーの一覧

条件名 ソルバー 条件
IPOPT(MUMPS) IPOPT 線形ソルバーにMUMPSを使用する
IPOPT(MA27) IPOPT 線形ソルバーにMA27を使用する
IPOPT(MA97) IPOPT 線形ソルバーにMA97を使用する
FATROP(NONE) FATROP 汎用非線形ソルバーとして使用する
FATROP(AUTO) FATROP ブロック構造を利用して効率的に問題を解く

実験条件

長くなるので「"(Dictのkey)"=(Dictのvalue)」形式で書いてます。

説明 設定値 IPOPTでの設定方法 FATROPでの設定方法
最大イテレーション回数 500 "ipopt.max_iter" = 500 "fatrop.max_iter" = 500
ウォームスタート あり "ipopt.warm_start_init_point" = "yes" "fatrop.warm_start_init_point" = true
収束条件 1e-6 "ipopt.tol" = 1e-6 "fatrop.tol" = 1e-6
許容可能収束条件 1e-4 "ipopt.acceptable_tol" = 1e-4 "fatrop.acceptable_tol" = 1e-4

ベンチマーク1 (2重積分器)

exampleからdouble_integrator_mpc_exampleの実行時間を5回計測し、その平均時間で比較します。
制御周期は10msで10秒間のシミュレーションを行います。

動作例

image.png

ベンチマーク結果

mpc_time3.jpg

FATROP(AUTO)が最速でIPOPT(MUMPS)と比較して78%程高速になりました。

ベンチマーク2 (倒立振子)

exampleからcartpole_mpc_exampleの実行時間を5回計測し、その平均時間で比較します。
制御周期は10msで12秒間のシミュレーションを行います。

動作例

video.gif

ベンチマーク結果

mpc_time.jpg

mpc_time2.jpg

IPOPT(MA27)とFATROP(AUTO)が並んで最速となりました。IPOPT(MUMPS)と比較すると43%程高速になってます。

まとめ

本記事ではCasADiでFATROPを用いてモデル予測制御を行い、FATROPの性能の高さを実感することができました。みなさんもぜひFATROPを使ってみてください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?