2022年12月14日水曜日

920MHz帯無線通信モジュールTY92SS-E2730を使う

 先にも書いたが、ドローン2号機上のコントローラーはラズパイ4で、それとのやりとりをもともとWIFI経由で予定していたが、機体がアルミパイプであるために通信が不安定で使い物にならなかった。そこで、プロポに変えた。プロポの信号取り出しもなんとか安定できるようになったが、そのシステムを最初、ディスプレイとかマウス、キーボードを繋いだ形で起動しなければならず、一旦動かしたのちにログの処理をするなどの場合に、再度繋ぎ直す必要があるなど、耐え難い不便があった。

そこで、無全モジュールを使ってコントローラーを動かすことを考えた。機体の制御はプロポを使うのだが、その他のシステム制御を担うべきものだ。

無線モジュールとして、TY92SS-E2730が秋月電子に二千数百円で売っていたので、それを使うことにした。920MHzで400メートル以上とどく。技適取得済みで免許は要らないことにも驚きだ。正々堂々と使える。

これは、XBeeモジュール用のUSBインターフェイス基盤(秋月電子、千数百円)と組み合わせて使うことが圧倒的に便利であることが色々試みた結果、事後的に分かった。そもそも、XBeeがなんであるかはよく知らないのだが、知らなくても使えることがいい。

多数のモジュールをネットワーク上に繋いだりもできるようだが、差し当たっては、1対1の通信ができれば良い。

それぞれを相互の送受信用に、二つずつ買って、コネクタを半田付けして組み立てた。ピン配列の向きに注意しないと、基盤を壊す可能性がある。




ネット上に、使用した詳細の情報がほとんどなく、サンプルもないので最初は、チンプンカンプンだった。
コマンドマニュアルと製品仕様書の読み込みに、長時間没頭するしかなかった。
USB経由のシリアル通信が基本だ。変換ICがポピュラーなので、MACでもラズパイでも特別なドライバーをインストールする必要もなく認識する。
ホスト側からモジュールに送る信号は、マニュアル通りに与えなければならない。
以下、大事な点をメモがわりに書いておこう。
(1)最初は、マッチングはどうするのかと思ったが、結局、相手のデバイスIDを指定して送ることになっている。ある意味、TCPIPのようなものである。そこには、自己のデバイスIDも書き込むことになっている。製品情報からデバイスIDを生成する方法は、製品仕様書に書いてある。
(2)MACの場合は、USBシリアルデバイスをオープンするときにO_NONBLOCKを指定した方がいい感じなのだが、ラズパイの場合は、これを指定するとエラーになるので外す。これで、半日ロスした。Cのプログラム自体は、ほとんど両者でほとんど同じものが使える。

また何かメモすべきものがあれば、追加するつもりだ。

2022年12月13日火曜日

2号機テスト飛行の解析(3)

 2号機のテスト飛行を、近所の農家のSさんの畑を借りて実行した。

Sさんには、日頃からいろいろお世話なってい流。私が下ケ傍示から二之袋の竹の人がやっている早朝のラジを体操に向かうとき、いつも散歩しているSさん夫婦に出会う。中の良い姿を見るのに癒される。また、私の二之袋にある畑用に、玉ねぎの苗を200本以上もらったりもした。そのSさんが、私のドローンのテスト飛行用に、下ケ傍示ベースと二之袋ベースの間にある、絶好の場所を提供していただいたのだった。

テスト飛行の様子はyoutubeにアップしたので、以下から見ていただきたい。

https://youtu.be/Z2vkQfhJmpc

結果的に墜落状態になったが、過去のテストと比べて、より高い位置で空中遊泳をした飛行になった。

色々な課題が浮かび上がったテスト飛行だったが、いつものように、まず、ログの分析を与えておこう。

機体のロール方向とピッチ方向の傾き、それに対応したモータースピード(実際の回転ではなく、モーターに加えた電圧レベルと考えたら良い)のデータは次のようになる。

図をクリックすれば拡大されるのでそれを見ていただきたい。上部のオレンジと青の線は、ロールとピッチ方向の傾きだ。揺れがずれながら(期待が渦巻き状態になり)拡大している。最後は破綻している。(縦のスパイク状の変化は、システムが発生する誤差であり、無視して良い)
下の四つの色のグラフは、各モータースピードである。PID制御がかかっているので、機体の傾きに対応する形で、モータースピードの調整が行われている。
図を見る限り、調整が、揺れを拡大する作用を引き起こしてしまっているようだ。これが生じるのは、これまでのシミュレーションでも何度も明らかにしてきたので、その現象が綺麗に実現していると見ることができる。
ロールが大きくなると、それに反応する形でモーター4の速度が増大し、モーター3の速度が低下している。ピッチが大きくなると、モーター1の速度が増大し、モーター2の速度が低下している。
ただ、実際に我々がコントロールする時意識するように、傾きそうになった時に、その実際の傾きが大きくなる前に、それに専攻する形で速度制御をすべきだ。しかし、図では多少の制御の先行はみえているのだが、それが遅すぎるために揺れが増大してしまっていることが考えられる。
この制御の先行性を実現するのが、実はPID制御のD制御なのだ。そこで、PID制御のP(傾きに直結した制御)とD(微分制御)の状態をグラフ化すると以下のようになる。



オレンジと黄色の線は、それぞれ、ピッチ制御のP制御とD制御を表している。P制御は、傾きの変化にそのまま逆向きのトルクを与えようとする制御だが、D制御は、それを微分した形になっている。わかりやすくいうと、P制御がサインカーブならば、D制御は、それを微分したコサインカーブというのに対応する。実際サインカーブを微分したコサインカーブが、4分の1周期だけ、サインカーブに先行する形を示すように、動いている。つまり、次の動きを予想しながら、それに対応するためには、D制御を強めなければならないということである。
上図を見ても、D制御のレベルが相対的に小さいの、P制御が優位になっていると考えられる。

次回は、D制御を少し強めて、揺れの拡大を抑えられないか試す必要がある。これが、まず何よりもの重要な次回の課題だ。

さらに次回に向けて、現在システムの起動のために、WIFI は使わないので、直接、ラズパイのディスプレイとキーボード、マウスを繋いでいるが、これによって色々細かい調整ができなくなっているので、無銭モジュールを導入しこれを回避したいと考えている。

次回のテスト飛行前は、ちょっと時間がかかりそうだ。





2022年11月6日日曜日

プロポからのPWM信号変換の方法を変更

 これまでの記事にあるように、プロポからのPWM信号を変換するのに、ローパスフィルターを使っていたが、値が不正確で、モーターの回転のばらつきが発生して、飛行失敗につながっていることがわかった。

そこで、この方法は諦めて、ラズパイのGPIOの立ち上がり、たち下がりを検知するCALLBACK関数を用いて変換することにした。そのために、pigpioというライブラリを使用する。詳細はまた、この記事に書こうと思う。

(1)インストール

https://abyz.me.uk/rpi/pigpio/download.html

最新バージョンのダウンロードとインストールはここに書いてあるとおりにすればいい。

(2)C++で実行するときは、作成したプログラムをsudoを使ってroot権限で実行する必要がある。その代わり、pigpiodを事前に起動する必要はない。

(3)受信機の接続

受信機からの信号を空いている GPIOピンに接続。



(4)プログラム

8ちゃんねるの信号を読みとっとμ秒単位のPWMの幅で出力するプログラムの概要は以下のような感じである。CALLBACK関数は、グローバルな場所に置いておかなければならない。それに伴い、変数もStaticである。

コンパイル時のライブラリに pipgioとpthreadを追加しなければならない。

#include <stdio.h>
#include <pigpio.h>

static int pwm_count[8];
static uint32_t rise_tick[8];
static int pwm_width[8];
unsigned int from_gpio[30];

void interruptDisplay( int gpio, int level, uint32_t tick)
{
    int array_No = from_gpio[gpio];
    if(level==1){
        rise_tick[array_No] = tick;
    }else if(level==0){
        int diff = tick - rise_tick[array_No];
        if(diff > 500 && diff < 2500){
            pwm_width[array_No] = tick - rise_tick[array_No];
            //printf("Interrupt pin %d #%d level %d at %u DIFF = %d\n", gpio, c, level, tick, pwm_width);
            printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", gpio,pwm_count[array_No]
                    , pwm_width[0]
                    , pwm_width[1]
                    , pwm_width[2]
                    , pwm_width[3]
                    , pwm_width[4]
                    , pwm_width[5]
                    , pwm_width[6]
                    , pwm_width[7]
                   );
            pwm_count[gpio]++;
        }
    }else{
        printf("ERROR level is non 0 and non 1\n");
    }

}

int main(void)
{
   int ret;
   // 配列番号をGPIO番号に
   unsigned int to_gpio[8];
   to_gpio[0] = 4;
   to_gpio[1] = 17;
   to_gpio[2] = 27;
   to_gpio[3] = 22;
   to_gpio[4] = 5;
   to_gpio[5] = 6;
   to_gpio[6] = 13;
   to_gpio[7] = 26;
   // GPIO番号を配列番号に
   from_gpio[4] = 0;
   from_gpio[17] = 1;
   from_gpio[27] = 2;
   from_gpio[22] = 3;
   from_gpio[5] = 4;
   from_gpio[6] = 5;
   from_gpio[13] = 6;
   from_gpio[26] = 7;

   if (gpioInitialise()<0) return 1;

   for(int i=0;i<8;i++){
       pwm_count[i] = 0;
       rise_tick[i] = 0;
       pwm_width[i] = 0;
       /* Set GPIO modes */
       gpioSetMode(to_gpio[i], PI_INPUT);
       gpioSetPullUpDown(to_gpio[i], PI_PUD_UP);
       printf("GPIO %d is level %d\n",to_gpio[i], gpioRead(to_gpio[i]));
       ret = gpioSetISRFunc(to_gpio[i], EITHER_EDGE, 5000, interruptDisplay);
       // Callback 設定
       if(ret < 0) printf("error GPIO Int %d\n",to_gpio[i]);
   }

   while (1)
   {
    time_sleep(60);
   }

   gpioTerminate();
}

(5)プロポに反応した結果

実行はルート権限で行う必要がある。



異常値を取り除けば十分よく反応している。




2022年10月20日木曜日

2号機テスト飛行の解析(2)

 先の分析で示したPID制御信号について、D制御のギザギザがあるという話をした。それでも、P制御よりも先行した制御信号になっているはずだと書いた。その辺りを確かめてみよう。

以下の図は、PID信号をそれぞれに分解したものだ。

D信号は、Roll データの細かい信号を拾ってギザギザになっているが、平均すればP信号よりも先行する制御信号を出していることがわかる。すなわち、いわば、SINカーブに対して微分したCOSカーブである。

ただ、このような信号がESCに与えられた時に、モータがその大きな流れを反映したものになるかどうかはやや不安である。D信号が弱められてしまう懸念がある。

このD信号の細かい揺らぎについては、IMU(慣性計測装置)から送られてくる信号の実際の揺らぎと、サンプリングの問題で取られてきた値が変わらなかった時に微分値がゼロになってしまうという二つの問題が含まれていて、後者は、ゼロの時は前の日ゼロの値を採用するというロジックで改善する。前者は、移動平均をとってなめらかにしていくしかない。

データ上だけで(実際の飛行ではなくの意)、このように対応した結果は次の図のようになる。

赤の線が処理済みデータで、灰色の線が0だけを取り除いたデータである。移動平均の期間は10期である。

いい感じでなめらかになっている。移動平均で最も困るのが変化の遅れが発生することだが、問題になるほどの遅れは、図では見えていない。

これをコントロールプログラムに組み込もう。



2号機テスト飛行の解析(1)

 2号機を下ケ傍示ベースでテスト飛行させたが、当然のように(!)不成功だった。その様子は以下のようにyoutubeに上げてある。

https://youtu.be/YN_Zxr1MBT0

この機体は、ジョイント部分が3Dプリンタで作成したプラスティックなので、完成機体とは言えないものだ。本来は、ジョイントはアルミで製作したい。が、そのためにはアルミ溶接をしなければならないが、その準備ができていないので暫定的にプラスティックで作成している。

プラスティックだが、パイプの接合という点ではある程度丈夫に作ったつもりだ。しかし、今回のテスト飛行でコントロールシステムを載せた中央のアルミ板を支える部分が壊れてしまった。設計上、弱過ぎた。アルミ板自体も450gくらいありやや重たいという問題もある。この脆弱性を克服するために、新しく設計し直したものを製作中だ。

この記事では、今回の初飛行のログを解析しておこうと思う。

初めに、ドローンの回転の方向を確認しておく。


ローターの番号、2から1の方向の軸をLとすると、Lに関して右回転をRollとし、4から3への軸をMとし、その右回転をPitchとしている。これに対して45度傾いた軸を設定することも可能だが、そうするとRollとPitchのデータにどのローターの回転が影響をしているのか、関係づけるのが複雑になるので、それが明快な図の設定にしている。

動画では、離陸してバランスを崩して着地、さらにもう一度飛行させている。以下では、最初の飛行を解析する。

動画では、右奥のローターから左手前のローターに向けた軸がL軸である。つまり、小屋側から母家側に向かう方向である。

RollとPitchの動きをデータで見ておく。




相対的に大きな変動をしているRollの動きを見ると、まずRollが負の方向へと傾き(A→B)、Rollが正の方向に反転し(B→C)その過程で、ローター1と4の辺が地面に接触した。その接触したのがC点である。その後、Rollは正の方向に大きく傾いて着地している。これは、ほぼ動画そのまま確認できるところだ。

この機体傾きの変化に対して、PID調整がどのよう関係しているのかを確かめてみよう。


まず初めに了解しなければならないことは、AからBにかけてRollが負の方向に傾いた原因は、不問にしておくことだ。1号機では、この点に強くこだわり、モーターの回転数のばらつきや機体の微妙な傾き、あるいは地面効果や壁面の機能など色々調べたりした。しかし、これはキリがない。どのような状況が発生しても、それに対して機体の修正能力を保つべきだし、PID制御は、潜在的にそれをできる可能性を持っているはずだからだ。だから、2号機は、機体の元々の揺らぎの原因をあまり追求しないことにしている。

図の上半分は、PID制御によって各モーターがスピード調整した分だけを取り出している。

AからBへのRollの負の方向への傾きに対して、モーター3が強化される方向に反応している。ずで細かい振動があるのは、D制御(微分制御)がある程度効くように設定しているので機体傾きの微妙な変動の反映結果である。微分制御は、このような細かい変動に意味あるのではなく、機体の揺れの大きな変動を先取りしてモーター速度に反映させることで、その点では機能しているはずである。

モーター3の強化の結果として、Rollの揺り戻しが生じているように見える。ただし、ここで、私がプロポをコントロールして、Rollを強めるように動かしたという事実も考慮しなければならない。プロポからのモーターへの制御信号を重ね合わせると、次のような図になる。


Rollの傾きが現れて、やや遅れて、モーター3を強め、モーター4を弱める信号が出ていることがわかる。プロポのこの信号の強さは、PIDの信号の強さの倍くらいある。

Rollの負の動きに対する二つの信号の効果を識別することはなかなか難しい。ただ、直感的には、BからCへの変化は、PIDによってもたらされ、DからEへの変化は、プロポによるものであるようだ。

動画と詳細に照らし合わせると、PIDによる姿勢安定化は一定程度、実現しているのではないかと思える。初期の機体の傾きだけは、離陸位置を変えるなどして問題を回避し、PIDの効果の程度を最後まで追う必要がある。プロポからのRollやPitchの信号を出さずに、PID信号の効果を確認すべきだ。それが結論。

2022年10月11日火曜日

10Hzのリップルをカットするコンデンサ容量

 PWM信号を作成した8チャンネルローパスフィルタに通すと、大まかな定電流信号に変わるが、微妙にリップルが含まれている。


図は、プロポのスティックの動きを変換したものだが、10Hz程度のリップルが規則的に表れている。RCローパスフィルタは、15KΩの抵抗と1μFのコンデンサで形成されている。そのカットオフ周波数は次の式で表される。

$$f_{c}=\frac{1}{2\pi RC}$$

値を式に入れるとカットオフ周波数は、ほぼ10Hzだ。カットオフ周波数の定義から10Hzでカットしている電圧は3dbであるから、これでは十分カットしていると言えないということなのではないかと思う。

Rを増加させてもいいのかもしれないが、フィルターの働きを弱めそうな気もするので、ここはCを増加させるのが妥当だろう。5μF、10μFを確かめたい。

2022年10月2日日曜日

8チャンネルPWMコンバーター

 PWMをアナログ直流信号に変換するためのプリント基盤を作成した。それについては、先の記事に詳しく書いておいた。



上のように部品を全て装着した。部品が80個近くあるので、半田付けは大変だった。一回目は、オペアンプの足の半田付けに失敗して、それまで装着した抵抗やコンデンサーが全てお釈迦になった。やはり、一挙にはんだ付けしようとせず、くぎりながら丁寧にやる必要があることを痛感した。

予定通りプロポからの信号に反応するか、機能を調べた。


1チャンネルずつイラベタところ、予定通り変換していることがわかった。RaspiのMCP3208を通してデータにした結果が以下の通りだ。

8チャンネルのうち、ピッチ、ロー、スロットル、ヨーに関するものだけを見ている。一部エラーデータが混じっていることと、リップルがホワイトノイズとして入っているのが、気になるが、使えるということがわかる。


920MHz帯無線通信モジュールTY92SS-E2730を使う

 先にも書いたが、ドローン2号機上のコントローラーはラズパイ4で、それとのやりとりをもともとWIFI経由で予定していたが、機体がアルミパイプであるために通信が不安定で使い物にならなかった。そこで、プロポに変えた。プロポの信号取り出しもなんとか安定できるようになったが、そのシステム...