2022年1月24日月曜日

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

ドローンにPID制御をかけると、安定化は可能であるが同時に機体の揺れも発生させる。この状況を数値シミュレーションする。ただし、今回は、ESCに与える信号と、モーターの回転数の変化の間に遅れが発生しないことを前提にする。このラグのある場合の状況は次に試みる予定だ。

というよりも、もともとこの分析を始めるきっかけが、自作ドローンの信号とモーター回転数の間にあるラグがPID制御の不安定の原因だと思ったことだ。それを分析したいのだが、まず単純でピュアな状態を分析しなければ話にならないので、最初はその前提で進める。

モデルを示そう。



4ローターのドローンを想定しているが、問題の趣旨から、ロールないしはピッチの片方だけ考慮すればよい。上図のように、モーターの腕方向に機体座標が設定されているとする。



ピッチをイメージしよう。先頭のモーター番号を1後方を2とする。zが垂直方向で、xがピッチが現れる水平方向である。

機体が太黒線のように傾いた状態を考える。また、問題はさらに単純化できる。

今、二つのモーターが完全に対称に動くとすると、原点Oが固定されていて、一方のモータの動きだけで回転する状況を想定すればよい。今そのモータを2番のモーターだとしよう。以後、1番のモーターの動きは問題にしない(Oが固定されているので)。

接線方向の運動方程式を立てる。モーターによる推力を$F$とする。重力加速度を$g$、機体のモーターにかかる重さを$m$とする。これは全機体重の1/4と考えてよいかもしれない(深く考えると色々ありそうだが、無視する)。さらに、図のように、機体がピッチが正の方向に$\theta$(ラジアン単位)だけ傾いているとしよう。上向きの接線方向の速度を$v$とすると、運動方程式は次のようになる。

$$\begin{equation} m\frac{dv}{dt}=F-mg\cos \theta \end{equation}\label{eq1}$$

また、角速度を$\omega$とすると、次の式が成立する。

$$\begin{equation}v=L\frac{d\theta}{dt}=L\omega\end{equation}\label{eq2}$$

プロペラの1分あたり回転数を$V$(単位rpm)とする。一般に、推力$F$ は、$V$の二乗に比例すると考えられているので、次の式を考える。

$$\begin{equation}F=\delta V^{2}\end{equation}\label{eq3}$$

ここで、$\delta$は、ある与えられたプロペラの元でのモーターパワーを表すパラメータと考えれば良い。

PID制御のP制御(比例制御)を次の式で導入する。微分(D)制御も入れることは可能だが、以下計算がさらに複雑になるので、次の課題とする。ただし、D制御を入れないと安定化しない場合があるので、それは念頭に置いておかなければならない。(D制御を入れたモデルは、次の記事で行なっているPID制御によるドローンの揺れに関する数値シミュレーション(4):P制御+D制御モデル)

$$\begin{equation}V=V_{0}-p\theta\end{equation}\label{eq4}$$

ここで、$V_{0}$は、ホバリングを実現可能なスロットルレベルに対応したモーターの回転数である。$p$は、P制御の水準である。すなわち、このシミュレーションモデルにある唯一の制御変数である。$\theta$はピッチ角なので、ピッチ角に比例してモーターの回転数を制御することになる。ピッチ角がゼロの時は、ホバリングレベルのモーター回転数で、ピッチが正になると回転数を落とす方向に、逆に負になると回転数を増やす方向に変化させる。

私が自作のドローンで問題視しているのは、この制御信号が回転数に変化する上で200m秒くらいタイムラグがあることだ。それを本来調べるためのこの数値シミュレーションをしようと思ったのだが、そのタイムラグを入れるのは次の課題としてて、まず、タイムラグなしにESC信号をモータは回転数に反映させるとここでは考えている。(制御の遅延を組み込んだモデルは、このシリーズの「(6)の記事」以降で解析している)

この制御式$\eqref{eq4}$を、回転数と力の関係$\eqref{eq3}$に入れる。

$$\begin{equation}F=\delta V^{2}=\delta (V_{0}-p\theta)^{2}=\delta V_{0}^{2}-2p\delta V_{0}\theta+p^{2}\delta \theta^{2}\end{equation}\label{eq5}$$

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

$$\begin{equation}F=\alpha-\beta\theta+\gamma\theta^{2}\end{equation}\label{eq6}$$

ここで、$\alpha, \beta, \gamma$の各パラメータは、$\eqref{eq5}$式の各パラメータを表している。この式を運動方程式$\eqref{eq5}$に代入すると、次の式を得る。

$$\begin{equation}mL\frac{d^{2}\theta}{dt^{2}}=\alpha-mg\cos \theta-\beta \theta+\gamma \theta^{2} \end{equation}\label{eq7}$$

両辺を$mL$で割ると、

$$\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{eq8}$$

を得る。これは、二階非線型常微分方程式である。これを満たす$\theta$の振る舞いについて、解析的を求める方法が有るかどうかはわからなかった。しかし、ここでおこなう数値シミュレーションはこのままの形で実行可能、実際、あとでその結果を示すことができる。

ただ、その前に、ここでは議論をわかりやすくするために、$\theta$の値が小さい範囲で成立する、

$$\cos\theta\simeq 1$$

という近似を用いて議論の見通しをよくする。この時、$\eqref{eq8}$は、次のように書き換えることができる。

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

これもまた、二階非線型常微分方程式であるが、これには解析解が存在している。(例えば. http://www6338.la.coocan.jp/mathematics/diff-equation.pdf 参照)しかし、それはワイエルシュトラスの$\wp$関数を用いて表現される楕円関数を使うもので、そこまで複雑なものは上手く扱えない。

そこで、さらに、この$\theta$の二乗の項(右辺最後の項)が存在しなかった場合を考えてみよう。すなわち、

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

となる。これは、高校物理でもお馴染みの、中心が原点以外のところにある単振動の式に他ならない。詳しくは教科書を見ていただきたいが、これは、周期$T$が、
$$T=2\pi\sqrt{\frac{mL}{2pV_{0}\delta}}$$
単振動の中心位置 $\theta_{0}$が、

$$\theta_{0}=\frac{1}{2p}\left(V_{0}-\frac{mg}{V_{0}\delta}\right)$$
となるものである。つまり、振動への傾向は、このモデルに内蔵されているということである。しかし、制御機能があるので、その振動は安定、すなわち一定の時間が経てば収束する可能性ももちろん持っている。

また、$\theta$が小さい範囲ということは、また、最終項の$\theta^{2}$も小さいと考えることもできるので、そうなると、このリアリティは重要だ。しかし、実際のドローンは、わずかな傾きでも、水平方向へ移動する。水平移動は、まだモデルに組み込んでいないので、このシミュレーションには現れない(いずれ組み込みたい)。このような振動の影響の大きさを考えると、この近似は避けるべきだ。

そこで、ここでは$\eqref{eq8}$そのものの数値シミュレーションを行うことにする。ここからは、次の記事(2)で解説する。

このシリーズの記事の目次は次のところにある。


2022年1月9日日曜日

ESCをメーカー品にしてみた:スロットル90%までの直線性

 今まで、安くて動けばそれでいいと思って、ノーブランドのESCを利用してきた。その結果が、先の投稿にも書いたように、肝心の離陸後のスロットル直線性が失われ、制御できない状態になっていた。

そこで、ESCを 「ブラシレスESC 40A アンプ SBEC 5V/3A RC飛行機固定翼空用スピードコントローラー ZTW Beatles 40A ESC 2-4S」というものを1個Amazonで買って(2500円、ちょっと高いが)、交換してみた。スロットルと回転との関係は、次のようなものになった。


驚くべき違いだ。スロットル90%まで、ほぼ直線的に上昇している。最大回転数も、前のESCが最大およそ13000だったので、30%増大している。

50%までは、前と同じに伸びている。その前あたりで離陸するので、スロットルで30%分の制御余地が出てきている。これだと、少なくとも駆動部分で制御の問題は現れないはずだ。

早速、残りの3個も購入した。明後日の朝、到着する。楽しみだ。

2022年1月7日金曜日

モーター駆動の線形性


 いくら制御信号をきちんと出力しても、それに正しくモーターが反応していなければ、姿勢制御はできない。

この間、そのあたりの問題が気になった。まず、スロットルレベル(%)とモーターの回転数を調べた。


こんな感じである。縦軸が回転数だが、プロペラ2枚の回転数を測っているので、半分にしなければならないはずだ。そうなると、モーターは、940Kvなので、回転数が少ない。1Vあたり940rpmであるから4sバッテリーで少し多めに15V(実際16Vの時もある)としても28200回転くらいなければならないのだが、最大でもその半分以下である。非接触回転系が、プロペラの数に無関係に回転数を測れるなら別だが、そんなことは考えられない。
そしてなによりも線形性だ。スロットルレベル40%あたりから徐々に線形性(厳密には直線性のこと)が崩れる。ということは、信号に対して比例的にモーターが反応していないということだ。そもそも、スロットルレベルが40%後半で期待は浮上するので、浮上した途端、制御信号に正しく反応しなくなることを意味している。これでは、姿勢が制御できるわけがない。

心配になって、PWMモジュールからESCに対して、正しく信号が送られているかが気になって、以前も調べたのだが、再度オシロスコープで調べ直した。

特に問題は見当たらなかった。

ということは、ESCか、モーターに問題があるが、ESCの可能性が高い。というのも、Kv値がおおきなレース用モーターのESCに、今使っているモーターを繋いで、回転数を測ったところ、少なくとも60%くらいまでは線形性を確保していたからだ(それ以上は、回転数が大きすぎて怖くて測らなかった)。

2021年11月14日日曜日

スロットルレベル20%の回転数

 引っ接触タコメーターで測定したところ

No.1 3070rpm

No.2 2749rpm

No.3 2715rpm

No.4 2745rpm

というわけで、No.1だけが大きく異なる。これは、このドライブだけが、違うESCを使っているかだ。

さらにいろいろ調べた結果、基本的な問題は、キャリブレーションだった。全てのESCをキャリブレーションしなおしたら

No.1 2800rpm

No.2 2891rpm

No.3 2871rpm

No.4 2865rpm

と、誤差の範囲の差しか出なくなった。これくらいは、フライトコントローラーが吸収できるはずだ。

2021年11月10日水曜日

C++ forkとパイプ

 フライトコントロールの制御ループは、ミリ秒単位の周期になる。C++のスレッドで簡単にできそうだったが結局うまくいかず、forkコマンドで子プロセスを作って動かしている。


途中、親から子プロセスのパラメータを変更するときにパイプ機能を使うことになった。一つハマったのが、パイプはforkする前に作らなければならないことだ。

2021年10月11日月曜日

ESCを経由したモーター制御

 ドローンを制御する一番基礎はモーターのコントロールだ。

ということで、この間かなり徹底的に、ラズパイからのモーター制御を試みてきた。そして、その細かいところまで要約できたようなので、次の姿勢制御の問題に移っている。

そこで、モーター制御のポイントをここに書いておこう。ラズパイから、I2C経由で、PCA9685を制御し、そこでPWM信号を生成しESCを制御するというのが基本的流れだ。PCA9685は、ハード的にパルス信号を生成する。

このパルスの周波数を指定しなければならないが、オシロスコープでしらべると、PixHawkは400Hzを使用していることがわかった。したがって、周期は2.5msである。2500マイクロ秒ということになる。この周期の中で、パルスのONの期間の長さがモータの強さとなる。これは、PixHawkの場合、1000マイクロ秒までが、モーターが動かないパルスはちょうとなている。そして、1250マイクロ秒が出力0%で、2000マイクロ秒が最大である。

このことをESCに記憶させなければならないが、これがキャリブレーションである。

このあたりのことは、

https://team432.jpn.org/?p=272

で、勉強させていただいた。

周波数などはPCA9685に設定できる。

実際は1250マイクロ秒が0%出力ではなく、1300マイクロ秒にするとようやく起動する。

2021年10月1日金曜日

RaspberryPIとMPC23S17の接続

 距離センサーを5個、raspiに接続しようとして、GPIO拡張用のMPC23S17に繋げようとして時間がかかったので、ここに記録しておこう。








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

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