Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[irteus/irtdyna.l] Add riccati equation solver based on Arimoto Potter method #553

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

k-kimura
Copy link
Contributor

euslispでriccati方程式を解くためのsolverを追加しました.

既存のriccati-equationは繰り返し計算により定常解を得るもの(イテレーション数などの設定が必要)で,うまく解けないことがありましたが
繰り返し計算をしない方法として新しく「有本-Potterの方法(固有値分解法)」というアルゴリズムを採用して,riccati方程式の解が求められるようになっています.
また,LQRのフィードバックゲインも同時に出力されるようにしています.

以下,倒立振子のLQR制御を例に,
riccati-equation(繰り返し計算)
riccati-equation-arimoto-potter-method(有本-Potterの方法)
matlab(octave)
を比較した結果です.

  • riccati-equation(繰り返し計算)
irteusgl$ ;; (send (instance riccati-equation :init AA bb cc QQ RR) :solve)
irteusgl$ (setq *riccati-result* (send (instance riccati-equation :init (make-matrix 4 4 '((0 0 1 0) (0 0 0 1) (34.67763 0 0 0) (-679.76829 0 0 0))) (make-matrix 4 1 '((0) (0) (-1.27842) (32.73032))) (make-matrix 2 4 '((1 0 0 0) (0 1 0 0))) 4 7) :solve))
(#2f((1.757195e+05 0.0 0.0 0.0) (0.0 4.0 0.0 0.0) (0.0 0.0 1.757195e+05 0.0) (0.0 0.0 0.0 4.0)) #2f((-27.0313 0.0 0.0 0.0)))

irteusgl$ (format-array (car *riccati-result*)) ;; solution P of riccati equation
       175719.519   0.000   0.000   0.000 
         0.000   4.000   0.000   0.000 
         0.000   0.000 175719.519   0.000 
         0.000   0.000   0.000   4.000 
#2f((1.757195e+05 0.0 0.0 0.0) (0.0 4.0 0.0 0.0) (0.0 0.0 1.757195e+05 0.0) (0.0 0.0 0.0 4.0))
irteusgl$ (format-array (cadr *riccati-result*)) ;; LQR state feedback gain K
       -27.031   0.000   0.000   0.000 
#2f((-27.0313 0.0 0.0 0.0))
  • riccati-equation-arimoto-potter-method(有本-Potterの方法)
irteusgl$ ;; (send (instance riccati-equation-arimoto-potter-method :init AA BB QQ RR) :solve)
irteusgl$ (setq *riccati-result* (send (instance riccati-equation-arimoto-potter-method :init (make-matrix 4 4 '((0 0 1 0) (0 0 0 1) (34.67763 0 0 0) (-679.76829 0 0 0))) (make-matrix 4 1 '((0) (0) (-1.27842) (32.73032))) (make-matrix 4 4 '((4 0 0 0) (0 4 0 0) (0 0 4 0) (0 0 0 4))) (make-matrix 1 1 '((7)))) :solve))
(#2f((35705.6 314.265 12343.3 441.199) (314.265 7.02923 111.06 4.17625) (12343.3 111.06 4331.8 156.495) (441.199 4.17625 156.495 5.82846)) #2f((-191.33 -0.755929 -59.3904 -1.3284)))

irteusgl$ (format-array (car *riccati-result*)) ;; solution P of riccati equation
       35705.647 314.265 12343.274 441.199 
       314.265   7.029 111.060   4.176 
       12343.274 111.060 4331.802 156.495 
       441.199   4.176 156.495   5.828 
#2f((35705.6 314.265 12343.3 441.199) (314.265 7.02923 111.06 4.17625) (12343.3 111.06 4331.8 156.495) (441.199 4.17625 156.495 5.82846))
irteusgl$ (format-array (cadr *riccati-result*)) ;; LQR state feedback gain K
       -191.330  -0.756 -59.390  -1.328 
#2f((-191.33 -0.755929 -59.3904 -1.3284))
  • matlab(octave)
>> riccati_solve_test
A =
     0.00000     0.00000     1.00000     0.00000
     0.00000     0.00000     0.00000     1.00000
    34.67763     0.00000     0.00000     0.00000
  -679.76829     0.00000     0.00000     0.00000

B =
    0.00000
    0.00000
   -1.27842
   32.73032

Q =
Diagonal Matrix
   4   0   0   0
   0   4   0   0
   0   0   4   0
   0   0   0   4

R =  7

P =
   35705.77395     314.26480   12343.29561     441.19909
     314.26480       7.02922     111.06011       4.17624
   12343.29561     111.06011    4331.80142     156.49470
     441.19909       4.17624     156.49470       5.82845

K =
  -191.32998    -0.75593   -59.39046    -1.32840

新しく実装したriccati-equation-arimoto-potter-method(有本-Potterの方法)のほうは,ほぼmatlab(octave)と同じ結果が得られました.

現状は,「有本-Potterの方法」のポイントとなるHamilton行列(A,B,Q,Rから作成)の固有ベクトルの計算に関して,
euslispの固有値分解の関数(eigen-decompose)が虚数までカバーできていないため
Hamilton行列の固有ベクトルが虚数(固有値も虚数)になる場合には例外処理しています.
(今のところ,倒立振子モデルの場合はHamilton行列の固有値,固有ベクトルは実数となっています)

@k-okada
Copy link
Member

k-okada commented Jul 22, 2019 via email

@k-kimura
Copy link
Contributor Author

euslispの固有値分解の関数(eigen-decompose)が虚数までカバーできていないため

の問題を#554 の変更で対応させました.
これで,matlabのlqr関数とほぼ同じように動くかとおもいます.

それをテストする(matlabの結果と比較する)ためのriccati-equation-arimoto-potter-methodのサンプルプログラムも追加しました.
二輪倒立振子モデルの実装例(lqr-two-wheeled-inverted-pendulum)も中に含めています.

irteusgl$ (load "./irteus/test/riccati-equation-arimoto-potter-method-test.l")
TEST-NAME: riccati-equation-arimoto-potter-method-test
  now testing...
start testing [riccati-equation-arimoto-potter-method-test]
ALL RESULTS:
  TEST-NUM: 1
    PASSED:   1
    FAILURE:  0
RESULT: all-test
  TEST-NUM: 0
    PASSED:   0
    FAILURE:  0
RESULT: riccati-equation-arimoto-potter-method-test
  TEST-NUM: 1
    PASSED:   1
    FAILURE:  0
[ INFO] [1564217319.972668113]: cell* ROSEUS_EXIT(context*, int, cell**)

@k-kimura
Copy link
Contributor Author

euslisp/EusLisp#393 と同様にこちらも
riccati-equationクラスとriccati-equation-arimoto-potter-methodクラスの説明が
jskeus/doc以下に反映されるようにしました.

@k-okada
Copy link
Member

k-okada commented Jun 7, 2020

Thank you for contributing jskeus documentation

Please check latest documents before merging

PDF version of Japanese jmanual: jmanual.pdf
HTML version of Japanese manual: jmanual.html
Sphinx (ReST) version of Japanese manual: jmanual.rst

@k-okada
Copy link
Member

k-okada commented Jun 11, 2020

@k-kimura これは今のriccati方程式 を使っているプログラム(予見制御とかがそう?)には影響を与えないんだよね?
そうだとせっかくコードを追加しても誰も使わないものが出来ているだけなので,苦労してマージする意味があまりないので,例えば教科書的に考えると

(defclass riccatti-equation (:super propertied-object))
(defclass riccatti-equation-iteration-method (:super riccatti-equation)
(defclass riccatti-equation-arimoto-potter-method (:super riccatti-equation)

となっているべきだよね.ただ,肝心のpreview-controller

(defclass preview-controller   :super riccati-equation)

となっているので,こうしたからって何かいいことがあるとはならなそう,となると,

(defmethod riccatti
 (:init (AA bb cc QQ RR &key (method :iteration)))

となっていて,同じクラスの中でアルゴリズムを切り替えるような書き方にすると,
例えば irteus/demo/walk-motion.l で新しいriccatti 方程式を使ったテストが出来るのでくるはず.

で,もう一歩考えると,もし完全上位互換のものが作れているのであればそもそも切り替えても良い.

この辺は,riccatti 方程式を使っているユーザがどれぐらいいるかというのが問題で,ユーザがいないなら,そのまま色々切り替えていけば良いし,既に既存のユーザがいるなら,後方互換も意識して考えていく必要がある.

パット見,riccatti 方程式はpreview control に使われていて,このレイヤで歩行制御しているのはサンプルプログラムぐらいしか無いのかなぁ,とは思っているんだけどどうだろうか? 案外実は色々なところで活用されているのかな.

@k-kimura @Naoki-Hiraoka @s-noda @makabe0510 @hiroya1224

@k-kimura
Copy link
Contributor Author

プログラムを作って,サンプルプログラムを入れて,ドキュメントを追加して,
の後,何故かかれこれ1年くらい経っていますが
取り急ぎ,このPRは最低限の制御ツール(倒立振子)を目的にして入れたもので
まずは,他のプログラム(予見制御など)と干渉がないように追加しました.

確かに

せっかくコードを追加しても誰も使わないものが出来ているだけなので,苦労してマージする意味があまりないので,

(プログラムコード等々を書いて追加するだけでもすでに苦労はしていますが)
は自分も気にかけていることなので,
https://github.com/jsk-ros-pkg/euslib/issues/334
でもさっそく議論が進められていますが
具体的に,新しいriccati-equation-arimoto-potter-methodをどのプログラムのどのソースコード部分で試せるようになるといいか,ご教授いただけると幸いです.
時間のあるときに試してみようとおもいます.
(riccati-equationまわりの箇所をコピペしてriccati-equation-arimoto-potter-methodに置換したのを追加する程度なら自分でもすぐ試せるかもしれないです)
現時点では,これまでのpushで最低限,倒立振子の制御系設計ツールとしては活用できるようになっているかとおもいます.

@k-okada
Copy link
Member

k-okada commented Jun 11, 2020

どのプログラムのどのソースコード部分

これは普段から自分が使っているコードのタイポとかドキュメント直してPR送っていれば,誰がどの部分を使っているか可視化されるのでいいんだけど,そうでないとなかなかわからないですよね.
とはいえさっきの話だと,
https://github.com/jsk-ros-pkg/euslib/tree/master/demo/nozawa/multicontact_motion_planner/test
がまずは動けばいいんじゃないでしょうか?
ちなみに,これが動くように成るための環境設定,僕は1時間ぐらいかかったんだけど,,,,

@k-kimura
Copy link
Contributor Author

ありがとうございます.
時間のあるときに試してみます.

まだ理解が足りていないかもしれませんが,
https://github.com/jsk-ros-pkg/euslib/tree/master/demo/nozawa/multicontact_motion_planner
を手元に入れてみて
https://github.com/jsk-ros-pkg/euslib/tree/master/demo/nozawa/multicontact_motion_planner/test
の下にあるtest_multicontact_motion_planner.lが,エラーなくroseus(irteusgl)で実行できればOKということで合ってますでしょうか?

@k-okada
Copy link
Member

k-okada commented Jun 12, 2020

合ってますでしょうか?

はい.そういう意味でした.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants