モデルなしLQ最適制御の種類(MFR-LQ(model free recursive lq controller)) ・MFR-LQの雑音の振幅を 振幅^(1/n)にして時間が経てば減衰する方法を取る。n(root(振幅))の計算になる。Maximaで計算結果をグラフで確認する。n=1.1, 1.2, 1.3, 1.4, ... power関数を使って計算する。指数関数と対数関数を利用する。 ・MFR-LQのアイディアを考える。色々な応用範囲を考える。次世代の戦車を設計したい。砲身の自動追尾機能をつける。 ・MFR-LQの角度をリセットする時に次の角度を角速度から予測してリセットを行う。現在の角度 + 角速度 * シミュレーションのステップ時間 = 次の予測角度 (ここでリセットを行えば安全に地面に衝突せずにリセットできるはずだ。) ・応答信号の解析に使えるのは、数列、級数、幾何学、トポロジー、カオス、演算、計算、スカラーとベクトルと行列の値の加工と抽出とフィルタ、フィルタ、フィルター、違う種類の信号や雑音を高度な計算で組み合わせる。確率、統計、遺伝子、脳科学、ニュラルネット、遺伝アルゴリズム、乱択、乱数、シナプス、脳 モデル、脳 医学、脳 医療、学習 アルゴリズム。 ・MFR-LQの雑音の振幅を 振幅^(1/n)にして時間が経てば減衰する方法を取る。n(root(振幅))の計算になる。Maximaで計算結果をグラフで確認する。n=1.1, 1.2, 1.3, 1.4, ... power関数を使って計算する。指数関数と対数関数を利用する。 ・MFR-LQのアイディアを考える。色々な応用範囲を考える。次世代の戦車を設計したい。砲身の自動追尾機能をつける。 ・MFR-LQの角度をリセットする時に次の角度を角速度から予測してリセットを行う。現在の角度 + 角速度 * シミュレーションのステップ時間 = 次の予測角度 (ここでリセットを行えば安全に地面に衝突せずにリセットできるはずだ。) ・角速度から次の角度を予測してリセット動作を行うようにソースコードを改良する。 ・保存したゲインのファイルを読み込んで初期値応答と適応制御がおこなえるようにソースコードを改良する。 ・MFR-LQが完璧になったのでいろいろな人に多く使ってもらえるようにBlogの記事を充実させる。技術的な話題を多く書く。バグ報告もメーリングリストでする。 ・災害救助のレスキューロボットをMFR-LQを使ってシミュレーションする。 ・2リンクアームの論文とネットの検索結果を使ってMFR-LQで2リンクアームのシュミレーションを行う。それが終わったら倒立2輪車のシミュレーションを行う。2入力モデルが正しく動作するか確かめる必要がある。プログラムのコードを工夫して2入力モデルに対応させる。グラフの書き出しに注意してコーディングする。 ・MFR-LQでクレーンと2リンクアームを動かしてシミュレーションを行う。角度の範囲が限定されるので、標準の角度を取得する関数を利用する。 ・2リンクアームを順運動学を使って制御する。入力が2になるので各行列のサイズに注意してコーディングを行う。 ・MFR-LQの改良を続ける。最強の制御シミュレーターを目指す。使ってくれる人を増やすためにBlogで宣伝を行う。 ・MFR-LQに使える論文をダウンロードする。Sci-Hubを使ってダウンロードしておく。論文を大量に溜め込んでおく。 ・MFR-LQのソースコードを完璧に出来上がるまでメンテナンスし続ける。細かい修正を加えていく。バージョンが5.0ぐらいになったら、メーリングリストで宣伝したい。あとプロジェクトのソースコードのページのスクリーンショットを増やす。 ・MFR-LQの問題が解決して良かった。我慢して努力した結果が実った。問題解決したので他のシミュレーションで高度な応用を繰り広げる。 ・MFR-LQが完璧になったので2リンクアームのモデルをシミュレーションしてみる。台座は固定ジョイントを用いる。回転型倒立振子のモデルを参考にして実装する。 ・相対角度と絶対角度の問題を克服したので完璧な状態になっている。後は細かいバグをつぶしていく作業に充てる。メンテナンスを繰り返してバージョンをあげる。 ・MFR-LQのプロジェクトがバージョン3.4でほぼ完璧になった後はパラメータの設定と細かいところを修正してメンテナンスするぐらいになる。Linuxへの移植を開始する。 ・絶対角度を取得するのにODE自体の実装を完璧に読んで自分で追加の関数を用意する必要がある。正しい絶対角度を取得したい。そのためには時間がかかる。 ・dBodyGetRotation()の値を1ステップ前の値を保持して、差分をとる。Delta(dBodyGetRotation()); --> dBodyGetRotation() - Old-dBodyGetRotation(); それでそれを100.0で割ってロー、ピッチ、ヨーを出す。それを100.0倍して角度の差分に直す。それを足し上げる。totalangle += diffangle; ・もう一つは位置センサをつけて変位から角度を算出する。これはたぶん欠点があって1周回ってきたら不正な値になる。ので難しい。 ・Open Dynamics Engineの問題点は以下の2つある。 ・01.ジョイントの相対角度を正確に取得する関数を実装する。現在のままでも実行可能。 ・02.物体の絶対角度を正確に取得する関数を実装する。dBodyGetRotation()の関数の値を使ってどうにか出来ないか考える。 ・物理エンジン(Open Dynamics Engine)の問題点を作者と出村さんにメールする。既に分かっている問題点を解決してもらうようにメールする。 ・台車型倒立振り子でホイールが沈むバグがある。これも作者と出村さんにメールして解決してもらう。 ・出村 公成さんのホームページを参考にする。"demura.net", "ode", "open dynamics engine", で検索する。 ・ODE作者さんのRussell L. Smithさんのメールアドレス-Email: russ@q12.org ホームページアドレス-Web: www.q12.org を参考にする。必要なら質問のメールを送る。 ・GSL, "gsl", "gnu scientific library", "gsl 行列 クラス", で検索しておく。 ・学習制御(そのまま) ・初期値応答(初期ゲインを与えて、雑音vを無くして初期値を与える(例:角度等,状態変数から定数を引いて制御を実行する。))。それに加えてゲインの更新を止める。ゲインアップデートの関数を呼ばない。 ・適応制御(初期ゲインを与えて、雑音vは入れて、λ1kの値を小さくとる(例:λ1k=0.3等,λ1k=0.1等)) そして適応制御では、本体の重さを順番に変えてゲインの変動を見る。 ・追値制御は初期値応答の目標値を時間的に変更して値を追従させる。 ・MFR-LQのソースコードをメンテナンスして角度を取得できるように改良したのでその関数を呼び出して値が正確かを確認する。printfでコンソール上でデバッグすればよい。値が正確でなければ物理エンジンそのものを根本的に改良しないといけない。改良したらソースコードをzipで固めてSourceForge.netにアップロードする。ソフトウェアが正しく動作するならその学習のシミュレーション結果から論文を書く。最初は基礎的な部分から書く。「モデルなしLQ最適制御」に関する過去の論文を取り寄せておく。論文は日本語のものと英語のもの両方とも取り寄せる。 ・Havok,BulletでもMFR-LQを移植して実行できるようにする。その他の商用の物理エンジンを買っても良い。 ・角度を +∞ 〜 0 〜 -∞ [rad]でとれるようにする dJointGetHingeAngle(); の関数の実装を見て改造する。Open Dynamics Engineの開発者と連絡を取って角度を取得する関数を実装してもらう手もある。メールかフォーラムで質問して実装してもらえるように頼んでみてもいいかもしれない。日本でOpen Dynamics Engineについて一番詳しいDEMURA(出村)さんのサイトで関数を実装してもらえないか聞いてみてもいいかもしれない。(または角速度の関数dJointGetHingeAngleRate();をいじって角度に直して足しあげる)・タイマーの部分のコードが正しく実装されているか確認する。実時間表示できてるかも確かめる必要がある。 ・ode-0.16.tar.gzを解凍してode-0.16\ode\src\joints\hinge.cppの中にdJointGetHingeAngle()の中にgetHingeAngle()関数があることを確認済みここから値を取り出せないか考えてみる。getHingeAngle()関数の返す値がどの範囲かを確認してみる価値はある。getHingeAngle()関数がどこで宣言されているかも確認しておく。vimならジャンプできるからvimを使う。ctagsも要るかも。 ・ode-0.16.tar.gzを解凍してode-0.16\ode\src\joints\joint.cppの中にgetHingeAngle()関数が実装されている。その実装をさかのぼれば-πから+πまで角度を取得している実装が見えるはずなので修正をかけて自分で関数を宣言して自作関数を実装して+-∞の角度を取得できるようにすればよいかもしれない。getHingeAngleFromRelativeQuat()の実装を見てみるべきかもしれない。クォータニオンの知識が要る。 ・Open Dynamics Engineにはロー角度、ピッチ角度、ヨー角度を取得する関数があるみたいだ。dBodyGetRotation()がそれにあたる。それを使えば慣性ローターみたいに回転させるものも角度を絶対角で取得できるかもしれない。自分で作ったプログラムのコードから関数を見つけて欲しい。角度がどれだけの範囲で取得できるのかデバッグして調べておく。多めに回転させてどれだけの範囲まで角度を取得できるのか調べておかないといけない。 ・dJointGetHingeAngleRate()のコードを調べてみる。ode-0.16\ode\src\joints\hinge.cppのファイルの中に関数がある。角度を取得しているはずだから。角速度は完璧に実装されているみたいだ。値をprintf()で確認する必要があるだろう。 ・PhysXの角度を取得する関数の実装からそれをOpen Dynamics Engineに移植できないか考えてみる。できればそれにこしたことは無い。自分で実装するのは大変だから。 ・dJointGetHingeAngleInfinite()の関数を作って引数にジョイントIDと角度(Angle)と角度はポインタで(サンプル時間)÷(1000.0)=(ステップ時間のdt)を取得する関数を作る。リセットしたら角度の変数を初期化して0.0にするのを忘れないようにする。 ・カーソルキーの上下左右を入力すると目標値が変化するようにする。例えば1輪車なら車輪の角度とかだ。カーソルキーの入力で足したり引いたりする。カーソルキーの入力のサンプルがODEのライブラリのコードの中にあったはずだ。 ・クォータニオンについて調べておく。行列論とか行列とかあと英語と中国語で。 ・可制御行列、可観測行列の実装 ・追値制御はどうやるのか調べておく。専門書を頼りに。"最適制御 追値"で検索する。 ・モデルなしLQ最適制御の論文を全部集める。英語で投稿したIEEEの論文も取り寄せる。"モデルなしLQ最適制御", "model free recursive lq controller"で検索しておく。制御理論、制御工学、カルマンフィルタ、最適制御、確率、統計、解析力学、物理エンジン、リッカチ差分方程式、に関連した論文を全部自分の手元に取り寄せる。 ・C++ファイルストリームの部分をファイルポインタで実装しなおして完全なC言語にする ・C++のGSLのラッパークラスを改良する。ベクトルを扱えるように実装しなおす。公開しているサイトの人にお礼のコメントを書く。無理やりGPLにする。 ・"tr | nkf"で文字コードを変更して、Linux版も作成する。unicodeにしてみてもいいかもしれない。 ・各制御対象ごとにファイルに分ける。Makefileも作る。 ・2リンクアームは、逆運動学と円の方程式から。逆運動学は「運動学」の本を読んで勉強する。あと「運動学」に関する論文も参考にする。 ・運動学の教科書を買って複雑なモデルの運動学を求める。アームがシリンダーで伸び縮みするタイプのアームの制御をやってみたい。 ・学習制御、初期値応答と適応制御はゲインのファイルからfopen();を使って読み込む。追値制御もやる。追値制御はタイマーの関数を使って250msごとに目標値を更新する目標値生成関数を実装する。 ・4リンクアーム、3リンクアーム ・自転車 + 慣性ローター ・1輪車 ・1輪車(慣性ローターが2つついたもの)(慣性ローターが3つついたもの) 車輪の形を球体にしたら、左右方向の揺れとスピンする方向の揺れに対応できるかもしれない。学習制御が上手くいくように適切にパラメータを設定する。 ・4足歩行ロボット、6足歩行ロボット、8足歩行ロボット(ハルクツー、Halluc II)、10足歩行ロボット(ひょうたん滑走もできるようにする) ・アラクニダ、HAW206、タチコマ、フチコマに似せたロボット ・クレーン、クレーン車、何種類かのクレーン(多自由度のもの、回転型倒立振り子の振り子を逆にしたものとか) ・ロボットアーム 5軸 7軸 かなりの種類を作る。2台とか3台が協調して動作するモデルを作り上げる。 ・2リンクアーム ・boston dynamics ・lynx motion ・昆虫 ・ペッパー ・東京工業大学のロボット各種 ・Boston Dynamicsのロボット各種 ・segway, 倒立2輪 ・重機、建設機械、農機具 ・倒立振り子 1重 2重 3重 ・CFD(流体力学ライブラリ)を使って ヘリコプター、ジェットエンジンの飛行機、VTOL 飛行機の種類を網羅 ・無人誘導兵器(プレデター) ・振り上げ型倒立振り子 ・慣性ローター 最初から上にあるのと、下にあって振り上げるタイプの2種類、振り上げるタイプの慣性ローターは状態変数から(-目標角度)を取って目標値まで振り上げることが出来るようにしておく。 ・台車型倒立振り子 ホイールが沈むバグがある。どうやったら直すことが出来るかソースコードを全部チェックする必要がある。どうしても直らないなら他の開発者に問題を投げかけてみる。開発者が集まるサイトで質問してみる。ODE関連の開発者にメールで連絡する。 ・ライドバック ・台車型2重倒立振り子 ・"ハルク(Halluc II) ロボット"で検索 ・工作機械、製造装置、マシニング、マザーマシン ・慣性ローターの2つついたもの ・兵器、軍事利用、ファランクス ・2足歩行ロボット ・協調型ロボット(ロボットアーム2本とかを1つのモデルなしLQ最適制御で学習させて板を2本のロボットアームで持ち上げるとか) ・制御性能を見るための装置(基礎的なものから応用まで幅広く。) ・制御装置の実機 ・ロボットの実機 ・トランスフォーマー、IGPX、みたいに変形するロボット。 ・ドローンの制御 ・ロボカップ サッカー エージェント ・マイクロマウス ・変形ロボット ・ロボットアニメのモデル ・ロボット相撲 ・ロボットコンテスト ・ヘリコプターを使った送電線の無人点検にモデルなしLQ最適制御を使う。 ・3D プリンターの制御 ・ODE版とPhysX版の2種類作っても良いかもしれない。ODE,GSL,PhysXの実装を解析しておく。バグをみつけたらメールでソースコードを添付して開発者に送る。 ・歩行パターンを生成できるアルゴリズムを調べておく。GA,AI,ディープラーニング、強化学習とか遺伝アルゴリズムとか色々。 ・重機(クレーン車、セメント車)でカーブの時に後ろの重量のかかる部分を傾斜させるような制御ができないか考えてみる。 ・クモ、サソリ、ムカデ、昆虫、犬、いろんな動物や虫から歩行パターンを観察してみる。ヘビ型ロボットも学習させてみたい。今開発されているロボット全部。 ・回転数制御ができるように[rpm]回転数を算出するコードを実装しなければならない。 ・4足歩行ロボット1つの足の付け根の部分の目標値生成関数は(θ1)=(π/4)×sin(θ0)の(θ0)をタイマーを使って100msごとに0.1[rad]ずつ増やしてみる。出力される値は(-π/4)[rad]〜0[rad]〜(+π/4)[rad]の値の範囲に目標値が出てくるようにする。それを状態から引き算すればよい。プログラムのコードは、状態変数: x[0] = dJointGetHingeAngle() - (θ1);とすればよい。 ・全部の方法を試したけど角度が取得できないなら、odeの作者の名前を調べて、駄目ならodeの作者の Email: russ@q12.orgにメールする。webはWeb: www.q12.orgを参照する。英語でGoogle翻訳を使って作者に直接メールしてみる。 ・出村さんの研究室のある金沢工業大学のアポイントメントを取って自ら出向いてOpen Dynamics Engineの実装について角度を取得するにはどうしたらいいか相談してみてみる。 ・モデルなしLQ最適制御とPhysXの組み合わせの時にはソースコードはC++で実装しないといけないかもしれない。C++について勉強しておく。良い本があったら買うようにする。 ・Open Dyanmics Engineのソースコード全部をチェックして角度を取得する関数をどう実装したらいいか考える。他の物理エンジンの実装を見てみる。メールの他にフォーラムとかで質問してもよい。それか他のサイトで質問できるならそうする。 ・SourceForge.netのOpen Dynamics Engineのページからサポートを選んでそこに角度をどう取得したらいいかの質問を書き込めるか試してみる。 ・最悪Open Dynamics Engineの角度を取得する関数を自分で実装する。PhysXのソースコードを参考にして。何とかなるだろう。元のdJointGetHingeAngle()の実装を見てどうにかできないか考える。 ・dJointGetHingeAngleRate()の関数を呼び出してそれにサンプル時間をかけると角速度×サンプル時間で角度になるのでこれを足しあげると角度が取得できるはずだ。これが一番手っ取り早いはずだ。実装は汚くなるけど。 ・初期値応答を見るためにあらかじめ構造のオブジェクトをオフセットして角度とかをずらして組み立てることができないか考える。初期位置からトルクを加えて位置や角度をずらす方法もある。 ・学習制御、初期値応答、適応制御のためのモデルなしLQ最適制御のパラメータのどれを変更したら良いのか調べておく。 ・追値制御を出来るようにする。初期ゲインを与えて目標値を一定時間間隔で変化させて追従性能を見る。 ・MFR-LQのソースコードにはもうバグは少ないかもしれない。物理エンジン側にバグがあって学習に失敗することがあるかもしれない。重量を重くすると学習に失敗することが多い。物理エンジン側に問題があるかもしれない。物理エンジンのソースコードに目を通して問題点を発見しておく。 ・出村 公成, Russell L. Smith, の2人に直接会いに行きたい。まずはメールで限界までコミュニケーションを取っておく。将来英語を勉強しておいて海外に行ったらそこで話しをしたい。自分の作ったプログラムを持っていく。 出村さんのメールアドレスに件名は 「はじめまして」 としてメールする。 内容は 「はじめまして、高井といいます。Open Dynamics Engineと制御理論を使って1輪車の制御をやっているものなのですが 車輪を回転させる時に困ったことがあり、角度を取得する関数のdJointGetHingeAngle()の関数が-π[rad]〜0〜+π[rad]までの値しか返さないので困っています。 このままでは制御理論を使って学習させる際に不都合があるんです。dJointGetHingeAngle()の関数の返す値の範囲を -∞[rad]〜0〜+∞[rad]の値を返す関数に実装を変えれないかと思っています。 自分でもdJointGetHingeAngle()の実装を見て改良してみようと考えているのですが、自信がありません。 上手くいくかどうかわからないので出村さんに協力してもらえないかと思いメールした次第です。 ちなみに作ったプログラムのソースコードはSourceForge.netの"MFR-LQ"で検索してもらえば出てきます。WindowsXP時代に作ったコードなので64bit化するのにすこしコードを変更しないといけないのですがまだ出来ていません。 Linux版も作ろうと思っています。 Youtubeにも実行時の動画をのせています。Youtubeの検索ボックスに"Model Free Recursive LQ controller"と打ち込んだら一番上にヒットします。 お返事待っています。」 "