2025年7月20日日曜日

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

 システムで、dshot信号を作るのをpicoでやらせていた。UARTの使用の関係で、pico1台で、2つのモータに信号を送っていたので、2つのpicoを使っていた。それまでは、pico二信号を送って、あなたはどちらのpicoですかと問い合わせして、その答えを聞いて /dev/ttyACM0か/dev/ttyACM1であるかを区別した。プログラムは面倒だが、正しくソースがかければ、難なく区別できた。

しかし、ここに来て、ラズパイをやめて、ミニPCに変えた。GPIO的ピン操作やI2Cのやりとりなどを、PC自体ではできないので、picoを経由でやるのが、手っ取り早くて柔軟にできるので、さらに2つpicoを追加した。すると、4つのpicoがどのデバイスファイルになっているのか、を区別しなければならなくなった。2つのときと同じでもできなくはないが、色々面倒になる。しかも、imuからi2c経由でデータを取るときは、 picoに対して制御信号は送らなくていいのに、区別のためだけに信号の送受信手続きをプログラムしなければならない。これが痛く面倒だ。

しらべると、Linuxのudevというデーモンが、デバイスファイルの割り振りを制御していることを知った。今頃知るのはおそすぎだと言われそうだ。そこで、/etc/udev/rules.d/に、90-picos.rulesというファイルを用意し以下のように書いた。 

SUBSYSTEM=="tty", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", ATTRS{serial}=="E660C062134F4F27", SYMLINK+="ttyPi\
coA", MODE="0666"
SUBSYSTEM=="tty", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", ATTRS{serial}=="E663AC91D371B438", SYMLINK+="ttyPi\
coB", MODE="0666"
SUBSYSTEM=="tty", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", ATTRS{serial}=="E660D4A0A7933224", SYMLINK+="ttyPi\
coC", MODE="0666"
SUBSYSTEM=="tty", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0003", ATTRS{serial}=="E0C9125B0D9B", SYMLINK+="ttyPicoD"\
, MODE="0666"

これで、  それぞれのデバイスが

/dev/ttyPicoA

 /dev/ttyPicoB

/dev/ttyPicoC

/dev/ttyPicoD

にシンボリックリンクをはられていた。

2025年7月16日水曜日

UbuntuにQtCreatorをインストールする

結局、Qtのグラフィックインストーラーを使ってやった。

https://www.qt.io/download-qt-installer-oss 

ソースからのコンパイル、何度も挑戦した。失敗した。時間かかった。 

独特の通過儀礼がある。最も基礎的なものは、QtそのものとQtCreatorが別々のものだということ。それぞれ独立にインストールすべきものだということ。ほぼ常識的なことなのだが、ここをきちんと頭に入れておかないとおかしくなる。QtCreatorからみてQtのバージョン区別は、Qtのqmakeによって行われること。これも以前は意識しなかった。それらもふくめて、キットで適切な指定がなされないと、キットが利用不可になる。

MiniPCは以上で問題なくインストールできたが、MacにVirtualBoxでインストールしたUbuntuにインストールしたとき、OpenGLがなんちゃらというエラーがいっぱい出てきた。よくわからないが、以下のコマンドでエラーがなくなった。

 sudo apt install libegl1-mesa-dev

2025年7月3日木曜日

RaspberryPi5にQtCreatorをインストールした

 RaspberryPi4には、3で使っていたSDカードを援用していたので、QtCreatorをどうインストールしたか忘れていた。ときどき、さらのSDカードを使って、Qtを入れようとしたが、ことごとく失敗した。

今回、4号機の、電源配線をミスして、ラズパイそのものやIMU、無線ユニットなどを全て壊してしまった。数万円の損をした。色々考えた末、期待の乗せるラズパイを5にすることにした。グラフィックユーザーインターフェイスは、QtをあきらめてJAVAにしようかとも思った。JAVAは、よほど使い慣れている。だが、期待の基本システムはすべてC++で書いていて、メインのシステムはそのライブラリになっている。JAVAからC++のライブラリを呼び出すのはとてもとても面倒くさい。やはり、Qtでなければならないと、最新のQtをソースからコンパイルして、言い訳できないようにしようと考えた。

参考にするサイトは、かかっこさんの

https://note.com/bsoft/n/nadcad4db7454 Qt開発環境をソースコードからビルド(ラズパイ5)

にした。参考といういよりも、これそのものを実行すれば良いと判断した。QtWebEngineは、コンパイルに一週間かかるということなので、当然スキップなど、6のサンプルなど省略できるものは省いた。

このサイト通り行かなかったところだけは以下に示しておく。

(1)qt-everywhere-src-6.7.0.tar.xzは、なぜか消えていた。ので、qt-everywhere-src-6.9.1.tar.xzという、この時点で最新のものにした。サンプル絡みでエラーが出たので、それを排除してコンパイルした。

(2)qt-creator-opensource-src-13.0.0.tar.gzをダウンロードして、コンパイルしていたら、createという関数のリターン値が不整合というエラーで止まってしまった。細かいことなので、大きなところは間違っていないようだったが、コンパイルできなければ話にならない。6のバージョンを最新のものにしたからだと思った。だから少し古いものを入れ直そうかと、一瞬思ったが、あのコンパイル時間の長さをもう一度体験する気にならなかったので、creatorの方を最新のqt-creator-opensource-src-17.0.0.tar.gzにした。これでうまくコンパイルがしのげた。

(3)これが最も重要なものかもしれない。いざ全て整って、プロジェクトを作成しようとしたとき、非Qtのプロジェクトは難なく作成して、実行できたが、WidgetのGUIプロジェクトを作成しようとしたら、キットが見つかりませんというエラーになった。このエラーには何度も出会って、インストールを諦めた経緯がある。今回は、先の参考サイトを基本的になぞってきたので、そうかんたんには諦めるわけには行かなかった。色々やった結果、Qtのバージョン設定をやったら、解決した。

設定は、まず、編集のPrfferenceから、キットの設定画面を開く。Qtバージョンのタブで、追加をクリック。ここでは、Qt5とQt6の2つのバージョンが使えるようになっているので、それぞれを追加する。追加の仕方は、追加のボタンを押すとファイルの選択になるので、Qtがインストールされているフォルダにある、binフォルダのqmakeを選択すると、そのバージョンが追加される。追加した後に、キットのタブで、Qtバージョンのドロップダウンリストに、それぞれのバージョンが選択できるようになるので、必要なバージョンを選べばよい。これで、キットがないというエラーは消えた。

 ただし、上記以外の方オフでインストールした場合は、この方法は役立たない。

2025年5月30日金曜日

プロペラ回転面の方向を直接変化させ機体を安定させる

 複数プロペラドローンの機体の安定は、PID制御などによってプロペラ相互の回転速度を変化させることで実現してきた。ここでは、回転速度は一定のまま、プロペラの回転面の方向を変えることによって実現できないかを少し考えてみたい。

とは言っても、ヘリコプターは、実質回転面を変化させているので、すでになじみの方法なのかもしれない。そこで、まず、プロペラが一個にして状況を単純化しこのことを考えてみたい。

次の図を見ていただきたい。


ここで、OMは、長さLの質量を無視できる房であるとしよう。ドローンの機体を抽象化したものだ。機体は、位置が固定しているO点を支点として回転するのみである。Mにモーターとプロペラがありがあり、プロペラの回転面はMを支点に自由に動かすことができるとして、その回転面は直線PQで表されている。プロペラの回転面は、機体に対して垂直な状態が基準である。機体OMは垂直に立っている状態が基準となる。そこからの機体の傾きを図の$\theta$ で表される。また、機体のプロペラ面の基準状態からの傾きは、$\varphi$で表されている。

機体の質量は点Mに全て代表して存在し$m$で表される。重力加速度をgとしよう。M点の運動方程式を考える。プロペラの回転数は一定で、そのスロットルは一定の力$T$で表されるとしよう。

また、二つの角度$\varphi$と$\theta$は図の方向が正の方向であるとする。

$mL\frac{d^{2}\theta}{dt^{2}}=mg\sin\theta-T\sin\varphi$

となる。今、プロペラ面の角度を制御するスキームとして、次の式を考える。

$\varphi=\delta\theta$

つまり、機体の傾き角度に応じて一定の係数$\delta$をかけてプロペラ面を制御するというものである。このとき、運動方程式にこの式を代入し変形すると、次のようになる。

$\frac{d^{2}\theta}{dt^{2}}=-(\frac{T}{mL}\sin\delta\theta-\frac{g}{L}\sin\theta)$

今$\theta$が微小にのみ変化すると仮定すると、次のように近似できる。

$\frac{d^{2}\theta}{dt^{2}}=-\frac{1}{L}(\frac{T\delta}{m}-g)\theta$

すなわち、$\delta$が右辺の括弧内を正にする大きさであれば、これは単振動になる。逆に小さければ、重力に負けて落下する。

この制御では、機体の傾きを十分補正するようにプロペラ面の傾きを与えれば、機体は一定の揺れを繰り返した状態で定常状態になるわけだ。しかし、それでは安定しているとは言えない。

安定させるためにどうすればいいか考えよう。

傾きの角度に対する微分制御を加えたスキームに変更しよう。すなわち、

$\varphi=\delta\theta+\eta\frac{d\theta}{dt}$

である。運動方程式は、次のように変形できる。

$\frac{d^{2}\theta}{dt^{2}}=-(\frac{T}{mL}\sin(\delta\theta+\eta\frac{d\theta}{dt})-\frac{g}{L}\sin\theta)$


右辺のカッコ内の第1項を三角関数の加法定理を使って変形すると次のようになる。

$\frac{d^{2}\theta}{dt^{2}}=-(\frac{T}{mL}(\sin(\delta\theta)\cos(\eta\frac{d\theta}{dt})+\cos(\delta\theta)\sin(\eta\frac{d\theta}{dt}))-\frac{g}{L}\sin\theta)$

今、$\theta$が微小な範囲でのみ変化するとして、$\sin\beta\sim\beta, \cos\beta\sim 1$という近似を持ちいると、

$\frac{d^{2}\theta}{dt^{2}}=-(\frac{T}{mL}(\delta\theta+\eta\frac{d\theta}{dt})-\frac{g}{L}\theta)$

単振動にはならないので、二階同次微分方程式の形にしておこう。

$\frac{d^{2}\theta}{dt^{2}}+\frac{\eta T}{mL}\frac{d\theta}{dt}+(\frac{\delta T}{mL}-\frac{g}{L})\theta=0$

この微分方程式は、同次式になっているので解析的に解くことができるが、煩雑かつそれほど必要でもないのでやめておこう。

はっきりしているのは、$\delta$が十分な大きさを持つことを前提にすると、これは簡単に言えば速度に比例した摩擦が発生する錘のついたバネの振動になり、一方的にか、振動しながら元の状態に収束する。つまり、機体を安定させることができるわけである。

結論的に、プロペラ平面を制御する適切なスキームを与えれば、機体を安定させることができる。

2025年3月2日日曜日

向かい風によってドローンの頭が上げるpitching moment に関する論文を読む

 Reduction of the head-up pitching moment of small quad-rotor unmanned aerial vehicles in uniform flow (2018, Hikaru Otsuka, Daisuke Sasaki and Keiji Nagatani, International Journal of Micro Air Vehicles 10-1)

https://journals.sagepub.com/doi/epub/10.1177/1756829317745318

という論文を読んだ。中身は、飛行体に対して向かい風が吹いてきた時に発生するpitch方向のhead up不安定性がドローンのローターの傾きを変えた時にどうなるかを調べている。

さまざまな実験を行った結果として、結論的に、モーターの向きを外側に向けて開くことによってその不安定性を低減できると主張している。

"Based on the experimental results, we conclude that rotor tilting to the outer side reduces pitching moment generation."

私の書いた前の記事の議論と整合的であるので嬉しい。

モーター平面をV型(inward tilt)にするとドローンの安定性は増大するか?

 概要

ドローンのモーター平面をV型に傾けるとより安定するといわれているようだが、理論的には、逆Vにした方が安定することを示す。


本文

あるYouTube動画を見ていたら、モーター平面を内側に傾ける(inward tiltというらしい)とドローンの安定性は増すのだという説明があった。聞いた一瞬はとても納得して、既存の大型のドローンのモーター平面がそうなっている理由がわかった気がした。しかし、理論的に考えて、本当にそうなのかと思った。

自分なりに考えてみた結果一概にそんなことは言えないような気がした。その理由を説明しよう。





図を見て考えみよう。単純化して、AOBで表されるのが、ドローンの機体を一方向から見た状況だと考えよう。機体の垂直方向は、Vで機体は右に少し回転した状態で、傾いている。モーターの平面は、内側に折れるように傾いていて、その傾き角度はβである。
両翼の長さは、それぞれ$l$である。

この状態で、復元力が、このモーター平面の傾きによって発生すれば良いわけである。
面倒なので、一番単純に考えてみる。
(1)機体の中心Oは、固定されている。ただし、自由に画面と水平に回転できる。
(2)機体の片側の重さ$m$は、モーターの場所に集約されている。
(3)モータの上昇力、スラスト$t$は、重さで測られ片側の重さと釣り合っている。
すなわち、$$t=m$$である。
今、A点における力のバランスを見てみよう。
動画では、復元力が発生する理由を、A点では、傾いているせいで、そこにかかる重力に比べて、上昇力が$$t\cos\beta<t=m$$となってしまっていて、下向きの力が大きくなっているからだと説明していた。
だが、それは、傾いているが故に発生する右向きの力を無視している。さらにmが働いている腕の長さも短くなってしまっていることを忘れているのではないだろうか。
そこで、A点において、左向きに回転する力(傾きを復元しようとする力)と、右向きに回ろうとする力(傾きをさらに増大させようとする力)のバランスを調べてみよう。
左向きに回転しようとする力と、腕の長さを掛け合わせたトルクは、
$$(m-t\cos\beta)l\cos\beta$$
である。
一方、さらに右向きに回転しようとするトルクは、
$$t\sin\beta l\sin\beta$$
である、
左向きの回転力から右向きの回転力を差し引く
$$ (m-t\cos\beta)l\cos\beta-t\sin\beta l\sin\beta$$
$$ = ml\cos\beta-tl\cos^{2}\beta -tl\sin^{2}\beta$$
$$ = ml\cos\beta-tl$$
$$ = l(m\cos\beta -t)$$
$$ = lm(\cos\beta-1)$$
$$ < 0$$
(ただし、ここで$t = m $を使っている)
この結果は、安定化するどころか、不安定性を増加させるという結論だ。
どこか、考え方が間違っているだろうか?

簡単な練習問題になるが、モーター平面が、逆に、下に開いたVの形をしていると、安定性が増すようなバランスになることがわかる。式の変形はそのままで良い。ただ、下向きの場合は上の式が負になるのは、復元力が働く、右回転することを意味するからだ。

ここで、もしかすると今までの議論が、ドローンの腕そのものが傾いていることに依存しているのではないかと疑問が湧いてきたので、さらに調べてみた。

次の図のように、腕そのものは傾いていず、まっすぐで、モーターだけが傾いている状況を考えてみよう。
今、モーターの傾きは、$\alpha$で、機体が$\beta$だけ傾いている状況を考えてみよう。他、腕がまっすぐになった以外は、前と同様の条件である。

次のような単純化を行おう。
(1)モーターの傾きと、機体の傾きがちょうど同じになった状態を考慮する
(2)その状態で、B点のスラストと重さのバランスは釣り合っている。すなわち相変わらず、$t=m$を想定する。
この状態で、左回転のトルクが発生すれば復元力があることになる。

ただ、これは計算をするまでもなく、先の機体の腕が傾いている状況の分析で$\beta$を$2\beta$にしただけで、計算過程は同じである。従って、結論も同じである。

機体の傾きが、前のモデルと同じでも、モーターが傾いているだけ、不安定性は増す可能性がある。また、逆向きにモーターが傾いていると、安定性は増加する。

2025年2月15日土曜日

3号機、ホバリングのログ解析

 3号機のホバリングの様子は、以下のYoutubeに投稿した。

https://youtu.be/ZYVSvt3-ws4

3回、試みているが、それぞれ様子が違う。ログを見てみる。まず、コントローラーから送っているスロットル値とPID制御によって与えられたスロットル値の様子は、以下のようになっている。


1回目は、全体が安定しているが、2回目と3回目は、後半が不安定になっている。

1回目の離陸では、1600くらい、80%で離陸している。そして、PID制御によるスロットルの変動の最大幅は、400前後である。合計すれば2000前後である。スロットルの最大値は、2047だからぎりぎりなのである。

次のグラフは、機体の傾き、ROLLとPITCHの様子と、PID制御のスロットル値の様子が、2回目と3回目は、機体の傾きに対して、極端なPID制御値が必要になってい。ので無理が表れている。




これでは見にくいかもしれないので、第1回目の離陸だけを取り出して詳しく見てみる。


太い青の線がROLLで、太い緑の線がPITCHだ。それぞれの目盛りは右側に示されていて、値は度である。モーターの番号は、前が北として、北西がモーター1(細い青線)、南東がモーター2(オレンジ細線)、南西がモーター(灰色)、北東がモーター4(黄色)である。赤で囲ったところを見てみよう。ロールが正で、ピッチが負である。ロールが正なので、2と4のスロットルを上げる必要がある。一方、ピッチが負なので、2と3のスロットルを上げ、4はスロットルを落とさなければならない。結局、しっかりスロットルを上げる必要があるのは、2で、しっかり落とす必要があるのは、1という事になる。図はその通りになっている。PIDは、よく反応しているのだ。


2024年12月7日土曜日

立ち上がらないraspberrypiのネットワーク

 raspberrypiのネットワークが立ち上がらなくなってしまっていた。差し当たって必要ないのでほっておいたが、今日、いろいろ調べてみた。

結局、raspi-confgで、network Configure をdhcpcdから、networkmanagerに変更したら立ち上がるようになった。理由は、わからない。

2024年8月15日木曜日

起動しないraspberrypiの修復

 前日の終了の仕方が悪かったのか、raspberrypi が起動しなくなった。You are in emergency mode・・・・・・を限りない感じで繰り返している。

https://www.jh4vaj.com/archives/26989

このサイトを参考にした。

WindowsにいれたVirtualboxのraspberryで問題のSDカードを認識させて上記サイトの最後の方にある、e2fsckをbootではなくファイルシステムの方に実行した。全てyesで、終了させる。再度起動させたら、正常起動した。ほっと胸を撫で下ろした。

2024年8月14日水曜日

再開

 昨年の2月に、財政的な理由で一時的に作業を中断した。が、ようやく、再開できる感じになってきた。かつての自分の頭が考えていたことが、少しずつ戻ってきている。

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


2022年9月29日木曜日

プリント基板の設計と業者への発注:(5)業者の対応

 先に示した8チャンネルの回路について、部品を実装しない基盤を中国の業者3社に発注した。対応の違いを確認しておく。これからは1社に依頼し、こんな無駄なことはしないで済むようにしようと思う。

(P)  PCBGogo

2022年9月25日(日)に、ガーバーデータをアップした。データ審査過程でなんら問題を指摘されなかった。翌26日に、製造に入るから振込み要請が来て、基盤代5ドルと配送代と手数料込みで、計27ドルをPayPal で振り込んだ。

27日製造完了で配達手続きに入った。追跡番号はマイページに記載されている。29日にDHL経由で配達予定になっていたが、DHLの都合で配達日変更になったようだ。DHLの配達予定は、DHLが佐川急便に荷物を引き渡す日だったようで、配達は30日になった。

到着した基盤の画像は以下のよう。



(S) SpeedSTUDIO (Fusion)

2022年9月26日(月)に、ガーバーデータをアップした。その日のうちに請求がまず来た。基盤製作、送料込みで18.55ドル。Paypalで振り込んだ。

しかし、その後にデータの不備が見つかったので、マイページに返信をしなさいとメールが届いた。この時、NextPCBが基盤の取り付け用のネジ穴がデータ間でずれがあると指摘されていたので、そこを治したデータを作成していた。ところが、マイページに再アップロードボタンが見つからない。それからも一二度、早く返事をしなさい胸のメールがきたが、こちら側としてはどうしようもない。やがて、翌27日マイアップロードページのメッセージが変わって、穴位置の不備が指摘された画像が掲載されていた。さらにチャットができるようになっていたので、データアップロードボタンが見つからないと書くと、しばらくしてボタンがつけられた。マイページのシステムは、とても柔軟なようだ。

翌28日審査が通ったようで、生産開始になった。30日朝の時点で、いまだに生産中になっている。

生産が終了し、出荷されたのが10月8日、到着が14日だった。他の2社と比べると遅い。

(N) NextPCB

2022年9月25日(日)に、ガーバーデータをアップした。翌26日、審査した人からドリルファイルがないというむねの審査状況がメールできたので、再アップロードした。また、その日のうちに、基盤のネジ穴位置が不整合であることと、PADが指定されていないという問題の指摘がきた。基盤位置の穴が不整合だったのは、新しいガーバーファイルでは、基盤の少し内側にねじ穴を設定し直したのにドリルファイルが古いままだったので、位置が不整合になったのだ。PADが指定されていないという意味がわからなかったが、おそらくオペアンプLSIについて、ソケットではなく、LSLを直接取り付けるから電極をハンダする面(PAD)が必要だと思われたのではないかと考えて、フットプリントをソケット用のものに変えた。ここは、再アップロードするボタンがマイページに明確に指定されていたので、再アップロードは容易にできた。

翌27日、審査が通ったようで、支払いの指示がきた。製作、送料込みで23.73ドルをPaypalで振り込んだ。翌28日には、生産終了と配送が終わったというメールが届いた。DHLの追跡番号はマイページに記載されている。

配送予定日は、9月30日となっている。これが佐川に渡される日としても迅速なのかもしれない。

9月30日に「配達中」。DHLカスタマーセンターとチャットしたら、配達は佐川急便ではなくDHL自身がやっているとのこと。その日の午後5時前に到着した。

到着した基盤の画像は以下のよう。


(P)の基盤と(N)の基盤を比べて、パッと見て大きな違いは(N)の基盤にはパーツ名が入っていること。これがないと、いちいち配線図と比べて部品を取り付けなければならないが、名前があれば、これが明確にわかる。(P)もオプション指定でできるのかもしれないが、確かめていない。

(N)の基盤では、設計上で裏面に一つのネットワークをベタ塗りしているところが改良点である。ところが、そのネットワークを、間違ってGND以外のものにしてしまった。ノイズの状況が悪ければ、ベタ塗りをGNDにしたものを再度依頼しようと思っている。


2022年9月27日火曜日

プリント基板の設計と業者への発注:(4)ガーバーファイルの出力とビュー

業者には、ガーバーファイルを中心に提出することになる。だから、とても大事な作業である。

 ガーバーファイルの出力は、上段メニューの「プロット」をクリックして開始する。


必要なレイヤーを指定したりなどするが、だいたいこの設定でうまくいっている。出力ディレクトリが指定されていないと、プロジェクトのトップディレクトリに出力される。だいたいガーバーファイルはレイヤーごとにたくさん出力されるので、他のファイルとすぐ区別できるつように、フォルダをプロジェクトの中に作った方が良い。

「プロット」ボタンを押すと、塗りつぶしの再描画が問い合わせされる。

「再塗り直し」を選択する。基盤に塗りつぶしが表示される。


再び、プロットダイアログが表示されるので、今度はドリルファイルの出力ボタンを押すと、ドリルファイルのダイアログが表示される。


だいたいこのような設定で問題なかったと思う。ドリルファイルの生成ボタンを押してガーバーファイルの出力を終了する。他にも、必要に応じてマップファイルなども出力しなければならないが、ここでのサンプルでは、ガーバーファイルとドリルファイルだけで良い。業者に渡すのもその二つのファイルをアーカイブしたものである。

次に、ガーバーファイルをプレビューしなければならない。

KiCadのアプリ選択ウィンドウで、ガーバービューを選択し立ち上げる。そのトップメニューのファイルから、「ガーバープロットファイルを開くを選択すると、ファイル選択ダイアログが現れるので、ガーバーファイルを出力したフォルダを開き、サフィックスが .gbrのファイルを全て選択し決定する。

という出力基盤が現れる。ここでは、ベタの色が緑になっているが、これはB.Cuレイヤーの色を意図的に変更してこうなっている。やり方は、ビューワーの右に例や選択ウィンドウがあり、その該当レイヤーの上で右クリックすると色の選択ボタンがあるので、それで変更できる。

各レイヤーを一通り個別にチェックできるので、問題がないか確かめなければならない。特にベタが確かに意図通りにセットされているかは重要である。なぜならば、ベタ領域はある意味追加的な結線のようになっているので、下手すると回路の整合性が取れなくなるからである。ちょっと変な言い方だが、ベタ領域はある意味一つのネットワークになっていて、対象のネットワーlくが二重化しているようなもので、基盤エディタには、両方のデータが組まれていて、一方を削除しても一方は残るようになっている。だから、他のものと間違いを起こしやすいように思えるからである。

業者へは、このガーバーファイルとドリルファイル、必要ならばマップファイルなどをzip して渡すことになる。

国内の業者はいずれも高そうだ(正確には、国内業者でリーズナブルな価格で提供しているものが、私には見つからなかったというべきだ)から、中国の業者にお願いすることになるが、アップロードした時点でのファイルチェックが厳しいところとそうでないところがある。また、アップロードしたのち、設計ミスがないかという審査(あくまで製造ができるかどうかであり、回路の配線ミスなどは設計者の責任になる)のやり方も業者ごとに異なっている。

私なりの業者の評価は、いろいろ体験したのちに書こうと思う。




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

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