2022年1月31日月曜日

PID制御によるドローンの揺れに関する数値シミュレーション(10):ジャイロ効果シミュレーション

前の(9)では、遅延制御による問題を回避するためにジャイロ効果を利用する理論的モデルを示した。ここでは二階の非線型常微分方程式と数値解用の漸化式で表されたモデルを、計算で解いた結果を示す。

これまでの記事は以下のリンクから見ることができる。


シミュレーションで使用したc++のプログラムは、次のgithubのレポジトリから取得できる。gyroeffect-1.cppという名前のファイルである。

https://github.com/toyowa/pidsimulation/tree/main 

シミュレーション結果を示す。まず、試行錯誤の末に到達した最もよい結果から示す。制御の遅延レベルは、実機の実態を反映した200msに統一している。

1。遅延20期(200ms)、σ = 1.0、P=5000. D=1000

青い線が、機体のピッチ角である。オレンジの線は、モータの回転rpmである。ほぼ迷いなくホバリングの水平姿勢に向け一直線に姿勢を正している。腕の長さや重量などを実機のままに、遅延20期は、これまで全て飛行破綻状態だったが、初めて、遅延のない制御とほぼ同じ結果がもたらされた。おろどくべきことだ。

2。遅延20期(200ms)、σ = 0.5、P=5000. D=1000

他は同じで、ジャイロ効果を半分まで小さくすると、初期の揺れののちにホバリング姿勢に収束していく。
これよりも小さく、例えばシグマを0.25とすると、飛行はすぐに破綻する。すなわち、ジャイロ効果のない事態に近づいていくのである。

逆にシグマを増加させてみよう。

3。遅延20期(200ms)、σ = 2.0、P=5000. D=1000

シグマが1.0の時よりも、滑らかに変化しているが、収束スピードは逆に弱まっている。

PIDのスケールを変えたものも行ったが、ここでのPDの値で、シグマが1.0あたりが一番、綺麗に制御されているように思う。

いずれにしても、ジャイロ効果は、PIDの制御遅延の問題を解決する上で、大きな効果と意味があることがわかった。

PID制御によるドローンの揺れに関する数値シミュレーション(9):ジャイロ効果

これまでの記事は以下のリンクから見ることができる。

これまでのシミュレーションで、フライトコントロールシステムに制御遅延が生じていると、PID制御は強く悪影響を受けて、振動やフライトの破綻が引き起こされることを見た。そして、その対策として、機体の慣性モーメントを増加させることによって、制御遅延の問題を吸収可能であることを示した。しかし、その方法としての、モーターまでの腕の長さを長くしたり、機体をあえて重くしたりすることでは、現実的な解決にはならない。

そこで、機体の中でジャイロ効果を発生させることによって慣性モーメントを大きくすることと同じ効果をもたらすかどうかを確かめることにする。

ジャイロ効果とは、回転体の回転によって回転軸方向を維持する力が発生したり、回転軸の歳差運動などを引き起こす効果を指す。コマが倒れなかったり、歳差運動を引き起こすのがその典型的な例である。

ヘリコプターはその大きなローターによってジャイロ効果を発生させ、それを機体の制御に利用していると言われている。一方ドローンは、ジャイロ効果に依存して制御するのではなく、PID制御など情報処理システムによって機体の姿勢制御を行なっていると言われている。

しかし、ドローンもまたプロペラという明確な回転体を持っているので、ジャイロ効果を発生させていることは確実だ。実際、ある程度の制御の遅延は避けられないはずなのに、市販のメーカードローンは、綺麗に機体の制御が行われている。これについて、ある程度は、プロペラのジャイロ効果が役割を果たしているのではないかと私は考えている。

しかし、DJIのプロペラなどを見ていると、あえてプロペラが発生するジャイロ効果を低減させているのではないかと思えなくもない。それはなぜか。プロペラのジャイロ効果が存在するということは、機敏な姿勢制御ができないことを意味していて、都合が悪いからではないか。優れたレスポンスのモーターさえあれば、プロペラのジャイロ効果に依存しなくても、PID制御は適切に機能するので、それで問題ないはずだからである。

ここでは、これまでの制御遅延が含まれたモデルに、ジャイロ効果を導入し、その効果を確かめる。今回は、モデルの理論的な側面を明らかにし、次回にシミュレーション結果を示す。

まず、プロペラなどの形で(明示的なフライホイール型のジャイロを組み込む場合もある)ジャイロ効果が導入されているとしよう。するとそれは、ピッチ角やロール角の与えられたレベルに対してジャイロ効果が働くのではない。変化に対する効力として働くのであるから、ここでは機体角度の変化分に対してそれを打ち消す方向に力が働くとしよう。

理論的には、この力はジャイロモーメントと言われるもので、方向性を無視すると回転の核速度に比例するので、角度ではなく角度の変化の速さが復元力になるものと考えればよい(これについては、(11)でより詳しい説明を加えているので、そちらを参考にしていただきたい)。方向も交えて説明すると、機体の回転の角運動量を$\vec{L}$で表すとその方向はベクトルの方向である。機体に加わる揺れの角速度をベクトルで$\vec{\Omega}$で表すと、ベクトルの外積で、

$$\vec{T}_{g}=\vec{L}\times\vec{\Omega}$$

のジャイロモーメント$\vec{T}_{g}$を発生させるということである。この方向は、加えられた揺れとは方向が異なったものであり(それをどう処理するかは別問題として)、その揺れを吸収させる力と考えればよい。すなわち、方向は別に、復元力は角度の微分値を使えばよいということである。

この時、(6)で導入された遅延制御モデルの運動方程式は次のように変形される。

\begin{eqnarray*}\frac{d^{2}\theta_{t}}{dt^{2}}&=&\frac{\delta}{mL}\left(V_{0}^{2}+P^{2}\theta^{2}_{t-\tau}+D^{2}\left(\left.\frac{d\theta}{dt}\right|_{t-\tau}\right)^{2}-2V_{0}P\theta_{t-\tau}+2P\theta D\left.\frac{d\theta}{dt}\right|_{t-\tau}-2V_{0}D\left.\frac{d\theta}{dt}\right|_{t-\tau}\right)\\& &-\frac{g}{L}\cos \theta_{t}-\sigma \frac{d\theta_{t}}{dt}\end{eqnarray*}

最後に$-\sigma \frac{d\theta_{t}}{dt}$がジャイロ効果の項で、$\sigma$はパラメータである。

これを4次のルンゲ・クッタ法で解くために、この二階の非線型微分方程式を一階の連立微分方程式に変換する。

$$\begin{eqnarray*}\frac{d\theta_{t}}{dt} & = & \omega_{t} \\\frac{d\omega_{t}}{dt} & = & lag(\theta_{t-\tau}, \omega_{t-\tau})+s\cos\theta_{t}+\xi \omega_{t}\end{eqnarray*}$$

ラグ関数$lag(\theta_{t-\tau}, \omega_{t-\tau})$は、パラメータの定義も含め(6)で導入したものと同じである。(パラメータの定義は元々(4)で行われている)

これを解くための漸化式は次のようになる。

\begin{eqnarray*}k_{1}^{\theta}&=&h\omega_{n}\\k_{1}^{\omega}&=&h(lag(\theta_{n-\tau}, \omega_{n-\tau})+s\cos \theta_{n}+\xi \omega_{n})\\k_{2}^{\theta}&=&h(\omega_{n}+\frac{k_{1}^{\omega}}{2})\\k_{2}^{\omega}&=&h(lag(\theta_{n-\tau}, \omega_{n-\tau})+s\cos(\theta_{n}+\frac{k_{1}^{\theta}}{2})+\xi(\omega_{n}+\frac{k_{1}^{\omega}}{2}))\\k_{3}^{\theta}&=&h(\omega_{n}+\frac{k_{2}^{\omega}}{2})\\k_{3}^{\omega}&=&h(lag(\theta_{n-\tau}, \omega_{n-\tau})+s\cos (\theta_{n}+\frac{k_{2}^{\theta}}{2})+\xi(\omega_{n}+\frac{k_{2}^{\omega}}{2}))\\k_{4}^{\theta}&=&h(\omega_{n}+k_{3}^{\omega})\\k_{4}^{\omega}&=&h(lag(\theta_{n-\tau}, \omega_{n-\tau})+s\cos( \theta_{n}+k_{3}^{\theta})+\xi(\omega_{n}+k_{3}^{\omega}))\\\theta_{n+1}&=&\theta_{n}+\frac{1}{6}(k_{1}^{\theta}+k_{2}^{\theta}+k_{3}^{\theta}+k_{4}^{\theta})\\\omega_{n+1}&=&\omega_{n}+\frac{1}{6}(k_{1}^{\omega}+k_{2}^{\omega}+k_{3}^{\omega}+k_{4}^{\omega})\end{eqnarray*}

漸化式は、最後にジャイロ効果の項が加わっているだけで大きく変化していない。また、漸化式の解き方も、これまでの遅延制御モデルと同じである。

次回にその結果を示そう。

2022年1月30日日曜日

P制御とD制御

 数値シミュレーションで、P 制御にD制御が加わると、姿勢安定化への傾向が一挙に強まることわかった。そのことについて、少し考えてみる。

まず、サインカーブとコサインカーブを示しておこう。


青がサインで、赤がコサインだ。いま、例えばドローンの揺れ(ピッチあるいはロール)がサインカーブのように発生していると使用。P制御はその揺れを抑止する形で制御をかける。すなわち、サインカーブを水平軸で裏返したような動きの指示を与える。

これまでみたように、それでは揺れは治らない。また別の揺れを作り出すものだ。ところが、その揺れを微分した制御を加えるのが、D制御だが、 サインの微分はコサインなので、図のコサインカーブの逆向きの制御をかける。それが決定的に重要なのは、振動の位相が90度ずれているということである。

実際の機体が揺れている時の、ロールのP制御、とロールのD制御の値を示している。ただし、激しく細かく揺れ過ぎているので、20期(1期10msなので、200ms)の移動平均を取った値である。よくみると、D制御のピークがP制御のピークから少し早く始まっている。


制御における、位相をずらすことがD制御の大事な役割なのである。微分制御だから急激な変化を弱めるということも言われるが、より大事なのは、この位相をずらした制御だと思っている。

2022年1月29日土曜日

プロペラ用タコメーター(回転数 rpm 計測器)

 ESC信号に対してどれほど正しくモーターが反応しているかを確かめたかった。市販の非接触タコメーターも持っていて、飛行していない時の回転数はそれで計測できたが、飛行中、すなわちPID制御に対するモーターの反応が、信号と並列に捉えられない限り、その辺りが、どうしてもブラックボックスになっていて、精密なシミュレーションをする気にもならなかったが、なんとか自作のプロペラタコメーターをドローンにつなぐことができたので、色々わかってきた。

ここでは、また、もう一度作る時のために、メモがわりにここに書いておく。

反射型光センサーについては、以下のサイトを参考にさせていただいた。

http://nanoappli.com/blog/archives/5051

タコメータは、プロペラ直下に以下のように置かれている。




左側の黒いのが反射型の光センサーRPR220である。右の3ピンコネクタが、上からグラウンド、3.3V電源、信号の順になっている。真ん中の赤いものがLEDで、プロペラが直上に来ると、光る。白いプロペラはカウントできるが、黒いものはカウントできないので、反射シートなどをプロペラに貼る必要がある。

ここでは、小さい基盤に回路を組んで、モーターベースに強力接着テープで貼り付けている。

回路図は、次のようなものである。書き方のルールは特に意識していないが、簡単なので理解いただけると思う。

10Kオームの可変抵抗をつけているが、大事な役割を果たす。というのは、上に来た時の電圧レベルとそうでない時の電圧レベルの絶対水準を変更するもので、プログラム上でその境界電圧を設定するときに、調整して、4つのタコメータが同じになるようにしておかなければ、ややこしくなるからである。

私の場合は、プロペラがない時の信号電圧を1.0V、プロペラがある時のそれを1.9Vに調整し、1.5Vを超えたときにプロペラが通過したと判定するようにしている。この電圧は、RPR220とプロペラの距離によっても変わる。6ミリ程度離れているのが一番感度がいいと書かれていたが、私も、再接近で5mmくらいになるようにタコメーターを設置している。

信号は、SPIのシリアル通信で、ADコンバーター経由で、raspberrypiに送られる。距離センサーの電圧信号をデジタル信号に変換するのは、8チャンネルの、MCP3208を使った(MCP3204は、4チャンネルで、それでもいいのだが)。当初はI2CのADS1115を使っていたが、信号速度の遅さが気になって、圧倒的に早いSPI通信に変えた。

RaspberrypiのSPI通信は、一つのチャンネルが解放されていて、CS0とCS1が使える。CS0が超音波距離センサーのために塞がっているので、CS1にぶら下げた。他のバスは共通に繋いでおけば良い。もし、それ以上のデバイスをぶら下げる場合はRspberryPiは、もう一つSPIチャンネルが潜在的に利用可能になっている(いくつか処理をしなければならないが)。

MCP3208のRaspberryPI用のプログラムは、数多く公開されている。

それらをもとに、基準電圧を超えた回数をカウントするようにすれば、プロペラタコメータになる。

ESC信号とそれに対するモーターの回転数が、例えば次のように捉えられるようになる。

青い線がESCが与えた回転指示で、オレンジの線がそれに対する回転数だ。D制御の細かい揺れは回転数に反映することはできない。

PID制御によるドローンの揺れに関する数値シミュレーション(8):慣性モーメント

 遅延シミュレーション(7)では、制御に遅延がある場合に、深刻な困難が発生することを示した。

問題をどう克服するか。どこで遅延が発生するのかをきちんと把握することが必要である。モーターのパワーあるいは反応特性の可能性は高いと思っているが、制御コンピュータ(私の場合はRaspberryPI 4)からPWMモジュール、そしてESCの間の信号の流れの中で発生している可能性も否定できない。このような問題の所在を突き止めることはまた次の課題にして、ここでは、信号遅延があることを前提に、可能な解決の道を少し探りたいと思う。

これまでの記事については、以下を見ていただきたい。


先の記事で示した、フライトの破綻は、機体の動きに対する必要な制御が遅れることによって、加速度的に事態を悪化させている状況と見ることができる。そこで、機体の反応をゆっくりにして、信号の遅れを許容するようにすることが考えられる。それは、言い換えれば、機体の慣性モーメントを大きくして、動きをゆったりとしたものにすることである。

(1)腕の長さ1m、遅延200ms
中心からモーター位置までの距離を長くすると慣性モーメントは大きくなる。ここではL=1.0メートルにしよう。期待幅が2メートルを超えるドローンになるので、現実にはありえないが、何しろシミュレーションなので簡単である(笑)

プログラムは遅延シミュレーション(7)にリンク先を書いておいたので、そちらからダウンロードできる。そのパラメータLを1.0に変更したわけである。

ピッチ角とモーター回転数の結果は次のようになる。
(7)の結果と決定的に違うのは、加速度的破綻ではなく、一応、振動に留まっていることである。ただ、モーターの回転数が瞬間的に負になっている、フライトが破綻しているという事態は変わりない。その一瞬、モーターが逆回りするようなシステムであれば対応可能だが、まあ、ありえない。P制御と、D制御のスケールは、それぞれ10000と4000であり、遅延がない状況では、一瞬で安定したホバリングが実現できる状況である((5)を参照)。

後半では、ほぼ単振動状態になり、振動の周期は、約1秒である。

(2)腕の長さ1m、遅延100ms
もし、他は上と同じ状況で、遅延が半分の100msにとどまったとしたら次のような結果になる。(タイトルに L=0.5とあるのは、L=1.0の間違い)
揺れは正常に収束する。前のシミュレーションでは100msの遅延でも200msの遅延と全く変わらず、一方的に破綻していたのに、こちらは正常に収束している点では、完成モーめんを大きくすることの効果は絶大と言ってもいい。

その意味では、少しでも遅延を小さくした方がいいのである。まさに、喫緊の課題なのだ。

(3)腕の長さ1m、遅延200ms、P制御10000、D制御3000
(1)の状況から、D制御を3000に小さくしてみた。
比較すると、振動の周期が傾向的に増大、(1)のような単身同状態にはならなくなる。D制御が効かなくなったことがネガティブな影響を与えている。

(4)腕の長さ1m、遅延200ms、P制御5000、D制御4000
(1)の状態から、P制御だけを半分にした。




遅延が200msなのに、かなり急速に安定化している。

(5)腕の長さ1m、質量=1.0Kg、遅延200ms、P制御10000、D制御4000
(1)の状態からモーターにかかる機体荷重が1Kgに増えたとしよう。これは4ロータードローンの場合、機体荷重が4Kgになるということである。

当然、モーター強度も強くならなければならない。モーターの強度は、このシミュレーションモデルの場合、$\delta$で表され、それはホバリングを実現するレベル、与えられた機体荷重のもとで、基準回転数で重力による力と浮力がバランスする値として、自動で計算されるようにしている。その時は、機体の加速度がゼロになっているということである。

結果は次のようになる。


(1)と比べてみると、一瞬でもモーター回転が負になる状況が存在しないという点では、パフォーマンスは改善しているが、単振動化の事実は変わらない。

それでも機体重量の増加による慣性モーメントの増大はポジティブな結果をもたらすことはわかった。

(5)腕の長さ0.8m、質量=1.0Kg、遅延200ms、P制御5000、D制御4000
最後に、一応、いいところを入れたものを一つ示しておく。実用性はないのだが。


慣性モーメント、特に腕の長さが、遅延に対して影響を与えることは確認できた。

記事のシリーズ一覧は以下です。

PID制御によるドローンの揺れに関する数値シミュレーション(7):遅延シミュレーション 

PID制御によるドローンの揺れに関する数値シミュレーション(8):慣性モーメント

PID制御によるドローンの揺れに関する数値シミュレーション(9):ジャイロ効果

PID制御によるドローンの揺れに関する数値シミュレーション(10):ジャイロ効果シミュレーション



2022年1月28日金曜日

PID制御によるドローンの揺れに関する数値シミュレーション(7):遅延シミュレーション

 前の記事で示した、ドローンのPID制御において、制御とプロペラの回転の間に遅延がある場合のモデルを実際に計算してみる。

本稿で不明なところは、以下のページを参考にしてください。

目次:PID制御によるドローンの揺れに関する数値シミュレーション


モデルは、(6)の記事に示しているもので、それをc++でプログラム化する。

これまでは、EXCELを用いて、結果が直ちにグラフ化されるようにしていたが、遅延を組み込むと実行のたびにモデルの構造を変える必要性が出てくるようなので(モジュールを使えばもっと簡単に行くのだろうが面倒なので)C++で、遅延構造も含めパラメータを変更したのちの結果の数字はすぐにファイルに保存されるようにした。それはcsv形式になっているので、EXCELにも直ちに組み込め、グラフ化できるはずである。

c++のプログラムは、次のgithubのレポジトリから取得できる。ファイル名、pidlag.cppを選んでください。。


(1)遅延が200msの場合(P=10000, D=100)
これまでと同様のP制御に、緩くD制御をかけている。

ピッチ角とモーター回転数のグラフである。

最初から20期分は初期状態として与えたもので、これまでと同様に30度ほどピッチが正になるように期待を傾けて200msど持って、静かに離すというものである。ピッチ角度(青線:目盛左)は0.5でモータスピード(オレンジ線:目盛右)は、ピッチが正に傾いているために、ホバリングよりも少ない8000rpmくらいからスタートしている。90期に近づくと、実際にはありえないが、モーター回転数が負の領域まで落ち込んでしまっている。つまり1秒もたたないうちに飛行が破綻していることになる。

(2)遅延が50msの場合(P=10000, D=100)
遅延を1/4にした。1サイクル10msなので、5サイクル遅れて制御がモーター回転数に伝わるとしている。

状況は基本的に変わっていない。ただし、増加から低下、低下から増加への周期が短くなっている。

(3)遅延が20msの場合(P=10000, D=100)
元の1/10の遅延である。

ついに振動が現れた。

(4)遅延が10msの場合(P=10000, D=100)
1期分の遅れであり、これまでの遅延のないモデルのD制御の弱い状況に大きく近づいている。

(5)遅延が200msの場合(P=10000, D=1000)

元の200msの遅れの状態で、D制御のスケールを10倍にしてみた。状況はほとんど変わっていない。

これらをまとめると、ESCからプロペラの回転までの遅延は、ホバリングの姿勢制御に決定的な影響を与えるということである。なんとも、単純で分かりやすい結論に至った。


PID制御によるドローンの揺れに関する数値シミュレーション(6):制御遅延モデル

 これまでのモデルは、制御が直ちにモーターの回転数に反映することを前提にしていた。ESCの信号に対して機敏に反応するモータであれば、これまでの分析通りに結果が出るはずである。しかし、私の場合は、開発資金の貧しさによって、1個数百円から千円程度の2212型、KV値が920のトルク重視で、プロペラ9インチ用のモータを使っていると、このような機敏さは期待できない。

実際、最近、光反射センサーによるタコメータを自作し、回転中の4つのプロペラ回転数をリアルタイムで把握して送ってくるシステムをつけたところ、ESCの信号に対して、波形で確認される限り200ms程度の遅延が発生していることがわかった。これが、どれほどの問題か、自作ドローンの安定したホバリングの困難性と、どれほどつながっているかを調べることが、このシリーズの分析を始めた動機だった。

つまり、これからが本番なのである(笑)

お決まりで、これまでの議論のページをリストアップしておく。

目次:PID制御によるドローンの揺れに関する数値シミュレーション


以下の解説で不明なところがあれば、これらを参考にしていただきたい。

まず、ここでは、制御遅延を含むモデルを示そう。

プロペラ回転数$V$に対するPID制御の式は次のようになる。

$$V_{t} = V_{0} -P\theta_{t-\tau}-D\left.\frac{\theta_{t}}{dt}\right|_{t-\tau}$$

ここで、$V$はプロペラ回転数で、$V_{0}$は、ホバリング可能なプロペラ回転数、$\theta$は、ドローンのピッチ角である。$I$制御は、組み込んでいない(傾向的傾斜継続の理由がないので必要性もない)。

すなわち$\tau$期以前のピッチ角に対してモータが反応している状態である。この時、力学的な運動方程式は次のようになる。

$$\begin{eqnarray*}\frac{d^{2}\theta_{t}}{dt^{2}}&=&\frac{\delta}{mL} \left(V_{0}^{2}+P^{2}\theta^{2}_{t-\tau}+D^{2}\left(\left.\frac{d\theta}{dt}\right|_{t-\tau}\right)^{2}-2V_{0}P\theta_{t-\tau}+2P\theta D\left.\frac{d\theta}{dt}\right|_{t-\tau}-2V_{0}D\left.\frac{d\theta}{dt}\right|_{t-\tau}\right)\\& &-\frac{g}{L}\cos \theta_{t}\end{eqnarray*}$$

これは遅延のある二階の非線型常微分方程式で、遅延が加わった分、これまでのもの以上に複雑な面を持っている。非線型上微分方程式の遅延については「微分方程式による計算科学入門」(斎藤、小藤、三井)を参考にしたが、こちらが二階の微分方程式であることもあり、以下の理論モデルに誤りがあるかもしれないので、気づいたらお知らせいただきたい。

まず、連立させて一階の常微分方程式に変換する。

それにあたって、次のようなラグ関数$lag(t)$を定義しておこう。

$$lag(\theta, \omega) = a+b\theta_{t}+c\theta^{2}_{t}+d\omega_{t}+e\theta_{t}\omega_{t}+j\omega_{t}^{2}$$ 

ここに現れているパラメータ$a,b,c,d,e,j$は、常微分方程式の各係数に対応するもので、詳細は(4)に掲載されているもと同じなので、参照していただきたい。

この時、連立微分方程式は次のようになる。

$$\begin{eqnarray*}\frac{d\theta_{t}}{dt} & = & \omega_{t} \\\frac{d\omega_{t}}{dt} & = & lag(\theta_{t-\tau}, \omega_{t-\tau})+s\cos\theta_{t}\end{eqnarray*}$$

ここで遅延に関わる項は、全て関数 $lag(\theta_{t-\tau}, \omega_{t-\tau})$に集約されていて、その関数には当期の変数が現れず、第二式については、当期の変数は最後の項$s\cos\theta_{t}$の中にだけ現れている。また、第一式は、当期の項しか含まれていない。したがって、問題は見通しが良いものとなっている。ラグ関数の項$lag(\theta_{t-\tau}, \omega_{t-\tau})$は、その木までに既に値が確定してしまっているので、当期の中では、与件として扱う、つまり過去の値から決定される定数項として処理すれば良い。

一方、$s\cos\theta_{t}$は、常微分方程式としての適切な処理が必要になる。

その意味では、この遅延付きの常微分方程式は、差分方程式が混じった常微分方程式と考えればよいのではないかと思う。

 $lag(\theta_{t-\tau}, \omega_{t-\tau})$をそのように位置付けて、この連立差分方程式に、これまでと同じように4次のルンゲ・クッタ法を適用し、漸化式を求め、数値計算を行う。

漸化式は次のようになる。

$$\begin{eqnarray*}k_{1}^{\theta}&=&h\omega_{n}\\k_{1}^{\omega}&=&h(lag(\theta_{n-\tau}, \omega_{n-\tau})+s\cos \theta_{n})\\k_{2}^{\theta}&=&h(\omega_{n}+\frac{k_{1}^{\omega}}{2})\\k_{2}^{\omega}&=&h(lag(\theta_{n-\tau}, \omega_{n-\tau})+s\cos(\theta_{n}+\frac{k_{1}^{\theta}}{2}))\\k_{3}^{\theta}&=&h(\omega_{n}+\frac{k_{2}^{\omega}}{2})\\k_{3}^{\omega}&=&h(lag(\theta_{n-\tau}, \omega_{n-\tau})+s\cos (\theta_{n}+\frac{k_{2}^{\theta}}{2}))\\k_{4}^{\theta}&=&h(\omega_{n}+k_{3}^{\omega})\\k_{4}^{\omega}&=&h(lag(\theta_{n-\tau}, \omega_{n-\tau})+s\cos( \theta_{n}+k_{3}^{\theta}))\\\theta_{n+1}&=&\theta_{n}+\frac{1}{6}(k_{1}^{\theta}+k_{2}^{\theta}+k_{3}^{\theta}+k_{4}^{\theta})\\\omega_{n+1}&=&\omega_{n}+\frac{1}{6}(k_{1}^{\omega}+k_{2}^{\omega}+k_{3}^{\omega}+k_{4}^{\omega})\end{eqnarray*}$$

なお、今までは、開始時の状態を初期状態として与えらばよかったが、遅延モデルの初期状態は、ラグの期数分だけ事前に与えなければならない。

これを次の記事(7)で、C++プログラムにして解いてみよう。


ピコをudevを制御して区別する

 システムで、dshot信号を作るのをpicoでやらせていた。UARTの使用の関係で、pico1台で、2つのモータに信号を送っていたので、2つのpicoを使っていた。それまでは、pico二信号を送って、あなたはどちらのpicoですかと問い合わせして、その答えを聞いて /dev/t...