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++プログラムにして解いてみよう。


2022年1月26日水曜日

ドローンPID制御の意味

 この間、今現に作製しているドローンの使用に近づけて、物理的な現象をより再現する形で、PID制御をシミュレーションするという作業をやってきた。それで気づいたことをメモがわりにここに書いておく。

まず何よりも、P制御では、一応揺れが収束はしていくものの、機体の安定を実現するのは困難なレベルだった。とろこが、D制御をしっかり入れると、揺れは、あるいは初期の傾きは一挙に解消して水平を実現してしまう。それは驚くべきほどのレベルでそうなった。

その時のモーター回転に対する、P制御とD制御のレベルをグラフに書かせてみた。最終的には、ほとんど揺れなく水平状態になるのだが、あえてD制御のスケールを少し抑え気味にした時の結果をグラフで示しておこう。

これは、D制御を500というスケールで入れた場合だった。オレンジの線が回転数という単位で見たD制御の調整量の推移である。これに対して、青の線は、同じく回転数で見たP制御のスケールである。回転数で見たとは、そのレベルの回転数の調整がモータに指示されるという意味である。このD制御のレベルを2000まで増加すると、揺れなく、ワンショットで、水平状態を達成してしまう。(ひとつ前の記事を見ればその図を見ることができる)

この状況ですら、P制御だけに比べてみれば、より急速に水平かを実現しているものとなっている。なぜD制御を入れるとそうなるのか。それは、見てもわかるように、調整周期のズレである。P制御は実際の機体の傾きを比例的に反映するが、D制御は、実際の傾きに対して周期が微妙に遅れている。その遅れによって、揺れを打ち消しているのである。

今まで、D制御はパルス的な反応に対して、それをまず打ち消す動きとして現れるというような認識でいた。パルス的な動きが重要だと思っていたのである。しかし、そのようなものは、このシミュレーションの動きの中では現れないし、たとえ現れたとしても姿勢安定化の上で大きな役割を果たさないだろう。

実機の飛行状態のモーターの回転数がログされるようになったので、わかってきたことは、そのようなパルス的なD制御の信号に対して、モータは反応できないということである。だから、D制御は、実機では重要な機能を持たせられないなと思い、P制御だけでなんとかならないかと思うようになっていた。そして、姿勢から周期を推測して、P制御のずれた形での制御信号を与えればなんとかなるのではと思っていたのだが、D 制御はまさにそれをやっていたのである。

sinカーブを微分するとcosカーブになる。つまり、1/4周期、微分は遅れるのである。上の図の揺れの1周期は約1.2秒であり、その1/4は300msである。この遅れこそが素早い収束の動きを実現する決定的要素だと考えられる。

やっぱり信号から回転数へのラグの問題を考えないといけないか。


2022年1月25日火曜日

PID制御によるドローンの揺れに関する数値シミュレーション(5):P制御+D制御の計算

 ドローン姿勢のPID制御のうち、P制御とD制御を行なったシミュレーション結果を示す。これまでの議論については、以下のページを参照してください。

PID制御によるドローンの揺れに関する数値シミュレーション(1):理論編

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


以下で解説する、EXCELのシミュレーションファイルは、以下からダウンロードできる。(基本的にEXCELで開いてください。Googleのスプレッドシートなど代替ソフトで開くと、計算とグラフ表示に問題が生じる可能性があります。クリックして、Googleのスプレッドシートが開いてしまった場合は、メニューの「ファイル」から一旦ダウンロードしたのちにExcelで再実行してください)

EXCELファイル(モジュールなし)のダウンロード(2022/01/28修正)

EXCELファイル(モジュール組み込み済み)のダウンロード(2022/01/28修正)

シミュレーションにはRKMETHODという自作の関数をEXCELのVBAで作成し使用している。モージュールなしを選んだ場合は、それがないというエラーが出るので、「ツール」→「マクロ」からVBAのエディタを開いて、「挿入」→「標準モジュール」をクリックして、エディタを開き、次の関数をコピペしてください。そして、PDパラメータなどを更新すると正しく表示されます。

(次から)

Function RKMETHOD(a As Double, b As Double, c As Double, d As Double, e As Double, j As Double, s As Double, omega As Double, theta As Double, k_omega As Double, k_theta As Double) As Double

    RKMETHOD = a + b * (theta + k_theta) + c * (theta + k_theta) ^ 2 + d * (omega + k_omega) + e * (theta + k_theta) * (omega + k_omega) + j * (omega + k_omega) ^ 2 + s * Cos(theta + k_theta)

End Function

(以上)

ファイルの使い方を説明する。


ファイルを開くと左側に、パラメーターの設定欄、右側にシミュレーションの実行画面が現れる。パラメータを変更すると自動的にシミュレーション結果も変更される。ただし、計算量が多いので、時間が1、2分かかる場合があるかもしれない。その時はそのまま待つしかない。

開いたEXCELシートの左側のパラメータは、私の自作ドローンの使用に沿ったものが書いてある。薄緑蘭のものは、任意に変更が可能である。薄赤の欄は、自動的に変更されるパラメータである。

パラメータの説明を加える。

スロットル(回転数:rpm)
これはドローンのホバリングするプロペラ回転数を書いてください。初期値としては、13000rpmが入力されていますが、小型のドローンでは数万rpmになるのではと思われる。
回転数を力に変換
これは、回転数を水力に変換するパラメータである。が、他が入力されると、機体角度が水平の時の回転数が、上で定義された回転数になるような、適切な値が、自動的に与えられることになっている。これは、理論のページで解説されているので参照して、自力で変更しても問題ない。
機体質量 Kg
これは、機体重量をプロペラの数で割ったものをKg単位で入力することが妥当だ。
中心とモーター間の距離 m
腕の長さである。機体の中心から一つのプロペラの軸までの長さをm単位で入力する。
制御パラメータP
Pパラメータのスケールを記入する。0にすると、P制御が働かない状態になる。
制御パラメータD
Dパラメータのスケールを記入する。0にすると、D制御は働かない。
Δt (時間間隔:秒)
シミュレーションのステップ間隔である。これを大きくすると、計算は速くなるが精度が悪くなる。逆は逆である。

以下、私の自作ドローンのパラメータで実行したシミュレーション結果を示しておこう。初期状態は、ピッチ角が0.5にしてあるので、ピッチが正の方向に30度ほど傾けた状態で、角速度の初期値はゼロにしているので、どの方向にも力を加えず、そのままただ手を離した状態だと考えればよい。
(1)P=10000, D=0
まず、微分制御を入れない、すなわちD=0の場合を調べよう。これは、前に実行したシミュレーションの再現になるはずである。




掲げた図は少し小さいが、ダウンロードしたファイルにP=10000, D=0を代入して実行すれば、このグラフも表示される。
0.8秒くらいの周期で期待が揺れる。自作機の揺れの周期とほぼ等しい感じだ。振幅は変わらない。
振幅は、これ以降もほとんど変わらない。単振動状態である。P制御だけでは姿勢制御は困難なことを意味している。

(2)P=10000, D=100
D制御をD=100のスケールで導入する。




先の場合と比べると、揺れが急速に小さくなっていくことが確認できる。
(3)P=10000, D=1000
さらに10倍のスケールでD制御を加える。




揺れとは言えないほど、ほんの僅かに機体角が負の側に振れただけで、ほぼホバリングを再現している。モーター速度も、一瞬、ホバリングの回転数を超えただけである。
(4)P=10000, D=2000
さらに、D制御のスケールを2倍にした。




ピッチ角は一直線にゼロに収束し、揺れはほとんどなく、一方的にホバリング状態を再現している。ピッチ角がゼロで安定するまでに、0.7秒しかかかっていない。
(5)P=10000, D=5000
さらにD制御を強めたらどうなるか。
モーター速度は、瞬間的に13000rpmを達成しているが、ピッチ角がゼロになるまでに、2秒以上の時間を要するようになり、実用的ではなくなってしまった。


以上の結果は、D制御が高い有効性を持っていることを示している。その一方で、過度に損は姿勢制御に悪影響を及ぼすことがわかる。



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

 これまでの記述については、以下のページを参考にしてください。

PID制御によるドローンの揺れに関する数値シミュレーション(1):理論編

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


モデルについての基本的なコンセプトはこれまでの議論を踏襲する。これまでは、PID制御と言ってもP制御だけを組み込んだモデルを扱ってきた。確かに、P制御は基本的なものだが、結果として、機体の揺れは、収束には向かうものの時間がかかったり揺れの大きさでドローンを安定させるためには不十分なものだった。

そこで、ここではさらにD制御もモデルの中に組み込んでその効果を確認する。

すなわち、

$$V=V_{0}-P\theta-D\frac{d\theta}{dt}$$

とする。$V$はモーター回転数(rpm)で、$V_{0}$は、ホバリングを可能にする定常回転数である。$\theta$はピッチ角であり、$t$は時間である。$P$は制御係数でピッチ角に比例して、その揺れを抑える方向に回転数を調整する。$D$は、揺れの急激な変化に反応する微分項である。

モーターの推力$F$は、次のようになる(パラメータの意味および式の解説はこれまでの記事を参考にしていただきたい)。
$$\begin{eqnarray*}F & = & \delta V^{2} \\& = & \delta \left(V_{0}-P\theta-D\frac{d\theta}{dt}\right)^{2} \\& = &  \delta \left(V_{0}^{2}+P^{2}\theta^{2}+D^{2}\left(\frac{d\theta}{dt}\right)^{2}-2V_{0}P\theta+2P\theta D\frac{d\theta}{dt}-2V_{0}D\frac{d\theta}{dt}\right)\end{eqnarray*}$$

これを運動方程式

$$mL\frac{d^{2}\theta}{dt^{2}}=F-mg\cos \theta$$

に代入し変形すると、

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

となる。これまでと同様に、これは特殊な二階非線形常微分方程式で帯域的な解を求めることはできるのかもしれないが、一般に困難なものとなる。ここでの目的は、数値的解が目的なので、一般解にこだわる理由もない。

4次のルンゲ・クッタ法で解くためのモデルを示そう。

まず、この二階の常微分方程式を一階の連立常微分方程式に変換する。角速度を$\omega$とすると、

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

簡単化のため、この第2式を次のように表そう。

$$\frac{d\omega}{dt}=a+b\theta+c\theta^{2}+d\omega+e\theta\omega+j\omega^{2}+s\cos\theta$$

各係数は次のようなものである。

$$\begin{eqnarray*}a & = &  \frac{\delta V_{0}^{2}}{mL}\\b & = &  -\frac{2\delta V_{0}P}{mL} \\c & = &   \frac{\delta P^{2}}{mL}\\d & = &   -\frac{2D\delta V_{0}}{mL}\\e & = &   \frac{2DP\delta}{mL}\\j & = &   \frac{\delta D^{2}}{mL}\\s & = &  -\frac{g}{L}\end{eqnarray*}$$

モデルの記述をわかりやすくするために、ここで次のような関数を定義する。

$$\begin{eqnarray*}f(\omega_{n},\theta_{n},k^{\omega},k^{\theta})&=&a+b(\theta+k^{\theta})+c(\theta^{2}+k^{\theta})+d(\omega+k^{\omega})\\& &+e(\theta+k^{\theta})(\omega+k^{\omega})+j(\omega+k^{\omega})^{2}\\& &+s\cos(\theta+k^{\theta}))\end{eqnarray*}$$

これは、EXCELで計算するときに、VBAで定義しても使う。これを使うと、微分方程式を解くための漸化式は次のように定式化できる。$n = 0, 1, 2 \cdots$は、繰り返される時間、ステップを表している。

$$\begin{eqnarray*}k_{1}^{\theta}&=&h\omega_{n}\\k_{1}^{\omega}&=&hf(\omega_{n},\theta_{n},0,0)\\k_{2}^{\theta}&=&h(\omega_{n}+\frac{k_{1}^{\omega}}{2})\\k_{2}^{\omega}&=&hf(\omega_{n},\theta_{n},\frac{k_{1}^{\omega}}{2},\frac{k_{1}^{\theta}}{2})\\k_{3}^{\theta}&=&h(\omega_{n}+\frac{k_{2}^{\omega}}{2})\\k_{3}^{\omega}&=&hf(\omega_{n},\theta_{n},\frac{k_{2}^{\omega}}{2},\frac{k_{2}^{\theta}}{2})\\k_{4}^{\theta}&=&h(\omega_{n}+k_{3}^{\omega})\\k_{4}^{\omega}&=&f(\omega_{n},\theta_{n},k_{1}^{\omega},k_{1}^{\theta})\\\theta_{n+1}&=&\theta_{n}+\frac{1}{6}(k_{1}^{\theta}+2k_{2}^{\theta}+2k_{3}^{\theta}+k_{4}^{\theta})\\\omega_{n+1}&=&\omega_{n}+\frac{1}{6}(k_{1}^{\omega}+2k_{2}^{\omega}+2k_{3}^{\omega}+k_{4}^{\omega})\end{eqnarray*}$$

初期値、$\theta_{0}$および$\omega_{0}$が与えられると、上から順に代入していけば、$\theta_{1}$および$\omega_{1}$が得られ、これを繰り返すことによって機体角とその加速度の系列を得ることができる。

EXCELによる実際の計算とその結果は次回示します。

このシリーズの記事目次。

2022年1月24日月曜日

PID制御によるドローンの揺れに関する数値シミュレーション(3):EXCELで実行

 ここで実行するシミュレーションモデルについては、以下の二つの記事で解説している。必要に応じてそちらを参照していただきたい。

PID制御によるドローンの揺れに関する数値シミュレーション(1):理論編

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

以下で解説する、EXCELのシミュレーションファイルは、以下からダウンロードできる。(EXCELで開いてください。代替ソフトで開くと、データや式は問題ないと思いますが、グラフが正しく表示されない可能性があります。グラフを書き直せば大丈夫だと思いますが)

EXCELファイルのダウンロード(このファイルのダウンロードを中止しました。D制御も組み込んだより一般的なモデルのEXCELファイルをお使いください。その中で、この記事の結果が再現可能です【D制御パラメータをゼロにする】。以下のリンク先にある、このシリーズの(5)の記事からダウンロードできます。)


ファイルの使い方を説明する。

ファイルを開くと、緑の縦線の左側に設定すべきパラメータの欄があり、「パラメータ」の蘭のDeltaという項目以外を入力する必要がある。Deltaは、そのままにすると、自動的にホバリングレベルのプロペラ回転速度で、上昇力(スラスト)と重力加速度がバランスするように計算される。あえて違う値を入力する場合は、そうしてもよい。どうなるかはご自身で考えていただきたいが、モデルが壊れることはないので、自由にやられたらよいと思う。

ダウンロードした現状は、私の自作のドローンに関わる値がセットされている。

右側は、パラメータに基づいて、シミュレーションが実行される。左側に時間の推移が示されている。時間の刻みはパラメータのΔtの欄で指定することができる。現状では、10ms毎に実行される(私の自作システムのループタイムに一致させているが、それより長くても短くてもよい)。
その後各期のパラメータが続いて、最後から3列目に、機体角度の$\theta$およびその角速度$\omega$、さらにその外側に、プロペラの回転数の変化が現れる。

パラメータを変更すると、実行結果全てがそれに合わせて自動的に変わる。

私の自作ドローンのパラメータで実行した結果を少し解説しよう。まず、解そのものを見てみよう。

この図は小さいが、EXCELの中にオリジナルが表示されているはずで、それを見ていただきたい。青い線が機体の傾き、ピッチ角を表す解で、単位は左側の軸に示されている。ラジアンで、0.1前後を頂点とする揺れなので、この揺れの角度は、30度が、π/6だから、0.1は、6度くらいの傾きが現れている。角速度は、当然ずれていて、期待が水平状態の時、絶対値で最大になる。速度は、正負が現れる。

また、その周期は約1秒である。少し緩い揺れだと思うが、自分のドローン的には、結構いいところだと思っている。

P制御だけでは揺れの制御が全くできていないことがわかる。

モータの回転数とピッチ角を同じグラフで表すと次のようになる。


興味深いのは、モータの回転の変化から、実際の回転角の変化が現れるまで、800msくらいラグがあるということである(ちょっと大きすぎる)。ESC信号から、モータの回転までのラグが、200msくらいあることが気になっているが、それ以上に回転と推力の間のラグがあるといことだ。
プロペラの回転は、直ちに力を生み出し、遅れるっことなく機体の加速度を生み出す。しかし、その加速度が、一定の機体の回転回転角の変化につながるためには、時間がかかるということだ。加速度と速度の関係から明らかなのだが、改めてなるほどと感じさせられた。
 

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

 ここで実行する数値シミュレーションモデルは、次の2階非線型常微分方程式で表される。

それは、次の式で表される。

$$\begin{equation}\frac{d^{2}\theta}{dt^{2}}=\frac{1}{L}\left(\frac{\alpha}{m}-g\cos \theta\right)-\frac{\beta \theta}{mL}+\frac{\gamma}{mL} \theta^{2} \end{equation}\label{eq11}$$

この式がどのように導出されるかについては、以下のページで詳しく説明しているので、参照いただきたい。

PID制御によるドローンの揺れに関する数値シミュレーション(1):理論編

動きを確かめるのは、$\theta$のピッチ角である。

$t$は時間、$L$はドローン中心からモーター位置までの距離、$m$は、ドローンのモーター位置にかかる質量である。$g$は、重力加速度である。また、パラメーター$\alpha, \beta, \gamma$は次のように表される。

$$\begin{eqnarray*}\alpha&=&\delta V_{0}^{2}\\\beta&=&2pV_{0}\delta\\\gamma&=&p^{2}\delta\end{eqnarray*}$$

ここで、$\delta$はモーターの回転数の二乗を力(N)に変換するパラメーターでモーターのパワー水準を表すパラメータである。$V_{0}$は、ホバリング状態を可能にするプロペラ回転数、$p$は、PID制御のうちのP 制御のパラメータである。先のモデル解説でも述べたように、現時点でのモデルでは、P制御のみを組み込み、D(微分)制御は次の課題にしている。(I制御は、モデルの性質上不要と考えている。傾向的傾きを作る潜在要素が見当たらない)

シミュレーションは、常微分方程式に関する4次のルンゲ・クッタ法を用いる。ただし、この常微分方程式は、2階なので、1階の常微分方程式を連立させる方法で行う。そのためにやや複雑になることが避けられない。

$\eqref{eq11}$の係数を$a, b, c, d$にまとめて、見やすくし、次のように表す。

$$\begin{equation}\frac{d^{2}\theta}{dt^{2}}=a-b\cos \theta-c\theta+d\theta^{2}\end{equation}\label{eq12}$$

また、初期値は、$\theta$の初期値$\theta_{0}$と角速度$\frac{d\theta}{dt}=\omega$の初期値$\omega_{0}$が与えられているものとする(シミュレーションでは、妥当な数値を適当に与えればよい)。

この時、上記の二階常微分方程式は、次の連立1階常微分方程式として表される。

$$\begin{eqnarray*}\frac{d\theta}{dt}&=&w\\\frac{d\omega}{dt}&=&a-b\cos \theta-c\theta+d\theta^{2}\end{eqnarray*}$$

この二つの式に、4次のルンゲ・クッタ法を用いる。(4次のルンゲ・クッタ法については、『微分方程式による計算科学入門』三井、小藤、斎藤著、「常微分方程式の数値計算法」山本昌志など、参照)

計算式は、次のような10本の式で表される。以下の、$n: (0,1,2,\cdots)$は時間を表す。

$$\begin{eqnarray*}k_{1}^{\theta}&=&h\omega_{n}\\k_{1}^{\omega}&=&h(\alpha-b\cos(\theta_{n})-c \theta_{n}+d \theta_{n}^{2})\\k_{2}^{\theta}&=&h(\omega_{n}+\frac{k_{1}^{\omega}}{2})\\k_{2}^{\omega}&=&h(a-b\cos(\theta_{n}+\frac{k_{1}^{\theta}}{2})-c( \theta_{n}+\frac{k_{1}^{\theta}}{2})+d (\theta_{n}+\frac{k_{1}^{\theta}}{2})^{2})\\k_{3}^{\theta}&=&h(\omega_{n}+\frac{k_{2}^{\omega}}{2})\\k_{3}^{\omega}&=&h(a-b\cos(\theta_{n}+\frac{k_{2}^{\theta}}{2})-c( \theta_{n}+\frac{k_{2}^{\theta}}{2})+d (\theta_{n}+\frac{k_{2}^{\theta}}{2})^{2})\\k_{4}^{\theta}&=&h(\omega_{n}+k_{3}^{\omega})\\k_{4}^{\omega}&=&h(a-b\cos(\theta_{n}+k_{3}^{\theta})-c( \theta_{n}+k_{3}^{\theta})+d (\theta_{n}+k_{3}^{\theta})^{2})\\\theta_{n+1}&=&\theta_{n}+\frac{1}{6}(k_{1}^{\theta}+2k_{2}^{\theta}+2k_{3}^{\theta}+k_{4}^{\theta})\\\omega_{n+1}&=&\omega_{n}+\frac{1}{6}(k_{1}^{\omega}+2k_{2}^{\omega}+2k_{3}^{\omega}+k_{4}^{\omega})\end{eqnarray*}$$


これがシミュレーションモデルとなる。初期の$\theta_{0}, \omega_{0}$が与えられると、上記の式の上から順にこの値を与えていけば、次期の$\theta_{1}, \omega_{1}$を得ることができる。これを繰り返せば$\theta_{0}, \theta_{1}, \theta_{2}, \theta_{3},\cdots$および$\omega_{0},\omega_{1}, \omega_{2}, \omega_{3},\cdots$を得ることができる。


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

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